From ab6a6eee6bcf67d306722f2fe2cb3307aad36a3a Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Sat, 26 Jun 2021 13:20:28 -0500 Subject: [PATCH] [Attributor][NFCI] Make the state of AAValueSimplify explicit As we have done with other states we want the AAValueSimplify state to be explicit to use it more easily in our helpers. --- include/llvm/Transforms/IPO/Attributor.h | 82 ++++++++++++++++++++- lib/Transforms/IPO/Attributor.cpp | 4 +- lib/Transforms/IPO/AttributorAttributes.cpp | 79 +++++++++----------- 3 files changed, 116 insertions(+), 49 deletions(-) diff --git a/include/llvm/Transforms/IPO/Attributor.h b/include/llvm/Transforms/IPO/Attributor.h index 5449003a98b..393160d8b2e 100644 --- a/include/llvm/Transforms/IPO/Attributor.h +++ b/include/llvm/Transforms/IPO/Attributor.h @@ -3341,10 +3341,86 @@ struct AANoCapture static const char ID; }; +struct ValueSimplifyStateType : public AbstractState { + + ValueSimplifyStateType(Type *Ty) : Ty(Ty) {} + + static ValueSimplifyStateType getBestState(Type *Ty) { + return ValueSimplifyStateType(Ty); + } + static ValueSimplifyStateType getBestState(const ValueSimplifyStateType &VS) { + return getBestState(VS.Ty); + } + + /// Return the worst possible representable state. + static ValueSimplifyStateType getWorstState(Type *Ty) { + ValueSimplifyStateType DS(Ty); + DS.indicatePessimisticFixpoint(); + return DS; + } + static ValueSimplifyStateType + getWorstState(const ValueSimplifyStateType &VS) { + return getWorstState(VS.Ty); + } + + /// See AbstractState::isValidState(...) + bool isValidState() const override { return BS.isValidState(); } + + /// See AbstractState::isAtFixpoint(...) + bool isAtFixpoint() const override { return BS.isAtFixpoint(); } + + /// Return the assumed state encoding. + ValueSimplifyStateType getAssumed() { return *this; } + const ValueSimplifyStateType &getAssumed() const { return *this; } + + /// See AbstractState::indicatePessimisticFixpoint(...) + ChangeStatus indicatePessimisticFixpoint() override { + return BS.indicatePessimisticFixpoint(); + } + + /// See AbstractState::indicateOptimisticFixpoint(...) + ChangeStatus indicateOptimisticFixpoint() override { + return BS.indicateOptimisticFixpoint(); + } + + /// "Clamp" this state with \p PVS. + ValueSimplifyStateType operator^=(const ValueSimplifyStateType &VS) { + BS ^= VS.BS; + unionAssumed(VS.SimplifiedAssociatedValue); + return *this; + } + + bool operator==(const ValueSimplifyStateType &RHS) const { + if (isValidState() != RHS.isValidState()) + return false; + if (!isValidState() && !RHS.isValidState()) + return true; + return SimplifiedAssociatedValue == RHS.SimplifiedAssociatedValue; + } + +protected: + /// The type of the original value. + Type *Ty; + + /// Merge \p Other into the currently assumed simplified value + bool unionAssumed(Optional Other); + + /// Helper to track validity and fixpoint + BooleanState BS; + + /// An assumed simplified value. Initially, it is set to Optional::None, which + /// means that the value is not clear under current assumption. If in the + /// pessimistic state, getAssumedSimplifiedValue doesn't return this value but + /// returns orignal associated value. + Optional SimplifiedAssociatedValue; +}; + /// An abstract interface for value simplify abstract attribute. -struct AAValueSimplify : public StateWrapper { - using Base = StateWrapper; - AAValueSimplify(const IRPosition &IRP, Attributor &A) : Base(IRP) {} +struct AAValueSimplify + : public StateWrapper { + using Base = StateWrapper; + AAValueSimplify(const IRPosition &IRP, Attributor &A) + : Base(IRP, IRP.getAssociatedType()) {} /// Create an abstract attribute view for the position \p IRP. static AAValueSimplify &createForPosition(const IRPosition &IRP, diff --git a/lib/Transforms/IPO/Attributor.cpp b/lib/Transforms/IPO/Attributor.cpp index 47d1bbc607f..71148626537 100644 --- a/lib/Transforms/IPO/Attributor.cpp +++ b/lib/Transforms/IPO/Attributor.cpp @@ -579,7 +579,7 @@ Attributor::getAssumedConstant(const Value &V, const AbstractAttribute &AA, AA, IRPosition::value(V, AA.getCallBaseContext()), DepClassTy::NONE); Optional SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(*this); - bool IsKnown = ValueSimplifyAA.isKnown(); + bool IsKnown = ValueSimplifyAA.isAtFixpoint(); UsedAssumedInformation |= !IsKnown; if (!SimplifiedV.hasValue()) { recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL); @@ -618,7 +618,7 @@ Attributor::getAssumedSimplified(const IRPosition &IRP, getOrCreateAAFor(IRP, AA, DepClassTy::NONE); Optional SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(*this); - bool IsKnown = ValueSimplifyAA.isKnown(); + bool IsKnown = ValueSimplifyAA.isAtFixpoint(); UsedAssumedInformation |= !IsKnown; if (!SimplifiedV.hasValue()) { if (AA) diff --git a/lib/Transforms/IPO/AttributorAttributes.cpp b/lib/Transforms/IPO/AttributorAttributes.cpp index 78c9a6b1ac1..8ae1cff4050 100644 --- a/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/lib/Transforms/IPO/AttributorAttributes.cpp @@ -4512,6 +4512,32 @@ struct AANoCaptureCallSiteReturned final : AANoCaptureImpl { }; /// ------------------ Value Simplify Attribute ---------------------------- + +bool ValueSimplifyStateType::unionAssumed(Optional Other) { + // FIXME: Add a typecast support. + if (!Other.hasValue()) + return true; + + if (!Other.getValue()) + return false; + + Value &QueryingValueSimplifiedUnwrapped = *Other.getValue(); + + if (SimplifiedAssociatedValue.hasValue() && + !isa(SimplifiedAssociatedValue.getValue()) && + !isa(QueryingValueSimplifiedUnwrapped)) + return SimplifiedAssociatedValue == Other; + if (SimplifiedAssociatedValue.hasValue() && + isa(QueryingValueSimplifiedUnwrapped)) + return true; + + LLVM_DEBUG(dbgs() << "[ValueSimplify] is assumed to be " + << QueryingValueSimplifiedUnwrapped << "\n"); + + SimplifiedAssociatedValue = Other; + return true; +} + struct AAValueSimplifyImpl : AAValueSimplify { AAValueSimplifyImpl(const IRPosition &IRP, Attributor &A) : AAValueSimplify(IRP, A) {} @@ -4529,8 +4555,8 @@ struct AAValueSimplifyImpl : AAValueSimplify { if (SimplifiedAssociatedValue) errs() << "SAV: " << **SimplifiedAssociatedValue << " "; }); - return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple") - : "not-simple"; + return isValidState() ? (isAtFixpoint() ? "simplified" : "maybe-simple") + : "not-simple"; } /// See AbstractAttribute::trackStatistics() @@ -4538,45 +4564,19 @@ struct AAValueSimplifyImpl : AAValueSimplify { /// See AAValueSimplify::getAssumedSimplifiedValue() Optional getAssumedSimplifiedValue(Attributor &A) const override { - if (!getAssumed()) + if (!isValidState()) return const_cast(&getAssociatedValue()); return SimplifiedAssociatedValue; } /// Helper function for querying AAValueSimplify and updating candicate. /// \param IRP The value position we are trying to unify with SimplifiedValue - /// \param AccumulatedSimplifiedValue Current simplification result. - static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, - const IRPosition &IRP, - Optional &AccumulatedSimplifiedValue) { - // FIXME: Add a typecast support. + bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA, + const IRPosition &IRP) { bool UsedAssumedInformation = false; Optional QueryingValueSimplified = A.getAssumedSimplified(IRP, QueryingAA, UsedAssumedInformation); - - if (!QueryingValueSimplified.hasValue()) - return true; - - if (!QueryingValueSimplified.getValue()) - return false; - - Value &QueryingValueSimplifiedUnwrapped = - *QueryingValueSimplified.getValue(); - - if (AccumulatedSimplifiedValue.hasValue() && - !isa(AccumulatedSimplifiedValue.getValue()) && - !isa(QueryingValueSimplifiedUnwrapped)) - return AccumulatedSimplifiedValue == QueryingValueSimplified; - if (AccumulatedSimplifiedValue.hasValue() && - isa(QueryingValueSimplifiedUnwrapped)) - return true; - - LLVM_DEBUG(dbgs() << "[ValueSimplify] " << IRP.getAssociatedValue() - << " is assumed to be " - << QueryingValueSimplifiedUnwrapped << "\n"); - - AccumulatedSimplifiedValue = QueryingValueSimplified; - return true; + return unionAssumed(QueryingValueSimplified); } /// Returns a candidate is found or not @@ -4645,13 +4645,6 @@ struct AAValueSimplifyImpl : AAValueSimplify { indicateOptimisticFixpoint(); return ChangeStatus::CHANGED; } - -protected: - // An assumed simplified value. Initially, it is set to Optional::None, which - // means that the value is not clear under current assumption. If in the - // pessimistic state, getAssumedSimplifiedValue doesn't return this value but - // returns orignal associated value. - Optional SimplifiedAssociatedValue; }; struct AAValueSimplifyArgument final : AAValueSimplifyImpl { @@ -4711,7 +4704,7 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl { if (auto *C = dyn_cast(&ArgOp)) if (C->isThreadDependent()) return false; - return checkAndUpdate(A, *this, ACSArgPos, SimplifiedAssociatedValue); + return checkAndUpdate(A, *this, ACSArgPos); }; // Generate a answer specific to a call site context. @@ -4749,8 +4742,7 @@ struct AAValueSimplifyReturned : AAValueSimplifyImpl { auto PredForReturned = [&](Value &V) { return checkAndUpdate(A, *this, - IRPosition::value(V, getCallBaseContext()), - SimplifiedAssociatedValue); + IRPosition::value(V, getCallBaseContext())); }; if (!A.checkForAllReturnedValues(PredForReturned, *this)) @@ -4906,8 +4898,7 @@ struct AAValueSimplifyFloating : AAValueSimplifyImpl { return false; } return checkAndUpdate(A, *this, - IRPosition::value(V, getCallBaseContext()), - SimplifiedAssociatedValue); + IRPosition::value(V, getCallBaseContext())); }; bool Dummy = false;