]>
Commit | Line | Data |
---|---|---|
6ade8b0a | 1 | (* L3 Compiler |
12aa4087 JW |
2 | * Takes a interference graph and generates an ordering for coloring |
3 | * Author: Joshua Wise <jwise@andrew.cmu.edu> | |
0a24e44d | 4 | * Author: Chris Lu <czl@aundrew.cmu.edu> |
12aa4087 JW |
5 | *) |
6 | ||
7 | signature COLORORDER = | |
8 | sig | |
6ade8b0a | 9 | structure OperSet : ORD_SET |
5c79bb68 | 10 | where type Key.ord_key = x86.basicop |
6ade8b0a JW |
11 | structure LiveMap : ORD_MAP |
12 | where type Key.ord_key = int | |
13 | structure TempMap : ORD_MAP | |
14 | where type Key.ord_key = Temp.temp | |
15 | ||
16 | type igraph = OperSet.set TempMap.map | |
0a24e44d | 17 | type ordering = Temp.temp list |
12aa4087 | 18 | |
6ade8b0a | 19 | val colororder : Igraph.graph * Temp.temp list -> ordering |
12aa4087 JW |
20 | end |
21 | ||
22 | structure ColorOrder :> COLORORDER = | |
23 | struct | |
24 | structure T = Temp | |
25 | structure X = x86 | |
26 | ||
6ade8b0a JW |
27 | structure OperSet = Igraph.OperSet |
28 | structure LiveMap = Igraph.LiveMap | |
29 | structure TempMap = Igraph.TempMap | |
30 | ||
31 | type igraph = OperSet.set TempMap.map | |
0a24e44d | 32 | type ordering = Temp.temp list |
12aa4087 | 33 | |
6ade8b0a | 34 | fun colororder (graph,temps) = |
12aa4087 | 35 | let |
6ade8b0a | 36 | val initialWeights = TempMap.mapi (fn (t, _) => (t, 0)) graph |
12aa4087 | 37 | |
12aa4087 JW |
38 | (* Chooses one temporary to pick, and updates the weights. *) |
39 | fun orderOne (weights : (Temp.temp * int) list) : Temp.temp * (Temp.temp * int) list = | |
40 | let | |
5c79bb68 JW |
41 | val (chosen, w) = |
42 | foldr | |
43 | (fn ((t1, w1), (t2, w2)) => | |
44 | if (w2 > w1) | |
45 | then (t2, w2) | |
46 | else (t1, w1)) | |
47 | (Temp.new "emarnus" Temp.Word, ~9999) | |
48 | weights | |
49 | ||
50 | fun ditchOne f nil = nil (* Special case of filter, which bails out after it removes one. *) | |
51 | | ditchOne f (h::l) = | |
52 | if f h | |
53 | then l | |
54 | else h::(ditchOne f l) | |
55 | val remaining = ditchOne (fn (t, w) => Temp.eq (t, chosen)) weights | |
56 | ||
0a24e44d | 57 | val neighbors = (* Grab all the neighbors for some given temp. *) |
6ade8b0a JW |
58 | (OperSet.listItems |
59 | (valOf (TempMap.find (graph, chosen)))) | |
12aa4087 JW |
60 | val newWeights = |
61 | List.map | |
62 | (fn (t, wt) => | |
63 | (t, | |
64 | if (List.exists | |
6ade8b0a | 65 | (fn X.TEMP t' => (T.eq (t, t')) |
12aa4087 JW |
66 | | _ => false) |
67 | neighbors) | |
68 | then (wt + 1) | |
69 | else wt | |
70 | ) | |
71 | ) remaining | |
72 | in | |
73 | (chosen, newWeights) | |
74 | end | |
75 | ||
76 | (* Recursively order until we run out of things to order. *) | |
77 | fun keepOrdering (nil : (Temp.temp * int) list) : Temp.temp list = nil | |
78 | | keepOrdering (weights) = | |
79 | let | |
80 | val (chosen, newWeights) = orderOne weights | |
81 | in | |
82 | chosen :: (keepOrdering newWeights) | |
83 | end | |
6ade8b0a JW |
84 | |
85 | val ordered = keepOrdering (TempMap.listItems initialWeights) | |
12aa4087 | 86 | in |
6ade8b0a | 87 | ordered @ (List.filter (fn a => not (List.exists (fn b => Temp.eq (a,b)) ordered)) temps) |
12aa4087 JW |
88 | end |
89 | end |