Skip to content

Commit b672c60

Browse files
committed
[Attributor][NFCI] Merge MemoryEffects explicitly
We had some custom handling for existing MemoryEffects but we now move it to the place we check other existing attributes before we manifest new ones. If we later decide to curb duplication (of attributes on the call site and callee), we can do that at a single location and for all attributes. The test changes basically add known `memory` callee information to the call sites.
1 parent 9987646 commit b672c60

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+582
-627
lines changed

llvm/lib/Transforms/IPO/Attributor.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include "llvm/Support/DebugCounter.h"
4242
#include "llvm/Support/FileSystem.h"
4343
#include "llvm/Support/GraphWriter.h"
44+
#include "llvm/Support/ModRef.h"
4445
#include "llvm/Support/raw_ostream.h"
4546
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
4647
#include "llvm/Transforms/Utils/Cloning.h"
@@ -930,10 +931,23 @@ static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
930931
}
931932
if (Attr.isIntAttribute()) {
932933
Attribute::AttrKind Kind = Attr.getKindAsEnum();
933-
if (Attrs.hasAttributeAtIndex(AttrIdx, Kind))
934+
if (Attrs.hasAttributeAtIndex(AttrIdx, Kind)) {
935+
if (!ForceReplace && Kind == Attribute::Memory) {
936+
MemoryEffects ExistingME =
937+
Attrs.getAttributeAtIndex(AttrIdx, Attribute::Memory)
938+
.getMemoryEffects();
939+
MemoryEffects ME = Attr.getMemoryEffects() & ExistingME;
940+
if (ME == ExistingME)
941+
return false;
942+
Attrs = Attrs.removeAttributeAtIndex(Ctx, AttrIdx, Kind);
943+
Attrs = Attrs.addAttributesAtIndex(Ctx, AttrIdx,
944+
AttrBuilder(Ctx).addMemoryAttr(ME));
945+
return true;
946+
}
934947
if (!ForceReplace &&
935948
isEqualOrWorse(Attr, Attrs.getAttributeAtIndex(AttrIdx, Kind)))
936949
return false;
950+
}
937951
Attrs = Attrs.removeAttributeAtIndex(Ctx, AttrIdx, Kind);
938952
Attrs = Attrs.addAttributeAtIndex(Ctx, AttrIdx, Attr);
939953
return true;

llvm/lib/Transforms/IPO/AttributorAttributes.cpp

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -8006,6 +8006,7 @@ struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
80068006
removeKnownBits(NO_WRITES);
80078007
removeAssumedBits(NO_WRITES);
80088008
}
8009+
getIRPosition().removeAttrs(AttrKinds);
80098010
return AAMemoryBehaviorFloating::manifest(A);
80108011
}
80118012

@@ -8110,16 +8111,9 @@ struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
81108111
else if (isAssumedWriteOnly())
81118112
ME = MemoryEffects::writeOnly();
81128113

8113-
// Intersect with existing memory attribute, as we currently deduce the
8114-
// location and modref portion separately.
8115-
MemoryEffects ExistingME = F.getMemoryEffects();
8116-
ME &= ExistingME;
8117-
if (ME == ExistingME)
8118-
return ChangeStatus::UNCHANGED;
8119-
81208114
return IRAttributeManifest::manifestAttrs(
8121-
A, getIRPosition(), Attribute::getWithMemoryEffects(F.getContext(), ME),
8122-
/*ForceReplace*/ true);
8115+
A, getIRPosition(),
8116+
Attribute::getWithMemoryEffects(F.getContext(), ME));
81238117
}
81248118

81258119
/// See AbstractAttribute::trackStatistics()
@@ -8165,17 +8159,10 @@ struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
81658159
else if (isAssumedWriteOnly())
81668160
ME = MemoryEffects::writeOnly();
81678161

8168-
// Intersect with existing memory attribute, as we currently deduce the
8169-
// location and modref portion separately.
8170-
MemoryEffects ExistingME = CB.getMemoryEffects();
8171-
ME &= ExistingME;
8172-
if (ME == ExistingME)
8173-
return ChangeStatus::UNCHANGED;
8174-
8162+
getIRPosition().removeAttrs(AttrKinds);
81758163
return IRAttributeManifest::manifestAttrs(
81768164
A, getIRPosition(),
8177-
Attribute::getWithMemoryEffects(CB.getContext(), ME),
8178-
/*ForceReplace*/ true);
8165+
Attribute::getWithMemoryEffects(CB.getContext(), ME));
81798166
}
81808167

81818168
/// See AbstractAttribute::trackStatistics()
@@ -8539,22 +8526,9 @@ struct AAMemoryLocationImpl : public AAMemoryLocation {
85398526
return ChangeStatus::UNCHANGED;
85408527
MemoryEffects ME = DeducedAttrs[0].getMemoryEffects();
85418528

8542-
// Intersect with existing memory attribute, as we currently deduce the
8543-
// location and modref portion separately.
8544-
SmallVector<Attribute, 1> ExistingAttrs;
8545-
IRP.getAttrs({Attribute::Memory}, ExistingAttrs,
8546-
/* IgnoreSubsumingPositions */ true);
8547-
if (ExistingAttrs.size() == 1) {
8548-
MemoryEffects ExistingME = ExistingAttrs[0].getMemoryEffects();
8549-
ME &= ExistingME;
8550-
if (ME == ExistingME)
8551-
return ChangeStatus::UNCHANGED;
8552-
}
8553-
85548529
return IRAttributeManifest::manifestAttrs(
85558530
A, IRP,
8556-
Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), ME),
8557-
/*ForceReplace*/ true);
8531+
Attribute::getWithMemoryEffects(IRP.getAnchorValue().getContext(), ME));
85588532
}
85598533

85608534
/// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).

llvm/test/Transforms/Attributor/ArgumentPromotion/2008-07-02-array-indexing.ll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ define i32 @foo(ptr %A) {
4545
; CGSCC: Function Attrs: mustprogress nofree nosync nounwind willreturn memory(argmem: read)
4646
; CGSCC-LABEL: define {{[^@]+}}@foo
4747
; CGSCC-SAME: (ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A:%.*]]) #[[ATTR1:[0-9]+]] {
48-
; CGSCC-NEXT: [[X:%.*]] = call i32 @callee(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]])
48+
; CGSCC-NEXT: [[X:%.*]] = call i32 @callee(ptr nocapture nofree noundef nonnull readonly align 4 dereferenceable(4) [[A]]) #[[ATTR2:[0-9]+]]
4949
; CGSCC-NEXT: ret i32 [[X]]
5050
;
5151
%X = call i32 @callee(i1 false, ptr %A) ; <i32> [#uses=1]
@@ -54,8 +54,9 @@ define i32 @foo(ptr %A) {
5454

5555
;.
5656
; TUNIT: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
57-
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn }
57+
; TUNIT: attributes #[[ATTR1]] = { nofree nosync nounwind willreturn memory(read) }
5858
;.
5959
; CGSCC: attributes #[[ATTR0]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: read) }
6060
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: read) }
61+
; CGSCC: attributes #[[ATTR2]] = { memory(read) }
6162
;.

llvm/test/Transforms/Attributor/ArgumentPromotion/X86/attributes.ll

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ define void @no_promote(ptr %arg) #1 {
2828
; TUNIT-NEXT: bb:
2929
; TUNIT-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
3030
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
31-
; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false)
32-
; TUNIT-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR3:[0-9]+]]
31+
; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3:[0-9]+]]
32+
; TUNIT-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR4:[0-9]+]]
3333
; TUNIT-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
3434
; TUNIT-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
3535
; TUNIT-NEXT: ret void
@@ -40,8 +40,8 @@ define void @no_promote(ptr %arg) #1 {
4040
; CGSCC-NEXT: bb:
4141
; CGSCC-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
4242
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
43-
; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false)
44-
; CGSCC-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR3:[0-9]+]]
43+
; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3:[0-9]+]]
44+
; CGSCC-NEXT: call fastcc void @no_promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], ptr noalias nocapture nofree noundef nonnull readonly align 32 dereferenceable(32) [[TMP]]) #[[ATTR4:[0-9]+]]
4545
; CGSCC-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
4646
; CGSCC-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
4747
; CGSCC-NEXT: ret void
@@ -80,9 +80,9 @@ define void @promote(ptr %arg) #0 {
8080
; TUNIT-NEXT: bb:
8181
; TUNIT-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
8282
; TUNIT-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
83-
; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false)
83+
; TUNIT-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3]]
8484
; TUNIT-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[TMP]], align 32
85-
; TUNIT-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR3]]
85+
; TUNIT-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR4]]
8686
; TUNIT-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
8787
; TUNIT-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
8888
; TUNIT-NEXT: ret void
@@ -93,9 +93,9 @@ define void @promote(ptr %arg) #0 {
9393
; CGSCC-NEXT: bb:
9494
; CGSCC-NEXT: [[TMP:%.*]] = alloca <4 x i64>, align 32
9595
; CGSCC-NEXT: [[TMP2:%.*]] = alloca <4 x i64>, align 32
96-
; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false)
96+
; CGSCC-NEXT: call void @llvm.memset.p0.i64(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP]], i8 noundef 0, i64 noundef 32, i1 noundef false) #[[ATTR3]]
9797
; CGSCC-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[TMP]], align 32
98-
; CGSCC-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR3]]
98+
; CGSCC-NEXT: call fastcc void @promote_avx2(ptr noalias nocapture nofree noundef nonnull writeonly align 32 dereferenceable(32) [[TMP2]], <4 x i64> [[TMP0]]) #[[ATTR4]]
9999
; CGSCC-NEXT: [[TMP4:%.*]] = load <4 x i64>, ptr [[TMP2]], align 32
100100
; CGSCC-NEXT: store <4 x i64> [[TMP4]], ptr [[ARG]], align 2
101101
; CGSCC-NEXT: ret void
@@ -120,10 +120,12 @@ attributes #2 = { argmemonly nounwind }
120120
; TUNIT: attributes #[[ATTR0]] = { inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" }
121121
; TUNIT: attributes #[[ATTR1]] = { mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable }
122122
; TUNIT: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
123-
; TUNIT: attributes #[[ATTR3]] = { nofree nosync nounwind willreturn }
123+
; TUNIT: attributes #[[ATTR3]] = { memory(write) }
124+
; TUNIT: attributes #[[ATTR4]] = { nofree nosync nounwind willreturn }
124125
;.
125126
; CGSCC: attributes #[[ATTR0]] = { inlinehint mustprogress nofree norecurse nosync nounwind willreturn memory(argmem: readwrite) uwtable "target-features"="+avx2" }
126127
; CGSCC: attributes #[[ATTR1]] = { mustprogress nofree nosync nounwind willreturn memory(argmem: readwrite) uwtable }
127128
; CGSCC: attributes #[[ATTR2:[0-9]+]] = { nocallback nofree nounwind willreturn memory(argmem: write) }
128-
; CGSCC: attributes #[[ATTR3]] = { nounwind }
129+
; CGSCC: attributes #[[ATTR3]] = { memory(write) }
130+
; CGSCC: attributes #[[ATTR4]] = { nounwind }
129131
;.

0 commit comments

Comments
 (0)