aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Scalar/GVN.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Scalar/GVN.cpp')
-rw-r--r--llvm/lib/Transforms/Scalar/GVN.cpp78
1 files changed, 36 insertions, 42 deletions
diff --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 03e8a2507b45..5e58af0edc15 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -760,7 +760,7 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
auto &AA = AM.getResult<AAManager>(F);
auto *MemDep =
isMemDepEnabled() ? &AM.getResult<MemoryDependenceAnalysis>(F) : nullptr;
- auto *LI = AM.getCachedResult<LoopAnalysis>(F);
+ auto &LI = AM.getResult<LoopAnalysis>(F);
auto *MSSA = AM.getCachedResult<MemorySSAAnalysis>(F);
auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
bool Changed = runImpl(F, AC, DT, TLI, AA, MemDep, LI, &ORE,
@@ -772,8 +772,7 @@ PreservedAnalyses GVNPass::run(Function &F, FunctionAnalysisManager &AM) {
PA.preserve<TargetLibraryAnalysis>();
if (MSSA)
PA.preserve<MemorySSAAnalysis>();
- if (LI)
- PA.preserve<LoopAnalysis>();
+ PA.preserve<LoopAnalysis>();
return PA;
}
@@ -946,9 +945,14 @@ static void replaceValuesPerBlockEntry(
SmallVectorImpl<AvailableValueInBlock> &ValuesPerBlock, Value *OldValue,
Value *NewValue) {
for (AvailableValueInBlock &V : ValuesPerBlock) {
- if ((V.AV.isSimpleValue() && V.AV.getSimpleValue() == OldValue) ||
- (V.AV.isCoercedLoadValue() && V.AV.getCoercedLoadValue() == OldValue))
- V = AvailableValueInBlock::get(V.BB, NewValue);
+ if (V.AV.Val == OldValue)
+ V.AV.Val = NewValue;
+ if (V.AV.isSelectValue()) {
+ if (V.AV.V1 == OldValue)
+ V.AV.V1 = NewValue;
+ if (V.AV.V2 == OldValue)
+ V.AV.V2 = NewValue;
+ }
}
}
@@ -1147,13 +1151,11 @@ static Value *findDominatingValue(const MemoryLocation &Loc, Type *LoadTy,
BasicBlock *FromBB = From->getParent();
BatchAAResults BatchAA(*AA);
for (BasicBlock *BB = FromBB; BB; BB = BB->getSinglePredecessor())
- for (auto I = BB == FromBB ? From->getReverseIterator() : BB->rbegin(),
- E = BB->rend();
- I != E; ++I) {
+ for (auto *Inst = BB == FromBB ? From : BB->getTerminator();
+ Inst != nullptr; Inst = Inst->getPrevNonDebugInstruction()) {
// Stop the search if limit is reached.
if (++NumVisitedInsts > MaxNumVisitedInsts)
return nullptr;
- Instruction *Inst = &*I;
if (isModSet(BatchAA.getModRefInfo(Inst, Loc)))
return nullptr;
if (auto *LI = dyn_cast<LoadInst>(Inst))
@@ -1368,7 +1370,7 @@ LoadInst *GVNPass::findLoadToHoistIntoPred(BasicBlock *Pred, BasicBlock *LoadBB,
LoadInst *Load) {
// For simplicity we handle a Pred has 2 successors only.
auto *Term = Pred->getTerminator();
- if (Term->getNumSuccessors() != 2 || Term->isExceptionalTerminator())
+ if (Term->getNumSuccessors() != 2 || Term->isSpecialTerminator())
return nullptr;
auto *SuccBB = Term->getSuccessor(0);
if (SuccBB == LoadBB)
@@ -1416,16 +1418,8 @@ void GVNPass::eliminatePartiallyRedundantLoad(
Load->getSyncScopeID(), UnavailableBlock->getTerminator());
NewLoad->setDebugLoc(Load->getDebugLoc());
if (MSSAU) {
- auto *MSSA = MSSAU->getMemorySSA();
- // Get the defining access of the original load or use the load if it is a
- // MemoryDef (e.g. because it is volatile). The inserted loads are
- // guaranteed to load from the same definition.
- auto *LoadAcc = MSSA->getMemoryAccess(Load);
- auto *DefiningAcc =
- isa<MemoryDef>(LoadAcc) ? LoadAcc : LoadAcc->getDefiningAccess();
auto *NewAccess = MSSAU->createMemoryAccessInBB(
- NewLoad, DefiningAcc, NewLoad->getParent(),
- MemorySSA::BeforeTerminator);
+ NewLoad, nullptr, NewLoad->getParent(), MemorySSA::BeforeTerminator);
if (auto *NewDef = dyn_cast<MemoryDef>(NewAccess))
MSSAU->insertDef(NewDef, /*RenameUses=*/true);
else
@@ -1444,8 +1438,7 @@ void GVNPass::eliminatePartiallyRedundantLoad(
if (auto *RangeMD = Load->getMetadata(LLVMContext::MD_range))
NewLoad->setMetadata(LLVMContext::MD_range, RangeMD);
if (auto *AccessMD = Load->getMetadata(LLVMContext::MD_access_group))
- if (LI &&
- LI->getLoopFor(Load->getParent()) == LI->getLoopFor(UnavailableBlock))
+ if (LI->getLoopFor(Load->getParent()) == LI->getLoopFor(UnavailableBlock))
NewLoad->setMetadata(LLVMContext::MD_access_group, AccessMD);
// We do not propagate the old load's debug location, because the new
@@ -1482,6 +1475,7 @@ void GVNPass::eliminatePartiallyRedundantLoad(
// Perform PHI construction.
Value *V = ConstructSSAForLoadSet(Load, ValuesPerBlock, *this);
// ConstructSSAForLoadSet is responsible for combining metadata.
+ ICF->removeUsersOf(Load);
Load->replaceAllUsesWith(V);
if (isa<PHINode>(V))
V->takeName(Load);
@@ -1752,9 +1746,6 @@ bool GVNPass::PerformLoadPRE(LoadInst *Load, AvailValInBlkVect &ValuesPerBlock,
bool GVNPass::performLoopLoadPRE(LoadInst *Load,
AvailValInBlkVect &ValuesPerBlock,
UnavailBlkVect &UnavailableBlocks) {
- if (!LI)
- return false;
-
const Loop *L = LI->getLoopFor(Load->getParent());
// TODO: Generalize to other loop blocks that dominate the latch.
if (!L || L->getHeader() != Load->getParent())
@@ -1901,6 +1892,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
// Perform PHI construction.
Value *V = ConstructSSAForLoadSet(Load, ValuesPerBlock, *this);
// ConstructSSAForLoadSet is responsible for combining metadata.
+ ICF->removeUsersOf(Load);
Load->replaceAllUsesWith(V);
if (isa<PHINode>(V))
@@ -1922,7 +1914,7 @@ bool GVNPass::processNonLocalLoad(LoadInst *Load) {
// Step 4: Eliminate partial redundancy.
if (!isPREEnabled() || !isLoadPREEnabled())
return Changed;
- if (!isLoadInLoopPREEnabled() && LI && LI->getLoopFor(Load->getParent()))
+ if (!isLoadInLoopPREEnabled() && LI->getLoopFor(Load->getParent()))
return Changed;
if (performLoopLoadPRE(Load, ValuesPerBlock, UnavailableBlocks) ||
@@ -1998,12 +1990,12 @@ bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
if (ConstantInt *Cond = dyn_cast<ConstantInt>(V)) {
if (Cond->isZero()) {
Type *Int8Ty = Type::getInt8Ty(V->getContext());
+ Type *PtrTy = PointerType::get(V->getContext(), 0);
// Insert a new store to null instruction before the load to indicate that
// this code is not reachable. FIXME: We could insert unreachable
// instruction directly because we can modify the CFG.
auto *NewS = new StoreInst(PoisonValue::get(Int8Ty),
- Constant::getNullValue(Int8Ty->getPointerTo()),
- IntrinsicI);
+ Constant::getNullValue(PtrTy), IntrinsicI);
if (MSSAU) {
const MemoryUseOrDef *FirstNonDom = nullptr;
const auto *AL =
@@ -2023,14 +2015,12 @@ bool GVNPass::processAssumeIntrinsic(AssumeInst *IntrinsicI) {
}
}
- // This added store is to null, so it will never executed and we can
- // just use the LiveOnEntry def as defining access.
auto *NewDef =
FirstNonDom ? MSSAU->createMemoryAccessBefore(
- NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
+ NewS, nullptr,
const_cast<MemoryUseOrDef *>(FirstNonDom))
: MSSAU->createMemoryAccessInBB(
- NewS, MSSAU->getMemorySSA()->getLiveOnEntryDef(),
+ NewS, nullptr,
NewS->getParent(), MemorySSA::BeforeTerminator);
MSSAU->insertDef(cast<MemoryDef>(NewDef), /*RenameUses=*/false);
@@ -2177,6 +2167,7 @@ bool GVNPass::processLoad(LoadInst *L) {
Value *AvailableValue = AV->MaterializeAdjustedValue(L, L, *this);
// MaterializeAdjustedValue is responsible for combining metadata.
+ ICF->removeUsersOf(L);
L->replaceAllUsesWith(AvailableValue);
markInstructionForDeletion(L);
if (MSSAU)
@@ -2695,7 +2686,7 @@ bool GVNPass::processInstruction(Instruction *I) {
/// runOnFunction - This is the main transformation entry point for a function.
bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
const TargetLibraryInfo &RunTLI, AAResults &RunAA,
- MemoryDependenceResults *RunMD, LoopInfo *LI,
+ MemoryDependenceResults *RunMD, LoopInfo &LI,
OptimizationRemarkEmitter *RunORE, MemorySSA *MSSA) {
AC = &RunAC;
DT = &RunDT;
@@ -2705,7 +2696,7 @@ bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
MD = RunMD;
ImplicitControlFlowTracking ImplicitCFT;
ICF = &ImplicitCFT;
- this->LI = LI;
+ this->LI = &LI;
VN.setMemDep(MD);
ORE = RunORE;
InvalidBlockRPONumbers = true;
@@ -2719,7 +2710,7 @@ bool GVNPass::runImpl(Function &F, AssumptionCache &RunAC, DominatorTree &RunDT,
// Merge unconditional branches, allowing PRE to catch more
// optimization opportunities.
for (BasicBlock &BB : llvm::make_early_inc_range(F)) {
- bool removedBlock = MergeBlockIntoPredecessor(&BB, &DTU, LI, MSSAU, MD);
+ bool removedBlock = MergeBlockIntoPredecessor(&BB, &DTU, &LI, MSSAU, MD);
if (removedBlock)
++NumGVNBlocks;
@@ -2778,7 +2769,12 @@ bool GVNPass::processBlock(BasicBlock *BB) {
// use our normal hash approach for phis. Instead, simply look for
// obvious duplicates. The first pass of GVN will tend to create
// identical phis, and the second or later passes can eliminate them.
- ChangedFunction |= EliminateDuplicatePHINodes(BB);
+ SmallPtrSet<PHINode *, 8> PHINodesToRemove;
+ ChangedFunction |= EliminateDuplicatePHINodes(BB, PHINodesToRemove);
+ for (PHINode *PN : PHINodesToRemove) {
+ VN.erase(PN);
+ removeInstruction(PN);
+ }
for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
BI != BE;) {
@@ -2997,9 +2993,9 @@ bool GVNPass::performScalarPRE(Instruction *CurInst) {
++NumGVNPRE;
// Create a PHI to make the value available in this block.
- PHINode *Phi =
- PHINode::Create(CurInst->getType(), predMap.size(),
- CurInst->getName() + ".pre-phi", &CurrentBlock->front());
+ PHINode *Phi = PHINode::Create(CurInst->getType(), predMap.size(),
+ CurInst->getName() + ".pre-phi");
+ Phi->insertBefore(CurrentBlock->begin());
for (unsigned i = 0, e = predMap.size(); i != e; ++i) {
if (Value *V = predMap[i].first) {
// If we use an existing value in this phi, we have to patch the original
@@ -3290,8 +3286,6 @@ public:
if (skipFunction(F))
return false;
- auto *LIWP = getAnalysisIfAvailable<LoopInfoWrapperPass>();
-
auto *MSSAWP = getAnalysisIfAvailable<MemorySSAWrapperPass>();
return Impl.runImpl(
F, getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F),
@@ -3301,7 +3295,7 @@ public:
Impl.isMemDepEnabled()
? &getAnalysis<MemoryDependenceWrapperPass>().getMemDep()
: nullptr,
- LIWP ? &LIWP->getLoopInfo() : nullptr,
+ getAnalysis<LoopInfoWrapperPass>().getLoopInfo(),
&getAnalysis<OptimizationRemarkEmitterWrapperPass>().getORE(),
MSSAWP ? &MSSAWP->getMSSA() : nullptr);
}