From 92392c6041ba02370be515978bb4a6a59878ea04 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Thu, 3 Aug 2017 13:48:30 -0700 Subject: [PATCH] Add a prologue_epilogue() hook to TargetIsa. This will compute the stack frame layout as appropriate for the function's calling convention and insert prologue and epilogue code. The default implementation is not useful, each target ISA will need to override this function. --- lib/cretonne/src/context.rs | 7 +++++++ lib/cretonne/src/isa/mod.rs | 13 +++++++++++++ 2 files changed, 20 insertions(+) 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