[llvm] r363880 - [MemorySSA] Cleanup trivial phis.

Alina Sbirlea via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 19 14:33:10 PDT 2019


Author: asbirlea
Date: Wed Jun 19 14:33:09 2019
New Revision: 363880

URL: http://llvm.org/viewvc/llvm-project?rev=363880&view=rev
Log:
[MemorySSA] Cleanup trivial phis.

Summary:
This is unfortunately needed for correctness, if we are to extend the tolerance of the update API to the way simple loop unswitch is doing cloning.

In simple loop unswitch (as opposed to loop unswitch), not all blocks are cloned. This can create unreachable cloned blocks (no predecessor), which are later cleaned up.

In MemorySSA, the  APIs for supporting these kind of updates (clone + update exit blocks), make certain assumption on the integrity of the CFG. When cloning, if something was not cloned, it's values in MemorySSA default to LiveOnEntry. When updating exit blocks, it is safe to assume that we can first insert phis in the blocks merging two clones, then add additional phis in the IDF of the blocks that received phis. This no longer holds true if one of the clones being merged comes from an unreachable block. We'd conservatively need to add all phis before filling in their incoming definitions. In practice this restriction can be relaxed if we clean up trivial phis after the first round of insertion.

Reviewers: george.burgess.iv

Subscribers: jlebar, Prazek, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D63354

Added:
    llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll
Modified:
    llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp

Modified: llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp?rev=363880&r1=363879&r2=363880&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp (original)
+++ llvm/trunk/lib/Analysis/MemorySSAUpdater.cpp Wed Jun 19 14:33:09 2019
@@ -866,7 +866,6 @@ void MemorySSAUpdater::applyInsertUpdate
   for (auto *BB : NewBlocks)
     PredMap.erase(BB);
 
-  SmallVector<BasicBlock *, 8> BlocksToProcess;
   SmallVector<BasicBlock *, 16> BlocksWithDefsToReplace;
   SmallVector<WeakVH, 8> InsertedPhis;
 
@@ -942,10 +941,6 @@ void MemorySSAUpdater::applyInsertUpdate
       for (auto *Pred : PrevBlockSet)
         for (int I = 0, E = EdgeCountMap[{Pred, BB}]; I < E; ++I)
           NewPhi->addIncoming(DefP1, Pred);
-
-      // Insert BB in the set of blocks that now have definition. We'll use this
-      // to compute IDF and add Phis there next.
-      BlocksToProcess.push_back(BB);
     }
 
     // Get all blocks that used to dominate BB and no longer do after adding
@@ -960,6 +955,14 @@ void MemorySSAUpdater::applyInsertUpdate
     GetNoLongerDomBlocks(PrevIDom, NewIDom, BlocksWithDefsToReplace);
   }
 
+  tryRemoveTrivialPhis(InsertedPhis);
+  // Create the set of blocks that now have a definition. We'll use this to
+  // compute IDF and add Phis there next.
+  SmallVector<BasicBlock *, 8> BlocksToProcess;
+  for (auto &VH : InsertedPhis)
+    if (auto *MPhi = cast_or_null<MemoryPhi>(VH))
+      BlocksToProcess.push_back(MPhi->getBlock());
+
   // Compute IDF and add Phis in all IDF blocks that do not have one.
   SmallVector<BasicBlock *, 32> IDFBlocks;
   if (!BlocksToProcess.empty()) {

Added: llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll?rev=363880&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll (added)
+++ llvm/trunk/test/Analysis/MemorySSA/simple_loop_unswitch_nontrivial.ll Wed Jun 19 14:33:09 2019
@@ -0,0 +1,113 @@
+; RUN: opt -simple-loop-unswitch -enable-nontrivial-unswitch -verify-memoryssa -S %s | FileCheck %s
+; REQUIRES: asserts
+
+target triple = "x86_64-unknown-linux-gnu"
+
+declare void @foo()
+
+; In Test1, there are no definitions. MemorySSA updates insert trivial phis and remove them.
+; Verify all are removed, considering the SLU pass leaves unreachable blocks hanging when the MSSA updates are done.
+; CHECK-LABEL: @Test1
+define void @Test1(i32) {
+header:
+  br label %outer
+
+outer.loopexit.split:                             ; preds = %continue
+  br label %outer.loopexit
+
+outer.loopexit:                                   ; preds = %outer.loopexit.split.us, %outer.loopexit.split
+  br label %outer
+
+outer:                                            ; preds = %outer.loopexit, %header
+  br i1 false, label %outer.split.us, label %outer.split
+
+outer.split.us:                                   ; preds = %outer
+  br label %inner.us
+
+inner.us:                                         ; preds = %continue.us, %outer.split.us
+  br label %overflow.us
+
+overflow.us:                                      ; preds = %inner.us
+  br label %continue.us
+
+continue.us:                                      ; preds = %overflow.us
+  br i1 true, label %outer.loopexit.split.us, label %inner.us
+
+outer.loopexit.split.us:                          ; preds = %continue.us
+  br label %outer.loopexit
+
+outer.split:                                      ; preds = %outer
+  br label %inner
+
+inner:                                            ; preds = %continue, %outer.split
+  br label %switchme
+
+switchme:                                         ; preds = %inner
+  switch i32 %0, label %continue [
+    i32 88, label %go_out
+    i32 99, label %case2
+  ]
+
+case2:                                            ; preds = %switchme
+  br label %continue
+
+continue:                                         ; preds = %case2, %switchme
+  br i1 true, label %outer.loopexit.split, label %inner
+
+go_out:                                           ; preds = %switchme
+  unreachable
+}
+
+; In Test2 there is a single def (call to foo). There are already Phis in place that are cloned when unswitching.
+; Ensure MemorySSA remains correct. Due to SLU's pruned cloning, continue.us2 becomes unreachable, with an empty Phi that is later cleaned.
+; CHECK-LABEL: @Test2
+define void @Test2(i32) {
+header:
+  br label %outer
+
+outer.loopexit.split:                             ; preds = %continue
+  br label %outer.loopexit
+
+outer.loopexit:                                   ; preds = %outer.loopexit.split.us, %outer.loopexit.split
+  br label %outer
+
+outer:                                            ; preds = %outer.loopexit, %header
+  br i1 false, label %outer.split.us, label %outer.split
+
+outer.split.us:                                   ; preds = %outer
+  br label %inner.us
+
+inner.us:                                         ; preds = %continue.us, %outer.split.us
+  br label %overflow.us
+
+overflow.us:                                      ; preds = %inner.us
+  br label %continue.us
+
+continue.us:                                      ; preds = %overflow.us
+  br i1 true, label %outer.loopexit.split.us, label %inner.us
+
+outer.loopexit.split.us:                          ; preds = %continue.us
+  br label %outer.loopexit
+
+outer.split:                                      ; preds = %outer
+  br label %inner
+
+inner:                                            ; preds = %continue, %outer.split
+  br label %switchme
+
+switchme:                                         ; preds = %inner
+  switch i32 %0, label %continue [
+    i32 88, label %go_out
+    i32 99, label %case2
+  ]
+
+case2:                                            ; preds = %switchme
+  call void @foo()
+  br label %continue
+
+continue:                                         ; preds = %case2, %switchme
+  br i1 true, label %outer.loopexit.split, label %inner
+
+go_out:                                           ; preds = %switchme
+  unreachable
+}




More information about the llvm-commits mailing list