[cfe-dev] Code generation for noexcept functions

Stephan Tolksdorf st at quanttec.com
Tue May 13 12:36:22 PDT 2014


On 2014-05-11 Richard Smith wrote:
> On Sun, May 11, 2014 at 8:19 AM, Stephan Tolksdorf <st at quanttec.com
> <mailto: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.)

Thanks for the reply! Do you or maybe somebody else have an opinion on 
what the best way would be to efficiently support this case in LLVM IR?

- Stephan

>
>     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 <mailto:cfe-dev at cs.uiuc.edu>
>     http://lists.cs.uiuc.edu/__mailman/listinfo/cfe-dev
>     <http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev>
>
>



More information about the cfe-dev mailing list