[llvm-branch-commits] [llvm] 6029d33 - Exit reads.

Florian Hahn via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Tue Feb 15 07:10:28 PST 2022


Author: Florian Hahn
Date: 2022-02-15T15:10:07Z
New Revision: 6029d33b407191aa1341ca0ce855523e7c2d6409

URL: https://github.com/llvm/llvm-project/commit/6029d33b407191aa1341ca0ce855523e7c2d6409
DIFF: https://github.com/llvm/llvm-project/commit/6029d33b407191aa1341ca0ce855523e7c2d6409.diff

LOG: Exit reads.

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
index 8739ddce91606..d75f6f2d97e38 100644
--- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
+++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp
@@ -100,9 +100,6 @@ STATISTIC(NumFastStores, "Number of stores deleted");
 STATISTIC(NumFastOther, "Number of other instrs removed");
 STATISTIC(NumCompletePartials, "Number of stores dead by later partials");
 STATISTIC(NumModifiedStores, "Number of stores modified");
-STATISTIC(NumCFGChecks, "Number of stores modified");
-STATISTIC(NumCFGTries, "Number of stores modified");
-STATISTIC(NumCFGSuccess, "Number of stores modified");
 STATISTIC(NumGetDomMemoryDefPassed,
           "Number of times a valid candidate is returned from getDomMemoryDef");
 STATISTIC(NumDomMemDefChecks,
@@ -763,6 +760,9 @@ struct DSEState {
   DenseMap<const Value *, bool> InvisibleToCallerAfterRet;
   // Keep track of blocks with throwing instructions not modeled in MemorySSA.
   SmallPtrSet<BasicBlock *, 16> ThrowingBlocks;
+
+  SmallPtrSet<Instruction *, 4> ExitReads;
+
   // Post-order numbers for each basic block. Used to figure out if memory
   // accesses are executed before another access.
   DenseMap<BasicBlock *, unsigned> PostOrderNumbers;
@@ -771,6 +771,8 @@ struct DSEState {
   /// basic block.
   MapVector<BasicBlock *, InstOverlapIntervalsTy> IOLs;
 
+  MemorySSAUpdater Updater;
+
   // Class contains self-reference, make sure it's not copied/moved.
   DSEState(const DSEState &) = delete;
   DSEState &operator=(const DSEState &) = delete;
@@ -779,7 +781,8 @@ struct DSEState {
            PostDominatorTree &PDT, const TargetLibraryInfo &TLI,
            const LoopInfo &LI)
       : F(F), AA(AA), EI(DT, LI), BatchAA(AA, &EI), MSSA(MSSA), DT(DT),
-        PDT(PDT), TLI(TLI), DL(F.getParent()->getDataLayout()), LI(LI) {
+        PDT(PDT), TLI(TLI), DL(F.getParent()->getDataLayout()), LI(LI),
+        Updater(&MSSA) {
     // Collect blocks with throwing instructions not modeled in MemorySSA and
     // alloc-like objects.
     unsigned PO = 0;
@@ -805,6 +808,23 @@ struct DSEState {
 
     // Collect whether there is any irreducible control flow in the function.
     ContainsIrreducibleLoops = mayContainIrreducibleControl(F, &LI);
+
+    LLVMContext &Ctx = F.getContext();
+    Type *I8Ty = IntegerType::get(Ctx, 8);
+
+    GlobalVariable *Ext = nullptr;
+    for (BasicBlock *E : PDT.roots()) {
+      if (!Ext)
+        Ext = new GlobalVariable(
+            *F.getParent(), I8Ty, false, GlobalValue::ExternalLinkage, nullptr,
+            "", nullptr, GlobalValue::NotThreadLocal, None, true);
+      auto *Term = E->getTerminator();
+      auto *LI = new LoadInst(I8Ty, Ext, "", Term);
+      auto *MemUse = cast<MemoryUse>(
+          Updater.createMemoryAccessInBB(LI, nullptr, E, MemorySSA::End));
+      Updater.insertUse(MemUse);
+      ExitReads.insert(LI);
+    }
   }
 
   /// Return 'OW_Complete' if a store to the 'KillingLoc' location (by \p
@@ -1150,7 +1170,10 @@ struct DSEState {
     if (auto *CB = dyn_cast<CallBase>(UseInst))
       if (CB->onlyAccessesInaccessibleMemory())
         return false;
-
+    auto *LI = dyn_cast<LoadInst>(UseInst);
+    if (LI && ExitReads.count(LI)) {
+      return !isInvisibleToCallerAfterRet(getUnderlyingObject(DefLoc.Ptr));
+    }
     return isRefSet(BatchAA.getModRefInfo(UseInst, DefLoc));
   }
 
@@ -1289,6 +1312,7 @@ struct DSEState {
       if (any_of(Current->uses(), [this, &KillingLoc, StartAccess](Use &U) {
             if (auto *UseOrDef = dyn_cast<MemoryUseOrDef>(U.getUser()))
               return !MSSA.dominates(StartAccess, UseOrDef) &&
+                     !ExitReads.count(UseOrDef->getMemoryInst()) &&
                      isReadClobber(KillingLoc, UseOrDef->getMemoryInst());
             return false;
           })) {
@@ -1490,69 +1514,6 @@ struct DSEState {
       }
     }
 
-    // For accesses to locations visible after the function returns, make sure
-    // that the location is dead (=overwritten) along all paths from
-    // MaybeDeadAccess to the exit.
-    if (!isInvisibleToCallerAfterRet(KillingUndObj)) {
-      SmallPtrSet<BasicBlock *, 16> KillingBlocks;
-      for (Instruction *KD : KillingDefs)
-        KillingBlocks.insert(KD->getParent());
-      assert(!KillingBlocks.empty() &&
-             "Expected at least a single killing block");
-
-      // Find the common post-dominator of all killing blocks.
-      BasicBlock *CommonPred = *KillingBlocks.begin();
-      for (BasicBlock *BB : llvm::drop_begin(KillingBlocks)) {
-        if (!CommonPred)
-          break;
-        CommonPred = PDT.findNearestCommonDominator(CommonPred, BB);
-      }
-
-      // If the common post-dominator does not post-dominate MaybeDeadAccess,
-      // there is a path from MaybeDeadAccess to an exit not going through a
-      // killing block.
-      if (!PDT.dominates(CommonPred, MaybeDeadAccess->getBlock()))
-        return None;
-
-      // If CommonPred itself is in the set of killing blocks, we're done.
-      if (KillingBlocks.count(CommonPred))
-        return {MaybeDeadAccess};
-
-      SetVector<BasicBlock *> WorkList;
-
-      // If CommonPred is null, there are multiple exits from the function.
-      // They all have to be added to the worklist.
-      if (CommonPred)
-        WorkList.insert(CommonPred);
-      else
-        for (BasicBlock *R : PDT.roots())
-          WorkList.insert(R);
-
-      NumCFGTries++;
-      // Check if all paths starting from an exit node go through one of the
-      // killing blocks before reaching MaybeDeadAccess.
-      for (unsigned I = 0; I < WorkList.size(); I++) {
-        NumCFGChecks++;
-        BasicBlock *Current = WorkList[I];
-        if (KillingBlocks.count(Current))
-          continue;
-        if (Current == MaybeDeadAccess->getBlock())
-          return None;
-
-        // MaybeDeadAccess is reachable from the entry, so we don't have to
-        // explore unreachable blocks further.
-        if (!DT.isReachableFromEntry(Current))
-          continue;
-
-        for (BasicBlock *Pred : predecessors(Current))
-          WorkList.insert(Pred);
-
-        if (WorkList.size() >= MemorySSAPathCheckLimit)
-          return None;
-      }
-      NumCFGSuccess++;
-    }
-
     // No aliasing MemoryUses of MaybeDeadAccess found, MaybeDeadAccess is
     // potentially dead.
     return {MaybeDeadAccess};
@@ -1560,7 +1521,6 @@ struct DSEState {
 
   // Delete dead memory defs
   void deleteDeadInstruction(Instruction *SI) {
-    MemorySSAUpdater Updater(&MSSA);
     SmallVector<Instruction *, 32> NowDeadInsts;
     NowDeadInsts.push_back(SI);
     --NumFastOther;
@@ -1744,7 +1704,6 @@ struct DSEState {
                  Malloc->getArgOperand(0), IRB, TLI);
     if (!Calloc)
       return false;
-    MemorySSAUpdater Updater(&MSSA);
     auto *LastDef =
       cast<MemoryDef>(Updater.getMemorySSA()->getMemoryAccess(Malloc));
     auto *NewAccess =
@@ -2087,6 +2046,17 @@ static bool eliminateDeadStores(Function &F, AliasAnalysis &AA, MemorySSA &MSSA,
 
   MadeChange |= State.eliminateRedundantStoresOfExistingValues();
   MadeChange |= State.eliminateDeadWritesAtEndOfFunction();
+
+  GlobalVariable *Ext = nullptr;
+  for (BasicBlock *E : PDT.roots()) {
+    auto *LI = cast<LoadInst>(E->getTerminator()->getPrevNode());
+    Ext = cast<GlobalVariable>(LI->getPointerOperand());
+    State.Updater.removeMemoryAccess(LI);
+    LI->eraseFromParent();
+  }
+  if (Ext)
+    Ext->eraseFromParent();
+
   return MadeChange;
 }
 } // end anonymous namespace


        


More information about the llvm-branch-commits mailing list