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 714 - (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 : george 705 | getLoc(G.NODE{color=ref(G.SPILLED), number, ...}) = number
238 :     | getLoc(G.NODE{color=ref(G.MEMREG m), ...}) = m
239 :     | getLoc(G.NODE{color=ref(G.SPILL_LOC s), ...}) = ~s
240 : leunga 641 | getLoc(G.NODE{number, ...}) = number
241 :    
242 :     val parallelCopies = Word.andb(RACore.HAS_PARALLEL_COPIES, mode) <> 0w0
243 :     (*
244 :     * Rewrite the instruction given that a bunch of registers have
245 :     * to be spilled and reloaded.
246 :     *)
247 :     fun spillRewrite{pt, instrs, annotations} =
248 :     let
249 :     (* Environment manipulation functions.
250 :     * The environment is just a list of triples.
251 :     *)
252 :     fun update(pt,env,r,NONE) = kill(env, r)
253 :     | update(pt,env,r,SOME newReg) =
254 :     (r,newReg,pt)::(if !keep_multiple_values then env else [])
255 :    
256 :     and kill(env,r) =
257 :     let fun loop([], env') = env'
258 :     | loop((binding as (r',_,_))::env,env') =
259 :     loop(env, if r = r' then env' else binding::env')
260 :     in loop(env, []) end
261 :    
262 :     (*
263 :     * Insert reloading code for an instruction.
264 :     * Note: reload code goes after the instruction, if any.
265 :     *)
266 :     fun reloadInstr(pt,instr,regToSpill,env,spillLoc) =
267 :     let val {code, proh, newReg} =
268 :     reload{regmap=regmap,instr=instr,reg=regToSpill,
269 :     spillLoc=spillLoc,annotations=annotations}
270 :     in addProh(proh);
271 :     (code,update(pt,env,regToSpill,newReg))
272 :     end
273 :    
274 :     (*
275 :     * Renaming the source for an instruction.
276 :     *)
277 :     fun renameInstr(pt,instr,regToSpill,env,toSrc) =
278 :     let val {code, proh, newReg} =
279 :     renameSrc{regmap=regmap,instr=instr,
280 :     fromSrc=regToSpill,toSrc=toSrc}
281 :     in addProh(proh);
282 :     (code,update(pt,env,regToSpill,newReg))
283 :     end
284 :    
285 :     (*
286 :     * Remove uses of regToSpill from a set of parallel copies.
287 :     * If there are multiple uses, then return multiple moves.
288 :     *)
289 :     fun extractUses(regToSpill, rds, rss) =
290 :     let fun loop(rd::rds, rs::rss, newRds, rds', rss') =
291 :     if regmap rs = regToSpill then
292 :     loop(rds, rss, rd::newRds, rds', rss')
293 :     else
294 :     loop(rds, rss, newRds, rd::rds', rs::rss')
295 :     | loop(_, _, newRds, rds', rss') = (newRds, rds', rss')
296 :     in loop(rds, rss, [], [], []) end
297 :    
298 :     (*
299 :     * Insert reload code for the sources of a copy.
300 :     * Transformation:
301 :     * d1..dn <- s1..sn
302 :     * =>
303 :     * d1..dn/r <- s1...sn/r.
304 :     * reload code
305 :     * reload copies
306 :     *
307 :     *)
308 :     fun reloadCopySrc(instr,regToSpill,env,spillLoc) =
309 :     let val (dst, src) = P.moveDstSrc instr
310 :     val (rds, copyDst, copySrc) = extractUses(regToSpill, dst, src)
311 :     fun processMoves([], reloadCode) = reloadCode
312 :     | processMoves(rd::rds, reloadCode) =
313 :     let val code =
314 :     reloadDst{spillLoc=spillLoc,reg=regToSpill,
315 :     dst=rd,annotations=annotations}
316 :     in processMoves(rds, code@reloadCode)
317 :     end
318 :     val reloadCode = processMoves(rds, [])
319 :     in case copyDst of
320 :     [] => (reloadCode, env)
321 :     | _ => (copyInstr((copyDst, copySrc), instr) @ reloadCode,env)
322 :     end
323 :    
324 :     (*
325 :     * Insert reload code.
326 :     * If regToSpill is live in the current environment, we choose
327 :     * to rename instead.
328 :     *)
329 :     fun reload(pt,instr,regToSpill,env,spillLoc) =
330 :     if P.moveInstr instr then
331 :     reloadCopySrc(instr,regToSpill,env,spillLoc)
332 :     else
333 :     let fun lookup [] =
334 :     reloadInstr(pt,instr,regToSpill,env,spillLoc)
335 :     | lookup((r,currentReg,defPt)::env) =
336 :     if r = regToSpill then
337 :     if defPt = pt
338 :     then lookup env (* this is NOT the right renaming!*)
339 :     else if defPt - pt <= MAX_DIST then
340 :     renameInstr(pt,instr,regToSpill,env,currentReg)
341 :     else
342 :     reloadInstr(pt,instr,regToSpill,env,spillLoc)
343 :     else
344 :     lookup(env)
345 :     in lookup env
346 :     end
347 :    
348 :     (*
349 :     * Check whether the regToSpill is in a list
350 :     *)
351 :     fun contains(regToSpill:int,[]) = false
352 :     | contains(regToSpill,r::rs) =
353 :     r = regToSpill orelse contains(regToSpill,rs)
354 :    
355 :     (*
356 :     * Insert spill code for an instruction.
357 :     * Spill code occur after the instruction.
358 :     * If the value in regToSpill is never used, the client also
359 :     * has the opportunity to remove the instruction.
360 :     *)
361 :     fun spillInstr(pt,instr,regToSpill,spillLoc,kill,env) =
362 :     let val {code, proh, newReg} =
363 :     spill{regmap=regmap, instr=instr,
364 :     kill=kill, spillLoc=spillLoc,
365 :     reg=regToSpill, annotations=annotations}
366 :     in addProh(proh);
367 :     (code, update(pt,env,regToSpill,newReg))
368 :     end
369 :    
370 :     (* Remove the definition regToSpill <- from
371 :     * parallel copies rds <- rss.
372 :     * Note, there is a guarantee that regToSpill is not aliased
373 :     * to another register in the rds set.
374 :     *)
375 :     fun extractDef(regToSpill,rds,rss,kill) =
376 :     let fun loop(rd::rds, rs::rss, rds', rss') =
377 :     if spillLocOf rd = spillLocOf rs then
378 :     (rs, rds@rds', rss@rss', true)
379 :     else if regmap rd = regToSpill then
380 :     (rs, rds@rds', rss@rss', kill)
381 :     else loop(rds, rss, rd::rds', rs::rss')
382 :     | loop _ =
383 :     (print("rds=");
384 :     app (fn r => print(Int.toString r^":"^
385 :     Int.toString(spillLocOf r)^" ")) rds;
386 :     print("\nrss=");
387 :     app (fn r => print(Int.toString r^":"^
388 :     Int.toString(spillLocOf r)^" ")) rss;
389 :     print "\n";
390 :     error("extractDef: "^Int.toString regToSpill))
391 :     in loop(rds, rss, [], []) end
392 :    
393 :     (*
394 :     * Insert spill code for a destination of a copy
395 :     * suppose d = r and we have a copy d <- s in
396 :     * d1...dn <- s1...sn
397 :     *
398 :     * d1...dn <- s1...sn
399 :     * =>
400 :     * spill s to spillLoc
401 :     * d1...dn/d <- s1...sn/s
402 :     *
403 :     * However, if the spill code may ovewrite the spill location
404 :     * shared by other uses, we do the following less
405 :     * efficient scheme:
406 :     *
407 :     * /* save the result of d */
408 :     * d1...dn, tmp <- s1...sn, s
409 :     * spill tmp to spillLoc /* spill d */
410 :     *
411 :     *)
412 : leunga 714 fun spillCopyDst(pt,instr,regToSpill,spillLoc,
413 :     kill,env,don'tOverwrite) =
414 : leunga 641 let val (dst, src) = P.moveDstSrc instr
415 :     val (mvSrc,copyDst,copySrc,kill) =
416 :     extractDef(regToSpill,dst,src,kill)
417 :     val copy = case copyDst of
418 :     [] => []
419 :     | _ => copyInstr((copyDst,copySrc),instr)
420 :     in if kill
421 :     then (* kill the move *)
422 :     ((* print ("Copy "^Int.toString(hd mvDst)^" <- "^
423 :     Int.toString(hd mvSrc)^" removed\n"); *)
424 :     (copy, env)
425 :     )
426 :     else (* normal spill *)
427 :     if contains(spillLoc, don'tOverwrite) then
428 :     let (* cycle found *)
429 :     (*val _ = print("Register r"^Int.toString regToSpill^
430 :     " overwrites ["^Int.toString spillLoc^"]\n")*)
431 :     val tmp = I.C.newCell cellkind () (* new temporary *)
432 :     val copy = copyInstr((tmp::copyDst, mvSrc::copySrc),
433 :     instr)
434 :     val spillCode = spillSrc{src=tmp,reg=regToSpill,
435 :     spillLoc=spillLoc,
436 :     annotations=annotations}
437 : leunga 714 in (copy @ spillCode, [(regToSpill,tmp,pt)])
438 : leunga 641 end
439 :     else
440 :     let (* spill the move instruction *)
441 :     val spillCode = spillSrc{src=mvSrc,reg=regToSpill,
442 :     spillLoc=spillLoc,
443 :     annotations=annotations}
444 : leunga 714 in (spillCode @ copy, [(regToSpill,mvSrc,pt)])
445 : leunga 641 end
446 :     end
447 :    
448 :     (*
449 :     * Insert spill code for a copy
450 :     *)
451 :     fun spillCopy(pt,instr,regToSpill,spillLoc,kill,env,don'tOverwrite) =
452 :     case P.moveTmpR instr of
453 : leunga 714 NONE => spillCopyDst(pt,instr,regToSpill,spillLoc,kill,env,
454 : leunga 641 don'tOverwrite)
455 :     | SOME tmp =>
456 :     if regmap tmp = regToSpill
457 :     then ((* spilledCopyTmps := !spilledCopyTmps + 1; *)
458 :     [spillCopyTmp{copy=instr, spillLoc=spillLoc,
459 :     annotations=annotations}], [])
460 : leunga 714 else spillCopyDst(pt,instr,regToSpill,spillLoc,kill,
461 : leunga 641 env, don'tOverwrite)
462 :    
463 :     (*
464 :     * Insert spill code
465 :     *)
466 :     fun spill(pt,instr,regToSpill,spillLoc,killSet,env,don'tOverwrite) =
467 :     let val kill = contains(regToSpill,killSet)
468 :     in if P.moveInstr instr then
469 :     spillCopy(pt,instr,regToSpill,spillLoc,kill,env,don'tOverwrite)
470 :     else
471 :     spillInstr(pt,instr,regToSpill,spillLoc,kill,env)
472 :     end
473 :    
474 :     fun contains([],reg) = false
475 :     | contains(r::rs,reg) = regmap r = reg orelse contains(rs,reg)
476 :     fun hasDef(i,reg) = contains(#1(insnDefUse i),reg)
477 :     fun hasUse(i,reg) = contains(#2(insnDefUse i),reg)
478 :    
479 :     fun spillOneReg(pt,[],_,_,_,env,_) = ([], env)
480 :     | spillOneReg(pt,i::instrs,r,spillLoc,killSet,env,don'tOverwrite) =
481 :     if hasDef(i,r) then
482 :     let val (instrs',env) =
483 :     spill(pt,i,r,spillLoc,killSet,env,don'tOverwrite)
484 :     in spillOneReg(pt,instrs'@instrs,r,spillLoc,
485 :     killSet,env,don'tOverwrite)
486 :     end
487 :     else
488 :     let val (instrs,env) =
489 :     spillOneReg(pt,instrs,r,spillLoc,killSet,env,don'tOverwrite)
490 :     in (i::instrs, env)
491 :     end
492 :    
493 :     fun reloadOneReg(pt,[],_,env,_) = ([], env)
494 :     | reloadOneReg(pt,i::instrs,r,env,spillLoc) =
495 :     if hasUse(i,r) then
496 :     let val (instrs',env) = reload(pt,i,r,env,spillLoc)
497 :     in reloadOneReg(pt,instrs'@instrs,r,env,spillLoc) end
498 :     else
499 :     let val (instrs,env) = reloadOneReg(pt,instrs,r,env,spillLoc)
500 :     in (i::instrs, env) end
501 :    
502 :     (* This function spills a set of registers for an instruction *)
503 :     fun spillAll(pt,instrs,[],killSet,env,don'tOverwrite) = (instrs, env)
504 :     | spillAll(pt,instrs,r::rs,killSet,env,don'tOverwrite) =
505 :     let val node = getnode r
506 :     val spillLoc = getLoc node
507 :     val (instrs, env) =
508 :     spillOneReg(pt,instrs,r,spillLoc,killSet,env,don'tOverwrite)
509 :     in spillAll(pt,instrs,rs,killSet,env,don'tOverwrite)
510 :     end
511 :    
512 :     (* This function reloads a set of registers for an instruction *)
513 :     fun reloadAll(pt,instrs,env,[]) = (instrs, env)
514 :     | reloadAll(pt,instrs,env,r::rs) =
515 :     let val node = getnode r
516 :     val spillLoc = getLoc node
517 :     val (instrs, env) = reloadOneReg(pt,instrs,r,env,spillLoc)
518 :     in reloadAll(pt,instrs,env,rs)
519 :     end
520 :    
521 :     fun loop([], pt, env, newInstrs) = newInstrs
522 :     | loop(instr::rest, pt, env, newInstrs) =
523 :     let val spillRegs = getSpills pt
524 :     val reloadRegs = getReloads pt
525 :     in case (spillRegs, reloadRegs) of
526 : leunga 646 ([], []) =>
527 :     let val env' =
528 :     case env of
529 :     [] => []
530 :     | _ => let val (defs, uses) = insnDefUse instr
531 :     in if hasNonDedicated defs orelse
532 :     hasNonDedicated uses then []
533 :     else env
534 :     end
535 :     in loop(rest, dec pt, env', instr::newInstrs)
536 :     end
537 : leunga 641 | _ =>
538 :     (* Eliminate duplicates from the spill/reload candidates *)
539 :     let val killRegs = getKills pt
540 :     val spillRegs = SL.uniq spillRegs
541 :     val reloadRegs = SL.uniq reloadRegs
542 :    
543 :     (* spill locations that we can't overwrite if we
544 :     * are spilling a parallel copy
545 :     *)
546 :     val don'tOverwrite =
547 :     if parallelCopies then spillLocsOf reloadRegs
548 :     else []
549 :    
550 :     fun prEnv env =
551 :     (print("Env=");
552 :     app (fn (r,v,_) => print(Int.toString r^"=>"^
553 :     Int.toString v^" ")) env;
554 :     print "\n")
555 :    
556 :     val _ =
557 :     if debug then
558 :     let val regs = app (fn r =>
559 :     print(Int.toString(regmap r)^" ["^Int.toString
560 :     (getLoc (getnode r))^"] "))
561 :     in print("pt="^Int.toString pt^"\n");
562 :     if spillRegs = [] then () else
563 :     (print("Spilling ");
564 :     regs spillRegs; print "\n");
565 :     if reloadRegs = [] then () else
566 :     (print("Reloading ");
567 :     regs reloadRegs; print "\n");
568 :     print "Before:"; emit regmap instr;
569 :     prEnv env
570 :     end else ()
571 :    
572 :     (* Generate all the spills *)
573 :     val (instrs,env) =
574 :     spillAll(pt,[instr],spillRegs,killRegs,
575 :     env,don'tOverwrite)
576 :    
577 :     val (instrs,env) =
578 :     reloadAll(pt,instrs,env,reloadRegs)
579 :    
580 :     val _ = if debug then
581 :     (print "After:"; app (emit regmap) instrs;
582 :     prEnv env;
583 :     print "------------------\n") else ()
584 :    
585 :     fun concat([], l) = l
586 :     | concat(a::b, l) = concat(b, a::l)
587 :     in loop(rest, dec pt, env, concat(instrs, newInstrs))
588 :     end
589 :     end
590 :     in loop(rev instrs, pt, [], [])
591 :     end
592 :     in spillRewrite
593 :     end
594 :    
595 :     end

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