summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/Attributor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/Attributor.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/Attributor.cpp186
1 files changed, 83 insertions, 103 deletions
diff --git a/llvm/lib/Transforms/IPO/Attributor.cpp b/llvm/lib/Transforms/IPO/Attributor.cpp
index ee3541b7c1d..76f6405eb62 100644
--- a/llvm/lib/Transforms/IPO/Attributor.cpp
+++ b/llvm/lib/Transforms/IPO/Attributor.cpp
@@ -139,7 +139,7 @@ ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
template <typename AAType, typename StateTy>
bool genericValueTraversal(
Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
- const function_ref<void(Value &, StateTy &, bool)> &VisitValueCB,
+ const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
int MaxValues = 8) {
const AAIsDead *LivenessAA = nullptr;
@@ -204,7 +204,8 @@ bool genericValueTraversal(
}
// Once a leaf is reached we inform the user through the callback.
- VisitValueCB(*V, State, Iteration > 1);
+ if (!VisitValueCB(*V, State, Iteration > 1))
+ return false;
} while (!Worklist.empty());
// All values have been visited.
@@ -468,6 +469,12 @@ ChangeStatus clampStateAndIndicateChange<IntegerState>(IntegerState &S,
return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
: ChangeStatus::CHANGED;
}
+
+template <>
+ChangeStatus clampStateAndIndicateChange<BooleanState>(BooleanState &S,
+ const BooleanState &R) {
+ return clampStateAndIndicateChange<IntegerState>(S, R);
+}
///}
/// Clamp the information known for all returned values of a function
@@ -888,7 +895,7 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
};
// Callback for a leaf value returned by the associated function.
- auto VisitValueCB = [](Value &Val, RVState &RVS, bool) {
+ auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
auto Size = RVS.RetValsMap[&Val].size();
RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
bool Inserted = RVS.RetValsMap[&Val].size() != Size;
@@ -898,6 +905,7 @@ ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
<< " => " << RVS.RetInsts.size() << "\n";
});
+ return true;
};
// Helper method to invoke the generic value traversal.
@@ -1245,141 +1253,111 @@ using AANoFreeCallSite = AANoFreeFunction;
struct AANonNullImpl : AANonNull {
AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {}
- /// See AbstractAttribute::getAsStr().
- const std::string getAsStr() const override {
- return getAssumed() ? "nonnull" : "may-null";
- }
-
/// See AbstractAttribute::initialize(...).
void initialize(Attributor &A) override {
if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
indicateOptimisticFixpoint();
}
- /// Generate a predicate that checks if a given value is assumed nonnull.
- /// The generated function returns true if a value satisfies any of
- /// following conditions.
- /// (i) A value is known nonZero(=nonnull).
- /// (ii) A value is associated with AANonNull and its isAssumedNonNull() is
- /// true.
- std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
- generatePredicate(Attributor &);
+ /// See AbstractAttribute::getAsStr().
+ const std::string getAsStr() const override {
+ return getAssumed() ? "nonnull" : "may-null";
+ }
};
-std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
-AANonNullImpl::generatePredicate(Attributor &A) {
- // FIXME: The `AAReturnedValues` should provide the predicate with the
- // `ReturnInst` vector as well such that we can use the control flow sensitive
- // version of `isKnownNonZero`. This should fix `test11` in
- // `test/Transforms/FunctionAttrs/nonnull.ll`
-
- std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
- [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
- if (isKnownNonZero(&RV, A.getDataLayout()))
- return true;
+/// NonNull attribute for a floating value.
+struct AANonNullFloating : AANonNullImpl {
+ AANonNullFloating(const IRPosition &IRP) : AANonNullImpl(IRP) {}
- if (ImmutableCallSite ICS = ImmutableCallSite(&RV))
- if (ICS.hasRetAttr(Attribute::NonNull))
- return true;
+ /// See AbstractAttribute::initialize(...).
+ void initialize(Attributor &A) override {
+ AANonNullImpl::initialize(A);
- auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(RV));
- return (NonNullAA && NonNullAA->isAssumedNonNull());
- };
+ if (isAtFixpoint())
+ return;
- return Pred;
-}
+ const IRPosition &IRP = getIRPosition();
+ const Value &V = IRP.getAssociatedValue();
+ const DataLayout &DL = A.getDataLayout();
-/// NonNull attribute for function return value.
-struct AANonNullReturned final : AANonNullImpl {
- AANonNullReturned(const IRPosition &IRP) : AANonNullImpl(IRP) {}
+ // TODO: This context sensitive query should be removed once we can do
+ // context sensitive queries in the genericValueTraversal below.
+ if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(),
+ /* TODO: DT */ nullptr))
+ indicateOptimisticFixpoint();
+ }
/// See AbstractAttribute::updateImpl(...).
ChangeStatus updateImpl(Attributor &A) override {
- std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
- this->generatePredicate(A);
+ const DataLayout &DL = A.getDataLayout();
- if (!A.checkForAllReturnedValuesAndReturnInsts(Pred, *this))
+ auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
+ bool Stripped) -> bool {
+ if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr,
+ /* TODO: CtxI */ nullptr,
+ /* TODO: DT */ nullptr)) {
+ // Known non-zero, all good.
+ } else if (const auto *AA =
+ A.getAAFor<AANonNull>(*this, IRPosition::value(V))) {
+ // Try to use abstract attribute information.
+ if (!AA->isAssumedNonNull())
+ T.indicatePessimisticFixpoint();
+ } else {
+ // IR information was not sufficient and we did not find an abstract
+ // attribute to use. TODO: on-demand attribute creation!
+ T.indicatePessimisticFixpoint();
+ }
+ return T.isValidState();
+ };
+
+ StateType T;
+ if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
+ T, VisitValueCB))
return indicatePessimisticFixpoint();
- return ChangeStatus::UNCHANGED;
+
+ return clampStateAndIndicateChange(getState(), T);
}
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
};
-/// NonNull attribute for function argument.
-struct AANonNullArgument final : AANonNullImpl {
- AANonNullArgument(const IRPosition &IRP) : AANonNullImpl(IRP) {}
-
- /// See AbstractAttribute::updateImpl(...).
- ChangeStatus updateImpl(Attributor &A) override {
- unsigned ArgNo = getArgNo();
-
- // Callback function
- std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
- assert(CS && "Sanity check: Call site was not initialized properly!");
-
- IRPosition CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
- if (CSArgPos.hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
- return true;
-
- // Check that NonNullAA is AANonNullCallSiteArgument.
- if (auto *NonNullAA = A.getAAFor<AANonNullImpl>(*this, CSArgPos)) {
- ImmutableCallSite ICS(&NonNullAA->getAnchorValue());
- if (ICS && CS.getInstruction() == ICS.getInstruction())
- return NonNullAA->isAssumedNonNull();
- return false;
- }
+/// NonNull attribute for function return value.
+struct AANonNullReturned final : AAReturnedFromReturnedValues<AANonNullImpl> {
+ AANonNullReturned(const IRPosition &IRP)
+ : AAReturnedFromReturnedValues<AANonNullImpl>(IRP) {}
- Value *V = CS.getArgOperand(ArgNo);
- if (isKnownNonZero(V, A.getDataLayout()))
- return true;
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
+};
- return false;
- };
- if (!A.checkForAllCallSites(CallSiteCheck, *this, true))
- return indicatePessimisticFixpoint();
- return ChangeStatus::UNCHANGED;
- }
+/// NonNull attribute for function argument.
+struct AANonNullArgument final
+ : AAArgumentFromCallSiteArguments<AANonNullImpl> {
+ AANonNullArgument(const IRPosition &IRP)
+ : AAArgumentFromCallSiteArguments<AANonNullImpl>(IRP) {}
/// See AbstractAttribute::trackStatistics()
void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
};
-/// NonNull attribute for a call site argument.
-struct AANonNullCallSiteArgument final : AANonNullImpl {
- AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullImpl(IRP) {}
-
- /// See AbstractAttribute::initialize(...).
- void initialize(Attributor &A) override {
- AANonNullImpl::initialize(A);
- if (!isKnownNonNull() &&
- isKnownNonZero(&getAssociatedValue(), A.getDataLayout()))
- indicateOptimisticFixpoint();
- }
+struct AANonNullCallSiteArgument final : AANonNullFloating {
+ AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
- /// See AbstractAttribute::updateImpl(Attributor &A).
- ChangeStatus updateImpl(Attributor &A) override {
- // NOTE: Never look at the argument of the callee in this method.
- // If we do this, "nonnull" is always deduced because of the
- // assumption.
-
- Value &V = getAssociatedValue();
- auto *NonNullAA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
-
- if (!NonNullAA || !NonNullAA->isAssumedNonNull())
- return indicatePessimisticFixpoint();
+ /// See AbstractAttribute::trackStatistics()
+ void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
+};
- return ChangeStatus::UNCHANGED;
- }
+/// NonNull attribute for a call site return position.
+struct AANonNullCallSiteReturned final
+ : AACallSiteReturnedFromReturned<AANonNullImpl> {
+ AANonNullCallSiteReturned(const IRPosition &IRP)
+ : AACallSiteReturnedFromReturned<AANonNullImpl>(IRP) {}
/// See AbstractAttribute::trackStatistics()
- void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
+ void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
};
-/// NonNull attribute deduction for a call sites.
-using AANonNullCallSiteReturned = AANonNullReturned;
-
/// ------------------------ No-Recurse Attributes ----------------------------
struct AANoRecurseImpl : public AANoRecurse {
@@ -2245,7 +2223,8 @@ struct AAAlignFloating : AAAlignImpl {
ChangeStatus updateImpl(Attributor &A) override {
const DataLayout &DL = A.getDataLayout();
- auto VisitValueCB = [&](Value &V, AAAlign::StateType &T, bool Stripped) {
+ auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
+ bool Stripped) -> bool {
if (!Stripped &&
getIRPosition().getPositionKind() == IRPosition::IRP_FLOAT) {
// Use only IR information if we did not strip anything.
@@ -2262,6 +2241,7 @@ struct AAAlignFloating : AAAlignImpl {
T.takeKnownMaximum(V.getPointerAlignment(DL));
T.indicatePessimisticFixpoint();
}
+ return T.isValidState();
};
StateType T;
OpenPOWER on IntegriCloud