Skip to content

Commit 8cad414

Browse files
committed
Improve readability and shave off another 7ms
1 parent 53a725d commit 8cad414

1 file changed

Lines changed: 21 additions & 51 deletions

File tree

‎zjit/src/hir.rs‎

Lines changed: 21 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -6351,20 +6351,6 @@ impl Function {
63516351
/// This produces a minimal SSA representation amenable to further optimizations.
63526352
/// The implementation is inspired from algorithm 2 in <https://c9x.me/compile/bib/braun13cc.pdf>.
63536353
fn remove_trivial_block_params(&mut self) {
6354-
6355-
#[derive(Copy, Clone)]
6356-
enum Edge {
6357-
True,
6358-
False,
6359-
Unconditional
6360-
}
6361-
6362-
#[derive(Copy, Clone)]
6363-
struct EdgeKey {
6364-
block_id: BlockId,
6365-
edge: Edge
6366-
}
6367-
63686354
// Each block param is lifted to an abstract domain of ParamValues.
63696355
// The lattice is simple. None is Bottom, Multiple is Top, and One is between both.
63706356
// During analysis, all block params start with None.
@@ -6439,20 +6425,11 @@ impl Function {
64396425
rpo_order[block_id] = idx;
64406426
}
64416427

6442-
64436428
// Populate each block with a vec of instructions that call the block
6444-
let mut predecessors: Vec<Vec<EdgeKey>> = vec![vec![]; self.num_blocks()];
6429+
let mut predecessors: Vec<Vec<BlockId>> = vec![vec![]; self.num_blocks()];
64456430
for block_id in rpo.iter().cloned() {
6446-
let insn_id = self.blocks[block_id].insns().last().unwrap();
6447-
match self.resolve(*insn_id).insn(self) {
6448-
Insn::CondBranch { if_true, if_false, .. } => {
6449-
predecessors[if_true.target].push(EdgeKey { block_id, edge: Edge::True });
6450-
predecessors[if_false.target].push(EdgeKey { block_id, edge: Edge::False });
6451-
}
6452-
Insn::Jump(edge) => {
6453-
predecessors[edge.target].push(EdgeKey { block_id, edge: Edge::Unconditional });
6454-
}
6455-
_ => ()
6431+
for edge in outgoing_edges(self, block_id) {
6432+
predecessors[edge.target].push(block_id);
64566433
}
64576434
}
64586435

@@ -6465,22 +6442,18 @@ impl Function {
64656442
for target in rpo.iter().copied() {
64666443
let mut abstract_domain = vec![AbstractValue::None; self.blocks[target].params.len()];
64676444

6468-
for pred in &predecessors[target] {
6469-
// Collect the params for abstract interpretation. The params are args of the BranchEdges extracted from block terminators.
6470-
let insn_idx = self.blocks[pred.block_id].insns.len() - 1;
6471-
let insn = self.resolve(self.blocks[pred.block_id].insns[insn_idx]).insn(self);
6472-
let params = match (insn, pred.edge) {
6473-
(Insn::Jump(edge), Edge::Unconditional) => &edge.args,
6474-
(Insn::CondBranch { if_true, .. }, Edge::True) => &if_true.args,
6475-
(Insn::CondBranch { if_false, .. }, Edge::False) => &if_false.args,
6476-
(_, _) => unreachable!("Predecessors should only be Jump or CondBranch with a corresponding EdgeKey bool.")
6477-
};
6478-
6479-
// Perform abstract interpretation to determine trivial params
6480-
for i in 0..params.len() {
6481-
let param = self.find_id(params[i]);
6482-
let self_loop_param = self.find_id(self.blocks[target].params[i]);
6483-
abstract_domain[i].update(param, self_loop_param);
6445+
for &block_id in &predecessors[target] {
6446+
// In almost all cases, there is only one edge that returns from this filter. However, there's one thorny edge case.
6447+
// Technically, a CondBranch could pass two sets of different parameters to the same target. Both of these are predecessors and both must be checked.
6448+
for edge in outgoing_edges(self, block_id).filter(|edge| edge.target == target) {
6449+
// Collect the params for abstract interpretation. The params are args of the BranchEdges extracted from block terminators.
6450+
let predecessor_params = &edge.args;
6451+
// Perform abstract interpretation to determine trivial params
6452+
for i in 0..predecessor_params.len() {
6453+
let param = self.find_id(predecessor_params[i]);
6454+
let self_loop_param = self.find_id(self.blocks[target].params[i]);
6455+
abstract_domain[i].update(param, self_loop_param);
6456+
}
64846457
}
64856458
}
64866459

@@ -6507,15 +6480,12 @@ impl Function {
65076480
}
65086481

65096482
// Remove trivial params from the incoming edges
6510-
for pred in &predecessors[target] {
6511-
let insn_idx = self.blocks[pred.block_id].insns.len() - 1;
6512-
let insn = self.resolve(self.blocks[pred.block_id].insns[insn_idx]).insn_mut(self);
6513-
match (insn, pred.edge) {
6514-
(Insn::Jump(edge), Edge::Unconditional) => prune_vec_by_indices(&mut edge.args, &trivial_indices),
6515-
(Insn::CondBranch { if_true, .. }, Edge::True) => prune_vec_by_indices(&mut if_true.args, &trivial_indices),
6516-
(Insn::CondBranch { if_false, .. }, Edge::False) => prune_vec_by_indices(&mut if_false.args, &trivial_indices),
6517-
(_, _) => unreachable!("Predecessors should only be Jump or CondBranch with a corresponding EdgeKey bool.")
6518-
};
6483+
for &block_id in &predecessors[target] {
6484+
for edge in outgoing_edges_mut(self, block_id) {
6485+
if edge.target == target {
6486+
prune_vec_by_indices(&mut edge.args, &trivial_indices);
6487+
}
6488+
}
65196489
}
65206490

65216491
// Remove trivial params from the block definition

0 commit comments

Comments
 (0)