41
41
import jdk .graal .compiler .graph .NodeBitMap ;
42
42
import jdk .graal .compiler .graph .spi .NodeWithIdentity ;
43
43
import jdk .graal .compiler .nodes .ControlSinkNode ;
44
+ import jdk .graal .compiler .nodes .FixedGlobalValueNumberable ;
44
45
import jdk .graal .compiler .nodes .FixedGuardNode ;
45
46
import jdk .graal .compiler .nodes .FixedNode ;
46
47
import jdk .graal .compiler .nodes .FixedWithNextNode ;
@@ -313,18 +314,22 @@ private static void processNode(FixedWithNextNode cur, LocationSet thisLoopKille
313
314
final LoopBeginNode exitedLoop = ((LoopExitNode ) cur ).loopBegin ();
314
315
killLoopLocations (((HIRLoop ) cfg .blockFor (exitedLoop ).getLoop ()).getKillLocations (), blockMap );
315
316
}
317
+ boolean mustGVN = (cur instanceof FixedGlobalValueNumberable );
318
+ if (!mustGVN ) {
319
+ // Handle nodes which don't explicitly opt into DGVN
320
+ if (MemoryKill .isMemoryKill (cur )) {
321
+ blockMap .killValuesByPotentialMemoryKill (cur );
322
+ return ;
323
+ }
316
324
317
- if (MemoryKill .isMemoryKill (cur )) {
318
- blockMap .killValuesByPotentialMemoryKill (cur );
319
- return ;
320
- }
321
-
322
- if (!canGVN (cur )) {
323
- return ;
325
+ if (!canGVN (cur )) {
326
+ return ;
327
+ }
324
328
}
325
329
326
330
boolean canSubsitute = blockMap .hasSubstitute (cur );
327
- boolean canLICM = loopCandidate != null ;
331
+ // assume FixedGlobalValueNumberable nodes shouldn't be moved
332
+ boolean canLICM = loopCandidate != null && !mustGVN ;
328
333
if (cur instanceof MemoryAccess ) {
329
334
MemoryAccess access = (MemoryAccess ) cur ;
330
335
if (loopKillsLocation (thisLoopKilledLocations , access .getLocationIdentity ())) {
@@ -347,15 +352,21 @@ private static void processNode(FixedWithNextNode cur, LocationSet thisLoopKille
347
352
* a limited form of LICM for nodes that are dominated by the loop header and dominate
348
353
* all exits. Such operations that are unconditionally executed in the particular loop.
349
354
*/
355
+ boolean substituted = false ;
350
356
if (canSubsitute ) {
351
357
// GVN node
352
- blockMap .substitute (cur , cfg , licmNodes , canLICM ? loopCandidate : null );
358
+ substituted = blockMap .substitute (cur , cfg , licmNodes , canLICM ? loopCandidate : null );
353
359
} else {
354
360
if (canLICM ) {
355
361
tryPerformLICM (loopCandidate , cur , licmNodes );
356
362
}
357
363
blockMap .rememberNodeForGVN (cur );
358
364
}
365
+ if (mustGVN && !substituted ) {
366
+ if (MemoryKill .isMemoryKill (cur )) {
367
+ blockMap .killValuesByPotentialMemoryKill (cur );
368
+ }
369
+ }
359
370
}
360
371
361
372
@ Override
@@ -589,47 +600,49 @@ public boolean hasSubstitute(Node n) {
589
600
* Perform actual global value numbering. Replace node {@code n} with an equal node (inputs
590
601
* and data fields) up in the dominance chain.
591
602
*/
592
- public void substitute (Node n , ControlFlowGraph cfg , NodeBitMap licmNodes , Loop invariantInLoop ) {
603
+ public boolean substitute (Node n , ControlFlowGraph cfg , NodeBitMap licmNodes , Loop invariantInLoop ) {
593
604
Node edgeDataEqual = find (n );
594
- if (edgeDataEqual != null ) {
595
- assert edgeDataEqual .graph () != null ;
596
- assert edgeDataEqual instanceof FixedNode : "Only process fixed nodes" ;
597
- StructuredGraph graph = (StructuredGraph ) edgeDataEqual .graph ();
598
-
599
- HIRBlock defBlock = cfg .blockFor (edgeDataEqual );
600
-
601
- if (invariantInLoop != null ) {
602
- HIRBlock loopDefBlock = cfg .blockFor (invariantInLoop .loopBegin ()).getLoop ().getHeader ().getDominator ();
603
- if (loopDefBlock .strictlyDominates (defBlock )) {
604
- /*
605
- * The LICM location strictly dominates the GVN location so it must be the
606
- * final location. Move the GVN node to the LICM location and then perform
607
- * the substitution normally.
608
- */
609
- if (!tryPerformLICM (invariantInLoop , (FixedNode ) edgeDataEqual , licmNodes )) {
610
- GraalError .shouldNotReachHere ("tryPerformLICM must succeed for " + edgeDataEqual ); // ExcludeFromJacocoGeneratedReport
611
- }
612
- } else {
613
- GraalError .guarantee (defBlock .dominates (loopDefBlock ), "No dominance relation between GVN and LICM locations: %s and %s" , defBlock , loopDefBlock );
605
+ if (edgeDataEqual == null ) {
606
+ return false ;
607
+ }
608
+ assert edgeDataEqual .graph () != null ;
609
+ assert edgeDataEqual instanceof FixedNode : "Only process fixed nodes" ;
610
+ StructuredGraph graph = (StructuredGraph ) edgeDataEqual .graph ();
611
+
612
+ HIRBlock defBlock = cfg .blockFor (edgeDataEqual );
613
+
614
+ if (invariantInLoop != null ) {
615
+ HIRBlock loopDefBlock = cfg .blockFor (invariantInLoop .loopBegin ()).getLoop ().getHeader ().getDominator ();
616
+ if (loopDefBlock .strictlyDominates (defBlock )) {
617
+ /*
618
+ * The LICM location strictly dominates the GVN location so it must be the final
619
+ * location. Move the GVN node to the LICM location and then perform the
620
+ * substitution normally.
621
+ */
622
+ if (!tryPerformLICM (invariantInLoop , (FixedNode ) edgeDataEqual , licmNodes )) {
623
+ GraalError .shouldNotReachHere ("tryPerformLICM must succeed for " + edgeDataEqual ); // ExcludeFromJacocoGeneratedReport
614
624
}
625
+ } else {
626
+ GraalError .guarantee (defBlock .dominates (loopDefBlock ), "No dominance relation between GVN and LICM locations: %s and %s" , defBlock , loopDefBlock );
615
627
}
628
+ }
616
629
617
- if (!LoopUtility .canUseWithoutProxy (cfg , edgeDataEqual , n )) {
618
- earlyGVNAbort .increment (graph .getDebug ());
619
- return ;
620
- }
630
+ if (!LoopUtility .canUseWithoutProxy (cfg , edgeDataEqual , n )) {
631
+ earlyGVNAbort .increment (graph .getDebug ());
632
+ return false ;
633
+ }
621
634
622
- graph .getDebug ().log (DebugContext .VERY_DETAILED_LEVEL , "Early GVN: replacing %s with %s" , n , edgeDataEqual );
623
- graph .getDebug ().dump (DebugContext .VERY_DETAILED_LEVEL , graph , "Before replacing %s with %s" , n , edgeDataEqual );
624
- n .replaceAtUsages (edgeDataEqual );
625
- GraphUtil .unlinkFixedNode ((FixedWithNextNode ) n );
626
- n .safeDelete ();
627
- graph .getDebug ().dump (DebugContext .VERY_DETAILED_LEVEL , graph , "After replacing %s with %s" , n , edgeDataEqual );
628
- earlyGVN .increment (graph .getDebug ());
629
- if (graph .getDebug ().isCountEnabled ()) {
630
- DebugContext .counter (earlyGVN .getName () + "_" + edgeDataEqual .getClass ().getSimpleName ()).increment (graph .getDebug ());
631
- }
635
+ graph .getDebug ().log (DebugContext .VERY_DETAILED_LEVEL , "Early GVN: replacing %s with %s" , n , edgeDataEqual );
636
+ graph .getDebug ().dump (DebugContext .VERY_DETAILED_LEVEL , graph , "Before replacing %s with %s" , n , edgeDataEqual );
637
+ n .replaceAtUsages (edgeDataEqual );
638
+ GraphUtil .unlinkFixedNode ((FixedWithNextNode ) n );
639
+ n .safeDelete ();
640
+ graph .getDebug ().dump (DebugContext .VERY_DETAILED_LEVEL , graph , "After replacing %s with %s" , n , edgeDataEqual );
641
+ earlyGVN .increment (graph .getDebug ());
642
+ if (graph .getDebug ().isCountEnabled ()) {
643
+ DebugContext .counter (earlyGVN .getName () + "_" + edgeDataEqual .getClass ().getSimpleName ()).increment (graph .getDebug ());
632
644
}
645
+ return true ;
633
646
}
634
647
635
648
/**
0 commit comments