From 543f13c99b1fa87d491f17dc4a9bcead471b3c58 Mon Sep 17 00:00:00 2001 From: Huan Nguyen Date: Sat, 18 Jun 2022 11:38:37 -0700 Subject: [PATCH] [BOLT] Allow function entry to be a cold fragment Allow cold fragment to get new address. Our previous assumption is that a fragment (.cold) is only reached through the main fragment of same function. In addition, .cold fragment must be reached through either (a) direct transfer, or (b) split jump table. For (a), we perform a simple fix-up. For (b), we currently mark all relevant fragments as non-simple. Therefore, there is no need to get new address for .cold fragment. This is not always the case, as function entry can be rarely executed, and is placed in .text.cold segment. Essentially we cannot tell which the source-level function entry is based on hot and cold segments, so we must treat each fragment a function on its own. Therfore, we remove the assertion that a function entry cannot be cold fragment. Test Plan: ``` ninja check-bolt ``` Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D128111 --- bolt/lib/Rewrite/RewriteInstance.cpp | 2 -- bolt/test/X86/shared_object_entry.s | 38 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 bolt/test/X86/shared_object_entry.s diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 5b7548f862c26..b11a498c9375e 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -5207,8 +5207,6 @@ uint64_t RewriteInstance::getNewFunctionAddress(uint64_t OldAddress) { if (!Function) return 0; - assert(!Function->isFragment() && "cannot get new address for a fragment"); - return Function->getOutputAddress(); } diff --git a/bolt/test/X86/shared_object_entry.s b/bolt/test/X86/shared_object_entry.s new file mode 100644 index 0000000000000..ce72f0bf11101 --- /dev/null +++ b/bolt/test/X86/shared_object_entry.s @@ -0,0 +1,38 @@ +# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o +# RUN: ld.lld %t.o -o %t.so --shared --entry=func1.cold.1 --emit-relocs +# RUN: llvm-bolt -relocs %t.so -o %t -reorder-functions=hfsort+ \ +# RUN: -split-functions=3 -reorder-blocks=ext-tsp -split-all-cold \ +# RUN: -dyno-stats -icf=1 -use-gnu-stack + +# Check that an entry point is a cold symbol +# RUN: llvm-readelf -h %t.so > %t.log +# RUN: llvm-nm %t.so >> %t.log +# RUN: FileCheck %s --input-file %t.log +# CHECK: Entry point address: 0x[[#%X,ENTRY:]] +# CHECK: [[#%x,ENTRY]] {{.*}} func1.cold.1 + +.globl func1.cold.1 +.type func1.cold.1,@function +func1.cold.1: + .cfi_startproc +.L1: + movq %rbx, %rdx + jmp .L3 +.L2: + # exit(0) + movq $60, %rax + xorq %rdi, %rdi + syscall + .size func1.cold.1, .-func1.cold.1 + .cfi_endproc + +.globl func1 +.type func1,@function +func1: + .cfi_startproc +.L3: + movq %rax, %rdi + jmp .L2 + call exit + .size func1, .-func1 + .cfi_endproc