@@ -4195,92 +4195,88 @@ uint64_t BinaryFunction::translateInputToOutputAddress(uint64_t Address) const {
4195
4195
BB->getOutputAddressRange ().second );
4196
4196
}
4197
4197
4198
- DebugAddressRangesVector BinaryFunction::translateInputToOutputRanges (
4199
- const DWARFAddressRangesVector &InputRanges ) const {
4200
- DebugAddressRangesVector OutputRanges ;
4198
+ DebugAddressRangesVector
4199
+ BinaryFunction::translateInputToOutputRange (DebugAddressRange InRange ) const {
4200
+ DebugAddressRangesVector OutRanges ;
4201
4201
4202
+ // The function was removed from the output. Return an empty range.
4202
4203
if (isFolded ())
4203
- return OutputRanges ;
4204
+ return OutRanges ;
4204
4205
4205
- // If the function hasn't changed return the same ranges .
4206
+ // If the function hasn't changed return the same range .
4206
4207
if (!isEmitted ()) {
4207
- OutputRanges.resize (InputRanges.size ());
4208
- llvm::transform (InputRanges, OutputRanges.begin (),
4209
- [](const DWARFAddressRange &Range) {
4210
- return DebugAddressRange (Range.LowPC , Range.HighPC );
4211
- });
4212
- return OutputRanges;
4208
+ OutRanges.emplace_back (InRange);
4209
+ return OutRanges;
4210
+ }
4211
+
4212
+ if (!containsAddress (InRange.LowPC ))
4213
+ return OutRanges;
4214
+
4215
+ // Special case of an empty range [X, X). Some tools expect X to be updated.
4216
+ if (InRange.LowPC == InRange.HighPC ) {
4217
+ if (uint64_t NewPC = translateInputToOutputAddress (InRange.LowPC ))
4218
+ OutRanges.push_back (DebugAddressRange{NewPC, NewPC});
4219
+ return OutRanges;
4213
4220
}
4214
4221
4215
- // Even though we will merge ranges in a post-processing pass, we attempt to
4216
- // merge them in a main processing loop as it improves the processing time.
4217
- uint64_t PrevEndAddress = 0 ;
4218
- for (const DWARFAddressRange &Range : InputRanges) {
4219
- if (!containsAddress (Range.LowPC )) {
4222
+ uint64_t InputOffset = InRange.LowPC - getAddress ();
4223
+ const uint64_t InputEndOffset =
4224
+ std::min (InRange.HighPC - getAddress (), getSize ());
4225
+
4226
+ auto BBI = llvm::upper_bound (BasicBlockOffsets,
4227
+ BasicBlockOffset (InputOffset, nullptr ),
4228
+ CompareBasicBlockOffsets ());
4229
+ assert (BBI != BasicBlockOffsets.begin ());
4230
+
4231
+ // Iterate over blocks in the input order using BasicBlockOffsets.
4232
+ for (--BBI; InputOffset < InputEndOffset && BBI != BasicBlockOffsets.end ();
4233
+ InputOffset = BBI->second ->getEndOffset (), ++BBI) {
4234
+ const BinaryBasicBlock &BB = *BBI->second ;
4235
+ if (InputOffset < BB.getOffset () || InputOffset >= BB.getEndOffset ()) {
4220
4236
LLVM_DEBUG (
4221
4237
dbgs () << " BOLT-DEBUG: invalid debug address range detected for "
4222
- << *this << " : [0x" << Twine::utohexstr (Range.LowPC ) << " , 0x"
4223
- << Twine::utohexstr (Range.HighPC ) << " ]\n " );
4224
- PrevEndAddress = 0 ;
4225
- continue ;
4238
+ << *this << " : [0x" << Twine::utohexstr (InRange.LowPC )
4239
+ << " , 0x" << Twine::utohexstr (InRange.HighPC ) << " ]\n " );
4240
+ break ;
4226
4241
}
4227
- uint64_t InputOffset = Range.LowPC - getAddress ();
4228
- const uint64_t InputEndOffset =
4229
- std::min (Range.HighPC - getAddress (), getSize ());
4230
-
4231
- auto BBI = llvm::upper_bound (BasicBlockOffsets,
4232
- BasicBlockOffset (InputOffset, nullptr ),
4233
- CompareBasicBlockOffsets ());
4234
- --BBI;
4235
- do {
4236
- const BinaryBasicBlock *BB = BBI->second ;
4237
- if (InputOffset < BB->getOffset () || InputOffset >= BB->getEndOffset ()) {
4238
- LLVM_DEBUG (
4239
- dbgs () << " BOLT-DEBUG: invalid debug address range detected for "
4240
- << *this << " : [0x" << Twine::utohexstr (Range.LowPC )
4241
- << " , 0x" << Twine::utohexstr (Range.HighPC ) << " ]\n " );
4242
- PrevEndAddress = 0 ;
4243
- break ;
4244
- }
4245
4242
4246
- // Skip the range if the block was deleted.
4247
- if (const uint64_t OutputStart = BB->getOutputAddressRange ().first ) {
4248
- const uint64_t StartAddress =
4249
- OutputStart + InputOffset - BB->getOffset ();
4250
- uint64_t EndAddress = BB->getOutputAddressRange ().second ;
4251
- if (InputEndOffset < BB->getEndOffset ())
4252
- EndAddress = StartAddress + InputEndOffset - InputOffset;
4253
-
4254
- if (StartAddress == PrevEndAddress) {
4255
- OutputRanges.back ().HighPC =
4256
- std::max (OutputRanges.back ().HighPC , EndAddress);
4257
- } else {
4258
- OutputRanges.emplace_back (StartAddress,
4259
- std::max (StartAddress, EndAddress));
4260
- }
4261
- PrevEndAddress = OutputRanges.back ().HighPC ;
4262
- }
4243
+ // Skip the block if it wasn't emitted.
4244
+ if (!BB.getOutputAddressRange ().first )
4245
+ continue ;
4263
4246
4264
- InputOffset = BB->getEndOffset ();
4265
- ++BBI;
4266
- } while (InputOffset < InputEndOffset);
4267
- }
4247
+ // Find output address for an instruction with an offset greater or equal
4248
+ // to /p Offset. The output address should fall within the same basic
4249
+ // block boundaries.
4250
+ auto translateBlockOffset = [&](const uint64_t Offset) {
4251
+ const uint64_t OutAddress = BB.getOutputAddressRange ().first + Offset;
4252
+ return OutAddress;
4253
+ };
4268
4254
4269
- // Post-processing pass to sort and merge ranges.
4270
- llvm::sort (OutputRanges);
4271
- DebugAddressRangesVector MergedRanges;
4272
- PrevEndAddress = 0 ;
4273
- for (const DebugAddressRange &Range : OutputRanges) {
4274
- if (Range.LowPC <= PrevEndAddress) {
4275
- MergedRanges.back ().HighPC =
4276
- std::max (MergedRanges.back ().HighPC , Range.HighPC );
4277
- } else {
4278
- MergedRanges.emplace_back (Range.LowPC , Range.HighPC );
4255
+ uint64_t OutLowPC = BB.getOutputAddressRange ().first ;
4256
+ if (InputOffset > BB.getOffset ())
4257
+ OutLowPC = translateBlockOffset (InputOffset - BB.getOffset ());
4258
+
4259
+ uint64_t OutHighPC = BB.getOutputAddressRange ().second ;
4260
+ if (InputEndOffset < BB.getEndOffset ()) {
4261
+ assert (InputEndOffset >= BB.getOffset ());
4262
+ OutHighPC = translateBlockOffset (InputEndOffset - BB.getOffset ());
4279
4263
}
4280
- PrevEndAddress = MergedRanges.back ().HighPC ;
4264
+
4265
+ // Check if we can expand the last translated range.
4266
+ if (!OutRanges.empty () && OutRanges.back ().HighPC == OutLowPC)
4267
+ OutRanges.back ().HighPC = std::max (OutRanges.back ().HighPC , OutHighPC);
4268
+ else
4269
+ OutRanges.emplace_back (OutLowPC, std::max (OutLowPC, OutHighPC));
4281
4270
}
4282
4271
4283
- return MergedRanges;
4272
+ LLVM_DEBUG ({
4273
+ dbgs () << " BOLT-DEBUG: translated address range " << InRange << " -> " ;
4274
+ for (const DebugAddressRange &R : OutRanges)
4275
+ dbgs () << R << ' ' ;
4276
+ dbgs () << ' \n ' ;
4277
+ });
4278
+
4279
+ return OutRanges;
4284
4280
}
4285
4281
4286
4282
MCInst *BinaryFunction::getInstructionAtOffset (uint64_t Offset) {
@@ -4311,92 +4307,6 @@ MCInst *BinaryFunction::getInstructionAtOffset(uint64_t Offset) {
4311
4307
}
4312
4308
}
4313
4309
4314
- DebugLocationsVector BinaryFunction::translateInputToOutputLocationList (
4315
- const DebugLocationsVector &InputLL) const {
4316
- DebugLocationsVector OutputLL;
4317
-
4318
- if (isFolded ())
4319
- return OutputLL;
4320
-
4321
- // If the function hasn't changed - there's nothing to update.
4322
- if (!isEmitted ())
4323
- return InputLL;
4324
-
4325
- uint64_t PrevEndAddress = 0 ;
4326
- SmallVectorImpl<uint8_t > *PrevExpr = nullptr ;
4327
- for (const DebugLocationEntry &Entry : InputLL) {
4328
- const uint64_t Start = Entry.LowPC ;
4329
- const uint64_t End = Entry.HighPC ;
4330
- if (!containsAddress (Start)) {
4331
- LLVM_DEBUG (dbgs () << " BOLT-DEBUG: invalid debug address range detected "
4332
- " for "
4333
- << *this << " : [0x" << Twine::utohexstr (Start)
4334
- << " , 0x" << Twine::utohexstr (End) << " ]\n " );
4335
- continue ;
4336
- }
4337
- uint64_t InputOffset = Start - getAddress ();
4338
- const uint64_t InputEndOffset = std::min (End - getAddress (), getSize ());
4339
- auto BBI = llvm::upper_bound (BasicBlockOffsets,
4340
- BasicBlockOffset (InputOffset, nullptr ),
4341
- CompareBasicBlockOffsets ());
4342
- --BBI;
4343
- do {
4344
- const BinaryBasicBlock *BB = BBI->second ;
4345
- if (InputOffset < BB->getOffset () || InputOffset >= BB->getEndOffset ()) {
4346
- LLVM_DEBUG (dbgs () << " BOLT-DEBUG: invalid debug address range detected "
4347
- " for "
4348
- << *this << " : [0x" << Twine::utohexstr (Start)
4349
- << " , 0x" << Twine::utohexstr (End) << " ]\n " );
4350
- PrevEndAddress = 0 ;
4351
- break ;
4352
- }
4353
-
4354
- // Skip the range if the block was deleted.
4355
- if (const uint64_t OutputStart = BB->getOutputAddressRange ().first ) {
4356
- const uint64_t StartAddress =
4357
- OutputStart + InputOffset - BB->getOffset ();
4358
- uint64_t EndAddress = BB->getOutputAddressRange ().second ;
4359
- if (InputEndOffset < BB->getEndOffset ())
4360
- EndAddress = StartAddress + InputEndOffset - InputOffset;
4361
-
4362
- if (StartAddress == PrevEndAddress && Entry.Expr == *PrevExpr) {
4363
- OutputLL.back ().HighPC = std::max (OutputLL.back ().HighPC , EndAddress);
4364
- } else {
4365
- OutputLL.emplace_back (DebugLocationEntry{
4366
- StartAddress, std::max (StartAddress, EndAddress), Entry.Expr });
4367
- }
4368
- PrevEndAddress = OutputLL.back ().HighPC ;
4369
- PrevExpr = &OutputLL.back ().Expr ;
4370
- }
4371
-
4372
- ++BBI;
4373
- InputOffset = BB->getEndOffset ();
4374
- } while (InputOffset < InputEndOffset);
4375
- }
4376
-
4377
- // Sort and merge adjacent entries with identical location.
4378
- llvm::stable_sort (
4379
- OutputLL, [](const DebugLocationEntry &A, const DebugLocationEntry &B) {
4380
- return A.LowPC < B.LowPC ;
4381
- });
4382
- DebugLocationsVector MergedLL;
4383
- PrevEndAddress = 0 ;
4384
- PrevExpr = nullptr ;
4385
- for (const DebugLocationEntry &Entry : OutputLL) {
4386
- if (Entry.LowPC <= PrevEndAddress && *PrevExpr == Entry.Expr ) {
4387
- MergedLL.back ().HighPC = std::max (Entry.HighPC , MergedLL.back ().HighPC );
4388
- } else {
4389
- const uint64_t Begin = std::max (Entry.LowPC , PrevEndAddress);
4390
- const uint64_t End = std::max (Begin, Entry.HighPC );
4391
- MergedLL.emplace_back (DebugLocationEntry{Begin, End, Entry.Expr });
4392
- }
4393
- PrevEndAddress = MergedLL.back ().HighPC ;
4394
- PrevExpr = &MergedLL.back ().Expr ;
4395
- }
4396
-
4397
- return MergedLL;
4398
- }
4399
-
4400
4310
void BinaryFunction::printLoopInfo (raw_ostream &OS) const {
4401
4311
if (!opts::shouldPrint (*this ))
4402
4312
return ;
0 commit comments