|
|
1.1 ! root 1: The pattern looks like this: ! 2: ! 3: movl P,rA ! 4: xxxl3 Q,rA,rB ! 5: yyyl2 R,rB ! 6: ! 7: xxx and yyy may be any of several binary operators like 'add', ! 8: 'mul', 'and'. rA and rB must both be temporary registers. ! 9: ! 10: Here's how it happens... We work backwards from the last instruction: ! 11: ! 12: movl P,rA ! 13: xxxl3 Q,rA,rB ! 14: => yyyl2 R,rB ! 15: ! 16: Here we note that rB is a 'modify' operand and mark rB alive. ! 17: ! 18: movl P,rA ! 19: => xxxl3 Q,rA,rB ! 20: yyyl2 R,rB ! 21: ! 22: We see that this instruction writes into rB and kills it, but since ! 23: rB is previously alive, the store is not redundant and we leave it ! 24: alone. ! 25: ! 26: => movl P,rA ! 27: xxxl3 Q,rA,rB ! 28: yyyl2 R,rB ! 29: ! 30: We notice that this is a useless store into rA, since we can replace ! 31: rA with P in the following instruction. We delete this instruction ! 32: and modify the following one. ! 33: ! 34: => xxxl3 Q,P,rB ! 35: yyyl2 R,rB ! 36: ! 37: Unfortunately rB is no longer alive because we killed it evaluating ! 38: the earlier form of this very instruction. The optimizer assumes that ! 39: we have a redundant store and deletes the instruction. Bleah.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.