Преглед изворни кода

Check there is no jump between the checks

Jumps between loads make the analysis useless, and the LOAD cannot be removed safely
Cesar Rodas пре 8 месеци
родитељ
комит
535247fb00

+ 1 - 1
utxo/src/filter_expr/compiler/mod.rs

@@ -154,8 +154,8 @@ impl<'a> Compiler<'a> {
 
     pub fn optimize(opcodes: Vec<OpCode>) -> (Vec<OpCode>, bool) {
         vec![
-            optimizations::remove_redundant_load_and_mov,
             optimizations::remove_unused_load,
+            optimizations::remove_redundant_load_and_mov,
             optimizations::calculate_static_values,
             optimizations::remove_useless_jumps,
             optimizations::remove_dead_code,

+ 18 - 1
utxo/src/filter_expr/compiler/optimizations/remove_unused_load.rs

@@ -81,6 +81,7 @@ pub fn remove_unused_load(mut opcodes: Vec<OpCode>) -> (Vec<OpCode>, bool) {
         });
 
     let old_total_opcodes = opcodes.len();
+    let old_opcodes = opcodes.clone();
 
     // remove unused registers. If the register has not been read by any opcode, then it can be
     // removed.
@@ -104,10 +105,26 @@ pub fn remove_unused_load(mut opcodes: Vec<OpCode>) -> (Vec<OpCode>, bool) {
                         next
                     });
 
+                if let Some(next_load) = next_load {
+                    if old_opcodes[pos..next_load].iter().any(|opcode| {
+                        matches!(
+                            opcode,
+                            OpCode::JEQ(_, _) | OpCode::JMP(_) | OpCode::JNE(_, _)
+                        )
+                    }) {
+                        // Between the current LOAD and the next time is updated, either with
+                        // another LOAD or another OpCode that updates this register there is a
+                        // jump, making it too complex to determine right now if the register is
+                        // used or not, it is safer just to keep it until further analysis is
+                        // implemented
+                        return Some(opcode);
+                    }
+                }
+
                 if let Some(readed_at) = used_registers.get(dst) {
                     if readed_at.iter().any(|readed_at| {
                         if let Some(next_load) = next_load {
-                            *readed_at < next_load && *readed_at > pos
+                            *readed_at <= next_load && *readed_at >= pos
                         } else if *readed_at > pos {
                             true
                         } else {