Analysis: Remove no-AssumptionCache path in getKnowledgeForValue (#139232)
As requested in https://github.com/llvm/llvm-project/pull/138961#discussion_r2078483175
This commit is contained in:
@@ -152,18 +152,19 @@ RetainedKnowledge getKnowledgeFromUse(const Use *U,
|
||||
/// in AttrKinds and it matches the Filter.
|
||||
RetainedKnowledge getKnowledgeForValue(
|
||||
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
|
||||
AssumptionCache *AC = nullptr,
|
||||
AssumptionCache &AC,
|
||||
function_ref<bool(RetainedKnowledge, Instruction *,
|
||||
const CallBase::BundleOpInfo *)>
|
||||
const CallBase::BundleOpInfo *)>
|
||||
Filter = [](auto...) { return true; });
|
||||
|
||||
/// Return a valid Knowledge associated to the Value V if its Attribute kind is
|
||||
/// in AttrKinds and the knowledge is suitable to be used in the context of
|
||||
/// CtxI.
|
||||
RetainedKnowledge getKnowledgeValidInContext(
|
||||
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
|
||||
const Instruction *CtxI, const DominatorTree *DT = nullptr,
|
||||
AssumptionCache *AC = nullptr);
|
||||
RetainedKnowledge
|
||||
getKnowledgeValidInContext(const Value *V,
|
||||
ArrayRef<Attribute::AttrKind> AttrKinds,
|
||||
AssumptionCache &AC, const Instruction *CtxI,
|
||||
const DominatorTree *DT = nullptr);
|
||||
|
||||
/// This extracts the Knowledge from an element of an operand bundle.
|
||||
/// This is mostly for use in the assume builder.
|
||||
|
||||
@@ -157,51 +157,33 @@ llvm::getKnowledgeFromUse(const Use *U,
|
||||
RetainedKnowledge
|
||||
llvm::getKnowledgeForValue(const Value *V,
|
||||
ArrayRef<Attribute::AttrKind> AttrKinds,
|
||||
AssumptionCache *AC,
|
||||
AssumptionCache &AC,
|
||||
function_ref<bool(RetainedKnowledge, Instruction *,
|
||||
const CallBase::BundleOpInfo *)>
|
||||
Filter) {
|
||||
NumAssumeQueries++;
|
||||
if (AC) {
|
||||
for (AssumptionCache::ResultElem &Elem : AC->assumptionsFor(V)) {
|
||||
auto *II = cast_or_null<AssumeInst>(Elem.Assume);
|
||||
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
|
||||
continue;
|
||||
if (RetainedKnowledge RK = getKnowledgeFromBundle(
|
||||
*II, II->bundle_op_info_begin()[Elem.Index])) {
|
||||
if (V != RK.WasOn)
|
||||
continue;
|
||||
if (is_contained(AttrKinds, RK.AttrKind) &&
|
||||
Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
|
||||
NumUsefullAssumeQueries++;
|
||||
return RK;
|
||||
}
|
||||
}
|
||||
}
|
||||
return RetainedKnowledge::none();
|
||||
}
|
||||
|
||||
if (!V->hasUseList())
|
||||
return RetainedKnowledge::none();
|
||||
|
||||
for (const auto &U : V->uses()) {
|
||||
CallInst::BundleOpInfo* Bundle = getBundleFromUse(&U);
|
||||
if (!Bundle)
|
||||
for (AssumptionCache::ResultElem &Elem : AC.assumptionsFor(V)) {
|
||||
auto *II = cast_or_null<AssumeInst>(Elem.Assume);
|
||||
if (!II || Elem.Index == AssumptionCache::ExprResultIdx)
|
||||
continue;
|
||||
if (RetainedKnowledge RK =
|
||||
getKnowledgeFromBundle(*cast<AssumeInst>(U.getUser()), *Bundle))
|
||||
if (RetainedKnowledge RK = getKnowledgeFromBundle(
|
||||
*II, II->bundle_op_info_begin()[Elem.Index])) {
|
||||
if (V != RK.WasOn)
|
||||
continue;
|
||||
if (is_contained(AttrKinds, RK.AttrKind) &&
|
||||
Filter(RK, cast<Instruction>(U.getUser()), Bundle)) {
|
||||
Filter(RK, II, &II->bundle_op_info_begin()[Elem.Index])) {
|
||||
NumUsefullAssumeQueries++;
|
||||
return RK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RetainedKnowledge::none();
|
||||
}
|
||||
|
||||
RetainedKnowledge llvm::getKnowledgeValidInContext(
|
||||
const Value *V, ArrayRef<Attribute::AttrKind> AttrKinds,
|
||||
const Instruction *CtxI, const DominatorTree *DT, AssumptionCache *AC) {
|
||||
AssumptionCache &AC, const Instruction *CtxI, const DominatorTree *DT) {
|
||||
return getKnowledgeForValue(V, AttrKinds, AC,
|
||||
[&](auto, Instruction *I, auto) {
|
||||
return isValidAssumeForContext(I, CtxI, DT);
|
||||
|
||||
@@ -174,14 +174,14 @@ static bool isDereferenceableAndAlignedPointer(
|
||||
// information for values that cannot be freed in the function.
|
||||
// TODO: More precisely check if the pointer can be freed between assumption
|
||||
// and use.
|
||||
if (CtxI && !V->canBeFreed()) {
|
||||
if (CtxI && AC && !V->canBeFreed()) {
|
||||
/// Look through assumes to see if both dereferencability and alignment can
|
||||
/// be proven by an assume if needed.
|
||||
RetainedKnowledge AlignRK;
|
||||
RetainedKnowledge DerefRK;
|
||||
bool IsAligned = V->getPointerAlignment(DL) >= Alignment;
|
||||
if (getKnowledgeForValue(
|
||||
V, {Attribute::Dereferenceable, Attribute::Alignment}, AC,
|
||||
V, {Attribute::Dereferenceable, Attribute::Alignment}, *AC,
|
||||
[&](RetainedKnowledge RK, Instruction *Assume, auto) {
|
||||
if (!isValidAssumeForContext(Assume, CtxI, DT))
|
||||
return false;
|
||||
|
||||
@@ -8010,7 +8010,7 @@ static bool isGuaranteedNotToBeUndefOrPoison(
|
||||
Dominator = Dominator->getIDom();
|
||||
}
|
||||
|
||||
if (getKnowledgeValidInContext(V, {Attribute::NoUndef}, CtxI, DT, AC))
|
||||
if (AC && getKnowledgeValidInContext(V, {Attribute::NoUndef}, *AC, CtxI, DT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
||||
@@ -114,12 +114,12 @@ struct AssumeBuilderState {
|
||||
: M(M), InstBeingModified(I), AC(AC), DT(DT) {}
|
||||
|
||||
bool tryToPreserveWithoutAddingAssume(RetainedKnowledge RK) {
|
||||
if (!InstBeingModified || !RK.WasOn)
|
||||
if (!InstBeingModified || !RK.WasOn || !AC)
|
||||
return false;
|
||||
bool HasBeenPreserved = false;
|
||||
Use* ToUpdate = nullptr;
|
||||
getKnowledgeForValue(
|
||||
RK.WasOn, {RK.AttrKind}, AC,
|
||||
RK.WasOn, {RK.AttrKind}, *AC,
|
||||
[&](RetainedKnowledge RKOther, Instruction *Assume,
|
||||
const CallInst::BundleOpInfo *Bundle) {
|
||||
if (!isValidAssumeForContext(Assume, InstBeingModified, DT))
|
||||
|
||||
Reference in New Issue
Block a user