@@ -4967,46 +4967,224 @@ AllocaInst *SROA::rewritePartition(AllocaInst &AI, AllocaSlices &AS,
49674967 return NewAI;
49684968}
49694969
4970- static void insertNewDbgInst (DIBuilder &DIB, DbgDeclareInst *Orig,
4971- AllocaInst *NewAddr, DIExpression *NewFragmentExpr,
4972- Instruction *BeforeInst) {
4973- DIB.insertDeclare (NewAddr, Orig->getVariable (), NewFragmentExpr,
4970+ // There isn't a shared interface to get the "address" parts out of a
4971+ // dbg.declare and dbg.assign, so provide some wrappers now for
4972+ // both debug intrinsics and records.
4973+ const Value *getAddress (const DbgVariableIntrinsic *DVI) {
4974+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
4975+ return DAI->getAddress ();
4976+ return cast<DbgDeclareInst>(DVI)->getAddress ();
4977+ }
4978+ const Value *getAddress (const DbgVariableRecord *DVR) {
4979+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
4980+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
4981+ return DVR->getAddress ();
4982+ }
4983+ bool isKillAddress (const DbgVariableIntrinsic *DVI) {
4984+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
4985+ return DAI->isKillAddress ();
4986+ return cast<DbgDeclareInst>(DVI)->isKillLocation ();
4987+ }
4988+ bool isKillAddress (const DbgVariableRecord *DVR) {
4989+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
4990+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
4991+ if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
4992+ return DVR->isKillAddress ();
4993+ return DVR->isKillLocation ();
4994+ }
4995+ const DIExpression *getAddressExpression (const DbgVariableIntrinsic *DVI) {
4996+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
4997+ return DAI->getAddressExpression ();
4998+ return cast<DbgDeclareInst>(DVI)->getExpression ();
4999+ }
5000+ const DIExpression *getAddressExpression (const DbgVariableRecord *DVR) {
5001+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
5002+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
5003+ if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
5004+ return DVR->getAddressExpression ();
5005+ return DVR->getExpression ();
5006+ }
5007+
5008+ // / Similar to DIExpression::createFragmentExpression except for 3 important
5009+ // / distinctions:
5010+ // / 1. The new fragment isn't relative to an existing fragment.
5011+ // / 2. There are no checks on the the operation types because it is assumed
5012+ // / the location this expression is computing is not implicit (i.e., it's
5013+ // / always safe to create a fragment because arithmetic operations apply
5014+ // / to the address computation, not to an implicit value computation).
5015+ // / 3. Existing extract_bits are modified independetly of fragment changes
5016+ // / using \p BitExtractOffset. A change to the fragment offset or size
5017+ // / may affect a bit extract. But a bit extract offset can change
5018+ // / independently of the fragment dimensions.
5019+ // /
5020+ // / Returns the new expression, or nullptr if one couldn't be created.
5021+ // / Ideally this is only used to signal that a bit-extract has become
5022+ // / zero-sized (and thus the new debug record has no size and can be
5023+ // / dropped), however, it fails for other reasons too - see the FIXME below.
5024+ // /
5025+ // / FIXME: To keep the change that introduces this function NFC it bails
5026+ // / in some situations unecessarily, e.g. when fragment and bit extract
5027+ // / sizes differ.
5028+ static DIExpression *createOrReplaceFragment (const DIExpression *Expr,
5029+ DIExpression::FragmentInfo Frag,
5030+ int64_t BitExtractOffset) {
5031+ SmallVector<uint64_t , 8 > Ops;
5032+ bool HasFragment = false ;
5033+ bool HasBitExtract = false ;
5034+
5035+ for (auto &Op : Expr->expr_ops ()) {
5036+ if (Op.getOp () == dwarf::DW_OP_LLVM_fragment) {
5037+ HasFragment = true ;
5038+ continue ;
5039+ }
5040+ if (Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_zext ||
5041+ Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_sext) {
5042+ HasBitExtract = true ;
5043+ int64_t ExtractOffsetInBits = Op.getArg (0 );
5044+ int64_t ExtractSizeInBits = Op.getArg (1 );
5045+
5046+ // DIExpression::createFragmentExpression doesn't know how to handle
5047+ // a fragment that is smaller than the extract. Copy the behaviour
5048+ // (bail) to avoid non-NFC changes.
5049+ // FIXME: Don't do this.
5050+ if (Frag.SizeInBits < uint64_t (ExtractSizeInBits))
5051+ return nullptr ;
5052+
5053+ assert (BitExtractOffset <= 0 );
5054+ int64_t AdjustedOffset = ExtractOffsetInBits + BitExtractOffset;
5055+
5056+ // DIExpression::createFragmentExpression doesn't know what to do
5057+ // if the new extract starts "outside" the existing one. Copy the
5058+ // behaviour (bail) to avoid non-NFC changes.
5059+ // FIXME: Don't do this.
5060+ if (AdjustedOffset < 0 )
5061+ return nullptr ;
5062+
5063+ Ops.push_back (Op.getOp ());
5064+ Ops.push_back (std::max<int64_t >(0 , AdjustedOffset));
5065+ Ops.push_back (ExtractSizeInBits);
5066+ continue ;
5067+ }
5068+ Op.appendToVector (Ops);
5069+ }
5070+
5071+ // Unsupported by createFragmentExpression, so don't support it here yet to
5072+ // preserve NFC-ness.
5073+ if (HasFragment && HasBitExtract)
5074+ return nullptr ;
5075+
5076+ if (!HasBitExtract) {
5077+ Ops.push_back (dwarf::DW_OP_LLVM_fragment);
5078+ Ops.push_back (Frag.OffsetInBits );
5079+ Ops.push_back (Frag.SizeInBits );
5080+ }
5081+ return DIExpression::get (Expr->getContext (), Ops);
5082+ }
5083+
5084+ // / Insert a new dbg.declare.
5085+ // / \p Orig Original to copy debug loc and variable from.
5086+ // / \p NewAddr Location's new base address.
5087+ // / \p NewAddrExpr New expression to apply to address.
5088+ // / \p BeforeInst Insert position.
5089+ // / \p NewFragment New fragment (absolute, non-relative).
5090+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5091+ static void
5092+ insertNewDbgInst (DIBuilder &DIB, DbgDeclareInst *Orig, AllocaInst *NewAddr,
5093+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5094+ std::optional<DIExpression::FragmentInfo> NewFragment,
5095+ int64_t BitExtractAdjustment) {
5096+ if (NewFragment)
5097+ NewAddrExpr = createOrReplaceFragment (NewAddrExpr, *NewFragment,
5098+ BitExtractAdjustment);
5099+ if (!NewAddrExpr)
5100+ return ;
5101+
5102+ DIB.insertDeclare (NewAddr, Orig->getVariable (), NewAddrExpr,
49745103 Orig->getDebugLoc (), BeforeInst);
49755104}
4976- static void insertNewDbgInst (DIBuilder &DIB, DbgAssignIntrinsic *Orig,
4977- AllocaInst *NewAddr, DIExpression *NewFragmentExpr,
4978- Instruction *BeforeInst) {
5105+
5106+ // / Insert a new dbg.assign.
5107+ // / \p Orig Original to copy debug loc, variable, value and value expression
5108+ // / from.
5109+ // / \p NewAddr Location's new base address.
5110+ // / \p NewAddrExpr New expression to apply to address.
5111+ // / \p BeforeInst Insert position.
5112+ // / \p NewFragment New fragment (absolute, non-relative).
5113+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5114+ static void
5115+ insertNewDbgInst (DIBuilder &DIB, DbgAssignIntrinsic *Orig, AllocaInst *NewAddr,
5116+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5117+ std::optional<DIExpression::FragmentInfo> NewFragment,
5118+ int64_t BitExtractAdjustment) {
49795119 (void )BeforeInst;
5120+
5121+ // A dbg.assign puts fragment info in the value expression only. The address
5122+ // expression has already been built: NewAddrExpr.
5123+ DIExpression *NewFragmentExpr = Orig->getExpression ();
5124+ if (NewFragment)
5125+ NewFragmentExpr = createOrReplaceFragment (NewFragmentExpr, *NewFragment,
5126+ BitExtractAdjustment);
5127+ if (!NewFragmentExpr)
5128+ return ;
5129+
5130+ // Apply a DIAssignID to the store if it doesn't already have it.
49805131 if (!NewAddr->hasMetadata (LLVMContext::MD_DIAssignID)) {
49815132 NewAddr->setMetadata (LLVMContext::MD_DIAssignID,
49825133 DIAssignID::getDistinct (NewAddr->getContext ()));
49835134 }
5135+
49845136 Instruction *NewAssign =
49855137 DIB.insertDbgAssign (NewAddr, Orig->getValue (), Orig->getVariable (),
4986- NewFragmentExpr, NewAddr,
4987- Orig->getAddressExpression (), Orig-> getDebugLoc ())
5138+ NewFragmentExpr, NewAddr, NewAddrExpr,
5139+ Orig->getDebugLoc ())
49885140 .get <Instruction *>();
49895141 LLVM_DEBUG (dbgs () << " Created new assign intrinsic: " << *NewAssign << " \n " );
49905142 (void )NewAssign;
49915143}
4992- static void insertNewDbgInst (DIBuilder &DIB, DbgVariableRecord *Orig,
4993- AllocaInst *NewAddr, DIExpression *NewFragmentExpr,
4994- Instruction *BeforeInst) {
5144+
5145+ // / Insert a new DbgRecord.
5146+ // / \p Orig Original to copy record type, debug loc and variable from, and
5147+ // / additionally value and value expression for dbg_assign records.
5148+ // / \p NewAddr Location's new base address.
5149+ // / \p NewAddrExpr New expression to apply to address.
5150+ // / \p BeforeInst Insert position.
5151+ // / \p NewFragment New fragment (absolute, non-relative).
5152+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5153+ static void
5154+ insertNewDbgInst (DIBuilder &DIB, DbgVariableRecord *Orig, AllocaInst *NewAddr,
5155+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5156+ std::optional<DIExpression::FragmentInfo> NewFragment,
5157+ int64_t BitExtractAdjustment) {
49955158 (void )DIB;
5159+
5160+ // A dbg_assign puts fragment info in the value expression only. The address
5161+ // expression has already been built: NewAddrExpr. A dbg_declare puts the
5162+ // new fragment info into NewAddrExpr (as it only has one expression).
5163+ DIExpression *NewFragmentExpr =
5164+ Orig->isDbgAssign () ? Orig->getExpression () : NewAddrExpr;
5165+ if (NewFragment)
5166+ NewFragmentExpr = createOrReplaceFragment (NewFragmentExpr, *NewFragment,
5167+ BitExtractAdjustment);
5168+ if (!NewFragmentExpr)
5169+ return ;
5170+
49965171 if (Orig->isDbgDeclare ()) {
49975172 DbgVariableRecord *DVR = DbgVariableRecord::createDVRDeclare (
49985173 NewAddr, Orig->getVariable (), NewFragmentExpr, Orig->getDebugLoc ());
49995174 BeforeInst->getParent ()->insertDbgRecordBefore (DVR,
50005175 BeforeInst->getIterator ());
50015176 return ;
50025177 }
5178+
5179+ // Apply a DIAssignID to the store if it doesn't already have it.
50035180 if (!NewAddr->hasMetadata (LLVMContext::MD_DIAssignID)) {
50045181 NewAddr->setMetadata (LLVMContext::MD_DIAssignID,
50055182 DIAssignID::getDistinct (NewAddr->getContext ()));
50065183 }
5184+
50075185 DbgVariableRecord *NewAssign = DbgVariableRecord::createLinkedDVRAssign (
50085186 NewAddr, Orig->getValue (), Orig->getVariable (), NewFragmentExpr, NewAddr,
5009- Orig-> getAddressExpression () , Orig->getDebugLoc ());
5187+ NewAddrExpr , Orig->getDebugLoc ());
50105188 LLVM_DEBUG (dbgs () << " Created new DVRAssign: " << *NewAssign << " \n " );
50115189 (void )NewAssign;
50125190}
@@ -5019,7 +5197,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
50195197
50205198 unsigned NumPartitions = 0 ;
50215199 bool Changed = false ;
5022- const DataLayout &DL = AI.getDataLayout ();
5200+ const DataLayout &DL = AI.getModule ()-> getDataLayout ();
50235201
50245202 // First try to pre-split loads and stores.
50255203 Changed |= presplitLoadsAndStores (AI, AS);
@@ -5110,57 +5288,79 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
51105288 NumAllocaPartitions += NumPartitions;
51115289 MaxPartitionsPerAlloca.updateMax (NumPartitions);
51125290
5113- // Migrate debug information from the old alloca to the new alloca(s)
5114- // and the individual partitions.
51155291 auto MigrateOne = [&](auto *DbgVariable) {
5116- auto *Expr = DbgVariable->getExpression ();
5117- DIBuilder DIB (*AI.getModule (), /* AllowUnresolved*/ false );
5118- uint64_t AllocaSize =
5119- DL.getTypeSizeInBits (AI.getAllocatedType ()).getFixedValue ();
5120- for (auto Fragment : Fragments) {
5121- // Create a fragment expression describing the new partition or reuse AI's
5122- // expression if there is only one partition.
5123- auto *FragmentExpr = Expr;
5124- if (Fragment.Size < AllocaSize || Expr->isFragment ()) {
5125- // If this alloca is already a scalar replacement of a larger aggregate,
5126- // Fragment.Offset describes the offset inside the scalar.
5127- auto ExprFragment = Expr->getFragmentInfo ();
5128- uint64_t Offset = ExprFragment ? ExprFragment->OffsetInBits : 0 ;
5129- uint64_t Start = Offset + Fragment.Offset ;
5130- uint64_t Size = Fragment.Size ;
5131- if (ExprFragment) {
5132- uint64_t AbsEnd =
5133- ExprFragment->OffsetInBits + ExprFragment->SizeInBits ;
5134- if (Start >= AbsEnd) {
5135- // No need to describe a SROAed padding.
5136- continue ;
5137- }
5138- Size = std::min (Size, AbsEnd - Start);
5139- }
5140- // The new, smaller fragment is stenciled out from the old fragment.
5141- if (auto OrigFragment = FragmentExpr->getFragmentInfo ()) {
5142- assert (Start >= OrigFragment->OffsetInBits &&
5143- " new fragment is outside of original fragment" );
5144- Start -= OrigFragment->OffsetInBits ;
5145- }
5292+ // Can't overlap with undef memory.
5293+ if (isKillAddress (DbgVariable))
5294+ return ;
51465295
5147- // The alloca may be larger than the variable.
5148- auto VarSize = DbgVariable->getVariable ()->getSizeInBits ();
5149- if (VarSize) {
5150- if (Size > *VarSize)
5151- Size = *VarSize;
5152- if (Size == 0 || Start + Size > *VarSize)
5153- continue ;
5154- }
5296+ const Value *DbgPtr = getAddress (DbgVariable);
5297+ DIExpression::FragmentInfo VarFrag =
5298+ DbgVariable->getFragmentOrEntireVariable ();
5299+ // Get the address expression constant offset if one exists and the ops
5300+ // that come after it.
5301+ int64_t CurrentExprOffsetInBytes = 0 ;
5302+ SmallVector<uint64_t > PostOffsetOps;
5303+ if (!getAddressExpression (DbgVariable)
5304+ ->extractLeadingOffset (CurrentExprOffsetInBytes, PostOffsetOps))
5305+ return ; // Couldn't interpret this DIExpression - drop the var.
5306+
5307+ // Offset defined by a DW_OP_LLVM_extract_bits_[sz]ext.
5308+ int64_t ExtractOffsetInBits = 0 ;
5309+ for (auto Op : getAddressExpression (DbgVariable)->expr_ops ()) {
5310+ if (Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_zext ||
5311+ Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_sext) {
5312+ ExtractOffsetInBits = Op.getArg (0 );
5313+ break ;
5314+ }
5315+ }
51555316
5156- // Avoid creating a fragment expression that covers the entire variable.
5157- if (!VarSize || *VarSize != Size) {
5158- if (auto E =
5159- DIExpression::createFragmentExpression (Expr, Start, Size))
5160- FragmentExpr = *E;
5161- else
5162- continue ;
5163- }
5317+ DIBuilder DIB (*AI.getModule (), /* AllowUnresolved*/ false );
5318+ for (auto Fragment : Fragments) {
5319+ int64_t OffsetFromLocationInBits;
5320+ std::optional<DIExpression::FragmentInfo> NewDbgFragment;
5321+ // Find the variable fragment that the new alloca slice covers.
5322+ // Drop debug info for this variable fragment if we can't compute an
5323+ // intersect between it and the alloca slice.
5324+ if (!DIExpression::calculateFragmentIntersect (
5325+ DL, &AI, Fragment.Offset , Fragment.Size , DbgPtr,
5326+ CurrentExprOffsetInBytes * 8 , ExtractOffsetInBits, VarFrag,
5327+ NewDbgFragment, OffsetFromLocationInBits))
5328+ continue ; // Do not migrate this fragment to this slice.
5329+
5330+ // Zero sized fragment indicates there's no intersect between the variable
5331+ // fragment and the alloca slice. Skip this slice for this variable
5332+ // fragment.
5333+ if (NewDbgFragment && !NewDbgFragment->SizeInBits )
5334+ continue ; // Do not migrate this fragment to this slice.
5335+
5336+ // No fragment indicates DbgVariable's variable or fragment exactly
5337+ // overlaps the slice; copy its fragment (or nullopt if there isn't one).
5338+ if (!NewDbgFragment)
5339+ NewDbgFragment = DbgVariable->getFragment ();
5340+
5341+ // Reduce the new expression offset by the bit-extract offset since
5342+ // we'll be keeping that.
5343+ int64_t OffestFromNewAllocaInBits =
5344+ OffsetFromLocationInBits - ExtractOffsetInBits;
5345+ // We need to adjust an existing bit extract if the offset expression
5346+ // can't eat the slack (i.e., if the new offset would be negative).
5347+ int64_t BitExtractOffset =
5348+ std::min<int64_t >(0 , OffestFromNewAllocaInBits);
5349+ // The magnitude of a negative value indicates the number of bits into
5350+ // the existing variable fragment that the memory region begins. The new
5351+ // variable fragment already excludes those bits - the new DbgPtr offset
5352+ // only needs to be applied if it's positive.
5353+ OffestFromNewAllocaInBits =
5354+ std::max (int64_t (0 ), OffestFromNewAllocaInBits);
5355+
5356+ // Rebuild the expression:
5357+ // {Offset(OffestFromNewAllocaInBits), PostOffsetOps, NewDbgFragment}
5358+ // Add NewDbgFragment later, because dbg.assigns don't want it in the
5359+ // address expression but the value expression instead.
5360+ DIExpression *NewExpr = DIExpression::get (AI.getContext (), PostOffsetOps);
5361+ if (OffestFromNewAllocaInBits > 0 ) {
5362+ int64_t OffsetInBytes = (OffestFromNewAllocaInBits + 7 ) / 8 ;
5363+ NewExpr = DIExpression::prepend (NewExpr, /* flags=*/ 0 , OffsetInBytes);
51645364 }
51655365
51665366 // Remove any existing intrinsics on the new alloca describing
@@ -5177,7 +5377,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
51775377 for_each (findDbgDeclares (Fragment.Alloca ), RemoveOne);
51785378 for_each (findDVRDeclares (Fragment.Alloca ), RemoveOne);
51795379
5180- insertNewDbgInst (DIB, DbgVariable, Fragment.Alloca , FragmentExpr, &AI);
5380+ insertNewDbgInst (DIB, DbgVariable, Fragment.Alloca , NewExpr, &AI,
5381+ NewDbgFragment, BitExtractOffset);
51815382 }
51825383 };
51835384
0 commit comments