comparison doc/design/graal_compiler.tex @ 2577:ac2029d0898f

doc: framestate and deopt changes
author Lukas Stadler <lukas.stadler@jku.at>
date Wed, 04 May 2011 16:39:06 +0200
parents c59db1f02893
children 999407dbfe10
comparison
equal deleted inserted replaced
2576:c59db1f02893 2577:ac2029d0898f
196 \begin{itemize} 196 \begin{itemize}
197 \item Array stores: {\tt IASTORE, LASTORE, FASTORE, \\DASTORE, AASTORE, BASTORE, CASTORE, SASTORE} 197 \item Array stores: {\tt IASTORE, LASTORE, FASTORE, \\DASTORE, AASTORE, BASTORE, CASTORE, SASTORE}
198 \item Field stores: {\tt PUTSTATIC, PUTFIELD} 198 \item Field stores: {\tt PUTSTATIC, PUTFIELD}
199 \item Method calls: {\tt INVOKEVIRTUAL, INVOKESPECIAL, \\INVOKESTATIC, INVOKEINTERFACE} 199 \item Method calls: {\tt INVOKEVIRTUAL, INVOKESPECIAL, \\INVOKESTATIC, INVOKEINTERFACE}
200 \item Memory allocations: {\tt NEW, NEWARRAY, ANEWARRAY, \\MULTIANEWARRAY} 200 \item Memory allocations: {\tt NEW, NEWARRAY, ANEWARRAY, \\MULTIANEWARRAY}
201 \item Exception throw: {\tt ATHROW}
202 \item Synchronization: {\tt MONITORENTER, MONITOREXIT} 201 \item Synchronization: {\tt MONITORENTER, MONITOREXIT}
203 \end{itemize} 202 \end{itemize}
204 203
205 Within the node graph a frame state is represented as a node that is fixed to the node that caused it to be generated (control dependency). 204 Within the node graph a frame state is represented as a node that is fixed to the node that caused it to be generated (control dependency).
206 205
207 \begin{digraphenv}{scale=0.5}{fs1} 206 \begin{digraphenv}{scale=0.5}{fs1}
208 nodesep="0.02"; 207 \nodetrisplit{store1}{ArrayStore}
209 \nodequadsplit{store1}{ArrayStore} 208 \nodebi{load1}{ArrayLoad}
210 \nodetri{load1}{ArrayLoad}
211 \controllabel{store1:succ1}{load1} 209 \controllabel{store1:succ1}{load1}
212 \nodequadsplit{store2}{ArrayStore} 210 \nodetrisplit{store2}{ArrayStore}
213 \control{load1}{store2} 211 \control{load1}{store2}
214 end [shape=plaintext, label="...", width="2.0"] 212 end [shape=plaintext, label="...", width="2.0"]
215 store2:succ1:s -> end:n [color=red]; 213 store2:succ1:s -> end:n [color=red];
216 % 214 %
217 \nodeframestate{fs1}{FrameState} 215 \nodeframestate{fs1}{FrameState}
225 \subsection{Deoptimization and Uncommon Traps} 223 \subsection{Deoptimization and Uncommon Traps}
226 Uncommon trap nodes are not fixed to a certain frame state node, they can move around freely and will always use the correct frame state. 224 Uncommon trap nodes are not fixed to a certain frame state node, they can move around freely and will always use the correct frame state.
227 The node that is guarded by the deoptimization has a data dependency on the trap, and the trap in turn has a data dependency on the condition and on the most distant node that is postdominated by the guarded node. 225 The node that is guarded by the deoptimization has a data dependency on the trap, and the trap in turn has a data dependency on the condition and on the most distant node that is postdominated by the guarded node.
228 226
229 \begin{digraphenv}{scale=0.5}{trap1} 227 \begin{digraphenv}{scale=0.5}{trap1}
230 nodesep="0.02";
231 start [shape=plaintext, label="..."]
232 \control{start}{if}
233 \nodesplit{if}{If} 228 \nodesplit{if}{If}
234 \node{split1}{ControlSplit} 229 \node{split1}{Split}
235 \controllabel{if:succ1}{split1} 230 \controllabel{if:succ1}{split1}
236 nop [shape=plaintext, label="..."] 231 nop [shape=plaintext, label="..."]
237 \control{split1}{nop} 232 \control{split1}{nop}
238 % 233 %
239 \node{split2}{ControlSplit} 234 \node{split2}{Split}
240 \controllabel{if:succ2}{split2} 235 \controllabel{if:succ2}{split2}
241 \nodebi{load1}{FieldLoad} 236 \nodebi{load1}{MemLoad}
242 \control{split2}{load1} 237 \control{split2}{load1}
243 \nodebi{load2}{FieldLoad} 238 \nodebi{load2}{MemLoad}
244 \control{load1}{load2} 239 \control{load1}{load2}
245 \control{load2}{merge} 240 \control{load2}{merge}
246 \node{merge}{Merge} 241 \node{merge}{Merge}
247 \control{nop}{merge} 242 \control{nop}{merge}
248 nop2 [shape=plaintext, label="..."]
249 \control{merge}{nop2}
250 % 243 %
251 \nodeconst{o1}{obj1} 244 \nodeconst{o1}{obj1}
252 \nodeconst{o2}{obj2} 245 \nodeconst{o2}{obj2}
253 \datalabel{load1:in2}{o1} 246 \datalabel{load1:in2}{o1}
254 \datalabel{load2:in2}{o2} 247 \datalabel{load2:in2}{o2}
258 \datalabel{trap:in2}{cmpnull} 251 \datalabel{trap:in2}{cmpnull}
259 \datalabel{load2:in1}{trap} 252 \datalabel{load2:in1}{trap}
260 \datalabel{trap:in1}{split2} 253 \datalabel{trap:in1}{split2}
261 \end{digraphenv} 254 \end{digraphenv}
262 255
263 \emph{\small In this example, the second field load is guarded by an uncommon trap, because its receiver might be null (the receiver of the first load is assumed to be non-null). 256 \emph{\small In this example, the second load is guarded by an uncommon trap, because its receiver might be null (the receiver of the load is assumed to be non-null).
264 The trap is anchored to the control split, because as soon as this node is executed the field load must be executed as well. 257 The trap is anchored to the control split, because as soon as this node is executed the second load must be executed as well.
265 In the final scheduling the trap can be placed before or after the first load.} 258 In the final scheduling the trap can be placed before or after the first load.}
266 259
267 Another type of uncommon trap is a guard, which is used to remove branches that have a very low execution frequency from the compiled code. 260 Another type of uncommon trap is a guard, which is used to remove branches that have a very low execution frequency from the compiled code.
268 261
269 \begin{digraphenv}{scale=0.5}{trap2} 262 \begin{digraphenv}{scale=0.5}{trap2}
270 nodesep="0.02";
271 start [shape=plaintext, label="..."] 263 start [shape=plaintext, label="..."]
272 start2 [shape=plaintext, label=""] 264 start2 [shape=plaintext, label=""]
273 start3 [shape=plaintext, label=""] 265 start3 [shape=plaintext, label=""]
274 \control{start}{guard} 266 \control{start}{guard}
275 \node{guard}{Guard} 267 \node{guard}{Guard}
276 \nodebi{load1}{FieldLoad} 268 \nodebi{load1}{MemLoad}
277 \control{guard}{load1} 269 \control{guard}{load1}
278 \nodebi{load2}{FieldLoad} 270 \control{load1}{nop}
279 \control{load1}{load2}
280 \control{load2}{nop}
281 nop [shape=plaintext, label="..."] 271 nop [shape=plaintext, label="..."]
282 % 272 %
283 \nodetrap{trap}{Trap} 273 \nodetrap{trap}{Trap}
284 \datalabel{trap:in1}{start2} 274 \datalabel{trap:in1}{start2}
285 \datalabel{trap:in2}{start3} 275 \datalabel{trap:in2}{start3}
287 \end{digraphenv} 277 \end{digraphenv}
288 278
289 279
290 \emph{\small In this example the If from the previous example was replaced by a guard and an uncommon trap. 280 \emph{\small In this example the If from the previous example was replaced by a guard and an uncommon trap.
291 The guard takes the place of the If in the control flow, and is connected to the trap node. 281 The guard takes the place of the If in the control flow, and is connected to the trap node.
292 The uncommon trap is again anchored to the most distant node of which the If was a postdominator.} 282 The uncommon trap is now anchored to the most distant node of which the If was a postdominator.}
293 283
294 At some point during the compilation, trap nodes need to be fixed, which means that appropriate data and control dependencies will be inserted so that they cannot move outside the scope of the associated frame state. 284 At some point during the compilation, trap nodes need to be fixed, which means that appropriate data and control dependencies will be inserted so that they cannot move outside the scope of the associated frame state.
295 This will generate deoptimization-free zones that can be targeted by the most aggressive optimizations. 285 This will generate deoptimization-free zones that can be targeted by the most aggressive optimizations.
296 A simple algorithm for this removal of FrameStates would be to move all traps as far upwards as possible. 286 A simple algorithm for this removal of FrameStates would be to move all traps as far upwards as possible.
297 287
288
289 Multiple Traps with the same condition and anchor can be merged:
290
291 \begin{digraphenv}{scale=0.5}{trap3}
292 \nodesplit{if}{If}
293 \node{split1}{Split}
294 \controllabel{if:succ1}{split1}
295 nop [shape=plaintext, label="..."]
296 \control{split1}{nop}
297 %
298 \node{split2}{Split}
299 \controllabel{if:succ2}{split2}
300 \nodebi{load1}{MemLoad}
301 \control{split2}{load1}
302 \nodebi{load2}{MemLoad}
303 \control{load1}{load2}
304 \control{load2}{merge}
305 \node{merge}{Merge}
306 \control{nop}{merge}
307 %
308 \nodeconst{o}{obj}
309 \datalabel{load1:in2}{o}
310 \datalabel{load2:in2}{o}
311 \nodetrap{trap}{Trap}
312 \node{cmpnull}{IsNull}
313 \data{cmpnull}{o}
314 \datalabel{trap:in2}{cmpnull}
315 \datalabel{load2:in1}{trap}
316 \datalabel{load1:in1}{trap}
317 \datalabel{trap:in1}{split2}
318 \end{digraphenv}
319
320 Also, if two Traps that are anchored to the true and false branch of the same If have the same condition, they can be merged, so that the resulting Trap is anchored at the most distant node of which the If is a postdominator.
298 321
299 %Frame states should be represented using a delta-encoding. 322 %Frame states should be represented using a delta-encoding.
300 %This will make them significantly smaller and will make inlining, etc. much easier. 323 %This will make them significantly smaller and will make inlining, etc. much easier.
301 %In later compilation phases unnecessary frame states might be removed, using a mark-and-merge algorithm. 324 %In later compilation phases unnecessary frame states might be removed, using a mark-and-merge algorithm.
302 325