AssumptionCache *AC = nullptr;
const DataLayout *DL = nullptr;
class TargetLibraryInfo *TLI = nullptr;
- DominatorTree *DT = nullptr;
void *PImpl = nullptr;
LazyValueInfo(const LazyValueInfo&) = delete;
void operator=(const LazyValueInfo&) = delete;
public:
~LazyValueInfo();
LazyValueInfo() {}
- LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_, TargetLibraryInfo *TLI_,
- DominatorTree *DT_)
- : AC(AC_), DL(DL_), TLI(TLI_), DT(DT_) {}
+ LazyValueInfo(AssumptionCache *AC_, const DataLayout *DL_,
+ TargetLibraryInfo *TLI_)
+ : AC(AC_), DL(DL_), TLI(TLI_) {}
LazyValueInfo(LazyValueInfo &&Arg)
- : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), DT(Arg.DT), PImpl(Arg.PImpl) {
+ : AC(Arg.AC), DL(Arg.DL), TLI(Arg.TLI), PImpl(Arg.PImpl) {
Arg.PImpl = nullptr;
}
LazyValueInfo &operator=(LazyValueInfo &&Arg) {
AC = Arg.AC;
DL = Arg.DL;
TLI = Arg.TLI;
- DT = Arg.DT;
PImpl = Arg.PImpl;
Arg.PImpl = nullptr;
return *this;
/// Print the \LazyValueInfo Analysis.
/// We pass in the DTree that is required for identifying which basic blocks
- /// we can solve/print for, in the LVIPrinter. The DT is optional
- /// in LVI, so we need to pass it here as an argument.
+ /// we can solve/print for, in the LVIPrinter.
void printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS);
- /// Disables use of the DominatorTree within LVI.
- void disableDT();
-
- /// Enables use of the DominatorTree within LVI. Does nothing if the class
- /// instance was initialized without a DT pointer.
- void enableDT();
-
// For old PM pass. Delete once LazyValueInfoWrapperPass is gone.
void releaseMemory();
class LazyValueInfoAnnotatedWriter : public AssemblyAnnotationWriter {
LazyValueInfoImpl *LVIImpl;
// While analyzing which blocks we can solve values for, we need the dominator
- // information. Since this is an optional parameter in LVI, we require this
- // DomTreeAnalysis pass in the printer pass, and pass the dominator
- // tree to the LazyValueInfoAnnotatedWriter.
+ // information.
DominatorTree &DT;
public:
AssumptionCache *AC; ///< A pointer to the cache of @llvm.assume calls.
const DataLayout &DL; ///< A mandatory DataLayout
- DominatorTree *DT; ///< An optional DT pointer.
- DominatorTree *DisabledDT; ///< Stores DT if it's disabled.
Optional<ValueLatticeElement> getBlockValue(Value *Val, BasicBlock *BB);
Optional<ValueLatticeElement> getEdgeValue(Value *V, BasicBlock *F,
TheCache.eraseBlock(BB);
}
- /// Disables use of the DominatorTree within LVI.
- void disableDT() {
- if (DT) {
- assert(!DisabledDT && "Both DT and DisabledDT are not nullptr!");
- std::swap(DT, DisabledDT);
- }
- }
-
- /// Enables use of the DominatorTree within LVI. Does nothing if the class
- /// instance was initialized without a DT pointer.
- void enableDT() {
- if (DisabledDT) {
- assert(!DT && "Both DT and DisabledDT are not nullptr!");
- std::swap(DT, DisabledDT);
- }
- }
-
/// This is the update interface to inform the cache that an edge from
/// PredBB to OldSucc has been threaded to be from PredBB to NewSucc.
void threadEdge(BasicBlock *PredBB,BasicBlock *OldSucc,BasicBlock *NewSucc);
- LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL,
- DominatorTree *DT = nullptr)
- : AC(AC), DL(DL), DT(DT), DisabledDT(nullptr) {}
+ LazyValueInfoImpl(AssumptionCache *AC, const DataLayout &DL)
+ : AC(AC), DL(DL) {}
};
} // end anonymous namespace
/// This lazily constructs the LazyValueInfoImpl.
static LazyValueInfoImpl &getImpl(void *&PImpl, AssumptionCache *AC,
- const DataLayout *DL,
- DominatorTree *DT = nullptr) {
+ const DataLayout *DL) {
if (!PImpl) {
assert(DL && "getCache() called with a null DataLayout");
- PImpl = new LazyValueInfoImpl(AC, *DL, DT);
+ PImpl = new LazyValueInfoImpl(AC, *DL);
}
return *static_cast<LazyValueInfoImpl*>(PImpl);
}
bool LazyValueInfoWrapperPass::runOnFunction(Function &F) {
Info.AC = &getAnalysis<AssumptionCacheTracker>().getAssumptionCache(F);
const DataLayout &DL = F.getParent()->getDataLayout();
-
- DominatorTreeWrapperPass *DTWP =
- getAnalysisIfAvailable<DominatorTreeWrapperPass>();
- Info.DT = DTWP ? &DTWP->getDomTree() : nullptr;
Info.TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
if (Info.PImpl)
- getImpl(Info.PImpl, Info.AC, &DL, Info.DT).clear();
+ getImpl(Info.PImpl, Info.AC, &DL).clear();
// Fully lazy.
return false;
// We need to invalidate if we have either failed to preserve this analyses
// result directly or if any of its dependencies have been invalidated.
auto PAC = PA.getChecker<LazyValueAnalysis>();
- if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()) ||
- (DT && Inv.invalidate<DominatorTreeAnalysis>(F, PA)))
+ if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>()))
return true;
return false;
FunctionAnalysisManager &FAM) {
auto &AC = FAM.getResult<AssumptionAnalysis>(F);
auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
- auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
- return LazyValueInfo(&AC, &F.getParent()->getDataLayout(), &TLI, DT);
+ return LazyValueInfo(&AC, &F.getParent()->getDataLayout(), &TLI);
}
/// Returns true if we can statically tell that this value will never be a
const DataLayout &DL = BB->getModule()->getDataLayout();
ValueLatticeElement Result =
- getImpl(PImpl, AC, &DL, DT).getValueInBlock(V, BB, CxtI);
+ getImpl(PImpl, AC, &DL).getValueInBlock(V, BB, CxtI);
if (Result.isConstant())
return Result.getConstant();
unsigned Width = V->getType()->getIntegerBitWidth();
const DataLayout &DL = BB->getModule()->getDataLayout();
ValueLatticeElement Result =
- getImpl(PImpl, AC, &DL, DT).getValueInBlock(V, BB, CxtI);
+ getImpl(PImpl, AC, &DL).getValueInBlock(V, BB, CxtI);
if (Result.isUnknown())
return ConstantRange::getEmpty(Width);
if (Result.isConstantRange(UndefAllowed))
Instruction *CxtI) {
const DataLayout &DL = FromBB->getModule()->getDataLayout();
ValueLatticeElement Result =
- getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getImpl(PImpl, AC, &DL).getValueOnEdge(V, FromBB, ToBB, CxtI);
if (Result.isConstant())
return Result.getConstant();
unsigned Width = V->getType()->getIntegerBitWidth();
const DataLayout &DL = FromBB->getModule()->getDataLayout();
ValueLatticeElement Result =
- getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getImpl(PImpl, AC, &DL).getValueOnEdge(V, FromBB, ToBB, CxtI);
if (Result.isUnknown())
return ConstantRange::getEmpty(Width);
Instruction *CxtI) {
const DataLayout &DL = FromBB->getModule()->getDataLayout();
ValueLatticeElement Result =
- getImpl(PImpl, AC, &DL, DT).getValueOnEdge(V, FromBB, ToBB, CxtI);
+ getImpl(PImpl, AC, &DL).getValueOnEdge(V, FromBB, ToBB, CxtI);
return getPredicateResult(Pred, C, Result, DL, TLI);
}
else if (Pred == ICmpInst::ICMP_NE)
return LazyValueInfo::True;
}
- ValueLatticeElement Result = getImpl(PImpl, AC, &DL, DT).getValueAt(V, CxtI);
+ ValueLatticeElement Result = getImpl(PImpl, AC, &DL).getValueAt(V, CxtI);
Tristate Ret = getPredicateResult(Pred, C, Result, DL, TLI);
if (Ret != Unknown)
return Ret;
BasicBlock *NewSucc) {
if (PImpl) {
const DataLayout &DL = PredBB->getModule()->getDataLayout();
- getImpl(PImpl, AC, &DL, DT).threadEdge(PredBB, OldSucc, NewSucc);
+ getImpl(PImpl, AC, &DL).threadEdge(PredBB, OldSucc, NewSucc);
}
}
void LazyValueInfo::eraseBlock(BasicBlock *BB) {
if (PImpl) {
const DataLayout &DL = BB->getModule()->getDataLayout();
- getImpl(PImpl, AC, &DL, DT).eraseBlock(BB);
+ getImpl(PImpl, AC, &DL).eraseBlock(BB);
}
}
void LazyValueInfo::printLVI(Function &F, DominatorTree &DTree, raw_ostream &OS) {
if (PImpl) {
- getImpl(PImpl, AC, DL, DT).printLVI(F, DTree, OS);
+ getImpl(PImpl, AC, DL).printLVI(F, DTree, OS);
}
}
-void LazyValueInfo::disableDT() {
- if (PImpl)
- getImpl(PImpl, AC, DL, DT).disableDT();
-}
-
-void LazyValueInfo::enableDT() {
- if (PImpl)
- getImpl(PImpl, AC, DL, DT).enableDT();
-}
-
// Print the LVI for the function arguments at the start of each basic block.
void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
const BasicBlock *BB, formatted_raw_ostream &OS) {
if (skipFunction(F))
return false;
auto TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
- // Get DT analysis before LVI. When LVI is initialized it conditionally adds
- // DT if it's available.
auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
auto LVI = &getAnalysis<LazyValueInfoWrapperPass>().getLVI();
auto AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
std::move(BFI), std::move(BPI));
if (PrintLVIAfterJumpThreading) {
dbgs() << "LVI for function '" << F.getName() << "':\n";
- LVI->printLVI(F, *DT, dbgs());
+ LVI->printLVI(F, DTU.getDomTree(), dbgs());
}
return Changed;
}
PreservedAnalyses JumpThreadingPass::run(Function &F,
FunctionAnalysisManager &AM) {
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
- // Get DT analysis before LVI. When LVI is initialized it conditionally adds
- // DT if it's available.
auto &DT = AM.getResult<DominatorTreeAnalysis>(F);
auto &LVI = AM.getResult<LazyValueAnalysis>(F);
auto &AA = AM.getResult<AAManager>(F);
} while (Changed);
LoopHeaders.clear();
- // Flush only the Dominator Tree.
- DTU->getDomTree();
- LVI->enableDT();
return EverChanged;
}
// able to handle value inequalities better, for example if the compare is
// "X < 4" and "X < 3" is known true but "X < 4" itself is not available.
// Perhaps getConstantOnEdge should be smart enough to do this?
-
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
for (BasicBlock *P : predecessors(BB)) {
// If the value is known by LazyValueInfo to be a constant in a
// predecessor, use that information to try to thread this block.
/// If I is a PHI node, then we know the incoming values for any constants.
if (PHINode *PN = dyn_cast<PHINode>(I)) {
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
Value *InVal = PN->getIncomingValue(i);
if (Constant *KC = getKnownConstant(InVal, Preference)) {
const DataLayout &DL = PN->getModule()->getDataLayout();
// We can do this simplification if any comparisons fold to true or false.
// See if any do.
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
BasicBlock *PredBB = PN->getIncomingBlock(i);
Value *LHS, *RHS;
if (!isa<Instruction>(CmpLHS) ||
cast<Instruction>(CmpLHS)->getParent() != BB) {
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
for (BasicBlock *P : predecessors(BB)) {
// If the value is known by LazyValueInfo to be a constant in a
// predecessor, use that information to try to thread this block.
match(CmpLHS, m_Add(m_Value(AddLHS), m_ConstantInt(AddConst)))) {
if (!isa<Instruction>(AddLHS) ||
cast<Instruction>(AddLHS)->getParent() != BB) {
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
for (BasicBlock *P : predecessors(BB)) {
// If the value is known by LazyValueInfo to be a ConstantRange in
// a predecessor, use that information to try to thread this
}
// If all else fails, see if LVI can figure out a constant value for us.
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
Constant *CI = LVI->getConstant(V, BB, CxtI);
if (Constant *KC = getKnownConstant(CI, Preference)) {
for (BasicBlock *Pred : predecessors(BB))
// threading is concerned.
assert(CondBr->isConditional() && "Threading on unconditional terminator");
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
LazyValueInfo::Tristate Ret =
LVI->getPredicateAt(CondCmp->getPredicate(), CondCmp->getOperand(0),
CondConst, CondBr);
// Consult LVI if V is not an instruction in BB or PredBB.
Instruction *I = dyn_cast<Instruction>(V);
if (!I || (I->getParent() != BB && I->getParent() != PredBB)) {
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
return LVI->getConstantOnEdge(V, PredPredBB, PredBB, nullptr);
}
<< "' to '" << SuccBB->getName()
<< ", across block:\n " << *BB << "\n");
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
LVI->threadEdge(PredBB, BB, SuccBB);
BasicBlock *NewBB = BasicBlock::Create(BB->getContext(),
// Now check if one of the select values would allow us to constant fold the
// terminator in BB. We don't do the transform if both sides fold, those
// cases will be threaded in any case.
- if (DTU->hasPendingDomTreeUpdates())
- LVI->disableDT();
- else
- LVI->enableDT();
LazyValueInfo::Tristate LHSFolds =
LVI->getPredicateOnEdge(CondCmp->getPredicate(), SI->getOperand(1),
CondRHS, Pred, BB, CondCmp);