Rename the 'cretonne' crate to 'cretonne-codegen'.
This fixes the next part of #287.
This commit is contained in:
159
lib/codegen/src/regalloc/context.rs
Normal file
159
lib/codegen/src/regalloc/context.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
//! Register allocator context.
|
||||
//!
|
||||
//! The `Context` struct contains data structures that should be preserved across invocations of
|
||||
//! the register allocator algorithm. This doesn't preserve any data between functions, but it
|
||||
//! avoids allocating data structures independently for each function begin compiled.
|
||||
|
||||
use dominator_tree::DominatorTree;
|
||||
use flowgraph::ControlFlowGraph;
|
||||
use ir::Function;
|
||||
use isa::TargetIsa;
|
||||
use regalloc::coalescing::Coalescing;
|
||||
use regalloc::coloring::Coloring;
|
||||
use regalloc::live_value_tracker::LiveValueTracker;
|
||||
use regalloc::liveness::Liveness;
|
||||
use regalloc::reload::Reload;
|
||||
use regalloc::spilling::Spilling;
|
||||
use regalloc::virtregs::VirtRegs;
|
||||
use result::CtonResult;
|
||||
use timing;
|
||||
use topo_order::TopoOrder;
|
||||
use verifier::{verify_context, verify_cssa, verify_liveness, verify_locations};
|
||||
|
||||
/// Persistent memory allocations for register allocation.
|
||||
pub struct Context {
|
||||
liveness: Liveness,
|
||||
virtregs: VirtRegs,
|
||||
coalescing: Coalescing,
|
||||
topo: TopoOrder,
|
||||
tracker: LiveValueTracker,
|
||||
spilling: Spilling,
|
||||
reload: Reload,
|
||||
coloring: Coloring,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
/// Create a new context for register allocation.
|
||||
///
|
||||
/// This context should be reused for multiple functions in order to avoid repeated memory
|
||||
/// allocations.
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
liveness: Liveness::new(),
|
||||
virtregs: VirtRegs::new(),
|
||||
coalescing: Coalescing::new(),
|
||||
topo: TopoOrder::new(),
|
||||
tracker: LiveValueTracker::new(),
|
||||
spilling: Spilling::new(),
|
||||
reload: Reload::new(),
|
||||
coloring: Coloring::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Clear all data structures in this context.
|
||||
pub fn clear(&mut self) {
|
||||
self.liveness.clear();
|
||||
self.virtregs.clear();
|
||||
self.coalescing.clear();
|
||||
self.topo.clear();
|
||||
self.tracker.clear();
|
||||
self.spilling.clear();
|
||||
self.reload.clear();
|
||||
self.coloring.clear();
|
||||
}
|
||||
|
||||
/// Allocate registers in `func`.
|
||||
///
|
||||
/// After register allocation, all values in `func` have been assigned to a register or stack
|
||||
/// location that is consistent with instruction encoding constraints.
|
||||
pub fn run(
|
||||
&mut self,
|
||||
isa: &TargetIsa,
|
||||
func: &mut Function,
|
||||
cfg: &ControlFlowGraph,
|
||||
domtree: &mut DominatorTree,
|
||||
) -> CtonResult {
|
||||
let _tt = timing::regalloc();
|
||||
debug_assert!(domtree.is_valid());
|
||||
|
||||
// `Liveness` and `Coloring` are self-clearing.
|
||||
self.virtregs.clear();
|
||||
|
||||
// Tracker state (dominator live sets) is actually reused between the spilling and coloring
|
||||
// phases.
|
||||
self.tracker.clear();
|
||||
|
||||
// Pass: Liveness analysis.
|
||||
self.liveness.compute(isa, func, cfg);
|
||||
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
}
|
||||
|
||||
// Pass: Coalesce and create Conventional SSA form.
|
||||
self.coalescing.conventional_ssa(
|
||||
isa,
|
||||
func,
|
||||
cfg,
|
||||
domtree,
|
||||
&mut self.liveness,
|
||||
&mut self.virtregs,
|
||||
);
|
||||
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_context(func, cfg, domtree, isa)?;
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
|
||||
}
|
||||
|
||||
// Pass: Spilling.
|
||||
self.spilling.run(
|
||||
isa,
|
||||
func,
|
||||
domtree,
|
||||
&mut self.liveness,
|
||||
&self.virtregs,
|
||||
&mut self.topo,
|
||||
&mut self.tracker,
|
||||
);
|
||||
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_context(func, cfg, domtree, isa)?;
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
|
||||
}
|
||||
|
||||
// Pass: Reload.
|
||||
self.reload.run(
|
||||
isa,
|
||||
func,
|
||||
domtree,
|
||||
&mut self.liveness,
|
||||
&mut self.topo,
|
||||
&mut self.tracker,
|
||||
);
|
||||
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_context(func, cfg, domtree, isa)?;
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
|
||||
}
|
||||
|
||||
// Pass: Coloring.
|
||||
self.coloring.run(
|
||||
isa,
|
||||
func,
|
||||
domtree,
|
||||
&mut self.liveness,
|
||||
&mut self.tracker,
|
||||
);
|
||||
|
||||
if isa.flags().enable_verifier() {
|
||||
verify_context(func, cfg, domtree, isa)?;
|
||||
verify_liveness(isa, func, cfg, &self.liveness)?;
|
||||
verify_locations(isa, func, Some(&self.liveness))?;
|
||||
verify_cssa(func, cfg, domtree, &self.liveness, &self.virtregs)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user