[cfe-dev] Code generation for noexcept functions
Richard Smith
richard at metafoo.co.uk
Sun May 11 13:57:32 PDT 2014
On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <st at quanttec.com> wrote:
> 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?
>
As far as I can see, this is impossible to represent in LLVM IR. (If there
is a way, I'm sure we'd be happy to make clang emit that IR.)
> 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
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20140511/1293f7d0/attachment.html>
More information about the cfe-dev
mailing list