Recompute the dominator tree on demand.

The legalizer can invalidate the dominator tree, but we don't actually
need a dominator tree during legalization, so defer the construction of
the domtree.

- Add an "invalid" state to the dominator tree along with clear() and
  is_valid() methods to test it.
- Invalidate the dominator tree as part of legalization.
- Ensure that a valid dominator tree exists before the passes that need
  it.

Together these features add up to a manual invalidation mechanism for
the dominator tree.
This commit is contained in:
Jakob Stoklund Olesen
2017-08-28 11:13:53 -07:00
parent fecbcbb7b4
commit 6d9198d55f
3 changed files with 34 additions and 5 deletions

View File

@@ -63,7 +63,7 @@ impl Context {
///
/// Returns the size of the function's code.
pub fn compile(&mut self, isa: &TargetIsa) -> Result<CodeOffset, CtonError> {
self.flowgraph();
self.cfg.compute(&self.func);
self.verify_if(isa)?;
self.legalize(isa)?;
@@ -103,6 +103,8 @@ impl Context {
/// Run the legalizer for `isa` on the function.
pub fn legalize(&mut self, isa: &TargetIsa) -> CtonResult {
// Legalization invalidates the domtree by mutating the CFG.
self.domtree.clear();
legalize_function(&mut self.func, &mut self.cfg, isa);
self.verify_if(isa)
}
@@ -113,6 +115,13 @@ impl Context {
self.domtree.compute(&self.func, &self.cfg);
}
/// Ensure that a valid domtree exists.
pub fn ensure_domtree(&mut self) {
if !self.domtree.is_valid() {
self.domtree.compute(&self.func, &self.cfg);
}
}
/// Perform simple GVN on the function.
pub fn simple_gvn(&mut self) -> CtonResult {
do_simple_gvn(&mut self.func, &mut self.cfg);
@@ -123,6 +132,7 @@ impl Context {
/// Perform LICM on the function.
pub fn licm(&mut self) -> CtonResult {
self.ensure_domtree();
do_licm(&mut self.func,
&mut self.cfg,
&mut self.domtree,
@@ -132,6 +142,7 @@ impl Context {
/// Run the register allocator.
pub fn regalloc(&mut self, isa: &TargetIsa) -> CtonResult {
self.ensure_domtree();
self.regalloc
.run(isa, &mut self.func, &self.cfg, &self.domtree)
}