diff --git a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp --- a/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp +++ b/llvm/lib/Transforms/Scalar/DeadStoreElimination.cpp @@ -1347,13 +1347,11 @@ MemoryAccess *Current = StartAccess; Instruction *KillingI = KillingDef->getMemoryInst(); - bool StepAgain; LLVM_DEBUG(dbgs() << " trying to get dominating access\n"); // Find the next clobbering Mod access for DefLoc, starting at StartAccess. Optional CurrentLoc; - do { - StepAgain = false; + for (;; Current = cast(Current)->getDefiningAccess()) { LLVM_DEBUG({ dbgs() << " visiting " << *Current; if (!MSSA.isLiveOnEntryDef(Current) && isa(Current)) @@ -1391,11 +1389,8 @@ MemoryDef *CurrentDef = cast(Current); Instruction *CurrentI = CurrentDef->getMemoryInst(); - if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); + if (canSkipDef(CurrentDef, !isInvisibleToCallerBeforeRet(DefUO))) continue; - } // Before we try to remove anything, check for any extra throwing // instructions that block us from DSEing @@ -1431,27 +1426,19 @@ // If Current cannot be analyzed or is not removable, check the next // candidate. - if (!hasAnalyzableMemoryWrite(CurrentI, TLI) || !isRemovable(CurrentI)) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); + if (!hasAnalyzableMemoryWrite(CurrentI, TLI) || !isRemovable(CurrentI)) continue; - } // If Current does not have an analyzable write location, skip it CurrentLoc = getLocForWriteEx(CurrentI); - if (!CurrentLoc) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); + if (!CurrentLoc) continue; - } // AliasAnalysis does not account for loops. Limit elimination to // candidates for which we can guarantee they always store to the same // memory location and not located in different loops. if (!isGuaranteedLoopIndependent(CurrentI, KillingI, *CurrentLoc)) { LLVM_DEBUG(dbgs() << " ... not guaranteed loop independent\n"); - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); WalkerStepLimit -= 1; continue; } @@ -1460,35 +1447,30 @@ // If the killing def is a memory terminator (e.g. lifetime.end), check // the next candidate if the current Current does not write the same // underlying object as the terminator. - if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); - } - continue; + if (!isMemTerminator(*CurrentLoc, CurrentI, KillingI)) + continue; } else { int64_t InstWriteOffset, DepWriteOffset; auto OR = isOverwrite(KillingI, CurrentI, DefLoc, *CurrentLoc, DepWriteOffset, InstWriteOffset); // If Current does not write to the same object as KillingDef, check // the next candidate. - if (OR == OW_Unknown) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); - } else if (OR == OW_MaybePartial) { + if (OR == OW_Unknown) + continue; + else if (OR == OW_MaybePartial) { // If KillingDef only partially overwrites Current, check the next // candidate if the partial step limit is exceeded. This aggressively // limits the number of candidates for partial store elimination, // which are less likely to be removable in the end. if (PartialLimit <= 1) { - StepAgain = true; - Current = CurrentDef->getDefiningAccess(); WalkerStepLimit -= 1; continue; } PartialLimit -= 1; } } - } while (StepAgain); + break; + }; // Accesses to objects accessible after the function returns can only be // eliminated if the access is killed along all paths to the exit. Collect