为什么Clang不能优化远离std :: initializer_list?

Dan*_*iel 2 c++ optimization c++11

为什么Clang 3.6不能为版本ab以下程序生成相同的程序集?

#include <iostream>
#include <algorithm>

int main(int argc, char** argv)
{
    std::cout << std::max(3, argc) << std::endl; // a
    //std::cout << std::max({3, argc}) << std::endl; // b

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译-O3,组装的用于相关的比特ab分别是:

##a
    cmpl    $2, %edi
    movl    $3, %esi
    cmovgl  %edi, %esi
    movq    __ZNSt3__14coutE@GOTPCREL(%rip), %rdi

##b
    movq    ___stack_chk_guard@GOTPCREL(%rip), %r15
    movq    (%r15), %r15
    movq    %r15, -32(%rbp)
    leaq    -40(%rbp), %rcx
    movl    $3, -40(%rbp)
    leaq    -36(%rbp), %rax
    movl    %edi, -36(%rbp)
    movl    $3, %esi
    leaq    -32(%rbp), %r8
    movq    %rcx, %rdx
    jmp LBB0_1
    .align  4, 0x90
LBB0_2:
    movl    (%rbx), %edi
    movq    %rax, %rcx
    movq    %rbx, %rax
LBB0_1:
    cmpl    %edi, %esi
    cmovlq  %rax, %rdx
    movq    %rcx, %rbx
    addq    $8, %rbx
    cmpq    %r8, %rbx
    movl    (%rdx), %esi
    jne LBB0_2
    movq    __ZNSt3__14coutE@GOTPCREL(%rip), %rdi
Run Code Online (Sandbox Code Playgroud)

根据我对汇编的有限知识,看起来版本b已编译成std::max_element算法,这显然不如使用的算法有效a.为什么是这样?我们在使用时可以实际期望什么样的优化std::initializer_list

Mat*_*son 5

您需要将您的clang升级到更高版本,因为有人显然发现了这种低效率并改进了它:

这是您的b示例现在生成的代码:

movl    %edi, %eax
movl    $3, (%rsp)
movl    %eax, 4(%rsp)
cmpl    $3, %eax
cmovlel (%rsp), %eax
Run Code Online (Sandbox Code Playgroud)

它不像原始示例那么整洁,但它比3.6编译器生成的代码更好.

与往常一样,编译器所做的优化很大程度上取决于"作者发现了什么,并找到了解决方案".第一步是"让它发挥作用".然后你看看它更快/更小.

我的铿锵版:

clang version 3.7.0 
(http://llvm.org/git/clang.git 490122a3730b4ac7120ba9bee3e5dc51510d68d9) 
(http://llvm.org/git/llvm.git 1c63fe6c61b2e1d6050f971f26946cda1e708a9c)
Run Code Online (Sandbox Code Playgroud)