neo_solidity/cli/ir_optimize/
optimize.rs1pub(crate) fn optimize_ir(mut module: ir::Module, optimizer_level: u8) -> ir::Module {
4 if optimizer_level == 0 {
5 return module;
6 }
7
8 let enable_neovm_specific = optimizer_level >= 3;
9 let enable_constant_folding = optimizer_level >= 2;
10
11 for function in &mut module.functions {
12 let mut label_remap = std::collections::HashMap::new();
13
14 for block in &mut function.basic_blocks {
15 let mut trimmed = Vec::with_capacity(block.instructions.len());
16 let mut terminated = false;
17
18 for instr in block.instructions.drain(..) {
19 if terminated {
20 if matches!(instr, ir::Instruction::Label(_)) {
22 trimmed.push(instr);
23 terminated = false; }
25 continue;
26 }
27
28 match instr {
29 ir::Instruction::Return
30 | ir::Instruction::ReturnVoid
31 | ir::Instruction::ReturnDefault(_) => {
32 trimmed.push(instr);
33 terminated = true;
34 }
35 ir::Instruction::Jump { .. } => {
36 trimmed.push(instr);
37 terminated = true;
38 }
39 ir::Instruction::Abort
40 | ir::Instruction::AbortMsg
41 | ir::Instruction::Throw => {
42 trimmed.push(instr);
43 terminated = true;
44 }
45 ir::Instruction::EndTry { .. } => {
46 trimmed.push(instr);
47 terminated = true;
48 }
49 other => trimmed.push(other),
50 }
51 }
52
53 block.instructions = trimmed;
54
55 if enable_constant_folding {
56 fold_constant_binary_ops(block);
57 }
58
59 if enable_neovm_specific {
60 dedupe_labels(block, &mut label_remap);
61 remove_trivial_jumps(block);
62
63 neovm_peephole_optimize(block);
65 neovm_simplify_identity_ops(block);
66 neovm_bool_optimize(block);
67
68 neovm_peephole_optimize(block);
70 }
71 }
72
73 if enable_neovm_specific && !label_remap.is_empty() {
74 retarget_jumps(&mut function.basic_blocks, &label_remap);
75 }
76 }
77
78 module
79}