[cfe-dev] Code generation for noexcept functions
Stephan Tolksdorf
st at quanttec.com
Sun May 11 08:19:46 PDT 2014
Hi,
When clang/LLVM can't prove that a noexcept function only contains
non-throwing code, it seems to insert an explicit exception handler that
calls std::terminate. Why doesn't clang leave it to the eh personality
function to call std::terminate when an exception is thrown inside a
noexcept function, as GCC does?
For example, GCC generates more efficient code for this test case:
using FP = void(*)();
inline void test(FP fp) noexcept {
fp();
}
void test2(FP fp) {
test(fp);
test(fp);
}
The code generated by GCC (ToT, -O3, Linux x64) is:
.LHOTB0:
.p2align 4,,15
.globl _Z5test2PFvvE
.type _Z5test2PFvvE, @function
_Z5test2PFvvE:
.LFB1:
.cfi_startproc
.cfi_personality 0x3,__gxx_personality_v0
.cfi_lsda 0x3,.LLSDA1
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset 3, -16
movq %rdi, %rbx
call *%rdi
movq %rbx, %rax
popq %rbx
.cfi_def_cfa_offset 8
jmp *%rax
.cfi_endproc
.LFE1:
.globl __gxx_personality_v0
.section .gcc_except_table,"a", at progbits
.LLSDA1:
.byte 0xff
.byte 0xff
.byte 0x1
.uleb128 .LLSDACSE1-.LLSDACSB1
.LLSDACSB1:
.LLSDACSE1:
.text
.size _Z5test2PFvvE, .-_Z5test2PFvvE
.section .text.unlikely
The code generated by clang (ToT, -O3, Linux x64) is:
.globl _Z5test2PFvvE
.align 16, 0x90
.type _Z5test2PFvvE, at function
_Z5test2PFvvE: # @_Z5test2PFvvE
.cfi_startproc
.cfi_personality 3, __gxx_personality_v0
.Leh_func_begin0:
.cfi_lsda 3, .Lexception0
# BB#0: # %entry
pushq %rbx
.Ltmp6:
.cfi_def_cfa_offset 16
.Ltmp7:
.cfi_offset %rbx, -16
movq %rdi, %rbx
.Ltmp0:
callq *%rbx
.Ltmp1:
# BB#1: # %_Z4testPFvvE.exit
.Ltmp3:
callq *%rbx
.Ltmp4:
# BB#2: # %_Z4testPFvvE.exit3
popq %rbx
retq
.LBB0_3: # %terminate.lpad.i
.Ltmp2:
movq %rax, %rdi
callq __clang_call_terminate
.LBB0_4: # %terminate.lpad.i2
.Ltmp5:
movq %rax, %rdi
callq __clang_call_terminate
.Ltmp8:
.size _Z5test2PFvvE, .Ltmp8-_Z5test2PFvvE
.cfi_endproc
.Leh_func_end0:
.section .gcc_except_table,"a", at progbits
.align 4
GCC_except_table0:
.Lexception0:
.byte 255 # @LPStart Encoding = omit
.byte 3 # @TType Encoding = udata4
.asciz "\242\200\200" # @TType base offset
.byte 3 # Call site Encoding = udata4
.byte 26 # Call site table length
.Lset0 = .Ltmp0-.Leh_func_begin0 # >> Call Site 1 <<
.long .Lset0
.Lset1 = .Ltmp1-.Ltmp0 # Call between .Ltmp0 and .Ltmp1
.long .Lset1
.Lset2 = .Ltmp2-.Leh_func_begin0 # jumps to .Ltmp2
.long .Lset2
.byte 1 # On action: 1
.Lset3 = .Ltmp3-.Leh_func_begin0 # >> Call Site 2 <<
.long .Lset3
.Lset4 = .Ltmp4-.Ltmp3 # Call between .Ltmp3 and .Ltmp4
.long .Lset4
.Lset5 = .Ltmp5-.Leh_func_begin0 # jumps to .Ltmp5
.long .Lset5
.byte 1 # On action: 1
.byte 1 # >> Action Record 1 <<
# Catch TypeInfo 1
.byte 0 # No further actions
# >> Catch TypeInfos <<
.long 0 # TypeInfo 1
.align 4
.section
.text.__clang_call_terminate,"axG", at progbits,__clang_call_terminate,comdat
.hidden __clang_call_terminate
.weak __clang_call_terminate
.align 16, 0x90
.type __clang_call_terminate, at function
__clang_call_terminate: # @__clang_call_terminate
# BB#0:
pushq %rax
callq __cxa_begin_catch
callq _ZSt9terminatev
.Ltmp9:
.size __clang_call_terminate, .Ltmp9-__clang_call_terminate
- Stephan
More information about the cfe-dev
mailing list