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).
This commit is contained in:
Ulrich Weigand
2020-11-02 13:14:57 +01:00
parent d1be8dcfc0
commit c9bc4edd08
4 changed files with 12 additions and 4 deletions

View File

@@ -336,6 +336,7 @@ pub trait ABIMachineSpec {
call_conv: isa::CallConv,
flags: &settings::Flags,
clobbers: &Set<Writable<RealReg>>,
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<M: ABIMachineSpec> {
clobbered: Set<Writable<RealReg>>,
/// Total number of spillslots, from regalloc.
spillslots: Option<usize>,
/// 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<M: ABIMachineSpec> ABICalleeImpl<M> {
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<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
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<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
}
}
if total_stacksize > 0 {
fixed_frame_storage_size += total_stacksize;
self.fixed_frame_storage_size += total_stacksize;
}
}
@@ -970,7 +974,7 @@ impl<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
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<M: ABIMachineSpec> ABICallee for ABICalleeImpl<M> {
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