// cache needs updating, i.e. if we have solve a new value or not.
OverDefinedCacheUpdater ODCacheUpdater(Val, BB, BBLV, this);
- // Once this BB is encountered, Val's value for this BB will not be Undefined
- // any longer. When we encounter this BB again, if Val's value is Overdefined,
- // we need to compute its value again.
- //
- // For example, considering this control flow,
- // BB1->BB2, BB1->BB3, BB2->BB3, BB2->BB4
- //
- // Suppose we have "icmp slt %v, 0" in BB1, and "icmp sgt %v, 0" in BB3. At
- // the very beginning, when analyzing edge BB2->BB3, we don't know %v's value
- // in BB2, and the data flow algorithm tries to compute BB2's predecessors, so
- // then we know %v has negative value on edge BB1->BB2. And then we return to
- // check BB2 again, and at this moment BB2 has Overdefined value for %v in
- // BB2. So we should have to follow data flow propagation algorithm to get the
- // value on edge BB1->BB2 propagated to BB2, and finally %v on BB2 has a
- // constant range describing a negative value.
-
- if (!BBLV.isUndefined() && !BBLV.isOverdefined()) {
+ if (!BBLV.isUndefined()) {
DEBUG(dbgs() << " reuse BB '" << BB->getName() << "' val=" << BBLV <<'\n');
// Since we're reusing a cached value here, we don't need to update the
BasicBlock *PhiBB = PN->getIncomingBlock(i);
Value *PhiVal = PN->getIncomingValue(i);
LVILatticeVal EdgeResult;
+ // Note that we can provide PN as the context value to getEdgeValue, even
+ // though the results will be cached, because PN is the value being used as
+ // the cache key in the caller.
EdgesMissing |= !getEdgeValue(PhiVal, PhiBB, BB, EdgeResult, PN);
if (EdgesMissing)
continue;
// 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;
// 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;
}