neo_solidity/cli/ir_optimize/
labels.rs

1fn 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                    // Skip the jump; fallthrough reaches the label
9                    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}