neo_solidity/cli/ir_optimize/
labels.rs1fn remove_trivial_jumps(block: &mut ir::BasicBlock) {
2 let mut optimized = Vec::with_capacity(block.instructions.len());
3 let mut iter = block.instructions.iter();
4 while let Some(instr) = iter.next() {
5 if let ir::Instruction::Jump { target } = instr {
6 if let Some(ir::Instruction::Label(id)) = iter.clone().next() {
7 if id == target {
8 continue;
10 }
11 }
12 }
13 optimized.push(instr.clone());
14 }
15 block.instructions = optimized;
16}
17
18fn dedupe_labels(block: &mut ir::BasicBlock, remap: &mut std::collections::HashMap<usize, usize>) {
19 let mut optimized = Vec::with_capacity(block.instructions.len());
20 let mut last_label: Option<usize> = None;
21
22 for instr in block.instructions.drain(..) {
23 match instr {
24 ir::Instruction::Label(id) => {
25 if let Some(prev) = last_label {
26 remap.insert(id, prev);
27 continue;
28 } else {
29 last_label = Some(id);
30 optimized.push(ir::Instruction::Label(id));
31 }
32 }
33 other => {
34 last_label = None;
35 optimized.push(other);
36 }
37 }
38 }
39
40 block.instructions = optimized;
41}
42
43fn retarget_jumps(blocks: &mut [ir::BasicBlock], remap: &std::collections::HashMap<usize, usize>) {
44 for block in blocks {
45 for instr in &mut block.instructions {
46 match instr {
47 ir::Instruction::Jump { target } | ir::Instruction::JumpIf { target } => {
48 if let Some(canonical) = remap.get(target) {
49 *target = *canonical;
50 }
51 }
52 ir::Instruction::Try { catch_target } => {
53 if let Some(canonical) = remap.get(catch_target) {
54 *catch_target = *canonical;
55 }
56 }
57 ir::Instruction::EndTry { target } => {
58 if let Some(canonical) = remap.get(target) {
59 *target = *canonical;
60 }
61 }
62 _ => {}
63 }
64 }
65 }
66}