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/MLRISC/ra/ra-spill-with-renaming.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/ra/ra-spill-with-renaming.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 815 - (view) (download)

1 : leunga 641 (*
2 :     * This version also performs local renaming on the spill code.
3 :     * For example, spilling t below
4 :     *
5 :     * t <- ...
6 :     * .. <- t
7 :     * ....
8 :     * ....
9 :     * .. <- t
10 :     * .. <- t
11 :     *
12 : leunga 744 * would result in
13 : leunga 641 *
14 :     * tmp1 <- ...
15 : leunga 744 * mem[t] <- tmp1
16 : leunga 641 * .. <- tmp1 <---- rename from t to tmp1
17 :     * ....
18 :     * ....
19 :     * tmp2 <- mem[t]
20 :     * .. <- tmp2
21 :     * .. <- tmp2 <---- rename from t to tmp2
22 :     *
23 :     * That is, we try to avoid inserting reload code whenever it is possible.
24 :     * This is done by keeping track of which values are live locally.
25 :     *
26 :     * Allen (5/9/00)
27 :     *
28 : leunga 744 *)
29 :     (*
30 :     * This module manages the spill/reload process.
31 : leunga 641 * The reason this is detached from the main module is that
32 :     * I can't understand the old code.
33 :     *
34 :     * Okay, now I understand the code.
35 :     *
36 :     * The new code does things slightly differently.
37 :     * Here, we are given an instruction and a list of registers to spill
38 :     * and reload. We rewrite the instruction until all instances of these
39 :     * registers are rewritten.
40 :     *
41 :     * (12/13/99) Some major caveats when spill coalescing/coloring is used:
42 :     * When parallel copies are generated and spill coalescing/coloring is used,
43 :     * two special cases have to be identified:
44 :     *
45 :     * Case 1 (spillLoc dst = spillLoc src)
46 :     * Suppose we have a parallel copy
47 :     * (u,v) <- (x,y)
48 :     * where u has to be spilled and y has to reloaded. When both
49 :     * u and y are mapped to location M. The following wrong code may
50 :     * be generated:
51 :     * M <- x (spill u)
52 :     * v <- M (reload y)
53 :     * This is incorrect. Instead, we generate a dummy copy and
54 :     * delay the spill after the reload, like this:
55 :     *
56 :     * tmp <- x (save value of u)
57 :     * v <- M (reload y)
58 :     * M <- tmp (spill u)
59 :     * Case 2 (spillLoc copyTmp = spillLoc src)
60 :     * Another case that can cause problems is when the spill location of
61 :     * the copy temporary is the same as that of one of the sources:
62 :     *
63 :     * (a, b, v) <- (b, a, u) where spillLoc(u) = spillLoc(tmp) = v
64 :     *
65 :     * The incorrect code is
66 :     * (a, b) <- (b, a)
67 :     * v <- M
68 :     * But then the shuffle code for the copy can clobber the location M.
69 :     *
70 :     * tmp <- M
71 :     * (a, b) <- (b, a)
72 :     * v <- tmp
73 :     *
74 :     * (Note that spillLoc copyTmp = spillLoc src can never happen)
75 :     *
76 :     * -- Allen
77 :     *)
78 : leunga 744
79 :     local
80 :    
81 :     val debug = false
82 :    
83 :     in
84 :    
85 : leunga 641 functor RASpillWithRenaming
86 : leunga 744 (structure InsnProps : INSN_PROPERTIES
87 : leunga 641 structure Asm : INSTRUCTION_EMITTER
88 : leunga 744 sharing InsnProps.I = Asm.I
89 : leunga 641
90 :     (* Spilling a variable v creates tiny live-ranges at all its definitions
91 : leunga 744 * and uses. The following parameter is the maximal distance of
92 :     * live-ranges created between a definition and its use,
93 : leunga 641 * measured in the number of instructions. If, max_dist = D, then
94 :     * the spill routine will never create a new live-range that is more
95 :     * than D instructions apart.
96 :     *)
97 :     val max_dist : int ref
98 :    
99 :     (* When this parameter is on, the spill routine will keep track of
100 :     * multiple values for the renaming process. This is recommended
101 : leunga 744 * if the architecture has a lot of free registers. But it should
102 : leunga 641 * probably be turned off on the x86.
103 :     *)
104 :     val keep_multiple_values : bool ref
105 :     ) : RA_SPILL =
106 :     struct
107 :    
108 :     structure I = InsnProps.I
109 :     structure P = InsnProps
110 :     structure C = I.C
111 :     structure Core = RACore
112 : leunga 744 structure G = Core.G
113 : leunga 641
114 : leunga 744 fun error msg = MLRiscErrorMsg.error("RASpillWithRenaming",msg)
115 : leunga 641
116 :     fun dec n = Word.toIntX(Word.fromInt n - 0w1)
117 :    
118 : leunga 744 structure T = RASpillTypes(I)
119 :     open T
120 : leunga 641
121 : leunga 744 fun uniq s = C.SortedCells.return(C.SortedCells.uniq s)
122 :     val i2s = Int.toString
123 : leunga 641
124 : leunga 744 val Asm.S.STREAM{emit, ...} = Asm.makeStream[]
125 : leunga 641
126 :     (* val spilledCopyTmps = MLRiscControl.getCounter "ra-spilled-copy-temps" *)
127 :    
128 :     (*
129 :     * The following function performs spilling.
130 :     *)
131 :     fun spillRewrite
132 : leunga 744 {graph=G as G.GRAPH{showReg, spilledRegs, nodes, mode, dedicated,...},
133 : leunga 641 spill : spill,
134 :     spillCopyTmp : spillCopyTmp,
135 :     spillSrc : spillSrc,
136 :     renameSrc : renameSrc,
137 :     reload : reload,
138 :     reloadDst : reloadDst,
139 :     copyInstr : copyInstr,
140 :     cellkind,
141 :     spillSet, reloadSet, killSet
142 :     } =
143 :     let
144 : leunga 744 (* Must do this to make sure the interference graph is
145 :     * reflected to the cells
146 :     *)
147 :     val _ = Core.updateCellAliases G
148 :    
149 :     val getSpillLoc = Core.spillLoc G
150 :     fun spillLocOf(C.CELL{id, ...}) = getSpillLoc id
151 : leunga 641 val spillLocsOf = map spillLocOf
152 : leunga 744 val getnode = IntHashTable.lookup nodes
153 :     val getnode = fn C.CELL{id, ...} => getnode id
154 : leunga 641
155 :     val MAX_DIST = !max_dist
156 :    
157 :     val insnDefUse = P.defUse cellkind
158 :    
159 : leunga 744 fun hasNonDedicated rs =
160 : leunga 646 let fun isDedicated r = Array.sub(dedicated,r) handle _ => false
161 :     fun loop [] = false
162 : leunga 744 | loop(r::rs) =
163 :     if isDedicated(C.registerId r) then loop rs else true
164 : leunga 646 in loop rs end
165 :    
166 : leunga 641 (* Merge prohibited registers *)
167 : leunga 744 val enterSpill = IntHashTable.insert spilledRegs
168 :     val addProh = app (fn c => enterSpill(C.registerId c,true))
169 : leunga 641
170 : leunga 744 val getSpills = G.PPtHashTable.find spillSet
171 :     val getSpills = fn p => case getSpills p of SOME s => s | NONE => []
172 :     val getReloads = G.PPtHashTable.find reloadSet
173 :     val getReloads = fn p => case getReloads p of SOME s => s | NONE => []
174 :     val getKills = G.PPtHashTable.find killSet
175 :     val getKills = fn p => case getKills p of SOME s => s | NONE => []
176 : leunga 641
177 :     fun getLoc(G.NODE{color=ref(G.ALIASED n), ...}) = getLoc n
178 : leunga 744 | getLoc(G.NODE{color=ref(G.MEMREG(_, m)), ...}) = G.MEM_REG m
179 :     | getLoc(G.NODE{color=ref(G.SPILL_LOC s), ...}) = G.FRAME s
180 :     | getLoc(G.NODE{color=ref(G.SPILLED), number, ...}) = G.FRAME number
181 :     | getLoc(G.NODE{color=ref(G.PSEUDO), number, ...}) = G.FRAME number
182 :     | getLoc _ = error "getLoc"
183 : leunga 641
184 : leunga 744 fun printRegs regs =
185 :     app (fn r => print(C.toString r^" ["^
186 :     Core.spillLocToString G (C.cellId r)^"] ")) regs
187 :    
188 :     val parallelCopies = Word.andb(Core.HAS_PARALLEL_COPIES, mode) <> 0w0
189 :    
190 :     fun chase(C.CELL{col=ref(C.ALIASED c), ...}) = chase c
191 :     | chase c = c
192 :    
193 :     fun cellId(C.CELL{id, ...}) = id
194 :    
195 :     fun sameCell(C.CELL{id=x,...}, C.CELL{id=y, ...}) = x=y
196 :    
197 :     fun same(x,regToSpill) = sameCell(chase x,regToSpill)
198 :    
199 : leunga 641 (*
200 :     * Rewrite the instruction given that a bunch of registers have
201 :     * to be spilled and reloaded.
202 :     *)
203 :     fun spillRewrite{pt, instrs, annotations} =
204 : leunga 744 let
205 : leunga 641 (* Environment manipulation functions.
206 :     * The environment is just a list of triples.
207 : leunga 744 *)
208 : leunga 641 fun update(pt,env,r,NONE) = kill(env, r)
209 : leunga 744 | update(pt,env,r,SOME newReg) =
210 : leunga 641 (r,newReg,pt)::(if !keep_multiple_values then env else [])
211 :    
212 :     and kill(env,r) =
213 :     let fun loop([], env') = env'
214 :     | loop((binding as (r',_,_))::env,env') =
215 : leunga 744 loop(env,
216 :     if C.sameColor(r, r') then env' else binding::env')
217 : leunga 641 in loop(env, []) end
218 :    
219 :     (*
220 :     * Insert reloading code for an instruction.
221 :     * Note: reload code goes after the instruction, if any.
222 :     *)
223 :     fun reloadInstr(pt,instr,regToSpill,env,spillLoc) =
224 :     let val {code, proh, newReg} =
225 : leunga 744 reload{instr=instr,reg=regToSpill,
226 : leunga 641 spillLoc=spillLoc,annotations=annotations}
227 :     in addProh(proh);
228 :     (code,update(pt,env,regToSpill,newReg))
229 :     end
230 :    
231 :     (*
232 :     * Renaming the source for an instruction.
233 :     *)
234 :     fun renameInstr(pt,instr,regToSpill,env,toSrc) =
235 :     let val {code, proh, newReg} =
236 : leunga 744 renameSrc{instr=instr, fromSrc=regToSpill,toSrc=toSrc}
237 : leunga 641 in addProh(proh);
238 : leunga 744 (code,update(pt,env,regToSpill,newReg))
239 : leunga 641 end
240 :    
241 :     (*
242 :     * Remove uses of regToSpill from a set of parallel copies.
243 :     * If there are multiple uses, then return multiple moves.
244 :     *)
245 :     fun extractUses(regToSpill, rds, rss) =
246 :     let fun loop(rd::rds, rs::rss, newRds, rds', rss') =
247 : leunga 744 if same(rs,regToSpill) then
248 : leunga 641 loop(rds, rss, rd::newRds, rds', rss')
249 :     else
250 :     loop(rds, rss, newRds, rd::rds', rs::rss')
251 :     | loop(_, _, newRds, rds', rss') = (newRds, rds', rss')
252 :     in loop(rds, rss, [], [], []) end
253 :    
254 :     (*
255 :     * Insert reload code for the sources of a copy.
256 :     * Transformation:
257 :     * d1..dn <- s1..sn
258 :     * =>
259 :     * d1..dn/r <- s1...sn/r.
260 :     * reload code
261 :     * reload copies
262 :     *
263 :     *)
264 :     fun reloadCopySrc(instr,regToSpill,env,spillLoc) =
265 :     let val (dst, src) = P.moveDstSrc instr
266 :     val (rds, copyDst, copySrc) = extractUses(regToSpill, dst, src)
267 :     fun processMoves([], reloadCode) = reloadCode
268 :     | processMoves(rd::rds, reloadCode) =
269 :     let val code =
270 :     reloadDst{spillLoc=spillLoc,reg=regToSpill,
271 :     dst=rd,annotations=annotations}
272 :     in processMoves(rds, code@reloadCode)
273 :     end
274 :     val reloadCode = processMoves(rds, [])
275 :     in case copyDst of
276 :     [] => (reloadCode, env)
277 : leunga 744 | _ => (copyInstr((copyDst, copySrc), instr) @ reloadCode, env)
278 : leunga 641 end
279 :    
280 :     (*
281 : leunga 744 * Insert reload code
282 : leunga 641 *)
283 :     fun reload(pt,instr,regToSpill,env,spillLoc) =
284 :     if P.moveInstr instr then
285 :     reloadCopySrc(instr,regToSpill,env,spillLoc)
286 :     else
287 : leunga 744 let fun lookup [] =
288 : leunga 641 reloadInstr(pt,instr,regToSpill,env,spillLoc)
289 : leunga 744 | lookup((r,currentReg,defPt)::env) =
290 :     if C.sameColor(r,regToSpill) then
291 : leunga 641 if defPt = pt
292 : leunga 744 then lookup env(* this is NOT the right renaming!*)
293 :     else if defPt - pt <= MAX_DIST then
294 :     renameInstr(pt,instr,regToSpill,env,currentReg)
295 : leunga 641 else
296 :     reloadInstr(pt,instr,regToSpill,env,spillLoc)
297 :     else
298 :     lookup(env)
299 : leunga 744 in lookup env
300 : leunga 641 end
301 : leunga 744
302 : leunga 641 (*
303 : leunga 744 * Check whether the id is in a list
304 : leunga 641 *)
305 : leunga 744 fun containsId(id,[]) = false
306 :     | containsId(id:C.cell_id,r::rs) = r = id orelse containsId(id,rs)
307 :     fun spillConflict(G.FRAME loc, rs) = containsId(~loc, rs)
308 :     | spillConflict(G.MEM_REG(C.CELL{id, ...}), rs) =
309 :     containsId(id, rs)
310 :    
311 :     fun contains(r',[]) = false
312 :     | contains(r',r::rs) = sameCell(r',r) orelse contains(r',rs)
313 :    
314 : leunga 641 (*
315 :     * Insert spill code for an instruction.
316 :     * Spill code occur after the instruction.
317 :     * If the value in regToSpill is never used, the client also
318 :     * has the opportunity to remove the instruction.
319 :     *)
320 :     fun spillInstr(pt,instr,regToSpill,spillLoc,kill,env) =
321 :     let val {code, proh, newReg} =
322 : leunga 744 spill{instr=instr,
323 : leunga 641 kill=kill, spillLoc=spillLoc,
324 :     reg=regToSpill, annotations=annotations}
325 :     in addProh(proh);
326 :     (code, update(pt,env,regToSpill,newReg))
327 :     end
328 :    
329 :     (* Remove the definition regToSpill <- from
330 :     * parallel copies rds <- rss.
331 :     * Note, there is a guarantee that regToSpill is not aliased
332 :     * to another register in the rds set.
333 :     *)
334 :     fun extractDef(regToSpill,rds,rss,kill) =
335 :     let fun loop(rd::rds, rs::rss, rds', rss') =
336 :     if spillLocOf rd = spillLocOf rs then
337 :     (rs, rds@rds', rss@rss', true)
338 : leunga 744 else if same(rd, regToSpill) then
339 : leunga 641 (rs, rds@rds', rss@rss', kill)
340 :     else loop(rds, rss, rd::rds', rs::rss')
341 :     | loop _ =
342 :     (print("rds=");
343 : leunga 744 app (fn r => print(C.toString r^":"^
344 :     i2s(spillLocOf r)^" ")) rds;
345 : leunga 641 print("\nrss=");
346 : leunga 744 app (fn r => print(C.toString r^":"^
347 :     i2s(spillLocOf r)^" ")) rss;
348 : leunga 641 print "\n";
349 : leunga 744 error("extractDef: "^C.toString regToSpill))
350 : leunga 641 in loop(rds, rss, [], []) end
351 :    
352 :     (*
353 :     * Insert spill code for a destination of a copy
354 :     * suppose d = r and we have a copy d <- s in
355 :     * d1...dn <- s1...sn
356 :     *
357 :     * d1...dn <- s1...sn
358 :     * =>
359 :     * spill s to spillLoc
360 :     * d1...dn/d <- s1...sn/s
361 :     *
362 :     * However, if the spill code may ovewrite the spill location
363 :     * shared by other uses, we do the following less
364 :     * efficient scheme:
365 :     *
366 :     * /* save the result of d */
367 :     * d1...dn, tmp <- s1...sn, s
368 :     * spill tmp to spillLoc /* spill d */
369 :     *
370 :     *)
371 : leunga 714 fun spillCopyDst(pt,instr,regToSpill,spillLoc,
372 : leunga 744 kill,env,don'tOverwrite) =
373 : leunga 641 let val (dst, src) = P.moveDstSrc instr
374 :     val (mvSrc,copyDst,copySrc,kill) =
375 :     extractDef(regToSpill,dst,src,kill)
376 :     val copy = case copyDst of
377 :     [] => []
378 :     | _ => copyInstr((copyDst,copySrc),instr)
379 :     in if kill
380 :     then (* kill the move *)
381 :     ((* print ("Copy "^Int.toString(hd mvDst)^" <- "^
382 :     Int.toString(hd mvSrc)^" removed\n"); *)
383 :     (copy, env)
384 :     )
385 :     else (* normal spill *)
386 : leunga 744 if spillConflict(spillLoc, don'tOverwrite) then
387 : leunga 641 let (* cycle found *)
388 :     (*val _ = print("Register r"^Int.toString regToSpill^
389 :     " overwrites ["^Int.toString spillLoc^"]\n")*)
390 : leunga 744 val tmp = I.C.newVar regToSpill (* new temporary *)
391 : leunga 641 val copy = copyInstr((tmp::copyDst, mvSrc::copySrc),
392 :     instr)
393 :     val spillCode = spillSrc{src=tmp,reg=regToSpill,
394 :     spillLoc=spillLoc,
395 :     annotations=annotations}
396 : leunga 714 in (copy @ spillCode, [(regToSpill,tmp,pt)])
397 : leunga 641 end
398 :     else
399 :     let (* spill the move instruction *)
400 :     val spillCode = spillSrc{src=mvSrc,reg=regToSpill,
401 :     spillLoc=spillLoc,
402 :     annotations=annotations}
403 : leunga 714 in (spillCode @ copy, [(regToSpill,mvSrc,pt)])
404 : leunga 641 end
405 :     end
406 :    
407 :     (*
408 :     * Insert spill code for a copy
409 :     *)
410 : leunga 744 fun spillCopy(pt,instr,regToSpill,spillLoc,kill,env,don'tOverwrite)=
411 : leunga 641 case P.moveTmpR instr of
412 : leunga 714 NONE => spillCopyDst(pt,instr,regToSpill,spillLoc,kill,env,
413 : leunga 641 don'tOverwrite)
414 :     | SOME tmp =>
415 : leunga 744 if same(tmp, regToSpill)
416 : leunga 641 then ((* spilledCopyTmps := !spilledCopyTmps + 1; *)
417 :     [spillCopyTmp{copy=instr, spillLoc=spillLoc,
418 : leunga 815 reg=regToSpill,
419 :     annotations=annotations}], [])
420 : leunga 714 else spillCopyDst(pt,instr,regToSpill,spillLoc,kill,
421 : leunga 641 env, don'tOverwrite)
422 :    
423 :     (*
424 :     * Insert spill code
425 :     *)
426 :     fun spill(pt,instr,regToSpill,spillLoc,killSet,env,don'tOverwrite) =
427 :     let val kill = contains(regToSpill,killSet)
428 :     in if P.moveInstr instr then
429 :     spillCopy(pt,instr,regToSpill,spillLoc,kill,env,don'tOverwrite)
430 :     else
431 :     spillInstr(pt,instr,regToSpill,spillLoc,kill,env)
432 :     end
433 :    
434 :     fun contains([],reg) = false
435 : leunga 744 | contains(r::rs,reg) = same(r,reg) orelse contains(rs,reg)
436 : leunga 641 fun hasDef(i,reg) = contains(#1(insnDefUse i),reg)
437 :     fun hasUse(i,reg) = contains(#2(insnDefUse i),reg)
438 :    
439 :     fun spillOneReg(pt,[],_,_,_,env,_) = ([], env)
440 : leunga 744 | spillOneReg(pt,i::instrs,r,spillLoc,killSet,env,don'tOverwrite)=
441 :     if hasDef(i,r) then
442 :     let val (instrs',env) =
443 :     spill(pt,i,r,spillLoc,killSet,env,don'tOverwrite)
444 :     in spillOneReg(pt,instrs'@instrs,r,spillLoc,
445 :     killSet,env,don'tOverwrite)
446 :     end
447 :     else
448 :     let val (instrs,env) =
449 :     spillOneReg(pt,instrs,r,spillLoc,killSet,
450 :     env,don'tOverwrite)
451 :     in (i::instrs, env)
452 :     end
453 : leunga 641
454 :     fun reloadOneReg(pt,[],_,env,_) = ([], env)
455 :     | reloadOneReg(pt,i::instrs,r,env,spillLoc) =
456 : leunga 744 if hasUse(i,r) then
457 : leunga 641 let val (instrs',env) = reload(pt,i,r,env,spillLoc)
458 : leunga 744 in reloadOneReg(pt,instrs'@instrs,r,env,spillLoc)
459 :     end
460 : leunga 641 else
461 : leunga 744 let val (instrs, env) = reloadOneReg(pt,instrs,r,env,spillLoc)
462 :     in (i::instrs, env)
463 :     end
464 : leunga 641
465 :     (* This function spills a set of registers for an instruction *)
466 : leunga 744 fun spillAll(pt,instrs,[],killSet,env,don'tOverwrite) = (instrs,env)
467 : leunga 641 | spillAll(pt,instrs,r::rs,killSet,env,don'tOverwrite) =
468 :     let val node = getnode r
469 :     val spillLoc = getLoc node
470 :     val (instrs, env) =
471 : leunga 744 spillOneReg(pt,instrs,r,spillLoc,killSet,
472 :     env,don'tOverwrite)
473 : leunga 641 in spillAll(pt,instrs,rs,killSet,env,don'tOverwrite)
474 :     end
475 :    
476 :     (* This function reloads a set of registers for an instruction *)
477 :     fun reloadAll(pt,instrs,env,[]) = (instrs, env)
478 :     | reloadAll(pt,instrs,env,r::rs) =
479 :     let val node = getnode r
480 :     val spillLoc = getLoc node
481 :     val (instrs, env) = reloadOneReg(pt,instrs,r,env,spillLoc)
482 : leunga 744 in reloadAll(pt, instrs, env, rs)
483 : leunga 641 end
484 :    
485 :     fun loop([], pt, env, newInstrs) = newInstrs
486 :     | loop(instr::rest, pt, env, newInstrs) =
487 :     let val spillRegs = getSpills pt
488 :     val reloadRegs = getReloads pt
489 :     in case (spillRegs, reloadRegs) of
490 : leunga 646 ([], []) =>
491 : leunga 744 let val env' =
492 :     case env of
493 :     [] => [] (* An approximation here *)
494 :     | _ => let val (defs, uses) = insnDefUse instr
495 :     in if hasNonDedicated defs orelse
496 :     hasNonDedicated uses then []
497 :     else env
498 :     end
499 :     (* should be handled better *)
500 : leunga 646 in loop(rest, dec pt, env', instr::newInstrs)
501 :     end
502 : leunga 641 | _ =>
503 :     (* Eliminate duplicates from the spill/reload candidates *)
504 :     let val killRegs = getKills pt
505 : leunga 744 val spillRegs = uniq spillRegs
506 :     val reloadRegs = uniq reloadRegs
507 : leunga 641
508 :     (* spill locations that we can't overwrite if we
509 :     * are spilling a parallel copy
510 :     *)
511 :     val don'tOverwrite =
512 :     if parallelCopies then spillLocsOf reloadRegs
513 :     else []
514 :    
515 : leunga 744 fun prEnv env =
516 : leunga 641 (print("Env=");
517 : leunga 744 app (fn (r,v,_) => print(C.toString r^"=>"^
518 :     C.toString v^" ")) env;
519 : leunga 641 print "\n")
520 :    
521 :     val (instrs,env) =
522 : leunga 744 spillAll(pt,[instr],spillRegs,killRegs,
523 :     env,don'tOverwrite)
524 : leunga 641
525 : leunga 744 val _ = if debug then
526 :     (print("pt="^i2s pt^"\n");
527 :     case spillRegs of
528 :     [] => ()
529 :     | _ => (print("Spilling ");
530 :     printRegs spillRegs;
531 :     print "\n");
532 :     case reloadRegs of
533 :     [] => ()
534 :     | _ => (print("Reloading ");
535 :     printRegs reloadRegs;
536 :     print "\n");
537 :     print "Before:"; emit instr;
538 :     prEnv env
539 :     ) else ()
540 :    
541 :     val (instrs, env) =
542 : leunga 641 reloadAll(pt,instrs,env,reloadRegs)
543 :    
544 :     val _ = if debug then
545 : leunga 744 (print "After:"; app emit instrs;
546 :     print "------------------\n")
547 :     else ()
548 : leunga 641
549 :     fun concat([], l) = l
550 :     | concat(a::b, l) = concat(b, a::l)
551 :     in loop(rest, dec pt, env, concat(instrs, newInstrs))
552 :     end
553 :     end
554 :     in loop(rev instrs, pt, [], [])
555 :     end
556 :     in spillRewrite
557 :     end
558 : leunga 744 end
559 : leunga 641
560 : leunga 744 end (* local *)

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