Skip to content

Commit eed0dff

Browse files
committed
Fix loop format, index type, and clean up ArgumentInitInfo struct members
1 parent 002d984 commit eed0dff

File tree

2 files changed

+42
-21
lines changed

2 files changed

+42
-21
lines changed

llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -846,33 +846,37 @@ struct MemoryDefWrapper {
846846
SmallVector<MemoryLocationWrapper, 1> DefinedLocations;
847847
};
848848

849-
bool HasInitializesAttr(Instruction *I) {
849+
bool hasInitializesAttr(Instruction *I) {
850850
CallBase *CB = dyn_cast<CallBase>(I);
851851
if (!CB)
852852
return false;
853853

854-
for (size_t Idx = 0; Idx < CB->arg_size(); Idx++)
854+
for (unsigned Idx = 0, Count = CB->arg_size(); Idx < Count; ++Idx)
855855
if (CB->paramHasAttr(Idx, Attribute::Initializes))
856856
return true;
857857
return false;
858858
}
859859

860860
struct ArgumentInitInfo {
861-
size_t Idx = -1;
861+
unsigned Idx;
862+
bool HasDeadOnUnwindAttr;
862863
ConstantRangeList Inits;
863-
bool HasDeadOnUnwindAttr = false;
864-
bool FuncHasNoUnwindAttr = false;
865864
};
866865

866+
// Return the intersected range list of the initializes attributes of "Args".
867+
// "Args" are call arguments that alias to each other.
868+
// If any argument in "Args" doesn't have dead_on_unwind attr and
869+
// "FuncHasNoUnwindAttr" is false, return empty.
867870
ConstantRangeList
868-
GetMergedInitAttr(const SmallVectorImpl<ArgumentInitInfo> &Args) {
871+
getIntersectedInitRangeList(const SmallVectorImpl<ArgumentInitInfo> &Args,
872+
bool FuncHasNoUnwindAttr) {
869873
if (Args.empty())
870874
return {};
871875

872876
// To address unwind, the function should have nounwind attribute or the
873877
// arguments have dead_on_unwind attribute. Otherwise, return empty.
874878
for (const auto &Arg : Args) {
875-
if (!Arg.FuncHasNoUnwindAttr && !Arg.HasDeadOnUnwindAttr)
879+
if (!FuncHasNoUnwindAttr && !Arg.HasDeadOnUnwindAttr)
876880
return {};
877881
if (Arg.Inits.empty())
878882
return {};
@@ -881,36 +885,35 @@ GetMergedInitAttr(const SmallVectorImpl<ArgumentInitInfo> &Args) {
881885
if (Args.size() == 1)
882886
return Args[0].Inits;
883887

884-
ConstantRangeList MergedIntervals = Args[0].Inits;
885-
for (size_t i = 1; i < Args.size(); i++)
886-
MergedIntervals = MergedIntervals.intersectWith(Args[i].Inits);
888+
ConstantRangeList IntersectedIntervals = Args[0].Inits;
889+
for (unsigned I = 1, Count = Args.size(); I < Count; ++I)
890+
IntersectedIntervals = IntersectedIntervals.intersectWith(Args[I].Inits);
887891

888-
return MergedIntervals;
892+
return IntersectedIntervals;
889893
}
890894

891895
// Return the locations wrote by the initializes attribute.
892896
// Note that this function considers:
893897
// 1. Unwind edge: apply "initializes" attribute only if the callee has
894898
// "nounwind" attribute or the argument has "dead_on_unwind" attribute.
895899
// 2. Argument alias: for aliasing arguments, the "initializes" attribute is
896-
// the merged range list of their "initializes" attributes.
900+
// the intersected range list of their "initializes" attributes.
897901
SmallVector<MemoryLocation, 1>
898-
GetInitializesArgMemLoc(const Instruction *I, BatchAAResults &BatchAA) {
902+
getInitializesArgMemLoc(const Instruction *I, BatchAAResults &BatchAA) {
899903
const CallBase *CB = dyn_cast<CallBase>(I);
900904
if (!CB)
901905
return {};
902906

903907
// Collect aliasing arguments and their initializes ranges.
904-
bool HasNoUnwindAttr = CB->hasFnAttr(Attribute::NoUnwind);
905908
SmallMapVector<Value *, SmallVector<ArgumentInitInfo, 2>, 2> Arguments;
906-
for (size_t Idx = 0; Idx < CB->arg_size(); Idx++) {
909+
for (unsigned Idx = 0, Count = CB->arg_size(); Idx < Count; ++Idx) {
907910
ConstantRangeList Inits;
908911
if (CB->paramHasAttr(Idx, Attribute::Initializes))
909912
Inits = CB->getParamAttr(Idx, Attribute::Initializes)
910913
.getValueAsConstantRangeList();
911914

912915
bool HasDeadOnUnwindAttr = CB->paramHasAttr(Idx, Attribute::DeadOnUnwind);
913-
ArgumentInitInfo InitInfo{Idx, Inits, HasDeadOnUnwindAttr, HasNoUnwindAttr};
916+
ArgumentInitInfo InitInfo{Idx, HasDeadOnUnwindAttr, Inits};
914917
Value *CurArg = CB->getArgOperand(Idx);
915918
bool FoundAliasing = false;
916919
for (auto &[Arg, AliasList] : Arguments) {
@@ -925,14 +928,16 @@ GetInitializesArgMemLoc(const Instruction *I, BatchAAResults &BatchAA) {
925928

926929
SmallVector<MemoryLocation, 1> Locations;
927930
for (const auto &[_, Args] : Arguments) {
928-
auto MergedInitAttr = GetMergedInitAttr(Args);
929-
if (MergedInitAttr.empty())
931+
auto IntersectedRanges =
932+
getIntersectedInitRangeList(Args, CB->hasFnAttr(Attribute::NoUnwind));
933+
if (IntersectedRanges.empty())
930934
continue;
931935

932936
for (const auto &Arg : Args) {
933-
for (const auto &Range : MergedInitAttr) {
937+
for (const auto &Range : IntersectedRanges) {
934938
int64_t Start = Range.getLower().getSExtValue();
935939
int64_t End = Range.getUpper().getSExtValue();
940+
// For now, we only handle locations starting at offset 0.
936941
if (Start == 0)
937942
Locations.push_back(MemoryLocation(CB->getArgOperand(Arg.Idx),
938943
LocationSize::precise(End - Start),
@@ -1021,7 +1026,7 @@ struct DSEState {
10211026
auto *MD = dyn_cast_or_null<MemoryDef>(MA);
10221027
if (MD && MemDefs.size() < MemorySSADefsPerBlockLimit &&
10231028
(getLocForWrite(&I) || isMemTerminatorInst(&I) ||
1024-
HasInitializesAttr(&I)))
1029+
(EnableInitializesImprovement && hasInitializesAttr(&I))))
10251030
MemDefs.push_back(MD);
10261031
}
10271032
}
@@ -1272,7 +1277,7 @@ struct DSEState {
12721277
Locations.push_back(std::make_pair(*Loc, false));
12731278

12741279
if (ConsiderInitializesAttr) {
1275-
for (auto &MemLoc : GetInitializesArgMemLoc(I, BatchAA)) {
1280+
for (auto &MemLoc : getInitializesArgMemLoc(I, BatchAA)) {
12761281
Locations.push_back(std::make_pair(MemLoc, true));
12771282
}
12781283
}

llvm/test/Transforms/DeadStoreElimination/inter-procedural.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ declare void @p1_write_then_read(ptr nocapture noundef initializes((0, 2)) dead_
66
declare void @p2_same_range(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef initializes((0, 2)) dead_on_unwind)
77
declare void @p2_no_init(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef dead_on_unwind)
88
declare void @p2_no_dead_on_unwind(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef initializes((0, 2)))
9+
declare void @p2_no_dead_on_unwind_but_nounwind(ptr nocapture noundef initializes((0, 2)) dead_on_unwind, ptr nocapture noundef initializes((0, 2))) nounwind
910

1011
; Function Attrs: mustprogress nounwind uwtable
1112
define i16 @p1_write_only_caller() {
@@ -102,6 +103,21 @@ define i16 @p2_no_dead_on_unwind_alias_caller() {
102103
ret i16 %l
103104
}
104105

106+
; Function Attrs: mustprogress nounwind uwtable
107+
define i16 @p2_no_dead_on_unwind_but_nounwind_alias_caller() {
108+
; CHECK-LABEL: @p2_no_dead_on_unwind_but_nounwind_alias_caller(
109+
; CHECK-NEXT: %ptr = alloca i16, align 2
110+
; CHECK-NEXT: call void @p2_no_dead_on_unwind_but_nounwind(ptr %ptr, ptr %ptr)
111+
; CHECK-NEXT: %l = load i16, ptr %ptr
112+
; CHECK-NEXT: ret i16 %l
113+
;
114+
%ptr = alloca i16
115+
store i16 0, ptr %ptr
116+
call void @p2_no_dead_on_unwind_but_nounwind(ptr %ptr, ptr %ptr)
117+
%l = load i16, ptr %ptr
118+
ret i16 %l
119+
}
120+
105121
declare void @llvm.memset.p0.i64(ptr nocapture, i8, i64, i1) nounwind
106122
declare void @large_p1(ptr nocapture noundef initializes((0, 200))) nounwind
107123
declare void @large_p2(ptr nocapture noundef initializes((0, 200)), ptr nocapture noundef initializes((0, 100))) nounwind

0 commit comments

Comments
 (0)