27
27
#include " llvm/IR/Instruction.h"
28
28
#include " llvm/IR/LLVMContext.h"
29
29
#include " llvm/IR/MDBuilder.h"
30
+ #include " llvm/IR/Mangler.h"
30
31
#include " llvm/IR/Metadata.h"
31
32
#include " llvm/IR/Module.h"
32
33
#include " llvm/IR/Type.h"
@@ -264,6 +265,67 @@ static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix) {
264
265
return PathNameStr.substr (LastPos);
265
266
}
266
267
268
+ static StringRef getStrippedSourceFileName (const Function &F) {
269
+ StringRef FileName (F.getParent ()->getSourceFileName ());
270
+ uint32_t StripLevel = StaticFuncFullModulePrefix ? 0 : (uint32_t )-1 ;
271
+ if (StripLevel < StaticFuncStripDirNamePrefix)
272
+ StripLevel = StaticFuncStripDirNamePrefix;
273
+ if (StripLevel)
274
+ FileName = stripDirPrefix (FileName, StripLevel);
275
+ return FileName;
276
+ }
277
+
278
+ // The PGO name has the format [<filepath>;]<linkage-name> where <filepath>; is
279
+ // provided if linkage is local and <linkage-name> is the mangled function
280
+ // name. The filepath is used to discriminate possibly identical function names.
281
+ // ; is used because it is unlikely to be found in either <filepath> or
282
+ // <linkage-name>.
283
+ //
284
+ // Older compilers used getPGOFuncName() which has the format
285
+ // [<filepath>:]<function-name>. <filepath> is used to discriminate between
286
+ // possibly identical function names when linkage is local and <function-name>
287
+ // simply comes from F.getName(). This caused trouble for Objective-C functions
288
+ // which commonly have :'s in their names. Also, since <function-name> is not
289
+ // mangled, they cannot be passed to Mach-O linkers via -order_file. We still
290
+ // need to compute this name to lookup functions from profiles built by older
291
+ // compilers.
292
+ static std::string getIRPGOFuncName (const Function &F,
293
+ GlobalValue::LinkageTypes Linkage,
294
+ StringRef FileName) {
295
+ SmallString<64 > Name;
296
+ if (llvm::GlobalValue::isLocalLinkage (Linkage)) {
297
+ Name.append (FileName.empty () ? " <unknown>" : FileName);
298
+ Name.append (" ;" );
299
+ }
300
+ Mangler ().getNameWithPrefix (Name, &F, /* CannotUsePrivateLabel=*/ true );
301
+ return Name.str ().str ();
302
+ }
303
+
304
+ static std::optional<std::string> lookupPGOFuncName (const Function &F) {
305
+ if (MDNode *MD = getPGOFuncNameMetadata (F)) {
306
+ StringRef S = cast<MDString>(MD->getOperand (0 ))->getString ();
307
+ return S.str ();
308
+ }
309
+ return {};
310
+ }
311
+
312
+ // See getPGOFuncName()
313
+ std::string getIRPGOFuncName (const Function &F, bool InLTO) {
314
+ if (!InLTO) {
315
+ auto FileName = getStrippedSourceFileName (F);
316
+ return getIRPGOFuncName (F, F.getLinkage (), FileName);
317
+ }
318
+
319
+ // In LTO mode (when InLTO is true), first check if there is a meta data.
320
+ if (auto IRPGOFuncName = lookupPGOFuncName (F))
321
+ return *IRPGOFuncName;
322
+
323
+ // If there is no meta data, the function must be a global before the value
324
+ // profile annotation pass. Its current linkage may be internal if it is
325
+ // internalized in LTO mode.
326
+ return getIRPGOFuncName (F, GlobalValue::ExternalLinkage, " " );
327
+ }
328
+
267
329
// Return the PGOFuncName. This function has some special handling when called
268
330
// in LTO optimization. The following only applies when calling in LTO passes
269
331
// (when \c InLTO is true): LTO's internalization privatizes many global linkage
@@ -279,27 +341,29 @@ static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix) {
279
341
// data, its original linkage must be non-internal.
280
342
std::string getPGOFuncName (const Function &F, bool InLTO, uint64_t Version) {
281
343
if (!InLTO) {
282
- StringRef FileName (F.getParent ()->getSourceFileName ());
283
- uint32_t StripLevel = StaticFuncFullModulePrefix ? 0 : (uint32_t )-1 ;
284
- if (StripLevel < StaticFuncStripDirNamePrefix)
285
- StripLevel = StaticFuncStripDirNamePrefix;
286
- if (StripLevel)
287
- FileName = stripDirPrefix (FileName, StripLevel);
344
+ auto FileName = getStrippedSourceFileName (F);
288
345
return getPGOFuncName (F.getName (), F.getLinkage (), FileName, Version);
289
346
}
290
347
291
348
// In LTO mode (when InLTO is true), first check if there is a meta data.
292
- if (MDNode *MD = getPGOFuncNameMetadata (F)) {
293
- StringRef S = cast<MDString>(MD->getOperand (0 ))->getString ();
294
- return S.str ();
295
- }
349
+ if (auto PGOFuncName = lookupPGOFuncName (F))
350
+ return *PGOFuncName;
296
351
297
352
// If there is no meta data, the function must be a global before the value
298
353
// profile annotation pass. Its current linkage may be internal if it is
299
354
// internalized in LTO mode.
300
355
return getPGOFuncName (F.getName (), GlobalValue::ExternalLinkage, " " );
301
356
}
302
357
358
+ // See getIRPGOFuncName() for a discription of the format.
359
+ std::pair<StringRef, StringRef>
360
+ getParsedIRPGOFuncName (StringRef IRPGOFuncName) {
361
+ auto [FileName, FuncName] = IRPGOFuncName.split (' ;' );
362
+ if (FuncName.empty ())
363
+ return std::make_pair (StringRef (), IRPGOFuncName);
364
+ return std::make_pair (FileName, FuncName);
365
+ }
366
+
303
367
StringRef getFuncNameWithoutPrefix (StringRef PGOFuncName, StringRef FileName) {
304
368
if (FileName.empty ())
305
369
return PGOFuncName;
@@ -320,7 +384,7 @@ std::string getPGOFuncNameVarName(StringRef FuncName,
320
384
return VarName;
321
385
322
386
// Now fix up illegal chars in local VarName that may upset the assembler.
323
- const char * InvalidChars = " -:<>/\" '" ;
387
+ const char InvalidChars[] = " -:; <>/\" '" ;
324
388
size_t found = VarName.find_first_of (InvalidChars);
325
389
while (found != std::string::npos) {
326
390
VarName[found] = ' _' ;
@@ -366,41 +430,49 @@ Error InstrProfSymtab::create(Module &M, bool InLTO) {
366
430
// Ignore in this case.
367
431
if (!F.hasName ())
368
432
continue ;
369
- const std::string &PGOFuncName = getPGOFuncName (F, InLTO);
370
- if (Error E = addFuncName (PGOFuncName))
433
+ if (Error E = addFuncWithName (F, getIRPGOFuncName (F, InLTO)))
434
+ return E;
435
+ // Also use getPGOFuncName() so that we can find records from older profiles
436
+ if (Error E = addFuncWithName (F, getPGOFuncName (F, InLTO)))
371
437
return E;
372
- MD5FuncMap.emplace_back (Function::getGUID (PGOFuncName), &F);
373
- // In ThinLTO, local function may have been promoted to global and have
374
- // suffix ".llvm." added to the function name. We need to add the
375
- // stripped function name to the symbol table so that we can find a match
376
- // from profile.
377
- //
378
- // We may have other suffixes similar as ".llvm." which are needed to
379
- // be stripped before the matching, but ".__uniq." suffix which is used
380
- // to differentiate internal linkage functions in different modules
381
- // should be kept. Now this is the only suffix with the pattern ".xxx"
382
- // which is kept before matching.
383
- const std::string UniqSuffix = " .__uniq." ;
384
- auto pos = PGOFuncName.find (UniqSuffix);
385
- // Search '.' after ".__uniq." if ".__uniq." exists, otherwise
386
- // search '.' from the beginning.
387
- if (pos != std::string::npos)
388
- pos += UniqSuffix.length ();
389
- else
390
- pos = 0 ;
391
- pos = PGOFuncName.find (' .' , pos);
392
- if (pos != std::string::npos && pos != 0 ) {
393
- const std::string &OtherFuncName = PGOFuncName.substr (0 , pos);
394
- if (Error E = addFuncName (OtherFuncName))
395
- return E;
396
- MD5FuncMap.emplace_back (Function::getGUID (OtherFuncName), &F);
397
- }
398
438
}
399
439
Sorted = false ;
400
440
finalizeSymtab ();
401
441
return Error::success ();
402
442
}
403
443
444
+ Error InstrProfSymtab::addFuncWithName (Function &F, StringRef PGOFuncName) {
445
+ if (Error E = addFuncName (PGOFuncName))
446
+ return E;
447
+ MD5FuncMap.emplace_back (Function::getGUID (PGOFuncName), &F);
448
+ // In ThinLTO, local function may have been promoted to global and have
449
+ // suffix ".llvm." added to the function name. We need to add the
450
+ // stripped function name to the symbol table so that we can find a match
451
+ // from profile.
452
+ //
453
+ // We may have other suffixes similar as ".llvm." which are needed to
454
+ // be stripped before the matching, but ".__uniq." suffix which is used
455
+ // to differentiate internal linkage functions in different modules
456
+ // should be kept. Now this is the only suffix with the pattern ".xxx"
457
+ // which is kept before matching.
458
+ const std::string UniqSuffix = " .__uniq." ;
459
+ auto pos = PGOFuncName.find (UniqSuffix);
460
+ // Search '.' after ".__uniq." if ".__uniq." exists, otherwise
461
+ // search '.' from the beginning.
462
+ if (pos != std::string::npos)
463
+ pos += UniqSuffix.length ();
464
+ else
465
+ pos = 0 ;
466
+ pos = PGOFuncName.find (' .' , pos);
467
+ if (pos != std::string::npos && pos != 0 ) {
468
+ StringRef OtherFuncName = PGOFuncName.substr (0 , pos);
469
+ if (Error E = addFuncName (OtherFuncName))
470
+ return E;
471
+ MD5FuncMap.emplace_back (Function::getGUID (OtherFuncName), &F);
472
+ }
473
+ return Error::success ();
474
+ }
475
+
404
476
uint64_t InstrProfSymtab::getFunctionHashFromAddress (uint64_t Address) {
405
477
finalizeSymtab ();
406
478
auto It = partition_point (AddrToMD5Map, [=](std::pair<uint64_t , uint64_t > A) {
0 commit comments