diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp --- a/bolt/lib/Passes/ReorderFunctions.cpp +++ b/bolt/lib/Passes/ReorderFunctions.cpp @@ -12,6 +12,8 @@ #include "bolt/Passes/ReorderFunctions.h" #include "bolt/Passes/HFSort.h" +#include "bolt/Utils/Utils.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/CommandLine.h" #include @@ -332,6 +334,13 @@ break; case RT_USER: { + // Build LTOCommonNameMap + StringMap> LTOCommonNameMap; + for (const BinaryFunction &BF : llvm::make_second_range(BFs)) + for (StringRef Name : BF.getNames()) + if (std::optional LTOCommonName = getLTOCommonName(Name)) + LTOCommonNameMap[*LTOCommonName].push_back(BF.getAddress()); + uint32_t Index = 0; uint32_t InvalidEntries = 0; for (const std::string &Function : readFunctionOrderFile()) { @@ -339,9 +348,9 @@ BinaryData *BD = BC.getBinaryDataByName(Function); if (!BD) { + // If we can't find the main symbol name, look for alternates. uint32_t LocalID = 1; while (true) { - // If we can't find the main symbol name, look for alternates. const std::string FuncName = Function + "/" + std::to_string(LocalID); BD = BC.getBinaryDataByName(FuncName); @@ -351,6 +360,10 @@ break; LocalID++; } + // Strip LTO suffixes + if (std::optional CommonName = getLTOCommonName(Function)) + if (LTOCommonNameMap.find(*CommonName) != LTOCommonNameMap.end()) + llvm::append_range(FuncAddrs, LTOCommonNameMap[*CommonName]); } else { FuncAddrs.push_back(BD->getAddress()); } diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -2756,10 +2756,14 @@ LiteThresholdExecCount, static_cast(opts::LiteThresholdCount)); StringSet<> ReorderFunctionsUserSet; + StringSet<> ReorderFunctionsLTOCommonSet; if (opts::ReorderFunctions == ReorderFunctions::RT_USER) { for (const std::string &Function : - ReorderFunctions::readFunctionOrderFile()) + ReorderFunctions::readFunctionOrderFile()) { ReorderFunctionsUserSet.insert(Function); + if (std::optional LTOCommonName = getLTOCommonName(Function)) + ReorderFunctionsLTOCommonSet.insert(*LTOCommonName); + } } uint64_t NumFunctionsToProcess = 0; @@ -2795,6 +2799,10 @@ }); if (Match.has_value()) return true; + for (const StringRef Name : Function.getNames()) + if (std::optional LTOCommonName = getLTOCommonName(Name)) + if (ReorderFunctionsLTOCommonSet.contains(*LTOCommonName)) + return true; } if (ProfileReader && !ProfileReader->mayHaveProfileData(Function)) diff --git a/bolt/test/X86/Inputs/order-lite.txt b/bolt/test/X86/Inputs/order-lite.txt --- a/bolt/test/X86/Inputs/order-lite.txt +++ b/bolt/test/X86/Inputs/order-lite.txt @@ -1 +1,2 @@ main +foo.__uniq.321 diff --git a/bolt/test/X86/function-order-lite.s b/bolt/test/X86/function-order-lite.s --- a/bolt/test/X86/function-order-lite.s +++ b/bolt/test/X86/function-order-lite.s @@ -8,8 +8,9 @@ # RUN: --function-order=%p/Inputs/order-lite.txt -o %t -print-all 2>&1 \ # RUN: | FileCheck %s -# CHECK: 1 out of 2 functions in the binary (50.0%) have non-empty execution profile -# CHECK: Binary Function "main" after reorder-functions +# CHECK: 1 out of 3 functions in the binary (33.3%) have non-empty execution profile +# CHECK-DAG: Binary Function "main" after reorder-functions +# CHECK-DAG: Binary Function "foo.__uniq.123" after reorder-functions .globl main .type main, %function @@ -33,3 +34,15 @@ retq .cfi_endproc .size testfunc, .-testfunc + + .globl foo.__uniq.123 + .type foo.__uniq.123, %function +foo.__uniq.123: + .cfi_startproc + pushq %rbp + movq %rsp, %rbp + movl $0x0, %eax + popq %rbp + retq + .cfi_endproc +.size foo.__uniq.123, .-foo.__uniq.123