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

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