Rather than switching on instruction formats to discover the destination of a
branch, use the analyze_branch method which returns a BranchInfo enum with just
the relevant information.
This makes CFG algorithms independent of future instruction formats for
branches. Only analyze_branch needs to be updated when adding a new format.
- Add a ir::jumptable module with a JumpTableData struct representing the vector
of destinations.
- Add an entity map of jump tables to the Function.
- Parse and write jump tables in the function preamble.
- Rewrite EBB references in jumptables after parsing.
Replace the three tables instructions, extended_basic_blocks, and
extended_values with a single 'dfg' public member.
Clients using Function are changed to refer to func.layout and func.dfg
respectively.
The DFG keeps track of instruction definitions, values, and EBBs.
Store the primary definition of each instruction: Opcode and operands.
Track SSA values as either the result of an instruction or EBB arguments.
There are two kinds of entity maps:
- A primary map is used to allocate entity references and store the primary
entity data. This map only grows when adding new entities with 'push'.
- A secondary map contains additional information about entities in a primary
map. This map always grows with 'ensure', making default entries for any
unknown primary entities.
Only require the 'Default + Clone' traits for values stored in a secondary map.
Also remove the 'grow automatically' feature of the IndexMut implementation.
This means that clients need to call 'ensure' whenever using a potentially
unknown entity reference.
The 'grow automatically' feature could not be implemented for the Index trait,
and it seems unfortunate to have different semantics for Index and IndexMut.
The Layout also handles EBB layout, so new append_ebb calls are necessary.
- Rewrite callers to use the public data member 'layout'.
- Implement Debug for Function in terms of the write module to avoid deriving
it.
This is the opposite of unwrap(). It converts the ad-hoc null references like
NO_EBB and NO_INST into the more standard Option<Ebb> type which unfortunately
takes twice as much space in data structures.
This supports the pattern of creating structs wrapping a u32 and using them as
indexes into a vector of entities. These entity references should implement the
EntityRef trait.
The EntityMap is a generic map from an EntityRef to some value type. It expects
densely indexed entities and uses a Vec to represent the mapping compactly.