Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml
ViewVC logotype

Annotation of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 513 - (view) (download)

1 : jhr 454 (* codegen-fn.sml
2 :     *
3 :     * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     * All rights reserved.
5 : jhr 455 *
6 :     * Generic support for translating LowIL code to the target representation. We
7 :     * assume that the LowIL has first been run through the splitting pass to match
8 :     * the target's vector widths.
9 : jhr 454 *)
10 :    
11 :     functor CodeGenFn (T : TARGET) : sig
12 :    
13 :     val generate : LowIL.program -> T.program
14 :    
15 :     end = struct
16 :    
17 : jhr 512 structure IL = LowIL
18 :     structure V = LowIL.Var
19 :     structure Op = LowOps
20 :     structure Nd = LowIL.Node
21 :     structure CFG = LowIL.Node
22 : jhr 454
23 :     (* a mapping from LowIL variables to target expressions. Variables get
24 :     * removed when the expressions are used as arguments.
25 :     *)
26 :     structure VDefTbl : sig
27 :     type tbl
28 :    
29 :     val newTbl : unit -> tbl
30 : jhr 512 val getDefOf : tbl -> V.var -> T.exp
31 :     val useDefOf : tbl -> V.var -> T.exp
32 :     val setDefOf : tbl -> (V.var * T.exp) -> unit
33 : jhr 454
34 :     val clear : tbl -> unit
35 :    
36 : jhr 512 val bind : tbl -> (V.var * T.exp) -> T.stm list
37 : jhr 454
38 : jhr 455 (* force all pending expressions into variables *)
39 :     val flush : tbl -> T.stm list
40 :    
41 : jhr 454 end = struct
42 :    
43 : jhr 455 type info = {
44 :     cnt : int ref, (* count of oustanding uses (usually 1) *)
45 :     bind : T.exp
46 :     }
47 :    
48 : jhr 512 type tbl = info V.Tbl.hash_table
49 : jhr 455
50 : jhr 512 fun newTbl () = V.Tbl.mkTable (512, Fail "vtbl")
51 : jhr 455
52 : jhr 512 fun getDefOf tbl x = (case V.Tbl.find tbl x
53 : jhr 455 of NONE => ??
54 :     | SOME{bind, cnt} => bind
55 :     (* end case *))
56 :    
57 : jhr 512 fun useDefOf tbl x = (case V.Tbl.find tbl x
58 : jhr 455 of NONE => ??
59 : jhr 512 | SOME{cnt=ref 1, bind} => (
60 :     ignore (V.Tbl.remove tbl x);
61 : jhr 455 bind)
62 :     | SOME{cnt, bind} => => (
63 :     cnt := !cnt - 1;
64 :     bind)
65 :     (* end case *))
66 :    
67 :     fun setDefOf tbl (x, exp) =
68 : jhr 512 V.Tbl.insert tbl (x, {cnt = ref(V.useCount x), bind = exp})
69 : jhr 455
70 :     fun assign tbl (x, exp) = let
71 :     val lhs : T.local_var = ??
72 :     in
73 : jhr 512 V.Tbl.insert tbl
74 :     (x, {cnt = V.useCount x, bind = T.Expr.var lhs});
75 : jhr 455 [T.Stmt.assign(lhs, exp)]
76 :     end
77 :    
78 : jhr 512 fun bind tbl (x, exp) = (case V.useCount lhs
79 :     of 1 => (V.Tbl.insert tbl (x, {cnt = 1, bind = exp}); [])
80 : jhr 455 | n => let (* bind exp to a new target variable *)
81 :     val lhs : T.local_var = ??
82 :     in
83 : jhr 512 V.Tbl.insert tbl (x, {cnt = n, bind = T.Expr.var lhs});
84 : jhr 455 [T.Stmt.assign(lhs, exp)]
85 :     end
86 :     (* end case *))
87 :    
88 : jhr 454 end (* VDefTbl *)
89 :    
90 : jhr 455 (* FIXME: what about splitting code where the target width doesn't match the
91 :     * source width?
92 :     *)
93 :     fun doRator (vtbl, lhs, rator, args) = let
94 :     val args' = List.map (VDefTbl.useDefOf vtbl) args
95 : jhr 513 val rhs' = (case (rator, args)
96 :     of (Op.Add ty, [a, b]) =>
97 :     | (Op.Sub ty, [a, b]) =>
98 :     | (Op.Mul ty, [a, b]) =>
99 :     | (Op.Div ty, [a, b]) =>
100 :     | (Op.Neg ty, [a]) =>
101 :     | (Op.LT ty, [a, b]) =>
102 :     | (Op.LTE ty, [a, b]) =>
103 :     | (Op.EQ ty, [a, b]) =>
104 :     | (Op.NEQ ty, [a, b]) =>
105 :     | (Op.GT ty, [a, b]) =>
106 :     | (Op.GTE ty, [a, b]) =>
107 :     | (Op.Not, [a]) =>
108 :     | (Op.Max, [a, b]) =>
109 :     | (Op.Min, [a, b]) =>
110 :     | (Op.Sin, [a]) =>
111 :     | (Op.Cos, [a]) =>
112 :     | (Op.Pow, [a, b]) =>
113 :     | (Op.Dot d, [a, b]) =>
114 :     | (Op.Cross, [a, b]) =>
115 :     | (Op.Select(ty, i), [a]) =>
116 :     | (Op.Norm d, [a]) =>
117 :     | (Op.Scale d, [a, b]) =>
118 :     | (Op.InvScale d, [a, b]) =>
119 :     | (Op.CL
120 :     | (Op.PrincipleEvec of ty
121 :     | (Op.Subscript of ty
122 :     | (Op.Floor of int
123 :     | (Op.IntToReal
124 :     | (Op.TruncToInt of int
125 :     | (Op.RoundToInt of int
126 :     | (Op.CeilToInt of int
127 :     | (Op.FloorToInt of int
128 :     | (Op.ImageAddress of ImageInfo.info
129 :     | (Op.LoadVoxels of RawTypes.ty * int
130 :     | (Op.PosToImgSpace of ImageInfo.info
131 :     | (Op.GradToWorldSpace of ImageInfo.info
132 :     | (Op.LoadImage of ImageInfo.info
133 :     | (Op.Inside of ImageInfo.info
134 :     | (Op.Input of ty * string
135 :     | (Op.InputWithDefault of ty * string
136 : jhr 455 (* end case *))
137 :     in
138 :     VDefTbl.bind vtbl (lhs, rhs')
139 :     end
140 : jhr 454
141 : jhr 455 (* translate a LowIL assignment to a list of zero or more target statements *)
142 :     fun doAssign vtbl (lhs, rhs) = let
143 :     fun setDef rhs = (VTbl.setDefOf vtbl (lhs, rhs); [])
144 :     in
145 :     case rhs
146 : jhr 512 of IL.VAR x => setDef (T.Expr.var(VDefTbl.useDefOf vtbl x))
147 :     | IL.LIT(Literal.Int n) => setDef (T.Expr.intLit n)
148 :     | IL.LIT(Literal.Bool b) => setDef (T.Expr.boolLit b)
149 :     | IL.LIT(Literal.Float f) => setDef (T.Expr.floatLit f)
150 :     | IL.LIT(Literal.String s) => setDef (T.Expr.stringLit s)
151 :     | IL.OP(rator, args) => doRator(vtbl, lhs, rator, args)
152 :     | IL.CONS args =>
153 : jhr 455 VTbl.assign ctbl (lhs, T.Expr.vector (List.map (VDefTbl.useDefOf vtbl) args))
154 :     (* end case *)
155 :     end
156 :    
157 : jhr 512 datatype open_if = T.stm list * IL.node -> stm
158 :    
159 :     fun gen (vtbl, cfg) = let
160 :     val doAssign = doAssign vtbl
161 : jhr 513 fun doNode (vtbl, ifCont, stms, nd) = (case Nd.kind nd
162 :     of IL.NULL => raise Fail "unexpected NULL"
163 :     | IL.ENTRY{succ} => doNode (vtbl, ifStk, stms, !succ)
164 :     | IL.JOIN{phis, succ, ...} => ifCont (stms, nd)
165 : jhr 512 | IL.COND{cond, trueBranch, falseBranch, ...} => let
166 :     fun kThen (stms', _) = let
167 :     val thenBlk = T.Stmt.block (List.rev stms')
168 : jhr 513 fun kElse (stms', IL.JOIN{phis, succ, ...}) = let
169 : jhr 512 val stm = T.Stmt.ifthenelse (
170 :     VDefTbl.useDefOf vtbl cond,
171 :     thenBlk,
172 :     T.Stmt.block (List.rev stms'))
173 :     in
174 : jhr 513 (* FIXME: what do we do about phis? *)
175 :     doNode (vtbl, ifStk, stm::stms, !succ)
176 : jhr 512 end
177 :     in
178 :     doNode (vtbl, kElse::ifStk, [], !falseBranch)
179 :     end
180 :     in
181 :     doNode (vtbl, kThen::ifStk, [], !trueBranch)
182 :     end
183 :     | IL.COM {text, succ, ...} =>
184 : jhr 513 doNode (vtbl, ifStk, T.Stmt.comment text :: stms, !succ)
185 : jhr 512 | IL.ASSIGN{stm, succ, ...} =>
186 : jhr 513 doNode (vtbl, ifStk, doAssign stm :: stms, !succ)
187 :     | IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented"
188 : jhr 512 | IL.DIE _ =>
189 : jhr 513 doNode (vtbl, ifStk, T.Stmt.die() :: stms, !succ)
190 : jhr 512 | IL.STABILIZE _ =>
191 : jhr 513 doNode (vtbl, ifStk, T.Stmt.stabilize() :: stms, !succ)
192 :     | IL.EXIT _ => T.Stmt.mkBlock (List.rev stms)
193 : jhr 512 (* end case *))
194 :     in
195 : jhr 513 doNode (vtbl, fn _ => raise Fail "bogus ifCont at JOIN node", [], CFG.entry cfg)
196 : jhr 512 end
197 :    
198 : jhr 454 end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0