//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "lazy-value-info"
+#include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/LazyValueInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/Constants.h"
//===----------------------------------------------------------------------===//
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 {
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, NULL, 1)) {
+ for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();
+ BI != BE; ++BI) {
+ if (InstructionDereferencesPointer(BI, UnderlyingVal)) {
+ NotNull = true;
+ break;
+ }
}
}
}