mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
[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.
This commit is contained in:
parent
a031eae9ff
commit
ab6a6eee6b
@ -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<Value *> 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<Value *> SimplifiedAssociatedValue;
|
||||
};
|
||||
|
||||
/// An abstract interface for value simplify abstract attribute.
|
||||
struct AAValueSimplify : public StateWrapper<BooleanState, AbstractAttribute> {
|
||||
using Base = StateWrapper<BooleanState, AbstractAttribute>;
|
||||
AAValueSimplify(const IRPosition &IRP, Attributor &A) : Base(IRP) {}
|
||||
struct AAValueSimplify
|
||||
: public StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *> {
|
||||
using Base = StateWrapper<ValueSimplifyStateType, AbstractAttribute, Type *>;
|
||||
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,
|
||||
|
@ -579,7 +579,7 @@ Attributor::getAssumedConstant(const Value &V, const AbstractAttribute &AA,
|
||||
AA, IRPosition::value(V, AA.getCallBaseContext()), DepClassTy::NONE);
|
||||
Optional<Value *> 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<AAValueSimplify>(IRP, AA, DepClassTy::NONE);
|
||||
Optional<Value *> SimplifiedV =
|
||||
ValueSimplifyAA.getAssumedSimplifiedValue(*this);
|
||||
bool IsKnown = ValueSimplifyAA.isKnown();
|
||||
bool IsKnown = ValueSimplifyAA.isAtFixpoint();
|
||||
UsedAssumedInformation |= !IsKnown;
|
||||
if (!SimplifiedV.hasValue()) {
|
||||
if (AA)
|
||||
|
@ -4512,6 +4512,32 @@ struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
|
||||
};
|
||||
|
||||
/// ------------------ Value Simplify Attribute ----------------------------
|
||||
|
||||
bool ValueSimplifyStateType::unionAssumed(Optional<Value *> Other) {
|
||||
// FIXME: Add a typecast support.
|
||||
if (!Other.hasValue())
|
||||
return true;
|
||||
|
||||
if (!Other.getValue())
|
||||
return false;
|
||||
|
||||
Value &QueryingValueSimplifiedUnwrapped = *Other.getValue();
|
||||
|
||||
if (SimplifiedAssociatedValue.hasValue() &&
|
||||
!isa<UndefValue>(SimplifiedAssociatedValue.getValue()) &&
|
||||
!isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
|
||||
return SimplifiedAssociatedValue == Other;
|
||||
if (SimplifiedAssociatedValue.hasValue() &&
|
||||
isa<UndefValue>(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<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
|
||||
if (!getAssumed())
|
||||
if (!isValidState())
|
||||
return const_cast<Value *>(&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<Value *> &AccumulatedSimplifiedValue) {
|
||||
// FIXME: Add a typecast support.
|
||||
bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
|
||||
const IRPosition &IRP) {
|
||||
bool UsedAssumedInformation = false;
|
||||
Optional<Value *> QueryingValueSimplified =
|
||||
A.getAssumedSimplified(IRP, QueryingAA, UsedAssumedInformation);
|
||||
|
||||
if (!QueryingValueSimplified.hasValue())
|
||||
return true;
|
||||
|
||||
if (!QueryingValueSimplified.getValue())
|
||||
return false;
|
||||
|
||||
Value &QueryingValueSimplifiedUnwrapped =
|
||||
*QueryingValueSimplified.getValue();
|
||||
|
||||
if (AccumulatedSimplifiedValue.hasValue() &&
|
||||
!isa<UndefValue>(AccumulatedSimplifiedValue.getValue()) &&
|
||||
!isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
|
||||
return AccumulatedSimplifiedValue == QueryingValueSimplified;
|
||||
if (AccumulatedSimplifiedValue.hasValue() &&
|
||||
isa<UndefValue>(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<Value *> SimplifiedAssociatedValue;
|
||||
};
|
||||
|
||||
struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
|
||||
@ -4711,7 +4704,7 @@ struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
|
||||
if (auto *C = dyn_cast<Constant>(&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;
|
||||
|
Loading…
Reference in New Issue
Block a user