summaryrefslogtreecommitdiff
path: root/lib/Analysis/LazyValueInfo.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Analysis/LazyValueInfo.cpp')
-rw-r--r--lib/Analysis/LazyValueInfo.cpp121
1 files changed, 81 insertions, 40 deletions
diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp
index d7da669f6e79..435b6f205199 100644
--- a/lib/Analysis/LazyValueInfo.cpp
+++ b/lib/Analysis/LazyValueInfo.cpp
@@ -392,8 +392,8 @@ namespace {
if (!BlockValueSet.insert(BV).second)
return false; // It's already in the stack.
- DEBUG(dbgs() << "PUSH: " << *BV.second << " in " << BV.first->getName()
- << "\n");
+ LLVM_DEBUG(dbgs() << "PUSH: " << *BV.second << " in "
+ << BV.first->getName() << "\n");
BlockValueStack.push_back(BV);
return true;
}
@@ -401,6 +401,7 @@ namespace {
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.
ValueLatticeElement getBlockValue(Value *Val, BasicBlock *BB);
bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T,
@@ -463,13 +464,30 @@ namespace {
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) {}
+ : AC(AC), DL(DL), DT(DT), DisabledDT(nullptr) {}
};
} // end anonymous namespace
@@ -490,7 +508,8 @@ void LazyValueInfoImpl::solve() {
// PredicateInfo is used in LVI or CVP, we should be able to make the
// overdefined cache global, and remove this throttle.
if (processedCount > MaxProcessedPerValue) {
- DEBUG(dbgs() << "Giving up on stack because we are getting too deep\n");
+ LLVM_DEBUG(
+ dbgs() << "Giving up on stack because we are getting too deep\n");
// Fill in the original values
while (!StartingStack.empty()) {
std::pair<BasicBlock *, Value *> &e = StartingStack.back();
@@ -511,8 +530,9 @@ void LazyValueInfoImpl::solve() {
assert(TheCache.hasCachedValueInfo(e.second, e.first) &&
"Result should be in cache!");
- DEBUG(dbgs() << "POP " << *e.second << " in " << e.first->getName()
- << " = " << TheCache.getCachedValueInfo(e.second, e.first) << "\n");
+ LLVM_DEBUG(
+ dbgs() << "POP " << *e.second << " in " << e.first->getName() << " = "
+ << TheCache.getCachedValueInfo(e.second, e.first) << "\n");
BlockValueStack.pop_back();
BlockValueSet.erase(e);
@@ -563,8 +583,8 @@ bool LazyValueInfoImpl::solveBlockValue(Value *Val, BasicBlock *BB) {
if (TheCache.hasCachedValueInfo(Val, BB)) {
// If we have a cached value, use that.
- DEBUG(dbgs() << " reuse BB '" << BB->getName()
- << "' val=" << TheCache.getCachedValueInfo(Val, BB) << '\n');
+ LLVM_DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val="
+ << TheCache.getCachedValueInfo(Val, BB) << '\n');
// Since we're reusing a cached value, we don't need to update the
// OverDefinedCache. The cache will have been properly updated whenever the
@@ -619,8 +639,8 @@ bool LazyValueInfoImpl::solveBlockValueImpl(ValueLatticeElement &Res,
return solveBlockValueBinaryOp(Res, BO, BB);
}
- DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - unknown inst def found.\n");
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - unknown inst def found.\n");
Res = getFromRangeMetadata(BBI);
return true;
}
@@ -684,9 +704,11 @@ bool LazyValueInfoImpl::solveBlockValueNonLocal(ValueLatticeElement &BBLV,
assert(isa<Argument>(Val) && "Unknown live-in to the entry block");
// Before giving up, see if we can prove the pointer non-null local to
// this particular block.
- if (Val->getType()->isPointerTy() &&
- (isKnownNonZero(Val, DL) || isObjectDereferencedInBlock(Val, BB))) {
- PointerType *PTy = cast<PointerType>(Val->getType());
+ PointerType *PTy = dyn_cast<PointerType>(Val->getType());
+ if (PTy &&
+ (isKnownNonZero(Val, DL) ||
+ (isObjectDereferencedInBlock(Val, BB) &&
+ !NullPointerIsDefined(BB->getParent(), PTy->getAddressSpace())))) {
Result = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
} else {
Result = ValueLatticeElement::getOverdefined();
@@ -715,13 +737,13 @@ bool LazyValueInfoImpl::solveBlockValueNonLocal(ValueLatticeElement &BBLV,
// If we hit overdefined, exit early. The BlockVals entry is already set
// to overdefined.
if (Result.isOverdefined()) {
- DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined because of pred (non local).\n");
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - overdefined because of pred (non local).\n");
// Before giving up, see if we can prove the pointer non-null local to
// this particular block.
- if (Val->getType()->isPointerTy() &&
- isObjectDereferencedInBlock(Val, BB)) {
- PointerType *PTy = cast<PointerType>(Val->getType());
+ PointerType *PTy = dyn_cast<PointerType>(Val->getType());
+ if (PTy && isObjectDereferencedInBlock(Val, BB) &&
+ !NullPointerIsDefined(BB->getParent(), PTy->getAddressSpace())) {
Result = ValueLatticeElement::getNot(ConstantPointerNull::get(PTy));
}
@@ -759,8 +781,8 @@ bool LazyValueInfoImpl::solveBlockValuePHINode(ValueLatticeElement &BBLV,
// If we hit overdefined, exit early. The BlockVals entry is already set
// to overdefined.
if (Result.isOverdefined()) {
- DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined because of pred (local).\n");
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - overdefined because of pred (local).\n");
BBLV = Result;
return true;
@@ -950,8 +972,8 @@ bool LazyValueInfoImpl::solveBlockValueCast(ValueLatticeElement &BBLV,
break;
default:
// Unhandled instructions are overdefined.
- DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined (unknown cast).\n");
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - overdefined (unknown cast).\n");
BBLV = ValueLatticeElement::getOverdefined();
return true;
}
@@ -1009,8 +1031,8 @@ bool LazyValueInfoImpl::solveBlockValueBinaryOp(ValueLatticeElement &BBLV,
break;
default:
// Unhandled instructions are overdefined.
- DEBUG(dbgs() << " compute BB '" << BB->getName()
- << "' - overdefined (unknown binary operator).\n");
+ LLVM_DEBUG(dbgs() << " compute BB '" << BB->getName()
+ << "' - overdefined (unknown binary operator).\n");
BBLV = ValueLatticeElement::getOverdefined();
return true;
};
@@ -1127,9 +1149,17 @@ getValueFromConditionImpl(Value *Val, Value *Cond, bool isTrueDest,
(!isTrueDest && BO->getOpcode() != BinaryOperator::Or))
return ValueLatticeElement::getOverdefined();
- auto RHS = getValueFromCondition(Val, BO->getOperand(0), isTrueDest, Visited);
- auto LHS = getValueFromCondition(Val, BO->getOperand(1), isTrueDest, Visited);
- return intersect(RHS, LHS);
+ // Prevent infinite recursion if Cond references itself as in this example:
+ // Cond: "%tmp4 = and i1 %tmp4, undef"
+ // BL: "%tmp4 = and i1 %tmp4, undef"
+ // BR: "i1 undef"
+ Value *BL = BO->getOperand(0);
+ Value *BR = BO->getOperand(1);
+ if (BL == Cond || BR == Cond)
+ return ValueLatticeElement::getOverdefined();
+
+ return intersect(getValueFromCondition(Val, BL, isTrueDest, Visited),
+ getValueFromCondition(Val, BR, isTrueDest, Visited));
}
static ValueLatticeElement
@@ -1196,7 +1226,7 @@ static ValueLatticeElement constantFoldUser(User *Usr, Value *Op,
return ValueLatticeElement::getOverdefined();
}
-/// \brief Compute the value of Val on the edge BBFrom -> BBTo. Returns false if
+/// Compute the value of Val on the edge BBFrom -> BBTo. Returns false if
/// Val is not constrained on the edge. Result is unspecified if return value
/// is false.
static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
@@ -1321,7 +1351,7 @@ static bool getEdgeValueLocal(Value *Val, BasicBlock *BBFrom,
return false;
}
-/// \brief Compute the value of Val on the edge BBFrom -> BBTo or the value at
+/// Compute the value of Val on the edge BBFrom -> BBTo or the value at
/// the basic block if the edge does not constrain Val.
bool LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
BasicBlock *BBTo,
@@ -1373,8 +1403,8 @@ bool LazyValueInfoImpl::getEdgeValue(Value *Val, BasicBlock *BBFrom,
ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
Instruction *CxtI) {
- DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '"
- << BB->getName() << "'\n");
+ LLVM_DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '"
+ << BB->getName() << "'\n");
assert(BlockValueStack.empty() && BlockValueSet.empty());
if (!hasBlockValue(V, BB)) {
@@ -1384,13 +1414,13 @@ ValueLatticeElement LazyValueInfoImpl::getValueInBlock(Value *V, BasicBlock *BB,
ValueLatticeElement Result = getBlockValue(V, BB);
intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
- DEBUG(dbgs() << " Result = " << Result << "\n");
+ LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
return Result;
}
ValueLatticeElement LazyValueInfoImpl::getValueAt(Value *V, Instruction *CxtI) {
- DEBUG(dbgs() << "LVI Getting value " << *V << " at '"
- << CxtI->getName() << "'\n");
+ LLVM_DEBUG(dbgs() << "LVI Getting value " << *V << " at '" << CxtI->getName()
+ << "'\n");
if (auto *C = dyn_cast<Constant>(V))
return ValueLatticeElement::get(C);
@@ -1400,15 +1430,16 @@ ValueLatticeElement LazyValueInfoImpl::getValueAt(Value *V, Instruction *CxtI) {
Result = getFromRangeMetadata(I);
intersectAssumeOrGuardBlockValueConstantRange(V, Result, CxtI);
- DEBUG(dbgs() << " Result = " << Result << "\n");
+ LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
return Result;
}
ValueLatticeElement LazyValueInfoImpl::
getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
Instruction *CxtI) {
- DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '"
- << FromBB->getName() << "' to '" << ToBB->getName() << "'\n");
+ LLVM_DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '"
+ << FromBB->getName() << "' to '" << ToBB->getName()
+ << "'\n");
ValueLatticeElement Result;
if (!getEdgeValue(V, FromBB, ToBB, Result, CxtI)) {
@@ -1418,7 +1449,7 @@ getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB,
assert(WasFastQuery && "More work to do after problem solved?");
}
- DEBUG(dbgs() << " Result = " << Result << "\n");
+ LLVM_DEBUG(dbgs() << " Result = " << Result << "\n");
return Result;
}
@@ -1791,6 +1822,16 @@ void LazyValueInfo::printLVI(Function &F, DominatorTree &DTree, raw_ostream &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) {
@@ -1807,7 +1848,7 @@ void LazyValueInfoAnnotatedWriter::emitBasicBlockStartAnnot(
// This function prints the LVI analysis for the instruction I at the beginning
// of various basic blocks. It relies on calculated values that are stored in
-// the LazyValueInfoCache, and in the absence of cached values, recalculte the
+// the LazyValueInfoCache, and in the absence of cached values, recalculate the
// LazyValueInfo for `I`, and print that info.
void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
const Instruction *I, formatted_raw_ostream &OS) {
@@ -1830,7 +1871,7 @@ void LazyValueInfoAnnotatedWriter::emitInstructionAnnot(
};
printResult(ParentBB);
- // Print the LVI analysis results for the the immediate successor blocks, that
+ // Print the LVI analysis results for the immediate successor blocks, that
// are dominated by `ParentBB`.
for (auto *BBSucc : successors(ParentBB))
if (DT.dominates(ParentBB, BBSucc))