cranelift: Add a flag for preserving frame pointers (#4469)
Preserving frame pointers -- even inside leaf functions -- makes it easy to capture the stack of a running program, without requiring any side tables or metadata (like `.eh_frame` sections). Many sampling profilers and similar tools walk frame pointers to capture stacks. Enabling this option will play nice with those tools.
This commit is contained in:
@@ -237,6 +237,19 @@ pub(crate) fn define() -> SettingGroup {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
settings.add_bool(
|
||||||
|
"preserve_frame_pointers",
|
||||||
|
"Preserve frame pointers",
|
||||||
|
r#"
|
||||||
|
Preserving frame pointers -- even inside leaf functions -- makes it
|
||||||
|
easy to capture the stack of a running program, without requiring any
|
||||||
|
side tables or metadata (like `.eh_frame` sections). Many sampling
|
||||||
|
profilers and similar tools walk frame pointers to capture stacks.
|
||||||
|
Enabling this option will play nice with those tools.
|
||||||
|
"#,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
|
||||||
settings.add_bool(
|
settings.add_bool(
|
||||||
"machine_code_cfg_info",
|
"machine_code_cfg_info",
|
||||||
"Generate CFG metadata for machine code.",
|
"Generate CFG metadata for machine code.",
|
||||||
|
|||||||
@@ -1410,12 +1410,13 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
|
|||||||
|
|
||||||
if !self.call_conv.extends_baldrdash() {
|
if !self.call_conv.extends_baldrdash() {
|
||||||
self.fixed_frame_storage_size += total_stacksize;
|
self.fixed_frame_storage_size += total_stacksize;
|
||||||
self.setup_frame = M::is_frame_setup_needed(
|
self.setup_frame = self.flags.preserve_frame_pointers()
|
||||||
self.is_leaf,
|
|| M::is_frame_setup_needed(
|
||||||
self.stack_args_size(),
|
self.is_leaf,
|
||||||
clobbered_callee_saves.len(),
|
self.stack_args_size(),
|
||||||
self.fixed_frame_storage_size,
|
clobbered_callee_saves.len(),
|
||||||
);
|
self.fixed_frame_storage_size,
|
||||||
|
);
|
||||||
|
|
||||||
insts.extend(
|
insts.extend(
|
||||||
M::gen_debug_frame_info(self.call_conv, &self.flags, &self.isa_flags).into_iter(),
|
M::gen_debug_frame_info(self.call_conv, &self.flags, &self.isa_flags).into_iter(),
|
||||||
|
|||||||
@@ -541,6 +541,7 @@ enable_atomics = true
|
|||||||
enable_safepoints = false
|
enable_safepoints = false
|
||||||
enable_llvm_abi_extensions = false
|
enable_llvm_abi_extensions = false
|
||||||
unwind_info = true
|
unwind_info = true
|
||||||
|
preserve_frame_pointers = false
|
||||||
machine_code_cfg_info = false
|
machine_code_cfg_info = false
|
||||||
emit_all_ones_funcaddrs = false
|
emit_all_ones_funcaddrs = false
|
||||||
enable_probestack = true
|
enable_probestack = true
|
||||||
|
|||||||
15
cranelift/filetests/filetests/isa/aarch64/leaf.clif
Normal file
15
cranelift/filetests/filetests/isa/aarch64/leaf.clif
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
;; Test compilation of leaf functions without preserving frame pointers.
|
||||||
|
|
||||||
|
test compile precise-output
|
||||||
|
set unwind_info=false
|
||||||
|
set preserve_frame_pointers=false
|
||||||
|
target aarch64
|
||||||
|
|
||||||
|
function %leaf(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
return v0
|
||||||
|
}
|
||||||
|
|
||||||
|
; block0:
|
||||||
|
; ret
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
;; Test compilation of leaf functions while preserving frame pointers.
|
||||||
|
|
||||||
|
test compile precise-output
|
||||||
|
set unwind_info=false
|
||||||
|
set preserve_frame_pointers=true
|
||||||
|
target aarch64
|
||||||
|
|
||||||
|
function %leaf(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
return v0
|
||||||
|
}
|
||||||
|
|
||||||
|
; stp fp, lr, [sp, #-16]!
|
||||||
|
; mov fp, sp
|
||||||
|
; block0:
|
||||||
|
; ldp fp, lr, [sp], #16
|
||||||
|
; ret
|
||||||
|
|
||||||
20
cranelift/filetests/filetests/isa/x64/leaf.clif
Normal file
20
cranelift/filetests/filetests/isa/x64/leaf.clif
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
;; Test compilation of leaf functions without preserving frame pointers.
|
||||||
|
|
||||||
|
test compile precise-output
|
||||||
|
set unwind_info=false
|
||||||
|
set preserve_frame_pointers=false
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
function %leaf(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
return v0
|
||||||
|
}
|
||||||
|
|
||||||
|
; pushq %rbp
|
||||||
|
; movq %rsp, %rbp
|
||||||
|
; block0:
|
||||||
|
; movq %rdi, %rax
|
||||||
|
; movq %rbp, %rsp
|
||||||
|
; popq %rbp
|
||||||
|
; ret
|
||||||
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
;; Test compilation of leaf functions while preserving frame pointers.
|
||||||
|
|
||||||
|
test compile precise-output
|
||||||
|
set unwind_info=false
|
||||||
|
set preserve_frame_pointers=true
|
||||||
|
target x86_64
|
||||||
|
|
||||||
|
function %leaf(i64) -> i64 {
|
||||||
|
block0(v0: i64):
|
||||||
|
return v0
|
||||||
|
}
|
||||||
|
|
||||||
|
; pushq %rbp
|
||||||
|
; movq %rsp, %rbp
|
||||||
|
; block0:
|
||||||
|
; movq %rdi, %rax
|
||||||
|
; movq %rbp, %rsp
|
||||||
|
; popq %rbp
|
||||||
|
; ret
|
||||||
|
|
||||||
@@ -393,6 +393,7 @@ impl Engine {
|
|||||||
| "machine_code_cfg_info"
|
| "machine_code_cfg_info"
|
||||||
| "tls_model" // wasmtime doesn't use tls right now
|
| "tls_model" // wasmtime doesn't use tls right now
|
||||||
| "opt_level" // opt level doesn't change semantics
|
| "opt_level" // opt level doesn't change semantics
|
||||||
|
| "preserve_frame_pointers" // we don't currently rely on frame pointers
|
||||||
| "enable_alias_analysis" // alias analysis-based opts don't change semantics
|
| "enable_alias_analysis" // alias analysis-based opts don't change semantics
|
||||||
| "probestack_func_adjusts_sp" // probestack above asserted disabled
|
| "probestack_func_adjusts_sp" // probestack above asserted disabled
|
||||||
| "probestack_size_log2" // probestack above asserted disabled
|
| "probestack_size_log2" // probestack above asserted disabled
|
||||||
|
|||||||
Reference in New Issue
Block a user