[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