diff --git a/lib/cretonne/src/context.rs b/lib/cretonne/src/context.rs index d0288789f6..9967f1e11e 100644 --- a/lib/cretonne/src/context.rs +++ b/lib/cretonne/src/context.rs @@ -68,6 +68,7 @@ impl Context { self.legalize(isa)?; self.regalloc(isa)?; + self.prologue_epilogue(isa)?; self.relax_branches(isa) } @@ -135,6 +136,12 @@ impl Context { .run(isa, &mut self.func, &self.cfg, &self.domtree) } + /// Insert prologue and epilogues after computing the stack frame layout. + pub fn prologue_epilogue(&mut self, isa: &TargetIsa) -> CtonResult { + isa.prologue_epilogue(&mut self.func)?; + self.verify_if(isa) + } + /// Run the branch relaxation pass and return the final code size. pub fn relax_branches(&mut self, isa: &TargetIsa) -> Result { let code_size = relax_branches(&mut self.func, isa)?; diff --git a/lib/cretonne/src/isa/mod.rs b/lib/cretonne/src/isa/mod.rs index 7caac93a67..08c45dd8b8 100644 --- a/lib/cretonne/src/isa/mod.rs +++ b/lib/cretonne/src/isa/mod.rs @@ -49,6 +49,7 @@ use flowgraph; use settings; use ir; use regalloc; +use result; use isa::enc_tables::Encodings; #[cfg(build_riscv)] @@ -227,6 +228,18 @@ pub trait TargetIsa { /// registers. fn allocatable_registers(&self, func: &ir::Function) -> regalloc::AllocatableSet; + /// Compute the stack layout and insert prologue and epilogue code into `func`. + /// + /// Return an error if the stack frame is too large. + fn prologue_epilogue(&self, func: &mut ir::Function) -> result::CtonResult { + // This default implementation is unlikely to be good enough. + use stack_layout::layout_stack; + + let align = if self.flags().is_64bit() { 8 } else { 4 }; + layout_stack(&mut func.stack_slots, align)?; + Ok(()) + } + /// Emit binary machine code for a single instruction into the `sink` trait object. /// /// Note that this will call `put*` methods on the trait object via its vtable which is not the