瀏覽代碼

More optimizations

Cesar Rodas 9 月之前
父節點
當前提交
d1673fe0c4
共有 2 個文件被更改,包括 64 次插入45 次删除
  1. 64 34
      utxo/src/filter_expr/filter.rs
  2. 0 11
      utxo/src/filter_expr/opcode.rs

+ 64 - 34
utxo/src/filter_expr/filter.rs

@@ -108,40 +108,55 @@ impl Filter {
         let mut has_changed = false;
         let mut counter: usize = self.opcodes.len();
 
-        let mut register_new_mapping = HashMap::new();
+        let mut register_new_mapping = HashMap::<_, Register>::new();
+
+        let mut new_mapping = |register_new_mapping: &mut HashMap<Register, Register>,
+                               current: &Register|
+         -> Register {
+            counter += 1;
+            if counter != **current {
+                has_changed = true;
+            }
+
+            register_new_mapping.insert(current.clone(), counter.into());
+            counter.into()
+        };
 
         self.opcodes.iter_mut().for_each(|opcode| match opcode {
             OpCode::LOAD(current, _) | OpCode::LOAD_EXTERNAL(current, _) => {
-                counter += 1;
-                if counter != **current {
-                    has_changed = true;
-                }
-
-                register_new_mapping.insert(**current, counter.into());
-                *current = register_new_mapping[current];
+                *current = new_mapping(&mut register_new_mapping, current);
             }
-            OpCode::SHL(_, reg1, _)
-            | OpCode::SHR(_, reg1, _)
-            | OpCode::NOT(_, reg1)
-            | OpCode::CPY(_, reg1)
-            | OpCode::MOV(_, reg1)
-            | OpCode::JEQ(reg1, _)
-            | OpCode::JNE(reg1, _) => {
+            OpCode::SHL(set, reg1, _)
+            | OpCode::SHR(set, reg1, _)
+            | OpCode::NOT(set, reg1)
+            | OpCode::CPY(set, reg1)
+            | OpCode::NEG(set, reg1)
+            | OpCode::MOV(set, reg1) => {
                 *reg1 = register_new_mapping[reg1];
+                *set = new_mapping(&mut register_new_mapping, set);
             }
-            OpCode::ADD(_, reg1, reg2)
-            | OpCode::MUL(_, reg1, reg2)
-            | OpCode::DIV(_, reg1, reg2)
-            | OpCode::MOD(_, reg1, reg2)
-            | OpCode::XOR(_, reg1, reg2)
-            | OpCode::SUB(_, reg1, reg2)
-            | OpCode::AND(_, reg1, reg2)
-            | OpCode::EQ(_, reg1, reg2)
-            | OpCode::OR(_, reg1, reg2) => {
+            OpCode::HLT(reg1) | OpCode::JEQ(reg1, _) | OpCode::JNE(reg1, _) => {
+                *reg1 = register_new_mapping[reg1];
+            }
+            OpCode::ADD(set, reg1, reg2)
+            | OpCode::MUL(set, reg1, reg2)
+            | OpCode::NE(set, reg1, reg2)
+            | OpCode::GE(set, reg1, reg2)
+            | OpCode::LE(set, reg1, reg2)
+            | OpCode::GT(set, reg1, reg2)
+            | OpCode::LT(set, reg1, reg2)
+            | OpCode::DIV(set, reg1, reg2)
+            | OpCode::MOD(set, reg1, reg2)
+            | OpCode::XOR(set, reg1, reg2)
+            | OpCode::SUB(set, reg1, reg2)
+            | OpCode::AND(set, reg1, reg2)
+            | OpCode::EQ(set, reg1, reg2)
+            | OpCode::OR(set, reg1, reg2) => {
                 *reg1 = register_new_mapping[reg1];
                 *reg2 = register_new_mapping[reg2];
+                *set = new_mapping(&mut register_new_mapping, set);
             }
-            _ => {}
+            OpCode::LABEL(_) | OpCode::JMP(_) => {}
         });
 
         has_changed
@@ -155,17 +170,27 @@ impl Filter {
             .iter()
             .enumerate()
             .map(|(pos, opcode)| match opcode {
+                OpCode::LOAD(_, _)
+                | OpCode::LOAD_EXTERNAL(_, _)
+                | OpCode::LABEL(_)
+                | OpCode::JMP(_) => vec![],
                 OpCode::NOT(_, reg1)
                 | OpCode::CPY(_, reg1)
                 | OpCode::MOV(_, reg1)
                 | OpCode::JEQ(reg1, _)
                 | OpCode::SHL(_, reg1, _)
                 | OpCode::SHR(_, reg1, _)
+                | OpCode::NEG(_, reg1)
+                | OpCode::HLT(reg1)
+                | OpCode::JNE(reg1, _)
                 | OpCode::JEQ(reg1, _) => {
                     vec![(*reg1, pos)]
                 }
                 OpCode::ADD(_, reg1, reg2)
+                | OpCode::GE(_, reg1, reg2)
+                | OpCode::LE(_, reg1, reg2)
                 | OpCode::MUL(_, reg1, reg2)
+                | OpCode::NE(_, reg1, reg2)
                 | OpCode::DIV(_, reg1, reg2)
                 | OpCode::MOD(_, reg1, reg2)
                 | OpCode::XOR(_, reg1, reg2)
@@ -177,7 +202,6 @@ impl Filter {
                 | OpCode::LT(_, reg1, reg2) => {
                     vec![(*reg1, pos), (*reg2, pos)]
                 }
-                _ => vec![],
             })
             .flatten()
             .fold(HashMap::new(), |mut acc, (reg, pos)| {
@@ -194,7 +218,7 @@ impl Filter {
             .into_iter()
             .enumerate()
             .filter_map(|(pos, opcode)| match &opcode {
-                OpCode::LOAD(dst, _) => {
+                OpCode::LOAD(dst, _) | OpCode::LOAD_EXTERNAL(dst, _) => {
                     if used_registers.get(dst).is_some() {
                         return Some(opcode);
                     } else {
@@ -276,7 +300,7 @@ mod test {
         let mut x = Filter::new(
             r#"
             WHERE
-                $foo = 3 + 2 * 4 / 2 * 298210
+                $foo = 3 + 2 * 4 / 2 * 298210 + $bar
         "#,
         )
         .unwrap();
@@ -291,13 +315,19 @@ mod test {
             }
         }
 
-        let external_variables_1 = vec![("foo".into(), ValueOrRef::Value(0.into()))]
-            .into_iter()
-            .collect();
+        let external_variables_1 = vec![
+            ("foo".into(), ValueOrRef::Value(0.into())),
+            ("bar".into(), ValueOrRef::Value(0.into())),
+        ]
+        .into_iter()
+        .collect();
 
-        let external_variables_2 = vec![("foo".into(), ValueOrRef::Value(1192843.into()))]
-            .into_iter()
-            .collect();
+        let external_variables_2 = vec![
+            ("foo".into(), ValueOrRef::Value(1192844.into())),
+            ("bar".into(), ValueOrRef::Value(1.into())),
+        ]
+        .into_iter()
+        .collect();
 
         let value = x.execute(&external_variables_1).expect("valid execution");
         assert!(matches!(value, Value::Bool(false)));

+ 0 - 11
utxo/src/filter_expr/opcode.rs

@@ -126,15 +126,6 @@ pub enum OpCode {
     /// Jump to the address if the value in the register is false (zero).
     JNE(Register, Addr),
 
-    // Stack Operations
-    /// PUSH <register>
-    /// Push the value in the register onto the stack.
-    PUSH(Register),
-
-    /// POP <register>
-    /// Pop the value from the stack into the register.
-    POP(Register),
-
     // Control Operation
     /// HLT
     /// Halt the execution.
@@ -170,8 +161,6 @@ impl ToString for OpCode {
             OpCode::JMP(a) => format!("JMP {:?}", a),
             OpCode::JEQ(r, a) => format!("JEQ {:?} {:?}", r, a),
             OpCode::JNE(r, a) => format!("JNE {:?} {:?}", r, a),
-            OpCode::PUSH(r) => format!("PUSH {:?}", r),
-            OpCode::POP(r) => format!("POP {:?}", r),
             OpCode::HLT(r) => format!("HLT {:?}", r),
         }
     }