mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-17 03:26:48 +00:00

We used to emit EH trampolines for PIE/DSO whenever a function fragment contained a landing pad outside of it. However, it is common to have all landing pads in a cold fragment even when their throwers are in a hot one. To reduce the number of trampolines, analyze landing pads for any given function fragment, and if they all belong to the same (possibly different) fragment, designate that fragment as a landing pad fragment for the "thrower" fragment. Later, emit landing pad fragment symbol as an LPStart for the thrower LSDA.
87 lines
2.4 KiB
ArmAsm
87 lines
2.4 KiB
ArmAsm
# REQUIRES: system-linux
|
|
|
|
# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-linux %s -o %t.o
|
|
# RUN: link_fdata %s %t.o %t.fdata
|
|
# RUN: llvm-strip --strip-unneeded %t.o
|
|
# RUN: ld.lld --pie %t.o -o %t.exe -q
|
|
# RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --split-functions --split-eh \
|
|
# RUN: --split-all-cold --print-after-lowering --print-only=_start 2>&1 \
|
|
# RUN: | FileCheck %s
|
|
|
|
## _start has two landing pads: one hot and one cold. Hence, BOLT will introduce
|
|
## a landing pad trampoline. However, the trampoline code will make the main
|
|
## split fragment larger than the whole function before split. Then BOLT will
|
|
## undo the splitting and remove the trampoline.
|
|
|
|
# CHECK: Binary Function "_start"
|
|
# CHECK: IsSplit :
|
|
# CHECK-SAME: 0
|
|
|
|
## Check that a landing pad trampoline was created, but contains no instructions
|
|
## and falls though to the real landing pad.
|
|
|
|
# CHECK: {{^[^[:space:]]+}} (0 instructions
|
|
# CHECK-NEXT: Landing Pad{{$}}
|
|
# CHECK: Exec Count
|
|
# CHECK-SAME: : 0
|
|
# CHECK: Successors:
|
|
# CHECK-SAME: [[LP:[^[:space:]]+]]
|
|
# CHECK-EMPTY:
|
|
# CHECK-NEXT: [[LP]]
|
|
|
|
.text
|
|
.global foo
|
|
.type foo, %function
|
|
foo:
|
|
.cfi_startproc
|
|
ret
|
|
.cfi_endproc
|
|
.size foo, .-foo
|
|
|
|
.globl _start
|
|
.type _start, %function
|
|
_start:
|
|
# FDATA: 0 [unknown] 0 1 _start 0 1 100
|
|
.Lfunc_begin0:
|
|
.cfi_startproc
|
|
.cfi_lsda 27, .Lexception0
|
|
call foo
|
|
.Ltmp0:
|
|
call foo
|
|
.Ltmp1:
|
|
ret
|
|
|
|
## Cold landing pad.
|
|
.LLP1:
|
|
ret
|
|
|
|
## Hot landing pad.
|
|
LLP0:
|
|
# FDATA: 0 [unknown] 0 1 _start #LLP0# 1 100
|
|
ret
|
|
|
|
.cfi_endproc
|
|
.Lfunc_end0:
|
|
.size _start, .-_start
|
|
|
|
## EH table.
|
|
.section .gcc_except_table,"a",@progbits
|
|
.p2align 2
|
|
GCC_except_table0:
|
|
.Lexception0:
|
|
.byte 255 # @LPStart Encoding = omit
|
|
.byte 255 # @TType Encoding = omit
|
|
.byte 1 # Call site Encoding = uleb128
|
|
.uleb128 .Lcst_end0-.Lcst_begin0
|
|
.Lcst_begin0:
|
|
.uleb128 .Lfunc_begin0-.Lfunc_begin0 # >> Call Site 1 <<
|
|
.uleb128 .Ltmp0-.Lfunc_begin0 # Call between .Lfunc_begin0 and .Ltmp0
|
|
.uleb128 LLP0-.Lfunc_begin0 # jumps to LLP0
|
|
.byte 0 # On action: cleanup
|
|
.uleb128 .Ltmp0-.Lfunc_begin0 # >> Call Site 2 <<
|
|
.uleb128 .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
|
|
.uleb128 .LLP1-.Lfunc_begin0 # jumps to .LLP1
|
|
.byte 0 # On action: cleanup
|
|
.Lcst_end0:
|
|
|