diff options
| -rw-r--r-- | lib/std/build.zig | 9 | ||||
| -rw-r--r-- | src/Compilation.zig | 13 | ||||
| -rw-r--r-- | src/clang_options_data.zig | 18 | ||||
| -rw-r--r-- | src/codegen/llvm.zig | 25 | ||||
| -rw-r--r-- | src/codegen/llvm/bindings.zig | 3 | ||||
| -rw-r--r-- | src/glibc.zig | 1 | ||||
| -rw-r--r-- | src/libcxx.zig | 2 | ||||
| -rw-r--r-- | src/libunwind.zig | 1 | ||||
| -rw-r--r-- | src/link.zig | 1 | ||||
| -rw-r--r-- | src/main.zig | 12 | ||||
| -rw-r--r-- | src/musl.zig | 1 | ||||
| -rw-r--r-- | src/stage1.zig | 1 | ||||
| -rw-r--r-- | src/stage1/all_types.hpp | 1 | ||||
| -rw-r--r-- | src/stage1/codegen.cpp | 16 | ||||
| -rw-r--r-- | src/stage1/stage1.cpp | 1 | ||||
| -rw-r--r-- | src/stage1/stage1.h | 1 | ||||
| -rw-r--r-- | tools/update_clang_options.zig | 8 |
17 files changed, 102 insertions, 12 deletions
diff --git a/lib/std/build.zig b/lib/std/build.zig index 228c50cd20..a2b9aa3030 100644 --- a/lib/std/build.zig +++ b/lib/std/build.zig @@ -1515,6 +1515,8 @@ pub const LibExeObjStep = struct { red_zone: ?bool = null, + omit_frame_pointer: ?bool = null, + subsystem: ?std.Target.SubSystem = null, /// Overrides the default stack size @@ -2406,6 +2408,13 @@ pub const LibExeObjStep = struct { try zig_args.append("-mno-red-zone"); } } + if (self.omit_frame_pointer) |omit_frame_pointer| { + if (omit_frame_pointer) { + try zig_args.append("-fomit-frame-pointer"); + } else { + try zig_args.append("-fno-omit-frame-pointer"); + } + } if (self.disable_sanitize_c) { try zig_args.append("-fno-sanitize-c"); } diff --git a/src/Compilation.zig b/src/Compilation.zig index a7a76633ab..50d9376c58 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -688,6 +688,7 @@ pub const InitOptions = struct { want_sanitize_c: ?bool = null, want_stack_check: ?bool = null, want_red_zone: ?bool = null, + omit_frame_pointer: ?bool = null, want_valgrind: ?bool = null, want_tsan: ?bool = null, want_compiler_rt: ?bool = null, @@ -1123,6 +1124,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { const strip = options.strip or !target_util.hasDebugInfo(options.target); const red_zone = options.want_red_zone orelse target_util.hasRedZone(options.target); + const omit_frame_pointer = options.omit_frame_pointer orelse (options.optimize_mode != .Debug); // We put everything into the cache hash that *cannot be modified during an incremental update*. // For example, one cannot change the target between updates, but one can change source files, @@ -1156,6 +1158,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { cache.hash.add(tsan); cache.hash.add(stack_check); cache.hash.add(red_zone); + cache.hash.add(omit_frame_pointer); cache.hash.add(link_mode); cache.hash.add(options.function_sections); cache.hash.add(strip); @@ -1426,6 +1429,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation { .tsan = tsan, .stack_check = stack_check, .red_zone = red_zone, + .omit_frame_pointer = omit_frame_pointer, .single_threaded = single_threaded, .verbose_link = options.verbose_link, .machine_code_model = options.machine_code_model, @@ -3292,6 +3296,12 @@ pub fn addCCArgs( try argv.append("-mno-red-zone"); } + if (comp.bin_file.options.omit_frame_pointer) { + try argv.append("-fomit-frame-pointer"); + } else { + try argv.append("-fno-omit-frame-pointer"); + } + switch (comp.bin_file.options.optimize_mode) { .Debug => { // windows c runtime requires -D_DEBUG if using debug libraries @@ -4122,6 +4132,7 @@ fn buildOutputFromZig( .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, @@ -4405,6 +4416,7 @@ fn updateStage1Module(comp: *Compilation, main_progress_node: *std.Progress.Node .include_compiler_rt = include_compiler_rt, .enable_stack_probing = comp.bin_file.options.stack_check, .red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .enable_time_report = comp.time_report, .enable_stack_report = comp.stack_report, .test_is_evented = comp.test_evented_io, @@ -4554,6 +4566,7 @@ pub fn build_crt_file( .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, diff --git a/src/clang_options_data.zig b/src/clang_options_data.zig index ecaa383b69..e027d2471c 100644 --- a/src/clang_options_data.zig +++ b/src/clang_options_data.zig @@ -3014,7 +3014,14 @@ flagpd1("fno-objc-infer-related-result-type"), flagpd1("fno-objc-legacy-dispatch"), flagpd1("fno-objc-nonfragile-abi"), flagpd1("fno-objc-weak"), -flagpd1("fno-omit-frame-pointer"), +.{ + .name = "fno-omit-frame-pointer", + .syntax = .flag, + .zig_equivalent = .no_omit_frame_pointer, + .pd1 = true, + .pd2 = false, + .psl = false, +}, flagpd1("fno-openmp"), flagpd1("fno-openmp-cuda-force-full-runtime"), flagpd1("fno-openmp-cuda-mode"), @@ -3235,7 +3242,14 @@ flagpd1("fobjc-runtime-has-weak"), flagpd1("fobjc-sender-dependent-dispatch"), flagpd1("fobjc-subscripting-legacy-runtime"), flagpd1("fobjc-weak"), -flagpd1("fomit-frame-pointer"), +.{ + .name = "fomit-frame-pointer", + .syntax = .flag, + .zig_equivalent = .omit_frame_pointer, + .pd1 = true, + .pd2 = false, + .psl = false, +}, flagpd1("fopenmp"), flagpd1("fopenmp-cuda-force-full-runtime"), flagpd1("fopenmp-cuda-mode"), diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 80f2d8b653..80625928cb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -668,6 +668,11 @@ pub const DeclGen = struct { if (!dg.module.comp.bin_file.options.red_zone) { dg.addFnAttr(llvm_fn, "noredzone"); } + if (dg.module.comp.bin_file.options.omit_frame_pointer) { + dg.addFnAttrString(llvm_fn, "frame-pointer", "none"); + } else { + dg.addFnAttrString(llvm_fn, "frame-pointer", "all"); + } dg.addFnAttr(llvm_fn, "nounwind"); if (dg.module.comp.unwind_tables) { dg.addFnAttr(llvm_fn, "uwtable"); @@ -1541,10 +1546,30 @@ pub const DeclGen = struct { val.addAttributeAtIndex(index, llvm_attr); } + fn addAttrString( + dg: *DeclGen, + val: *const llvm.Value, + index: llvm.AttributeIndex, + name: []const u8, + value: []const u8, + ) void { + const llvm_attr = dg.context.createStringAttribute( + name.ptr, + @intCast(c_uint, name.len), + value.ptr, + @intCast(c_uint, value.len), + ); + val.addAttributeAtIndex(index, llvm_attr); + } + fn addFnAttr(dg: DeclGen, val: *const llvm.Value, name: []const u8) void { dg.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name); } + fn addFnAttrString(dg: *DeclGen, val: *const llvm.Value, name: []const u8, value: []const u8) void { + dg.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value); + } + fn removeFnAttr(fn_val: *const llvm.Value, name: []const u8) void { removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name); } diff --git a/src/codegen/llvm/bindings.zig b/src/codegen/llvm/bindings.zig index 9a62fa791f..43aca87532 100644 --- a/src/codegen/llvm/bindings.zig +++ b/src/codegen/llvm/bindings.zig @@ -28,6 +28,9 @@ pub const Context = opaque { pub const createEnumAttribute = LLVMCreateEnumAttribute; extern fn LLVMCreateEnumAttribute(*const Context, KindID: c_uint, Val: u64) *const Attribute; + pub const createStringAttribute = LLVMCreateStringAttribute; + extern fn LLVMCreateStringAttribute(*const Context, Key: [*]const u8, Key_Len: c_uint, Value: [*]const u8, Value_Len: c_uint) *const Attribute; + pub const intType = LLVMIntTypeInContext; extern fn LLVMIntTypeInContext(C: *const Context, NumBits: c_uint) *const Type; diff --git a/src/glibc.zig b/src/glibc.zig index aed1a24437..049db4f870 100644 --- a/src/glibc.zig +++ b/src/glibc.zig @@ -953,6 +953,7 @@ fn buildSharedLib( .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = false, .emit_h = null, diff --git a/src/libcxx.zig b/src/libcxx.zig index 2cff5d738a..0fa0a8fc75 100644 --- a/src/libcxx.zig +++ b/src/libcxx.zig @@ -189,6 +189,7 @@ pub fn buildLibCXX(comp: *Compilation) !void { .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = comp.bin_file.options.tsan, .want_pic = comp.bin_file.options.pic, @@ -321,6 +322,7 @@ pub fn buildLibCXXABI(comp: *Compilation) !void { .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = comp.bin_file.options.tsan, .want_pic = comp.bin_file.options.pic, diff --git a/src/libunwind.zig b/src/libunwind.zig index 192f9ac2d2..50c329c6d6 100644 --- a/src/libunwind.zig +++ b/src/libunwind.zig @@ -113,6 +113,7 @@ pub fn buildStaticLib(comp: *Compilation) !void { .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = false, .want_pic = comp.bin_file.options.pic, diff --git a/src/link.zig b/src/link.zig index 8cb2c4a485..a1df48f759 100644 --- a/src/link.zig +++ b/src/link.zig @@ -90,6 +90,7 @@ pub const Options = struct { tsan: bool, stack_check: bool, red_zone: bool, + omit_frame_pointer: bool, single_threaded: bool, verbose_link: bool, dll_export_fns: bool, diff --git a/src/main.zig b/src/main.zig index 61380303e1..a2dd8d1d96 100644 --- a/src/main.zig +++ b/src/main.zig @@ -323,6 +323,8 @@ const usage_build_generic = \\ medium|large] \\ -mred-zone Force-enable the "red-zone" \\ -mno-red-zone Force-disable the "red-zone" + \\ -fomit-frame-pointer Omit the stack frame pointer + \\ -fno-omit-frame-pointer Store the stack frame pointer \\ -mexec-model=[value] Execution model (WASI only) \\ --name [name] Override root name (not a file path) \\ -O [mode] Choose what to optimize for @@ -581,6 +583,7 @@ fn buildOutputType( var want_sanitize_c: ?bool = null; var want_stack_check: ?bool = null; var want_red_zone: ?bool = null; + var omit_frame_pointer: ?bool = null; var want_valgrind: ?bool = null; var want_tsan: ?bool = null; var want_compiler_rt: ?bool = null; @@ -976,6 +979,10 @@ fn buildOutputType( want_red_zone = true; } else if (mem.eql(u8, arg, "-mno-red-zone")) { want_red_zone = false; + } else if (mem.eql(u8, arg, "-fomit-frame-pointer")) { + omit_frame_pointer = true; + } else if (mem.eql(u8, arg, "-fno-omit-frame-pointer")) { + omit_frame_pointer = false; } else if (mem.eql(u8, arg, "-fsanitize-c")) { want_sanitize_c = true; } else if (mem.eql(u8, arg, "-fno-sanitize-c")) { @@ -1217,6 +1224,8 @@ fn buildOutputType( .no_lto => want_lto = false, .red_zone => want_red_zone = true, .no_red_zone => want_red_zone = false, + .omit_frame_pointer => omit_frame_pointer = true, + .no_omit_frame_pointer => omit_frame_pointer = false, .unwind_tables => want_unwind_tables = true, .no_unwind_tables => want_unwind_tables = false, .nostdlib => ensure_libc_on_non_freestanding = false, @@ -2082,6 +2091,7 @@ fn buildOutputType( .want_sanitize_c = want_sanitize_c, .want_stack_check = want_stack_check, .want_red_zone = want_red_zone, + .omit_frame_pointer = omit_frame_pointer, .want_valgrind = want_valgrind, .want_tsan = want_tsan, .want_compiler_rt = want_compiler_rt, @@ -3708,6 +3718,8 @@ pub const ClangArgIterator = struct { nostdlibinc, red_zone, no_red_zone, + omit_frame_pointer, + no_omit_frame_pointer, strip, exec_model, emit_llvm, diff --git a/src/musl.zig b/src/musl.zig index 3b5915719b..d0f11af604 100644 --- a/src/musl.zig +++ b/src/musl.zig @@ -207,6 +207,7 @@ pub fn buildCRTFile(comp: *Compilation, crt_file: CRTFile) !void { .want_sanitize_c = false, .want_stack_check = false, .want_red_zone = comp.bin_file.options.red_zone, + .omit_frame_pointer = comp.bin_file.options.omit_frame_pointer, .want_valgrind = false, .want_tsan = false, .emit_h = null, diff --git a/src/stage1.zig b/src/stage1.zig index 8ebc876665..467f0e69d7 100644 --- a/src/stage1.zig +++ b/src/stage1.zig @@ -128,6 +128,7 @@ pub const Module = extern struct { include_compiler_rt: bool, enable_stack_probing: bool, red_zone: bool, + omit_frame_pointer: bool, enable_time_report: bool, enable_stack_report: bool, test_is_evented: bool, diff --git a/src/stage1/all_types.hpp b/src/stage1/all_types.hpp index 5b58766df9..284a5a5468 100644 --- a/src/stage1/all_types.hpp +++ b/src/stage1/all_types.hpp @@ -2175,6 +2175,7 @@ struct CodeGen { bool dll_export_fns; bool have_stack_probing; bool red_zone; + bool omit_frame_pointer; bool function_sections; bool include_compiler_rt; bool test_is_evented; diff --git a/src/stage1/codegen.cpp b/src/stage1/codegen.cpp index 91e9f55aa7..047fb54b85 100644 --- a/src/stage1/codegen.cpp +++ b/src/stage1/codegen.cpp @@ -363,10 +363,6 @@ static bool cc_want_sret_attr(CallingConvention cc) { zig_unreachable(); } -static bool codegen_have_frame_pointer(CodeGen *g) { - return g->build_mode == BuildModeDebug; -} - static void add_common_fn_attributes(CodeGen *g, LLVMValueRef llvm_fn) { if (!g->red_zone) { addLLVMFnAttr(llvm_fn, "noredzone"); @@ -603,7 +599,7 @@ static LLVMValueRef make_fn_llvm_value(CodeGen *g, ZigFn *fn) { addLLVMFnAttrInt(llvm_fn, "alignstack", fn->alignstack_value); } - if (codegen_have_frame_pointer(g) && cc != CallingConventionInline) { + if (!g->omit_frame_pointer && cc != CallingConventionInline) { ZigLLVMAddFunctionAttr(llvm_fn, "frame-pointer", "all"); } if (fn->section_name) { @@ -1223,7 +1219,7 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { // Error return trace memory is in the stack, which is impossible to be at address 0 // on any architecture. addLLVMArgAttr(fn_val, (unsigned)0, "nonnull"); - if (codegen_have_frame_pointer(g)) { + if (!g->omit_frame_pointer) { ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } @@ -1299,7 +1295,7 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { LLVMSetLinkage(fn_val, LLVMInternalLinkage); ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); add_common_fn_attributes(g, fn_val); - if (codegen_have_frame_pointer(g)) { + if (!g->omit_frame_pointer) { ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } @@ -1381,7 +1377,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { LLVMSetLinkage(fn_val, LLVMInternalLinkage); ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); add_common_fn_attributes(g, fn_val); - if (codegen_have_frame_pointer(g)) { + if (!g->omit_frame_pointer) { ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } // Not setting alignment here. See the comment above about @@ -2389,7 +2385,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { addLLVMArgAttr(fn_val, (unsigned)1, "noalias"); addLLVMArgAttr(fn_val, (unsigned)1, "readonly"); - if (codegen_have_frame_pointer(g)) { + if (!g->omit_frame_pointer) { ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } @@ -5418,7 +5414,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { LLVMSetLinkage(fn_val, LLVMInternalLinkage); ZigLLVMFunctionSetCallingConv(fn_val, get_llvm_cc(g, CallingConventionUnspecified)); add_common_fn_attributes(g, fn_val); - if (codegen_have_frame_pointer(g)) { + if (!g->omit_frame_pointer) { ZigLLVMAddFunctionAttr(fn_val, "frame-pointer", "all"); } diff --git a/src/stage1/stage1.cpp b/src/stage1/stage1.cpp index 118747e79e..856bb61dcb 100644 --- a/src/stage1/stage1.cpp +++ b/src/stage1/stage1.cpp @@ -95,6 +95,7 @@ void zig_stage1_build_object(struct ZigStage1 *stage1) { g->unwind_tables = stage1->unwind_tables; g->have_stack_probing = stage1->enable_stack_probing; g->red_zone = stage1->red_zone; + g->omit_frame_pointer = stage1->omit_frame_pointer; g->is_single_threaded = stage1->is_single_threaded; g->valgrind_enabled = stage1->valgrind_enabled; g->tsan_enabled = stage1->tsan_enabled; diff --git a/src/stage1/stage1.h b/src/stage1/stage1.h index b3d4893747..ce8254eaef 100644 --- a/src/stage1/stage1.h +++ b/src/stage1/stage1.h @@ -199,6 +199,7 @@ struct ZigStage1 { bool include_compiler_rt; bool enable_stack_probing; bool red_zone; + bool omit_frame_pointer; bool enable_time_report; bool enable_stack_report; bool test_is_evented; diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index 2a0da66578..361d28cfa0 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -301,6 +301,14 @@ const known_options = [_]KnownOpt{ .ident = "no_red_zone", }, .{ + .name = "fomit-frame-pointer", + .ident = "omit_frame_pointer", + }, + .{ + .name = "fno-omit-frame-pointer", + .ident = "no_omit_frame_pointer", + }, + .{ .name = "MD", .ident = "dep_file", }, |
