jameysharp added the good first issue label to Issue #7954.
jameysharp added the cranelift:E-easy label to Issue #7954.
jameysharp added the cranelift:mid-end label to Issue #7954.
jameysharp added the cranelift:goal:compile-time label to Issue #7954.
jameysharp opened issue #7954:
Feature
We have two interfaces in Cranelift for navigating dominator trees, both defined in the
cranelift_codegen::dominator_treemodule:DominatorTreeandDominatorTreePreorder. But we weren't using the latter outside of tests after #3434 landed in 2021, until I switched the egraph pass over to using it in #7948 today.
- We should audit all uses of
DominatorTreeto see if they would be better served by usingDominatorTreePreorderinstead.- If we end up using
DominatorTreePreorderin more places than just the egraph pass, then we should compute it once and share it.- If it turns out that we always need a
DominatorTreePreorderwhen compiling any function, then we should fold the two types into one and always compute the preorder when we're computing the dominator tree.Benefit
These two interfaces both provide a method named
dominateswhich checks whether one basic block dominates another. However,DominatorTreedoes this in time proportional to the length of the path from one block to the other within the dominator tree. Thanks to a linear-time preprocessing step performed once,DominatorTreePreordercan answer this question in constant time.So if we're using the
DominatorTree::dominatesmethod anywhere that's performance-critical, switching toDominatorTreePreordercould provide an asymptotic-complexity improvement.On top of that, sharing a precomputed preorder across multiple uses saves time redoing the preprocessing step and also may allow us to reuse a heap allocation for the temporary storage used during that preprocessing step.
Implementation
To start with, search for all uses of
DominatorTree::dominates. For each one, see if we can just replace it withDominatorTreePreorder::dominates.This is easy if both arguments are
BlockIDs, but either one is currently also allowed to be an instruction ID (Inst) or aProgramPoint. If we're relying on that feature somewhere, it's only slightly more complicated: If two instructions are in the same block then the earlier instruction dominates the later instruction; otherwise we can go back to the easy case and compare the blocks they're in to see if one block dominates the other.If some instances of
DominatorTreeare only being used to calldominates, then removing that structure from those instances in favor ofDominatorTreePreorderis the next step. However, some cases may also be using other methods such ascfg_postorderoridom, which are not available onDominatorTreePreorder.Alternatives
We can always leave this alone, but I think it's a good source of small changes that may give us performance improvements during compilation.
MuhtasimTanmoy commented on issue #7954:
Would like to take this one
jameysharp commented on issue #7954:
Great, please do! If you have any questions, let us know. We're happy to help!
badumbatish commented on issue #7954:
hi there! is this issue still on going?
badumbatish commented on issue #7954:
i'll give this one a try if nobody's doing this
adamperlin commented on issue #7954:
Hi! I'm curious if this PR is blocked?
adamperlin commented on issue #7954:
Hi! I'm curious what the status of this issue is?
cfallin commented on issue #7954:
It looks like the most recent attempt to adapt our alias analysis and related optimizations to use
DominatorTreePreorderin #9213 stalled because of some failing assertions in the modified version. I suspect you'd be welcome to ping there and try pushing it further if you like!
PhantomInTheWire commented on issue #7954:
I’d like to pick this up, is anyone actively working on it? If not can someone assign this to me?
PhantomInTheWire commented on issue #7954:
@cfallin this should probably be closed now
cfallin commented on issue #7954:
@PhantomInTheWire the
DominatorTreestill exists and is used in several places still, so IMHO let's leave this open until the issue's stated goal (auditing remaining uses ofDominatorTreeand migrating all possible cases). Thank you for your efforts in pushing this forward, however!
cfallin closed issue #7954:
Feature
We have two interfaces in Cranelift for navigating dominator trees, both defined in the
cranelift_codegen::dominator_treemodule:DominatorTreeandDominatorTreePreorder. But we weren't using the latter outside of tests after #3434 landed in 2021, until I switched the egraph pass over to using it in #7948 today.
- We should audit all uses of
DominatorTreeto see if they would be better served by usingDominatorTreePreorderinstead.- If we end up using
DominatorTreePreorderin more places than just the egraph pass, then we should compute it once and share it.- If it turns out that we always need a
DominatorTreePreorderwhen compiling any function, then we should fold the two types into one and always compute the preorder when we're computing the dominator tree.Benefit
These two interfaces both provide a method named
dominateswhich checks whether one basic block dominates another. However,DominatorTreedoes this in time proportional to the length of the path from one block to the other within the dominator tree. Thanks to a linear-time preprocessing step performed once,DominatorTreePreordercan answer this question in constant time.So if we're using the
DominatorTree::dominatesmethod anywhere that's performance-critical, switching toDominatorTreePreordercould provide an asymptotic-complexity improvement.On top of that, sharing a precomputed preorder across multiple uses saves time redoing the preprocessing step and also may allow us to reuse a heap allocation for the temporary storage used during that preprocessing step.
Implementation
To start with, search for all uses of
DominatorTree::dominates. For each one, see if we can just replace it withDominatorTreePreorder::dominates.This is easy if both arguments are
BlockIDs, but either one is currently also allowed to be an instruction ID (Inst) or aProgramPoint. If we're relying on that feature somewhere, it's only slightly more complicated: If two instructions are in the same block then the earlier instruction dominates the later instruction; otherwise we can go back to the easy case and compare the blocks they're in to see if one block dominates the other.If some instances of
DominatorTreeare only being used to calldominates, then removing that structure from those instances in favor ofDominatorTreePreorderis the next step. However, some cases may also be using other methods such ascfg_postorderoridom, which are not available onDominatorTreePreorder.Alternatives
We can always leave this alone, but I think it's a good source of small changes that may give us performance improvements during compilation.
Last updated: Dec 13 2025 at 19:03 UTC