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/cluster-ra.sml
ViewVC logotype

Annotation of /sml/trunk/src/MLRISC/ra/cluster-ra.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 900 - (view) (download)

1 : monnier 467 (*
2 :     * This module provides services for the new RA when using the cluster
3 :     * representation.
4 : monnier 475 * The algorithm is adapted from
5 :     * Algorithm 19.17 from Appel, Modern Compiler Implementation in ML,
6 :     * Calculation of live ranges in SSA form. We don't directly use SSA
7 :     * here but the principles are the same.
8 : monnier 467 *
9 :     * -- Allen
10 :     *)
11 :    
12 :     functor ClusterRA
13 :     (structure Flowgraph : FLOWGRAPH
14 :     structure Asm : INSTRUCTION_EMITTER
15 :     structure InsnProps : INSN_PROPERTIES
16 : leunga 744 structure Spill : RA_SPILL
17 : leunga 641 sharing Flowgraph.I = InsnProps.I = Asm.I = Spill.I
18 : monnier 467 sharing Asm.P = Flowgraph.P
19 :     ) : RA_FLOWGRAPH =
20 :     struct
21 :     structure F = Flowgraph
22 :     structure I = F.I
23 :     structure W = F.W
24 :     structure G = RAGraph
25 :     structure Props = InsnProps
26 :     structure Core = RACore
27 :     structure A = Array
28 :     structure UA = Unsafe.Array (* okay, I'm cheating a bit here *)
29 : leunga 641 structure Spill = Spill
30 : monnier 467
31 : george 545 structure PrintCluster = PrintCluster
32 : monnier 467 (structure Flowgraph = F
33 :     structure Asm = Asm
34 :     )
35 :    
36 :     open G
37 : george 889 structure C = I.C
38 :     structure CB = CellsBasis
39 : monnier 467
40 : monnier 498 fun isOn(flag,mask) = Word.andb(flag,mask) <> 0w0
41 :    
42 : leunga 628 val dump_size = MLRiscControl.getFlag "ra-dump-size"
43 :    
44 : monnier 467 type flowgraph = F.cluster (* flowgraph is a cluster *)
45 :    
46 :     fun error msg = MLRiscErrorMsg.error("ClusterRA", msg)
47 : leunga 744
48 :     val i2s = Int.toString
49 : monnier 498
50 :     val mode = 0w0
51 : monnier 467
52 : george 889 fun uniqCells s = CB.SortedCells.return(CB.SortedCells.uniq s)
53 : monnier 467
54 : george 889 fun chaseCell(c as CB.CELL{col=ref(CB.MACHINE r),...}) = (c,r)
55 :     | chaseCell(CB.CELL{col=ref(CB.ALIASED c), ...}) = chaseCell c
56 :     | chaseCell(c as CB.CELL{col=ref CB.SPILLED, ...}) = (c,~1)
57 :     | chaseCell(c as CB.CELL{col=ref CB.PSEUDO, id, ...}) = (c,id)
58 : leunga 744
59 : george 889 fun colorOf(CB.CELL{col=ref(CB.MACHINE r),...}) = r
60 :     | colorOf(CB.CELL{col=ref(CB.ALIASED c), ...}) = colorOf c
61 :     | colorOf(CB.CELL{col=ref CB.SPILLED, ...}) = ~1
62 :     | colorOf(CB.CELL{col=ref CB.PSEUDO, id, ...}) = id
63 : leunga 744
64 :     fun chase(NODE{color=ref(ALIASED n), ...}) = chase n
65 :     | chase n = n
66 :    
67 : monnier 467 fun dumpFlowgraph(msg, cluster, stream) =
68 :     PrintCluster.printCluster stream
69 :     ("------------------ "^msg^" ------------------") cluster
70 :    
71 :     exception NotThere
72 :    
73 :     val dummyLabel = F.LABEL(Label.Label{id= ~1, addr=ref ~1, name=""})
74 :    
75 : monnier 498 fun x + y = Word.toIntX(Word.+(Word.fromInt x, Word.fromInt y))
76 : monnier 467
77 :     fun length l =
78 :     let fun loop([],n) = n
79 : monnier 498 | loop(_::l,n) = loop(l,n+1)
80 : monnier 467 in loop(l,0) end
81 :    
82 : george 823 fun services(cluster as F.CLUSTER{blocks, blkCounter, annotations=clAnns, ...}) =
83 : monnier 467 let (* Create a graph based view of cluster *)
84 : leunga 585 val N = !blkCounter
85 : monnier 467
86 : monnier 498 fun computeShift(0w0, max) = 0w31-max
87 :     | computeShift(N, max) = computeShift(Word.>>(N, 0w1), Word.+(max,0w1))
88 :     val shift = computeShift(Word.>>(Word.fromInt N, 0w15), 0w15)
89 :     val mask = Word.<<(0w1, shift) - 0w1
90 :    
91 :     (*
92 :     * Construct program point
93 :     *)
94 :     fun progPt(blknum, instrId) =
95 :     Word.toIntX(Word.+(Word.<<(Word.fromInt blknum, shift),
96 :     Word.fromInt instrId))
97 :     fun blockNum pt = Word.toIntX(Word.>>(Word.fromInt pt, shift))
98 :     fun instrNum pt = Word.toIntX(Word.andb(Word.fromInt pt, mask))
99 :    
100 : george 545 (* blocks indexed by block id *)
101 : monnier 467 val blockTable = A.array(N, dummyLabel)
102 :    
103 : george 545 fun fillBlockTable [] = ()
104 :     | fillBlockTable((b as F.BBLOCK{blknum, ...})::blocks) =
105 :     (UA.update(blockTable, blknum, b); fillBlockTable blocks)
106 :     | fillBlockTable(_::blocks) = fillBlockTable blocks
107 :     val _ = fillBlockTable blocks
108 : monnier 467
109 :     (*
110 : george 545 * Building the interference graph
111 :     *)
112 : leunga 744 fun buildIt (cellkind,
113 : george 545 G as GRAPH{nodes, dedicated, mode, span, copyTmps, ...}) =
114 : monnier 467
115 : george 545 let (* definitions indexed by block id+instruction id *)
116 :     val defsTable = A.array(N, A.array(0, [] : node list))
117 :     val marked = A.array(N, ~1)
118 : leunga 744 val addEdge = Core.addEdge G
119 : leunga 624
120 : leunga 744 (* copies indexed by source
121 :     * This table maps variable v to the program points where
122 :     * v is a source of a copy.
123 :     *)
124 :     val copyTable = IntHashTable.mkTable(N, NotThere)
125 : george 889 : {dst:CB.cell,pt:int} list IntHashTable.hash_table
126 : leunga 744 val lookupCopy = IntHashTable.find copyTable
127 :     val lookupCopy = fn r => case lookupCopy r of SOME c => c
128 :     | NONE => []
129 : blume 733 val addCopy = IntHashTable.insert copyTable
130 : leunga 624
131 :    
132 : george 545 val stamp = ref 0
133 :    
134 :     (* Allocate the arrays *)
135 :     fun alloc [] = ()
136 :     | alloc((b as F.BBLOCK{blknum, insns, ...})::blocks) =
137 :     let val n = length(!insns)
138 :     val m = n+1
139 :     in UA.update(defsTable, blknum, A.array(m, []));
140 :     alloc blocks
141 :     end
142 :     | alloc(_::blocks) = alloc blocks
143 :     val _ = alloc blocks
144 :    
145 :     (*
146 :     * Remove pseudo use generated by copy temporaries
147 :     *)
148 :     fun rmPseudoUses [] = ()
149 :     | rmPseudoUses(NODE{uses,...}::ns) = (uses := []; rmPseudoUses ns)
150 :    
151 :     (*
152 : leunga 624 * Initialize the definitions before computing the liveness for v.
153 : george 545 *)
154 : leunga 624 fun initialize(v,v',useSites) =
155 :     let (* First we remove all definitions for all copies
156 :     * with v as source.
157 : leunga 744 * When we have a copy and while we are processing v
158 :     *
159 :     * x <- v
160 :     *
161 :     * x does not really interfere with v at this point,
162 :     * so we remove the definition of x temporarily.
163 : leunga 624 *)
164 :     fun markCopies([], trail) = trail
165 :     | markCopies({pt, dst}::copies, trail) =
166 :     let val b = blockNum pt
167 :     val i = instrNum pt
168 :     val defs = UA.sub(defsTable, b)
169 :     val nodes = UA.sub(defs, i)
170 :     fun revAppend([], nodes) = nodes
171 :     | revAppend(n::ns, nodes) = revAppend(ns, n::nodes)
172 : leunga 744 val dstColor = colorOf dst
173 : leunga 624 fun removeDst([], nodes') = nodes'
174 :     | removeDst((d as NODE{number=r,...})::nodes, nodes')=
175 : leunga 744 if r = dstColor then revAppend(nodes', nodes)
176 : leunga 624 else removeDst(nodes, d::nodes')
177 :     val nodes' = removeDst(nodes, [])
178 :     in UA.update(defs, i, nodes');
179 :     markCopies(copies, (defs, i, nodes)::trail)
180 : george 545 end
181 : leunga 624
182 :     (*
183 : leunga 744 * Then we mark all use sites of v with a fake definition so that
184 :     * the scanning will terminate correctly at these points.
185 : leunga 624 *)
186 :     fun markUseSites([], trail) = trail
187 :     | markUseSites(pt::pts, trail) =
188 :     let val b = blockNum pt
189 :     val i = instrNum pt
190 :     val defs = UA.sub(defsTable, b)
191 :     val nodes = UA.sub(defs, i)
192 :     in UA.update(defs, i, v'::nodes);
193 :     markUseSites(pts, (defs, i, nodes)::trail)
194 : george 545 end
195 : leunga 624
196 :     val copies = lookupCopy v
197 :     val trail = markCopies(copies, [])
198 :     val trail = markUseSites(useSites, trail)
199 :     in trail end
200 : george 545
201 : leunga 624 fun cleanup [] = ()
202 :     | cleanup ((defs, i, nodes)::trail) =
203 :     (UA.update(defs, i, nodes); cleanup trail)
204 : george 545 (*
205 :     * Perform incremental liveness analysis on register v
206 :     * and compute the span
207 :     *)
208 : leunga 744 fun liveness(v, v' as NODE{uses, ...}, cellV) =
209 : george 545 let val st = !stamp
210 :     val _ = stamp := st + 1
211 :     fun foreachUseSite([], span) = span
212 :     | foreachUseSite(u::uses, span) =
213 :     let val b = blockNum u
214 :     val i = instrNum u
215 :     in case UA.sub(blockTable, b) of
216 :     block as F.BBLOCK{freq, ...} =>
217 :     let val span =
218 :     if i = 0 then
219 :     liveOutAtBlock(block, span) (* live out *)
220 :     else
221 :     let val f = !freq
222 : leunga 624 val defs = UA.sub(defsTable, b)
223 :     in liveOutAtStmt(block, A.length defs,
224 :     defs, i+1, f, span+f)
225 : george 545 end;
226 :     in foreachUseSite(uses, span)
227 :     end
228 :     | _ => error "liveness2"
229 :     end
230 :    
231 :     and visitPred(block, span) =
232 :     let fun foreachPred([], span) = span
233 :     | foreachPred((b, _)::pred, span) =
234 :     let val span = liveOutAtBlock(b, span)
235 :     in foreachPred(pred, span) end
236 :     in case block of
237 :     F.BBLOCK{pred, ...} => foreachPred(!pred, span)
238 :     | _ => error "visitPred"
239 :     end
240 :    
241 : leunga 624 and liveOutAtStmt(block, nDefs, defs, pos, freq, span) =
242 : george 545 (* v is live out *)
243 : leunga 624 if pos < nDefs then
244 : george 545 let fun foreachDef([], true) = span
245 :     | foreachDef([], false) =
246 : leunga 624 liveOutAtStmt(block, nDefs, defs,
247 :     pos+1, freq, span+freq)
248 : george 545 | foreachDef((d as NODE{number=r, ...})::ds, kill) =
249 :     if r = v then foreachDef(ds, true)
250 :     else (addEdge(d, v'); foreachDef(ds, kill))
251 :     in foreachDef(UA.sub(defs, pos), false)
252 :     end
253 :     else visitPred(block, span)
254 :    
255 :     and liveOutAtBlock(block as F.BBLOCK{blknum, freq, ...}, span) =
256 :     (* v is live out at the current block *)
257 :     if UA.sub(marked, blknum) = st then span
258 :     else
259 :     (UA.update(marked, blknum, st);
260 : leunga 624 let val defs = UA.sub(defsTable, blknum)
261 :     in liveOutAtStmt(block, A.length defs, defs,
262 :     1, !freq, span)
263 :     end
264 : george 545 )
265 :     | liveOutAtBlock(_, span) = span
266 : leunga 624
267 :     val useSites = SortedList.uniq(!uses)
268 :     val trail = initialize(v, v', useSites)
269 : george 545 val span = foreachUseSite (useSites, 0)
270 : leunga 624 val _ = cleanup trail
271 :     in span
272 : george 545 end
273 : george 705
274 : george 545 val newNodes = Core.newNodes G
275 : blume 733 val getnode = IntHashTable.lookup nodes
276 : monnier 467 val insnDefUse = Props.defUse cellkind
277 : jhr 900 val getCell = C.getCellsByKind cellkind
278 : monnier 467
279 : george 823 fun isDedicated r = dedicated r
280 : monnier 467
281 : monnier 498 (* Remove all dedicated or spilled registers from the list *)
282 : monnier 467 fun rmvDedicated regs =
283 :     let fun loop([], rs') = rs'
284 :     | loop(r::rs, rs') =
285 : george 889 let fun rmv(r as CB.CELL{col=ref(CB.PSEUDO), id, ...}) =
286 : george 823 if isDedicated(id) then loop(rs, rs') else loop(rs, r::rs')
287 : george 889 | rmv(CB.CELL{col=ref(CB.ALIASED r), ...}) = rmv r
288 :     | rmv(r as CB.CELL{col=ref(CB.MACHINE col), ...}) =
289 : leunga 744 if isDedicated col then loop(rs, rs')
290 :     else loop(rs, r::rs')
291 : george 889 | rmv(CB.CELL{col=ref(CB.SPILLED), ...}) = loop(rs,rs')
292 : leunga 744 in rmv r
293 :     end
294 : monnier 467 in loop(regs, []) end
295 :    
296 :     (*
297 :     * Create parallel move
298 :     *)
299 : leunga 624 fun mkMoves(insn, pt, dst, src, cost, mv, tmps) =
300 : monnier 467 if Props.moveInstr insn then
301 :     let val (dst, tmps) =
302 :     case (Props.moveTmpR insn, dst) of
303 :     (SOME r, _::dst) =>
304 :     (* Add a pseudo use for tmpR *)
305 : leunga 744 (case chase(getnode(colorOf r)) of
306 :     tmp as NODE{uses,defs=ref [d],...} =>
307 :     (uses := [d-1]; (dst, tmp::tmps))
308 :     | _ => error "mkMoves"
309 :     )
310 : monnier 467 | (_, dst) => (dst, tmps)
311 :     fun moves([], [], mv) = mv
312 :     | moves(d::ds, s::ss, mv) =
313 : leunga 744 let val (d, cd) = chaseCell d
314 :     val (s, cs) = chaseCell s
315 :     in if isDedicated cd orelse isDedicated cs
316 :     then moves(ds, ss, mv)
317 :     else if cd = cs then moves(ds, ss, mv)
318 :     else
319 :     let val _ =
320 :     addCopy(cs, {dst=d, pt=pt}::lookupCopy cs);
321 :     val dst = chase(getnode cd)
322 :     val src = chase(getnode cs)
323 :     in moves(ds, ss, MV{dst=dst, src=src,
324 :     status=ref WORKLIST,
325 :     hicount=ref 0,
326 :     (* kind=REG_TO_REG, *)
327 :     cost=cost}::mv
328 :     )
329 :     end
330 : monnier 467 end
331 :     | moves _ = error "moves"
332 :     in (moves(dst, src, mv), tmps) end
333 :     else (mv, tmps)
334 :    
335 :     (* Add the nodes first *)
336 :     fun mkNodes([], mv, tmps) = (mv, tmps)
337 :     | mkNodes(F.BBLOCK{blknum, insns, succ, freq=ref w,
338 :     liveOut, ...}::blks, mv, tmps)=
339 :     let val dtab = A.sub(defsTable, blknum)
340 :     fun scan([], pt, i, mv, tmps) = (pt, i, mv, tmps)
341 : leunga 624 | scan(insn::rest, pt, i, mv, tmps) =
342 : monnier 467 let val (d, u) = insnDefUse insn
343 :     val defs = rmvDedicated d
344 :     val uses = rmvDedicated u
345 :     val defs = newNodes{cost=w, pt=pt,
346 :     defs=defs, uses=uses}
347 :     val _ = UA.update(dtab, i, defs)
348 : leunga 744 val (mv, tmps) =
349 :     mkMoves(insn, pt, d, u, w, mv, tmps)
350 : monnier 498 in scan(rest, pt+1, i+1, mv, tmps)
351 : monnier 467 end
352 :     val (pt, i, mv, tmps) =
353 :     scan(!insns, progPt(blknum,1), 1, mv, tmps)
354 :     val _ = if pt >= progPt(blknum+1, 0) then
355 : monnier 498 error("mkNodes: too many instructions")
356 : monnier 467 else ()
357 : leunga 585 in (* If the block is escaping, then all liveout
358 : monnier 467 * registers are considered used here.
359 :     *)
360 :     case !succ of
361 :     [(F.EXIT _, _)] =>
362 : leunga 744 let val liveSet = rmvDedicated(
363 :     uniqCells(getCell(!liveOut)))
364 : monnier 467 in newNodes{cost=w, pt=progPt(blknum, 0),
365 :     defs=[], uses=liveSet}; ()
366 :     end
367 :     | _ => ()
368 :     ;
369 :     mkNodes(blks, mv, tmps)
370 :     end
371 :     | mkNodes(_::blks, mv, tmps) = mkNodes(blks, mv, tmps)
372 :    
373 :     (* Add the edges *)
374 :    
375 :     val (moves, tmps) = mkNodes(blocks, [], [])
376 : blume 733 in IntHashTable.appi
377 : leunga 624 (let val setSpan =
378 :     if isOn(mode,Core.COMPUTE_SPAN) then
379 : leunga 744 let val spanMap = IntHashTable.mkTable
380 :     (IntHashTable.numItems nodes, NotThere)
381 : blume 733 val setSpan = IntHashTable.insert spanMap
382 : leunga 624 val _ = span := SOME spanMap
383 :     in setSpan end
384 :     else fn _ => ()
385 : leunga 744 in fn (v, v' as NODE{cell, color, ...}) =>
386 :     let fun computeLiveness() =
387 :     setSpan(v, liveness(v, v', cell))
388 :     in case !color of
389 :     PSEUDO => computeLiveness()
390 :     | COLORED _ => computeLiveness()
391 :     | MEMREG _ => computeLiveness()
392 :     | _ => ()
393 :     end
394 : leunga 624 end
395 : monnier 498 ) nodes;
396 :     if isOn(Core.SAVE_COPY_TEMPS, mode) then copyTmps := tmps else ();
397 : monnier 467 rmPseudoUses tmps;
398 :     moves
399 :     end
400 :    
401 :     (*
402 :     * Build the interference graph initially.
403 :     *)
404 : leunga 628 fun build(G, cellkind) =
405 : leunga 744 let val moves = buildIt(cellkind, G)
406 : leunga 628 in if !dump_size then
407 :     let val GRAPH{nodes, bitMatrix,...} = G
408 :     val insns =
409 :     foldr (fn (F.BBLOCK{insns,...},n) => length(!insns) + n
410 :     | (_,n) => n) 0 blocks
411 :     in TextIO.output(!MLRiscControl.debug_stream,
412 : leunga 744 "RA #blocks="^i2s N^
413 :     " #insns="^i2s insns^
414 :     " #nodes="^i2s(IntHashTable.numItems nodes)^
415 :     " #edges="^i2s(Core.BM.size(!bitMatrix))^
416 :     " #moves="^i2s(length moves)^"\n")
417 : leunga 628 end
418 :     else ();
419 :     moves
420 :     end
421 : george 705
422 : monnier 467 (*
423 :     * Rebuild the interference graph;
424 :     * We'll just do it from scratch for now.
425 :     *)
426 :     fun rebuild(cellkind, G) =
427 : leunga 579 (Core.clearNodes G;
428 : leunga 744 buildIt(cellkind, G)
429 : leunga 579 )
430 : monnier 467
431 :     (*
432 :     * Spill a set of nodes and rewrite the flowgraph
433 :     *)
434 : monnier 498 fun spill{copyInstr, spill, spillSrc, spillCopyTmp,
435 : leunga 744 reload, reloadDst, renameSrc, graph,
436 : monnier 467 cellkind, nodes=nodesToSpill} =
437 : leunga 579 let (* Remove the interference graph now *)
438 :     val _ = Core.clearGraph graph
439 :    
440 : monnier 467 (* maps program point to registers to be spilled *)
441 : blume 733 val spillSet = IntHashTable.mkTable(32, NotThere)
442 : monnier 467
443 :     (* maps program point to registers to be reloaded *)
444 : blume 733 val reloadSet = IntHashTable.mkTable(32, NotThere)
445 : monnier 467
446 :     (* maps program point to registers to be killed *)
447 : leunga 744 val killSet = IntHashTable.mkTable(32, NotThere)
448 : monnier 467
449 : monnier 498 val spillRewrite = Spill.spillRewrite
450 :     { graph=graph,
451 :     spill=spill,
452 :     spillSrc=spillSrc,
453 :     spillCopyTmp=spillCopyTmp,
454 :     reload=reload,
455 :     reloadDst=reloadDst,
456 :     renameSrc=renameSrc,
457 :     copyInstr=copyInstr,
458 :     cellkind=cellkind,
459 :     spillSet=spillSet,
460 :     reloadSet=reloadSet,
461 :     killSet=killSet
462 :     }
463 :    
464 : monnier 467 (* set of basic blocks that are affected *)
465 : blume 733 val affectedBlocks = IntHashTable.mkTable(32, NotThere)
466 : monnier 467
467 : blume 733 val addAffectedBlocks = IntHashTable.insert affectedBlocks
468 : monnier 467
469 : george 705 fun ins set = let
470 : blume 733 val add = IntHashTable.insert set
471 : leunga 744 val look = IntHashTable.find set
472 :     val look = fn r => case look r of SOME s => s | NONE => []
473 : leunga 579 fun enter(r, []) = ()
474 :     | enter(r, pt::pts) =
475 :     (add (pt, r::look pt);
476 :     addAffectedBlocks (blockNum pt, true);
477 :     enter(r, pts)
478 :     )
479 :     in enter
480 : monnier 467 end
481 :    
482 :     val insSpillSet = ins spillSet
483 :     val insReloadSet = ins reloadSet
484 :     val insKillSet =
485 : george 705 let
486 : blume 733 val add = IntHashTable.insert killSet
487 : leunga 744 val look = IntHashTable.find killSet
488 :     val look = fn r => case look r of SOME s => s | NONE => []
489 : leunga 579 fun enter(r, []) = ()
490 :     | enter(r, pt::pts) = (add(pt, r::look pt); enter(r, pts))
491 : george 705 in enter
492 :     end
493 : monnier 467
494 : monnier 498 (* Mark all spill/reload locations *)
495 : leunga 744 fun markSpills(G.NODE{color, number, cell, defs, uses, ...}) =
496 : monnier 498 let fun spillIt(defs, uses) =
497 : leunga 744 (insSpillSet(cell, defs);
498 :     insReloadSet(cell, uses);
499 : monnier 498 (* Definitions but no use! *)
500 :     case uses of
501 : leunga 744 [] => insKillSet(cell, defs)
502 : monnier 498 | _ => ()
503 :     )
504 : george 705 val d = !defs
505 :     val u = !uses
506 :     in
507 :     case !color
508 :     of G.SPILLED => spillIt(d,u)
509 :     | G.SPILL_LOC _ => spillIt(d,u)
510 :     | G.MEMREG _ => spillIt(d,u)
511 :     | G.PSEUDO => spillIt(d,u)
512 :     | _ => ()
513 : monnier 498 end
514 : george 705 val _ = app markSpills nodesToSpill
515 : monnier 467
516 :     (* Rewrite all affected blocks *)
517 :     fun rewriteAll (blknum, _) =
518 : george 705 (case A.sub(blockTable, blknum)
519 :     of F.BBLOCK{annotations, insns as ref instrs, ...} => let
520 :     val instrs =
521 :     spillRewrite{pt=progPt(blknum, length instrs),
522 :     instrs=instrs,
523 :     annotations=annotations}
524 :     in insns := instrs
525 : george 545 end
526 : george 705 | _ => error "rewriteAll"
527 :     (*esac*))
528 : monnier 467
529 :    
530 : george 705 fun mark(G.NODE{color, ...}) =
531 :     (case !color
532 :     of PSEUDO => color := SPILLED
533 :     | SPILLED => ()
534 :     | SPILL_LOC _ => ()
535 :     | ALIASED _ => ()
536 :     | MEMREG _ => ()
537 :     | COLORED _ => error "mark: COLORED"
538 :     | REMOVED => error "mark: REMOVED"
539 :     (*esac*))
540 :     in
541 : blume 733 IntHashTable.appi rewriteAll affectedBlocks;
542 : george 705 app mark nodesToSpill;
543 :     rebuild(cellkind, graph)
544 :     end (* spill *)
545 :     in
546 :     { build = build,
547 :     spill = spill,
548 :     programPoint= fn{block,instr} => progPt(block,instr),
549 :     blockNum = blockNum,
550 :     instrNum = instrNum
551 :     }
552 :     end
553 :     end
554 : monnier 467

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