@@ -4967,46 +4967,235 @@ 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+
4979+ const Value *getAddress (const DbgVariableRecord *DVR) {
4980+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
4981+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
4982+ return DVR->getAddress ();
4983+ }
4984+
4985+ bool isKillAddress (const DbgVariableIntrinsic *DVI) {
4986+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
4987+ return DAI->isKillAddress ();
4988+ return cast<DbgDeclareInst>(DVI)->isKillLocation ();
4989+ }
4990+
4991+ bool isKillAddress (const DbgVariableRecord *DVR) {
4992+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
4993+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
4994+ if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
4995+ return DVR->isKillAddress ();
4996+ return DVR->isKillLocation ();
4997+ }
4998+
4999+ const DIExpression *getAddressExpression (const DbgVariableIntrinsic *DVI) {
5000+ if (const auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI))
5001+ return DAI->getAddressExpression ();
5002+ return cast<DbgDeclareInst>(DVI)->getExpression ();
5003+ }
5004+
5005+ const DIExpression *getAddressExpression (const DbgVariableRecord *DVR) {
5006+ assert (DVR->getType () == DbgVariableRecord::LocationType::Declare ||
5007+ DVR->getType () == DbgVariableRecord::LocationType::Assign);
5008+ if (DVR->getType () == DbgVariableRecord::LocationType::Assign)
5009+ return DVR->getAddressExpression ();
5010+ return DVR->getExpression ();
5011+ }
5012+
5013+ // / Create or replace an existing fragment in a DIExpression with \p Frag.
5014+ // / If the expression already contains a DW_OP_LLVM_extract_bits_[sz]ext
5015+ // / operation, add \p BitExtractOffset to the offset part.
5016+ // /
5017+ // / Returns the new expression, or nullptr if this fails (see details below).
5018+ // /
5019+ // / This function is similar to DIExpression::createFragmentExpression except
5020+ // / for 3 important distinctions:
5021+ // / 1. The new fragment isn't relative to an existing fragment.
5022+ // / 2. It assumes the computed location is a memory location. This means we
5023+ // / don't need to perform checks that creating the fragment preserves the
5024+ // / expression semantics.
5025+ // / 3. Existing extract_bits are modified independently of fragment changes
5026+ // / using \p BitExtractOffset. A change to the fragment offset or size
5027+ // / may affect a bit extract. But a bit extract offset can change
5028+ // / independently of the fragment dimensions.
5029+ // /
5030+ // / Returns the new expression, or nullptr if one couldn't be created.
5031+ // / Ideally this is only used to signal that a bit-extract has become
5032+ // / zero-sized (and thus the new debug record has no size and can be
5033+ // / dropped), however, it fails for other reasons too - see the FIXME below.
5034+ // /
5035+ // / FIXME: To keep the change that introduces this function NFC it bails
5036+ // / in some situations unecessarily, e.g. when fragment and bit extract
5037+ // / sizes differ.
5038+ static DIExpression *createOrReplaceFragment (const DIExpression *Expr,
5039+ DIExpression::FragmentInfo Frag,
5040+ int64_t BitExtractOffset) {
5041+ SmallVector<uint64_t , 8 > Ops;
5042+ bool HasFragment = false ;
5043+ bool HasBitExtract = false ;
5044+
5045+ for (auto &Op : Expr->expr_ops ()) {
5046+ if (Op.getOp () == dwarf::DW_OP_LLVM_fragment) {
5047+ HasFragment = true ;
5048+ continue ;
5049+ }
5050+ if (Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_zext ||
5051+ Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_sext) {
5052+ HasBitExtract = true ;
5053+ int64_t ExtractOffsetInBits = Op.getArg (0 );
5054+ int64_t ExtractSizeInBits = Op.getArg (1 );
5055+
5056+ // DIExpression::createFragmentExpression doesn't know how to handle
5057+ // a fragment that is smaller than the extract. Copy the behaviour
5058+ // (bail) to avoid non-NFC changes.
5059+ // FIXME: Don't do this.
5060+ if (Frag.SizeInBits < uint64_t (ExtractSizeInBits))
5061+ return nullptr ;
5062+
5063+ assert (BitExtractOffset <= 0 );
5064+ int64_t AdjustedOffset = ExtractOffsetInBits + BitExtractOffset;
5065+
5066+ // DIExpression::createFragmentExpression doesn't know what to do
5067+ // if the new extract starts "outside" the existing one. Copy the
5068+ // behaviour (bail) to avoid non-NFC changes.
5069+ // FIXME: Don't do this.
5070+ if (AdjustedOffset < 0 )
5071+ return nullptr ;
5072+
5073+ Ops.push_back (Op.getOp ());
5074+ Ops.push_back (std::max<int64_t >(0 , AdjustedOffset));
5075+ Ops.push_back (ExtractSizeInBits);
5076+ continue ;
5077+ }
5078+ Op.appendToVector (Ops);
5079+ }
5080+
5081+ // Unsupported by createFragmentExpression, so don't support it here yet to
5082+ // preserve NFC-ness.
5083+ if (HasFragment && HasBitExtract)
5084+ return nullptr ;
5085+
5086+ if (!HasBitExtract) {
5087+ Ops.push_back (dwarf::DW_OP_LLVM_fragment);
5088+ Ops.push_back (Frag.OffsetInBits );
5089+ Ops.push_back (Frag.SizeInBits );
5090+ }
5091+ return DIExpression::get (Expr->getContext (), Ops);
5092+ }
5093+
5094+ // / Insert a new dbg.declare.
5095+ // / \p Orig Original to copy debug loc and variable from.
5096+ // / \p NewAddr Location's new base address.
5097+ // / \p NewAddrExpr New expression to apply to address.
5098+ // / \p BeforeInst Insert position.
5099+ // / \p NewFragment New fragment (absolute, non-relative).
5100+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5101+ static void
5102+ insertNewDbgInst (DIBuilder &DIB, DbgDeclareInst *Orig, AllocaInst *NewAddr,
5103+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5104+ std::optional<DIExpression::FragmentInfo> NewFragment,
5105+ int64_t BitExtractAdjustment) {
5106+ if (NewFragment)
5107+ NewAddrExpr = createOrReplaceFragment (NewAddrExpr, *NewFragment,
5108+ BitExtractAdjustment);
5109+ if (!NewAddrExpr)
5110+ return ;
5111+
5112+ DIB.insertDeclare (NewAddr, Orig->getVariable (), NewAddrExpr,
49745113 Orig->getDebugLoc (), BeforeInst);
49755114}
4976- static void insertNewDbgInst (DIBuilder &DIB, DbgAssignIntrinsic *Orig,
4977- AllocaInst *NewAddr, DIExpression *NewFragmentExpr,
4978- Instruction *BeforeInst) {
5115+
5116+ // / Insert a new dbg.assign.
5117+ // / \p Orig Original to copy debug loc, variable, value and value expression
5118+ // / from.
5119+ // / \p NewAddr Location's new base address.
5120+ // / \p NewAddrExpr New expression to apply to address.
5121+ // / \p BeforeInst Insert position.
5122+ // / \p NewFragment New fragment (absolute, non-relative).
5123+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5124+ static void
5125+ insertNewDbgInst (DIBuilder &DIB, DbgAssignIntrinsic *Orig, AllocaInst *NewAddr,
5126+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5127+ std::optional<DIExpression::FragmentInfo> NewFragment,
5128+ int64_t BitExtractAdjustment) {
5129+ // DIBuilder::insertDbgAssign will insert the #dbg_assign after NewAddr.
49795130 (void )BeforeInst;
5131+
5132+ // A dbg.assign puts fragment info in the value expression only. The address
5133+ // expression has already been built: NewAddrExpr.
5134+ DIExpression *NewFragmentExpr = Orig->getExpression ();
5135+ if (NewFragment)
5136+ NewFragmentExpr = createOrReplaceFragment (NewFragmentExpr, *NewFragment,
5137+ BitExtractAdjustment);
5138+ if (!NewFragmentExpr)
5139+ return ;
5140+
5141+ // Apply a DIAssignID to the store if it doesn't already have it.
49805142 if (!NewAddr->hasMetadata (LLVMContext::MD_DIAssignID)) {
49815143 NewAddr->setMetadata (LLVMContext::MD_DIAssignID,
49825144 DIAssignID::getDistinct (NewAddr->getContext ()));
49835145 }
5146+
49845147 Instruction *NewAssign =
49855148 DIB.insertDbgAssign (NewAddr, Orig->getValue (), Orig->getVariable (),
4986- NewFragmentExpr, NewAddr,
4987- Orig->getAddressExpression (), Orig-> getDebugLoc ())
5149+ NewFragmentExpr, NewAddr, NewAddrExpr,
5150+ Orig->getDebugLoc ())
49885151 .get <Instruction *>();
49895152 LLVM_DEBUG (dbgs () << " Created new assign intrinsic: " << *NewAssign << " \n " );
49905153 (void )NewAssign;
49915154}
4992- static void insertNewDbgInst (DIBuilder &DIB, DbgVariableRecord *Orig,
4993- AllocaInst *NewAddr, DIExpression *NewFragmentExpr,
4994- Instruction *BeforeInst) {
5155+
5156+ // / Insert a new DbgRecord.
5157+ // / \p Orig Original to copy record type, debug loc and variable from, and
5158+ // / additionally value and value expression for dbg_assign records.
5159+ // / \p NewAddr Location's new base address.
5160+ // / \p NewAddrExpr New expression to apply to address.
5161+ // / \p BeforeInst Insert position.
5162+ // / \p NewFragment New fragment (absolute, non-relative).
5163+ // / \p BitExtractAdjustment Offset to apply to any extract_bits op.
5164+ static void
5165+ insertNewDbgInst (DIBuilder &DIB, DbgVariableRecord *Orig, AllocaInst *NewAddr,
5166+ DIExpression *NewAddrExpr, Instruction *BeforeInst,
5167+ std::optional<DIExpression::FragmentInfo> NewFragment,
5168+ int64_t BitExtractAdjustment) {
49955169 (void )DIB;
5170+
5171+ // A dbg_assign puts fragment info in the value expression only. The address
5172+ // expression has already been built: NewAddrExpr. A dbg_declare puts the
5173+ // new fragment info into NewAddrExpr (as it only has one expression).
5174+ DIExpression *NewFragmentExpr =
5175+ Orig->isDbgAssign () ? Orig->getExpression () : NewAddrExpr;
5176+ if (NewFragment)
5177+ NewFragmentExpr = createOrReplaceFragment (NewFragmentExpr, *NewFragment,
5178+ BitExtractAdjustment);
5179+ if (!NewFragmentExpr)
5180+ return ;
5181+
49965182 if (Orig->isDbgDeclare ()) {
49975183 DbgVariableRecord *DVR = DbgVariableRecord::createDVRDeclare (
49985184 NewAddr, Orig->getVariable (), NewFragmentExpr, Orig->getDebugLoc ());
49995185 BeforeInst->getParent ()->insertDbgRecordBefore (DVR,
50005186 BeforeInst->getIterator ());
50015187 return ;
50025188 }
5189+
5190+ // Apply a DIAssignID to the store if it doesn't already have it.
50035191 if (!NewAddr->hasMetadata (LLVMContext::MD_DIAssignID)) {
50045192 NewAddr->setMetadata (LLVMContext::MD_DIAssignID,
50055193 DIAssignID::getDistinct (NewAddr->getContext ()));
50065194 }
5195+
50075196 DbgVariableRecord *NewAssign = DbgVariableRecord::createLinkedDVRAssign (
50085197 NewAddr, Orig->getValue (), Orig->getVariable (), NewFragmentExpr, NewAddr,
5009- Orig-> getAddressExpression () , Orig->getDebugLoc ());
5198+ NewAddrExpr , Orig->getDebugLoc ());
50105199 LLVM_DEBUG (dbgs () << " Created new DVRAssign: " << *NewAssign << " \n " );
50115200 (void )NewAssign;
50125201}
@@ -5019,7 +5208,7 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
50195208
50205209 unsigned NumPartitions = 0 ;
50215210 bool Changed = false ;
5022- const DataLayout &DL = AI.getDataLayout ();
5211+ const DataLayout &DL = AI.getModule ()-> getDataLayout ();
50235212
50245213 // First try to pre-split loads and stores.
50255214 Changed |= presplitLoadsAndStores (AI, AS);
@@ -5113,54 +5302,78 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
51135302 // Migrate debug information from the old alloca to the new alloca(s)
51145303 // and the individual partitions.
51155304 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- }
5305+ // Can't overlap with undef memory.
5306+ if (isKillAddress (DbgVariable))
5307+ return ;
51465308
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- }
5309+ const Value *DbgPtr = getAddress (DbgVariable);
5310+ DIExpression::FragmentInfo VarFrag =
5311+ DbgVariable->getFragmentOrEntireVariable ();
5312+ // Get the address expression constant offset if one exists and the ops
5313+ // that come after it.
5314+ int64_t CurrentExprOffsetInBytes = 0 ;
5315+ SmallVector<uint64_t > PostOffsetOps;
5316+ if (!getAddressExpression (DbgVariable)
5317+ ->extractLeadingOffset (CurrentExprOffsetInBytes, PostOffsetOps))
5318+ return ; // Couldn't interpret this DIExpression - drop the var.
5319+
5320+ // Offset defined by a DW_OP_LLVM_extract_bits_[sz]ext.
5321+ int64_t ExtractOffsetInBits = 0 ;
5322+ for (auto Op : getAddressExpression (DbgVariable)->expr_ops ()) {
5323+ if (Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_zext ||
5324+ Op.getOp () == dwarf::DW_OP_LLVM_extract_bits_sext) {
5325+ ExtractOffsetInBits = Op.getArg (0 );
5326+ break ;
5327+ }
5328+ }
51555329
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- }
5330+ DIBuilder DIB (*AI.getModule (), /* AllowUnresolved*/ false );
5331+ for (auto Fragment : Fragments) {
5332+ int64_t OffsetFromLocationInBits;
5333+ std::optional<DIExpression::FragmentInfo> NewDbgFragment;
5334+ // Find the variable fragment that the new alloca slice covers.
5335+ // Drop debug info for this variable fragment if we can't compute an
5336+ // intersect between it and the alloca slice.
5337+ if (!DIExpression::calculateFragmentIntersect (
5338+ DL, &AI, Fragment.Offset , Fragment.Size , DbgPtr,
5339+ CurrentExprOffsetInBytes * 8 , ExtractOffsetInBits, VarFrag,
5340+ NewDbgFragment, OffsetFromLocationInBits))
5341+ continue ; // Do not migrate this fragment to this slice.
5342+
5343+ // Zero sized fragment indicates there's no intersect between the variable
5344+ // fragment and the alloca slice. Skip this slice for this variable
5345+ // fragment.
5346+ if (NewDbgFragment && !NewDbgFragment->SizeInBits )
5347+ continue ; // Do not migrate this fragment to this slice.
5348+
5349+ // No fragment indicates DbgVariable's variable or fragment exactly
5350+ // overlaps the slice; copy its fragment (or nullopt if there isn't one).
5351+ if (!NewDbgFragment)
5352+ NewDbgFragment = DbgVariable->getFragment ();
5353+
5354+ // Reduce the new expression offset by the bit-extract offset since
5355+ // we'll be keeping that.
5356+ int64_t OffestFromNewAllocaInBits =
5357+ OffsetFromLocationInBits - ExtractOffsetInBits;
5358+ // We need to adjust an existing bit extract if the offset expression
5359+ // can't eat the slack (i.e., if the new offset would be negative).
5360+ int64_t BitExtractOffset =
5361+ std::min<int64_t >(0 , OffestFromNewAllocaInBits);
5362+ // The magnitude of a negative value indicates the number of bits into
5363+ // the existing variable fragment that the memory region begins. The new
5364+ // variable fragment already excludes those bits - the new DbgPtr offset
5365+ // only needs to be applied if it's positive.
5366+ OffestFromNewAllocaInBits =
5367+ std::max (int64_t (0 ), OffestFromNewAllocaInBits);
5368+
5369+ // Rebuild the expression:
5370+ // {Offset(OffestFromNewAllocaInBits), PostOffsetOps, NewDbgFragment}
5371+ // Add NewDbgFragment later, because dbg.assigns don't want it in the
5372+ // address expression but the value expression instead.
5373+ DIExpression *NewExpr = DIExpression::get (AI.getContext (), PostOffsetOps);
5374+ if (OffestFromNewAllocaInBits > 0 ) {
5375+ int64_t OffsetInBytes = (OffestFromNewAllocaInBits + 7 ) / 8 ;
5376+ NewExpr = DIExpression::prepend (NewExpr, /* flags=*/ 0 , OffsetInBytes);
51645377 }
51655378
51665379 // Remove any existing intrinsics on the new alloca describing
@@ -5177,7 +5390,8 @@ bool SROA::splitAlloca(AllocaInst &AI, AllocaSlices &AS) {
51775390 for_each (findDbgDeclares (Fragment.Alloca ), RemoveOne);
51785391 for_each (findDVRDeclares (Fragment.Alloca ), RemoveOne);
51795392
5180- insertNewDbgInst (DIB, DbgVariable, Fragment.Alloca , FragmentExpr, &AI);
5393+ insertNewDbgInst (DIB, DbgVariable, Fragment.Alloca , NewExpr, &AI,
5394+ NewDbgFragment, BitExtractOffset);
51815395 }
51825396 };
51835397
0 commit comments