Support for edge-splitting.
This commit is contained in:
parent
6623c8f9f3
commit
b198c653aa
|
@ -171,6 +171,49 @@ impl FunctionBody {
|
||||||
log::trace!("add_edge: from {} to {}", from, to);
|
log::trace!("add_edge: from {} to {}", from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn split_edge(&mut self, from: Block, to: Block, succ_idx: usize) -> Block {
|
||||||
|
assert_eq!(self.blocks[from].succs[succ_idx], to);
|
||||||
|
let pred_idx = self.blocks[from].pos_in_succ_pred[succ_idx];
|
||||||
|
assert_eq!(self.blocks[to].preds[pred_idx], from);
|
||||||
|
|
||||||
|
// Create the block itself.
|
||||||
|
let edge_block = self.add_block();
|
||||||
|
|
||||||
|
// Add blockparams.
|
||||||
|
let mut blockparams = vec![];
|
||||||
|
for i in 0..self.blocks[to].params.len() {
|
||||||
|
let ty = self.blocks[to].params[i].0;
|
||||||
|
blockparams.push(self.add_blockparam(edge_block, ty));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create an unconditional-branch terminator in the edge block.
|
||||||
|
self.blocks[edge_block].terminator = Terminator::Br {
|
||||||
|
target: BlockTarget {
|
||||||
|
block: to,
|
||||||
|
args: blockparams,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
// Update target of from-block.
|
||||||
|
self.blocks[from]
|
||||||
|
.terminator
|
||||||
|
.update_target(succ_idx, |target| target.block = edge_block);
|
||||||
|
|
||||||
|
// Fill in succ/pred links on edge block.
|
||||||
|
self.blocks[edge_block].succs.push(to);
|
||||||
|
self.blocks[edge_block].pos_in_succ_pred.push(pred_idx);
|
||||||
|
self.blocks[edge_block].preds.push(from);
|
||||||
|
self.blocks[edge_block].pos_in_pred_succ.push(succ_idx);
|
||||||
|
|
||||||
|
// Update `succs` in `from`, `preds` in `to`.
|
||||||
|
self.blocks[from].succs[succ_idx] = edge_block;
|
||||||
|
self.blocks[from].pos_in_succ_pred[succ_idx] = 0;
|
||||||
|
self.blocks[to].preds[pred_idx] = edge_block;
|
||||||
|
self.blocks[to].pos_in_pred_succ[pred_idx] = 0;
|
||||||
|
|
||||||
|
edge_block
|
||||||
|
}
|
||||||
|
|
||||||
pub fn recompute_edges(&mut self) {
|
pub fn recompute_edges(&mut self) {
|
||||||
for block in self.blocks.values_mut() {
|
for block in self.blocks.values_mut() {
|
||||||
block.preds.clear();
|
block.preds.clear();
|
||||||
|
|
Loading…
Reference in a new issue