[Attributor] Add helper to change an instruction to `unreachable` inst
authorHideto Ueno <uenoku.tokotoko@gmail.com>
Thu, 26 Dec 2019 17:39:37 +0000 (02:39 +0900)
committerHideto Ueno <uenoku.tokotoko@gmail.com>
Thu, 26 Dec 2019 17:39:37 +0000 (02:39 +0900)
Summary: Calling `changeToUnreachable` in `manifest` from different places might cause really unpredictable problems. As other deleting functions are doing, we need to change these instructions after all `manifest`.

Reviewers: jdoerfert, sstefan1

Reviewed By: jdoerfert

Subscribers: hiraditya, llvm-commits

Tags: #llvm

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

llvm/include/llvm/Transforms/IPO/Attributor.h
llvm/lib/Transforms/IPO/Attributor.cpp

index 25b3573..49196e0 100644 (file)
@@ -823,6 +823,12 @@ struct Attributor {
     return true;
   }
 
+  /// Record that \p I is to be replaced with `unreachable` after information
+  /// was manifested.
+  void changeToUnreachableAfterManifest(Instruction *I) {
+    ToBeChangedToUnreachableInsts.insert(I);
+  }
+
   /// Record that \p I is deleted after information was manifested. This also
   /// triggers deletion of trivially dead istructions.
   void deleteAfterManifest(Instruction &I) { ToBeDeletedInsts.insert(&I); }
@@ -1031,6 +1037,9 @@ private:
   /// then trivially dead instructions as well.
   DenseMap<Use *, Value *> ToBeChangedUses;
 
+  /// Instructions we replace with `unreachable` insts after manifest is done.
+  SmallPtrSet<Instruction *, 8> ToBeChangedToUnreachableInsts;
+
   /// Functions, blocks, and instructions we delete after manifest is done.
   ///
   ///{
index deb1101..65f02a7 100644 (file)
@@ -2049,7 +2049,7 @@ struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
     if (!UBMemAccessInsts.size())
       return ChangeStatus::UNCHANGED;
     for (Instruction *I : UBMemAccessInsts)
-      changeToUnreachable(I, /* UseLLVMTrap */ false);
+      A.changeToUnreachableAfterManifest(I);
     return ChangeStatus::CHANGED;
   }
 
@@ -2736,7 +2736,7 @@ struct AAIsDeadFunction : public AAIsDead {
 
       BB = SplitPos->getParent();
       SplitBlock(BB, SplitPos);
-      changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
+      A.changeToUnreachableAfterManifest(BB->getTerminator());
       HasChanged = ChangeStatus::CHANGED;
     }
 
@@ -5459,7 +5459,6 @@ ChangeStatus Attributor::run(Module &M) {
 
     SmallVector<Instruction *, 32> DeadInsts;
     SmallVector<Instruction *, 32> TerminatorsToFold;
-    SmallVector<Instruction *, 32> UnreachablesToInsert;
 
     for (auto &It : ToBeChangedUses) {
       Use *U = It.first;
@@ -5476,13 +5475,13 @@ ChangeStatus Attributor::run(Module &M) {
       if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
         Instruction *UserI = cast<Instruction>(U->getUser());
         if (isa<UndefValue>(NewV)) {
-          UnreachablesToInsert.push_back(UserI);
+          ToBeChangedToUnreachableInsts.insert(UserI);
         } else {
           TerminatorsToFold.push_back(UserI);
         }
       }
     }
-    for (Instruction *I : UnreachablesToInsert)
+    for (Instruction *I : ToBeChangedToUnreachableInsts)
       changeToUnreachable(I, /* UseLLVMTrap */ false);
     for (Instruction *I : TerminatorsToFold)
       ConstantFoldTerminator(I->getParent());