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

SCM Repository

[diderot] Annotation of /branches/charisee/src/compiler/tree-il/low-to-tree-fn.sml
ViewVC logotype

Annotation of /branches/charisee/src/compiler/tree-il/low-to-tree-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2857 - (view) (download)

1 : jhr 1115 (* low-to-tree-fn.sml
2 :     *
3 :     * COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     * All rights reserved.
5 :     *
6 :     * This module translates the LowIL representation of a program (i.e., a pure CFG) to
7 :     * a block-structured AST with nested expressions.
8 :     *
9 :     * NOTE: this translation is pretty dumb about variable coalescing (i.e., it doesn't do any).
10 :     *)
11 :    
12 :     functor LowToTreeFn (Target : sig
13 :    
14 : jhr 1640 val supportsPrinting : unit -> bool (* does the target support the Print op? *)
15 :    
16 : jhr 1115 (* tests for whether various expression forms can appear inline *)
17 : jhr 2356 val inlineCons : int -> bool (* can n'th-order tensor construction appear inline *)
18 :     val inlineMatrixExp : bool (* can matrix-valued expressions appear inline? *)
19 : cchiw 2624 val isHwVec : int -> bool
20 :     val isVecTy : int -> bool
21 : jhr 2632 val getPieces : int -> int list
22 : cchiw 2671 val getVecTy : int -> bool * int *int list
23 :    
24 : jhr 1115 end) : sig
25 :    
26 :     val translate : LowIL.program -> TreeIL.program
27 :    
28 :     end = struct
29 :    
30 : cchiw 2646
31 :     structure Src = LowIL
32 :     structure SrcOp = LowOps
33 : cchiw 2691 structure SrcV = LowIL.Var
34 :     structure SrcSV = LowIL.StateVar
35 : cchiw 2646 structure VA = VarAnalysis
36 :     structure Ty = LowILTypes
37 : jhr 1115 structure Nd = LowIL.Node
38 :     structure CFG = LowIL.CFG
39 : cchiw 2691 structure LowOpToTreeOp = LowOpToTreeOp
40 :     structure Dst = TreeIL
41 :     structure DstOp = TreeOps
42 : cchiw 2838 structure DstSV = Dst.StateVar
43 : cchiw 2844 structure SrcTy = LowILTypes
44 :     structure DstTy = TreeILTypes
45 :     structure DstV = Dst.Var
46 : cchiw 2691 structure TreeToOpr=TreeToOpr
47 :     structure Fnc=TreeFunc
48 :     structure TySet= Fnc.TySet
49 :     structure OprSet= Fnc.OprSet
50 : cchiw 2845 structure LowToS=LowToString
51 : cchiw 2688
52 : jhr 1115 (* create new tree IL variables *)
53 :     local
54 : cchiw 2646 val newVar = Dst.Var.new
55 : jhr 1115 val cnt = ref 0
56 :     fun genName prefix = let
57 : jhr 2356 val n = !cnt
58 :     in
59 :     cnt := n+1;
60 :     String.concat[prefix, "_", Int.toString n]
61 :     end
62 : jhr 1115 in
63 : cchiw 2842 val testing=0
64 : cchiw 2838 fun testp str=(case testing
65 :     of 1=> (print(String.concat str);1)
66 : cchiw 2628 | _ =>1
67 :     (*end case*))
68 : cchiw 2844 fun iTos n =Int.toString n
69 : cchiw 2838
70 : jhr 2632
71 : cchiw 2691 fun newGlobal x = newVar (genName("G_" ^ SrcV.name x), Dst.VK_Global, SrcV.ty x)
72 :     fun newParam x = newVar (genName("p_" ^ SrcV.name x), Dst.VK_Local, SrcV.ty x)
73 :     fun newLocal x = newVar (genName("l_" ^ SrcV.name x), Dst.VK_Local, SrcV.ty x)
74 :     fun newIter x = newVar (genName("i_" ^ SrcV.name x), Dst.VK_Local, SrcV.ty x)
75 : cchiw 2844 fun newTmp (x,n) = newVar (genName("l_" ^ iTos n^SrcV.name x), Dst.VK_Local, SrcV.ty x)
76 : cchiw 2827 fun newLocalPtrTy (name,ty)= newVar(genName("l_rp_"^name), Dst.VK_Local,ty)
77 : cchiw 2844 fun newLocalWithTy (name,n)= newVar(genName("l_"^iTos n^name), Dst.VK_Local,Ty.TensorTy [n])
78 :     fun newGlobalWithTy (name,n)= newVar(genName("G_"^iTos n^name), Dst.VK_Global,Ty.TensorTy [n])
79 : cchiw 2827
80 : jhr 1115 end
81 :    
82 : jhr 1640 (* associate Tree IL state variables with Low IL variables using properties *)
83 :     local
84 : cchiw 2646 fun mkStateVar x = Dst.SV{
85 : cchiw 2691 name = SrcSV.name x,
86 : jhr 1640 id = Stamp.new(),
87 : cchiw 2691 ty = SrcSV.ty x,
88 : jhr 1640 varying = VA.isVarying x,
89 : cchiw 2691 output = SrcSV.isOutput x
90 : jhr 1640 }
91 :     in
92 : cchiw 2691 val {getFn = getStateVar, ...} = SrcSV.newProp mkStateVar
93 : jhr 1640 end
94 :    
95 : cchiw 2646 fun mkBlock stms = Dst.Block{locals=[], body=stms}
96 :     fun mkIf (x, stms, []) = Dst.S_IfThen(x, mkBlock stms)
97 :     | mkIf (x, stms1, stms2) = Dst.S_IfThenElse(x, mkBlock stms1, mkBlock stms2)
98 : jhr 1115
99 :     (* an environment that tracks bindings of variables to target expressions and the list
100 :     * of locals that have been defined.
101 :     *)
102 :     local
103 : cchiw 2691 structure VT = SrcV.Tbl
104 : cchiw 2646 fun decCount ( Src.V{useCnt, ...}) = let
105 : jhr 2356 val n = !useCnt - 1
106 :     in
107 :     useCnt := n; (n <= 0)
108 :     end
109 : jhr 1115 datatype target_binding
110 : cchiw 2646 = GLOB of Dst.var (* variable is global *)
111 :     | TREE of Dst.exp (* variable bound to target expression tree *)
112 :     | DEF of Dst.exp (* either a target variable or constant for a defined variable *)
113 : cchiw 2637
114 :    
115 :     fun insert (key, value) d =fn s =>
116 :     if s = key then SOME value
117 :     else d s
118 :    
119 :     fun lookup k d = d k
120 :    
121 :    
122 :     structure ListSetOfInts = ListSetFn (struct
123 :     type ord_key = int
124 :     val compare = Int.compare
125 :     end)
126 :    
127 : cchiw 2844 (*changed env to add sets Tys and Oprs*)
128 : jhr 1115 datatype env = E of {
129 : jhr 2356 tbl : target_binding VT.hash_table,
130 : cchiw 2637 types: TySet.set,
131 :     functs : OprSet.set,
132 : cchiw 2646 locals : Dst.var list
133 : jhr 2356 }
134 : cchiw 2637
135 : jhr 1115 in
136 :     (* DEBUG *)
137 : cchiw 2637
138 : cchiw 2844
139 : cchiw 2637 fun peelEnv(E{tbl, types, functs ,locals})=(types,functs)
140 : cchiw 2691 fun peelEnvLoc(E{tbl, types, functs ,locals})=locals
141 : cchiw 2844 fun setEnv(E{tbl, types,functs,locals},types1,functs1)= E{tbl=tbl, types=types1, functs= functs1 ,locals=locals}
142 : cchiw 2637
143 : cchiw 2844 (*addOprFromExp: env* TreeIL.Exp-> env
144 :     * get new opr and type set and store it into the environment
145 :     *)
146 :     fun addOprFromExp(env,exp)=let
147 :     val t1=peelEnv env
148 :     val (ty2,opr2)= TreeToOpr.expToOpr (t1,exp)
149 :     in
150 :     setEnv(env, ty2,opr2)
151 :     end
152 :    
153 :     (*addOprFromStmt: env* TreeIL.Stmt-> env
154 :     * get new opr and type set and store it into the environment
155 :     *)
156 :     fun addOprFromStmt(env,stms)=let
157 :     val t1=peelEnv(env)
158 :     val (ty2,opr2)= TreeToOpr.stmtsToOpr ( t1 ,stms)
159 :     in
160 :     setEnv(env, ty2,opr2)
161 :     end
162 :    
163 :    
164 : jhr 1115 fun bindToString binding = (case binding
165 : cchiw 2646 of GLOB y => "GLOB " ^ Dst.Var.name y
166 : jhr 2356 | TREE e => "TREE"
167 : cchiw 2688 | DEF(Dst.E_Var y) => "DEFVar " ^ Dst.Var.name y
168 : cchiw 2692 | DEF e => "DEF"^Dst.toString e
169 : jhr 1115 (* end case *))
170 :     fun dumpEnv (E{tbl, ...}) = let
171 :     fun prEntry (x, binding) =
172 : cchiw 2838 testp[" ", Src.Var.toString x, " --> ", bindToString binding, "\n"]
173 : jhr 1115 in
174 : cchiw 2791 (* print "\n *** dump environment\n";
175 : jhr 2356 VT.appi prEntry tbl;
176 : cchiw 2791 print "***\n"*) print ""
177 : jhr 1115 end
178 :     (* DEBUG *)
179 :    
180 : cchiw 2637 fun newEnv () = E{tbl = VT.mkTable (512, Fail "tbl"), types=TySet.empty, functs=OprSet.empty, locals=[]}
181 : jhr 1115
182 :     (* use a variable. If it is a pending expression, we remove it from the table *)
183 : cchiw 2692 fun peek (env as E{tbl, ...}) x = (case (VT.find tbl x)
184 :     of NONE=>"none"
185 :     | SOME e=> bindToString e
186 :     (*end case *))
187 :    
188 :     fun useVar (env as E{tbl, ...}) x = (case VT.find tbl x
189 : cchiw 2791 of SOME(GLOB x') => ( (*print ("\n usevar found Glob "^SrcV.name x^"\n") ;*)Dst.E_Var x')
190 : jhr 2356 | SOME(TREE e) => (
191 : cchiw 2691 (*print(concat["useVar ", SrcV.toString x, " ==> TREE\n"]);*)
192 : jhr 2356 ignore(VT.remove tbl x);
193 :     e)
194 :     | SOME(DEF e) => (
195 : cchiw 2691 (*print(concat["useVar ", SrcV.toString x, " ==> ", bindToString(DEF e), "; use count = ", Int.toString(SrcV.useCount x), "\n"]);*)
196 : jhr 2356 (* if this is the last use of x, then remove it from the table *)
197 : cchiw 2791 (*if (decCount x) then ignore(VT.remove tbl x) else ();*)
198 :     (*print ("\n found Def "^SrcV.name x^"\n");*)
199 : jhr 2356 e)
200 :     | NONE => (
201 : jhr 1115 dumpEnv env;
202 : cchiw 2691 raise Fail(concat ["useVar(", SrcV.toString x, ")"])
203 : jhr 1115 )
204 : jhr 2356 (* end case *))
205 : jhr 1115
206 : cchiw 2844 (* record a local variable *)
207 : cchiw 2637 fun addLocal (E{tbl, types,functs,locals}, x) = E{tbl=tbl,types=types, functs=functs,locals=x::locals}
208 : cchiw 2844 fun addLocals (E{tbl, types,functs,locals}, x) = E{tbl=tbl,types=types, functs=functs,locals=x@locals}
209 :     fun global (E{tbl, ...}, x, x') =(VT.insert tbl (x, GLOB x'))
210 : jhr 1115
211 :     (* insert a pending expression into the table. Note that x should only be used once! *)
212 :     fun insert (env as E{tbl, ...}, x, exp) = (
213 : jhr 2356 VT.insert tbl (x, TREE exp);
214 :     env)
215 : jhr 1115
216 :     fun rename (env as E{tbl, ...}, x, x') = (
217 : cchiw 2646 VT.insert tbl (x, DEF(Dst.E_Var x'));
218 : jhr 2356 env)
219 : cchiw 2687
220 : cchiw 2692 fun renameGlob (env as E{tbl, ...}, x, x') = (
221 :     VT.insert tbl (x, GLOB( x'));
222 : cchiw 2687 env)
223 : cchiw 2692
224 : cchiw 2789 fun renameExp (env as E{tbl, ...}, x, x') = (
225 : cchiw 2692 VT.insert tbl (x, DEF( x'));
226 :     env)
227 : cchiw 2688
228 : cchiw 2692
229 : cchiw 2688 fun peekGlobal (E{tbl, ...}, x) = (case VT.find tbl x
230 : cchiw 2691 of SOME(GLOB x') => SOME x'
231 :     | SOME e => NONE
232 :     | NONE => NONE
233 :     (* end case *))
234 : cchiw 2838
235 : cchiw 2844 (*bindLocal: env*SrcV*Dst.Exp-> env*Dst.S list
236 :     * if lhs variable is used once then it is inserted
237 :     * else if lhs is used multiple times then new local variables are created
238 :     * when exp is a mux more ops are used
239 :     *)
240 : cchiw 2687 fun bindLocal (env, lhs, rhs) =let
241 : cchiw 2691 val n=SrcV.useCount lhs
242 : cchiw 2844 val _=testp ["\n In BindLocal: \n \t LHS: ",SrcV.name lhs, " Count \t",Int.toString n," rhs:", Dst.toString rhs ,"\n"]
243 : cchiw 2688 in (case (n,rhs)
244 : cchiw 2791 of (0,_) => (env,[])
245 : cchiw 2844 | (1,_) => (insert(addOprFromExp(env,rhs), lhs, rhs), [])
246 : cchiw 2795 | (_,Dst.E_Mux(A,isFill, nOrig,Tys as Ty.vectorLength tys,exps))=> let
247 : cchiw 2789 val name=SrcV.name lhs
248 : cchiw 2791 val vs=List.map (fn n=> newLocalWithTy(name,n) ) tys
249 : cchiw 2795 val rhs=Dst.E_Mux(A, isFill,nOrig,Tys,List.map (fn v=>Dst.E_Var v) vs)
250 : cchiw 2791 val stmts=ListPair.map (fn(x,e)=>Dst.S_Assign([x],e)) (vs,exps)
251 : cchiw 2692 in
252 : cchiw 2791 (renameExp(addLocals(env,vs),lhs,rhs),stmts)
253 : cchiw 2687 end
254 : cchiw 2838 |(_,_)=> let
255 :     val t = newLocal lhs
256 :     in
257 :     (rename(addLocal(env, t), lhs, t), [Dst.S_Assign([t], rhs)])
258 :     end
259 : cchiw 2688 (*end case*))
260 : cchiw 2687 end
261 :    
262 : cchiw 2691
263 :     fun bind (env, lhs, rhs) =(case peekGlobal (env, lhs)
264 : cchiw 2844 of SOME x =>((env, [Dst.S_Assign([x], rhs)]))
265 :     | NONE => (bindLocal (env, lhs, rhs))
266 : cchiw 2691 (* end case *))
267 : jhr 1115
268 :     (* set the definition of a variable, where the RHS is either a literal constant or a variable *)
269 : cchiw 2691 fun bindSimple (env as E{tbl, ...}, lhs, rhs) =(case peekGlobal (env, lhs)
270 :     of SOME x => (env, [Dst.S_Assign([x], rhs)])
271 :     | NONE => (VT.insert tbl (lhs, DEF rhs); (env, []))
272 :     (* end case *))
273 : cchiw 2688
274 : jhr 1115
275 :     (* at the end of a block, we need to assign any pending expressions to locals. The
276 :     * blkStms list and the resulting statement list are in reverse order.
277 :     *)
278 : cchiw 2637 fun flushPending (E{tbl,types, functs,locals}, blkStms) = let
279 : jhr 2356 fun doVar (x, TREE e, (locals, stms)) = let
280 :     val t = newLocal x
281 :     in
282 : cchiw 2646 VT.insert tbl (x, DEF(Dst.E_Var t));
283 :     (t::locals, Dst.S_Assign([t], e)::stms)
284 : jhr 2356 end
285 :     | doVar (_, _, acc) = acc
286 :     val (locals, stms) = VT.foldi doVar (locals, blkStms) tbl
287 :     in
288 : cchiw 2637 (E{tbl=tbl, types=types,functs=functs,locals=locals}, stms)
289 : jhr 2356 end
290 : jhr 1115
291 : cchiw 2646 fun doPhi ((lhs, rhs), (env, predBlks : Dst.stm list list)) = let
292 : jhr 2356 (* t will be the variable in the continuation of the JOIN *)
293 :     val t = newLocal lhs
294 :     val predBlks = ListPair.map
295 : cchiw 2646 (fn (x, stms) => Dst.S_Assign([t], useVar env x)::stms)
296 : jhr 2356 (rhs, predBlks)
297 :     in
298 :     (rename (addLocal(env, t), lhs, t), predBlks)
299 :     end
300 : cchiw 2844
301 :    
302 :     (*
303 :     fun endScope (E{locals, ...}, stms) = Dst.Block{
304 : jhr 2356 locals = List.rev locals,
305 :     body = stms
306 : cchiw 2844 }
307 :     *)
308 : cchiw 2637 fun endScope (env, stms) = let
309 : cchiw 2844 val env'=addOprFromStmt(env, stms)
310 :     val (types,opr)=peelEnv(env')
311 :     in Dst.BlockWithOpr{
312 : cchiw 2637 locals= List.rev(peelEnvLoc env),
313 :     types= types,
314 :     opr=opr,
315 :     body = stms
316 :     }
317 :     end
318 : jhr 1115 end
319 :    
320 :     (* Certain IL operators cannot be compiled to inline expressions. Return
321 :     * false for those and true for all others.
322 :     *)
323 : cchiw 2680
324 : jhr 1115 fun isInlineOp rator = let
325 : jhr 2356 fun chkTensorTy (Ty.TensorTy[]) = true
326 :     | chkTensorTy (Ty.TensorTy[_]) = true
327 :     | chkTensorTy (Ty.TensorTy[_, _]) = Target.inlineMatrixExp
328 :     | chkTensorTy _ = false
329 : cchiw 2688
330 : jhr 2356 in
331 :     case rator
332 : cchiw 2646 of SrcOp.LoadVoxels(_, 1) => true
333 :     | SrcOp.LoadVoxels _ => false
334 :     | SrcOp.EigenVecs2x2 => false
335 :     | SrcOp.EigenVecs3x3 => false
336 :     | SrcOp.EigenVals2x2 => false
337 :     | SrcOp.EigenVals3x3 => false
338 : cchiw 2691 (* | SrcOp.Zero _ => Target.inlineMatrixExp*)
339 : cchiw 2680 | _ => true (*when true calls binding *)
340 : jhr 2356 (* end case *)
341 :     end
342 : jhr 1115
343 : cchiw 2669 (*HERE- since we are using arrays, nothing can be inline
344 :     Fix later if it needs to be fixed*)
345 : cchiw 2525 (* is a CONS inline? *)
346 : cchiw 2669 fun isInlineCons ty = (*(case ty
347 : cchiw 2525 of Ty.SeqTy(Ty.IntTy, _) => true
348 :     | Ty.TensorTy dd => Target.inlineCons(List.length dd)
349 :     | Ty.SeqTy _ => false
350 :     (*CCCC-? DO we have this type*)
351 : cchiw 2615 (* | Ty.DynSeqTy ty => false*)
352 : cchiw 2525 | _ => raise Fail(concat["invalid CONS<", Ty.toString ty, ">"])
353 : cchiw 2669 (* end case *))*) false
354 : cchiw 2525
355 :     (* translate a LowIL assignment to a list of zero or more target statements in reverse
356 :     * order.
357 :     *)
358 : cchiw 2688
359 :    
360 :    
361 : jhr 1115 fun doAssign (env, (lhs, rhs)) = let
362 : cchiw 2688
363 : jhr 2356 fun doLHS () = (case peekGlobal(env, lhs)
364 : cchiw 2688 of SOME lhs' => (env, lhs')
365 :     | NONE => let
366 :     val t = newLocal lhs
367 :     in
368 :     (rename (addLocal(env, t), lhs, t), t)
369 :     end
370 :     (* end case *))
371 :    
372 : jhr 2356 (* for expressions that are going to be compiled to a call statement *)
373 :     fun assignExp (env, exp) = let
374 :     (* operations that return matrices may not be supported inline *)
375 :     val (env, t) = doLHS()
376 :     in
377 : cchiw 2646 (env, [Dst.S_Assign([t], exp)])
378 : jhr 2356 end
379 : cchiw 2680
380 : jhr 2632
381 : cchiw 2525 (* force an argument to be stored in something that will be mapped to an l-value *)
382 :     fun bindVar (env, x) = (case useVar env x
383 : cchiw 2688 of x' as Dst.E_State _ =>(env, x', [])
384 :     | x' as Dst.E_Var _ => (env, x', [])
385 :     | e => let
386 : cchiw 2525 val x' = newLocal x
387 :     in
388 : cchiw 2646 (addLocal(env, x'), Dst.E_Var x', [Dst.S_Assign([x'], e)])
389 : cchiw 2525 end
390 :     (* end case *))
391 : cchiw 2692
392 : cchiw 2845 val _=LowToS.ASSIGNtoString(lhs,rhs)
393 : cchiw 2844
394 :     (* opToString:LowIL.Ops* LowIL.Var list-> int
395 :     *Just used to print information about the op
396 :     *)
397 : cchiw 2830 fun opToString (rator,arg)= let
398 :     val r=SrcOp.toString rator
399 :     val a= String.concatWith " , " (List.map (fn e=> Dst.toString e) arg)
400 :     in
401 :    
402 : cchiw 2844 testp[ "\n ***** New Op**** \n ",r,"\n Args(",a,")"]
403 : cchiw 2830
404 : cchiw 2838 end
405 : jhr 2356 in
406 :     case rhs
407 : cchiw 2838 of Src.STATE x =>let
408 : cchiw 2844 (* Hmm, what to do with State nodes.
409 :     * They get represented like globals but their other operations register their kind as local
410 :     * Leads to trouble in their representation
411 :     * Fix me, once we change representation of state and local vars
412 :     * currently we load 1 piece when it is a local var.
413 :     * fun iter([],_)=[]
414 :     * | iter(e1::es,counter)=[Dst.E_LoadArr(isFill ,e1,oSize, t , Dst.E_Lit(Literal.Int counter))]@
415 :     * | iter(es,counter+ IntInf.fromInt e1)
416 :     * val ops=iter(Pieces,0)
417 :     *)
418 :     val (env, vt) = doLHS()
419 :     val t=Dst.E_State(getStateVar x)
420 :     val exp=(case (DstV.kind vt, DstV.ty vt)
421 : cchiw 2838 of (Dst.VK_Local,DstTy.TensorTy [oSize])=>let
422 :     val (isFill,nSize,Pieces)=Target.getVecTy oSize
423 :     val op1= Dst.E_LoadArr(false ,nSize,oSize, t , Dst.E_Lit(Literal.Int 0))
424 :     val splitTy=DstTy.vectorLength Pieces
425 :     in Dst.E_Mux(false,isFill,oSize,splitTy,[op1])
426 :     end
427 :     | _ => t
428 :     (*end case *))
429 : cchiw 2844 in
430 :     bindSimple (env, lhs,exp)
431 :     end
432 : cchiw 2688 | Src.VAR x => bindSimple (env, lhs, useVar env x)
433 :     | Src.LIT lit => bindSimple (env, lhs, Dst.E_Lit lit)
434 : jhr 2632
435 : cchiw 2845 (*need to put input operations back in! copied from vis branch.*)
436 :     (*
437 :     | IL.OP(Op.Input(InP.INP{ty=Ty.DynSeqTy _, name, desc, init}), []) => let
438 :     fun mkStm gv = (case init
439 :     of NONE => T.S_InputNrrd(gv, name, desc, NONE)
440 :     | SOME(InP.DynSeq nrrd) => T.S_InputNrrd(gv, name, desc, SOME nrrd)
441 :     | _ => raise Fail "bogus initialization for dynamic sequence"
442 :     (* end case *))
443 :     in
444 :     (recordInput (env, lhs, mkStm), [])
445 :     end
446 :     | IL.OP(Op.Input(InP.INP{ty=Ty.ImageTy _, name, desc, init}), []) => let
447 :     fun mkStm gv = (case init
448 :     of SOME(InP.Proxy(nrrd, _)) => T.S_InputNrrd(gv, name, desc, SOME nrrd)
449 :     | SOME(InP.Image _) => T.S_InputNrrd(gv, name, desc, NONE)
450 :     | _ => raise Fail "bogus initialization for image"
451 :     (* end case *))
452 :     in
453 :     (recordInput (env, lhs, mkStm), [])
454 :     end
455 :     | IL.OP(Op.Input(InP.INP{ty, name, desc, init=NONE}), []) => let
456 :     fun mkStm gv = T.S_Input(gv, name, desc, NONE)
457 :     in
458 :     (recordInput (env, lhs, mkStm), [])
459 :     end
460 :     | IL.OP(Op.InputWithDefault(InP.INP{ty, name, desc, init=NONE}), [dflt]) => let
461 :     val dflt = useVar env dflt
462 :     fun mkStm gv = T.S_Input(gv, name, desc, SOME dflt)
463 :     in
464 :     (recordInput (env, lhs, mkStm), [])
465 :     end
466 :     *)(*
467 :     | Src.OP( SrcOp.Prepend ty, [item, seq]) => let
468 : jhr 2356 val (env, t) = doLHS()
469 : cchiw 2525 val (env, item', stms) = bindVar (env, item)
470 : cchiw 2646 val exp = Dst.E_Op( DstOp.Prepend ty, [item', useVar env seq])
471 : jhr 2356 in
472 : cchiw 2646 (env, Dst.S_Assign([t], exp) :: stms)
473 : jhr 2356 end
474 : cchiw 2838 | Src.OP( SrcOpp.Append ty, [seq, item]) => let
475 : jhr 2356 val (env, t) = doLHS()
476 : cchiw 2525 val (env, item', stms) = bindVar (env, item)
477 : cchiw 2646 val exp = Dst.E_Op( DstOp.Append ty, [useVar env seq, item'])
478 : jhr 2356 in
479 : cchiw 2646 (env, Dst.S_Assign([t], exp) :: stms)
480 : cchiw 2615 end*)
481 : cchiw 2670
482 : cchiw 2838 | Src.OP(SrcOp.Kernel _,_) => (env, [])
483 :     | Src.OP(SrcOp.LoadImage info,[a]) => let
484 :     val dim = ImageInfo.dim info
485 :     val (env, t) = doLHS()
486 :     in
487 :     (env,[Dst.S_LoadImage(t, dim, (useVar env a))])
488 :     end
489 :    
490 :     | Src.OP(SrcOp.Inside (info,s),args) => let
491 :     val [a,b]=List.map (useVar env) args
492 :     val size=(case (ImageInfo.dim info)
493 : cchiw 2844 of 1=> raise Fail"Inside of 1-D dimension"
494 :     | 2=> 2
495 :     | 3=> 4
496 :     (*end case*))
497 :     (*separated the position to make it look cleaner*)
498 :     val k=newLocalWithTy ("Pos_"^SrcV.name lhs ,size)
499 : cchiw 2838 val s1= Dst.S_Assign([k],a)
500 :     val rhs=Dst.E_Op(DstOp.Inside(info,s),[Dst.E_Var k,b])
501 :     val (env,s)=bind(addLocal(env,k),lhs,rhs)
502 :     in
503 :     (env,[s1]@s)
504 :     end
505 :     | Src.OP(SrcOp.Translate v, [a])=> let
506 : cchiw 2844 (*Result is a vector so we have to use Mux*)
507 : cchiw 2838 val dim = ImageInfo.dim v
508 :     val splitTy=DstTy.vectorLength [dim]
509 :     val op1= Dst.E_Op(DstOp.Translate v,[(useVar env a)])
510 :     val exp= (case dim
511 :     of 1=> op1
512 : cchiw 2844 | 2 => Dst.E_Mux(true,false,dim,splitTy,[op1])
513 : cchiw 2838 | 3=> Dst.E_Mux(false,false,dim,splitTy,[op1])
514 :     (*end case*))
515 : cchiw 2844 in
516 :     bind(env,lhs,exp)
517 :     end
518 : cchiw 2838 | Src.OP(SrcOp.Transform v,args) => let
519 : cchiw 2844 (*Result is an array so we have to use Store*)
520 : cchiw 2838 val (env2, t) = doLHS()
521 :     val V=Dst.E_Var t
522 :     val dim = ImageInfo.dim v
523 :     val ty=DstTy.TensorTy [dim,dim]
524 :     val args'=List.map (useVar env) args
525 :     val a=List.tabulate(dim,(fn n=> Dst.E_Op(DstOp.Transform(v,n),args')))
526 :     val (env2,stmt)= (case dim
527 :     of 1=> bind(env2,lhs,Dst.E_Op(DstOp.Transform (v,1),args'))
528 :     | 2 =>(env2,[Dst.S_StoreVec(V,0,true,false,dim,ty,DstTy.vectorLength [2,2],a)])
529 :     | 3 =>(env2,[Dst.S_StoreVec(V,0,false,true,dim,ty,DstTy.vectorLength [4,4,4] ,a)])
530 :     (*end case*))
531 :     in
532 :     (env2,stmt)
533 :     end
534 :     | Src.OP(SrcOp.imgLoad(info,dim,oSize),[a])=>let
535 : cchiw 2844 (*create ptr variable vp and index it with stride*)
536 : cchiw 2838 val vp= newLocalPtrTy(SrcV.name lhs,DstTy.AddrTy info)
537 :     val stmt=Dst.S_Assign([vp], useVar env a)
538 :     val stride = ImageInfo.stride info
539 : cchiw 2844 val IndexArgs= List.tabulate(oSize,
540 :     fn n=> Dst.E_Op(DstOp.IndexTensor(false,Ty.indexTy [n*stride],Ty.TensorTy [oSize]),[Dst.E_Var vp]))
541 : cchiw 2838 (*create cons expressions*)
542 :     val (isFill,nSize,Pieces)=Target.getVecTy oSize
543 :     val exp=LowOpToTreeOp.consVecToTree(nSize,oSize,Pieces,IndexArgs,isFill)
544 :     (*increase use count so it is easier to read c-file*)
545 :     fun incUse (Src.V{useCnt, ...}) = (useCnt := !useCnt + 1)
546 : cchiw 2844 val _ = incUse lhs
547 :     val (env2,stmt2)=bind (addLocal(env, vp), lhs,exp)
548 : cchiw 2838 in
549 :     (env2, List.rev stmt2@[stmt])
550 :     end
551 : cchiw 2844 | Src.OP(SrcOp.IndexTensor e,[a])=> let
552 :     (*IndexTensor operation is int*ty*ty
553 :     * The first ty is the list of indexed position and second ty is the type of the argument
554 :     * When the rhs is a mux(matrix.. or larger arg) then we look for the right argument to index
555 :     * Otherwise we just pass the variable kind to the tree-il op and let c-util decide how/where to index
556 :     * The kind of variable decides if there is cast in the c-code
557 :     *)
558 :     val a'=(useVar env a)
559 :     val exp=(case ((SrcOp.IndexTensor e),a') of
560 :     (SrcOp.IndexTensor(_ ,Ty.indexTy [i],_),Dst.E_Mux(_,_,_,DstTy.vectorLength pieces,ops))=> let
561 :     fun findLocal(c,i,indexAt,v::vs,a1::args)=let
562 :     val newsize=c+v
563 :     in if(newsize>i) then Dst.E_Op(DstOp.IndexTensor(true,Ty.indexTy [indexAt],Ty.TensorTy [v]), [a1])
564 :     else findLocal(newsize,i,indexAt-v,vs,args)
565 :     end
566 :     val exp =findLocal(0,i,i,pieces,ops)
567 :     in
568 :     exp
569 :     end
570 :     | (SrcOp.IndexTensor( _ , indTy,argTy),Dst.E_Var v) => (case (DstV.kind v)
571 :     of TreeIL.VK_Local=>Dst.E_Op(DstOp.IndexTensor(true ,indTy,argTy),[a'])
572 :     | _ =>Dst.E_Op(DstOp.IndexTensor(false ,indTy,argTy),[a'])
573 :     (*end case*))
574 :     | (SrcOp.IndexTensor( _ , indTy,argTy),_) => Dst.E_Op(DstOp.IndexTensor(true ,indTy,argTy),[a'])
575 :    
576 :     (*end case*))
577 :     in
578 :     bind (env, lhs, exp)
579 :     end
580 : cchiw 2838
581 : cchiw 2827 | Src.OP(rator,args) =>let
582 : cchiw 2795 val args'=List.map (useVar env) args
583 : cchiw 2845 val _ =testp[ "\n ***** New Op \n \t\t",SrcV.name lhs,"-",SrcOp.toString rator,Int.toString(length(args))
584 :     , " Args(\n\t",String.concatWith"\n\t\t," (List.map (fn e=> Dst.toString e) args'),")"]
585 : cchiw 2844 (*foundVec:SrcOp.op* DstOP.ops*int*DstVar list *DstVar list
586 :     * Found a vector operation.
587 :     * Rewrites to correctly-sized vector operations
588 :     *)
589 : cchiw 2827 fun foundVec(origrator,rator,oSize,argsS,argsV)= let
590 :     val (isFill,nSize,Pieces)=Target.getVecTy oSize
591 :     val (env, t) = doLHS()
592 :     val stmt = LowOpToTreeOp.vecToTree(t,origrator,rator,nSize,oSize,Pieces,argsS,argsV,isFill)
593 :     val (envv,stmts)=(case stmt
594 :     of Dst.S_Assign(_,exp)=> bind (env, lhs, exp)
595 :     | stmt=> (env,[stmt])
596 :     (*end case*))
597 : cchiw 2844 val _ = testp["\n \n\t",Dst.toStringS stmt]
598 : cchiw 2827 in
599 :     (envv,stmts)
600 :     end
601 : cchiw 2680 in (case (rator,args')
602 : cchiw 2838 of (SrcOp.addVec n,_) => foundVec(rator,DstOp.addVec,n,[],args')
603 :     | (SrcOp.subVec n,_) => foundVec(rator,DstOp.subVec,n,[],args')
604 :     | (SrcOp.prodScaV n,e1::es) => foundVec(rator,DstOp.prodScaV ,n, [e1], es)
605 :     | (SrcOp.prodVec n,_) => foundVec(rator,DstOp.prodVec,n,[],args')
606 :     | (SrcOp.sumVec n ,_) => foundVec(rator,DstOp.addVec ,n,[],args')
607 :     | (SrcOp.Floor n ,_) => foundVec(rator,DstOp.Floor ,n,[],args')
608 :     | (SrcOp.ProjectTensor(_,n,_,_),_) => foundVec(rator,DstOp.addVec ,n,[],args')
609 : cchiw 2830 | (SrcOp.Clamp (Ty.TensorTy[n]) ,_) => foundVec(rator,DstOp.clampVec ,n,[],args')
610 : cchiw 2838 | (SrcOp.Lerp (Ty.TensorTy[n]) ,[a,b,c]) => foundVec(rator,DstOp.lerpVec ,n,[c],[a,b])
611 : cchiw 2844 | (SrcOp.Normalize n,_) => foundVec(rator,DstOp.Normalize ,n,[],args')
612 :     | (SrcOp.addSca ,[a,Dst.E_Lit (Literal.Int 0)]) => assignExp (env,a)
613 :     | (SrcOp.addSca ,[Dst.E_Lit (Literal.Int 0),a]) => assignExp (env,a)
614 :     | (SrcOp.subSca ,[a,Dst.E_Lit (Literal.Int 0)]) => assignExp (env,a)
615 : cchiw 2680 | _ => let
616 : cchiw 2637 val Trator = LowOpToTreeOp.expandOp rator
617 : cchiw 2671 val exp = Dst.E_Op(Trator, args')
618 : cchiw 2620 in
619 : cchiw 2688 if isInlineOp rator then (bind (env, lhs, exp))
620 :     else (assignExp (env, exp))
621 : cchiw 2620 end
622 :     (*end case*))
623 : cchiw 2827 end
624 : cchiw 2646 | Src.APPLY(f, args) =>
625 :     bind (env, lhs, Dst.E_Apply(f, List.map (useVar env) args))
626 : cchiw 2692 | Src.CONS(ty as Ty.TensorTy[oSize], args) => let
627 : cchiw 2844 (* CONS of a vector with real arguments
628 :     * If lhs is a local var then we assume lhs will be represented with vectors
629 :     * and we use Mux and E_ConsVec on pieces, much like a vector op
630 :     * Otherwise, assume it's an array and use S_Cons
631 : cchiw 2845 * testp["\n ****** here **\n ",LowToS.rhsToString (Src.CONS(ty , args)),
632 : cchiw 2844 "\n\t* lhs " ,SrcV.name lhs,"type",Ty.toString(SrcV.ty lhs),
633 :     "\nt",DstV.name t,"-kind:",Dst.kindToString (DstV.kind t),"\n"]
634 :     *)
635 :     val args'=List.map (useVar env) args
636 :     val (env2, t) = doLHS()
637 :     in (case DstV.kind t
638 :     of TreeIL.VK_Local=> let
639 :     val (isFill,nSize,Pieces)=Target.getVecTy oSize
640 :     val exp = LowOpToTreeOp.consVecToTree(nSize,oSize,Pieces,args',isFill)
641 :     val _ =testp["\nExp\n",Dst.toString exp]
642 :     in
643 :     bind (env2, lhs, exp)
644 :     end
645 :     | _ =>(env2,[Dst.S_Cons(t,oSize,args')])
646 :     (*end case*))
647 :     end
648 : cchiw 2845 (*| Src.CONS(ty as Ty.TensorTy [_,2], args)=>let
649 :     val args'=List.map (useVar env) args
650 :     val _=case args'
651 :    
652 :     val _=(case )
653 :     val (env2, t) = doLHS()
654 :     in
655 :     (env2,[Dst.S_Cons(t,4,args')])
656 :     end*)
657 : cchiw 2838 | Src.CONS(ty as Ty.TensorTy [_,j], args) =>let
658 : cchiw 2844 (* Cons is a matrix with vector arguments
659 :     * Each Vector Arg could be a global, local or state variable
660 :     * Which means their representation could be different
661 :     * when it is a global or state then we copy it S_Copy
662 :     * when it is a local or other then we use S_Store
663 :     *)
664 : cchiw 2791 val args' = List.map (useVar env) args
665 : cchiw 2844 val _ =testp["******************************\n CONS_Matrix \n With Args", Dst.toStrings args']
666 :     val (env2, t) = doLHS()
667 : cchiw 2838
668 : cchiw 2844
669 :     (*Vector params for last matrix index. Retrieved in case we use S_Store*)
670 : cchiw 2795 val (isFill,nSize,Pieces)=Target.getVecTy j
671 : cchiw 2827 val splitTy=LowILTypes.vectorLength Pieces
672 : cchiw 2838 val n=length Pieces
673 : cchiw 2844 val A =LowOpToTreeOp.isAlignedStore(isFill,n)
674 : cchiw 2827 fun f ([], _ ) = []
675 : cchiw 2844 | f (e1::es,count)=let
676 :     val t=(case e1
677 :     of Dst.E_State v=> Dst.S_Copy(Dst.E_Var t, e1, count,j)
678 :     | Dst.E_Var v=>(case (DstV.kind v)
679 :     of TreeIL.VK_Global => Dst.S_Copy(Dst.E_Var t, e1, count,j)
680 :     | _ =>
681 :     Dst.S_StoreVec(Dst.E_Var t,count,A,isFill,j,ty,splitTy, [e1])
682 :     (*end case*))
683 :     | _ => Dst.S_StoreVec(Dst.E_Var t,count,A,isFill,j,ty,splitTy, [e1])
684 : cchiw 2827 (*end case*))
685 : cchiw 2844 in
686 :     [t]@f(es,count+j)
687 :     end
688 : cchiw 2827 val stmts=f (args',0)
689 : cchiw 2844 val _ =testp["\n returning statements \n",Dst.toStringSs stmts,"\n end ******************************\n"]
690 : cchiw 2827 in
691 :     (env2, List.rev stmts)
692 : cchiw 2838 end
693 :     | Src.CONS(ty as Ty.TensorTy [_,i,j], args) =>let
694 : cchiw 2844 (* CONS is larger tensor with non-vector arguments
695 :     * Hooray! We can assume everything is an array and S_Copy everything
696 :     *)
697 : cchiw 2838 val args' = List.map (useVar env) args
698 : cchiw 2857 val _ =testp["******************************\n CONS_Matrix \n ",
699 :     "Number of args",Int.toString (length args),"---\n",Dst.toStrings args']
700 : cchiw 2838 val (env2, t) = doLHS()
701 : cchiw 2844 val shift=j*i (*New row index shift *)
702 : cchiw 2838 fun f ([], _ ) = []
703 :     | f (e1::es,count)= [Dst.S_Copy(Dst.E_Var t, e1, count,shift)]@ f(es,count+shift)
704 :     val stmts=f (args',0)
705 : cchiw 2857 val _ =testp["\n returning statements \n"^Dst.toStringSs stmts,"\n end ******************************\n"]
706 : cchiw 2838 in
707 :     (env2, List.rev stmts)
708 :     end
709 :    
710 : cchiw 2646 | Src.EINAPP _=> raise Fail "EINAPP in Low-IL to Tree-IL"
711 : jhr 2356 (* end case *)
712 :     end
713 : jhr 1115
714 :     (* In order to reconstruct the block-structure from the CFG, we keep a stack of open ifs.
715 :     * the items on this stack distinguish between when we are processing the then and else
716 :     * branches of the if.
717 :     *)
718 :     datatype open_if
719 :     (* working on the "then" branch. The fields are statments that preceed the if, the condition,
720 :     * and the else-branch node.
721 :     *)
722 : cchiw 2646 = THEN_BR of Dst.stm list * Dst.exp * Src.node
723 : jhr 1115 (* working on the "else" branch. The fields are statments that preceed the if, the condition,
724 :     * the "then" branch statements, and the node that terminated the "then" branch (will be
725 :     * a JOIN, DIE, or STABILIZE).
726 :     *)
727 : cchiw 2646 | ELSE_BR of Dst.stm list * Dst.exp * Dst.stm list * Src.node_kind
728 : jhr 1115
729 : cchiw 2628
730 : cchiw 2844 fun mkBlockOrig(Dst.BlockWithOpr{ locals ,types,opr,body})= Dst.Block{locals=locals ,body=body}
731 : cchiw 2830
732 : cchiw 2844 fun peelBlockOrig(env,Dst.BlockWithOpr{ locals ,types,opr,body})=let
733 : cchiw 2688 val env= setEnv(env,types,opr)
734 :     in
735 :     (env,Dst.Block{locals=locals ,body=body})
736 :     end
737 : cchiw 2637
738 : cchiw 2844 fun decCount ( Src.V{useCnt, ...}) = let
739 :     val n = !useCnt - 1
740 :     in
741 :     useCnt := n; (0 >= n)
742 :     end
743 : cchiw 2688
744 : jhr 1115 fun trCFG (env, prefix, finish, cfg) = let
745 : cchiw 2646 fun join (env, [], _, Src.JOIN _) = raise Fail "JOIN with no open if"
746 : cchiw 2830 | join (env, [], stms, _) = let
747 : cchiw 2844 val env'=addOprFromStmt(env, stms)
748 : cchiw 2838 in endScope (env', prefix @ List.rev stms) end
749 : jhr 2356 | join (env, THEN_BR(stms1, cond, elseBr)::stk, thenBlk, k) = let
750 : cchiw 2830
751 : jhr 2356 val (env, thenBlk) = flushPending (env, thenBlk)
752 : cchiw 2844 val env'=addOprFromStmt(env, stms1)
753 : jhr 2356 in
754 : cchiw 2838 doNode (env', ELSE_BR(stms1, cond, thenBlk, k)::stk, [], elseBr)
755 : jhr 2356 end
756 :     | join (env, ELSE_BR(stms, cond, thenBlk, k1)::stk, elseBlk, k2) = let
757 : cchiw 2830
758 : jhr 2356 val (env, elseBlk) = flushPending (env, elseBlk)
759 :     in
760 :     case (k1, k2)
761 : cchiw 2646 of ( Src.JOIN{phis, succ, ...}, Src.JOIN _) => let
762 : jhr 2356 val (env, [thenBlk, elseBlk]) =
763 :     List.foldl doPhi (env, [thenBlk, elseBlk]) (!phis)
764 :     val stm = mkIf(cond, List.rev thenBlk, List.rev elseBlk)
765 : cchiw 2830
766 : cchiw 2844 val env'=addOprFromStmt(env, stm::stms)
767 : jhr 2356 in
768 : cchiw 2830 doNode (env', stk, stm::stms, !succ)
769 : jhr 2356 end
770 : cchiw 2646 | ( Src.JOIN{phis, succ, ...}, _) => let
771 : jhr 2356 val (env, [thenBlk]) = List.foldl doPhi (env, [thenBlk]) (!phis)
772 :     val stm = mkIf(cond, List.rev thenBlk, List.rev elseBlk)
773 : cchiw 2830 in
774 : cchiw 2844 doNode (addOprFromStmt(env, [stm]), stk, stm::stms, !succ)
775 : jhr 2356 end
776 : cchiw 2646 | (_, Src.JOIN{phis, succ, ...}) => let
777 : jhr 2356 val (env, [elseBlk]) = List.foldl doPhi (env, [elseBlk]) (!phis)
778 :     val stm = mkIf(cond, List.rev thenBlk, List.rev elseBlk)
779 : cchiw 2830
780 :    
781 : jhr 2356 in
782 : cchiw 2844 doNode (addOprFromStmt(env, [stm]), stk, stm::stms, !succ)
783 : jhr 2356 end
784 :     | (_, _) => raise Fail "no path to exit unimplemented" (* FIXME *)
785 :     (* end case *)
786 :     end
787 : cchiw 2688 and doNode (env, ifStk : open_if list, stms, nd) =
788 : cchiw 2845 (* testp ["******************* \n doNode\n ",LowToS.printNode (Nd.kind nd),"\n"]*)
789 : cchiw 2688 (case Nd.kind nd
790 : cchiw 2646 of Src.NULL => raise Fail "unexpected NULL"
791 :     | Src.ENTRY{succ} => doNode (env, ifStk, stms, !succ)
792 : cchiw 2830 | k as Src.JOIN{phis, succ, ...} => (join (env, ifStk, stms, k))
793 : cchiw 2646 | Src.COND{cond, trueBranch, falseBranch, ...} => let
794 : jhr 2356 val cond = useVar env cond
795 :     val (env, stms) = flushPending (env, stms)
796 :     in
797 :     doNode (env, THEN_BR(stms, cond, !falseBranch)::ifStk, [], !trueBranch)
798 :     end
799 : cchiw 2646 | Src.COM {text, succ, ...} =>
800 :     doNode (env, ifStk, Dst.S_Comment text :: stms, !succ)
801 :     | Src.ASSIGN{stm, succ, ...} => let
802 : cchiw 2838
803 : jhr 2356 val (env, stms') = doAssign (env, stm)
804 : cchiw 2838
805 : jhr 2356 in
806 : cchiw 2844 doNode (addOprFromStmt(env, stms') , ifStk, stms' @ stms, !succ)
807 : jhr 2356 end
808 : cchiw 2646 | Src.MASSIGN{stm=(ys, rator, xs), succ, ...} => let
809 : cchiw 2688
810 : jhr 1640 fun doit () = let
811 :     fun doLHSVar (y, (env, ys)) = (case peekGlobal(env, y)
812 : cchiw 2688 of SOME y' => ((env, y'::ys))
813 : cchiw 2687 | NONE => let
814 : jhr 1640 val t = newLocal y
815 : cchiw 2688
816 : jhr 1640 in
817 :     (rename (addLocal(env, t), y, t), t::ys)
818 :     end
819 :     (* end case *))
820 :     val (env, ys) = List.foldr doLHSVar (env, []) ys
821 : cchiw 2637 val Trator = LowOpToTreeOp.expandOp rator
822 : cchiw 2646 val exp = Dst.E_Op(Trator, List.map (useVar env) xs)
823 :     val stm = Dst.S_Assign(ys, exp)
824 : jhr 1640 in
825 :     doNode (env, ifStk, stm :: stms, !succ)
826 :     end
827 :     in
828 :     case rator
829 : cchiw 2646 of SrcOp.Print _ => if Target.supportsPrinting()
830 : jhr 1640 then doit ()
831 :     else doNode (env, ifStk, stms, !succ)
832 :     | _ => doit()
833 :     (* end case *)
834 :     end
835 : cchiw 2646 | Src.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented"
836 : cchiw 2844 | Src.SAVE{lhs, rhs, succ, ...} => let
837 :     (* There is a Save and lhs is an array,
838 :     * Stmt depends on how rhs exp is stored
839 :     * If rhs is stored as a vector then use S_StoreVec(Mux, or Local Vector)
840 :     * If rhs is an array uses S_copy (higher order tensors)
841 :     * otherwise regular save
842 :     *)
843 :     val x=getStateVar lhs
844 :     val rhs2=useVar env rhs
845 :     val _ =testp["\n *********** \n FOUND SAVE \n\t StateVar: ",Dst.stateVarToString x,
846 :     ": Rest rhs: ",Dst.toString rhs2,"--end "]
847 :     fun size n=foldl (fn (a,b) => b*a) 1 n
848 :     val stm=(case rhs2
849 :     of Dst.E_Mux(A,isFill, oSize,splitTy,args) =>
850 :     (decCount rhs ;Dst.S_StoreVec( Dst.E_State x,0, A,isFill, oSize,Ty.TensorTy [oSize],splitTy,args))
851 :     | Dst.E_Var rhs3 => (case (DstV.kind rhs3,DstV.rTy rhs3)
852 :     of ( _ ,Ty.TensorTy []) => Dst.S_Save([x], rhs2)
853 :     | (Dst.VK_Local,Ty.TensorTy [oSize]) =>let
854 :     val (isFill,nSize,Pieces)=Target.getVecTy oSize
855 :     in Dst.S_StoreVec( Dst.E_State x,0, false,isFill, oSize,Ty.TensorTy [oSize],Ty.vectorLength Pieces,[rhs2])
856 : cchiw 2692 end
857 : cchiw 2844 | (_,Ty.TensorTy xs) => Dst.S_Copy( Dst.E_State x, rhs2,0,size xs)
858 :     | _ => Dst.S_Save([x], rhs2)
859 :     (*end case*))
860 :     | Dst.E_State rhs3 => (case (DstSV.ty rhs3)
861 :     of Ty.TensorTy xs => Dst.S_Copy( Dst.E_State x, rhs2,0,size xs)
862 : cchiw 2838 | _ => Dst.S_Save([x], rhs2)
863 :     (*end case*))
864 : cchiw 2844 | _ => Dst.S_Save([x], rhs2)
865 : cchiw 2838 (*end case*))
866 : cchiw 2845 val _ = testp [" \nSrc.Save: ",LowToS.SAVEtoString(lhs,rhs),"\n New stmt --",
867 : cchiw 2844 Dst.toStringS stm,"\nend save **************\n"]
868 : cchiw 2691 val stmts=stm::stms
869 : jhr 1640 in
870 : cchiw 2844 doNode (addOprFromStmt(env, stmts), ifStk, stmts, !succ)
871 : jhr 1640 end
872 : cchiw 2646 | k as Src.EXIT{kind, live, ...} => (case kind
873 : jhr 2356 of ExitKind.FRAGMENT =>
874 :     endScope (env, prefix @ List.revAppend(stms, finish env))
875 :     | ExitKind.SINIT => let
876 : jhr 1232 (* FIXME: we should probably call flushPending here! *)
877 : cchiw 2646 val suffix = finish env @ [Dst.S_Exit[]]
878 : jhr 2356 in
879 :     endScope (env, prefix @ List.revAppend(stms, suffix))
880 :     end
881 :     | ExitKind.RETURN => let
882 : jhr 1115 (* FIXME: we should probably call flushPending here! *)
883 : cchiw 2646 val suffix = finish env @ [Dst.S_Exit(List.map (useVar env) live)]
884 : jhr 2356 in
885 :     endScope (env, prefix @ List.revAppend(stms, suffix))
886 :     end
887 :     | ExitKind.ACTIVE => let
888 : jhr 1115 (* FIXME: we should probably call flushPending here! *)
889 : cchiw 2646 val suffix = finish env @ [Dst.S_Active]
890 : jhr 2356 in
891 :     endScope (env, prefix @ List.revAppend(stms, suffix))
892 :     end
893 :     | ExitKind.STABILIZE => let
894 : jhr 1115 (* FIXME: we should probably call flushPending here! *)
895 : cchiw 2646 val stms = Dst.S_Stabilize :: stms
896 : jhr 2356 in
897 : jhr 1115 (* FIXME: we should probably call flushPending here! *)
898 : cchiw 2830 (join (env, ifStk, stms, k))
899 : jhr 2356 end
900 : cchiw 2830 | ExitKind.DIE => (join (env, ifStk, Dst.S_Die :: stms, k))
901 : jhr 2356 (* end case *))
902 :     (* end case *))
903 : jhr 2632
904 : cchiw 2844 in
905 :     doNode (env, [], [], CFG.entry cfg)
906 : jhr 2356 end
907 : jhr 1115
908 : cchiw 2646 fun trInitially (env, Src.Initially{isArray, rangeInit, iters, create=(createInit, strand, args)}) =
909 : jhr 2356 let
910 : cchiw 2838 val (env2,iterPrefix) = peelBlockOrig(env,trCFG (env, [], fn _ => [], rangeInit))
911 :     (*val (iterPrefix) = mkBlockOrig(trCFG (env, [], fn _ => [], rangeInit))*)
912 :    
913 : jhr 2356 fun cvtIter ((param, lo, hi), (env, iters)) = let
914 :     val param' = newIter param
915 :     val env = rename (env, param, param')
916 :     in
917 :     (env, (param', useVar env lo, useVar env hi)::iters)
918 :     end
919 :     val (env, iters) = List.foldr cvtIter (env, []) iters
920 : cchiw 2637 val (env,createPrefix) = peelBlockOrig(env,trCFG (env, [], fn _ => [], createInit))
921 :     in (env,{
922 : jhr 2356 isArray = isArray,
923 :     iterPrefix = iterPrefix,
924 :     iters = iters,
925 :     createPrefix = createPrefix,
926 :     strand = strand,
927 :     args = List.map (useVar env) args
928 : cchiw 2637 }) end
929 : jhr 1115
930 : cchiw 2830 fun trMethod (env ,Src.Method{name, body}) = let
931 :    
932 : cchiw 2838 val (env,blk)=peelBlockOrig(env,trCFG (env, [], fn _ => [], body))
933 :     (*val (blk)=mkBlockOrig(trCFG (env, [], fn _ => [], body))*)
934 : cchiw 2830 in
935 : cchiw 2838 (env, Dst.Method{
936 : cchiw 2830 name = name,
937 :     body = blk})
938 :     end
939 : cchiw 2637
940 :    
941 :     fun trStrand(globalEnv, [],rest)=(globalEnv,rest)
942 : cchiw 2646 | trStrand(globalEnv ,( Src.Strand{name, params, state, stateInit, methods})::es,rest) = let
943 : cchiw 2637 val params' = List.map newParam params
944 :     val env = ListPair.foldlEq (fn (x, x', env) => rename(env, x, x')) globalEnv (params, params')
945 : cchiw 2830
946 :    
947 : cchiw 2637 val (env',sInit) = peelBlockOrig(env,trCFG (env, [], fn _ => [], stateInit))
948 : cchiw 2830
949 :    
950 :     fun callmethod(env,[],M)=(env,M)
951 :     | callmethod(env,b::es,Ms)=let
952 :     val (env2,M1)=trMethod(env,b)
953 :     in callmethod(env2,es,[M1]@Ms) end
954 :     val (env',Methods)=callmethod(env',methods,[])
955 : cchiw 2646 val strand'=Dst.Strand{
956 : cchiw 2637 name = name,
957 :     params = params',
958 :     state = List.map getStateVar state,
959 :     stateInit =sInit,
960 : cchiw 2830 methods = (*List.map (trMethod env) methods*) Methods
961 : cchiw 2637 }
962 :     in trStrand(env', es, rest@[strand'])
963 :     end
964 :    
965 :    
966 : jhr 1115
967 : jhr 1301 (* split the globalInit into the part that specifies the inputs and the rest of
968 :     * the global initialization.
969 :     *)
970 :     fun splitGlobalInit globalInit = let
971 : cchiw 2525 (* FIXME: can split as soon as we see a non-Input statement! *)
972 : cchiw 2687
973 : cchiw 2688
974 : jhr 2356 fun walk (nd, lastInput, live) = (case Nd.kind nd
975 : cchiw 2646 of Src.ENTRY{succ} => walk (!succ, lastInput, live)
976 :     | Src.COM{succ, ...} => walk (!succ, lastInput, live)
977 :     | Src.ASSIGN{stm=(lhs, rhs), succ, ...} => (case rhs
978 :     of Src.OP(SrcOp.Input _, _) => walk (!succ, nd, lhs::live)
979 : jhr 2356 | _ => walk (!succ, lastInput, live)
980 :     (* end case *))
981 :     | _ => if Nd.isNULL lastInput
982 :     then let (* no inputs *)
983 :     val entry = Nd.mkENTRY()
984 :     val exit = Nd.mkEXIT(ExitKind.RETURN, [])
985 :     in
986 :     Nd.addEdge (entry, exit);
987 : cchiw 2646 {inputInit = Src.CFG{entry=entry, exit=exit}, globalInit = globalInit}
988 : jhr 2356 end
989 :     else let (* split at lastInput *)
990 :     val inputExit = Nd.mkEXIT(ExitKind.RETURN, live)
991 :     val globalEntry = Nd.mkENTRY()
992 :     val [gFirst] = Nd.succs lastInput
993 :     in
994 :     Nd.replaceInEdge {src = lastInput, oldDst = gFirst, dst = inputExit};
995 :     Nd.replaceOutEdge {oldSrc = lastInput, src = globalEntry, dst = gFirst};
996 :     {
997 : cchiw 2646 inputInit = Src.CFG{entry = Src.CFG.entry globalInit, exit = inputExit},
998 :     globalInit = Src.CFG{entry = globalEntry, exit = Src.CFG.exit globalInit}
999 : jhr 2356 }
1000 :     end
1001 :     (* end case *))
1002 : cchiw 2637
1003 : jhr 2356 in
1004 : cchiw 2646 walk ( Src.CFG.entry globalInit, Nd.dummy, [])
1005 : jhr 2356 end
1006 : cchiw 2637 fun getInfo(env,Init)=let
1007 :     val inputInit' = trCFG (env, [], fn _ => [], Init)
1008 :     in
1009 :     peelBlockOrig(env,inputInit')
1010 :     end
1011 :    
1012 : jhr 1115 fun translate prog = let
1013 : jhr 2356 (* first we do a variable analysis pass on the Low IL *)
1014 : cchiw 2646 val prog as Src.Program{props, globalInit, initially, strands} = VA.optimize prog
1015 : jhr 1115 (* FIXME: here we should do a contraction pass to eliminate unused variables that VA may have created *)
1016 : jhr 2356 val _ = (* DEBUG *)
1017 :     LowPP.output (Log.logFile(), "LowIL after variable analysis", prog)
1018 : cchiw 2637 val envOrig = newEnv()
1019 : jhr 2632 val globals = List.map
1020 : cchiw 2637 (fn x => let val x' = newGlobal x in global(envOrig, x, x'); x' end)
1021 : cchiw 2646 ( Src.CFG.liveAtExit globalInit)
1022 : jhr 2356 val {inputInit, globalInit} = splitGlobalInit globalInit
1023 : cchiw 2637
1024 :     val (env,inputInit)=getInfo(envOrig,inputInit)
1025 :     val (env,globalInit)=getInfo(env, globalInit)
1026 :     val (env,strands) = trStrand (env, strands,[])
1027 :     val (env, initially) = trInitially (env, initially)
1028 :    
1029 :     val (typs,opr)= peelEnv(env)
1030 :     val typsList=TySet.listItems(typs);
1031 :     val oprList=OprSet.listItems(opr);
1032 : cchiw 2692 val _=testp[(Fnc.setListToString(typsList,oprList,"--FinalPostStrands--"))]
1033 : cchiw 2637
1034 : cchiw 2646 in Dst.Program{
1035 : jhr 2632 props = props,
1036 : cchiw 2637 types=typsList,
1037 :     oprations = oprList,
1038 : jhr 2632 globals = globals,
1039 :     inputInit = inputInit,
1040 :     globalInit = globalInit,
1041 :     strands = strands,
1042 : cchiw 2637 initially = initially
1043 : jhr 2632 }
1044 : jhr 2356 end
1045 : jhr 1115
1046 :     end

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