Add a coalescing pass to the register allocator.

Coalescing means creating virtual registers and transforming the code
into conventional SSA form. This means that every value used as a branch
argument will belong to the same virtual register as the corresponding
EBB argument value.

Conventional SSA form makes it easy to avoid memory-memory copies when
spilling values, and the virtual registers can be used as hints when
picking registers too. This reduces the number of register moves needed
for EBB arguments.
This commit is contained in:
Jakob Stoklund Olesen
2017-06-21 09:24:12 -07:00
parent d5055275c4
commit 85b624d13b
5 changed files with 661 additions and 0 deletions

View File

@@ -8,6 +8,7 @@ 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;
@@ -22,6 +23,7 @@ use verifier::{verify_context, verify_liveness};
pub struct Context {
liveness: Liveness,
virtregs: VirtRegs,
coalescing: Coalescing,
topo: TopoOrder,
tracker: LiveValueTracker,
spilling: Spilling,
@@ -38,6 +40,7 @@ impl Context {
Context {
liveness: Liveness::new(),
virtregs: VirtRegs::new(),
coalescing: Coalescing::new(),
topo: TopoOrder::new(),
tracker: LiveValueTracker::new(),
spilling: Spilling::new(),
@@ -70,6 +73,21 @@ impl Context {
verify_liveness(isa, func, cfg, &self.liveness)?;
}
// 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, Some(isa))?;
verify_liveness(isa, func, cfg, &self.liveness)?;
}
// Second pass: Spilling.
self.spilling
.run(isa,