SCM Repository
Annotation of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml
Parent Directory
|
Revision Log
Revision 562 - (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 : | jhr | 518 | val generate : string * LowIL.program -> unit |
14 : | jhr | 454 | |
15 : | end = struct | ||
16 : | |||
17 : | jhr | 532 | structure IL = TreeIL |
18 : | structure Ty = IL.Ty | ||
19 : | structure Op = IL.Op | ||
20 : | structure V = IL.Var | ||
21 : | jhr | 454 | |
22 : | jhr | 525 | (* convert LowIL types to T types *) |
23 : | fun cvtTy ty = (case ty | ||
24 : | of Ty.BoolTy => T.boolTy | ||
25 : | jhr | 533 | | Ty.StringTy => T.stringTy |
26 : | jhr | 525 | | Ty.IVecTy 1 => T.intTy |
27 : | | Ty.IVecTy n => T.ivecTy n (* FIXME: what about vector splits? *) | ||
28 : | | Ty.VecTy 1 => T.realTy | ||
29 : | | Ty.VecTy n => T.vecTy n (* FIXME: what about vector splits? *) | ||
30 : | jhr | 548 | | Ty.AddrTy info => T.imageDataTy info |
31 : | | Ty.ImageTy info => T.imageTy info | ||
32 : | jhr | 525 | (* end case *)) |
33 : | |||
34 : | jhr | 544 | fun addBindings (env, xs, ys) = |
35 : | ListPair.foldlEq (fn (x, y, env) => V.Map.insert(env, x, y)) env (xs, ys) | ||
36 : | |||
37 : | jhr | 532 | fun lookup (env, x) = (case V.Map.find (env, x) |
38 : | of SOME x' => x' | ||
39 : | jhr | 534 | | NONE => raise Fail(concat["lookup(_, ", V.name x, ")"]) |
40 : | jhr | 532 | (* end case *)) |
41 : | |||
42 : | fun trExp (env, e) = (case e | ||
43 : | of IL.E_Var x => (case V.kind x | ||
44 : | of IL.VK_Global => T.Expr.global(lookup(env, x)) | ||
45 : | jhr | 552 | | IL.VK_State strand => T.Expr.getState(lookup(env, x)) |
46 : | jhr | 532 | | IL.VK_Local => T.Expr.var(lookup(env, x)) |
47 : | (* end case *)) | ||
48 : | | IL.E_Lit(Literal.Int n) => T.Expr.intLit n | ||
49 : | | IL.E_Lit(Literal.Bool b) => T.Expr.boolLit b | ||
50 : | | IL.E_Lit(Literal.Float f) => T.Expr.floatLit f | ||
51 : | | IL.E_Lit(Literal.String s) => T.Expr.stringLit s | ||
52 : | | IL.E_Op(rator, args) => (case (rator, trExps(env, args)) | ||
53 : | of (Op.Add ty, [a, b]) => T.Expr.add(a, b) | ||
54 : | | (Op.Sub ty, [a, b]) => T.Expr.sub(a, b) | ||
55 : | | (Op.Mul ty, [a, b]) => T.Expr.mul(a, b) | ||
56 : | | (Op.Div ty, [a, b]) => T.Expr.divide(a, b) | ||
57 : | | (Op.Neg ty, [a]) => T.Expr.neg a | ||
58 : | | (Op.LT ty, [a, b]) => T.Expr.lt(a, b) | ||
59 : | | (Op.LTE ty, [a, b]) => T.Expr.lte(a, b) | ||
60 : | | (Op.EQ ty, [a, b]) => T.Expr.equ(a, b) | ||
61 : | | (Op.NEQ ty, [a, b]) => T.Expr.neq(a, b) | ||
62 : | | (Op.GT ty, [a, b]) => T.Expr.gt(a, b) | ||
63 : | | (Op.GTE ty, [a, b]) => T.Expr.gte(a, b) | ||
64 : | | (Op.Not, [a]) => T.Expr.not a | ||
65 : | | (Op.Max, [a, b]) => T.Expr.max(a, b) | ||
66 : | | (Op.Min, [a, b]) => T.Expr.min(a, b) | ||
67 : | | (Op.Sin, [a]) => T.Expr.sin a | ||
68 : | | (Op.Cos, [a]) => T.Expr.cos a | ||
69 : | | (Op.Pow, [a, b]) => T.Expr.pow(a, b) | ||
70 : | | (Op.Dot d, [a, b]) => T.Expr.dot(a, b) | ||
71 : | | (Op.Cross, [a, b]) => T.Expr.cross(a, b) | ||
72 : | | (Op.Select(ty, i), [a]) => T.Expr.select(i, a) | ||
73 : | | (Op.Norm d, [a]) => T.Expr.length a | ||
74 : | | (Op.Scale d, [a, b]) => T.Expr.mul(a, b) | ||
75 : | | (Op.InvScale d, [a, b]) => T.Expr.divide(a, b) | ||
76 : | jhr | 518 | | (Op.CL, _) => raise Fail "CL unimplemented" |
77 : | | (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented" | ||
78 : | jhr | 514 | (* |
79 : | jhr | 518 | | (Op.Subscript ty, |
80 : | jhr | 514 | *) |
81 : | jhr | 532 | | (Op.Floor d, [a]) => T.Expr.floor a |
82 : | | (Op.IntToReal, [a]) => T.Expr.toReal a | ||
83 : | | (Op.TruncToInt d, [a]) => T.Expr.truncToInt a | ||
84 : | | (Op.RoundToInt d, [a]) => T.Expr.roundToInt a | ||
85 : | | (Op.CeilToInt d, [a]) => T.Expr.ceilToInt a | ||
86 : | | (Op.FloorToInt d, [a]) => T.Expr.floorToInt a | ||
87 : | jhr | 548 | | (Op.ImageAddress d, [a]) => T.Expr.imageAddr a |
88 : | | (Op.LoadVoxels(info, 1), [a]) => T.Expr.getImgData a | ||
89 : | | (Op.LoadVoxels _, [a]) => raise Fail "impossible" | ||
90 : | | (Op.PosToImgSpace d, [v, x]) => T.Expr.posToImgSpace(v, x) | ||
91 : | jhr | 532 | | (Op.GradToWorldSpace d, [v, x]) => T.Expr.intLit 0 (* FIXME *) |
92 : | jhr | 547 | | (Op.LoadImage info, [a]) => raise Fail "impossible" |
93 : | jhr | 548 | | (Op.Inside(d, s), [x, v]) => T.Expr.inside(x, v, s) |
94 : | jhr | 547 | | (Op.Input(ty, name), []) => raise Fail "impossible" |
95 : | jhr | 532 | | (Op.InputWithDefault(ty, name), [a]) => T.Expr.intLit 0 (* FIXME *) |
96 : | jhr | 528 | | _ => raise Fail(concat[ |
97 : | "incorrect number of arguments for ", Op.toString rator | ||
98 : | ]) | ||
99 : | jhr | 518 | (* end case *)) |
100 : | jhr | 532 | (* end case *)) |
101 : | jhr | 454 | |
102 : | jhr | 532 | and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps |
103 : | jhr | 455 | |
104 : | jhr | 532 | fun trStmt (env, stm) = (case stm |
105 : | jhr | 533 | of IL.S_Comment text => [T.Stmt.comment text] |
106 : | jhr | 532 | | IL.S_Assign(x, exp) => (case V.kind x |
107 : | jhr | 533 | of IL.VK_Global => [T.Stmt.assign(lookup(env, x), trExp(env, exp))] |
108 : | jhr | 544 | | IL.VK_State strand => |
109 : | [T.Stmt.assignState(lookup(env, x), trExp(env, exp))] | ||
110 : | jhr | 533 | | IL.VK_Local => [T.Stmt.assign(lookup(env, x), trExp(env, exp))] |
111 : | jhr | 512 | (* end case *)) |
112 : | jhr | 533 | | IL.S_Cons(lhs, args) => |
113 : | [T.Stmt.cons(lookup(env, lhs), trExps(env, args))] | ||
114 : | jhr | 548 | | IL.S_LoadVoxels(lhs, dim, addr) => |
115 : | jhr | 554 | T.Stmt.getImgData(lookup(env, lhs), trExp(env, addr)) |
116 : | jhr | 533 | | IL.S_LoadImage(lhs, dim, name) => |
117 : | T.Stmt.loadImage (lookup(env, lhs), dim, trExp(env, name)) | ||
118 : | | IL.S_Input(lhs, name, optDflt) => | ||
119 : | T.Stmt.input(lookup(env, lhs), name, Option.map (fn e => trExp(env, e)) optDflt) | ||
120 : | jhr | 532 | | IL.S_IfThen(cond, thenBlk) => |
121 : | jhr | 533 | [T.Stmt.ifthen(trExp(env, cond), trBlock(env, thenBlk))] |
122 : | jhr | 532 | | IL.S_IfThenElse(cond, thenBlk, elseBlk) => |
123 : | jhr | 533 | [T.Stmt.ifthenelse(trExp(env, cond), |
124 : | jhr | 532 | trBlock(env, thenBlk), |
125 : | jhr | 533 | trBlock(env, elseBlk))] |
126 : | | IL.S_Die => [T.Stmt.die()] | ||
127 : | | IL.S_Stabilize => [T.Stmt.stabilize()] | ||
128 : | jhr | 562 | | IL.S_Exit => [T.Stmt.exit()] |
129 : | jhr | 532 | (* end case *)) |
130 : | jhr | 512 | |
131 : | jhr | 544 | and trBlock (env, IL.Block{locals, body}) = let |
132 : | val env = List.foldl | ||
133 : | (fn (x, env) => V.Map.insert(env, x, T.Var.var(cvtTy(V.ty x), V.name x))) | ||
134 : | env locals | ||
135 : | jhr | 559 | val stms = List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] body |
136 : | val stms = List.foldr | ||
137 : | (fn (x, stms) => T.Stmt.decl(lookup(env, x), NONE)::stms) | ||
138 : | stms locals | ||
139 : | jhr | 544 | in |
140 : | jhr | 559 | T.Stmt.block stms |
141 : | jhr | 544 | end |
142 : | jhr | 528 | |
143 : | jhr | 547 | fun trMethod (strand, env) (IL.Method{name, body}) = |
144 : | T.Strand.method (strand, Atom.toString name, trBlock (env, body)) | ||
145 : | |||
146 : | jhr | 544 | fun trStrand (prog, env) (IL.Strand{name, params, state, stateInit, methods}) = let |
147 : | val strand = T.Strand.define(prog, Atom.toString name) | ||
148 : | val state' = | ||
149 : | List.map (fn x => T.Var.state(strand, cvtTy(V.ty x), V.name x)) state | ||
150 : | val env = addBindings (env, state, state') | ||
151 : | (* define the parameters and add them to the environment *) | ||
152 : | val params' = List.map (fn x => T.Var.param(cvtTy(V.ty x), V.name x)) params | ||
153 : | val env = addBindings (env, params, params') | ||
154 : | in | ||
155 : | T.Strand.init (strand, params', trBlock (env, stateInit)); | ||
156 : | jhr | 547 | List.app (trMethod (strand, env)) methods |
157 : | jhr | 544 | end |
158 : | |||
159 : | jhr | 531 | fun generate (fileStem, srcProg) = let |
160 : | jhr | 535 | val treeProg as TreeIL.Program{globals, globalInit, strands} = LowToTree.translate srcProg |
161 : | val _ = ( | ||
162 : | TextIO.output(Log.logFile(), "********** After translation to TreeIL **********\n"); | ||
163 : | TreeILPP.program (Log.logFile(), treeProg)) | ||
164 : | jhr | 527 | val prog = T.newProgram () |
165 : | jhr | 532 | (* define the globals and initialize the environment *) |
166 : | val env = let | ||
167 : | fun gvar (x, env) = | ||
168 : | V.Map.insert(env, x, T.Var.global(prog, cvtTy(V.ty x), V.name x)) | ||
169 : | in | ||
170 : | List.foldl gvar V.Map.empty globals | ||
171 : | end | ||
172 : | jhr | 527 | in |
173 : | jhr | 533 | (* global initialization *) |
174 : | T.globalInit (prog, trBlock (env, globalInit)); | ||
175 : | jhr | 544 | (* translate strands *) |
176 : | List.app (trStrand (prog, env)) strands; | ||
177 : | jhr | 528 | (* output the program *) |
178 : | jhr | 527 | T.generate (fileStem, prog) |
179 : | end | ||
180 : | jhr | 518 | |
181 : | jhr | 454 | end |
root@smlnj-gforge.cs.uchicago.edu | ViewVC Help |
Powered by ViewVC 1.0.0 |