@@ -191,7 +191,7 @@ static bool ParseLine(const StringRef &Input, bool &IsCallsite, uint32_t &Depth,
191
191
// / the expected format.
192
192
// /
193
193
// / \returns true if the file was loaded successfully, false otherwise.
194
- std::error_code SampleProfileReaderText::read () {
194
+ std::error_code SampleProfileReaderText::readImpl () {
195
195
line_iterator LineIt (*Buffer, /* SkipBlanks=*/ true , ' #' );
196
196
sampleprof_error Result = sampleprof_error::success;
197
197
@@ -461,7 +461,7 @@ SampleProfileReaderBinary::readFuncProfile(const uint8_t *Start) {
461
461
return sampleprof_error::success;
462
462
}
463
463
464
- std::error_code SampleProfileReaderBinary::read () {
464
+ std::error_code SampleProfileReaderBinary::readImpl () {
465
465
while (!at_eof ()) {
466
466
if (std::error_code EC = readFuncProfile (Data))
467
467
return EC;
@@ -540,15 +540,23 @@ std::error_code SampleProfileReaderExtBinary::readFuncProfiles() {
540
540
return sampleprof_error::success;
541
541
}
542
542
543
- for (auto Name : FuncsToUse) {
544
- auto iter = FuncOffsetTable.find (Name);
545
- if (iter == FuncOffsetTable.end ())
543
+ if (Remapper) {
544
+ for (auto Name : FuncsToUse) {
545
+ Remapper->insert (Name);
546
+ }
547
+ }
548
+
549
+ for (auto NameOffset : FuncOffsetTable) {
550
+ auto FuncName = NameOffset.first ;
551
+ if (!FuncsToUse.count (FuncName) &&
552
+ (!Remapper || !Remapper->exist (FuncName)))
546
553
continue ;
547
- const uint8_t *FuncProfileAddr = Start + iter-> second ;
554
+ const uint8_t *FuncProfileAddr = Start + NameOffset. second ;
548
555
assert (FuncProfileAddr < End && " out of LBRProfile section" );
549
556
if (std::error_code EC = readFuncProfile (FuncProfileAddr))
550
557
return EC;
551
558
}
559
+
552
560
Data = End;
553
561
return sampleprof_error::success;
554
562
}
@@ -593,7 +601,7 @@ std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
593
601
return sampleprof_error::success;
594
602
}
595
603
596
- std::error_code SampleProfileReaderExtBinaryBase::read () {
604
+ std::error_code SampleProfileReaderExtBinaryBase::readImpl () {
597
605
const uint8_t *BufStart =
598
606
reinterpret_cast <const uint8_t *>(Buffer->getBufferStart ());
599
607
@@ -635,7 +643,7 @@ std::error_code SampleProfileReaderExtBinaryBase::read() {
635
643
return sampleprof_error::success;
636
644
}
637
645
638
- std::error_code SampleProfileReaderCompactBinary::read () {
646
+ std::error_code SampleProfileReaderCompactBinary::readImpl () {
639
647
std::vector<uint64_t > OffsetsToUse;
640
648
if (UseAllFuncs) {
641
649
for (auto FuncEntry : FuncOffsetTable) {
@@ -1184,7 +1192,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
1184
1192
// /
1185
1193
// / This format is generated by the Linux Perf conversion tool at
1186
1194
// / https://github.com/google/autofdo.
1187
- std::error_code SampleProfileReaderGCC::read () {
1195
+ std::error_code SampleProfileReaderGCC::readImpl () {
1188
1196
// Read the string table.
1189
1197
if (std::error_code EC = readNameTable ())
1190
1198
return EC;
@@ -1201,38 +1209,31 @@ bool SampleProfileReaderGCC::hasFormat(const MemoryBuffer &Buffer) {
1201
1209
return Magic == " adcg*704" ;
1202
1210
}
1203
1211
1204
- std::error_code SampleProfileReaderItaniumRemapper::read ( ) {
1205
- // If the underlying data is in compact format, we can't remap it because
1212
+ void SampleProfileReaderItaniumRemapper::applyRemapping (LLVMContext &Ctx ) {
1213
+ // If the reader is in compact format, we can't remap it because
1206
1214
// we don't know what the original function names were.
1207
- if (getFormat () == SPF_Compact_Binary) {
1215
+ if (Reader. getFormat () == SPF_Compact_Binary) {
1208
1216
Ctx.diagnose (DiagnosticInfoSampleProfile (
1209
- Buffer ->getBufferIdentifier (),
1217
+ Reader. getBuffer () ->getBufferIdentifier (),
1210
1218
" Profile data remapping cannot be applied to profile data "
1211
1219
" in compact format (original mangled names are not available)." ,
1212
1220
DS_Warning));
1213
- return sampleprof_error::success;
1214
- }
1215
-
1216
- if (Error E = Remappings.read (*Buffer)) {
1217
- handleAllErrors (
1218
- std::move (E), [&](const SymbolRemappingParseError &ParseError) {
1219
- reportError (ParseError.getLineNum (), ParseError.getMessage ());
1220
- });
1221
- return sampleprof_error::malformed;
1221
+ return ;
1222
1222
}
1223
1223
1224
- for (auto &Sample : getProfiles ())
1225
- if (auto Key = Remappings.insert (Sample.first ()))
1224
+ assert (Remappings && " should be initialized while creating remapper" );
1225
+ for (auto &Sample : Reader.getProfiles ())
1226
+ if (auto Key = Remappings->insert (Sample.first ()))
1226
1227
SampleMap.insert ({Key, &Sample.second });
1227
1228
1228
- return sampleprof_error::success ;
1229
+ RemappingApplied = true ;
1229
1230
}
1230
1231
1231
1232
FunctionSamples *
1232
1233
SampleProfileReaderItaniumRemapper::getSamplesFor (StringRef Fname) {
1233
- if (auto Key = Remappings. lookup (Fname))
1234
+ if (auto Key = Remappings-> lookup (Fname))
1234
1235
return SampleMap.lookup (Key);
1235
- return SampleProfileReader::getSamplesFor (Fname) ;
1236
+ return nullptr ;
1236
1237
}
1237
1238
1238
1239
// / Prepare a memory buffer for the contents of \p Filename.
@@ -1258,34 +1259,65 @@ setupMemoryBuffer(const Twine &Filename) {
1258
1259
// /
1259
1260
// / \param C The LLVM context to use to emit diagnostics.
1260
1261
// /
1262
+ // / \param RemapFilename The file used for profile remapping.
1263
+ // /
1261
1264
// / \returns an error code indicating the status of the created reader.
1262
1265
ErrorOr<std::unique_ptr<SampleProfileReader>>
1263
- SampleProfileReader::create (const Twine &Filename, LLVMContext &C) {
1266
+ SampleProfileReader::create (const std::string Filename, LLVMContext &C,
1267
+ const std::string RemapFilename) {
1264
1268
auto BufferOrError = setupMemoryBuffer (Filename);
1265
1269
if (std::error_code EC = BufferOrError.getError ())
1266
1270
return EC;
1267
- return create (BufferOrError.get (), C);
1271
+ return create (BufferOrError.get (), C, RemapFilename );
1268
1272
}
1269
1273
1270
1274
// / Create a sample profile remapper from the given input, to remap the
1271
1275
// / function names in the given profile data.
1272
1276
// /
1273
1277
// / \param Filename The file to open.
1274
1278
// /
1275
- // / \param C The LLVM context to use to emit diagnostics .
1279
+ // / \param Reader The profile reader the remapper is going to be applied to .
1276
1280
// /
1277
- // / \param Underlying The underlying profile data reader to remap .
1281
+ // / \param C The LLVM context to use to emit diagnostics .
1278
1282
// /
1279
1283
// / \returns an error code indicating the status of the created reader.
1280
- ErrorOr<std::unique_ptr<SampleProfileReader >>
1281
- SampleProfileReaderItaniumRemapper::create (
1282
- const Twine &Filename, LLVMContext &C ,
1283
- std::unique_ptr<SampleProfileReader> Underlying ) {
1284
+ ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper >>
1285
+ SampleProfileReaderItaniumRemapper::create (const std::string Filename,
1286
+ SampleProfileReader &Reader ,
1287
+ LLVMContext &C ) {
1284
1288
auto BufferOrError = setupMemoryBuffer (Filename);
1285
1289
if (std::error_code EC = BufferOrError.getError ())
1286
1290
return EC;
1291
+ return create (BufferOrError.get (), Reader, C);
1292
+ }
1293
+
1294
+ // / Create a sample profile remapper from the given input, to remap the
1295
+ // / function names in the given profile data.
1296
+ // /
1297
+ // / \param B The memory buffer to create the reader from (assumes ownership).
1298
+ // /
1299
+ // / \param C The LLVM context to use to emit diagnostics.
1300
+ // /
1301
+ // / \param Reader The profile reader the remapper is going to be applied to.
1302
+ // /
1303
+ // / \returns an error code indicating the status of the created reader.
1304
+ ErrorOr<std::unique_ptr<SampleProfileReaderItaniumRemapper>>
1305
+ SampleProfileReaderItaniumRemapper::create (std::unique_ptr<MemoryBuffer> &B,
1306
+ SampleProfileReader &Reader,
1307
+ LLVMContext &C) {
1308
+ auto Remappings = std::make_unique<SymbolRemappingReader>();
1309
+ if (Error E = Remappings->read (*B.get ())) {
1310
+ handleAllErrors (
1311
+ std::move (E), [&](const SymbolRemappingParseError &ParseError) {
1312
+ C.diagnose (DiagnosticInfoSampleProfile (B->getBufferIdentifier (),
1313
+ ParseError.getLineNum (),
1314
+ ParseError.getMessage ()));
1315
+ });
1316
+ return sampleprof_error::malformed;
1317
+ }
1318
+
1287
1319
return std::make_unique<SampleProfileReaderItaniumRemapper>(
1288
- std::move (BufferOrError. get ()), C, std::move (Underlying) );
1320
+ std::move (B), std::move (Remappings), Reader );
1289
1321
}
1290
1322
1291
1323
// / Create a sample profile reader based on the format of the input data.
@@ -1294,9 +1326,12 @@ SampleProfileReaderItaniumRemapper::create(
1294
1326
// /
1295
1327
// / \param C The LLVM context to use to emit diagnostics.
1296
1328
// /
1329
+ // / \param RemapFilename The file used for profile remapping.
1330
+ // /
1297
1331
// / \returns an error code indicating the status of the created reader.
1298
1332
ErrorOr<std::unique_ptr<SampleProfileReader>>
1299
- SampleProfileReader::create (std::unique_ptr<MemoryBuffer> &B, LLVMContext &C) {
1333
+ SampleProfileReader::create (std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
1334
+ const std::string RemapFilename) {
1300
1335
std::unique_ptr<SampleProfileReader> Reader;
1301
1336
if (SampleProfileReaderRawBinary::hasFormat (*B))
1302
1337
Reader.reset (new SampleProfileReaderRawBinary (std::move (B), C));
@@ -1311,6 +1346,17 @@ SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C) {
1311
1346
else
1312
1347
return sampleprof_error::unrecognized_format;
1313
1348
1349
+ if (!RemapFilename.empty ()) {
1350
+ auto ReaderOrErr =
1351
+ SampleProfileReaderItaniumRemapper::create (RemapFilename, *Reader, C);
1352
+ if (std::error_code EC = ReaderOrErr.getError ()) {
1353
+ std::string Msg = " Could not create remapper: " + EC.message ();
1354
+ C.diagnose (DiagnosticInfoSampleProfile (RemapFilename, Msg));
1355
+ return EC;
1356
+ }
1357
+ Reader->Remapper = std::move (ReaderOrErr.get ());
1358
+ }
1359
+
1314
1360
FunctionSamples::Format = Reader->getFormat ();
1315
1361
if (std::error_code EC = Reader->readHeader ()) {
1316
1362
return EC;
0 commit comments