本文整理汇总了C++中LVILatticeVal::mergeIn方法的典型用法代码示例。如果您正苦于以下问题:C++ LVILatticeVal::mergeIn方法的具体用法?C++ LVILatticeVal::mergeIn怎么用?C++ LVILatticeVal::mergeIn使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类LVILatticeVal
的用法示例。
在下文中一共展示了LVILatticeVal::mergeIn方法的5个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: solveBlockValuePHINode
bool LazyValueInfoCache::solveBlockValuePHINode(LVILatticeVal &BBLV,
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");
BBLV = 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?");
BBLV = Result;
return true;
}
示例2: mergeAssumeBlockValueConstantRange
// If we can determine a constant range for the value Val in the context
// provided by the instruction BBI, then merge it into BBLV. If we did find a
// constant range, return true.
void LazyValueInfoCache::mergeAssumeBlockValueConstantRange(Value *Val,
LVILatticeVal &BBLV,
Instruction *BBI) {
BBI = BBI ? BBI : dyn_cast<Instruction>(Val);
if (!BBI)
return;
for (auto &AssumeVH : AC->assumptions()) {
if (!AssumeVH)
continue;
auto *I = cast<CallInst>(AssumeVH);
if (!isValidAssumeForContext(I, BBI, DL, DT))
continue;
Value *C = I->getArgOperand(0);
if (ICmpInst *ICI = dyn_cast<ICmpInst>(C)) {
LVILatticeVal Result;
if (getValueFromFromCondition(Val, ICI, Result)) {
if (BBLV.isOverdefined())
BBLV = Result;
else
BBLV.mergeIn(Result);
}
}
}
}
示例3: solveBlockValueNonLocal
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;
}
示例4: getBlockValue
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
//.........这里部分代码省略.........
示例5: solveBlockValue
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;
}