@@ -195,13 +195,14 @@ SROAMemoryUseAnalyzer::
195195createAllocas (llvm::SmallVector<AllocStackInst *, 4 > &NewAllocations) {
196196 SILBuilderWithScope B (AI);
197197 SILType Type = AI->getType ().getObjectType ();
198+ std::optional<SILDebugVariable> AIDebugVarInfo =
199+ SILDebugVariable::createFromAllocation (AI);
198200
199201 // Intentionally dropping the debug location.
200202 SILLocation Loc = RegularLocation::getAutoGeneratedLocation ();
201203 if (TT) {
202204 for (unsigned EltNo : indices (TT->getElementTypes ())) {
203- std::optional<SILDebugVariable> NewDebugVarInfo =
204- SILDebugVariable::createFromAllocation (AI);
205+ std::optional<SILDebugVariable> NewDebugVarInfo = AIDebugVarInfo;
205206 if (NewDebugVarInfo)
206207 NewDebugVarInfo->DIExpr .append (
207208 SILDebugInfoExpression::createTupleFragment (TT, EltNo));
@@ -215,8 +216,7 @@ createAllocas(llvm::SmallVector<AllocStackInst *, 4> &NewAllocations) {
215216 " this point." );
216217 SILModule &M = AI->getModule ();
217218 for (VarDecl *VD : SD->getStoredProperties ()) {
218- std::optional<SILDebugVariable> NewDebugVarInfo =
219- SILDebugVariable::createFromAllocation (AI);
219+ std::optional<SILDebugVariable> NewDebugVarInfo = AIDebugVarInfo;
220220 if (NewDebugVarInfo)
221221 NewDebugVarInfo->DIExpr .append (
222222 SILDebugInfoExpression::createFragment (VD));
@@ -225,6 +225,10 @@ createAllocas(llvm::SmallVector<AllocStackInst *, 4> &NewAllocations) {
225225 NewDebugVarInfo, AI->hasDynamicLifetime (), AI->isLexical ()));
226226 }
227227 }
228+ if (AIDebugVarInfo && NewAllocations.empty ()) {
229+ // Don't eliminate empty structs, we can use undef as there is no data
230+ B.createDebugValue (Loc, SILUndef::get (AI), *AIDebugVarInfo);
231+ }
228232}
229233
230234void SROAMemoryUseAnalyzer::chopUpAlloca (std::vector<AllocStackInst *> &Worklist) {
@@ -274,7 +278,7 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
274278 }
275279
276280 // Find all dealloc instructions for AI and then chop them up.
277- llvm::SmallVector<DeallocStackInst *, 4 > ToRemove;
281+ llvm::SmallVector<SILInstruction *, 4 > ToRemove;
278282 for (auto *Operand : getNonDebugUses (SILValue (AI))) {
279283 SILInstruction *User = Operand->getUser ();
280284 SILBuilderWithScope B (User);
@@ -290,12 +294,41 @@ void SROAMemoryUseAnalyzer::chopUpAlloca(std::vector<AllocStackInst *> &Worklist
290294 }
291295 }
292296
293- // Remove the old DeallocStackInst instructions.
297+ for (auto *Operand : getDebugUses (SILValue (AI))) {
298+ SILInstruction *User = Operand->getUser ();
299+ auto *DVI = dyn_cast<DebugValueInst>(User);
300+ assert (DVI && " getDebugUses should only return DebugValueInst" );
301+ SILBuilderWithScope B (DVI);
302+ std::optional<SILDebugVariable> DVIVarInfo = DVI->getVarInfo ();
303+ assert (DVIVarInfo && " debug_value without debug info" );
304+
305+ for (size_t i : indices (NewAllocations)) {
306+ auto *NewAI = NewAllocations[i];
307+ SILDebugVariable VarInfo = *DVIVarInfo;
308+ if (TT) {
309+ VarInfo.DIExpr .append (
310+ SILDebugInfoExpression::createTupleFragment (TT, i));
311+ } else {
312+ VarInfo.DIExpr .append (
313+ SILDebugInfoExpression::createFragment (SD->getStoredProperties ()[i]));
314+ }
315+ if (!VarInfo.Type )
316+ VarInfo.Type = AI->getElementType ();
317+ B.createDebugValue (DVI->getLoc (), NewAI, VarInfo);
318+ }
319+ if (NewAllocations.empty ()) {
320+ // Don't eliminate empty structs, we can use undef as there is no data
321+ B.createDebugValue (DVI->getLoc (), SILUndef::get (AI), *DVIVarInfo);
322+ }
323+ ToRemove.push_back (DVI);
324+ }
325+
326+ // Remove the old DeallocStackInst/DebugValueInst instructions.
294327 for (auto *DSI : ToRemove) {
295328 DSI->eraseFromParent ();
296329 }
297330
298- eraseFromParentWithDebugInsts (AI );
331+ AI-> eraseFromParent ( );
299332}
300333
301334// / Returns true, if values of \ty should be ignored, because \p ty is known
0 commit comments