1

我找不到控制 C 语言的命名返回值优化的标志。对于 C++,它似乎是 -fno-elide-constructors。

实现它的源代码在这里,但由于它是一个中间端,即使在注释中也不会破坏前端信息。 手册部分也没有完全帮助。但是反汇编显示,由于它在 O0 上关闭并在 O1 上启用,因此它必须是以下之一:

      -fauto-inc-dec 
      -fcprop-registers 
      -fdce 
      -fdefer-pop 
      -fdelayed-branch 
      -fdse 
      -fguess-branch-probability 
      -fif-conversion2 
      -fif-conversion 
      -finline-small-functions 
      -fipa-pure-const 
      -fipa-reference 
      -fmerge-constants
      -fsplit-wide-types 
      -ftree-builtin-call-dce 
      -ftree-ccp 
      -ftree-ch 
      -ftree-copyrename 
      -ftree-dce 
      -ftree-dominator-opts 
      -ftree-dse 
      -ftree-fre 
      -ftree-sra 
      -ftree-ter 
      -funit-at-a-time

C代码:

struct p {
    long x;
    long y;
    long z;
};

__attribute__((noinline))
struct p f(void) {
    struct p copy;
    copy.x = 1; 
    copy.y = 2;
    copy.z = 3;
    return copy;
}

int main(int argc, char** argv) {
    volatile struct p inst = f();
    return 0;
}

使用 O0 编译,我们看到“复制”结构天真地分配在堆栈上:

00000000004004b6 <f>:
  4004b6:   55                      push   rbp
  4004b7:   48 89 e5                mov    rbp,rsp
  4004ba:   48 89 7d d8             mov    QWORD PTR [rbp-0x28],rdi
  4004be:   48 c7 45 e0 01 00 00    mov    QWORD PTR [rbp-0x20],0x1
  4004c5:   00 
  4004c6:   48 c7 45 e8 02 00 00    mov    QWORD PTR [rbp-0x18],0x2
  4004cd:   00 
  4004ce:   48 c7 45 f0 03 00 00    mov    QWORD PTR [rbp-0x10],0x3
  4004d5:   00 
  4004d6:   48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  4004da:   48 8b 55 e0             mov    rdx,QWORD PTR [rbp-0x20]
  4004de:   48 89 10                mov    QWORD PTR [rax],rdx
  4004e1:   48 8b 55 e8             mov    rdx,QWORD PTR [rbp-0x18]
  4004e5:   48 89 50 08             mov    QWORD PTR [rax+0x8],rdx
  4004e9:   48 8b 55 f0             mov    rdx,QWORD PTR [rbp-0x10]
  4004ed:   48 89 50 10             mov    QWORD PTR [rax+0x10],rdx
  4004f1:   48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  4004f5:   5d                      pop    rbp
  4004f6:   c3                      ret    

用 O1 编译它没有分配,但指针作为隐式参数传递

00000000004004b6 <f>:
  4004b6:   48 89 f8                mov    rax,rdi
  4004b9:   48 c7 07 01 00 00 00    mov    QWORD PTR [rdi],0x1
  4004c0:   48 c7 47 08 02 00 00    mov    QWORD PTR [rdi+0x8],0x2
  4004c7:   00 
  4004c8:   48 c7 47 10 03 00 00    mov    QWORD PTR [rdi+0x10],0x3
  4004cf:   00 
  4004d0:   c3                      ret 
4

1 回答 1

2

与 GCC 中最接近的东西(即复制省略的开关)是-fcprop-registers. C 中不存在复制省略,但这是与之最相似的功能。从手册页:

在寄存器分配和寄存器分配后指令拆分之后,我们执行复制传播传递以尝试减少调度依赖并偶尔消除复制。在 -O、-O2、-O3、-Os 级别启用。

于 2016-01-23T09:58:50.810 回答