|
@@ -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 {
|