mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 06:46:36 +00:00

In lite mode (default for X86), BOLT optimizes and relocates functions with profile. The rest of the code is preserved, but if it references relocated code such references have to be updated. The update is handled by scanExternalRefs() function. Note that we cannot solely rely on relocations written by the linker, as not all code references are exposed to the linker. Additionally, the linker can modify certain instructions and relocations will no longer match the code. With this change, start using symbolic disassembler for scanning code for references in scanExternalRefs(). Unlike the previous approach, the symbolizer properly detects and creates references for instructions with multiple/ambiguous symbolic operands and handles cases where a relocation doesn't match any operand. See test cases for examples. Reviewed By: Amir Differential Revision: https://reviews.llvm.org/D152631
68 lines
1.9 KiB
ArmAsm
68 lines
1.9 KiB
ArmAsm
## Check that BOLT can correctly use relocations to symbolize instruction
|
|
## operands when an instruction can have up to two relocations associated
|
|
## with it. The test checks that the update happens in the function that
|
|
## is not being optimized/relocated by BOLT.
|
|
|
|
# REQUIRES: system-linux
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
|
|
# RUN: ld.lld %t.o -o %t.exe -q --Ttext=0x80000
|
|
# RUN: llvm-bolt %t.exe --relocs -o %t.bolt --funcs=foo
|
|
# RUN: llvm-objdump -d --print-imm-hex %t.exe \
|
|
# RUN: | FileCheck %s
|
|
# RUN: llvm-objdump -d --print-imm-hex %t.bolt \
|
|
# RUN: | FileCheck %s --check-prefix=CHECK-POST-BOLT
|
|
|
|
.text
|
|
.globl foo
|
|
.type foo,@function
|
|
foo:
|
|
.cfi_startproc
|
|
ret
|
|
.cfi_endproc
|
|
.size foo, .-foo
|
|
|
|
|
|
.text
|
|
.globl _start
|
|
.type _start,@function
|
|
_start:
|
|
.cfi_startproc
|
|
|
|
## All four MOV instructions below are identical in the input binary, but
|
|
## different from each other after BOLT.
|
|
##
|
|
## foo value is 0x80000 pre-BOLT. Using relocations, llvm-bolt should correctly
|
|
## symbolize 0x80000 instruction operand and differentiate between an immediate
|
|
## constant 0x80000 and a reference to foo. When foo is relocated, BOLT should
|
|
## update references even from the code that is not being updated.
|
|
|
|
# CHECK: 80000 <foo>:
|
|
|
|
# CHECK: <_start>:
|
|
# CHECK-POST-BOLT: <_start>:
|
|
|
|
movq $0x80000, 0x80000
|
|
# CHECK-NEXT: movq $0x80000, 0x80000
|
|
# CHECK-POST-BOLT-NEXT: movq $0x80000, 0x80000
|
|
|
|
movq $foo, 0x80000
|
|
# CHECK-NEXT: movq $0x80000, 0x80000
|
|
# CHECK-POST-BOLT-NEXT: movq $0x[[#%x,ADDR:]], 0x80000
|
|
|
|
movq $0x80000, foo
|
|
# CHECK-NEXT: movq $0x80000, 0x80000
|
|
# CHECK-POST-BOLT-NEXT: movq $0x80000, 0x[[#ADDR]]
|
|
|
|
movq $foo, foo
|
|
# CHECK-NEXT: movq $0x80000, 0x80000
|
|
# CHECK-POST-BOLT-NEXT: movq $0x[[#ADDR]], 0x[[#ADDR]]
|
|
|
|
## After BOLT, foo is relocated after _start.
|
|
|
|
# CHECK-POST-BOLT: [[#ADDR]] <foo>:
|
|
|
|
retq
|
|
.size _start, .-_start
|
|
.cfi_endproc
|