@@ -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
860860struct 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.
867870ConstantRangeList
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.
897901SmallVector<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 }
0 commit comments