2 * Gathers tiberium, fires rockets
3 * Turns pseudoasm into liveness-annotated pseudoasm
4 * Author: Joshua Wise <jwise@andrew.cmu.edu>
9 type tiberium = x86.insn list
10 type rockets = x86.oper list list
12 val liveness : tiberium -> rockets
15 structure Liveness :> LIVENESS =
20 type tiberium = x86.insn list
21 type rockets = x86.oper list list
23 (* This does not 'follow the rules'.
25 * Since this is a straight line, we can just fold starting at the right,
26 * and accumulate variables. Thus, the accumulator has two parts: one to
27 * represent all of the line / liveness pairs that we've accumulated so far;
28 * and one to represent what was live at the previous line.
30 fun mashinstr ((instr : x86.insn), (curtemps, output) : x86.oper list * rockets) : x86.oper list * rockets =
33 (* Removes an element from a list. *)
34 fun blast (X.TEMP(elt)) l =
35 List.filter (fn a => case a of X.TEMP(b) => (T.compare (b, elt)) <> EQUAL | _ => true) l
36 | blast (X.REG(reg)) l =
37 List.filter (fn a => case a of X.REG(b) => b <> reg | _ => true) l
38 | blast _ l = raise ErrorMsg.InternalError "Why have we declared a CONST as live?"
40 (* Adds an element to a list iff the element doesn't exist already. *)
41 fun addonce (X.CONST(_)) l = l
42 | addonce oper l = oper :: blast oper l
46 of X.DIRECTIVE(_) => curtemps
47 | X.COMMENT(_) => curtemps
48 | X.MOVL(dest, src) => addonce src (blast dest curtemps)
49 | X.SUBL(dest, src) => addonce src (addonce dest curtemps)
50 | X.IMUL(dest, src) => addonce src (addonce dest curtemps)
51 | X.IMUL3(dest, src, _) => addonce src (blast dest curtemps)
52 | X.ADDL(dest, src) => addonce src (addonce dest curtemps)
53 | X.LEAL(dest, src1, src2) => addonce src1 (addonce src2 (blast dest curtemps))
54 | X.IDIVL(src) => addonce src (addonce (X.REG X.EAX) (addonce (X.REG X.EDX) curtemps))
55 | X.CLTD => blast (X.REG X.EDX) (addonce (X.REG X.EAX) curtemps)
56 | X.NEG(src) => (* meh *) curtemps
57 | X.RET => addonce (X.REG X.EAX) curtemps
58 (* | _ => raise ErrorMsg.InternalError "Unable to compute liveness for unused instruction form";*)
60 (newtemps, newtemps :: output)
63 fun liveness (instrs : tiberium) : rockets =
65 val (_, livelist) = foldr mashinstr (nil, nil) instrs