diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 1c5ce5d0a6cd0..644d87eeca42e 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -1513,6 +1513,23 @@ void RewriteInstance::registerFragments() { StopSymbol = *FSI; uint64_t ParentAddress{0}; + + // BOLT split fragment symbols are emitted just before the main function + // symbol. + for (ELFSymbolRef NextSymbol = Symbol; NextSymbol < StopSymbol; + NextSymbol.moveNext()) { + StringRef Name = cantFail(NextSymbol.getName()); + if (Name == ParentName) { + ParentAddress = cantFail(NextSymbol.getValue()); + goto registerParent; + } + if (Name.starts_with(ParentName)) + // With multi-way splitting, there are multiple fragments with different + // suffixes. Parent follows the last fragment. + continue; + break; + } + // Iterate over local file symbols and check symbol names to match parent. for (ELFSymbolRef Symbol(FSI[-1]); Symbol < StopSymbol; Symbol.moveNext()) { if (cantFail(Symbol.getName()) == ParentName) { @@ -1521,6 +1538,7 @@ void RewriteInstance::registerFragments() { } } +registerParent: // No local parent is found, use global parent function. if (!ParentAddress) if (BinaryData *ParentBD = BC->getBinaryDataByName(ParentName)) diff --git a/bolt/test/X86/register-fragments-bolt-symbols.s b/bolt/test/X86/register-fragments-bolt-symbols.s new file mode 100644 index 0000000000000..fa9b70e0b2d89 --- /dev/null +++ b/bolt/test/X86/register-fragments-bolt-symbols.s @@ -0,0 +1,32 @@ +# Test the heuristics for matching BOLT-added split functions. + +# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %S/cdsplit-symbol-names.s -o %t.main.o +# RUN: llvm-mc --filetype=obj --triple x86_64-unknown-unknown %s -o %t.chain.o +# RUN: link_fdata %S/cdsplit-symbol-names.s %t.main.o %t.fdata +# RUN: sed -i 's|chain|chain/2|g' %t.fdata +# RUN: llvm-strip --strip-unneeded %t.main.o +# RUN: llvm-objcopy --localize-symbol=chain %t.main.o +# RUN: %clang %cflags %t.chain.o %t.main.o -o %t.exe -Wl,-q +# RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=randomN \ +# RUN: --reorder-blocks=ext-tsp --enable-bat --bolt-seed=7 --data=%t.fdata +# RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS + +# RUN: link_fdata %s %t.bolt %t.preagg PREAGG +# PREAGG: B X:0 #chain.cold.0# 1 0 +# RUN: perf2bolt %t.bolt -p %t.preagg --pa -o %t.bat.fdata -w %t.bat.yaml -v=1 \ +# RUN: | FileCheck %s --check-prefix=CHECK-REGISTER + +# CHECK-SYMS: l df *ABS* [[#]] chain.s +# CHECK-SYMS: l F .bolt.org.text [[#]] chain +# CHECK-SYMS: l F .text.cold [[#]] chain.cold.0 +# CHECK-SYMS: l F .text [[#]] chain +# CHECK-SYMS: l df *ABS* [[#]] bolt-pseudo.o + +# CHECK-REGISTER: BOLT-INFO: marking chain.cold.0/1(*2) as a fragment of chain/2(*2) + +.file "chain.s" + .text + .type chain, @function +chain: + ret + .size chain, .-chain