//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "lazy-value-info"
#include "llvm/Analysis/LazyValueInfo.h"
-#include "llvm/Analysis/ValueTracking.h"
-#include "llvm/Constants.h"
-#include "llvm/Instructions.h"
-#include "llvm/IntrinsicInst.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/ConstantFolding.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLibraryInfo.h"
-#include "llvm/Support/CFG.h"
-#include "llvm/Support/ConstantRange.h"
+#include "llvm/Analysis/ValueTracking.h"
+#include "llvm/IR/CFG.h"
+#include "llvm/IR/ConstantRange.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/IR/PatternMatch.h"
+#include "llvm/IR/ValueHandle.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/PatternMatch.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/ValueHandle.h"
-#include "llvm/ADT/DenseSet.h"
-#include "llvm/ADT/STLExtras.h"
+#include "llvm/Target/TargetLibraryInfo.h"
#include <map>
#include <stack>
using namespace llvm;
using namespace PatternMatch;
+#define DEBUG_TYPE "lazy-value-info"
+
char LazyValueInfo::ID = 0;
INITIALIZE_PASS_BEGIN(LazyValueInfo, "lazy-value-info",
"Lazy Value Information Analysis", false, true)
ConstantRange Range;
public:
- LVILatticeVal() : Tag(undefined), Val(0), Range(1, true) {}
+ LVILatticeVal() : Tag(undefined), Val(nullptr), Range(1, true) {}
static LVILatticeVal get(Constant *C) {
LVILatticeVal Res;
// Unless we can prove that the two Constants are different, we must
// move to overdefined.
- // FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
+ // FIXME: use DataLayout/TargetLibraryInfo for smarter constant folding.
if (ConstantInt *Res = dyn_cast<ConstantInt>(
ConstantFoldCompareInstOperands(CmpInst::ICMP_NE,
getConstant(),
// Unless we can prove that the two Constants are different, we must
// move to overdefined.
- // FIXME: use TargetData/TargetLibraryInfo for smarter constant folding.
+ // FIXME: use DataLayout/TargetLibraryInfo for smarter constant folding.
if (ConstantInt *Res = dyn_cast<ConstantInt>(
ConstantFoldCompareInstOperands(CmpInst::ICMP_NE,
getNotConstant(),
//===----------------------------------------------------------------------===//
namespace {
- /// LVIValueHandle - A callback value handle update the cache when
+ /// LVIValueHandle - A callback value handle updates the cache when
/// values are erased.
class LazyValueInfoCache;
struct LVIValueHandle : public CallbackVH {
LVIValueHandle(Value *V, LazyValueInfoCache *P)
: CallbackVH(V), Parent(P) { }
-
- void deleted();
- void allUsesReplacedWith(Value *V) {
+
+ void deleted() override;
+ void allUsesReplacedWith(Value *V) override {
deleted();
}
};
if (I->second == getValPtr())
ToErase.push_back(*I);
}
-
- for (SmallVector<OverDefinedPairTy, 4>::iterator I = ToErase.begin(),
+
+ for (SmallVectorImpl<OverDefinedPairTy>::iterator I = ToErase.begin(),
E = ToErase.end(); I != E; ++I)
Parent->OverDefinedCache.erase(*I);
if (I->first == BB)
ToErase.push_back(*I);
}
-
- for (SmallVector<OverDefinedPairTy, 4>::iterator I = ToErase.begin(),
+
+ for (SmallVectorImpl<OverDefinedPairTy>::iterator I = ToErase.begin(),
E = ToErase.end(); I != E; ++I)
OverDefinedCache.erase(*I);
return true;
LVIValueHandle ValHandle(Val, this);
- if (!ValueCache.count(ValHandle)) return false;
- return ValueCache[ValHandle].count(BB);
+ std::map<LVIValueHandle, ValueCacheEntryTy>::iterator I =
+ ValueCache.find(ValHandle);
+ if (I == ValueCache.end()) return false;
+ return I->second.count(BB);
}
LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) {
// cache needs updating, i.e. if we have solve a new value or not.
OverDefinedCacheUpdater ODCacheUpdater(Val, BB, BBLV, this);
- // If we've already computed this block's value, return it.
- if (!BBLV.isUndefined()) {
+ // Once this BB is encountered, Val's value for this BB will not be Undefined
+ // any longer. When we encounter this BB again, if Val's value is Overdefined,
+ // we need to compute its value again.
+ //
+ // For example, considering this control flow,
+ // BB1->BB2, BB1->BB3, BB2->BB3, BB2->BB4
+ //
+ // Suppose we have "icmp slt %v, 0" in BB1, and "icmp sgt %v, 0" in BB3. At
+ // the very beginning, when analyzing edge BB2->BB3, we don't know %v's value
+ // in BB2, and the data flow algorithm tries to compute BB2's predecessors, so
+ // then we know %v has negative value on edge BB1->BB2. And then we return to
+ // check BB2 again, and at this moment BB2 has Overdefined value for %v in
+ // BB2. So we should have to follow data flow propagation algorithm to get the
+ // value on edge BB1->BB2 propagated to BB2, and finally %v on BB2 has a
+ // constant range describing a negative value.
+
+ if (!BBLV.isUndefined() && !BBLV.isOverdefined()) {
DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n');
// Since we're reusing a cached value here, we don't need to update the
BBLV.markOverdefined();
Instruction *BBI = dyn_cast<Instruction>(Val);
- if (BBI == 0 || BBI->getParent() != BB) {
+ if (!BBI || BBI->getParent() != BB) {
return ODCacheUpdater.markResult(solveBlockValueNonLocal(BBLV, Val, BB));
}
static bool InstructionDereferencesPointer(Instruction *I, Value *Ptr) {
if (LoadInst *L = dyn_cast<LoadInst>(I)) {
return L->getPointerAddressSpace() == 0 &&
- GetUnderlyingObject(L->getPointerOperand()) ==
- GetUnderlyingObject(Ptr);
+ GetUnderlyingObject(L->getPointerOperand()) == Ptr;
}
if (StoreInst *S = dyn_cast<StoreInst>(I)) {
return S->getPointerAddressSpace() == 0 &&
- GetUnderlyingObject(S->getPointerOperand()) ==
- GetUnderlyingObject(Ptr);
+ GetUnderlyingObject(S->getPointerOperand()) == Ptr;
}
if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(I)) {
if (MI->isVolatile()) return false;
if (!Len || Len->isZero()) return false;
if (MI->getDestAddressSpace() == 0)
- if (MI->getRawDest() == Ptr || MI->getDest() == Ptr)
+ if (GetUnderlyingObject(MI->getRawDest()) == Ptr)
return true;
if (MemTransferInst *MTI = dyn_cast<MemTransferInst>(MI))
if (MTI->getSourceAddressSpace() == 0)
- if (MTI->getRawSource() == Ptr || MTI->getSource() == Ptr)
+ if (GetUnderlyingObject(MTI->getRawSource()) == Ptr)
return true;
}
return false;
// then we know that the pointer can't be NULL.
bool NotNull = false;
if (Val->getType()->isPointerTy()) {
- if (isa<AllocaInst>(Val)) {
+ if (isKnownNonNull(Val)) {
NotNull = true;
} else {
- for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){
- if (InstructionDereferencesPointer(BI, Val)) {
- NotNull = true;
- break;
+ Value *UnderlyingVal = GetUnderlyingObject(Val);
+ // If 'GetUnderlyingObject' didn't converge, skip it. It won't converge
+ // inside InstructionDereferencesPointer either.
+ if (UnderlyingVal == GetUnderlyingObject(UnderlyingVal, nullptr, 1)) {
+ for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
+ BI != BE; ++BI) {
+ if (InstructionDereferencesPointer(BI, UnderlyingVal)) {
+ NotNull = true;
+ break;
+ }
}
}
}
// Recognize the range checking idiom that InstCombine produces.
// (X-C1) u< C2 --> [C1, C1+C2)
- ConstantInt *NegOffset = 0;
+ ConstantInt *NegOffset = nullptr;
if (ICI->getPredicate() == ICmpInst::ICMP_ULT)
match(ICI->getOperand(0), m_Add(m_Specific(Val),
m_ConstantInt(NegOffset)));
for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
i != e; ++i) {
ConstantRange EdgeVal(i.getCaseValue()->getValue());
- if (DefaultCase)
- EdgesVals = EdgesVals.difference(EdgeVal);
- else if (i.getCaseSuccessor() == BBTo)
+ if (DefaultCase) {
+ // It is possible that the default destination is the destination of
+ // some cases. There is no need to perform difference for those cases.
+ if (i.getCaseSuccessor() != BBTo)
+ EdgesVals = EdgesVals.difference(EdgeVal);
+ } else if (i.getCaseSuccessor() == BBTo)
EdgesVals = EdgesVals.unionWith(EdgeVal);
}
Result = LVILatticeVal::getRange(EdgesVals);
if (PImpl)
getCache(PImpl).clear();
- TD = getAnalysisIfAvailable<TargetData>();
+ DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
+ DL = DLP ? &DLP->getDataLayout() : nullptr;
TLI = &getAnalysis<TargetLibraryInfo>();
// Fully lazy.
// If the cache was allocated, free it.
if (PImpl) {
delete &getCache(PImpl);
- PImpl = 0;
+ PImpl = nullptr;
}
}
if (const APInt *SingleVal = CR.getSingleElement())
return ConstantInt::get(V->getContext(), *SingleVal);
}
- return 0;
+ return nullptr;
}
/// getConstantOnEdge - Determine whether the specified value is known to be a
if (const APInt *SingleVal = CR.getSingleElement())
return ConstantInt::get(V->getContext(), *SingleVal);
}
- return 0;
+ return nullptr;
}
/// getPredicateOnEdge - Determine whether the specified value comparison
LVILatticeVal Result = getCache(PImpl).getValueOnEdge(V, FromBB, ToBB);
// If we know the value is a constant, evaluate the conditional.
- Constant *Res = 0;
+ Constant *Res = nullptr;
if (Result.isConstant()) {
- Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, TD,
+ Res = ConstantFoldCompareInstOperands(Pred, Result.getConstant(), C, DL,
TLI);
if (ConstantInt *ResCI = dyn_cast<ConstantInt>(Res))
return ResCI->isZero() ? False : True;
if (Pred == ICmpInst::ICMP_EQ) {
// !C1 == C -> false iff C1 == C.
Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
- Result.getNotConstant(), C, TD,
+ Result.getNotConstant(), C, DL,
TLI);
if (Res->isNullValue())
return False;
} else if (Pred == ICmpInst::ICMP_NE) {
// !C1 != C -> true iff C1 == C.
Res = ConstantFoldCompareInstOperands(ICmpInst::ICMP_NE,
- Result.getNotConstant(), C, TD,
+ Result.getNotConstant(), C, DL,
TLI);
if (Res->isNullValue())
return True;