/// \brief 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 LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom, BasicBlock *BBTo, LVILatticeVal &Result, Instruction *CxtI) { // If already a constant, there is nothing to compute. if (Constant *VC = dyn_cast<Constant>(Val)) { Result = LVILatticeVal::get(VC); return true; } if (getEdgeValueLocal(Val, BBFrom, BBTo, Result)) { if (!Result.isConstantRange() || Result.getConstantRange().getSingleElement()) return true; // FIXME: this check should be moved to the beginning of the function when // LVI better supports recursive values. Even for the single value case, we // can intersect to detect dead code (an empty range). if (!hasBlockValue(Val, BBFrom)) { if (pushBlockValue(std::make_pair(BBFrom, Val))) return false; Result.markOverdefined(); return true; } // Try to intersect ranges of the BB and the constraint on the edge. LVILatticeVal InBlock = getBlockValue(Val, BBFrom); mergeAssumeBlockValueConstantRange(Val, InBlock, BBFrom->getTerminator()); // See note on the use of the CxtI with mergeAssumeBlockValueConstantRange, // and caching, below. mergeAssumeBlockValueConstantRange(Val, InBlock, CxtI); if (!InBlock.isConstantRange()) return true; ConstantRange Range = Result.getConstantRange().intersectWith(InBlock.getConstantRange()); Result = LVILatticeVal::getRange(Range); return true; } if (!hasBlockValue(Val, BBFrom)) { if (pushBlockValue(std::make_pair(BBFrom, Val))) return false; Result.markOverdefined(); return true; } // If we couldn't compute the value on the edge, use the value from the BB. Result = getBlockValue(Val, BBFrom); mergeAssumeBlockValueConstantRange(Val, Result, BBFrom->getTerminator()); // We can use the context instruction (generically the ultimate instruction // the calling pass is trying to simplify) here, even though the result of // this function is generally cached when called from the solve* functions // (and that cached result might be used with queries using a different // context instruction), because when this function is called from the solve* // functions, the context instruction is not provided. When called from // LazyValueInfoCache::getValueOnEdge, the context instruction is provided, // but then the result is not cached. mergeAssumeBlockValueConstantRange(Val, Result, CxtI); return true; }
bool LazyValueInfoCache::solveBlockValueConstantRange(LVILatticeVal &BBLV, Instruction *BBI, BasicBlock *BB) { // Figure out the range of the LHS. If that fails, bail. if (!hasBlockValue(BBI->getOperand(0), BB)) { BlockValueStack.push(std::make_pair(BB, BBI->getOperand(0))); return false; } LVILatticeVal LHSVal = getBlockValue(BBI->getOperand(0), BB); if (!LHSVal.isConstantRange()) { BBLV.markOverdefined(); return true; } ConstantRange LHSRange = LHSVal.getConstantRange(); ConstantRange RHSRange(1); IntegerType *ResultTy = cast<IntegerType>(BBI->getType()); if (isa<BinaryOperator>(BBI)) { if (ConstantInt *RHS = dyn_cast<ConstantInt>(BBI->getOperand(1))) { RHSRange = ConstantRange(RHS->getValue()); } else { BBLV.markOverdefined(); return true; } } // 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. LVILatticeVal Result; switch (BBI->getOpcode()) { case Instruction::Add: Result.markConstantRange(LHSRange.add(RHSRange)); break; case Instruction::Sub: Result.markConstantRange(LHSRange.sub(RHSRange)); break; case Instruction::Mul: Result.markConstantRange(LHSRange.multiply(RHSRange)); break; case Instruction::UDiv: Result.markConstantRange(LHSRange.udiv(RHSRange)); break; case Instruction::Shl: Result.markConstantRange(LHSRange.shl(RHSRange)); break; case Instruction::LShr: Result.markConstantRange(LHSRange.lshr(RHSRange)); break; case Instruction::Trunc: Result.markConstantRange(LHSRange.truncate(ResultTy->getBitWidth())); break; case Instruction::SExt: Result.markConstantRange(LHSRange.signExtend(ResultTy->getBitWidth())); break; case Instruction::ZExt: Result.markConstantRange(LHSRange.zeroExtend(ResultTy->getBitWidth())); break; case Instruction::BitCast: Result.markConstantRange(LHSRange); break; case Instruction::And: Result.markConstantRange(LHSRange.binaryAnd(RHSRange)); break; case Instruction::Or: Result.markConstantRange(LHSRange.binaryOr(RHSRange)); break; // Unhandled instructions are overdefined. default: DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Result.markOverdefined(); break; } BBLV = Result; return true; }
bool LazyValueInfoCache::solveBlockValueNonLocal(LVILatticeVal &BBLV, 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()) { if (isKnownNonNull(Val)) { NotNull = true; } else { 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; } } } } } // If this is the entry block, we must be asking about an argument. The // value is overdefined. if (BB == &BB->getParent()->getEntryBlock()) { assert(isa<Argument>(Val) && "Unknown live-in to the entry block"); if (NotNull) { PointerType *PTy = cast<PointerType>(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } else { Result.markOverdefined(); } BBLV = 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) { PointerType *PTy = cast<PointerType>(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } BBLV = Result; return true; } } if (EdgesMissing) return false; // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined()); BBLV = Result; return true; }
bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { if (isa<Constant>(Val)) return true; if (lookup(Val).count(BB)) { // If we have a cached value, use that. DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << lookup(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 // cached value was inserted. return true; } // Hold off inserting this value into the Cache in case we have to return // false and come back later. LVILatticeVal Res; Instruction *BBI = dyn_cast<Instruction>(Val); if (!BBI || BBI->getParent() != BB) { if (!solveBlockValueNonLocal(Res, Val, BB)) return false; insertResult(Val, BB, Res); return true; } if (PHINode *PN = dyn_cast<PHINode>(BBI)) { if (!solveBlockValuePHINode(Res, PN, BB)) return false; insertResult(Val, BB, Res); return true; } if (AllocaInst *AI = dyn_cast<AllocaInst>(BBI)) { Res = LVILatticeVal::getNot(ConstantPointerNull::get(AI->getType())); insertResult(Val, BB, Res); return 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; if ((!isa<BinaryOperator>(BBI) && !isa<CastInst>(BBI)) || !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI); if (BO && !isa<ConstantInt>(BO->getOperand(1))) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } if (!solveBlockValueConstantRange(Res, BBI, BB)) return false; insertResult(Val, BB, Res); return true; }
/// getEdgeValue - This method attempts to infer more complex 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<Constant>(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<BranchInst>(BBFrom->getTerminator())) { // If this is a conditional branch and only one successor goes to BBTo, then // we maybe able to infer something from the condition. if (BI->isConditional() && BI->getSuccessor(0) != BI->getSuccessor(1)) { bool isTrueDest = BI->getSuccessor(0) == BBTo; assert(BI->getSuccessor(!isTrueDest) == BBTo && "BBTo isn't a successor of BBFrom"); // If V is the condition of the branch itself, then we know exactly what // it is. 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. ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition()); if (ICI && ICI->getOperand(0) == Val && isa<Constant>(ICI->getOperand(1))) { if (ICI->isEquality()) { // We know that V has the RHS constant if this is a true SETEQ or // false SETNE. if (isTrueDest == (ICI->getPredicate() == ICmpInst::ICMP_EQ)) Result = LVILatticeVal::get(cast<Constant>(ICI->getOperand(1))); else Result = LVILatticeVal::getNot(cast<Constant>(ICI->getOperand(1))); return true; } if (ConstantInt *CI = dyn_cast<ConstantInt>(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. 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); return true; } // Find all potential values that satisfy both the input and output // conditions. ConstantRange PossibleValues = TrueValues.intersectWith(InBlock.getConstantRange()); Result = LVILatticeVal::getRange(PossibleValues); return true; } } } } // If the edge was formed by a switch on the value, then we may know exactly // what it is. if (SwitchInst *SI = dyn_cast<SwitchInst>(BBFrom->getTerminator())) { if (SI->getCondition() == Val) { // We don't know anything in the default case. if (SI->getDefaultDest() == BBTo) { Result.markOverdefined(); return true; } // We only know something if there is exactly one value that goes from // BBFrom to BBTo. unsigned NumEdges = 0; ConstantInt *EdgeVal = 0; for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) { if (SI->getSuccessor(i) != BBTo) continue; if (NumEdges++) break; EdgeVal = SI->getCaseValue(i); } assert(EdgeVal && "Missing successor?"); if (NumEdges == 1) { Result = LVILatticeVal::get(EdgeVal); return true; } } } // Otherwise see if the value is known in the block. if (hasBlockValue(Val, BBFrom)) { Result = getBlockValue(Val, BBFrom); return true; } BlockValueStack.push(std::make_pair(BBFrom, Val)); return false; }
LVILatticeVal LVIQuery::getBlockValue(BasicBlock *BB) { // See if we already have a value for this block. LVILatticeVal BBLV = getCachedEntryForBlock(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; } // Otherwise, this is the first time we're seeing this block. Reset the // lattice value to overdefined, so that cycles will terminate and be // conservatively correct. BBLV.markOverdefined(); Cache[BB] = BBLV; Instruction *BBI = dyn_cast<Instruction>(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<LoadInst>(BI); if (L && L->getPointerAddressSpace() == 0 && L->getPointerOperand()->getUnderlyingObject() == Val->getUnderlyingObject()) { 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(*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<PointerType>(Val->getType()); Result = LVILatticeVal::getNot(ConstantPointerNull::get(PTy)); } return Result; } ++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<Argument>(Val) && "Unknown live-in to the entry block"); Result.markOverdefined(); return Result; } // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined()); return Cache[BB] = Result; } // 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<PHINode>(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(Parent.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 Result; } } // Return the merged value, which is more precise than 'overdefined'. assert(!Result.isOverdefined()); return Cache[BB] = Result; } assert(Cache[BB].isOverdefined() && "Recursive query changed our cache?"); // 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; if ((!isa<BinaryOperator>(BBI) && !isa<CastInst>(BBI)) || !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Result.markOverdefined(); return Result; } // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI); if (BO && !isa<ConstantInt>(BO->getOperand(1))) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Result.markOverdefined(); return Result; } // Figure out the range of the LHS. If that fails, bail. LVILatticeVal LHSVal = Parent.getValueInBlock(BBI->getOperand(0), BB); if (!LHSVal.isConstantRange()) { Result.markOverdefined(); return Result; } ConstantInt *RHS = 0; ConstantRange LHSRange = LHSVal.getConstantRange(); ConstantRange RHSRange(1); const IntegerType *ResultTy = cast<IntegerType>(BBI->getType()); if (isa<BinaryOperator>(BBI)) { RHS = dyn_cast<ConstantInt>(BBI->getOperand(1)); if (!RHS) { Result.markOverdefined(); return Result; } 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. switch (BBI->getOpcode()) { case Instruction::Add: Result.markConstantRange(LHSRange.add(RHSRange)); break; case Instruction::Sub: Result.markConstantRange(LHSRange.sub(RHSRange)); break; case Instruction::Mul: Result.markConstantRange(LHSRange.multiply(RHSRange)); break; case Instruction::UDiv: Result.markConstantRange(LHSRange.udiv(RHSRange)); break; case Instruction::Shl: Result.markConstantRange(LHSRange.shl(RHSRange)); break; case Instruction::LShr: Result.markConstantRange(LHSRange.lshr(RHSRange)); break; case Instruction::Trunc: Result.markConstantRange(LHSRange.truncate(ResultTy->getBitWidth())); break; case Instruction::SExt: Result.markConstantRange(LHSRange.signExtend(ResultTy->getBitWidth())); break; case Instruction::ZExt: Result.markConstantRange(LHSRange.zeroExtend(ResultTy->getBitWidth())); break; case Instruction::BitCast: Result.markConstantRange(LHSRange); break; case Instruction::And: Result.markConstantRange(LHSRange.binaryAnd(RHSRange)); break; case Instruction::Or: Result.markConstantRange(LHSRange.binaryOr(RHSRange)); break; // Unhandled instructions are overdefined. default: DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Result.markOverdefined(); break; } return Cache[BB] = Result; }
bool LazyValueInfoCache::solveBlockValue(Value *Val, BasicBlock *BB) { if (isa<Constant>(Val)) return true; if (hasCachedValueInfo(Val, BB)) { // If we have a cached value, use that. DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << 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 // cached value was inserted. return true; } // Hold off inserting this value into the Cache in case we have to return // false and come back later. LVILatticeVal Res; Instruction *BBI = dyn_cast<Instruction>(Val); if (!BBI || BBI->getParent() != BB) { if (!solveBlockValueNonLocal(Res, Val, BB)) return false; insertResult(Val, BB, Res); return true; } if (PHINode *PN = dyn_cast<PHINode>(BBI)) { if (!solveBlockValuePHINode(Res, PN, BB)) return false; insertResult(Val, BB, Res); return true; } // If this value is a nonnull pointer, record it's range and bailout. PointerType *PT = dyn_cast<PointerType>(BBI->getType()); if (PT && isKnownNonNull(BBI)) { Res = LVILatticeVal::getNot(ConstantPointerNull::get(PT)); insertResult(Val, BB, Res); return true; } // If this is an instruction which supports range metadata, return the // implied range. TODO: This should be an intersection, not a union. Res.mergeIn(getFromRangeMetadata(BBI), DL); // 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; if ((!isa<BinaryOperator>(BBI) && !isa<CastInst>(BBI)) || !BBI->getType()->isIntegerTy()) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } // FIXME: We're currently limited to binops with a constant RHS. This should // be improved. BinaryOperator *BO = dyn_cast<BinaryOperator>(BBI); if (BO && !isa<ConstantInt>(BO->getOperand(1))) { DEBUG(dbgs() << " compute BB '" << BB->getName() << "' - overdefined because inst def found.\n"); Res.markOverdefined(); insertResult(Val, BB, Res); return true; } if (!solveBlockValueConstantRange(Res, BBI, BB)) return false; insertResult(Val, BB, Res); return true; }