From 44a08d5812a87e8376444d88a8cd5de5b795245e Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sat, 18 Dec 2010 01:00:40 +0000 Subject: [PATCH] Make LazyValueInfo non-recursive. llvm-svn: 122120 --- lib/Analysis/LazyValueInfo.cpp | 383 +++++++++++++++++++++------------ 1 file changed, 250 insertions(+), 133 deletions(-) diff --git a/lib/Analysis/LazyValueInfo.cpp b/lib/Analysis/LazyValueInfo.cpp index eab4ca06f07..bcac49856fa 100644 --- a/lib/Analysis/LazyValueInfo.cpp +++ b/lib/Analysis/LazyValueInfo.cpp @@ -29,6 +29,7 @@ #include "llvm/ADT/STLExtras.h" #include #include +#include using namespace llvm; char LazyValueInfo::ID = 0; @@ -296,8 +297,8 @@ namespace { typedef std::map, LVILatticeVal> ValueCacheEntryTy; private: - /// LVIValueHandle - A callback value handle update the cache when - /// values are erased. + /// LVIValueHandle - A callback value handle update the cache when + /// values are erased. struct LVIValueHandle : public CallbackVH { LazyValueInfoCache *Parent; @@ -319,9 +320,20 @@ namespace { /// for cache updating. std::set, Value*> > OverDefinedCache; - LVILatticeVal &getCachedEntryForBlock(Value *Val, BasicBlock *BB); LVILatticeVal getBlockValue(Value *Val, BasicBlock *BB); - LVILatticeVal getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T); + bool getEdgeValue(Value *V, BasicBlock *F, BasicBlock *T, + LVILatticeVal &Result); + bool hasBlockValue(Value *Val, BasicBlock *BB); + + // These methods process one work item and may add more. A false value + // returned means that the work item was not completely processed and must + // be revisited after going through the new items. + bool solveBlockValue(Value *Val, BasicBlock *BB); + bool solveBlockValueNonLocal(Value *Val, BasicBlock *BB); + bool solveBlockValuePHINode(PHINode *PN, BasicBlock *BB); + bool solveBlockValueConstantRange(Instruction *BBI, BasicBlock *BB); + + void solve(); ValueCacheEntryTy &lookup(Value *V) { return ValueCache[LVIValueHandle(V, this)]; @@ -332,7 +344,17 @@ namespace { if (L.isOverdefined()) OverDefinedCache.insert(std::make_pair(BB, V)); return Cache[BB] = L; } + LVILatticeVal setBlockValue(Value *V, BasicBlock *BB, LVILatticeVal L) { + return setBlockValue(V, BB, L, lookup(V)); + } + struct BlockStackEntry { + BlockStackEntry(Value *Val, BasicBlock *BB) : Val(Val), BB(BB) {} + Value *Val; + BasicBlock *BB; + }; + std::stack block_value_stack; + public: /// getValueInBlock - This is the query interface to determine the lattice /// value for the specified Value* at the end of the specified block. @@ -389,14 +411,41 @@ void LazyValueInfoCache::eraseBlock(BasicBlock *BB) { I->second.erase(BB); } +void LazyValueInfoCache::solve() { + while (!block_value_stack.empty()) { + BlockStackEntry &e = block_value_stack.top(); + if (solveBlockValue(e.Val, e.BB)) + block_value_stack.pop(); + } +} + +bool LazyValueInfoCache::hasBlockValue(Value *Val, BasicBlock *BB) { + // If already a constant, there is nothing to compute. + if (isa(Val)) + return true; + + return lookup(Val).count(BB); +} + LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { + // If already a constant, there is nothing to compute. + if (Constant *VC = dyn_cast(Val)) + return LVILatticeVal::get(VC); + + return lookup(Val)[BB]; +} + +bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { + if (isa(Val)) + return true; + ValueCacheEntryTy &Cache = lookup(Val); LVILatticeVal &BBLV = Cache[BB]; - + // If we've already computed this block's value, return it. if (!BBLV.isUndefined()) { DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n'); - return BBLV; + return true; } // Otherwise, this is the first time we're seeing this block. Reset the @@ -406,87 +455,12 @@ LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { Instruction *BBI = dyn_cast(Val); if (BBI == 0 || BBI->getParent() != BB) { - LVILatticeVal Result; // Start Undefined. - - // If this is a pointer, and there's a load from that pointer in this BB, - // 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){ - LoadInst *L = dyn_cast(BI); - if (L && L->getPointerAddressSpace() == 0 && - GetUnderlyingObject(L->getPointerOperand()) == - GetUnderlyingObject(Val)) { - NotNull = true; - break; - } - } - } - - unsigned NumPreds = 0; - // Loop over all of our predecessors, merging what we know from them into - // result. - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - Result.mergeIn(getEdgeValue(Val, *PI, BB)); - - // 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.\n"); - // 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()); - Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); - } - - return setBlockValue(Val, BB, Result, Cache); - } - ++NumPreds; - } - - - // If this is the entry block, we must be asking about an argument. The - // value is overdefined. - if (NumPreds == 0 && BB == &BB->getParent()->front()) { - assert(isa(Val) && "Unknown live-in to the entry block"); - Result.markOverdefined(); - return setBlockValue(Val, BB, Result, Cache); - } - - // Return the merged value, which is more precise than 'overdefined'. - assert(!Result.isOverdefined()); - return setBlockValue(Val, BB, Result, Cache); - } - - // If this value is defined by an instruction in this block, we have to - // process it here somehow or return overdefined. - if (PHINode *PN = dyn_cast(BBI)) { - LVILatticeVal Result; // Start Undefined. - - // Loop over all of our predecessors, merging what we know from them into - // result. - for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { - Value *PhiVal = PN->getIncomingValueForBlock(*PI); - Result.mergeIn(getValueOnEdge(PhiVal, *PI, BB)); - - // 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.\n"); - return setBlockValue(Val, BB, Result, Cache); - } - } - - // Return the merged value, which is more precise than 'overdefined'. - assert(!Result.isOverdefined()); - return setBlockValue(Val, BB, Result, Cache); + return solveBlockValueNonLocal(Val, BB); } - assert(Cache[BB].isOverdefined() && - "Recursive query changed our cache?"); + if (PHINode *PN = dyn_cast(BBI)) { + return solveBlockValuePHINode(PN, BB); + } // 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. @@ -496,9 +470,10 @@ LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Result.markOverdefined(); - return setBlockValue(Val, BB, Result, Cache); + setBlockValue(Val, BB, Result, Cache); + return true; } - + // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast(BBI); @@ -507,30 +482,155 @@ LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { << "' - overdefined because inst def found.\n"); Result.markOverdefined(); - return setBlockValue(Val, BB, Result, Cache); - } + setBlockValue(Val, BB, Result, Cache); + return true; + } + return solveBlockValueConstantRange(BBI, BB); +} + +static bool InstructionDereferencesPointer(Instruction *I, Value *Ptr) { + if (LoadInst *L = dyn_cast(I)) { + return L->getPointerAddressSpace() == 0 && + GetUnderlyingObject(L->getPointerOperand()) == + GetUnderlyingObject(Ptr); + } + if (StoreInst *S = dyn_cast(I)) { + return S->getPointerAddressSpace() == 0 && + GetUnderlyingObject(S->getPointerOperand()) == + GetUnderlyingObject(Ptr); + } + // FIXME: llvm.memset, etc. + return false; +} + +bool LazyValueInfoCache::solveBlockValueNonLocal(Value *Val, BasicBlock *BB) { + LVILatticeVal Result; // Start Undefined. + + // If this is a pointer, and there's a load from that pointer in this BB, + // 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 this is the entry block, we must be asking about an argument. The + // value is overdefined. + if (BB == &BB->getParent()->getEntryBlock()) { + assert(isa(Val) && "Unknown live-in to the entry block"); + if (NotNull) { + const PointerType *PTy = cast(Val->getType()); + Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); + } else { + Result.markOverdefined(); + } + setBlockValue(Val, BB, Result); + return true; + } + + // Loop over all of our predecessors, merging what we know from them into + // result. + bool EdgesMissing = false; + for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI) { + LVILatticeVal EdgeResult; + EdgesMissing |= !getEdgeValue(Val, *PI, BB, EdgeResult); + if (EdgesMissing) + continue; + + Result.mergeIn(EdgeResult); + + // 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.\n"); + // 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()); + Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); + } + setBlockValue(Val, BB, Result); + return true; + } + } + if (EdgesMissing) + return false; + + // Return the merged value, which is more precise than 'overdefined'. + assert(!Result.isOverdefined()); + setBlockValue(Val, BB, Result); + return true; +} + +bool LazyValueInfoCache::solveBlockValuePHINode(PHINode *PN, BasicBlock *BB) { + LVILatticeVal Result; // Start Undefined. + + // Loop over all of our predecessors, merging what we know from them into + // result. + bool EdgesMissing = false; + for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) { + BasicBlock *PhiBB = PN->getIncomingBlock(i); + Value *PhiVal = PN->getIncomingValue(i); + LVILatticeVal EdgeResult; + EdgesMissing |= !getEdgeValue(PhiVal, PhiBB, BB, EdgeResult); + if (EdgesMissing) + continue; + + Result.mergeIn(EdgeResult); + + // 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.\n"); + setBlockValue(PN, BB, Result); + return true; + } + } + if (EdgesMissing) + return false; + + // Return the merged value, which is more precise than 'overdefined'. + assert(!Result.isOverdefined() && "Possible PHI in entry block?"); + setBlockValue(PN, BB, Result); + return true; +} + +bool LazyValueInfoCache::solveBlockValueConstantRange(Instruction *BBI, + BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. - LVILatticeVal LHSVal = getValueInBlock(BBI->getOperand(0), BB); + if (!hasBlockValue(BBI->getOperand(0), BB)) { + block_value_stack.push(BlockStackEntry(BBI->getOperand(0), BB)); + return false; + } + + LVILatticeVal Result; + LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); if (!LHSVal.isConstantRange()) { Result.markOverdefined(); - return setBlockValue(Val, BB, Result, Cache); + setBlockValue(BBI, BB, Result); + return true; } - ConstantInt *RHS = 0; ConstantRange LHSRange = LHSVal.getConstantRange(); ConstantRange RHSRange(1); const IntegerType *ResultTy = cast(BBI->getType()); if (isa(BBI)) { - RHS = dyn_cast(BBI->getOperand(1)); - if (!RHS) { + if (ConstantInt *RHS = dyn_cast(BBI->getOperand(1))) { + RHSRange = ConstantRange(RHS->getValue()); + } else { Result.markOverdefined(); - return setBlockValue(Val, BB, Result, Cache); + setBlockValue(BBI, BB, Result); + return true; } - - RHSRange = ConstantRange(RHS->getValue(), RHS->getValue()+1); } - + // NOTE: We're currently limited by the set of operations that ConstantRange // can evaluate symbolically. Enhancing that set will allows us to analyze // more definitions. @@ -580,14 +680,19 @@ LVILatticeVal LazyValueInfoCache::getBlockValue(Value *Val, BasicBlock *BB) { break; } - return setBlockValue(Val, BB, Result, Cache); + setBlockValue(BBI, BB, Result); + return true; } - /// getEdgeValue - This method attempts to infer more complex -LVILatticeVal LazyValueInfoCache::getEdgeValue(Value *Val, - BasicBlock *BBFrom, - BasicBlock *BBTo) { +bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom, + BasicBlock *BBTo, LVILatticeVal &Result) { + // If already a constant, there is nothing to compute. + if (Constant *VC = dyn_cast(Val)) { + Result = LVILatticeVal::get(VC); + return true; + } + // TODO: Handle more complex conditionals. If (v == 0 || v2 < 1) is false, we // know that v != 0. if (BranchInst *BI = dyn_cast(BBFrom->getTerminator())) { @@ -601,9 +706,11 @@ LVILatticeVal LazyValueInfoCache::getEdgeValue(Value *Val, // If V is the condition of the branch itself, then we know exactly what // it is. - if (BI->getCondition() == Val) - return LVILatticeVal::get(ConstantInt::get( + if (BI->getCondition() == Val) { + Result = LVILatticeVal::get(ConstantInt::get( Type::getInt1Ty(Val->getContext()), isTrueDest)); + return true; + } // If the condition of the branch is an equality comparison, we may be // able to infer the value. @@ -614,30 +721,35 @@ LVILatticeVal LazyValueInfoCache::getEdgeValue(Value *Val, // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) - return LVILatticeVal::get(cast(ICI->getOperand(1))); - return LVILatticeVal::getNot(cast(ICI->getOperand(1))); + Result = LVILatticeVal::get(cast(ICI->getOperand(1))); + else + Result = LVILatticeVal::getNot(cast(ICI->getOperand(1))); + return true; } - + if (ConstantInt *CI = dyn_cast(ICI->getOperand(1))) { // Calculate the range of values that would satisfy the comparison. ConstantRange CmpRange(CI->getValue(), CI->getValue()+1); ConstantRange TrueValues = ConstantRange::makeICmpRegion(ICI->getPredicate(), CmpRange); - + // If we're interested in the false dest, invert the condition. if (!isTrueDest) TrueValues = TrueValues.inverse(); // Figure out the possible values of the query BEFORE this branch. LVILatticeVal InBlock = getBlockValue(Val, BBFrom); - if (!InBlock.isConstantRange()) - return LVILatticeVal::getRange(TrueValues); - + if (!InBlock.isConstantRange()) { + Result = LVILatticeVal::getRange(TrueValues); + return true; + } + // Find all potential values that satisfy both the input and output // conditions. ConstantRange PossibleValues = TrueValues.intersectWith(InBlock.getConstantRange()); - - return LVILatticeVal::getRange(PossibleValues); + + Result = LVILatticeVal::getRange(PossibleValues); + return true; } } } @@ -649,9 +761,8 @@ LVILatticeVal LazyValueInfoCache::getEdgeValue(Value *Val, if (SI->getCondition() == Val) { // We don't know anything in the default case. if (SI->getDefaultDest() == BBTo) { - LVILatticeVal Result; Result.markOverdefined(); - return Result; + return true; } // We only know something if there is exactly one value that goes from @@ -664,42 +775,48 @@ LVILatticeVal LazyValueInfoCache::getEdgeValue(Value *Val, EdgeVal = SI->getCaseValue(i); } assert(EdgeVal && "Missing successor?"); - if (NumEdges == 1) - return LVILatticeVal::get(EdgeVal); + if (NumEdges == 1) { + Result = LVILatticeVal::get(EdgeVal); + return true; + } } } // Otherwise see if the value is known in the block. - return getBlockValue(Val, BBFrom); + if (hasBlockValue(Val, BBFrom)) { + Result = getBlockValue(Val, BBFrom); + return true; + } + block_value_stack.push(BlockStackEntry(Val, BBFrom)); + return false; } LVILatticeVal LazyValueInfoCache::getValueInBlock(Value *V, BasicBlock *BB) { - // If already a constant, there is nothing to compute. - if (Constant *VC = dyn_cast(V)) - return LVILatticeVal::get(VC); - DEBUG(dbgs() << "LVI Getting block end value " << *V << " at '" << BB->getName() << "'\n"); + block_value_stack.push(BlockStackEntry(V, BB)); + solve(); LVILatticeVal Result = getBlockValue(V, BB); - + DEBUG(dbgs() << " Result = " << Result << "\n"); return Result; } LVILatticeVal LazyValueInfoCache:: getValueOnEdge(Value *V, BasicBlock *FromBB, BasicBlock *ToBB) { - // If already a constant, there is nothing to compute. - if (Constant *VC = dyn_cast(V)) - return LVILatticeVal::get(VC); - DEBUG(dbgs() << "LVI Getting edge value " << *V << " from '" << FromBB->getName() << "' to '" << ToBB->getName() << "'\n"); - LVILatticeVal Result = getEdgeValue(V, FromBB, ToBB); - + LVILatticeVal Result; + if (!getEdgeValue(V, FromBB, ToBB, Result)) { + solve(); + bool WasFastQuery = getEdgeValue(V, FromBB, ToBB, Result); + (void)WasFastQuery; + assert(WasFastQuery && "More work to do after problem solved?"); + } + DEBUG(dbgs() << " Result = " << Result << "\n"); - return Result; } @@ -747,7 +864,7 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, // Remove it from the caches. ValueCacheEntryTy &Entry = ValueCache[LVIValueHandle(*I, this)]; ValueCacheEntryTy::iterator CI = Entry.find(ToUpdate); - + assert(CI != Entry.end() && "Couldn't find entry to update?"); Entry.erase(CI); OverDefinedCache.erase(OI); @@ -756,7 +873,7 @@ void LazyValueInfoCache::threadEdge(BasicBlock *PredBB, BasicBlock *OldSucc, // blocks successors too. changed = true; } - + if (!changed) continue; worklist.insert(worklist.end(), succ_begin(ToUpdate), succ_end(ToUpdate));