This is now a generic function that can test arbitrary combinations of
instructions and EBBs for dominance.
It can handle anything that converts into an expanded program point,
including a ValueDef.
Also fix a bug if the earlier dominates() function which didn't properly
handle block layouts that were not topologically ordered.
When comparing instructions in the same EBB, behave like the RPO visits
instructions in program order.
- Add a Layout::pp_ebb() method for convenience. It gets the EBB
containing any program point.
- Add a conversion from ValueDef to ExpandedProgramPoint so it can be
used with the rpo_cmp method.
The DominatorTree has existing DomNodes per EBB that can be used in lieu
of expensive HastSets for the depth-first traversal of the CFG.
Make the computed and cached post-order available for other passes
through the `cfg_postorder()` method which returns a slice.
The post-order algorithm is essentially the same as the one in
ControlFlowGraph::postorder_ebbs(), except it will never push a
successor node that has already been visited once. This is more
efficient, but it generates a different post-order.
Change the cfg_traversal tests to check this new algorithm.
The Branch format also stores its fixed argument in the value list. This
requires the value pool to be passed to a few more functions.
Note that this actually makes the Branch and Jump variants of
InstructionData identical. The instruction format hashing does not yet
understand that all value operands are stored in the value list. We'll
fix that in a later patch.
Also convert IndirectCall, noting that Call and IndirectCall remain
separate instruction formats because they have different immediate
fields.
Move the flow graph computation into a compute method which can be
called with multiple functions.
This allows us to reuse the ControlFlowGraph memory and keep an instance
in the Context.
Also rework the algorithm to be more robust against unreachable blocks.
- Add an is_reachable(ebb) method.
- Change idom(ebb) to just return an instruction.
- Make idom() return None for the entry block as well as unreachable
blocks.
Rewrite Builder uses in test cases to use this method and construct a
new builder for each instruction. This pattern allows us to change the
InstBuilder trait to a one-shot implementation that can only create a
single instruction.
Don't re-export the Builder struct, it is less important than the
InstBuilder trait, and we may get more implementations.
All of the instruction format an opcode methods are emitted as an
InstBuilder trait instead of adding them to the Bulder struct directly.
The methods only make use of the InstBuilderBase methods to create new
instructions.
This makes it possible to reuse the InstBuilder trait for different ways
of inserting instructions.
Give these crates each a more standard directory layout with sources in
a 'src' sub-sirectory and Cargo.toml in the top lib/foo directory.
Add license and description fields to each.
The build script for the cretonne crate now lives in
'lib/cretonne/build.rs' separating it from the normal library sources
under 'lib/cretonne/src'.