@@ -315,11 +315,18 @@ calculateFragment(DILocalVariable *Variable,
315
315
return UseFrag;
316
316
}
317
317
318
+ static DebugVariable getAggregateVariable (DbgVariableIntrinsic *DVI) {
319
+ return DebugVariable (DVI->getVariable (), std::nullopt,
320
+ DVI->getDebugLoc ().getInlinedAt ());
321
+ }
318
322
static DebugVariable getAggregateVariable (DbgVariableRecord *DVR) {
319
323
return DebugVariable (DVR->getVariable (), std::nullopt,
320
324
DVR->getDebugLoc ().getInlinedAt ());
321
325
}
322
326
327
+ // / Helpers for handling new and old debug info modes in migrateDebugInfo.
328
+ // / These overloads unwrap a DbgInstPtr {Instruction* | DbgRecord*} union based
329
+ // / on the \p Unused parameter type.
323
330
DbgVariableRecord *UnwrapDbgInstPtr (DbgInstPtr P, DbgVariableRecord *Unused) {
324
331
(void )Unused;
325
332
return static_cast <DbgVariableRecord *>(cast<DbgRecord *>(P));
@@ -369,6 +376,9 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
369
376
// / Map of aggregate variables to their fragment associated with OldAlloca.
370
377
DenseMap<DebugVariable, std::optional<DIExpression::FragmentInfo>>
371
378
BaseFragments;
379
+ for (auto *DAI : at::getAssignmentMarkers (OldAlloca))
380
+ BaseFragments[getAggregateVariable (DAI)] =
381
+ DAI->getExpression ()->getFragmentInfo ();
372
382
for (auto *DVR : at::getDVRAssignmentMarkers (OldAlloca))
373
383
BaseFragments[getAggregateVariable (DVR)] =
374
384
DVR->getExpression ()->getFragmentInfo ();
@@ -381,7 +391,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
381
391
DIBuilder DIB (*OldInst->getModule (), /* AllowUnresolved*/ false );
382
392
assert (OldAlloca->isStaticAlloca ());
383
393
384
- auto MigrateDbgAssign = [&](DbgVariableRecord *DbgAssign) {
394
+ auto MigrateDbgAssign = [&](auto *DbgAssign) {
385
395
LLVM_DEBUG (dbgs () << " existing dbg.assign is: " << *DbgAssign
386
396
<< " \n " );
387
397
auto *Expr = DbgAssign->getExpression ();
@@ -476,6 +486,7 @@ static void migrateDebugInfo(AllocaInst *OldAlloca, bool IsSplit,
476
486
LLVM_DEBUG (dbgs () << " Created new assign: " << *NewAssign << " \n " );
477
487
};
478
488
489
+ for_each (MarkerRange, MigrateDbgAssign);
479
490
for_each (DVRAssignMarkerRange, MigrateDbgAssign);
480
491
}
481
492
@@ -5108,13 +5119,36 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
5108
5119
}
5109
5120
5110
5121
// There isn't a shared interface to get the "address" parts out of a
5111
- // dbg.declare and dbg.assign, so provide some wrappers.
5122
+ // dbg.declare and dbg.assign, so provide some wrappers now for
5123
+ // both debug intrinsics and records.
5124
+ const Value *getAddress (const DbgVariableIntrinsic *DVI) {
5125
+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
5126
+ return DAI->getAddress ();
5127
+ return cast<DbgDeclareInst>(DVI)->getAddress ();
5128
+ }
5129
+
5130
+ const Value *getAddress (const DbgVariableRecord *DVR) {
5131
+ return DVR->getAddress ();
5132
+ }
5133
+
5134
+ bool isKillAddress (const DbgVariableIntrinsic *DVI) {
5135
+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
5136
+ return DAI->isKillAddress ();
5137
+ return cast<DbgDeclareInst>(DVI)->isKillLocation ();
5138
+ }
5139
+
5112
5140
bool isKillAddress (const DbgVariableRecord *DVR) {
5113
5141
if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
5114
5142
return DVR->isKillAddress ();
5115
5143
return DVR->isKillLocation ();
5116
5144
}
5117
5145
5146
+ const DIExpression *getAddressExpression (const DbgVariableIntrinsic *DVI) {
5147
+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
5148
+ return DAI->getAddressExpression ();
5149
+ return cast<DbgDeclareInst>(DVI)->getExpression ();
5150
+ }
5151
+
5118
5152
const DIExpression *getAddressExpression (const DbgVariableRecord *DVR) {
5119
5153
if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
5120
5154
return DVR->getAddressExpression ();
@@ -5211,6 +5245,66 @@ static DIExpression *createOrReplaceFragment(const DIExpression *Expr,
5211
5245
return DIExpression::get (Expr->getContext (), Ops);
5212
5246
}
5213
5247
5248
+ // / Insert a new dbg.declare.
5249
+ // / \p Orig Original to copy debug loc and variable from.
5250
+ // / \p NewAddr Location's new base address.
5251
+ // / \p NewAddrExpr New expression to apply to address.
5252
+ // / \p BeforeInst Insert position.
5253
+ // / \p NewFragment New fragment (absolute, non-relative).
5254
+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5255
+ static void
5256
+ insertNewDbgInst (DIBuilder &DIB, DbgDeclareInst *Orig, AllocaInst *NewAddr,
5257
+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5258
+ std::optional<DIExpression::FragmentInfo> NewFragment,
5259
+ int64_t BitExtractAdjustment) {
5260
+ if (NewFragment)
5261
+ NewAddrExpr = createOrReplaceFragment (NewAddrExpr, *NewFragment,
5262
+ BitExtractAdjustment);
5263
+ if (!NewAddrExpr)
5264
+ return ;
5265
+
5266
+ DIB.insertDeclare (NewAddr, Orig->getVariable (), NewAddrExpr,
5267
+ Orig->getDebugLoc (), BeforeInst->getIterator ());
5268
+ }
5269
+
5270
+ // / Insert a new dbg.assign.
5271
+ // / \p Orig Original to copy debug loc, variable, value and value expression
5272
+ // / from.
5273
+ // / \p NewAddr Location's new base address.
5274
+ // / \p NewAddrExpr New expression to apply to address.
5275
+ // / \p BeforeInst Insert position.
5276
+ // / \p NewFragment New fragment (absolute, non-relative).
5277
+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5278
+ static void
5279
+ insertNewDbgInst (DIBuilder &DIB, DbgAssignIntrinsic *Orig, AllocaInst *NewAddr,
5280
+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5281
+ std::optional<DIExpression::FragmentInfo> NewFragment,
5282
+ int64_t BitExtractAdjustment) {
5283
+ // DIBuilder::insertDbgAssign will insert the #dbg_assign after NewAddr.
5284
+ (void )BeforeInst;
5285
+
5286
+ // A dbg.assign puts fragment info in the value expression only. The address
5287
+ // expression has already been built: NewAddrExpr.
5288
+ DIExpression *NewFragmentExpr = Orig->getExpression ();
5289
+ if (NewFragment)
5290
+ NewFragmentExpr = createOrReplaceFragment (NewFragmentExpr, *NewFragment,
5291
+ BitExtractAdjustment);
5292
+ if (!NewFragmentExpr)
5293
+ return ;
5294
+
5295
+ // Apply a DIAssignID to the store if it doesn't already have it.
5296
+ if (!NewAddr->hasMetadata (LLVMContext::MD_DIAssignID)) {
5297
+ NewAddr->setMetadata (LLVMContext::MD_DIAssignID,
5298
+ DIAssignID::getDistinct (NewAddr->getContext ()));
5299
+ }
5300
+
5301
+ Instruction *NewAssign = cast<Instruction *>(DIB.insertDbgAssign (
5302
+ NewAddr, Orig->getValue (), Orig->getVariable (), NewFragmentExpr, NewAddr,
5303
+ NewAddrExpr, Orig->getDebugLoc ()));
5304
+ LLVM_DEBUG (dbgs () << " Created new assign intrinsic: " << *NewAssign << " \n " );
5305
+ (void )NewAssign;
5306
+ }
5307
+
5214
5308
// / Insert a new DbgRecord.
5215
5309
// / \p Orig Original to copy record type, debug loc and variable from, and
5216
5310
// / additionally value and value expression for dbg_assign records.
@@ -5385,12 +5479,12 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
5385
5479
5386
5480
// Migrate debug information from the old alloca to the new alloca(s)
5387
5481
// and the individual partitions.
5388
- auto MigrateOne = [&](DbgVariableRecord *DbgVariable) {
5482
+ auto MigrateOne = [&](auto *DbgVariable) {
5389
5483
// Can't overlap with undef memory.
5390
5484
if (isKillAddress (DbgVariable))
5391
5485
return ;
5392
5486
5393
- const Value *DbgPtr = DbgVariable-> getAddress ();
5487
+ const Value *DbgPtr = getAddress (DbgVariable );
5394
5488
DIExpression::FragmentInfo VarFrag =
5395
5489
DbgVariable->getFragmentOrEntireVariable ();
5396
5490
// Get the address expression constant offset if one exists and the ops
@@ -5478,6 +5572,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
5478
5572
if (SameVariableFragment (OldDII, DbgVariable))
5479
5573
OldDII->eraseFromParent ();
5480
5574
};
5575
+ for_each (findDbgDeclares (Fragment.Alloca ), RemoveOne);
5481
5576
for_each (findDVRDeclares (Fragment.Alloca ), RemoveOne);
5482
5577
for_each (findDVRValues (Fragment.Alloca ), RemoveOne);
5483
5578
insertNewDbgInst (DIB, DbgVariable, Fragment.Alloca , NewExpr, &AI,
@@ -5487,8 +5582,10 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
5487
5582
5488
5583
// Migrate debug information from the old alloca to the new alloca(s)
5489
5584
// and the individual partitions.
5585
+ for_each (findDbgDeclares (&AI), MigrateOne);
5490
5586
for_each (findDVRDeclares (&AI), MigrateOne);
5491
5587
for_each (findDVRValues (&AI), MigrateOne);
5588
+ for_each (at::getAssignmentMarkers (&AI), MigrateOne);
5492
5589
for_each (at::getDVRAssignmentMarkers (&AI), MigrateOne);
5493
5590
5494
5591
return Changed;
@@ -5709,6 +5806,8 @@ bool SROA::deleteDeadInstructions(
5709
5806
// not be able to find it.
5710
5807
if (AllocaInst *AI = dyn_cast<AllocaInst>(I)) {
5711
5808
DeletedAllocas.insert (AI);
5809
+ for (DbgDeclareInst *OldDII : findDbgDeclares (AI))
5810
+ OldDII->eraseFromParent ();
5712
5811
for (DbgVariableRecord *OldDII : findDVRDeclares (AI))
5713
5812
OldDII->eraseFromParent ();
5714
5813
}
0 commit comments