Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Annotation of /sml/trunk/src/compiler/CodeGen/ppc/ppcCG.sml
ViewVC logotype

Annotation of /sml/trunk/src/compiler/CodeGen/ppc/ppcCG.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 247 - (view) (download)
Original Path: sml/branches/SMLNJ/src/compiler/CodeGen/ppc/ppcCG.sml

1 : monnier 247 functor PPCCG
2 :     (structure Emitter : EMITTER_NEW
3 :     where I = PPCInstr and P = PPCPseudoOps) : MACHINE_GEN =
4 :     struct
5 :     structure I = PPCInstr
6 :     structure C = PPCCells
7 :     structure R = PPCCpsRegs
8 :     structure B = PPCMLTree.BNames
9 :     structure F = PPCFlowGraph
10 :     structure Asm = PPCAsmEmitter
11 :     structure MLTree = PPCMLTree
12 :     structure MachSpec = PPCSpec
13 :     structure Ctrl = Control.MLRISC
14 :    
15 :     fun error msg = ErrorMsg.impossible ("PPCCG." ^ msg)
16 :    
17 :     val stack = PPCInstr.Region.stack
18 :     structure PPCRewrite = PPCRewrite(PPCInstr)
19 :    
20 :     (* properties of instruction set *)
21 :     structure P =
22 :     PPCProps(structure PPCInstr= I
23 :     structure Shuffle=PPCShuffle)
24 :    
25 :     (* Label backpatching and basic block scheduling *)
26 :     structure BBSched =
27 :     BBSched2(structure Flowgraph = F
28 :     structure Jumps =
29 :     PPCJumps(structure Instr=PPCInstr
30 :     structure Shuffle=PPCShuffle)
31 :     structure Emitter = Emitter)
32 :    
33 :     (* flow graph pretty printing routine *)
34 :     structure PrintFlowGraph =
35 :     PrintFlowGraphFn (structure FlowGraph = F
36 :     structure Emitter = Asm)
37 :    
38 :     val intSpillCnt = Ctrl.getInt "ra-int-spills"
39 :     val floatSpillCnt = Ctrl.getInt "ra-float-spills"
40 :     val intReloadCnt = Ctrl.getInt "ra-int-reloads"
41 :     val floatReloadCnt = Ctrl.getInt "ra-float-reloads"
42 :    
43 :     (* register allocation *)
44 :     structure RegAllocation :
45 :     sig
46 :     val ra : F.cluster -> F.cluster
47 :     val cp : F.cluster -> F.cluster
48 :     end =
49 :     struct
50 :    
51 :     (* spill area management *)
52 :     val initialSpillOffset = 144
53 :     val spillOffset = ref initialSpillOffset
54 :     fun newOffset n =
55 :     if n > 4096
56 :     then error "newOffset - spill area is too small"
57 :     else spillOffset := n
58 :     exception RegSpills and FregSpills
59 :    
60 :     val regSpills : int Intmap.intmap ref = ref(Intmap.new(0, RegSpills))
61 :     val fregSpills : int Intmap.intmap ref = ref(Intmap.new(0, FregSpills))
62 :    
63 :     (* get spill location for general registers *)
64 :     fun getRegLoc reg = Intmap.map (!regSpills) reg
65 :     handle RegSpills => let
66 :     val offset = !spillOffset
67 :     in
68 :     newOffset(offset+4);
69 :     Intmap.add (!regSpills) (reg, offset);
70 :     offset
71 :     end
72 :    
73 :     (* get spill location for floating registers *)
74 :     fun getFregLoc freg = Intmap.map (!fregSpills) freg
75 :     handle FregSpills => let
76 :     val offset = !spillOffset
77 :     val fromInt = Word.fromInt
78 :     val aligned = Word.toIntX(Word.andb(fromInt offset+0w7, fromInt ~8))
79 :     in
80 :     newOffset(aligned+8);
81 :     Intmap.add (!fregSpills) (freg, aligned);
82 :     aligned
83 :     end
84 :    
85 :     fun spill {regmap,instr,reg,id:B.name} = let
86 :     val offset = I.ImmedOp (getRegLoc(reg))
87 :     fun spillInstr(src) =
88 :     [I.ST{sz=I.Word, rs=src, ra=C.stackptrR, d=offset, mem=stack}]
89 :     in
90 :     intSpillCnt := !intSpillCnt + 1;
91 :     case instr
92 :     of I.COPY{dst as [rd], src as [rs], tmp, impl} =>
93 :     if rd=reg then
94 :     {code=spillInstr(rs), instr=NONE, proh=[]:int list}
95 :     else (case tmp
96 :     of SOME(I.Direct r) => let
97 :     val disp = I.ImmedOp(getRegLoc(r))
98 :     val loc = I.Displace{base=C.stackptrR, disp=disp}
99 :     val instr=I.COPY{dst=dst, src=src, tmp=SOME(loc), impl=impl}
100 :     in {code=[], instr=SOME instr, proh=[]}
101 :     end
102 :     | _ => error "spill: COPY"
103 :     (*esac*))
104 :     | _ => let
105 :     val newR = C.newReg()
106 :     val instr' = PPCRewrite.rewriteDef(regmap, instr, reg, newR)
107 :     in {code=spillInstr(newR), instr=SOME instr', proh=[newR]}
108 :     end
109 :     end
110 :    
111 :     fun fspill {regmap,instr,reg,id:B.name} = let
112 :     val offset = I.ImmedOp (getFregLoc(reg))
113 :     fun spillInstr(src) =
114 :     [I.ST{sz=I.Double, rs=src, ra=C.stackptrR, d=offset, mem=stack}]
115 :     in
116 :     floatSpillCnt := !floatSpillCnt + 1;
117 :     case instr
118 :     of I.FCOPY{dst as [fd], src as [fs], tmp, impl} => (* reg = fd *)
119 :     if reg=fd then
120 :     {code=spillInstr(fs), instr=NONE, proh=[]}
121 :     else (case tmp
122 :     of SOME(I.FDirect r) => let
123 :     val disp=I.ImmedOp(getFregLoc(r))
124 :     val loc = I.Displace{base=C.stackptrR, disp=disp}
125 :     val instr=I.FCOPY{dst=dst, src=src, tmp=SOME(loc), impl=impl}
126 :     in {code=[], instr=SOME instr, proh=[]}
127 :     end
128 :     | _ => error "spill: COPY"
129 :     (*esac*))
130 :     | _ => let
131 :     val newR = C.newFreg()
132 :     val instr' = PPCRewrite.frewriteDef(regmap, instr, reg, newR)
133 :     in {code=spillInstr(newR), instr=SOME instr', proh=[newR]}
134 :     end
135 :     end
136 :    
137 :     fun reload{regmap,instr,reg,id:B.name} = let
138 :     val offset = I.ImmedOp (getRegLoc(reg))
139 :     fun reloadInstr(dst, rest) =
140 :     I.L{sz=I.Word, rt=dst, ra=C.stackptrR, d=offset, mem=stack}::rest
141 :     in
142 :     intReloadCnt := !intReloadCnt + 1;
143 :     case instr
144 :     of I.COPY{dst=[rd], src=[rs], ...} => (* reg = rs *)
145 :     {code=reloadInstr(rd, []), proh=[]:int list}
146 :     | _ => let
147 :     val newR = C.newReg()
148 :     val instr' = PPCRewrite.rewriteUse(regmap, instr, reg, newR)
149 :     in {code=reloadInstr(newR, [instr']), proh=[newR]}
150 :     end
151 :     end
152 :    
153 :     fun freload {regmap, instr, reg, id:B.name} = let
154 :     val offset = I.ImmedOp (getFregLoc(reg))
155 :     fun reloadInstr(dst, rest) =
156 :     I.L{sz=I.Double, rt=dst, ra=C.stackptrR, d=offset, mem=stack}::rest
157 :     in
158 :     floatReloadCnt := !floatReloadCnt + 1;
159 :     case instr
160 :     of I.FCOPY{dst=[fd], src=[fs], ...} => (* reg = fs *)
161 :     {code=reloadInstr(fd, []), proh=[]}
162 :     | _ => let
163 :     val newR = C.newFreg()
164 :     val instr' = PPCRewrite.frewriteUse(regmap, instr, reg, newR)
165 :     in {code=reloadInstr(newR, [instr']), proh=[newR]}
166 :     end
167 :     end
168 :    
169 :     fun spillInit () =
170 :     (spillOffset := initialSpillOffset;
171 :     regSpills := Intmap.new(8, RegSpills);
172 :     fregSpills := Intmap.new(8, FregSpills))
173 :    
174 :     structure GR = GetReg(val nRegs=32 val available=R.availR)
175 :     structure FR = GetReg(val nRegs=32 val available=R.availF)
176 :    
177 :     structure PPCRa =
178 :     PPCRegAlloc(structure P = P
179 :     structure I = PPCInstr
180 :     structure F = F
181 :     structure Asm = Asm)
182 :    
183 :     (* register allocation for general purpose registers *)
184 :     structure IntRa =
185 :     PPCRa.IntRa
186 :     (structure RaUser = struct
187 :     structure I = PPCInstr
188 :     structure B = B
189 :    
190 :     val getreg = GR.getreg
191 :     val spill = spill
192 :     val reload = reload
193 :     val nFreeRegs = length R.availR
194 :     val dedicated = R.dedicatedR
195 :     fun copyInstr((rds, rss), I.COPY{tmp, ...}) =
196 :     I.COPY{dst=rds, src=rss, impl=ref NONE, tmp=tmp}
197 :     end)
198 :    
199 :     (* register allocation for floating point registers *)
200 :     structure FloatRa =
201 :     PPCRa.FloatRa
202 :     (structure RaUser = struct
203 :     structure I = PPCInstr
204 :     structure B = B
205 :    
206 :     val getreg = FR.getreg
207 :     val spill = fspill
208 :     val reload = freload
209 :     val nFreeRegs = length R.availF
210 :     val dedicated = R.dedicatedF
211 :     fun copyInstr((fds, fss), I.FCOPY{tmp, ...}) =
212 :     I.FCOPY{dst=fds, src=fss, impl=ref NONE, tmp=tmp}
213 :     end)
214 :    
215 :     val iRegAlloc = IntRa.ra IntRa.REGISTER_ALLOCATION []
216 :     val fRegAlloc = FloatRa.ra FloatRa.REGISTER_ALLOCATION []
217 :     val iCopyProp = IntRa.ra IntRa.COPY_PROPAGATION []
218 :     val fCopyProp = FloatRa.ra FloatRa.COPY_PROPAGATION []
219 :    
220 :     fun ra cluster = let
221 :     val pg = PrintFlowGraph.printCluster TextIO.stdOut
222 :     fun intRa cluster = (GR.reset(); iRegAlloc cluster)
223 :     fun floatRa cluster = (FR.reset(); fRegAlloc cluster)
224 :     in spillInit(); (floatRa o intRa) cluster
225 :     end
226 :     val cp = fCopyProp o iCopyProp
227 :     end (* RegAllocation *)
228 :    
229 :     val optimizerHook : (F.cluster->F.cluster) option ref = ref NONE
230 :    
231 :     (* primitives for generation of DEC alpha instruction flowgraphs *)
232 :     structure FlowGraphGen =
233 :     FlowGraphGen(structure Flowgraph = F
234 :     structure InsnProps = P
235 :     structure MLTree = MLTree
236 :     val optimize = optimizerHook
237 :     val output = BBSched.bbsched o RegAllocation.ra)
238 :    
239 :     (* compilation of CPS to MLRISC *)
240 :     structure MLTreeGen =
241 :     MLRiscGen(structure MachineSpec=PPCSpec
242 :     structure MLTreeComp=
243 :     PPC(structure Flowgen=FlowGraphGen
244 :     structure PPCInstr=PPCInstr
245 :     structure PPCMLTree=PPCMLTree
246 :     structure PseudoInstrs=
247 :     PPCPseudoInstr(structure Instr=PPCInstr)
248 :     val rs6000flag=false)
249 :     structure Cells=PPCCells
250 :     structure C=PPCCpsRegs
251 :     structure PseudoOp=PPCPseudoOps)
252 :    
253 :     val copyProp = RegAllocation.cp
254 :     val codegen = MLTreeGen.codegen
255 :     val finish = BBSched.finish
256 :     end
257 :    

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