MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / new

Method new

cranelift/codegen/src/machinst/blockorder.rs:148–311  ·  view source on GitHub ↗

Compute and return a lowered block order for `f`.

(
        f: &Function,
        domtree: &DominatorTree,
        ctrl_plane: &mut ControlPlane,
    )

Source from the content-addressed store, hash-verified

146impl BlockLoweringOrder {
147 /// Compute and return a lowered block order for `f`.
148 pub fn new(
149 f: &Function,
150 domtree: &DominatorTree,
151 ctrl_plane: &mut ControlPlane,
152 ) -> BlockLoweringOrder {
153 trace!("BlockLoweringOrder: function body {:?}", f);
154
155 // Step 1: compute the in-edge and out-edge count of every block.
156 let mut block_in_count = SecondaryMap::with_default(0);
157 let mut block_out_count = SecondaryMap::with_default(0);
158
159 // Block successors are stored as `LoweredBlocks` to simplify the construction of
160 // `lowered_succs` in the final result. Initially, all entries are `Orig` values, and are
161 // updated to be `CriticalEdge` when those cases are identified in step 2 below.
162 let mut block_succs: SmallVec<[LoweredBlock; 128]> = SmallVec::new();
163 let mut block_succ_range = SecondaryMap::with_default(0..0);
164
165 let mut indirect_branch_target_clif_blocks = FxHashSet::default();
166
167 for block in f.layout.blocks() {
168 let start = block_succs.len();
169 visit_block_succs(f, block, |_, succ, from_table| {
170 block_out_count[block] += 1;
171 block_in_count[succ] += 1;
172 block_succs.push(LoweredBlock::Orig { block: succ });
173
174 if from_table {
175 indirect_branch_target_clif_blocks.insert(succ);
176 }
177 });
178
179 // Ensure that blocks terminated by br_table instructions
180 // with an empty jump table are still treated like
181 // conditional blocks from the point of view of critical
182 // edge splitting. Also do the same for TryCall and
183 // TryCallIndirect: we cannot have edge moves before the
184 // branch, even if they have empty handler tables and thus
185 // would otherwise have only one successor.
186 if let Some(inst) = f.layout.last_inst(block) {
187 match f.dfg.insts[inst].opcode() {
188 Opcode::BrTable | Opcode::TryCall | Opcode::TryCallIndirect => {
189 block_out_count[block] = block_out_count[block].max(2);
190 }
191 _ => {}
192 }
193 }
194
195 let end = block_succs.len();
196 block_succ_range[block] = start..end;
197 }
198
199 // Step 2: walk the postorder from the domtree in reverse to produce our desired node
200 // lowering order, identifying critical edges to split along the way.
201
202 let mut lowered_order = Vec::new();
203 let mut blockindex_by_block = SecondaryMap::with_default(BlockIndex::invalid());
204 for &block in domtree.cfg_rpo() {
205 let idx = BlockIndex::new(lowered_order.len());

Callers

nothing calls this directly

Calls 15

visit_block_succsFunction · 0.85
from_iterFunction · 0.85
blocksMethod · 0.80
last_instMethod · 0.80
cfg_rpoMethod · 0.80
orig_blockMethod · 0.80
is_branchMethod · 0.80
newFunction · 0.50
lenMethod · 0.45
pushMethod · 0.45
insertMethod · 0.45
opcodeMethod · 0.45

Tested by

no test coverage detected