mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-20 19:42:54 +02:00
[Attributor][NFCI] Improve the usage of IntegerStates
Setting the upper bound directly in the state can be beneficial and simplifies the logic. This also exposed more copy&paste type errors.
This commit is contained in:
parent
ec80dede68
commit
7dda5a3585
@ -1146,24 +1146,27 @@ protected:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Specialization of the integer state for a bit-wise encoding.
|
/// Specialization of the integer state for a bit-wise encoding.
|
||||||
struct BitIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
|
template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
|
||||||
using base_t = IntegerStateBase::base_t;
|
base_ty WorstState = 0>
|
||||||
|
struct BitIntegerState
|
||||||
|
: public IntegerStateBase<base_ty, BestState, WorstState> {
|
||||||
|
using base_t = base_ty;
|
||||||
|
|
||||||
/// Return true if the bits set in \p BitsEncoding are "known bits".
|
/// Return true if the bits set in \p BitsEncoding are "known bits".
|
||||||
bool isKnown(base_t BitsEncoding) const {
|
bool isKnown(base_t BitsEncoding) const {
|
||||||
return (Known & BitsEncoding) == BitsEncoding;
|
return (this->Known & BitsEncoding) == BitsEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return true if the bits set in \p BitsEncoding are "assumed bits".
|
/// Return true if the bits set in \p BitsEncoding are "assumed bits".
|
||||||
bool isAssumed(base_t BitsEncoding) const {
|
bool isAssumed(base_t BitsEncoding) const {
|
||||||
return (Assumed & BitsEncoding) == BitsEncoding;
|
return (this->Assumed & BitsEncoding) == BitsEncoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add the bits in \p BitsEncoding to the "known bits".
|
/// Add the bits in \p BitsEncoding to the "known bits".
|
||||||
BitIntegerState &addKnownBits(base_t Bits) {
|
BitIntegerState &addKnownBits(base_t Bits) {
|
||||||
// Make sure we never miss any "known bits".
|
// Make sure we never miss any "known bits".
|
||||||
Assumed |= Bits;
|
this->Assumed |= Bits;
|
||||||
Known |= Bits;
|
this->Known |= Bits;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1174,14 +1177,14 @@ struct BitIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
|
|||||||
|
|
||||||
/// Remove the bits in \p BitsEncoding from the "known bits".
|
/// Remove the bits in \p BitsEncoding from the "known bits".
|
||||||
BitIntegerState &removeKnownBits(base_t BitsEncoding) {
|
BitIntegerState &removeKnownBits(base_t BitsEncoding) {
|
||||||
Known = (Known & ~BitsEncoding);
|
this->Known = (this->Known & ~BitsEncoding);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
|
/// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
|
||||||
BitIntegerState &intersectAssumedBits(base_t BitsEncoding) {
|
BitIntegerState &intersectAssumedBits(base_t BitsEncoding) {
|
||||||
// Make sure we never loose any "known bits".
|
// Make sure we never loose any "known bits".
|
||||||
Assumed = (Assumed & BitsEncoding) | Known;
|
this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1191,32 +1194,35 @@ private:
|
|||||||
}
|
}
|
||||||
void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
|
void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
|
||||||
void joinOR(base_t AssumedValue, base_t KnownValue) override {
|
void joinOR(base_t AssumedValue, base_t KnownValue) override {
|
||||||
Known |= KnownValue;
|
this->Known |= KnownValue;
|
||||||
Assumed |= AssumedValue;
|
this->Assumed |= AssumedValue;
|
||||||
}
|
}
|
||||||
void joinAND(base_t AssumedValue, base_t KnownValue) override {
|
void joinAND(base_t AssumedValue, base_t KnownValue) override {
|
||||||
Known &= KnownValue;
|
this->Known &= KnownValue;
|
||||||
Assumed &= AssumedValue;
|
this->Assumed &= AssumedValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Specialization of the integer state for an increasing value, hence ~0u is
|
/// Specialization of the integer state for an increasing value, hence ~0u is
|
||||||
/// the best state and 0 the worst.
|
/// the best state and 0 the worst.
|
||||||
struct IncIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
|
template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
|
||||||
using base_t = IntegerStateBase::base_t;
|
base_ty WorstState = 0>
|
||||||
|
struct IncIntegerState
|
||||||
|
: public IntegerStateBase<base_ty, BestState, WorstState> {
|
||||||
|
using base_t = base_ty;
|
||||||
|
|
||||||
/// Take minimum of assumed and \p Value.
|
/// Take minimum of assumed and \p Value.
|
||||||
IncIntegerState &takeAssumedMinimum(base_t Value) {
|
IncIntegerState &takeAssumedMinimum(base_t Value) {
|
||||||
// Make sure we never loose "known value".
|
// Make sure we never loose "known value".
|
||||||
Assumed = std::max(std::min(Assumed, Value), Known);
|
this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Take maximum of known and \p Value.
|
/// Take maximum of known and \p Value.
|
||||||
IncIntegerState &takeKnownMaximum(base_t Value) {
|
IncIntegerState &takeKnownMaximum(base_t Value) {
|
||||||
// Make sure we never loose "known value".
|
// Make sure we never loose "known value".
|
||||||
Assumed = std::max(Value, Assumed);
|
this->Assumed = std::max(Value, this->Assumed);
|
||||||
Known = std::max(Value, Known);
|
this->Known = std::max(Value, this->Known);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1226,12 +1232,12 @@ private:
|
|||||||
}
|
}
|
||||||
void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
|
void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
|
||||||
void joinOR(base_t AssumedValue, base_t KnownValue) override {
|
void joinOR(base_t AssumedValue, base_t KnownValue) override {
|
||||||
Known = std::max(Known, KnownValue);
|
this->Known = std::max(this->Known, KnownValue);
|
||||||
Assumed = std::max(Assumed, AssumedValue);
|
this->Assumed = std::max(this->Assumed, AssumedValue);
|
||||||
}
|
}
|
||||||
void joinAND(base_t AssumedValue, base_t KnownValue) override {
|
void joinAND(base_t AssumedValue, base_t KnownValue) override {
|
||||||
Known = std::min(Known, KnownValue);
|
this->Known = std::min(this->Known, KnownValue);
|
||||||
Assumed = std::min(Assumed, AssumedValue);
|
this->Assumed = std::min(this->Assumed, AssumedValue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1752,7 +1758,7 @@ struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute>,
|
|||||||
struct DerefState : AbstractState {
|
struct DerefState : AbstractState {
|
||||||
|
|
||||||
/// State representing for dereferenceable bytes.
|
/// State representing for dereferenceable bytes.
|
||||||
IncIntegerState DerefBytesState;
|
IncIntegerState<> DerefBytesState;
|
||||||
|
|
||||||
/// State representing that whether the value is globaly dereferenceable.
|
/// State representing that whether the value is globaly dereferenceable.
|
||||||
BooleanState GlobalState;
|
BooleanState GlobalState;
|
||||||
@ -1866,10 +1872,12 @@ struct AADereferenceable
|
|||||||
static const char ID;
|
static const char ID;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using AAAlignmentStateType =
|
||||||
|
IncIntegerState<uint32_t, /* maximal alignment */ 1U << 29, 0>;
|
||||||
/// An abstract interface for all align attributes.
|
/// An abstract interface for all align attributes.
|
||||||
struct AAAlign
|
struct AAAlign : public IRAttribute<
|
||||||
: public IRAttribute<Attribute::Alignment,
|
Attribute::Alignment,
|
||||||
StateWrapper<IncIntegerState, AbstractAttribute>> {
|
StateWrapper<AAAlignmentStateType, AbstractAttribute>> {
|
||||||
AAAlign(const IRPosition &IRP) : IRAttribute(IRP) {}
|
AAAlign(const IRPosition &IRP) : IRAttribute(IRP) {}
|
||||||
|
|
||||||
/// Return assumed alignment.
|
/// Return assumed alignment.
|
||||||
@ -1887,8 +1895,9 @@ struct AAAlign
|
|||||||
|
|
||||||
/// An abstract interface for all nocapture attributes.
|
/// An abstract interface for all nocapture attributes.
|
||||||
struct AANoCapture
|
struct AANoCapture
|
||||||
: public IRAttribute<Attribute::NoCapture,
|
: public IRAttribute<
|
||||||
StateWrapper<BitIntegerState, AbstractAttribute>> {
|
Attribute::NoCapture,
|
||||||
|
StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>> {
|
||||||
AANoCapture(const IRPosition &IRP) : IRAttribute(IRP) {}
|
AANoCapture(const IRPosition &IRP) : IRAttribute(IRP) {}
|
||||||
|
|
||||||
/// State encoding bits. A set bit in the state means the property holds.
|
/// State encoding bits. A set bit in the state means the property holds.
|
||||||
@ -1978,8 +1987,9 @@ struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute>,
|
|||||||
|
|
||||||
/// An abstract interface for all memory related attributes.
|
/// An abstract interface for all memory related attributes.
|
||||||
struct AAMemoryBehavior
|
struct AAMemoryBehavior
|
||||||
: public IRAttribute<Attribute::ReadNone,
|
: public IRAttribute<
|
||||||
StateWrapper<BitIntegerState, AbstractAttribute>> {
|
Attribute::ReadNone,
|
||||||
|
StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>> {
|
||||||
AAMemoryBehavior(const IRPosition &IRP) : IRAttribute(IRP) {}
|
AAMemoryBehavior(const IRPosition &IRP) : IRAttribute(IRP) {}
|
||||||
|
|
||||||
/// State encoding bits. A set bit in the state means the property holds.
|
/// State encoding bits. A set bit in the state means the property holds.
|
||||||
|
@ -2700,10 +2700,9 @@ struct AAIsDeadCallSite final : AAIsDeadFunction {
|
|||||||
template <>
|
template <>
|
||||||
ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
|
ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
|
||||||
const DerefState &R) {
|
const DerefState &R) {
|
||||||
ChangeStatus CS0 = clampStateAndIndicateChange<IncIntegerState>(
|
ChangeStatus CS0 =
|
||||||
S.DerefBytesState, R.DerefBytesState);
|
clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
|
||||||
ChangeStatus CS1 =
|
ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
|
||||||
clampStateAndIndicateChange<BooleanState>(S.GlobalState, R.GlobalState);
|
|
||||||
return CS0 | CS1;
|
return CS0 | CS1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2926,13 +2925,8 @@ struct AADereferenceableCallSiteReturned final
|
|||||||
struct AAAlignImpl : AAAlign {
|
struct AAAlignImpl : AAAlign {
|
||||||
AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
|
AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
|
||||||
|
|
||||||
// Max alignemnt value allowed in IR
|
|
||||||
static const unsigned MAX_ALIGN = 1U << 29;
|
|
||||||
|
|
||||||
/// See AbstractAttribute::initialize(...).
|
/// See AbstractAttribute::initialize(...).
|
||||||
void initialize(Attributor &A) override {
|
void initialize(Attributor &A) override {
|
||||||
takeAssumedMinimum(MAX_ALIGN);
|
|
||||||
|
|
||||||
SmallVector<Attribute, 4> Attrs;
|
SmallVector<Attribute, 4> Attrs;
|
||||||
getAttrs({Attribute::Alignment}, Attrs);
|
getAttrs({Attribute::Alignment}, Attrs);
|
||||||
for (const Attribute &Attr : Attrs)
|
for (const Attribute &Attr : Attrs)
|
||||||
@ -3273,7 +3267,7 @@ struct AACaptureUseTracker final : public CaptureTracker {
|
|||||||
/// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
|
/// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
|
||||||
/// conservatively set to true.
|
/// conservatively set to true.
|
||||||
AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
|
AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
|
||||||
const AAIsDead &IsDeadAA, BitIntegerState &State,
|
const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
|
||||||
SmallVectorImpl<const Value *> &PotentialCopies,
|
SmallVectorImpl<const Value *> &PotentialCopies,
|
||||||
unsigned &RemainingUsesToExplore)
|
unsigned &RemainingUsesToExplore)
|
||||||
: A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
|
: A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
|
||||||
@ -3392,7 +3386,7 @@ private:
|
|||||||
const AAIsDead &IsDeadAA;
|
const AAIsDead &IsDeadAA;
|
||||||
|
|
||||||
/// The state currently updated.
|
/// The state currently updated.
|
||||||
BitIntegerState &State;
|
AANoCapture::StateType &State;
|
||||||
|
|
||||||
/// Set of potential copies of the tracked value.
|
/// Set of potential copies of the tracked value.
|
||||||
SmallVectorImpl<const Value *> &PotentialCopies;
|
SmallVectorImpl<const Value *> &PotentialCopies;
|
||||||
@ -3478,6 +3472,8 @@ ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
|
|||||||
AANoCapture::StateType &S = getState();
|
AANoCapture::StateType &S = getState();
|
||||||
auto Assumed = S.getAssumed();
|
auto Assumed = S.getAssumed();
|
||||||
S.intersectAssumedBits(T.getAssumed());
|
S.intersectAssumedBits(T.getAssumed());
|
||||||
|
if (!isAssumedNoCaptureMaybeReturned())
|
||||||
|
return indicatePessimisticFixpoint();
|
||||||
return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
|
return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
|
||||||
: ChangeStatus::CHANGED;
|
: ChangeStatus::CHANGED;
|
||||||
}
|
}
|
||||||
@ -4220,7 +4216,7 @@ struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
|
|||||||
auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
|
auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
|
||||||
return clampStateAndIndicateChange(
|
return clampStateAndIndicateChange(
|
||||||
getState(),
|
getState(),
|
||||||
static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
|
static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See AbstractAttribute::trackStatistics()
|
/// See AbstractAttribute::trackStatistics()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=8 -S < %s | FileCheck %s
|
; RUN: opt -functionattrs -enable-nonnull-arg-prop -attributor -attributor-manifest-internal -attributor-disable=false -attributor-max-iterations-verify -attributor-max-iterations=7 -S < %s | FileCheck %s
|
||||||
;
|
;
|
||||||
; This is an evolved example to stress test SCC parameter attribute propagation.
|
; This is an evolved example to stress test SCC parameter attribute propagation.
|
||||||
; The SCC in this test is made up of the following six function, three of which
|
; The SCC in this test is made up of the following six function, three of which
|
||||||
|
Loading…
Reference in New Issue
Block a user