X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FLazyValueInfo.cpp;h=f80595c7dbedd26535279cd998007b4e0e9e3c3d;hb=83ec87755ed4d07f6650d6727fb762052bd0041c;hp=bd6fc3a8eb46acbda0d8cf8323f193b22e6b786a;hpb=bb39ac1458deecf167af2c51c9cbc0a80a0efb98;p=oota-llvm.git diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index bd6fc3a8eb4..f80595c7dbe 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -17,6 +17,7 @@ #include "llvm/Analysis/ValueTracking.h" #include "llvm/Constants.h" #include "llvm/Instructions.h" +#include "llvm/IntrinsicInst.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CFG.h" @@ -28,7 +29,6 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/STLExtras.h" #include -#include #include using namespace llvm; @@ -267,6 +267,8 @@ public: } // end anonymous namespace. namespace llvm { +raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) + LLVM_ATTRIBUTE_USED; raw_ostream &operator<<(raw_ostream &OS, const LVILatticeVal &Val) { if (Val.isUndefined()) return OS << "undefined"; @@ -322,19 +324,55 @@ namespace llvm { return LHS == RHS; } }; + + template<> + struct DenseMapInfo, Value*> > { + typedef std::pair, Value*> PairTy; + typedef DenseMapInfo > APointerInfo; + typedef DenseMapInfo BPointerInfo; + static inline PairTy getEmptyKey() { + return std::make_pair(APointerInfo::getEmptyKey(), + BPointerInfo::getEmptyKey()); + } + static inline PairTy getTombstoneKey() { + return std::make_pair(APointerInfo::getTombstoneKey(), + BPointerInfo::getTombstoneKey()); + } + static unsigned getHashValue( const PairTy &Val) { + return APointerInfo::getHashValue(Val.first) ^ + BPointerInfo::getHashValue(Val.second); + } + static bool isEqual(const PairTy &LHS, const PairTy &RHS) { + return APointerInfo::isEqual(LHS.first, RHS.first) && + BPointerInfo::isEqual(LHS.second, RHS.second); + } + }; } namespace { /// LazyValueInfoCache - This is the cache kept by LazyValueInfo which /// maintains information about queries across the clients' queries. class LazyValueInfoCache { - public: /// ValueCacheEntryTy - This is all of the cached block information for /// exactly one Value*. The entries are sorted by the BasicBlock* of the /// entries, allowing us to do a lookup with a binary search. typedef std::map, LVILatticeVal> ValueCacheEntryTy; - private: + /// ValueCache - This is all of the cached information for all values, + /// mapped from Value* to key information. + DenseMap ValueCache; + + /// OverDefinedCache - This tracks, on a per-block basis, the set of + /// values that are over-defined at the end of that block. This is required + /// for cache updating. + typedef std::pair, Value*> OverDefinedPairTy; + DenseSet OverDefinedCache; + + /// BlockValueStack - This stack holds the state of the value solver + /// during a query. It basically emulates the callstack of the naive + /// recursive value lookup process. + std::stack > BlockValueStack; + friend struct LVIValueHandle; /// OverDefinedCacheUpdater - A helper object that ensures that the @@ -355,15 +393,8 @@ namespace { return changed; } }; - - /// ValueCache - This is all of the cached information for all values, - /// mapped from Value* to key information. - DenseMap ValueCache; - /// OverDefinedCache - This tracks, on a per-block basis, the set of - /// values that are over-defined at the end of that block. This is required - /// for cache updating. - std::set, Value*> > OverDefinedCache; + LVILatticeVal getBlockValue(Value *Val, BasicBlock *BB); bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T, @@ -386,8 +417,6 @@ namespace { ValueCacheEntryTy &lookup(Value *V) { return ValueCache[LVIValueHandle(V, this)]; } - - std::stack > block_value_stack; public: /// getValueInBlock - This is the query interface to determine the lattice @@ -416,29 +445,37 @@ namespace { } // end anonymous namespace void LVIValueHandle::deleted() { - for (std::set, Value*> >::iterator + typedef std::pair, Value*> OverDefinedPairTy; + + SmallVector ToErase; + for (DenseSet::iterator I = Parent->OverDefinedCache.begin(), E = Parent->OverDefinedCache.end(); - I != E; ) { - std::set, Value*> >::iterator tmp = I; - ++I; - if (tmp->second == getValPtr()) - Parent->OverDefinedCache.erase(tmp); + I != E; ++I) { + if (I->second == getValPtr()) + ToErase.push_back(*I); } + for (SmallVector::iterator I = ToErase.begin(), + E = ToErase.end(); I != E; ++I) + Parent->OverDefinedCache.erase(*I); + // This erasure deallocates *this, so it MUST happen after we're done // using any and all members of *this. Parent->ValueCache.erase(*this); } void LazyValueInfoCache::eraseBlock(BasicBlock *BB) { - for (std::set, Value*> >::iterator - I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ) { - std::set, Value*> >::iterator tmp = I; - ++I; - if (tmp->first == BB) - OverDefinedCache.erase(tmp); + SmallVector ToErase; + for (DenseSet::iterator I = OverDefinedCache.begin(), + E = OverDefinedCache.end(); I != E; ++I) { + if (I->first == BB) + ToErase.push_back(*I); } + + for (SmallVector::iterator I = ToErase.begin(), + E = ToErase.end(); I != E; ++I) + OverDefinedCache.erase(*I); for (DenseMap::iterator I = ValueCache.begin(), E = ValueCache.end(); I != E; ++I) @@ -446,10 +483,10 @@ void LazyValueInfoCache::eraseBlock(BasicBlock *BB) { } void LazyValueInfoCache::solve() { - while (!block_value_stack.empty()) { - std::pair &e = block_value_stack.top(); + while (!BlockValueStack.empty()) { + std::pair &e = BlockValueStack.top(); if (solveBlockValue(e.second, e.first)) - block_value_stack.pop(); + BlockValueStack.pop(); } } @@ -458,7 +495,9 @@ bool LazyValueInfoCache::hasBlockValue(Value *Val, BasicBlock *BB) { if (isa(Val)) return true; - return lookup(Val).count(BB); + LVIValueHandle ValHandle(Val, this); + if (!ValueCache.count(ValHandle)) return false; + return ValueCache[ValHandle].count(BB); } LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { @@ -507,6 +546,11 @@ bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { return ODCacheUpdater.markResult(solveBlockValuePHINode(BBLV, PN, BB)); } + if (AllocaInst *AI = dyn_cast(BBI)) { + BBLV = LVILatticeVal::getNot(ConstantPointerNull::get(AI->getType())); + return ODCacheUpdater.markResult(true); + } + // We can only analyze the definitions of certain classes of instructions // (integral binops and casts at the moment), so bail if this isn't one. LVILatticeVal Result; @@ -543,7 +587,21 @@ static bool InstructionDereferencesPointer(Instruction *I, Value *Ptr) { GetUnderlyingObject(S->getPointerOperand()) == GetUnderlyingObject(Ptr); } - // FIXME: llvm.memset, etc. + if (MemIntrinsic *MI = dyn_cast(I)) { + if (MI->isVolatile()) return false; + + // FIXME: check whether it has a valuerange that excludes zero? + ConstantInt *Len = dyn_cast(MI->getLength()); + if (!Len || Len->isZero()) return false; + + if (MI->getDestAddressSpace() == 0) + if (MI->getRawDest() == Ptr || MI->getDest() == Ptr) + return true; + if (MemTransferInst *MTI = dyn_cast(MI)) + if (MTI->getSourceAddressSpace() == 0) + if (MTI->getRawSource() == Ptr || MTI->getSource() == Ptr) + return true; + } return false; } @@ -555,10 +613,14 @@ bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, // then we know that the pointer can't be NULL. bool NotNull = false; if (Val->getType()->isPointerTy()) { - for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){ - if (InstructionDereferencesPointer(BI, Val)) { - NotNull = true; - break; + if (isa(Val)) { + NotNull = true; + } else { + for (BasicBlock::iterator BI = BB->begin(), BE = BB->end();BI != BE;++BI){ + if (InstructionDereferencesPointer(BI, Val)) { + NotNull = true; + break; + } } } } @@ -568,7 +630,7 @@ bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, if (BB == &BB->getParent()->getEntryBlock()) { assert(isa(Val) && "Unknown live-in to the entry block"); if (NotNull) { - const PointerType *PTy = cast(Val->getType()); + PointerType *PTy = cast(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } else { Result.markOverdefined(); @@ -596,7 +658,7 @@ bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, // If we previously determined that this is a pointer that can't be null // then return that rather than giving up entirely. if (NotNull) { - const PointerType *PTy = cast(Val->getType()); + PointerType *PTy = cast(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } @@ -654,7 +716,7 @@ bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. if (!hasBlockValue(BBI->getOperand(0), BB)) { - block_value_stack.push(std::make_pair(BB, BBI->getOperand(0))); + BlockValueStack.push(std::make_pair(BB, BBI->getOperand(0))); return false; } @@ -666,7 +728,7 @@ bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, ConstantRange LHSRange = LHSVal.getConstantRange(); ConstantRange RHSRange(1); - const IntegerType *ResultTy = cast(BBI->getType()); + IntegerType *ResultTy = cast(BBI->getType()); if (isa(BBI)) { if (ConstantInt *RHS = dyn_cast(BBI->getOperand(1))) { RHSRange = ConstantRange(RHS->getValue()); @@ -783,6 +845,11 @@ bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom, if (!isTrueDest) TrueValues = TrueValues.inverse(); // Figure out the possible values of the query BEFORE this branch. + if (!hasBlockValue(Val, BBFrom)) { + BlockValueStack.push(std::make_pair(BBFrom, Val)); + return false; + } + LVILatticeVal InBlock = getBlockValue(Val, BBFrom); if (!InBlock.isConstantRange()) { Result = LVILatticeVal::getRange(TrueValues); @@ -833,7 +900,7 @@ bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom, Result = getBlockValue(Val, BBFrom); return true; } - block_value_stack.push(std::make_pair(BBFrom, Val)); + BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; } @@ -841,7 +908,7 @@ LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) { DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" << BB->getName() << "'\n"); - block_value_stack.push(std::make_pair(BB, V)); + BlockValueStack.push(std::make_pair(BB, V)); solve(); LVILatticeVal Result = getBlockValue(V, BB); @@ -882,8 +949,8 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, worklist.push_back(OldSucc); DenseSet ClearSet; - for (std::set, Value*> >::iterator - I = OverDefinedCache.begin(), E = OverDefinedCache.end(); I != E; ++I) { + for (DenseSet::iterator I = OverDefinedCache.begin(), + E = OverDefinedCache.end(); I != E; ++I) { if (I->first == OldSucc) ClearSet.insert(I->second); } @@ -903,7 +970,7 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, for (DenseSet::iterator I = ClearSet.begin(), E = ClearSet.end(); I != E; ++I) { // If a value was marked overdefined in OldSucc, and is here too... - std::set, Value*> >::iterator OI = + DenseSet::iterator OI = OverDefinedCache.find(std::make_pair(ToUpdate, *I)); if (OI == OverDefinedCache.end()) continue;