Skip to content

Commit 3178424

Browse files
committed
[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.
1 parent 48b4ab4 commit 3178424

File tree

3 files changed

+48
-42
lines changed

3 files changed

+48
-42
lines changed

llvm/include/llvm/Transforms/IPO/Attributor.h

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,24 +1146,27 @@ struct IntegerStateBase : public AbstractState {
11461146
};
11471147

11481148
/// Specialization of the integer state for a bit-wise encoding.
1149-
struct BitIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
1150-
using base_t = IntegerStateBase::base_t;
1149+
template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
1150+
base_ty WorstState = 0>
1151+
struct BitIntegerState
1152+
: public IntegerStateBase<base_ty, BestState, WorstState> {
1153+
using base_t = base_ty;
11511154

11521155
/// Return true if the bits set in \p BitsEncoding are "known bits".
11531156
bool isKnown(base_t BitsEncoding) const {
1154-
return (Known & BitsEncoding) == BitsEncoding;
1157+
return (this->Known & BitsEncoding) == BitsEncoding;
11551158
}
11561159

11571160
/// Return true if the bits set in \p BitsEncoding are "assumed bits".
11581161
bool isAssumed(base_t BitsEncoding) const {
1159-
return (Assumed & BitsEncoding) == BitsEncoding;
1162+
return (this->Assumed & BitsEncoding) == BitsEncoding;
11601163
}
11611164

11621165
/// Add the bits in \p BitsEncoding to the "known bits".
11631166
BitIntegerState &addKnownBits(base_t Bits) {
11641167
// Make sure we never miss any "known bits".
1165-
Assumed |= Bits;
1166-
Known |= Bits;
1168+
this->Assumed |= Bits;
1169+
this->Known |= Bits;
11671170
return *this;
11681171
}
11691172

@@ -1174,14 +1177,14 @@ struct BitIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
11741177

11751178
/// Remove the bits in \p BitsEncoding from the "known bits".
11761179
BitIntegerState &removeKnownBits(base_t BitsEncoding) {
1177-
Known = (Known & ~BitsEncoding);
1180+
this->Known = (this->Known & ~BitsEncoding);
11781181
return *this;
11791182
}
11801183

11811184
/// Keep only "assumed bits" also set in \p BitsEncoding but all known ones.
11821185
BitIntegerState &intersectAssumedBits(base_t BitsEncoding) {
11831186
// Make sure we never loose any "known bits".
1184-
Assumed = (Assumed & BitsEncoding) | Known;
1187+
this->Assumed = (this->Assumed & BitsEncoding) | this->Known;
11851188
return *this;
11861189
}
11871190

@@ -1191,32 +1194,35 @@ struct BitIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
11911194
}
11921195
void handleNewKnownValue(base_t Value) override { addKnownBits(Value); }
11931196
void joinOR(base_t AssumedValue, base_t KnownValue) override {
1194-
Known |= KnownValue;
1195-
Assumed |= AssumedValue;
1197+
this->Known |= KnownValue;
1198+
this->Assumed |= AssumedValue;
11961199
}
11971200
void joinAND(base_t AssumedValue, base_t KnownValue) override {
1198-
Known &= KnownValue;
1199-
Assumed &= AssumedValue;
1201+
this->Known &= KnownValue;
1202+
this->Assumed &= AssumedValue;
12001203
}
12011204
};
12021205

12031206
/// Specialization of the integer state for an increasing value, hence ~0u is
12041207
/// the best state and 0 the worst.
1205-
struct IncIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
1206-
using base_t = IntegerStateBase::base_t;
1208+
template <typename base_ty = uint32_t, base_ty BestState = ~base_ty(0),
1209+
base_ty WorstState = 0>
1210+
struct IncIntegerState
1211+
: public IntegerStateBase<base_ty, BestState, WorstState> {
1212+
using base_t = base_ty;
12071213

12081214
/// Take minimum of assumed and \p Value.
12091215
IncIntegerState &takeAssumedMinimum(base_t Value) {
12101216
// Make sure we never loose "known value".
1211-
Assumed = std::max(std::min(Assumed, Value), Known);
1217+
this->Assumed = std::max(std::min(this->Assumed, Value), this->Known);
12121218
return *this;
12131219
}
12141220

12151221
/// Take maximum of known and \p Value.
12161222
IncIntegerState &takeKnownMaximum(base_t Value) {
12171223
// Make sure we never loose "known value".
1218-
Assumed = std::max(Value, Assumed);
1219-
Known = std::max(Value, Known);
1224+
this->Assumed = std::max(Value, this->Assumed);
1225+
this->Known = std::max(Value, this->Known);
12201226
return *this;
12211227
}
12221228

@@ -1226,12 +1232,12 @@ struct IncIntegerState : public IntegerStateBase<uint32_t, ~0u, 0> {
12261232
}
12271233
void handleNewKnownValue(base_t Value) override { takeKnownMaximum(Value); }
12281234
void joinOR(base_t AssumedValue, base_t KnownValue) override {
1229-
Known = std::max(Known, KnownValue);
1230-
Assumed = std::max(Assumed, AssumedValue);
1235+
this->Known = std::max(this->Known, KnownValue);
1236+
this->Assumed = std::max(this->Assumed, AssumedValue);
12311237
}
12321238
void joinAND(base_t AssumedValue, base_t KnownValue) override {
1233-
Known = std::min(Known, KnownValue);
1234-
Assumed = std::min(Assumed, AssumedValue);
1239+
this->Known = std::min(this->Known, KnownValue);
1240+
this->Assumed = std::min(this->Assumed, AssumedValue);
12351241
}
12361242
};
12371243

@@ -1752,7 +1758,7 @@ struct AAIsDead : public StateWrapper<BooleanState, AbstractAttribute>,
17521758
struct DerefState : AbstractState {
17531759

17541760
/// State representing for dereferenceable bytes.
1755-
IncIntegerState DerefBytesState;
1761+
IncIntegerState<> DerefBytesState;
17561762

17571763
/// State representing that whether the value is globaly dereferenceable.
17581764
BooleanState GlobalState;
@@ -1866,10 +1872,12 @@ struct AADereferenceable
18661872
static const char ID;
18671873
};
18681874

1875+
using AAAlignmentStateType =
1876+
IncIntegerState<uint32_t, /* maximal alignment */ 1U << 29, 0>;
18691877
/// An abstract interface for all align attributes.
1870-
struct AAAlign
1871-
: public IRAttribute<Attribute::Alignment,
1872-
StateWrapper<IncIntegerState, AbstractAttribute>> {
1878+
struct AAAlign : public IRAttribute<
1879+
Attribute::Alignment,
1880+
StateWrapper<AAAlignmentStateType, AbstractAttribute>> {
18731881
AAAlign(const IRPosition &IRP) : IRAttribute(IRP) {}
18741882

18751883
/// Return assumed alignment.
@@ -1887,8 +1895,9 @@ struct AAAlign
18871895

18881896
/// An abstract interface for all nocapture attributes.
18891897
struct AANoCapture
1890-
: public IRAttribute<Attribute::NoCapture,
1891-
StateWrapper<BitIntegerState, AbstractAttribute>> {
1898+
: public IRAttribute<
1899+
Attribute::NoCapture,
1900+
StateWrapper<BitIntegerState<uint16_t, 7, 0>, AbstractAttribute>> {
18921901
AANoCapture(const IRPosition &IRP) : IRAttribute(IRP) {}
18931902

18941903
/// State encoding bits. A set bit in the state means the property holds.
@@ -1978,8 +1987,9 @@ struct AAHeapToStack : public StateWrapper<BooleanState, AbstractAttribute>,
19781987

19791988
/// An abstract interface for all memory related attributes.
19801989
struct AAMemoryBehavior
1981-
: public IRAttribute<Attribute::ReadNone,
1982-
StateWrapper<BitIntegerState, AbstractAttribute>> {
1990+
: public IRAttribute<
1991+
Attribute::ReadNone,
1992+
StateWrapper<BitIntegerState<uint8_t, 3>, AbstractAttribute>> {
19831993
AAMemoryBehavior(const IRPosition &IRP) : IRAttribute(IRP) {}
19841994

19851995
/// State encoding bits. A set bit in the state means the property holds.

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2700,10 +2700,9 @@ struct AAIsDeadCallSite final : AAIsDeadFunction {
27002700
template <>
27012701
ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
27022702
const DerefState &R) {
2703-
ChangeStatus CS0 = clampStateAndIndicateChange<IncIntegerState>(
2704-
S.DerefBytesState, R.DerefBytesState);
2705-
ChangeStatus CS1 =
2706-
clampStateAndIndicateChange<BooleanState>(S.GlobalState, R.GlobalState);
2703+
ChangeStatus CS0 =
2704+
clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
2705+
ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
27072706
return CS0 | CS1;
27082707
}
27092708

@@ -2926,13 +2925,8 @@ struct AADereferenceableCallSiteReturned final
29262925
struct AAAlignImpl : AAAlign {
29272926
AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
29282927

2929-
// Max alignemnt value allowed in IR
2930-
static const unsigned MAX_ALIGN = 1U << 29;
2931-
29322928
/// See AbstractAttribute::initialize(...).
29332929
void initialize(Attributor &A) override {
2934-
takeAssumedMinimum(MAX_ALIGN);
2935-
29362930
SmallVector<Attribute, 4> Attrs;
29372931
getAttrs({Attribute::Alignment}, Attrs);
29382932
for (const Attribute &Attr : Attrs)
@@ -3273,7 +3267,7 @@ struct AACaptureUseTracker final : public CaptureTracker {
32733267
/// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
32743268
/// conservatively set to true.
32753269
AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
3276-
const AAIsDead &IsDeadAA, BitIntegerState &State,
3270+
const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
32773271
SmallVectorImpl<const Value *> &PotentialCopies,
32783272
unsigned &RemainingUsesToExplore)
32793273
: A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
@@ -3392,7 +3386,7 @@ struct AACaptureUseTracker final : public CaptureTracker {
33923386
const AAIsDead &IsDeadAA;
33933387

33943388
/// The state currently updated.
3395-
BitIntegerState &State;
3389+
AANoCapture::StateType &State;
33963390

33973391
/// Set of potential copies of the tracked value.
33983392
SmallVectorImpl<const Value *> &PotentialCopies;
@@ -3478,6 +3472,8 @@ ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
34783472
AANoCapture::StateType &S = getState();
34793473
auto Assumed = S.getAssumed();
34803474
S.intersectAssumedBits(T.getAssumed());
3475+
if (!isAssumedNoCaptureMaybeReturned())
3476+
return indicatePessimisticFixpoint();
34813477
return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
34823478
: ChangeStatus::CHANGED;
34833479
}
@@ -4220,7 +4216,7 @@ struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
42204216
auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
42214217
return clampStateAndIndicateChange(
42224218
getState(),
4223-
static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4219+
static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
42244220
}
42254221

42264222
/// See AbstractAttribute::trackStatistics()

llvm/test/Transforms/FunctionAttrs/read_write_returned_arguments_scc.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
; 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
1+
; 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
22
;
33
; This is an evolved example to stress test SCC parameter attribute propagation.
44
; The SCC in this test is made up of the following six function, three of which

0 commit comments

Comments
 (0)