[NFC][SimplifyCFG] Common code sinking: check profitability once
authorRoman Lebedev <lebedev.ri@gmail.com>
Wed, 28 Apr 2021 20:40:58 +0000 (23:40 +0300)
committerRoman Lebedev <lebedev.ri@gmail.com>
Wed, 28 Apr 2021 22:01:00 +0000 (01:01 +0300)
We can just eagerly pre-check all the instructions that we *could*
sink that we'd actually want to sink them, clamping the number of
instructions that we'll sink to stop just before the first unprofitable one.

llvm/lib/Transforms/Utils/SimplifyCFG.cpp

index 6f19453..89f6273 100644 (file)
@@ -2024,8 +2024,8 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
   if (ScanIdx == 0)
     return false;
 
-  bool Changed = false;
-
+  // Okay, we *could* sink last ScanIdx instructions. But how many can we
+  // actually sink before encountering instruction that is unprofitable to sink?
   auto ProfitableToSinkInstruction = [&](LockstepReverseIterator &LRI) {
     unsigned NumPHIdValues = 0;
     for (auto *I : *LRI)
@@ -2039,6 +2039,25 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
 
     return NumPHIInsts <= 1;
   };
+  LRI.reset();
+  unsigned Idx = 0;
+  while (Idx < ScanIdx) {
+    if (!ProfitableToSinkInstruction(LRI)) {
+      // Too many PHIs would be created.
+      LLVM_DEBUG(
+          dbgs() << "SINK: stopping here, too many PHIs would be created!\n");
+      break;
+    }
+    --LRI;
+    ++Idx;
+  }
+  ScanIdx = Idx;
+
+  // If no instructions can be sunk, early-return.
+  if (ScanIdx == 0)
+    return false;
+
+  bool Changed = false;
 
   if (Cond) {
     // It is always legal to sink common instructions from unconditional
@@ -2049,7 +2068,7 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
     LRI.reset();
     unsigned Idx = 0;
     bool Profitable = false;
-    while (ProfitableToSinkInstruction(LRI) && Idx < ScanIdx) {
+    while (Idx < ScanIdx) {
       if (!isSafeToSpeculativelyExecute((*LRI)[0])) {
         Profitable = true;
         break;
@@ -2090,12 +2109,6 @@ static bool SinkCommonCodeFromPredecessors(BasicBlock *BB,
     // Because we've sunk every instruction in turn, the current instruction to
     // sink is always at index 0.
     LRI.reset();
-    if (!ProfitableToSinkInstruction(LRI)) {
-      // Too many PHIs would be created.
-      LLVM_DEBUG(
-          dbgs() << "SINK: stopping here, too many PHIs would be created!\n");
-      break;
-    }
 
     if (!sinkLastInstruction(UnconditionalPreds)) {
       LLVM_DEBUG(