一个函数返回临时对象引起的编译器优化问题

我们都知道,如果在一个函数调用另一个函数,假设是 main 函数调用 fun 函数,这个 fun 函数返回一个临时类类型变量,那么这个时候编译器就会在 main 函数申请一个空间并生成一个临时对象,通过拷贝构造函数将 fun 返回的临时变量的值拷贝到这个临时对象。我们看如下的代码:

#include <iostream>
#include <cstring> 

using namespace std;  

class Matrix
{
public:
        explicit Matrix(double d = 1.0)
        {
            cout << "Matrix::Matrix()" << endl;  

            for(int i = 0; i < 10; i++)
                for(int j = 0; j < 10; j++)
                    m[i][j] = d;
        }  

        Matrix(const Matrix& mt)
        {
            cout << "Matrix::Matrix(const Matrix&)" << endl;
            memcpy(this, &mt, sizeof(Matrix));
        }  

        Matrix& operator=(const Matrix& mt)
        {
            if(this == &mt)
                return *this;  

            cout << "Matrix::operator=(const Matrix&)" << endl;
            memcpy(this, &mt, sizeof(Matrix));  

            return *this;
        }  

        friend const Matrix operator+(const Matrix&, const Matrix&);
        //...  

private:
        double m[10][10];
};  

const Matrix operator+(const Matrix& arg1, const Matrix& arg2)
{
        Matrix sum;
        for(int i = 0; i < 10; i++)
            for(int j = 0; j < 10; j++)
                sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j];  return sum;
}  

int main()
{
        Matrix a(2.0),  b(3.0);
        Matrix c = (a + b);  return 0;
} 

按照我们的预期,输出结果应该是这样的:

这也正是 vs2012 的执行结果,但是在 GCC4.2.1 中的执行结果却是这样的:

这样看来,在构造 c 的时候根本就没有调用拷贝构造函数,同时也没用调用赋值操作符和构造函数。这样就会有一个问题,c 到底是怎么构造的?我们把代码改成这样:

#include <iostream>
#include <cstring> 

using namespace std;  

class Matrix
{
public:
        explicit Matrix(double d = 1.0)
        {
            cout << "Matrix::Matrix()" << endl;  

            for(int i = 0; i < 10; i++)
                for(int j = 0; j < 10; j++)
                    m[i][j] = d;
        }  

        Matrix(const Matrix& mt)
        {
            cout << "Matrix::Matrix(const Matrix&)" << endl;
            memcpy(this, &mt, sizeof(Matrix));
        }  

        Matrix& operator=(const Matrix& mt)
        {
            if(this == &mt)
                return *this;  

            cout << "Matrix::operator=(const Matrix&)" << endl;
            memcpy(this, &mt, sizeof(Matrix));  

            return *this;
        }  

        friend const Matrix operator+(const Matrix&, const Matrix&);
        //...  

private:
        double m[10][10];
};  

const Matrix operator+(const Matrix& arg1, const Matrix& arg2)
{
        Matrix sum;
        for(int i = 0; i < 10; i++)
            for(int j = 0; j < 10; j++)
                sum.m[i][j] = arg1.m[i][j] + arg2.m[i][j];
        cout << "Address of sum: " << &sum << endl;
        return sum;
}  

int main()
{
        Matrix a(2.0),  b(3.0);
        Matrix c = (a + b);
        cout << "Address of c:   " << &c << endl;

        return 0;
} 

其实就是把 sum 和 c 的地址打了出来,我们会发现在 gcc 的结果如下:

从这里可以看出,gcc 编译器对 c 的初始化做了优化,它没有再调用拷贝构造函数来构造 c,而是直接让 c 指向了 + 函数里的临时变量。当然这里也让 sum 的空间所有权交给了 main 作用域的 c, 否则在推出 sum 的时候 sum 的空间就应该被释放了。

这只是我从其执行结果推测的结果,而 gcc 产生的目标文件的汇编代码简直没法看,所以没有研究其汇编代码来验证我的想法,有人看得懂 gcc 的汇编代码的看完结果望告知!下面是代码的gcc汇编代码:

    .section    __TEXT,__text,regular,pure_instructions
    .globl    __ZplRK6MatrixS1_
    .align    4, 0x90
__ZplRK6MatrixS1_:                      ## @_ZplRK6MatrixS1_
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    subq    $64, %rsp
    movq    %rdi, %rax
    movabsq    $1, %rcx
    cvtsi2sdq    %rcx, %xmm0
    movq    %rsi, -24(%rbp)
    movq    %rdx, -32(%rbp)
    movq    %rdi, -48(%rbp)         ## 8-byte Spill
    movq    %rax, -56(%rbp)         ## 8-byte Spill
    callq    __ZN6MatrixC1Ed
    movl    $0, -36(%rbp)
LBB0_1:                                 ## =>This Loop Header: Depth=1
                                        ##     Child Loop BB0_3 Depth 2
    cmpl    $10, -36(%rbp)
    jge    LBB0_8
## BB#2:                                ##   in Loop: Header=BB0_1 Depth=1
    movl    $0, -40(%rbp)
LBB0_3:                                 ##   Parent Loop BB0_1 Depth=1
                                        ## =>  This Inner Loop Header: Depth=2
    cmpl    $10, -40(%rbp)
    jge    LBB0_6
## BB#4:                                ##   in Loop: Header=BB0_3 Depth=2
    movslq    -40(%rbp), %rax
    movslq    -36(%rbp), %rcx
    movq    -24(%rbp), %rdx
    imulq    $80, %rcx, %rcx
    addq    %rcx, %rdx
    movsd    (%rdx,%rax,8), %xmm0
    movslq    -40(%rbp), %rax
    movslq    -36(%rbp), %rcx
    movq    -32(%rbp), %rdx
    imulq    $80, %rcx, %rcx
    addq    %rcx, %rdx
    addsd    (%rdx,%rax,8), %xmm0
    movslq    -40(%rbp), %rax
    movslq    -36(%rbp), %rcx
    imulq    $80, %rcx, %rcx
    movq    -48(%rbp), %rdx         ## 8-byte Reload
    addq    %rcx, %rdx
    movsd    %xmm0, (%rdx,%rax,8)
## BB#5:                                ##   in Loop: Header=BB0_3 Depth=2
    movl    -40(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -40(%rbp)
    jmp    LBB0_3
LBB0_6:                                 ##   in Loop: Header=BB0_1 Depth=1
    jmp    LBB0_7
LBB0_7:                                 ##   in Loop: Header=BB0_1 Depth=1
    movl    -36(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -36(%rbp)
    jmp    LBB0_1
LBB0_8:
    movq    [email protected](%rip), %rdi
    leaq    L_.str(%rip), %rsi
    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    movq    -48(%rbp), %rsi         ## 8-byte Reload
    movq    %rax, %rdi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv
    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rsi
    movq    %rax, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rdi
    callq    *-16(%rbp)
    movq    -56(%rbp), %rsi         ## 8-byte Reload
    movq    %rax, -64(%rbp)         ## 8-byte Spill
    movq    %rsi, %rax
    addq    $64, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .globl    __ZN6MatrixC1Ed
    .weak_def_can_be_hidden    __ZN6MatrixC1Ed
    .align    4, 0x90
__ZN6MatrixC1Ed:                        ## @_ZN6MatrixC1Ed
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp7:
    .cfi_def_cfa_offset 16
Ltmp8:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp9:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movsd    %xmm0, -16(%rbp)
    movq    -8(%rbp), %rdi
    movsd    -16(%rbp), %xmm0
    callq    __ZN6MatrixC2Ed
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .globl    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    .weak_def_can_be_hidden    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    .align    4, 0x90
__ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc: ## @_ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp12:
    .cfi_def_cfa_offset 16
Ltmp13:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp14:
    .cfi_def_cfa_register %rbp
    subq    $48, %rsp
    movq    %rdi, -16(%rbp)
    movq    %rsi, -24(%rbp)
    movq    -16(%rbp), %rdi
    movq    -24(%rbp), %rsi
    movq    -24(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    %rdi, -32(%rbp)         ## 8-byte Spill
    movq    %rax, %rdi
    movq    %rsi, -40(%rbp)         ## 8-byte Spill
    callq    _strlen
    movq    -32(%rbp), %rdi         ## 8-byte Reload
    movq    -40(%rbp), %rsi         ## 8-byte Reload
    movq    %rax, %rdx
    callq    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
    addq    $48, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .private_extern    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_
    .globl    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_
    .weak_definition    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_
    .align    4, 0x90
__ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_: ## @_ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_
    .cfi_startproc
    .cfi_personality 155, ___gxx_personality_v0
Leh_func_begin3:
    .cfi_lsda 16, Lexception3
## BB#0:
    pushq    %rbp
Ltmp25:
    .cfi_def_cfa_offset 16
Ltmp26:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp27:
    .cfi_def_cfa_register %rbp
    subq    $144, %rsp
    movq    %rdi, -72(%rbp)
    movq    %rdi, %rax
    movq    (%rdi), %rcx
    movq    -24(%rcx), %rcx
    addq    %rcx, %rdi
    movq    %rdi, -32(%rbp)
    movb    $10, -33(%rbp)
    movq    -32(%rbp), %rsi
    leaq    -48(%rbp), %rcx
    movq    %rcx, %rdi
    movq    %rax, -80(%rbp)         ## 8-byte Spill
    movq    %rcx, -88(%rbp)         ## 8-byte Spill
    callq    __ZNKSt3__18ios_base6getlocEv
    movq    -88(%rbp), %rax         ## 8-byte Reload
    movq    %rax, -24(%rbp)
Ltmp15:
    movq    [email protected](%rip), %rsi
    movq    %rax, %rdi
    callq    __ZNKSt3__16locale9use_facetERNS0_2idE
Ltmp16:
    movq    %rax, -96(%rbp)         ## 8-byte Spill
    jmp    LBB3_1
LBB3_1:                                 ## %_ZNSt3__19use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE.exit.i
    movb    -33(%rbp), %al
    movq    -96(%rbp), %rcx         ## 8-byte Reload
    movq    %rcx, -8(%rbp)
    movb    %al, -9(%rbp)
    movq    -8(%rbp), %rdx
    movq    (%rdx), %rsi
    movq    56(%rsi), %rsi
    movsbl    -9(%rbp), %edi
Ltmp17:
    movl    %edi, -100(%rbp)        ## 4-byte Spill
    movq    %rdx, %rdi
    movl    -100(%rbp), %r8d        ## 4-byte Reload
    movq    %rsi, -112(%rbp)        ## 8-byte Spill
    movl    %r8d, %esi
    movq    -112(%rbp), %rdx        ## 8-byte Reload
    callq    *%rdx
Ltmp18:
    movb    %al, -113(%rbp)         ## 1-byte Spill
    jmp    LBB3_5
LBB3_2:
Ltmp19:
    movl    %edx, %ecx
    movq    %rax, -56(%rbp)
    movl    %ecx, -60(%rbp)
Ltmp20:
    leaq    -48(%rbp), %rdi
    callq    __ZNSt3__16localeD1Ev
Ltmp21:
    jmp    LBB3_3
LBB3_3:
    movq    -56(%rbp), %rdi
    callq    __Unwind_Resume
LBB3_4:
Ltmp22:
    movl    %edx, %ecx
    movq    %rax, %rdi
    movl    %ecx, -120(%rbp)        ## 4-byte Spill
    callq    ___clang_call_terminate
LBB3_5:                                 ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc.exit
    leaq    -48(%rbp), %rdi
    callq    __ZNSt3__16localeD1Ev
    movq    -80(%rbp), %rdi         ## 8-byte Reload
    movb    -113(%rbp), %al         ## 1-byte Reload
    movsbl    %al, %esi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE3putEc
    movq    -72(%rbp), %rdi
    movq    %rax, -128(%rbp)        ## 8-byte Spill
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE5flushEv
    movq    -72(%rbp), %rdi
    movq    %rax, -136(%rbp)        ## 8-byte Spill
    movq    %rdi, %rax
    addq    $144, %rsp
    popq    %rbp
    retq
    .cfi_endproc
Leh_func_end3:
    .section    __TEXT,__gcc_except_tab
    .align    2
GCC_except_table3:
Lexception3:
    .byte    255                     ## @LPStart Encoding = omit
    .byte    155                     ## @TType Encoding = indirect pcrel sdata4
    .asciz    "\274"                  ## @TType base offset
    .byte    3                       ## Call site Encoding = udata4
    .byte    52                      ## Call site table length
Lset0 = Leh_func_begin3-Leh_func_begin3 ## >> Call Site 1 <<
    .long    Lset0
Lset1 = Ltmp15-Leh_func_begin3          ##   Call between Leh_func_begin3 and Ltmp15
    .long    Lset1
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
Lset2 = Ltmp15-Leh_func_begin3          ## >> Call Site 2 <<
    .long    Lset2
Lset3 = Ltmp18-Ltmp15                   ##   Call between Ltmp15 and Ltmp18
    .long    Lset3
Lset4 = Ltmp19-Leh_func_begin3          ##     jumps to Ltmp19
    .long    Lset4
    .byte    0                       ##   On action: cleanup
Lset5 = Ltmp20-Leh_func_begin3          ## >> Call Site 3 <<
    .long    Lset5
Lset6 = Ltmp21-Ltmp20                   ##   Call between Ltmp20 and Ltmp21
    .long    Lset6
Lset7 = Ltmp22-Leh_func_begin3          ##     jumps to Ltmp22
    .long    Lset7
    .byte    1                       ##   On action: 1
Lset8 = Ltmp21-Leh_func_begin3          ## >> Call Site 4 <<
    .long    Lset8
Lset9 = Leh_func_end3-Ltmp21            ##   Call between Ltmp21 and Leh_func_end3
    .long    Lset9
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
    .byte    1                       ## >> Action Record 1 <<
                                        ##   Catch TypeInfo 1
    .byte    0                       ##   No further actions
                                        ## >> Catch TypeInfos <<
    .long    0                       ## TypeInfo 1
    .align    2

    .section    __TEXT,__text,regular,pure_instructions
    .globl    _main
    .align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp30:
    .cfi_def_cfa_offset 16
Ltmp31:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp32:
    .cfi_def_cfa_register %rbp
    subq    $2448, %rsp             ## imm = 0x990
    leaq    -824(%rbp), %rdi
    movabsq    $2, %rax
    cvtsi2sdq    %rax, %xmm0
    movl    $0, -20(%rbp)
    callq    __ZN6MatrixC1Ed
    leaq    -1624(%rbp), %rdi
    movabsq    $3, %rax
    cvtsi2sdq    %rax, %xmm0
    callq    __ZN6MatrixC1Ed
    leaq    -2424(%rbp), %rdi
    leaq    -824(%rbp), %rsi
    leaq    -1624(%rbp), %rdx
    callq    __ZplRK6MatrixS1_
    movq    [email protected](%rip), %rdi
    leaq    L_.str1(%rip), %rsi
    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    leaq    -2424(%rbp), %rdx
    movq    %rax, %rdi
    movq    %rdx, %rsi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEElsEPKv
    movl    $0, %ecx
    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rdx
    movq    %rax, -8(%rbp)
    movq    %rdx, -16(%rbp)
    movq    -8(%rbp), %rdi
    movl    %ecx, -2428(%rbp)       ## 4-byte Spill
    callq    *-16(%rbp)
    movl    -2428(%rbp), %ecx       ## 4-byte Reload
    movq    %rax, -2440(%rbp)       ## 8-byte Spill
    movl    %ecx, %eax
    addq    $2448, %rsp             ## imm = 0x990
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .private_extern    ___clang_call_terminate
    .globl    ___clang_call_terminate
    .weak_def_can_be_hidden    ___clang_call_terminate
    .align    4, 0x90
___clang_call_terminate:                ## @__clang_call_terminate
## BB#0:
    pushq    %rbp
    movq    %rsp, %rbp
    subq    $16, %rsp
    callq    ___cxa_begin_catch
    movq    %rax, -8(%rbp)          ## 8-byte Spill
    callq    __ZSt9terminatev

    .globl    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
    .weak_def_can_be_hidden    __ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
    .align    4, 0x90
__ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m: ## @_ZNSt3__124__put_character_sequenceIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_PKS4_m
    .cfi_startproc
    .cfi_personality 155, ___gxx_personality_v0
Leh_func_begin6:
    .cfi_lsda 16, Lexception6
## BB#0:
    pushq    %rbp
Ltmp65:
    .cfi_def_cfa_offset 16
Ltmp66:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp67:
    .cfi_def_cfa_register %rbp
    subq    $416, %rsp              ## imm = 0x1A0
    movq    %rdi, -208(%rbp)
    movq    %rsi, -216(%rbp)
    movq    %rdx, -224(%rbp)
    movq    -208(%rbp), %rsi
Ltmp33:
    leaq    -240(%rbp), %rdi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryC1ERS3_
Ltmp34:
    jmp    LBB6_1
LBB6_1:
    leaq    -240(%rbp), %rax
    movq    %rax, -200(%rbp)
    movq    -200(%rbp), %rax
    movb    (%rax), %cl
    movb    %cl, -273(%rbp)         ## 1-byte Spill
## BB#2:
    movb    -273(%rbp), %al         ## 1-byte Reload
    testb    $1, %al
    jne    LBB6_3
    jmp    LBB6_26
LBB6_3:
    leaq    -264(%rbp), %rax
    movq    -208(%rbp), %rcx
    movq    %rax, -184(%rbp)
    movq    %rcx, -192(%rbp)
    movq    -184(%rbp), %rax
    movq    -192(%rbp), %rcx
    movq    %rax, -152(%rbp)
    movq    %rcx, -160(%rbp)
    movq    -152(%rbp), %rax
    movq    -160(%rbp), %rcx
    movq    (%rcx), %rdx
    movq    -24(%rdx), %rdx
    addq    %rdx, %rcx
    movq    %rcx, -144(%rbp)
    movq    -144(%rbp), %rcx
    movq    %rcx, -136(%rbp)
    movq    -136(%rbp), %rcx
    movq    40(%rcx), %rcx
    movq    %rcx, (%rax)
    movq    -216(%rbp), %rsi
    movq    -208(%rbp), %rax
    movq    (%rax), %rcx
    movq    -24(%rcx), %rcx
    addq    %rcx, %rax
    movq    %rax, -96(%rbp)
    movq    -96(%rbp), %rax
    movl    8(%rax), %edi
    movq    %rsi, -288(%rbp)        ## 8-byte Spill
    movl    %edi, -292(%rbp)        ## 4-byte Spill
## BB#4:
    movl    -292(%rbp), %eax        ## 4-byte Reload
    andl    $176, %eax
    cmpl    $32, %eax
    jne    LBB6_6
## BB#5:
    movq    -216(%rbp), %rax
    addq    -224(%rbp), %rax
    movq    %rax, -304(%rbp)        ## 8-byte Spill
    jmp    LBB6_7
LBB6_6:
    movq    -216(%rbp), %rax
    movq    %rax, -304(%rbp)        ## 8-byte Spill
LBB6_7:
    movq    -304(%rbp), %rax        ## 8-byte Reload
    movq    -216(%rbp), %rcx
    addq    -224(%rbp), %rcx
    movq    -208(%rbp), %rdx
    movq    (%rdx), %rsi
    movq    -24(%rsi), %rsi
    addq    %rsi, %rdx
    movq    -208(%rbp), %rsi
    movq    (%rsi), %rdi
    movq    -24(%rdi), %rdi
    addq    %rdi, %rsi
    movq    %rsi, -80(%rbp)
    movq    -80(%rbp), %rsi
    movl    144(%rsi), %r8d
    movl    $-1, -4(%rbp)
    movl    %r8d, -8(%rbp)
    movl    -4(%rbp), %r8d
    cmpl    -8(%rbp), %r8d
    movq    %rax, -312(%rbp)        ## 8-byte Spill
    movq    %rcx, -320(%rbp)        ## 8-byte Spill
    movq    %rdx, -328(%rbp)        ## 8-byte Spill
    movq    %rsi, -336(%rbp)        ## 8-byte Spill
    jne    LBB6_16
## BB#8:
    movq    -336(%rbp), %rax        ## 8-byte Reload
    movq    %rax, -40(%rbp)
    movb    $32, -41(%rbp)
    movq    -40(%rbp), %rsi
Ltmp35:
    leaq    -56(%rbp), %rdi
    callq    __ZNKSt3__18ios_base6getlocEv
Ltmp36:
    jmp    LBB6_9
LBB6_9:                                 ## %.noexc
    leaq    -56(%rbp), %rax
    movq    %rax, -32(%rbp)
Ltmp37:
    movq    [email protected]L(%rip), %rsi
    movq    %rax, %rdi
    callq    __ZNKSt3__16locale9use_facetERNS0_2idE
Ltmp38:
    movq    %rax, -344(%rbp)        ## 8-byte Spill
    jmp    LBB6_10
LBB6_10:                                ## %_ZNSt3__19use_facetINS_5ctypeIcEEEERKT_RKNS_6localeE.exit.i.i
    movb    -41(%rbp), %al
    movq    -344(%rbp), %rcx        ## 8-byte Reload
    movq    %rcx, -16(%rbp)
    movb    %al, -17(%rbp)
    movq    -16(%rbp), %rdx
    movq    (%rdx), %rsi
    movq    56(%rsi), %rsi
    movsbl    -17(%rbp), %edi
Ltmp39:
    movl    %edi, -348(%rbp)        ## 4-byte Spill
    movq    %rdx, %rdi
    movl    -348(%rbp), %r8d        ## 4-byte Reload
    movq    %rsi, -360(%rbp)        ## 8-byte Spill
    movl    %r8d, %esi
    movq    -360(%rbp), %rdx        ## 8-byte Reload
    callq    *%rdx
Ltmp40:
    movb    %al, -361(%rbp)         ## 1-byte Spill
    jmp    LBB6_14
LBB6_11:
Ltmp41:
    movl    %edx, %ecx
    movq    %rax, -64(%rbp)
    movl    %ecx, -68(%rbp)
Ltmp42:
    leaq    -56(%rbp), %rdi
    callq    __ZNSt3__16localeD1Ev
Ltmp43:
    jmp    LBB6_12
LBB6_12:
    movq    -64(%rbp), %rax
    movl    -68(%rbp), %ecx
    movq    %rax, -376(%rbp)        ## 8-byte Spill
    movl    %ecx, -380(%rbp)        ## 4-byte Spill
    jmp    LBB6_24
LBB6_13:
Ltmp44:
    movl    %edx, %ecx
    movq    %rax, %rdi
    movl    %ecx, -384(%rbp)        ## 4-byte Spill
    callq    ___clang_call_terminate
LBB6_14:                                ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE5widenEc.exit.i
Ltmp45:
    leaq    -56(%rbp), %rdi
    callq    __ZNSt3__16localeD1Ev
Ltmp46:
    jmp    LBB6_15
LBB6_15:                                ## %.noexc1
    movb    -361(%rbp), %al         ## 1-byte Reload
    movsbl    %al, %ecx
    movq    -336(%rbp), %rdx        ## 8-byte Reload
    movl    %ecx, 144(%rdx)
LBB6_16:                                ## %_ZNKSt3__19basic_iosIcNS_11char_traitsIcEEE4fillEv.exit
    movq    -336(%rbp), %rax        ## 8-byte Reload
    movl    144(%rax), %ecx
    movb    %cl, %dl
    movb    %dl, -385(%rbp)         ## 1-byte Spill
## BB#17:
    movq    -264(%rbp), %rdi
Ltmp47:
    movb    -385(%rbp), %al         ## 1-byte Reload
    movsbl    %al, %r9d
    movq    -288(%rbp), %rsi        ## 8-byte Reload
    movq    -312(%rbp), %rdx        ## 8-byte Reload
    movq    -320(%rbp), %rcx        ## 8-byte Reload
    movq    -328(%rbp), %r8         ## 8-byte Reload
    callq    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
Ltmp48:
    movq    %rax, -400(%rbp)        ## 8-byte Spill
    jmp    LBB6_18
LBB6_18:
    leaq    -272(%rbp), %rax
    movq    -400(%rbp), %rcx        ## 8-byte Reload
    movq    %rcx, -272(%rbp)
    movq    %rax, -88(%rbp)
    movq    -88(%rbp), %rax
    cmpq    $0, (%rax)
    jne    LBB6_25
## BB#19:
    movq    -208(%rbp), %rax
    movq    (%rax), %rcx
    movq    -24(%rcx), %rcx
    addq    %rcx, %rax
    movq    %rax, -120(%rbp)
    movl    $5, -124(%rbp)
    movq    -120(%rbp), %rax
    movq    %rax, -104(%rbp)
    movl    $5, -108(%rbp)
    movq    -104(%rbp), %rax
    movl    32(%rax), %edx
    orl    $5, %edx
Ltmp49:
    movq    %rax, %rdi
    movl    %edx, %esi
    callq    __ZNSt3__18ios_base5clearEj
Ltmp50:
    jmp    LBB6_20
LBB6_20:                                ## %_ZNSt3__19basic_iosIcNS_11char_traitsIcEEE8setstateEj.exit
    jmp    LBB6_21
LBB6_21:
    jmp    LBB6_25
LBB6_22:
Ltmp56:
    movl    %edx, %ecx
    movq    %rax, -248(%rbp)
    movl    %ecx, -252(%rbp)
    jmp    LBB6_29
LBB6_23:
Ltmp51:
    movl    %edx, %ecx
    movq    %rax, -376(%rbp)        ## 8-byte Spill
    movl    %ecx, -380(%rbp)        ## 4-byte Spill
LBB6_24:                                ## %.body
    movl    -380(%rbp), %eax        ## 4-byte Reload
    movq    -376(%rbp), %rcx        ## 8-byte Reload
    movq    %rcx, -248(%rbp)
    movl    %eax, -252(%rbp)
Ltmp52:
    leaq    -240(%rbp), %rdi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev
Ltmp53:
    jmp    LBB6_28
LBB6_25:
    jmp    LBB6_26
LBB6_26:
Ltmp54:
    leaq    -240(%rbp), %rdi
    callq    __ZNSt3__113basic_ostreamIcNS_11char_traitsIcEEE6sentryD1Ev
Ltmp55:
    jmp    LBB6_27
LBB6_27:
    jmp    LBB6_31
LBB6_28:
    jmp    LBB6_29
LBB6_29:
    movq    -248(%rbp), %rdi
    callq    ___cxa_begin_catch
    movq    -208(%rbp), %rdi
    movq    (%rdi), %rcx
    movq    -24(%rcx), %rcx
    addq    %rcx, %rdi
Ltmp57:
    movq    %rax, -408(%rbp)        ## 8-byte Spill
    callq    __ZNSt3__18ios_base33__set_badbit_and_consider_rethrowEv
Ltmp58:
    jmp    LBB6_30
LBB6_30:
    callq    ___cxa_end_catch
LBB6_31:
    movq    -208(%rbp), %rax
    addq    $416, %rsp              ## imm = 0x1A0
    popq    %rbp
    retq
LBB6_32:
Ltmp59:
    movl    %edx, %ecx
    movq    %rax, -248(%rbp)
    movl    %ecx, -252(%rbp)
Ltmp60:
    callq    ___cxa_end_catch
Ltmp61:
    jmp    LBB6_33
LBB6_33:
    jmp    LBB6_34
LBB6_34:
    movq    -248(%rbp), %rdi
    callq    __Unwind_Resume
LBB6_35:
Ltmp62:
    movl    %edx, %ecx
    movq    %rax, %rdi
    movl    %ecx, -412(%rbp)        ## 4-byte Spill
    callq    ___clang_call_terminate
    .cfi_endproc
Leh_func_end6:
    .section    __TEXT,__gcc_except_tab
    .align    2
GCC_except_table6:
Lexception6:
    .byte    255                     ## @LPStart Encoding = omit
    .byte    155                     ## @TType Encoding = indirect pcrel sdata4
    .asciz    "\253\201"              ## @TType base offset
    .byte    3                       ## Call site Encoding = udata4
    .ascii    "\234\001"              ## Call site table length
Lset10 = Ltmp33-Leh_func_begin6         ## >> Call Site 1 <<
    .long    Lset10
Lset11 = Ltmp34-Ltmp33                  ##   Call between Ltmp33 and Ltmp34
    .long    Lset11
Lset12 = Ltmp56-Leh_func_begin6         ##     jumps to Ltmp56
    .long    Lset12
    .byte    5                       ##   On action: 3
Lset13 = Ltmp35-Leh_func_begin6         ## >> Call Site 2 <<
    .long    Lset13
Lset14 = Ltmp36-Ltmp35                  ##   Call between Ltmp35 and Ltmp36
    .long    Lset14
Lset15 = Ltmp51-Leh_func_begin6         ##     jumps to Ltmp51
    .long    Lset15
    .byte    5                       ##   On action: 3
Lset16 = Ltmp37-Leh_func_begin6         ## >> Call Site 3 <<
    .long    Lset16
Lset17 = Ltmp40-Ltmp37                  ##   Call between Ltmp37 and Ltmp40
    .long    Lset17
Lset18 = Ltmp41-Leh_func_begin6         ##     jumps to Ltmp41
    .long    Lset18
    .byte    3                       ##   On action: 2
Lset19 = Ltmp42-Leh_func_begin6         ## >> Call Site 4 <<
    .long    Lset19
Lset20 = Ltmp43-Ltmp42                  ##   Call between Ltmp42 and Ltmp43
    .long    Lset20
Lset21 = Ltmp44-Leh_func_begin6         ##     jumps to Ltmp44
    .long    Lset21
    .byte    7                       ##   On action: 4
Lset22 = Ltmp45-Leh_func_begin6         ## >> Call Site 5 <<
    .long    Lset22
Lset23 = Ltmp50-Ltmp45                  ##   Call between Ltmp45 and Ltmp50
    .long    Lset23
Lset24 = Ltmp51-Leh_func_begin6         ##     jumps to Ltmp51
    .long    Lset24
    .byte    5                       ##   On action: 3
Lset25 = Ltmp52-Leh_func_begin6         ## >> Call Site 6 <<
    .long    Lset25
Lset26 = Ltmp53-Ltmp52                  ##   Call between Ltmp52 and Ltmp53
    .long    Lset26
Lset27 = Ltmp62-Leh_func_begin6         ##     jumps to Ltmp62
    .long    Lset27
    .byte    5                       ##   On action: 3
Lset28 = Ltmp54-Leh_func_begin6         ## >> Call Site 7 <<
    .long    Lset28
Lset29 = Ltmp55-Ltmp54                  ##   Call between Ltmp54 and Ltmp55
    .long    Lset29
Lset30 = Ltmp56-Leh_func_begin6         ##     jumps to Ltmp56
    .long    Lset30
    .byte    5                       ##   On action: 3
Lset31 = Ltmp55-Leh_func_begin6         ## >> Call Site 8 <<
    .long    Lset31
Lset32 = Ltmp57-Ltmp55                  ##   Call between Ltmp55 and Ltmp57
    .long    Lset32
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
Lset33 = Ltmp57-Leh_func_begin6         ## >> Call Site 9 <<
    .long    Lset33
Lset34 = Ltmp58-Ltmp57                  ##   Call between Ltmp57 and Ltmp58
    .long    Lset34
Lset35 = Ltmp59-Leh_func_begin6         ##     jumps to Ltmp59
    .long    Lset35
    .byte    0                       ##   On action: cleanup
Lset36 = Ltmp58-Leh_func_begin6         ## >> Call Site 10 <<
    .long    Lset36
Lset37 = Ltmp60-Ltmp58                  ##   Call between Ltmp58 and Ltmp60
    .long    Lset37
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
Lset38 = Ltmp60-Leh_func_begin6         ## >> Call Site 11 <<
    .long    Lset38
Lset39 = Ltmp61-Ltmp60                  ##   Call between Ltmp60 and Ltmp61
    .long    Lset39
Lset40 = Ltmp62-Leh_func_begin6         ##     jumps to Ltmp62
    .long    Lset40
    .byte    5                       ##   On action: 3
Lset41 = Ltmp61-Leh_func_begin6         ## >> Call Site 12 <<
    .long    Lset41
Lset42 = Leh_func_end6-Ltmp61           ##   Call between Ltmp61 and Leh_func_end6
    .long    Lset42
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
    .byte    0                       ## >> Action Record 1 <<
                                        ##   Cleanup
    .byte    0                       ##   No further actions
    .byte    1                       ## >> Action Record 2 <<
                                        ##   Catch TypeInfo 1
    .byte    125                     ##   Continue to action 1
    .byte    1                       ## >> Action Record 3 <<
                                        ##   Catch TypeInfo 1
    .byte    0                       ##   No further actions
    .byte    1                       ## >> Action Record 4 <<
                                        ##   Catch TypeInfo 1
    .byte    125                     ##   Continue to action 3
                                        ## >> Catch TypeInfos <<
    .long    0                       ## TypeInfo 1
    .align    2

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .private_extern    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
    .globl    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
    .weak_def_can_be_hidden    __ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
    .align    4, 0x90
__ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_: ## @_ZNSt3__116__pad_and_outputIcNS_11char_traitsIcEEEENS_19ostreambuf_iteratorIT_T0_EES6_PKS4_S8_S8_RNS_8ios_baseES4_
    .cfi_startproc
    .cfi_personality 155, ___gxx_personality_v0
Leh_func_begin7:
    .cfi_lsda 16, Lexception7
## BB#0:
    pushq    %rbp
Ltmp76:
    .cfi_def_cfa_offset 16
Ltmp77:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp78:
    .cfi_def_cfa_register %rbp
    subq    $720, %rsp              ## imm = 0x2D0
    movb    %r9b, %al
    leaq    -552(%rbp), %r10
    leaq    -488(%rbp), %r11
    movq    %rdi, -504(%rbp)
    movq    %rsi, -512(%rbp)
    movq    %rdx, -520(%rbp)
    movq    %rcx, -528(%rbp)
    movq    %r8, -536(%rbp)
    movb    %al, -537(%rbp)
    movq    -504(%rbp), %rcx
    movq    %r11, -472(%rbp)
    movq    $-1, -480(%rbp)
    movq    -472(%rbp), %rdx
    movq    -480(%rbp), %rsi
    movq    %rdx, -456(%rbp)
    movq    %rsi, -464(%rbp)
    movq    -456(%rbp), %rdx
    movq    $0, (%rdx)
    movq    -488(%rbp), %rdx
    movq    %rdx, -552(%rbp)
    movq    %r10, -448(%rbp)
    cmpq    $0, %rcx
    jne    LBB7_2
## BB#1:
    movq    -504(%rbp), %rax
    movq    %rax, -496(%rbp)
    jmp    LBB7_29
LBB7_2:
    movq    -528(%rbp), %rax
    movq    -512(%rbp), %rcx
    subq    %rcx, %rax
    movq    %rax, -560(%rbp)
    movq    -536(%rbp), %rax
    movq    %rax, -344(%rbp)
    movq    -344(%rbp), %rax
    movq    24(%rax), %rax
    movq    %rax, -568(%rbp)
    movq    -568(%rbp), %rax
    cmpq    -560(%rbp), %rax
    jle    LBB7_4
## BB#3:
    movq    -560(%rbp), %rax
    movq    -568(%rbp), %rcx
    subq    %rax, %rcx
    movq    %rcx, -568(%rbp)
    jmp    LBB7_5
LBB7_4:
    movq    $0, -568(%rbp)
LBB7_5:
    movq    -520(%rbp), %rax
    movq    -512(%rbp), %rcx
    subq    %rcx, %rax
    movq    %rax, -576(%rbp)
    cmpq    $0, -576(%rbp)
    jle    LBB7_9
## BB#6:
    movq    -504(%rbp), %rax
    movq    -512(%rbp), %rcx
    movq    -576(%rbp), %rdx
    movq    %rax, -248(%rbp)
    movq    %rcx, -256(%rbp)
    movq    %rdx, -264(%rbp)
    movq    -248(%rbp), %rax
    movq    (%rax), %rcx
    movq    96(%rcx), %rcx
    movq    -256(%rbp), %rsi
    movq    -264(%rbp), %rdx
    movq    %rax, %rdi
    callq    *%rcx
    cmpq    -576(%rbp), %rax
    je    LBB7_8
## BB#7:
    leaq    -584(%rbp), %rax
    leaq    -240(%rbp), %rcx
    movq    %rcx, -224(%rbp)
    movq    $-1, -232(%rbp)
    movq    -224(%rbp), %rcx
    movq    -232(%rbp), %rdx
    movq    %rcx, -208(%rbp)
    movq    %rdx, -216(%rbp)
    movq    -208(%rbp), %rcx
    movq    $0, (%rcx)
    movq    -240(%rbp), %rcx
    movq    %rcx, -584(%rbp)
    movq    %rax, -8(%rbp)
    movq    $0, -504(%rbp)
    movq    -504(%rbp), %rax
    movq    %rax, -496(%rbp)
    jmp    LBB7_29
LBB7_8:
    jmp    LBB7_9
LBB7_9:
    cmpq    $0, -568(%rbp)
    jle    LBB7_24
## BB#10:
    leaq    -608(%rbp), %rax
    movq    -568(%rbp), %rcx
    movb    -537(%rbp), %dl
    movq    %rax, -72(%rbp)
    movq    %rcx, -80(%rbp)
    movb    %dl, -81(%rbp)
    movq    -72(%rbp), %rax
    movq    -80(%rbp), %rcx
    movb    -81(%rbp), %dl
    movq    %rax, -48(%rbp)
    movq    %rcx, -56(%rbp)
    movb    %dl, -57(%rbp)
    movq    -48(%rbp), %rax
    movq    %rax, -40(%rbp)
    movq    -40(%rbp), %rcx
    movq    %rcx, -32(%rbp)
    movq    -32(%rbp), %rcx
    movq    %rcx, -24(%rbp)
    movq    -24(%rbp), %rcx
    movq    %rcx, -16(%rbp)
    movq    -56(%rbp), %rsi
    movq    %rax, %rdi
    movsbl    -57(%rbp), %edx
    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE6__initEmc
    leaq    -608(%rbp), %rax
    movq    -504(%rbp), %rcx
    movq    %rax, -200(%rbp)
    movq    -200(%rbp), %rax
    movq    %rax, -192(%rbp)
    movq    -192(%rbp), %rax
    movq    %rax, -184(%rbp)
    movq    -184(%rbp), %rsi
    movq    %rsi, -176(%rbp)
    movq    -176(%rbp), %rsi
    movq    %rsi, -168(%rbp)
    movq    -168(%rbp), %rsi
    movzbl    (%rsi), %edx
    andl    $1, %edx
    cmpl    $0, %edx
    movq    %rcx, -656(%rbp)        ## 8-byte Spill
    movq    %rax, -664(%rbp)        ## 8-byte Spill
    je    LBB7_12
## BB#11:
    movq    -664(%rbp), %rax        ## 8-byte Reload
    movq    %rax, -120(%rbp)
    movq    -120(%rbp), %rcx
    movq    %rcx, -112(%rbp)
    movq    -112(%rbp), %rcx
    movq    %rcx, -104(%rbp)
    movq    -104(%rbp), %rcx
    movq    16(%rcx), %rcx
    movq    %rcx, -672(%rbp)        ## 8-byte Spill
    jmp    LBB7_13
LBB7_12:
    movq    -664(%rbp), %rax        ## 8-byte Reload
    movq    %rax, -160(%rbp)
    movq    -160(%rbp), %rcx
    movq    %rcx, -152(%rbp)
    movq    -152(%rbp), %rcx
    movq    %rcx, -144(%rbp)
    movq    -144(%rbp), %rcx
    addq    $1, %rcx
    movq    %rcx, -136(%rbp)
    movq    -136(%rbp), %rcx
    movq    %rcx, -128(%rbp)
    movq    -128(%rbp), %rcx
    movq    %rcx, -672(%rbp)        ## 8-byte Spill
LBB7_13:                                ## %_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4dataEv.exit
    movq    -672(%rbp), %rax        ## 8-byte Reload
    movq    %rax, -96(%rbp)
    movq    -568(%rbp), %rcx
    movq    -656(%rbp), %rdx        ## 8-byte Reload
    movq    %rdx, -272(%rbp)
    movq    %rax, -280(%rbp)
    movq    %rcx, -288(%rbp)
    movq    -272(%rbp), %rax
    movq    (%rax), %rsi
    movq    96(%rsi), %rsi
    movq    -280(%rbp), %rdi
Ltmp68:
    movq    %rdi, -680(%rbp)        ## 8-byte Spill
    movq    %rax, %rdi
    movq    -680(%rbp), %rax        ## 8-byte Reload
    movq    %rsi, -688(%rbp)        ## 8-byte Spill
    movq    %rax, %rsi
    movq    %rcx, %rdx
    movq    -688(%rbp), %rcx        ## 8-byte Reload
    callq    *%rcx
Ltmp69:
    movq    %rax, -696(%rbp)        ## 8-byte Spill
    jmp    LBB7_14
LBB7_14:                                ## %_ZNSt3__115basic_streambufIcNS_11char_traitsIcEEE5sputnEPKcl.exit
    jmp    LBB7_15
LBB7_15:
    movq    -696(%rbp), %rax        ## 8-byte Reload
    cmpq    -568(%rbp), %rax
    je    LBB7_20
## BB#16:
    leaq    -328(%rbp), %rax
    movq    %rax, -312(%rbp)
    movq    $-1, -320(%rbp)
    movq    -312(%rbp), %rax
    movq    -320(%rbp), %rcx
    movq    %rax, -296(%rbp)
    movq    %rcx, -304(%rbp)
    movq    -296(%rbp), %rax
    movq    $0, (%rax)
    movq    -328(%rbp), %rax
    movq    %rax, -704(%rbp)        ## 8-byte Spill
## BB#17:
    leaq    -632(%rbp), %rax
    movq    -704(%rbp), %rcx        ## 8-byte Reload
    movq    %rcx, -632(%rbp)
    movq    %rax, -336(%rbp)
## BB#18:
    movq    $0, -504(%rbp)
    movq    -504(%rbp), %rax
    movq    %rax, -496(%rbp)
    movl    $1, -636(%rbp)
    jmp    LBB7_21
LBB7_19:
Ltmp70:
    movl    %edx, %ecx
    movq    %rax, -616(%rbp)
    movl    %ecx, -620(%rbp)
Ltmp71:
    leaq    -608(%rbp), %rdi
    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
Ltmp72:
    jmp    LBB7_23
LBB7_20:
    movl    $0, -636(%rbp)
LBB7_21:
    leaq    -608(%rbp), %rdi
    callq    __ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEED1Ev
    movl    -636(%rbp), %eax
    movl    %eax, %ecx
    subl    $1, %ecx
    movl    %eax, -708(%rbp)        ## 4-byte Spill
    movl    %ecx, -712(%rbp)        ## 4-byte Spill
    je    LBB7_29
    jmp    LBB7_33
LBB7_33:
    movl    -708(%rbp), %eax        ## 4-byte Reload
    testl    %eax, %eax
    jne    LBB7_32
    jmp    LBB7_22
LBB7_22:
    jmp    LBB7_24
LBB7_23:
    jmp    LBB7_30
LBB7_24:
    movq    -528(%rbp), %rax
    movq    -520(%rbp), %rcx
    subq    %rcx, %rax
    movq    %rax, -576(%rbp)
    cmpq    $0, -576(%rbp)
    jle    LBB7_28
## BB#25:
    movq    -504(%rbp), %rax
    movq    -520(%rbp), %rcx
    movq    -576(%rbp), %rdx
    movq    %rax, -352(%rbp)
    movq    %rcx, -360(%rbp)
    movq    %rdx, -368(%rbp)
    movq    -352(%rbp), %rax
    movq    (%rax), %rcx
    movq    96(%rcx), %rcx
    movq    -360(%rbp), %rsi
    movq    -368(%rbp), %rdx
    movq    %rax, %rdi
    callq    *%rcx
    cmpq    -576(%rbp), %rax
    je    LBB7_27
## BB#26:
    leaq    -648(%rbp), %rax
    leaq    -408(%rbp), %rcx
    movq    %rcx, -392(%rbp)
    movq    $-1, -400(%rbp)
    movq    -392(%rbp), %rcx
    movq    -400(%rbp), %rdx
    movq    %rcx, -376(%rbp)
    movq    %rdx, -384(%rbp)
    movq    -376(%rbp), %rcx
    movq    $0, (%rcx)
    movq    -408(%rbp), %rcx
    movq    %rcx, -648(%rbp)
    movq    %rax, -416(%rbp)
    movq    $0, -504(%rbp)
    movq    -504(%rbp), %rax
    movq    %rax, -496(%rbp)
    jmp    LBB7_29
LBB7_27:
    jmp    LBB7_28
LBB7_28:
    movq    -536(%rbp), %rax
    movq    %rax, -424(%rbp)
    movq    $0, -432(%rbp)
    movq    -424(%rbp), %rax
    movq    24(%rax), %rcx
    movq    %rcx, -440(%rbp)
    movq    -432(%rbp), %rcx
    movq    %rcx, 24(%rax)
    movq    -504(%rbp), %rax
    movq    %rax, -496(%rbp)
LBB7_29:
    movq    -496(%rbp), %rax
    addq    $720, %rsp              ## imm = 0x2D0
    popq    %rbp
    retq
LBB7_30:
    movq    -616(%rbp), %rdi
    callq    __Unwind_Resume
LBB7_31:
Ltmp73:
    movl    %edx, %ecx
    movq    %rax, %rdi
    movl    %ecx, -716(%rbp)        ## 4-byte Spill
    callq    ___clang_call_terminate
LBB7_32:
    .cfi_endproc
Leh_func_end7:
    .section    __TEXT,__gcc_except_tab
    .align    2
GCC_except_table7:
Lexception7:
    .byte    255                     ## @LPStart Encoding = omit
    .byte    155                     ## @TType Encoding = indirect pcrel sdata4
    .asciz    "\274"                  ## @TType base offset
    .byte    3                       ## Call site Encoding = udata4
    .byte    52                      ## Call site table length
Lset43 = Leh_func_begin7-Leh_func_begin7 ## >> Call Site 1 <<
    .long    Lset43
Lset44 = Ltmp68-Leh_func_begin7         ##   Call between Leh_func_begin7 and Ltmp68
    .long    Lset44
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
Lset45 = Ltmp68-Leh_func_begin7         ## >> Call Site 2 <<
    .long    Lset45
Lset46 = Ltmp69-Ltmp68                  ##   Call between Ltmp68 and Ltmp69
    .long    Lset46
Lset47 = Ltmp70-Leh_func_begin7         ##     jumps to Ltmp70
    .long    Lset47
    .byte    0                       ##   On action: cleanup
Lset48 = Ltmp71-Leh_func_begin7         ## >> Call Site 3 <<
    .long    Lset48
Lset49 = Ltmp72-Ltmp71                  ##   Call between Ltmp71 and Ltmp72
    .long    Lset49
Lset50 = Ltmp73-Leh_func_begin7         ##     jumps to Ltmp73
    .long    Lset50
    .byte    1                       ##   On action: 1
Lset51 = Ltmp72-Leh_func_begin7         ## >> Call Site 4 <<
    .long    Lset51
Lset52 = Leh_func_end7-Ltmp72           ##   Call between Ltmp72 and Leh_func_end7
    .long    Lset52
    .long    0                       ##     has no landing pad
    .byte    0                       ##   On action: cleanup
    .byte    1                       ## >> Action Record 1 <<
                                        ##   Catch TypeInfo 1
    .byte    0                       ##   No further actions
                                        ## >> Catch TypeInfos <<
    .long    0                       ## TypeInfo 1
    .align    2

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .globl    __ZN6MatrixC2Ed
    .weak_def_can_be_hidden    __ZN6MatrixC2Ed
    .align    4, 0x90
__ZN6MatrixC2Ed:                        ## @_ZN6MatrixC2Ed
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp81:
    .cfi_def_cfa_offset 16
Ltmp82:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp83:
    .cfi_def_cfa_register %rbp
    subq    $64, %rsp
    movq    [email protected](%rip), %rax
    leaq    L_.str2(%rip), %rsi
    movq    %rdi, -24(%rbp)
    movsd    %xmm0, -32(%rbp)
    movq    -24(%rbp), %rdi
    movq    %rdi, -48(%rbp)         ## 8-byte Spill
    movq    %rax, %rdi
    callq    __ZNSt3__1lsINS_11char_traitsIcEEEERNS_13basic_ostreamIcT_EES6_PKc
    leaq    __ZNSt3__14endlIcNS_11char_traitsIcEEEERNS_13basic_ostreamIT_T0_EES7_(%rip), %rsi
    movq    %rax, -8(%rbp)
    movq    %rsi, -16(%rbp)
    movq    -8(%rbp), %rdi
    callq    *-16(%rbp)
    movl    $0, -36(%rbp)
    movq    %rax, -56(%rbp)         ## 8-byte Spill
LBB8_1:                                 ## =>This Loop Header: Depth=1
                                        ##     Child Loop BB8_3 Depth 2
    cmpl    $10, -36(%rbp)
    jge    LBB8_8
## BB#2:                                ##   in Loop: Header=BB8_1 Depth=1
    movl    $0, -40(%rbp)
LBB8_3:                                 ##   Parent Loop BB8_1 Depth=1
                                        ## =>  This Inner Loop Header: Depth=2
    cmpl    $10, -40(%rbp)
    jge    LBB8_6
## BB#4:                                ##   in Loop: Header=BB8_3 Depth=2
    movsd    -32(%rbp), %xmm0
    movslq    -40(%rbp), %rax
    movslq    -36(%rbp), %rcx
    imulq    $80, %rcx, %rcx
    movq    -48(%rbp), %rdx         ## 8-byte Reload
    addq    %rcx, %rdx
    movsd    %xmm0, (%rdx,%rax,8)
## BB#5:                                ##   in Loop: Header=BB8_3 Depth=2
    movl    -40(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -40(%rbp)
    jmp    LBB8_3
LBB8_6:                                 ##   in Loop: Header=BB8_1 Depth=1
    jmp    LBB8_7
LBB8_7:                                 ##   in Loop: Header=BB8_1 Depth=1
    movl    -36(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -36(%rbp)
    jmp    LBB8_1
LBB8_8:
    addq    $64, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__cstring,cstring_literals
L_.str:                                 ## @.str
    .asciz    "Address of sum: "

L_.str1:                                ## @.str1
    .asciz    "Address of c:   "

L_.str2:                                ## @.str2
    .asciz    "Matrix::Matrix()"

    .section    __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support

.subsections_via_symbols

而这时简化版的代码(突出返回临时对象):

#include <iostream>
#include <cstring> 

using namespace std;  

class Matrix
{
public:
        explicit Matrix()  {  }
        friend const Matrix operator+(const Matrix&, const Matrix&);
};  

const Matrix operator+(const Matrix& arg1, const Matrix& arg2)
{
        Matrix sum;
        return sum;
}  

int main()
{
        Matrix a,  b;
        Matrix c = (a + b);  

        return 0;
} 

汇编:

    .section    __TEXT,__text,regular,pure_instructions
    .globl    __ZplRK6MatrixS1_
    .align    4, 0x90
__ZplRK6MatrixS1_:                      ## @_ZplRK6MatrixS1_
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp2:
    .cfi_def_cfa_offset 16
Ltmp3:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp4:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    leaq    -8(%rbp), %rax
    movq    %rdi, -16(%rbp)
    movq    %rsi, -24(%rbp)
    movq    %rax, %rdi
    callq    __ZN6MatrixC1Ev
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .globl    __ZN6MatrixC1Ev
    .weak_def_can_be_hidden    __ZN6MatrixC1Ev
    .align    4, 0x90
__ZN6MatrixC1Ev:                        ## @_ZN6MatrixC1Ev
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp7:
    .cfi_def_cfa_offset 16
Ltmp8:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp9:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rdi
    callq    __ZN6MatrixC2Ev
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__text,regular,pure_instructions
    .globl    _main
    .align    4, 0x90
_main:                                  ## @main
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp12:
    .cfi_def_cfa_offset 16
Ltmp13:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp14:
    .cfi_def_cfa_register %rbp
    subq    $32, %rsp
    leaq    -8(%rbp), %rdi
    movl    $0, -4(%rbp)
    callq    __ZN6MatrixC1Ev
    leaq    -16(%rbp), %rdi
    callq    __ZN6MatrixC1Ev
    leaq    -8(%rbp), %rdi
    leaq    -16(%rbp), %rsi
    callq    __ZplRK6MatrixS1_
    movl    $0, %eax
    addq    $32, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .section    __TEXT,__textcoal_nt,coalesced,pure_instructions
    .globl    __ZN6MatrixC2Ev
    .weak_def_can_be_hidden    __ZN6MatrixC2Ev
    .align    4, 0x90
__ZN6MatrixC2Ev:                        ## @_ZN6MatrixC2Ev
    .cfi_startproc
## BB#0:
    pushq    %rbp
Ltmp17:
    .cfi_def_cfa_offset 16
Ltmp18:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp19:
    .cfi_def_cfa_register %rbp
    movq    %rdi, -8(%rbp)
    popq    %rbp
    retq
    .cfi_endproc

.subsections_via_symbols
时间: 2024-10-12 22:04:26

一个函数返回临时对象引起的编译器优化问题的相关文章

【C++对象模型】函数返回C++对象的问题

在深入C++对象模型中,对于形如 CObj obj1 = Get(obj2); 的形式,编译器会在将其改变为如下 Get(obj, CObj&  obj1); 将赋值操作符左边的变量作为函数的一个引用参赛,在函数内部改变其值: 如下 #include "stdafx.h" #include <iostream> using namespace std; class CTest { public: CTest(int a, int b); virtual ~CTest

用一个函数返回参数二进制中1的个数

//题目:写一个函数返回参数二进制中的1的个数 //      比如:15    0000 1111  4个1 //     程序原型:  int count_one_bit(unsigned int value) //                {  //                        //返回1的个数 //                 }     #include<stdio.h> #include<stdlib.h> int count_one_bit

用C语言写一个函数返回参数二进制中1的个数

首先,给出正确的C语言代码如下: #include <stdio.h> int count_one_bits(unsigned int value) { int count =0; while(value) { if(value%2==1) { count++; } value=value/2; } return count; } int main() { unsigned int num=0; int ret=0; scanf("%d",&num); ret=co

写一个函数返回参数二进制中 1 的个数

#include<stdio.h>int main(){   int num; int s=0,ys=0,count=0;  printf("请输入一个数字:");    scanf("%d",&num);     for(s=num;s>=1;)     {     ys=s%2;         s=s/2;         if (ys==1)      {    count++;         }     }    printf(

写一个函数返回参数二进制中 1 的个数 比如: 15 &nbsp; &nbsp; 0000 1111 &nbsp; &nbsp; 4 个 1

方法一: 程序: #include<stdio.h> int  count_one_bits(int t) { int i = 32; int count = 0; while (i>0) { if (t & 1 == 1) { count++; } //t=t/2 t = t >> 1; i -= 1; } return count; } int main() { int t = 0; printf("请输入一个整数:"); scanf(&quo

写一个函数返回参数二进制中1的个数

分析: (1)输入一个数 (2)判断它是否为0. (3)如果不为0,就对它进行模2取余,模2的过程就相当于把这个数向右移除了一位,如果余数为1,则证明移除的这一位为1,就将其记录下来.如果余数为0,就证明移除的这一位为0,就不记录. (4)经过第3步以后,对这个数进行除2取整,再进入到第2步中.如此循环,直到第3步中判断为0. 注意: (1)对于负数,在内存中是以其补码形式存放的.例如-1,它的二进制中有32个1. (2)以下方法中对于函数形参的定义方式有两种,一种是无符号整型,一种是有符号整型

指针:一个函数返回两个数值

#include<stdio.h> int sumAndminus(int n1, int n2, int *n3); int main() { int a = 10; int b = 7; int he; int cha; he = sumAndminus(a,b,&cha); printf("he=%d, cha=%d", he,cha); return 0; } int sumAndminus(int n1,int n2,int *n3) { *n3=n1-n

创建一个函数,传入对象,打印指定格式

格式:name=wang&age=18&sex=男 var person = {   name:'wang',   age:18,   sex:'男',  };  function getData(str){   var str='';   for(var i in person){    str += i+'='+person[i] + '&';   };   return str.substring(0,str.length-1);  }  console.log(getDat

一个函数返回参数二进制中 1 的个数

方法一: #include<stdio.h> int bit_count(unsigned int n) { int count; for (count = 0; n; n &= n - 1) { count++; } return count; } int main() { int y; int c; printf("请输入一个数:"); scanf("%d", &c); y = bit_count(c); printf("%