From c9bc4edd082f21cb3a4b53cdc2ed51531d7f2268 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Mon, 2 Nov 2020 13:14:57 +0100 Subject: [PATCH] machinst ABI: Pass fixed frame size to gen_clobber_restore The ABI common code currently passes the fixed frame size to the gen_clobber_save back-end routine, which is required to emit code to allocate the required stack space in the prologue. Similarly, the back-end needs to emit code to de-allocate the stack in the epilogue. However, at this point the back-end does not have access to that fixed frame size value any more. With targets that use a frame pointer, this does not matter, since de-allocation can be done simply by assigning the frame pointer back to the stack pointer. However, on targets that do not use a frame pointer, the frame size is required. To allow back-ends that option, this patch changes ABI common code to pass the fixed frame size to get_clobber_restore as well (the same value as is passed to get_clobber_save). --- cranelift/codegen/src/isa/aarch64/abi.rs | 1 + cranelift/codegen/src/isa/arm32/abi.rs | 1 + cranelift/codegen/src/isa/x64/abi.rs | 1 + cranelift/codegen/src/machinst/abi_impl.rs | 13 +++++++++---- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/cranelift/codegen/src/isa/aarch64/abi.rs b/cranelift/codegen/src/isa/aarch64/abi.rs index b897352ebe..acd8cc88e5 100644 --- a/cranelift/codegen/src/isa/aarch64/abi.rs +++ b/cranelift/codegen/src/isa/aarch64/abi.rs @@ -559,6 +559,7 @@ impl ABIMachineSpec for AArch64MachineDeps { call_conv: isa::CallConv, flags: &settings::Flags, clobbers: &Set>, + _fixed_frame_storage_size: u32, ) -> SmallVec<[Inst; 16]> { let mut insts = SmallVec::new(); let (clobbered_int, clobbered_vec) = get_regs_saved_in_prologue(call_conv, clobbers); diff --git a/cranelift/codegen/src/isa/arm32/abi.rs b/cranelift/codegen/src/isa/arm32/abi.rs index 8cd2df1396..4611899af6 100644 --- a/cranelift/codegen/src/isa/arm32/abi.rs +++ b/cranelift/codegen/src/isa/arm32/abi.rs @@ -336,6 +336,7 @@ impl ABIMachineSpec for Arm32MachineDeps { _call_conv: isa::CallConv, _flags: &settings::Flags, clobbers: &Set>, + _fixed_frame_storage_size: u32, ) -> SmallVec<[Inst; 16]> { let mut insts = SmallVec::new(); let clobbered_vec = get_callee_saves(clobbers); diff --git a/cranelift/codegen/src/isa/x64/abi.rs b/cranelift/codegen/src/isa/x64/abi.rs index bbbabc5ff4..25d1f58762 100644 --- a/cranelift/codegen/src/isa/x64/abi.rs +++ b/cranelift/codegen/src/isa/x64/abi.rs @@ -437,6 +437,7 @@ impl ABIMachineSpec for X64ABIMachineSpec { call_conv: isa::CallConv, flags: &settings::Flags, clobbers: &Set>, + _fixed_frame_storage_size: u32, ) -> SmallVec<[Self::I; 16]> { let mut insts = SmallVec::new(); diff --git a/cranelift/codegen/src/machinst/abi_impl.rs b/cranelift/codegen/src/machinst/abi_impl.rs index 68024b3f08..2fe61d78d1 100644 --- a/cranelift/codegen/src/machinst/abi_impl.rs +++ b/cranelift/codegen/src/machinst/abi_impl.rs @@ -336,6 +336,7 @@ pub trait ABIMachineSpec { call_conv: isa::CallConv, flags: &settings::Flags, clobbers: &Set>, + fixed_frame_storage_size: u32, ) -> SmallVec<[Self::I; 16]>; /// Generate a call instruction/sequence. This method is provided one @@ -435,6 +436,10 @@ pub struct ABICalleeImpl { clobbered: Set>, /// Total number of spillslots, from regalloc. spillslots: Option, + /// Storage allocated for the fixed part of the stack frame. This is + /// usually the same as the total frame size below, except in the case + /// of the baldrdash calling convention. + fixed_frame_storage_size: u32, /// "Total frame size", as defined by "distance between FP and nominal SP". /// Some items are pushed below nominal SP, so the function may actually use /// more stack than this would otherwise imply. It is simply the initial @@ -521,6 +526,7 @@ impl ABICalleeImpl { stackslots_size: stack_offset, clobbered: Set::empty(), spillslots: None, + fixed_frame_storage_size: 0, total_frame_size: None, ret_area_ptr: None, call_conv, @@ -939,8 +945,6 @@ impl ABICallee for ABICalleeImpl { let mask = 2 * bytes - 1; let total_stacksize = (total_stacksize + mask) & !mask; // 16-align the stack. - let mut fixed_frame_storage_size = 0; - if !self.call_conv.extends_baldrdash() { // Leaf functions with zero stack don't need a stack check if one's // specified, otherwise always insert the stack check. @@ -951,7 +955,7 @@ impl ABICallee for ABICalleeImpl { } } if total_stacksize > 0 { - fixed_frame_storage_size += total_stacksize; + self.fixed_frame_storage_size += total_stacksize; } } @@ -970,7 +974,7 @@ impl ABICallee for ABICalleeImpl { self.call_conv, &self.flags, &self.clobbered, - fixed_frame_storage_size, + self.fixed_frame_storage_size, ); insts.extend(clobber_insts); @@ -990,6 +994,7 @@ impl ABICallee for ABICalleeImpl { self.call_conv, &self.flags, &self.clobbered, + self.fixed_frame_storage_size, )); // N.B.: we do *not* emit a nominal SP adjustment here, because (i) there will be no