]> granicus.if.org Git - llvm/commitdiff
[MemorySSA] Update Phi creation when inserting a Def.
authorAlina Sbirlea <asbirlea@google.com>
Wed, 2 Oct 2019 18:42:33 +0000 (18:42 +0000)
committerAlina Sbirlea <asbirlea@google.com>
Wed, 2 Oct 2019 18:42:33 +0000 (18:42 +0000)
MemoryPhis should be added in the IDF of the blocks newly gaining Defs.
This includes the blocks that gained a Phi and the block gaining a Def,
if the block did not have one before.
Resolves PR43427.

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

lib/Analysis/MemorySSAUpdater.cpp
test/Analysis/MemorySSA/pr43427.ll [new file with mode: 0644]

index 6018968c199d7fd1ad5e0d3bafc87a7549cb0d08..d103c3a8b831fe1a1aaa6b989d0304ae4039ac34 100644 (file)
@@ -347,51 +347,54 @@ void MemorySSAUpdater::insertDef(MemoryDef *MD, bool RenameUses) {
 
     // If this is the first def in the block and this insert is in an arbitrary
     // place, compute IDF and place phis.
+    SmallPtrSet<BasicBlock *, 2> DefiningBlocks;
+
+    // If this is the last Def in the block, also compute IDF based on MD, since
+    // this may a new Def added, and we may need additional Phis.
     auto Iter = MD->getDefsIterator();
     ++Iter;
     auto IterEnd = MSSA->getBlockDefs(MD->getBlock())->end();
-    if (Iter == IterEnd) {
-      SmallPtrSet<BasicBlock *, 2> DefiningBlocks;
+    if (Iter == IterEnd)
       DefiningBlocks.insert(MD->getBlock());
-      for (const auto &VH : InsertedPHIs)
-        if (const auto *RealPHI = cast_or_null<MemoryPhi>(VH))
-          DefiningBlocks.insert(RealPHI->getBlock());
-      ForwardIDFCalculator IDFs(*MSSA->DT);
-      SmallVector<BasicBlock *, 32> IDFBlocks;
-      IDFs.setDefiningBlocks(DefiningBlocks);
-      IDFs.calculate(IDFBlocks);
-      SmallVector<AssertingVH<MemoryPhi>, 4> NewInsertedPHIs;
-      for (auto *BBIDF : IDFBlocks) {
-        auto *MPhi = MSSA->getMemoryAccess(BBIDF);
-        if (!MPhi) {
-          MPhi = MSSA->createMemoryPhi(BBIDF);
-          NewInsertedPHIs.push_back(MPhi);
-        }
-        // Add the phis created into the IDF blocks to NonOptPhis, so they are
-        // not optimized out as trivial by the call to getPreviousDefFromEnd
-        // below. Once they are complete, all these Phis are added to the
-        // FixupList, and removed from NonOptPhis inside fixupDefs(). Existing
-        // Phis in IDF may need fixing as well, and potentially be trivial
-        // before this insertion, hence add all IDF Phis. See PR43044.
-        NonOptPhis.insert(MPhi);
+
+    for (const auto &VH : InsertedPHIs)
+      if (const auto *RealPHI = cast_or_null<MemoryPhi>(VH))
+        DefiningBlocks.insert(RealPHI->getBlock());
+    ForwardIDFCalculator IDFs(*MSSA->DT);
+    SmallVector<BasicBlock *, 32> IDFBlocks;
+    IDFs.setDefiningBlocks(DefiningBlocks);
+    IDFs.calculate(IDFBlocks);
+    SmallVector<AssertingVH<MemoryPhi>, 4> NewInsertedPHIs;
+    for (auto *BBIDF : IDFBlocks) {
+      auto *MPhi = MSSA->getMemoryAccess(BBIDF);
+      if (!MPhi) {
+        MPhi = MSSA->createMemoryPhi(BBIDF);
+        NewInsertedPHIs.push_back(MPhi);
       }
-      for (auto &MPhi : NewInsertedPHIs) {
-        auto *BBIDF = MPhi->getBlock();
-        for (auto *Pred : predecessors(BBIDF)) {
-          DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> CachedPreviousDef;
-          MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef),
-                            Pred);
-        }
+      // Add the phis created into the IDF blocks to NonOptPhis, so they are not
+      // optimized out as trivial by the call to getPreviousDefFromEnd below.
+      // Once they are complete, all these Phis are added to the FixupList, and
+      // removed from NonOptPhis inside fixupDefs(). Existing Phis in IDF may
+      // need fixing as well, and potentially be trivial before this insertion,
+      // hence add all IDF Phis. See PR43044.
+      NonOptPhis.insert(MPhi);
+    }
+    for (auto &MPhi : NewInsertedPHIs) {
+      auto *BBIDF = MPhi->getBlock();
+      for (auto *Pred : predecessors(BBIDF)) {
+        DenseMap<BasicBlock *, TrackingVH<MemoryAccess>> CachedPreviousDef;
+        MPhi->addIncoming(getPreviousDefFromEnd(Pred, CachedPreviousDef), Pred);
       }
+    }
 
-      // Re-take the index where we're adding the new phis, because the above
-      // call to getPreviousDefFromEnd, may have inserted into InsertedPHIs.
-      NewPhiIndex = InsertedPHIs.size();
-      for (auto &MPhi : NewInsertedPHIs) {
-        InsertedPHIs.push_back(&*MPhi);
-        FixupList.push_back(&*MPhi);
-      }
+    // Re-take the index where we're adding the new phis, because the above call
+    // to getPreviousDefFromEnd, may have inserted into InsertedPHIs.
+    NewPhiIndex = InsertedPHIs.size();
+    for (auto &MPhi : NewInsertedPHIs) {
+      InsertedPHIs.push_back(&*MPhi);
+      FixupList.push_back(&*MPhi);
     }
+
     FixupList.push_back(MD);
   }
 
diff --git a/test/Analysis/MemorySSA/pr43427.ll b/test/Analysis/MemorySSA/pr43427.ll
new file mode 100644 (file)
index 0000000..f708878
--- /dev/null
@@ -0,0 +1,42 @@
+; RUN: opt -disable-output -licm -print-memoryssa -enable-mssa-loop-dependency=true < %s 2>&1 | FileCheck %s
+
+; CHECK-LABEL: @f()
+; CHECK: 8 = MemoryPhi(
+; CHECK: 7 = MemoryPhi(
+; CHECK: 9 = MemoryPhi(
+define void @f() {
+entry:
+  %e = alloca i16, align 1
+  br label %lbl1
+
+lbl1:                                             ; preds = %if.else, %cleanup, %entry
+  store i16 undef, i16* %e, align 1
+  call void @g()
+  br i1 undef, label %for.end, label %if.else
+
+for.end:                                          ; preds = %lbl1
+  br i1 undef, label %lbl3, label %lbl2
+
+lbl2:                                             ; preds = %lbl3, %for.end
+  br label %lbl3
+
+lbl3:                                             ; preds = %lbl2, %for.end
+  br i1 undef, label %lbl2, label %cleanup
+
+cleanup:                                          ; preds = %lbl3
+  %cleanup.dest = load i32, i32* undef, align 1
+  %switch = icmp ult i32 %cleanup.dest, 1
+  br i1 %switch, label %cleanup.cont, label %lbl1
+
+cleanup.cont:                                     ; preds = %cleanup
+  call void @llvm.lifetime.end.p0i8(i64 1, i8* null)
+  ret void
+
+if.else:                                          ; preds = %lbl1
+  br label %lbl1
+}
+
+declare void @g()
+
+; Function Attrs: argmemonly nounwind willreturn
+declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture)