]> Joshua Wise's Git repositories - snipe.git/blob - codegen/liveness.sml
34f5d478aa90bfa50252b63820505f9e6dbdba12
[snipe.git] / codegen / liveness.sml
1 (* L1 Compiler
2  * Gathers tiberium, fires rockets
3  * Turns pseudoasm into liveness-annotated pseudoasm
4  * Author: Joshua Wise <jwise@andrew.cmu.edu>
5  *)
6
7 signature LIVENESS =
8 sig
9   type tiberium = x86.insn list
10   type rockets = x86.oper list list
11
12   val liveness : tiberium -> rockets
13 end
14
15 structure Liveness :> LIVENESS =
16 struct
17   structure T = Temp
18   structure X = x86
19   
20   type tiberium = x86.insn list
21   type rockets = x86.oper list list
22
23   (* This does not 'follow the rules'.
24    *
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.
29    *)
30   fun mashinstr ((instr : x86.insn), (curtemps, output) : x86.oper list * rockets) : x86.oper list * rockets =
31     let
32
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?"
39
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
43
44       val newtemps =
45         case instr
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";*)
59     in
60       (newtemps, newtemps :: output)
61     end
62   
63   fun liveness (instrs : tiberium) : rockets =
64     let
65       val (_, livelist) = foldr mashinstr (nil, nil) instrs
66     in
67       livelist
68     end
69 end
This page took 0.017466 seconds and 2 git commands to generate.