@@ -902,6 +902,16 @@ struct DSEState {
902902 });
903903 }
904904
905+ static void pushMemUses (MemoryAccess *Acc,
906+ SmallVectorImpl<MemoryAccess *> &WorkList,
907+ SmallPtrSetImpl<MemoryAccess *> &Visited) {
908+ for (Use &U : Acc->uses ()) {
909+ auto *MA = cast<MemoryAccess>(U.getUser ());
910+ if (Visited.insert (MA).second )
911+ WorkList.push_back (MA);
912+ }
913+ };
914+
905915 LocationSize strengthenLocationSize (const Instruction *I,
906916 LocationSize Size) const {
907917 if (auto *CB = dyn_cast<CallBase>(I)) {
@@ -1157,26 +1167,14 @@ struct DSEState {
11571167 }
11581168
11591169 // / Returns true if \p Def is not read before returning from the function.
1160- bool isWriteAtEndOfFunction (MemoryDef *Def) {
1170+ bool isWriteAtEndOfFunction (MemoryDef *Def, const MemoryLocation &DefLoc ) {
11611171 LLVM_DEBUG (dbgs () << " Check if def " << *Def << " ("
11621172 << *Def->getMemoryInst ()
11631173 << " ) is at the end the function \n " );
1164-
1165- auto MaybeLoc = getLocForWrite (Def->getMemoryInst ());
1166- if (!MaybeLoc) {
1167- LLVM_DEBUG (dbgs () << " ... could not get location for write.\n " );
1168- return false ;
1169- }
1170-
11711174 SmallVector<MemoryAccess *, 4 > WorkList;
11721175 SmallPtrSet<MemoryAccess *, 8 > Visited;
1173- auto PushMemUses = [&WorkList, &Visited](MemoryAccess *Acc) {
1174- if (!Visited.insert (Acc).second )
1175- return ;
1176- for (Use &U : Acc->uses ())
1177- WorkList.push_back (cast<MemoryAccess>(U.getUser ()));
1178- };
1179- PushMemUses (Def);
1176+
1177+ pushMemUses (Def, WorkList, Visited);
11801178 for (unsigned I = 0 ; I < WorkList.size (); I++) {
11811179 if (WorkList.size () >= MemorySSAScanLimit) {
11821180 LLVM_DEBUG (dbgs () << " ... hit exploration limit.\n " );
@@ -1188,22 +1186,22 @@ struct DSEState {
11881186 // AliasAnalysis does not account for loops. Limit elimination to
11891187 // candidates for which we can guarantee they always store to the same
11901188 // memory location.
1191- if (!isGuaranteedLoopInvariant (MaybeLoc-> Ptr ))
1189+ if (!isGuaranteedLoopInvariant (DefLoc. Ptr ))
11921190 return false ;
11931191
1194- PushMemUses (cast<MemoryPhi>(UseAccess));
1192+ pushMemUses (cast<MemoryPhi>(UseAccess), WorkList, Visited );
11951193 continue ;
11961194 }
11971195 // TODO: Checking for aliasing is expensive. Consider reducing the amount
11981196 // of times this is called and/or caching it.
11991197 Instruction *UseInst = cast<MemoryUseOrDef>(UseAccess)->getMemoryInst ();
1200- if (isReadClobber (*MaybeLoc , UseInst)) {
1198+ if (isReadClobber (DefLoc , UseInst)) {
12011199 LLVM_DEBUG (dbgs () << " ... hit read clobber " << *UseInst << " .\n " );
12021200 return false ;
12031201 }
12041202
12051203 if (MemoryDef *UseDef = dyn_cast<MemoryDef>(UseAccess))
1206- PushMemUses (UseDef);
1204+ pushMemUses (UseDef, WorkList, Visited );
12071205 }
12081206 return true ;
12091207 }
@@ -1505,12 +1503,9 @@ struct DSEState {
15051503 LLVM_DEBUG (dbgs () << " Checking for reads of " << *MaybeDeadAccess << " ("
15061504 << *MaybeDeadI << " )\n " );
15071505
1508- SmallSetVector<MemoryAccess *, 32 > WorkList;
1509- auto PushMemUses = [&WorkList](MemoryAccess *Acc) {
1510- for (Use &U : Acc->uses ())
1511- WorkList.insert (cast<MemoryAccess>(U.getUser ()));
1512- };
1513- PushMemUses (MaybeDeadAccess);
1506+ SmallVector<MemoryAccess *, 32 > WorkList;
1507+ SmallPtrSet<MemoryAccess *, 32 > Visited;
1508+ pushMemUses (MaybeDeadAccess, WorkList, Visited);
15141509
15151510 // Check if DeadDef may be read.
15161511 for (unsigned I = 0 ; I < WorkList.size (); I++) {
@@ -1534,7 +1529,7 @@ struct DSEState {
15341529 continue ;
15351530 }
15361531 LLVM_DEBUG (dbgs () << " \n ... adding PHI uses\n " );
1537- PushMemUses (UseAccess);
1532+ pushMemUses (UseAccess, WorkList, Visited );
15381533 continue ;
15391534 }
15401535
@@ -1559,7 +1554,7 @@ struct DSEState {
15591554
15601555 if (isNoopIntrinsic (cast<MemoryUseOrDef>(UseAccess)->getMemoryInst ())) {
15611556 LLVM_DEBUG (dbgs () << " ... adding uses of intrinsic\n " );
1562- PushMemUses (UseAccess);
1557+ pushMemUses (UseAccess, WorkList, Visited );
15631558 continue ;
15641559 }
15651560
@@ -1618,7 +1613,7 @@ struct DSEState {
16181613 return std::nullopt ;
16191614 }
16201615 } else
1621- PushMemUses (UseDef);
1616+ pushMemUses (UseDef, WorkList, Visited );
16221617 }
16231618 }
16241619
@@ -1821,8 +1816,11 @@ struct DSEState {
18211816
18221817 Instruction *DefI = Def->getMemoryInst ();
18231818 auto DefLoc = getLocForWrite (DefI);
1824- if (!DefLoc || !isRemovable (DefI))
1819+ if (!DefLoc || !isRemovable (DefI)) {
1820+ LLVM_DEBUG (dbgs () << " ... could not get location for write or "
1821+ " instruction not removable.\n " );
18251822 continue ;
1823+ }
18261824
18271825 // NOTE: Currently eliminating writes at the end of a function is
18281826 // limited to MemoryDefs with a single underlying object, to save
@@ -1833,7 +1831,7 @@ struct DSEState {
18331831 if (!isInvisibleToCallerAfterRet (UO))
18341832 continue ;
18351833
1836- if (isWriteAtEndOfFunction (Def)) {
1834+ if (isWriteAtEndOfFunction (Def, *DefLoc )) {
18371835 // See through pointer-to-pointer bitcasts
18381836 LLVM_DEBUG (dbgs () << " ... MemoryDef is not accessed until the end "
18391837 " of the function\n " );
0 commit comments