Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions llvm/include/llvm/Analysis/AssumeBundleQueries.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
42 changes: 12 additions & 30 deletions llvm/lib/Analysis/AssumeBundleQueries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Analysis/Loads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Analysis/ValueTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Transforms/Utils/AssumeBundleBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
Loading