Posted to tcl by kbk at Mon Jan 13 20:12:06 GMT 2014view pretty
# revprop -- # # "Reverse copy propagation" # # Parameters: # quads - Sequence of quadruples (three-address instructions) # vnames - List of variable names in order by variable indices # # Results: # Returns the given bytecode sequence, with unneeded code # elided. # # This pass functions as a cleanup for sequences that look like: # # v := ... A # v2 := v B # ... code that uses v2 ... # # The conditions for the optimization are: # all reachable uses of A: v:=... are copies of the form v2:=v # all reachable uses of A: v:=... copy to the same variable v2 # no reachable use of A: v:=... has a reaching definition of v other than # A. # # In this case, the operation at A can be replaced with v2 :- ..., # and all the copies B can be elided proc revprop {quads vnames} [bdd::datalog::compileProgram db { set dead {} } { % An assignment of variable v at statement st can be replaced with % variable v2 to eliminate a copy of v to v2 at statement st2 if % there's no reason not to do so. revprop(v, v2, st, st2) :- reaches(v, st, st2), isCopy(st2), writes0(st2, v2), !cantRevprop(v, v2, st). % We cannot replace v with v2 in st if that would spoil any reachable % use of v or v2 from st. cantRevprop(v, v2, st) :- reaches(v, st, st2), cantRevprop2(v, v2, st ,st2). cantRevprop(_, v2, st) :- flowsPast(v2, st, st2), reads0(st2, v2). % A use of v in st2 is spoilt by this optimization if: % st2 isn't a copy, % st2 doesn't copy v to v2 % st2 has a reaching definition of v that isn't st. cantRevprop2(_, _, _, st2) :- !isCopy(st2). cantRevprop2(_, v2, _, st2) :- !writes0(st2, v2). cantRevprop2(v, _, st, st2) :- reaches(v, st3, st2), st3 != st. revprop(v, v2, st, st2)? } d { set v [lindex $vnames [dict get $d v]] set v2 [lindex $vnames [dict get $d v2]] set st [dict get $d st] set st2 [dict get $d st2] set q [lindex $quads $st] lset quads $st 1 $v2 dict set dead $st2 {} } { # Remove the instructions that this optimization has killed tailcall quads-remove-dead $quads $dead }]