27
27
import static org .graalvm .compiler .nodeinfo .NodeCycles .CYCLES_0 ;
28
28
import static org .graalvm .compiler .nodeinfo .NodeSize .SIZE_0 ;
29
29
30
+ import java .util .List ;
31
+
30
32
import org .graalvm .compiler .core .common .type .AbstractPointerStamp ;
31
33
import org .graalvm .compiler .core .common .type .ObjectStamp ;
32
34
import org .graalvm .compiler .core .common .type .Stamp ;
@@ -307,7 +309,9 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean
307
309
if (guardNode .hasNoUsages ()) {
308
310
return ;
309
311
}
310
- for (PiNode pi : guardNode .usages ().filter (PiNode .class ).snapshot ()) {
312
+
313
+ List <PiNode > pis = guardNode .usages ().filter (PiNode .class ).snapshot ();
314
+ for (PiNode pi : pis ) {
311
315
if (!pi .isAlive ()) {
312
316
continue ;
313
317
}
@@ -317,6 +321,8 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean
317
321
}
318
322
319
323
/*
324
+ * RECURSE CALL
325
+ *
320
326
* If there are PiNodes still anchored at this guard then either they must simplify away
321
327
* because they are no longer necessary or this node must be replaced with a
322
328
* ValueAnchorNode because the type injected by the PiNode is only true at this point in
@@ -330,6 +336,16 @@ private static void tryEvacuate(SimplifierTool tool, GuardingNode guard, boolean
330
336
tryEvacuate (tool , otherGuard , false );
331
337
}
332
338
}
339
+ /*
340
+ * A note on the RECURSE CALL above: When we have pis with input pis on the same guard
341
+ * (which should actually be combined) it can be that the recurse call (processing the
342
+ * same pis again) already deletes this node (very special stamp setups necessary).
343
+ * Thus, it can be that pi is dead at this point already, so we have to check for this
344
+ * again.
345
+ */
346
+ if (!pi .isAlive ()) {
347
+ continue ;
348
+ }
333
349
Node canonical = pi .canonical (tool );
334
350
if (canonical != pi ) {
335
351
if (!canonical .isAlive ()) {
0 commit comments