From f77b0b90d8daedf30e86ab09d292158e0b9af353 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Sat, 12 Oct 2019 16:47:51 +0200 Subject: Correctly mangle frameaddress intrinsic name --- src/codegen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index 5d1f2b8bf9..9f32e3dd35 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5256,7 +5256,7 @@ static LLVMValueRef get_frame_address_fn_val(CodeGen *g) { LLVMTypeRef fn_type = LLVMFunctionType(get_llvm_type(g, return_type), &g->builtin_types.entry_i32->llvm_type, 1, false); - g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress", fn_type); + g->frame_address_fn_val = LLVMAddFunction(g->module, "llvm.frameaddress.p0i8", fn_type); assert(LLVMGetIntrinsicID(g->frame_address_fn_val)); return g->frame_address_fn_val; -- cgit v1.2.3 From 17c8f108a4d4c753e087e23ff5722718a6cd7a6a Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 30 Jan 2020 17:50:50 -0500 Subject: drop @newStackCall this was causing unrelated behavior tests to fail. if this commit is reverted, the docs are good, but `@newStackCall` is already deprecated in favor of `@call`, supplying the `stack` property. --- doc/langref.html.in | 34 ----------------------------- lib/std/builtin.zig | 2 ++ src/all_types.hpp | 1 - src/codegen.cpp | 1 - src/ir.cpp | 33 ---------------------------- test/stage1/behavior.zig | 1 - test/stage1/behavior/new_stack_call.zig | 38 --------------------------------- 7 files changed, 2 insertions(+), 108 deletions(-) delete mode 100644 test/stage1/behavior/new_stack_call.zig (limited to 'src/codegen.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index 7915f82d61..079270aa1e 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -7001,40 +7001,6 @@ pub const CallOptions = struct { }; }; {#code_end#} - - {#header_open|Calling with a New Stack#} -

- When the {#syntax#}stack{#endsyntax#} option is provided, instead of using the same stack as the caller, the function uses the provided stack. -

- {#code_begin|test|new_stack_call#} -const std = @import("std"); -const assert = std.debug.assert; - -var new_stack_bytes: [1024]u8 align(16) = undefined; - -test "calling a function with a new stack" { - const arg = 1234; - - const a = @call(.{.stack = new_stack_bytes[0..512]}, targetFunction, .{arg}); - const b = @call(.{.stack = new_stack_bytes[512..]}, targetFunction, .{arg}); - _ = targetFunction(arg); - - assert(arg == 1234); - assert(a < b); -} - -fn targetFunction(x: i32) usize { - assert(x == 1234); - - var local_variable: i32 = 42; - const ptr = &local_variable; - ptr.* += 1; - - assert(local_variable == 43); - return @ptrToInt(ptr); -} - {#code_end#} - {#header_close#} {#header_close#} {#header_open|@cDefine#} diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index d8f24753d3..de2b800ea9 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -408,6 +408,8 @@ pub const Version = struct { /// therefore must be kept in sync with the compiler implementation. pub const CallOptions = struct { modifier: Modifier = .auto, + + /// Only valid when `Modifier` is `Modifier.async_kw`. stack: ?[]align(std.Target.stack_align) u8 = null, pub const Modifier = enum { diff --git a/src/all_types.hpp b/src/all_types.hpp index 651ea807ad..368309adcc 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1767,7 +1767,6 @@ enum BuiltinFnId { BuiltinFnIdFieldParentPtr, BuiltinFnIdByteOffsetOf, BuiltinFnIdBitOffsetOf, - BuiltinFnIdNewStackCall, BuiltinFnIdAsyncCall, BuiltinFnIdTypeId, BuiltinFnIdShlExact, diff --git a/src/codegen.cpp b/src/codegen.cpp index 72858a704f..e64a44bd13 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8215,7 +8215,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdNearbyInt, "nearbyInt", 1); create_builtin_fn(g, BuiltinFnIdRound, "round", 1); create_builtin_fn(g, BuiltinFnIdMulAdd, "mulAdd", 4); - create_builtin_fn(g, BuiltinFnIdNewStackCall, "newStackCall", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdAsyncCall, "asyncCall", SIZE_MAX); create_builtin_fn(g, BuiltinFnIdTypeId, "typeId", 1); create_builtin_fn(g, BuiltinFnIdShlExact, "shlExact", 2); diff --git a/src/ir.cpp b/src/ir.cpp index ef3426d111..4742d81b23 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7145,39 +7145,6 @@ static IrInstSrc *ir_gen_builtin_fn_call(IrBuilderSrc *irb, Scope *scope, AstNod IrInstSrc *offset_of = ir_build_bit_offset_of(irb, scope, node, arg0_value, arg1_value); return ir_lval_wrap(irb, scope, offset_of, lval, result_loc); } - case BuiltinFnIdNewStackCall: - { - if (node->data.fn_call_expr.params.length < 2) { - add_node_error(irb->codegen, node, - buf_sprintf("expected at least 2 arguments, found %" ZIG_PRI_usize, - node->data.fn_call_expr.params.length)); - return irb->codegen->invalid_inst_src; - } - - AstNode *new_stack_node = node->data.fn_call_expr.params.at(0); - IrInstSrc *new_stack = ir_gen_node(irb, new_stack_node, scope); - if (new_stack == irb->codegen->invalid_inst_src) - return new_stack; - - AstNode *fn_ref_node = node->data.fn_call_expr.params.at(1); - IrInstSrc *fn_ref = ir_gen_node(irb, fn_ref_node, scope); - if (fn_ref == irb->codegen->invalid_inst_src) - return fn_ref; - - size_t arg_count = node->data.fn_call_expr.params.length - 2; - - IrInstSrc **args = allocate(arg_count); - for (size_t i = 0; i < arg_count; i += 1) { - AstNode *arg_node = node->data.fn_call_expr.params.at(i + 2); - args[i] = ir_gen_node(irb, arg_node, scope); - if (args[i] == irb->codegen->invalid_inst_src) - return args[i]; - } - - IrInstSrc *call = ir_build_call_src(irb, scope, node, nullptr, fn_ref, arg_count, args, - nullptr, CallModifierNone, false, new_stack, result_loc); - return ir_lval_wrap(irb, scope, call, lval, result_loc); - } case BuiltinFnIdCall: { // Cast the options parameter to the options type ZigType *options_type = get_builtin_type(irb->codegen, "CallOptions"); diff --git a/test/stage1/behavior.zig b/test/stage1/behavior.zig index ea8720d98c..a6806e5928 100644 --- a/test/stage1/behavior.zig +++ b/test/stage1/behavior.zig @@ -80,7 +80,6 @@ comptime { _ = @import("behavior/misc.zig"); _ = @import("behavior/muladd.zig"); _ = @import("behavior/namespace_depends_on_compile_var.zig"); - _ = @import("behavior/new_stack_call.zig"); _ = @import("behavior/null.zig"); _ = @import("behavior/optional.zig"); _ = @import("behavior/pointers.zig"); diff --git a/test/stage1/behavior/new_stack_call.zig b/test/stage1/behavior/new_stack_call.zig deleted file mode 100644 index 69763a52c6..0000000000 --- a/test/stage1/behavior/new_stack_call.zig +++ /dev/null @@ -1,38 +0,0 @@ -const std = @import("std"); -const expect = std.testing.expect; - -var new_stack_bytes: [1024]u8 align(16) = undefined; - -test "calling a function with a new stack" { - // TODO: https://github.com/ziglang/zig/issues/3268 - if (@import("builtin").arch == .aarch64) return error.SkipZigTest; - if (@import("builtin").arch == .mipsel) return error.SkipZigTest; - - if (@import("builtin").arch == .riscv64) { - // TODO: https://github.com/ziglang/zig/issues/3338 - return error.SkipZigTest; - } - if (comptime !std.Target.current.supportsNewStackCall()) { - return error.SkipZigTest; - } - - const arg = 1234; - - const a = @call(.{ .stack = new_stack_bytes[0..512] }, targetFunction, .{arg}); - const b = @call(.{ .stack = new_stack_bytes[512..] }, targetFunction, .{arg}); - _ = targetFunction(arg); - - expect(arg == 1234); - expect(a < b); -} - -fn targetFunction(x: i32) usize { - expect(x == 1234); - - var local_variable: i32 = 42; - const ptr = &local_variable; - ptr.* += 1; - - expect(local_variable == 43); - return @ptrToInt(ptr); -} -- cgit v1.2.3 From 8d6536b50cfd43c07c6f0264171db6ecf8e80be5 Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Fri, 7 Feb 2020 17:08:21 +0100 Subject: codegen: Use the new frame-pointer fn attributes no-frame-pointer-elim and no-frame-pointer-elim-non-leaf have been deprecated for a while in favour of the newer (and clearer) frame-pointer attribute. Starting with LLVM10 the old attributes are silently ignored, leading to no stack traces in debug mode. --- src/codegen.cpp | 15 ++---- test/stack_traces.zig | 133 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 95 insertions(+), 53 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src/codegen.cpp b/src/codegen.cpp index e64a44bd13..9a29ba0364 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -564,8 +564,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { add_uwtable_attr(g, llvm_fn); addLLVMFnAttr(llvm_fn, "nobuiltin"); if (codegen_have_frame_pointer(g) && fn->fn_inline != FnInlineAlways) { - ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim", "true"); - ZigLLVMAddFunctionAttr(llvm_fn, "no-frame-pointer-elim-non-leaf", nullptr); + ZigLLVMAddFunctionAttr(llvm_fn, "frame-pointer", "all"); } if (fn->section_name) { LLVMSetSection(llvm_fn, buf_ptr(fn->section_name)); @@ -1128,8 +1127,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { // on any architecture. addLLVMArgAttr(fn_val, (unsigned)0, "nonnull"); if (codegen_have_frame_pointer(g)) { - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); + ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn_val, "Entry"); @@ -1206,8 +1204,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); + ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } // this is above the ZigLLVMClearCurrentDebugLocation @@ -1290,8 +1287,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); + ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } // Not setting alignment here. See the comment above about // "Cannot getTypeInfo() on a type that is unsized!" @@ -4995,8 +4991,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { addLLVMFnAttr(fn_val, "nounwind"); add_uwtable_attr(g, fn_val); if (codegen_have_frame_pointer(g)) { - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim", "true"); - ZigLLVMAddFunctionAttr(fn_val, "no-frame-pointer-elim-non-leaf", nullptr); + ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } LLVMBasicBlockRef prev_block = LLVMGetInsertBlock(g->builder); diff --git a/test/stack_traces.zig b/test/stack_traces.zig index 81e074f01e..cb4d9cfab0 100644 --- a/test/stack_traces.zig +++ b/test/stack_traces.zig @@ -41,6 +41,21 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ try foo(); \\} ; + const source_dumpCurrentStackTrace = + \\const std = @import("std"); + \\ + \\fn bar() void { + \\ std.debug.dumpCurrentStackTrace(@returnAddress()); + \\} + \\fn foo() void { + \\ bar(); + \\} + \\pub fn main() u8 { + \\ foo(); + \\ return 1; + \\} + ; + // zig fmt: off switch (builtin.os) { .freebsd => { @@ -49,25 +64,25 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in main (test) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in std.start.main (test) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -76,7 +91,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in foo (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -86,7 +101,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in std.start.main (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -96,11 +111,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -109,7 +124,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_try_return_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in make_error (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -125,7 +140,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in std.start.main (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -141,11 +156,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -156,25 +171,25 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in main (test) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -183,7 +198,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in foo (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -193,7 +208,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in std.start.posixCallMainAndExit (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -203,11 +218,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -216,7 +231,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_try_return_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in make_error (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -232,7 +247,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in std.start.posixCallMainAndExit (test) \\ return error.TheSkyIsFalling; \\ ^ @@ -248,14 +263,46 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); + cases.addCase( + "dumpCurrentStackTrace", + source_dumpCurrentStackTrace, + [_][]const u8{ + // debug + \\source.zig:7:8: [address] in foo (test) + \\ bar(); + \\ ^ + \\source.zig:10:8: [address] in main (test) + \\ foo(); + \\ ^ + \\start.zig:247:29: [address] in std.start.posixCallMainAndExit (test) + \\ return root.main(); + \\ ^ + \\start.zig:114:5: [address] in std.start._start (test) + \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); + \\ ^ + \\ + , + // release-safe + \\start.zig:114:5: [address] in std.start._start (test) + \\ @call(.{ .modifier = .never_inline }, posixCallMainAndExit, .{}); + \\ ^ + \\ + , + // release-fast + \\ + , + // release-small + \\ + }, + ); }, .macosx => { cases.addCase( @@ -263,25 +310,25 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in _main.0 (test.o) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in _main (test.o) \\ return error.TheSkyIsFalling; \\ ^ \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -290,7 +337,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in _foo (test.o) \\ return error.TheSkyIsFalling; \\ ^ @@ -300,7 +347,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in _main (test.o) \\ return error.TheSkyIsFalling; \\ ^ @@ -310,11 +357,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -323,7 +370,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_try_try_return_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in _make_error (test.o) \\ return error.TheSkyIsFalling; \\ ^ @@ -339,7 +386,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-safe - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:12:5: [address] in _main (test.o) \\ return error.TheSkyIsFalling; \\ ^ @@ -355,11 +402,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { \\ , // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -370,7 +417,7 @@ pub fn addCases(cases: *tests.StackTracesContext) void { source_return, [_][]const u8{ // debug - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\source.zig:4:5: [address] in main (test.obj) \\ return error.TheSkyIsFalling; \\ ^ @@ -380,11 +427,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { // --disabled-- results in segmenetation fault "", // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -406,11 +453,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { // --disabled-- results in segmenetation fault "", // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); @@ -438,11 +485,11 @@ pub fn addCases(cases: *tests.StackTracesContext) void { // --disabled-- results in segmenetation fault "", // release-fast - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ , // release-small - \\error: TheSkyIsFalling + \\error: TheSkyIsFalling \\ }, ); -- cgit v1.2.3 From 94f7c560015f7cb7ed8046339e2d0724dc86fcd6 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Mar 2020 21:47:19 -0400 Subject: riscv: add -mrelax arg for C to work around upstream issue See #4485 --- src-self-hosted/stage2.zig | 27 ++++++++++++++++++ src/analyze.hpp | 8 +++++- src/codegen.cpp | 70 ++++++++++++++++++++++++++++------------------ src/ir.cpp | 2 +- src/stage2.h | 3 ++ 5 files changed, 81 insertions(+), 29 deletions(-) (limited to 'src/codegen.cpp') diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index f67200097c..ff6ef47344 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -912,6 +912,9 @@ const Stage2Target = extern struct { dynamic_linker: ?[*:0]const u8, standard_dynamic_linker_path: ?[*:0]const u8, + llvm_cpu_features_asm_ptr: [*]const [*:0]const u8, + llvm_cpu_features_asm_len: usize, + fn fromTarget(self: *Stage2Target, cross_target: CrossTarget) !void { const allocator = std.heap.c_allocator; @@ -943,6 +946,12 @@ const Stage2Target = extern struct { var llvm_features_buffer = try std.Buffer.initSize(allocator, 0); defer llvm_features_buffer.deinit(); + // Unfortunately we have to do the work twice, because Clang does not support + // the same command line parameters for CPU features when assembling code as it does + // when compiling C code. + var asm_features_list = std.ArrayList([*:0]const u8).init(allocator); + defer asm_features_list.deinit(); + for (target.cpu.arch.allFeaturesList()) |feature, index_usize| { const index = @intCast(Target.Cpu.Feature.Set.Index, index_usize); const is_enabled = target.cpu.features.isEnabled(index); @@ -963,6 +972,21 @@ const Stage2Target = extern struct { } } + switch (target.cpu.arch) { + .riscv32, .riscv64 => { + if (std.Target.riscv.featureSetHas(target.cpu.features, .relax)) { + try asm_features_list.append("-mrelax"); + } else { + try asm_features_list.append("-mno-relax"); + } + }, + else => { + // TODO + // Argh, why doesn't the assembler accept the list of CPU features?! + // I don't see a way to do this other than hard coding everything. + }, + } + try cpu_builtin_str_buffer.append( \\ }), \\}; @@ -1128,6 +1152,7 @@ const Stage2Target = extern struct { null; const cache_hash_slice = cache_hash.toOwnedSlice(); + const asm_features = asm_features_list.toOwnedSlice(); self.* = .{ .arch = @enumToInt(target.cpu.arch) + 1, // skip over ZigLLVM_UnknownArch .vendor = 0, @@ -1135,6 +1160,8 @@ const Stage2Target = extern struct { .abi = @enumToInt(target.abi), .llvm_cpu_name = if (target.cpu.model.llvm_name) |s| s.ptr else null, .llvm_cpu_features = llvm_features_buffer.toOwnedSlice().ptr, + .llvm_cpu_features_asm_ptr = asm_features.ptr, + .llvm_cpu_features_asm_len = asm_features.len, .cpu_builtin_str = cpu_builtin_str_buffer.toOwnedSlice().ptr, .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, .cache_hash = cache_hash_slice.ptr, diff --git a/src/analyze.hpp b/src/analyze.hpp index b6404b1882..a7828663b0 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -257,7 +257,13 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose LLVMTypeRef get_llvm_type(CodeGen *g, ZigType *type); ZigLLVMDIType *get_llvm_di_type(CodeGen *g, ZigType *type); -void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c); +enum CSourceKind { + CSourceKindAsm, + CSourceKindC, +}; + +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c, + CSourceKind source_kind); void src_assert(bool ok, AstNode *source_node); bool is_container(ZigType *type_entry); diff --git a/src/codegen.cpp b/src/codegen.cpp index 7d4262d765..3edc99156f 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -9155,13 +9155,15 @@ static void detect_libc(CodeGen *g) { } // does not add the "cc" arg -void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, bool translate_c) { +void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_path, + bool translate_c, CSourceKind source_kind) +{ if (translate_c) { args.append("-x"); args.append("c"); } - if (out_dep_path != nullptr) { + if (source_kind != CSourceKindAsm && out_dep_path != nullptr) { args.append("-MD"); args.append("-MV"); args.append("-MF"); @@ -9176,10 +9178,12 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa } if (translate_c) { - // this gives us access to preprocessing entities, presumably at - // the cost of performance - args.append("-Xclang"); - args.append("-detailed-preprocessing-record"); + if (source_kind == CSourceKindC) { + // this gives us access to preprocessing entities, presumably at + // the cost of performance + args.append("-Xclang"); + args.append("-detailed-preprocessing-record"); + } } else { switch (g->err_color) { case ErrColorAuto: @@ -9212,26 +9216,29 @@ void add_cc_args(CodeGen *g, ZigList &args, const char *out_dep_pa args.append(include_dir); } - if (g->zig_target->is_native) { - if (target_supports_clang_march_native(g->zig_target)) { - args.append("-march=native"); - } - } else { - args.append("-target"); - args.append(buf_ptr(&g->llvm_triple_str)); + args.append("-target"); + args.append(buf_ptr(&g->llvm_triple_str)); - if (g->zig_target->llvm_cpu_name != nullptr) { - args.append("-Xclang"); - args.append("-target-cpu"); - args.append("-Xclang"); - args.append(g->zig_target->llvm_cpu_name); - } - if (g->zig_target->llvm_cpu_features != nullptr) { - args.append("-Xclang"); - args.append("-target-feature"); - args.append("-Xclang"); - args.append(g->zig_target->llvm_cpu_features); - } + switch (source_kind) { + case CSourceKindC: + if (g->zig_target->llvm_cpu_name != nullptr) { + args.append("-Xclang"); + args.append("-target-cpu"); + args.append("-Xclang"); + args.append(g->zig_target->llvm_cpu_name); + } + if (g->zig_target->llvm_cpu_features != nullptr) { + args.append("-Xclang"); + args.append("-target-feature"); + args.append("-Xclang"); + args.append(g->zig_target->llvm_cpu_features); + } + break; + case CSourceKindAsm: + break; + } + for (size_t i = 0; i < g->zig_target->llvm_cpu_features_asm_len; i += 1) { + args.append(g->zig_target->llvm_cpu_features_asm_ptr[i]); } if (g->zig_target->os == OsFreestanding) { @@ -9377,7 +9384,7 @@ void codegen_translate_c(CodeGen *g, Buf *full_path) { } ZigList clang_argv = {0}; - add_cc_args(g, clang_argv, out_dep_path_cstr, true); + add_cc_args(g, clang_argv, out_dep_path_cstr, true, CSourceKindC); clang_argv.append(buf_ptr(full_path)); @@ -9714,6 +9721,15 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { Buf *c_source_basename = buf_alloc(); os_path_split(c_source_file, nullptr, c_source_basename); + CSourceKind c_source_kind; + if (buf_ends_with_str(c_source_basename, ".s") || + buf_ends_with_str(c_source_basename, ".S")) + { + c_source_kind = CSourceKindAsm; + } else { + c_source_kind = CSourceKindC; + } + Stage2ProgressNode *child_prog_node = stage2_progress_start(g->sub_progress_node, buf_ptr(c_source_basename), buf_len(c_source_basename), 0); @@ -9786,7 +9802,7 @@ static void gen_c_object(CodeGen *g, Buf *self_exe_path, CFile *c_file) { } Buf *out_dep_path = buf_sprintf("%s.d", buf_ptr(out_obj_path)); - add_cc_args(g, args, buf_ptr(out_dep_path), false); + add_cc_args(g, args, buf_ptr(out_dep_path), false, c_source_kind); args.append("-o"); args.append(buf_ptr(out_obj_path)); diff --git a/src/ir.cpp b/src/ir.cpp index c8a60c3e57..913cd69cfe 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -25126,7 +25126,7 @@ static IrInstGen *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstSrcCImpo ZigList clang_argv = {0}; - add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true); + add_cc_args(ira->codegen, clang_argv, buf_ptr(tmp_dep_file), true, CSourceKindC); clang_argv.append(buf_ptr(&tmp_c_file_path)); diff --git a/src/stage2.h b/src/stage2.h index a66163eceb..8893b1e27b 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -293,6 +293,9 @@ struct ZigTarget { const char *os_builtin_str; const char *dynamic_linker; const char *standard_dynamic_linker_path; + + const char **llvm_cpu_features_asm_ptr; + size_t llvm_cpu_features_asm_len; }; // ABI warning -- cgit v1.2.3 From fae6cf09619e7a8e64f61b84cca7d9fcd471262f Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 25 Mar 2020 20:32:40 -0400 Subject: improved handling of native system directories * `-isystem` instead of `-I` for system include directories fixes a problem with native system directories interfering with zig's bundled libc. * separate Stage2Target.is_native into Stage2Target.is_native_os and Stage2Target.is_native_cpu. --- lib/std/zig/cross_target.zig | 15 +++++++++++---- src-self-hosted/stage2.zig | 6 ++++-- src/codegen.cpp | 15 +++++++++------ src/link.cpp | 6 +++--- src/main.cpp | 12 ++++++++++-- src/stage2.cpp | 6 ++++-- src/stage2.h | 3 ++- src/target.cpp | 3 ++- 8 files changed, 45 insertions(+), 21 deletions(-) (limited to 'src/codegen.cpp') diff --git a/lib/std/zig/cross_target.zig b/lib/std/zig/cross_target.zig index 130e8cdbc1..bea69b3978 100644 --- a/lib/std/zig/cross_target.zig +++ b/lib/std/zig/cross_target.zig @@ -480,12 +480,19 @@ pub const CrossTarget = struct { return Target.libPrefix_cpu_arch_abi(self.getCpuArch(), self.getAbi()); } - pub fn isNative(self: CrossTarget) bool { + pub fn isNativeCpu(self: CrossTarget) bool { return self.cpu_arch == null and (self.cpu_model == .native or self.cpu_model == .determined_by_cpu_arch) and - self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty() and - self.os_tag == null and self.os_version_min == null and self.os_version_max == null and - self.abi == null and self.dynamic_linker.get() == null and self.glibc_version == null; + self.cpu_features_sub.isEmpty() and self.cpu_features_add.isEmpty(); + } + + pub fn isNativeOs(self: CrossTarget) bool { + return self.os_tag == null and self.os_version_min == null and self.os_version_max == null and + self.dynamic_linker.get() == null and self.glibc_version == null; + } + + pub fn isNative(self: CrossTarget) bool { + return self.isNativeCpu() and self.isNativeOs() and self.abi == null; } pub fn zigTriple(self: CrossTarget, allocator: *mem.Allocator) error{OutOfMemory}![:0]u8 { diff --git a/src-self-hosted/stage2.zig b/src-self-hosted/stage2.zig index 03cdcc5b08..cd0956cae3 100644 --- a/src-self-hosted/stage2.zig +++ b/src-self-hosted/stage2.zig @@ -898,7 +898,8 @@ const Stage2Target = extern struct { abi: c_int, os: c_int, - is_native: bool, + is_native_os: bool, + is_native_cpu: bool, glibc_or_darwin_version: ?*Stage2SemVer, @@ -1166,7 +1167,8 @@ const Stage2Target = extern struct { .os_builtin_str = os_builtin_str_buffer.toOwnedSlice().ptr, .cache_hash = cache_hash_slice.ptr, .cache_hash_len = cache_hash_slice.len, - .is_native = cross_target.isNative(), + .is_native_os = cross_target.isNativeOs(), + .is_native_cpu = cross_target.isNativeCpu(), .glibc_or_darwin_version = glibc_or_darwin_version, .dynamic_linker = dynamic_linker, .standard_dynamic_linker_path = std_dl_z, diff --git a/src/codegen.cpp b/src/codegen.cpp index 3edc99156f..cb1ab6b6b8 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -8782,7 +8782,8 @@ static Error define_builtin_compile_vars(CodeGen *g) { cache_bool(&cache_hash, g->is_single_threaded); cache_bool(&cache_hash, g->test_is_evented); cache_int(&cache_hash, g->code_model); - cache_int(&cache_hash, g->zig_target->is_native); + cache_int(&cache_hash, g->zig_target->is_native_os); + cache_int(&cache_hash, g->zig_target->is_native_cpu); cache_int(&cache_hash, g->zig_target->arch); cache_int(&cache_hash, g->zig_target->vendor); cache_int(&cache_hash, g->zig_target->os); @@ -8917,7 +8918,7 @@ static void init(CodeGen *g) { const char *target_specific_cpu_args = ""; const char *target_specific_features = ""; - if (g->zig_target->is_native) { + if (g->zig_target->is_native_cpu) { target_specific_cpu_args = ZigLLVMGetHostCPUName(); target_specific_features = ZigLLVMGetNativeFeatures(); } @@ -9034,7 +9035,7 @@ static void detect_libc(CodeGen *g) { return; } - if (g->zig_target->is_native) { + if (g->zig_target->is_native_os) { g->libc = heap::c_allocator.create(); // search for native_libc.txt in following dirs: @@ -9672,7 +9673,8 @@ Error create_c_object_cache(CodeGen *g, CacheHash **out_cache_hash, bool verbose cache_int(cache_hash, g->err_color); cache_buf(cache_hash, g->zig_c_headers_dir); cache_list_of_str(cache_hash, g->libc_include_dir_list, g->libc_include_dir_len); - cache_int(cache_hash, g->zig_target->is_native); + cache_int(cache_hash, g->zig_target->is_native_os); + cache_int(cache_hash, g->zig_target->is_native_cpu); cache_int(cache_hash, g->zig_target->arch); cache_int(cache_hash, g->zig_target->vendor); cache_int(cache_hash, g->zig_target->os); @@ -10474,7 +10476,8 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_list_of_buf(ch, g->forbidden_libs.items, g->forbidden_libs.length); cache_int(ch, g->build_mode); cache_int(ch, g->out_type); - cache_bool(ch, g->zig_target->is_native); + cache_bool(ch, g->zig_target->is_native_os); + cache_bool(ch, g->zig_target->is_native_cpu); cache_int(ch, g->zig_target->arch); cache_int(ch, g->zig_target->vendor); cache_int(ch, g->zig_target->os); @@ -10941,7 +10944,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget os_path_join(g->zig_std_dir, buf_sprintf("special"), g->zig_std_special_dir); assert(target != nullptr); - if (!target->is_native) { + if (!target->is_native_os) { g->each_lib_rpath = false; } else { g->each_lib_rpath = true; diff --git a/src/link.cpp b/src/link.cpp index d39736e2a7..25b913be21 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -635,7 +635,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress c_file->args.append("-fPIC"); c_file->args.append("-D_LIBUNWIND_DISABLE_VISIBILITY_ANNOTATIONS"); c_file->args.append("-Wa,--noexecstack"); - if (parent->zig_target->is_native) { + if (parent->zig_target->is_native_os && parent->zig_target->is_native_cpu) { c_file->args.append("-D_LIBUNWIND_IS_NATIVE_ONLY"); } if (parent->build_mode == BuildModeDebug) { @@ -1829,7 +1829,7 @@ static void construct_linker_job_elf(LinkJob *lj) { } } - if (!g->zig_target->is_native) { + if (!g->zig_target->is_native_os) { lj->args.append("--allow-shlib-undefined"); } } @@ -2460,7 +2460,7 @@ static void construct_linker_job_macho(LinkJob *lj) { lj->args.append(buf_ptr(compiler_rt_o_path)); } - if (g->zig_target->is_native) { + if (g->zig_target->is_native_os) { for (size_t lib_i = 0; lib_i < g->link_libs_list.length; lib_i += 1) { LinkLib *link_lib = g->link_libs_list.at(lib_i); if (target_is_libc_lib_name(g->zig_target, buf_ptr(link_lib->name))) { diff --git a/src/main.cpp b/src/main.cpp index dd7cdead6c..a543b43579 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1325,7 +1325,15 @@ static int main0(int argc, char **argv) { return print_error_usage(arg0); } - if (target.is_native && link_libs.length != 0) { + bool any_non_c_link_libs = false; + for (size_t i = 0; i < link_libs.length; i += 1) { + if (!target_is_libc_lib_name(&target, link_libs.at(i))) { + any_non_c_link_libs = true; + break; + } + } + + if (target.is_native_os && any_non_c_link_libs) { Error err; Stage2NativePaths paths; if ((err = stage2_detect_native_paths(&paths))) { @@ -1338,7 +1346,7 @@ static int main0(int argc, char **argv) { } for (size_t i = 0; i < paths.include_dirs_len; i += 1) { const char *include_dir = paths.include_dirs_ptr[i]; - clang_argv.append("-I"); + clang_argv.append("-isystem"); clang_argv.append(include_dir); } for (size_t i = 0; i < paths.lib_dirs_len; i += 1) { diff --git a/src/stage2.cpp b/src/stage2.cpp index c83b1aa77c..f8a485f93b 100644 --- a/src/stage2.cpp +++ b/src/stage2.cpp @@ -181,7 +181,8 @@ static void get_native_target(ZigTarget *target) { &target->abi, &oformat); target->os = get_zig_os_type(os_type); - target->is_native = true; + target->is_native_os = true; + target->is_native_cpu = true; if (target->abi == ZigLLVM_UnknownEnvironment) { target->abi = target_default_abi(target->arch, target->os); } @@ -204,7 +205,8 @@ Error stage2_target_parse(struct ZigTarget *target, const char *zig_triple, cons target->llvm_cpu_features = ZigLLVMGetNativeFeatures(); target->cache_hash = "native\n\n"; } else if (strcmp(mcpu, "baseline") == 0) { - target->is_native = false; + target->is_native_os = false; + target->is_native_cpu = false; target->llvm_cpu_name = ""; target->llvm_cpu_features = ""; target->cache_hash = "baseline\n\n"; diff --git a/src/stage2.h b/src/stage2.h index 00a3b9451e..4b86fdc059 100644 --- a/src/stage2.h +++ b/src/stage2.h @@ -280,7 +280,8 @@ struct ZigTarget { enum ZigLLVM_EnvironmentType abi; Os os; - bool is_native; + bool is_native_os; + bool is_native_cpu; // null means default. this is double-purposed to be darwin min version struct Stage2SemVer *glibc_or_darwin_version; diff --git a/src/target.cpp b/src/target.cpp index db1e4be809..63360fc029 100644 --- a/src/target.cpp +++ b/src/target.cpp @@ -1239,7 +1239,8 @@ void target_libc_enum(size_t index, ZigTarget *out_target) { out_target->os = libcs_available[index].os; out_target->abi = libcs_available[index].abi; out_target->vendor = ZigLLVM_UnknownVendor; - out_target->is_native = false; + out_target->is_native_os = false; + out_target->is_native_cpu = false; } bool target_has_debug_info(const ZigTarget *target) { -- cgit v1.2.3