aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Compilation.zig13
-rw-r--r--src/clang_options_data.zig18
-rw-r--r--src/codegen/llvm.zig25
-rw-r--r--src/codegen/llvm/bindings.zig3
-rw-r--r--src/glibc.zig1
-rw-r--r--src/libcxx.zig2
-rw-r--r--src/libunwind.zig1
-rw-r--r--src/link.zig1
-rw-r--r--src/main.zig12
-rw-r--r--src/musl.zig1
-rw-r--r--src/stage1.zig1
-rw-r--r--src/stage1/all_types.hpp1
-rw-r--r--src/stage1/codegen.cpp16
-rw-r--r--src/stage1/stage1.cpp1
-rw-r--r--src/stage1/stage1.h1
15 files changed, 85 insertions, 12 deletions
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;