OSDN Git Service

[EarlyCSE] Make PhiToCheck in removeMSSA() a set.
authorDavide Italiano <davide@freebsd.org>
Wed, 14 Jun 2017 19:29:53 +0000 (19:29 +0000)
committerDavide Italiano <davide@freebsd.org>
Wed, 14 Jun 2017 19:29:53 +0000 (19:29 +0000)
This way we end up not looking at PHI args already removed.
MemSSA now goes through the updater so we can prune
it to avoid having redundant MemoryPHI arguments, but that
doesn't quite work for the general case.

Discussed with Daniel Berlin, fixes PR33406.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@305409 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/EarlyCSE.cpp
test/Transforms/EarlyCSE/pr33406.ll [new file with mode: 0644]

index c4f4509..0f92760 100644 (file)
@@ -15,6 +15,7 @@
 #include "llvm/Transforms/Scalar/EarlyCSE.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/ScopedHashTable.h"
+#include "llvm/ADT/SetVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Analysis/AssumptionCache.h"
 #include "llvm/Analysis/GlobalsModRef.h"
@@ -506,7 +507,7 @@ private:
     if (MemoryAccess *MA = MSSA->getMemoryAccess(Inst)) {
       // Optimize MemoryPhi nodes that may become redundant by having all the
       // same input values once MA is removed.
-      SmallVector<MemoryPhi *, 4> PhisToCheck;
+      SmallSetVector<MemoryPhi *, 4> PhisToCheck;
       SmallVector<MemoryAccess *, 8> WorkQueue;
       WorkQueue.push_back(MA);
       // Process MemoryPhi nodes in FIFO order using a ever-growing vector since
@@ -517,7 +518,7 @@ private:
 
         for (auto *U : WI->users())
           if (MemoryPhi *MP = dyn_cast<MemoryPhi>(U))
-            PhisToCheck.push_back(MP);
+            PhisToCheck.insert(MP);
 
         MSSAUpdater->removeMemoryAccess(WI);
 
diff --git a/test/Transforms/EarlyCSE/pr33406.ll b/test/Transforms/EarlyCSE/pr33406.ll
new file mode 100644 (file)
index 0000000..4d3312e
--- /dev/null
@@ -0,0 +1,26 @@
+; RUN: opt -early-cse-memssa -S %s | FileCheck %s
+
+; CHECK: define void @patatino() {
+; CHECK:  for.cond:
+; CHECK-NEXT:  br i1 true, label %if.end, label %for.inc
+; CHECK:  if.end:
+; CHECK-NEXT:  %tinkywinky = load i32, i32* @b
+; CHECK-NEXT:  br i1 true, label %for.inc, label %for.inc
+; CHECK:  for.inc:
+; CHECK-NEXT:  ret void
+
+
+@b = external global i32
+
+define void @patatino() {
+for.cond:
+  br i1 true, label %if.end, label %for.inc
+
+if.end:
+  %tinkywinky = load i32, i32* @b
+  store i32 %tinkywinky, i32* @b
+  br i1 true, label %for.inc, label %for.inc
+
+for.inc:
+  ret void
+}