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/branches/SMLNJ/src/MLRISC/x86/ra/x86Spill.sml
ViewVC logotype

Annotation of /sml/branches/SMLNJ/src/MLRISC/x86/ra/x86Spill.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 498 - (view) (download)

1 : monnier 247 (* X86Spill.sml
2 :     *
3 :     * X86 spilling is complicated business.
4 : monnier 498 * Allen: and it just got more complicated; now we have to recognize the regmap.
5 : monnier 247 *)
6 :     signature X86SPILL = sig
7 :     structure I : X86INSTR
8 :     val spill :
9 : monnier 498 I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
10 :     {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
11 : monnier 247
12 :     val reload :
13 : monnier 498 I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
14 :     {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
15 : monnier 247
16 :     val fspill :
17 : monnier 498 I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
18 :     {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
19 : monnier 247
20 :     val freload :
21 : monnier 498 I.instruction * (I.C.cell -> I.C.cell) * I.C.cell * I.operand ->
22 :     {code:I.instruction list, proh:I.C.cell list, newReg:I.C.cell option}
23 : monnier 247 end
24 :    
25 :    
26 :     functor X86Spill(structure Instr: X86INSTR
27 : monnier 498 structure Props: INSN_PROPERTIES where I = Instr
28 :     ) : X86SPILL = struct
29 : monnier 247
30 : monnier 429 structure I = Instr
31 :     structure C = I.C
32 : monnier 247
33 : monnier 411 fun error msg = MLRiscErrorMsg.impossible("X86Spill: "^ msg)
34 : monnier 247
35 :     fun immed(I.Immed _) = true
36 :     | immed(I.ImmedLabel _) = true
37 :     | immed(I.Const _) = true
38 :     | immed(I.LabelEA _) = true
39 :     | immed _ = false
40 :    
41 :     fun immedOrReg(I.Direct r) = true
42 : monnier 498 | immedOrReg(I.Immed _) = true
43 :     | immedOrReg(I.ImmedLabel _) = true
44 :     | immedOrReg(I.Const _) = true
45 :     | immedOrReg(I.LabelEA _) = true
46 :     | immedOrReg _ = false
47 : monnier 247
48 : monnier 498 (* Annotate instruction *)
49 :     fun mark(instr,[]) = instr
50 :     | mark(instr,a::an) = mark(I.ANNOTATION{i=instr,a=a},an)
51 : monnier 247
52 : monnier 498 val newReg = C.newReg
53 :    
54 : monnier 247 (* XXX:: Need to go through all the cases where 'done' is used
55 :     * to make sure that a the src cannot contain the register
56 :     * being spilled.
57 :     *)
58 : monnier 498 fun spill(instr, regmap, reg, spillLoc) =
59 :     let fun done(instr, an) = {code=[mark(instr, an)], proh=[], newReg=NONE}
60 :     fun spillIt(instr,an) =
61 :     case instr of
62 :     I.CALL(addr, defs, uses, mem) =>
63 :     done(I.CALL(addr, C.rmvReg(reg,defs), uses, mem), an)
64 :     | I.MOVE{mvOp=I.MOVZX, src, dst} =>
65 :     let val tmpR = newReg() val tmp = I.Direct tmpR
66 :     in {proh=[tmpR], newReg=SOME tmpR,
67 :     code=[mark(I.MOVE{mvOp=I.MOVZX, src=src, dst=tmp}, an),
68 :     I.MOVE{mvOp=I.MOVL, src=tmp, dst=spillLoc}]
69 :     }
70 :     end
71 :     | I.MOVE{mvOp, src as I.Direct rs, dst} =>
72 :     if regmap rs=reg then {code=[], proh=[], newReg=NONE}
73 :     else done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)
74 :     | I.MOVE{mvOp, src, dst=I.Direct _} =>
75 :     if Props.eqOpn(src, spillLoc) then {code=[], proh=[], newReg=NONE}
76 :     else if immed src then
77 :     done(I.MOVE{mvOp=mvOp, src=src, dst=spillLoc}, an)
78 :     else
79 :     let val tmpR = newReg()
80 :     val tmp = I.Direct tmpR
81 :     in {proh=[tmpR],
82 :     newReg=SOME tmpR,
83 :     code=[mark(I.MOVE{mvOp=mvOp, src=src, dst=tmp}, an),
84 :     I.MOVE{mvOp=mvOp, src=tmp, dst=spillLoc}]
85 :     }
86 :     end
87 :     | I.LEA{addr, r32} =>
88 :     let val tmpR = newReg()
89 :     in {proh=[tmpR],
90 :     newReg=SOME tmpR,
91 :     code=[mark(I.LEA{addr=addr, r32=tmpR}, an),
92 :     I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]
93 :     }
94 :     end
95 :     | I.BINARY{binOp, src, dst} => (* note: dst = reg *)
96 :     if immedOrReg src then
97 :     {proh=[],
98 :     code=[(* I.MOVE{mvOp=I.MOVL, src=dst, dst=spillLoc}, XXX *)
99 :     mark(I.BINARY{binOp=binOp, src=src, dst=spillLoc}, an)
100 :     ],
101 :     newReg=NONE
102 :     }
103 :     else
104 :     let val tmpR = newReg()
105 :     val tmp = I.Direct tmpR
106 :     in {proh=[tmpR],
107 :     code=[(* I.MOVE{mvOp=I.MOVL, src=dst, dst=spillLoc}, XXX *)
108 :     I.MOVE{mvOp=I.MOVL, src=src, dst=tmp},
109 :     mark(I.BINARY{binOp=binOp, src=tmp, dst=spillLoc}, an)
110 :     ],
111 :     newReg=NONE
112 :     }
113 : monnier 247 end
114 : monnier 498 | I.MULTDIV _ => error "spill: MULTDIV"
115 :     | I.MUL3{src1, src2, dst} =>
116 :     let val tmpR = newReg()
117 :     in {proh=[tmpR], newReg=SOME tmpR,
118 :     code=[mark(I.MUL3{src1=src1, src2=src2, dst=tmpR}, an),
119 :     I.MOVE{mvOp=I.MOVL, src=I.Direct tmpR, dst=spillLoc}]
120 :     }
121 :     end
122 :     | I.UNARY{unOp, opnd} => done(I.UNARY{unOp=unOp, opnd=spillLoc}, an)
123 :     | I.POP _ => done(I.POP spillLoc, an)
124 :     | I.COPY _ => error "spill: COPY"
125 :     | I.FNSTSW => error "spill: FNSTSW"
126 :     | I.ANNOTATION{i,a} => spillIt(i, a::an)
127 :     | _ => error "spill"
128 :     in spillIt(instr, [])
129 :     end (* spill *)
130 : monnier 247
131 : monnier 498 fun reload(instr, regmap, reg, spillLoc) =
132 :     let fun operand(rt, opnd) =
133 : monnier 247 (case opnd
134 : monnier 498 of I.Direct r => if regmap r=reg then I.Direct rt else opnd
135 : monnier 411 | I.Displace{base, disp, mem} =>
136 : monnier 498 if regmap base=reg then I.Displace{base=rt, disp=disp, mem=mem}
137 :     else opnd
138 : monnier 411 | I.Indexed{base=NONE, index, scale, disp, mem=mem} =>
139 : monnier 498 if regmap index=reg then
140 : monnier 411 I.Indexed{base=NONE, index=rt, scale=scale, disp=disp, mem=mem}
141 : monnier 247 else opnd
142 : monnier 411 | I.Indexed{base as SOME b, index, scale, disp, mem=mem} =>
143 : monnier 498 if regmap b=reg then
144 : monnier 247 operand(rt, I.Indexed{base=SOME rt, index=index,
145 : monnier 411 scale=scale, disp=disp, mem=mem})
146 : monnier 498 else if regmap index=reg then
147 : monnier 411 I.Indexed{base=base, index=rt, scale=scale, disp=disp, mem=mem}
148 : monnier 247 else opnd
149 :     | opnd => opnd
150 :     (*esac*))
151 :    
152 : monnier 498 fun done(instr, an) = {code=[mark(instr, an)], proh=[], newReg=NONE}
153 :    
154 :     (* This version assumes that the value of tmpR is killed *)
155 :     fun withTmp(f, an) =
156 :     let val tmpR = newReg()
157 :     in {newReg=NONE,
158 :     proh=[tmpR],
159 :     code=[I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR},
160 :     mark(f tmpR, an)
161 :     ]
162 :     }
163 : monnier 247 end
164 : monnier 498
165 :     (* This version assumes that the value of tmpR is available afterwards *)
166 :     fun withTmp'(f, an) =
167 :     let val tmpR = newReg()
168 :     val tmp = I.Direct tmpR
169 :     in {newReg=SOME tmpR,
170 :     proh=[tmpR],
171 :     code=[I.MOVE{mvOp=I.MOVL, src=spillLoc, dst=I.Direct tmpR},
172 :     mark(f tmpR, an)
173 :     ]
174 :     }
175 :     end
176 :    
177 :     fun reloadIt(instr, an) =
178 : monnier 247 case instr
179 : monnier 498 of I.JMP(I.Direct _, labs) => done(I.JMP(spillLoc, labs), an)
180 :     | I.JMP(opnd, labs) => withTmp(fn t => I.JMP(operand(t, opnd), labs), an)
181 :     | I.JCC{opnd=I.Direct _, cond} => done(I.JCC{opnd=spillLoc, cond=cond}, an)
182 : monnier 247 | I.JCC{opnd, cond} =>
183 : monnier 498 withTmp(fn t => I.JCC{opnd=operand(t,opnd), cond=cond}, an)
184 :     | I.CALL(opnd, defs, uses, mem) =>
185 :     let val tmpR = newReg()
186 :     in {proh=[tmpR],
187 :     newReg=NONE,
188 :     code=[mark(
189 :     I.CALL(operand(tmpR, opnd), defs, C.rmvReg(reg,uses), mem),
190 :     an)]
191 :     }
192 : monnier 429 end
193 : monnier 247 | I.MOVE{mvOp, src, dst as I.Direct _} =>
194 : monnier 498 withTmp'(fn t =>I.MOVE{mvOp=mvOp, src=operand(t, src), dst=dst},an)
195 : monnier 247 | I.MOVE{mvOp, src as I.Direct _, dst} =>
196 : monnier 498 if Props.eqOpn(dst, spillLoc) then {code=[], proh=[], newReg=NONE}
197 : monnier 247 else withTmp
198 : monnier 498 (fn t =>
199 :     I.MOVE{mvOp=mvOp, src=operand(t, src), dst=operand(t, dst)}, an)
200 : monnier 247 | I.MOVE{mvOp, src, dst} =>
201 :     withTmp
202 : monnier 498 (fn t =>
203 :     I.MOVE{mvOp=mvOp, src=operand(t, src), dst=operand(t, dst)}, an)
204 : monnier 247 | I.LEA{r32, addr} =>
205 : monnier 498 withTmp'(fn tmpR => I.LEA{r32=r32, addr=operand(tmpR, addr)}, an)
206 : monnier 247 | I.CMP{lsrc, rsrc} =>
207 : monnier 498 withTmp(fn tmpR =>
208 :     I.CMP{lsrc=operand(tmpR, lsrc), rsrc=operand(tmpR, rsrc)}, an)
209 : monnier 247 | I.BINARY{binOp, src, dst as I.Direct _} =>
210 : monnier 498 withTmp(fn tmpR =>
211 :     I.BINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)
212 : monnier 247 | I.BINARY{binOp, src, dst} =>
213 : monnier 498 withTmp(fn tmpR => I.BINARY{binOp=binOp, src=operand(tmpR, src),
214 :     dst=operand(tmpR, dst)}, an)
215 : monnier 247 | I.MULTDIV{multDivOp, src} =>
216 : monnier 498 withTmp(fn tmpR =>
217 :     I.MULTDIV{multDivOp=multDivOp, src=operand(tmpR, src)}, an)
218 : monnier 247 | I.MUL3{src1, src2, dst} =>
219 :     withTmp(fn tmpR =>
220 :     I.MUL3{src1=operand(tmpR, src1), src2=src2,
221 : monnier 498 dst=if regmap dst = reg then error "reload:MUL3" else dst}, an)
222 : monnier 247 | I.UNARY{unOp, opnd} =>
223 : monnier 498 withTmp'(fn tmpR => I.UNARY{unOp=unOp, opnd=operand(tmpR, opnd)}, an)
224 :     | I.PUSH arg => withTmp(fn tmpR => I.PUSH(operand(tmpR, arg)), an)
225 : monnier 247 | I.COPY _ => error "reload:COPY"
226 : monnier 498 | I.FILD opnd => withTmp'(fn tmpR => I.FILD(operand(tmpR, opnd)), an)
227 :     | I.FLD opnd => withTmp'(fn tmpR => I.FLD(operand(tmpR, opnd)), an)
228 :     | I.FSTP opnd => withTmp'(fn tmpR => I.FSTP(operand(tmpR, opnd)), an)
229 : monnier 247 | I.FBINARY{binOp, src, dst} =>
230 : monnier 498 withTmp'(fn tmpR =>
231 :     I.FBINARY{binOp=binOp, src=operand(tmpR, src), dst=dst}, an)
232 : monnier 247
233 : monnier 498 | I.ANNOTATION{i,a} => reloadIt(i, a::an)
234 : monnier 247 | _ => error "reload"
235 : monnier 498 in reloadIt(instr, [])
236 : monnier 247 end (*reload*)
237 :    
238 : monnier 498 fun fspill(instr, regmap, reg, spillLoc) =
239 :     let fun spillIt(instr, an) =
240 :     (case instr of
241 :     I.FSTP _ => {proh=[], code=[mark(I.FSTP spillLoc, an)], newReg=NONE}
242 : monnier 429 | I.CALL(opnd, defs, uses, mem) =>
243 :     {proh=[],
244 : monnier 498 code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],
245 :     newReg=NONE}
246 :     | I.ANNOTATION{i,a} => spillIt(i, a::an)
247 : monnier 247 | _ => error "fspill"
248 : monnier 498 (*esac*))
249 :     in spillIt(instr, [])
250 :     end (* fspill *)
251 : monnier 247
252 : monnier 498 fun freload(instr, regmap, reg, spillLoc) =
253 :     let fun reloadIt(instr, an) =
254 :     (case instr of
255 :     I.FLD opnd => {code=[mark(I.FLD spillLoc, an)], proh=[], newReg=NONE}
256 : monnier 247 | I.FBINARY{binOp, src=I.FDirect f, dst} =>
257 : monnier 498 if regmap f = reg then
258 :     {code=[mark(I.FBINARY{binOp=binOp, src=spillLoc, dst=dst}, an)],
259 :     proh=[],
260 :     newReg=NONE}
261 : monnier 247 else error "freload:FBINARY"
262 : monnier 429 | I.CALL(opnd, defs, uses, mem) =>
263 :     {proh=[],
264 : monnier 498 code=[mark(I.CALL(opnd, C.rmvFreg(reg,defs), uses, mem), an)],
265 :     newReg=NONE}
266 :     | I.ANNOTATION{i,a} => reloadIt(i, a::an)
267 : monnier 247 | _ => error "freload"
268 : monnier 498 (*esac*))
269 :     in reloadIt(instr, [])
270 :     end (* freload *)
271 :    
272 : monnier 411 end

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