[llvm] r314609 - NewGVN: Make OpIsSafeForPhiOfOps non-recursive

Daniel Berlin via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 30 16:51:04 PDT 2017


Author: dannyb
Date: Sat Sep 30 16:51:04 2017
New Revision: 314609

URL: http://llvm.org/viewvc/llvm-project?rev=314609&view=rev
Log:
NewGVN: Make OpIsSafeForPhiOfOps non-recursive

Modified:
    llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp

Modified: llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp?rev=314609&r1=314608&r2=314609&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/NewGVN.cpp Sat Sep 30 16:51:04 2017
@@ -2487,8 +2487,7 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *
   auto OISIt = OpSafeForPHIOfOps.find(V);
   if (OISIt != OpSafeForPHIOfOps.end())
     return OISIt->second;
-  // Keep walking until we either dominate the phi block, or hit a phi, or run
-  // out of things to check.
+
   if (DT->properlyDominates(getBlockForValue(V), PHIBlock)) {
     OpSafeForPHIOfOps.insert({V, true});
     return true;
@@ -2498,23 +2497,55 @@ bool NewGVN::OpIsSafeForPHIOfOps(Value *
     OpSafeForPHIOfOps.insert({V, false});
     return false;
   }
-  for (auto Op : cast<Instruction>(V)->operand_values()) {
+
+  SmallVector<Instruction *, 4> Worklist;
+  auto *OrigI = cast<Instruction>(V);
+  for (auto *Op : OrigI->operand_values()) {
     if (!isa<Instruction>(Op))
       continue;
-    // See if we already know the answer for this node.
-    auto OISIt = OpSafeForPHIOfOps.find(Op);
+    // Stop now if we find an unsafe operand.
+    auto OISIt = OpSafeForPHIOfOps.find(OrigI);
     if (OISIt != OpSafeForPHIOfOps.end()) {
       if (!OISIt->second) {
         OpSafeForPHIOfOps.insert({V, false});
         return false;
       }
+      continue;
     }
-    if (!Visited.insert(Op).second)
+    Worklist.push_back(cast<Instruction>(Op));
+  }
+
+  while (!Worklist.empty()) {
+    auto *I = Worklist.pop_back_val();
+    // Keep walking until we either dominate the phi block, or hit a phi, or run
+    // out of things to check.
+    //
+    if (DT->properlyDominates(getBlockForValue(I), PHIBlock)) {
+      OpSafeForPHIOfOps.insert({I, true});
       continue;
-    if (!OpIsSafeForPHIOfOps(Op, OrigInst, PHIBlock, Visited)) {
+    }
+    // PHI in the same block.
+    if (isa<PHINode>(I) && getBlockForValue(I) == PHIBlock) {
+      OpSafeForPHIOfOps.insert({I, false});
       OpSafeForPHIOfOps.insert({V, false});
       return false;
     }
+    for (auto *Op : cast<Instruction>(I)->operand_values()) {
+      if (!isa<Instruction>(Op))
+        continue;
+      // See if we already know the answer for this node.
+      auto OISIt = OpSafeForPHIOfOps.find(Op);
+      if (OISIt != OpSafeForPHIOfOps.end()) {
+        if (!OISIt->second) {
+          OpSafeForPHIOfOps.insert({V, false});
+          return false;
+        }
+        continue;
+      }
+      if (!Visited.insert(Op).second)
+        continue;
+      Worklist.push_back(cast<Instruction>(Op));
+    }
   }
   OpSafeForPHIOfOps.insert({V, true});
   return true;




More information about the llvm-commits mailing list