MSVC 2013内联可以从单独的目标文件调用x64汇编代码吗?

时间:2014-08-26 16:37:02

标签: visual-studio visual-c++ assembly compiler-optimization inlining

我在MSVC上学习x64汇编。 x64代码中不允许内联汇编。我在一个单独的文件中写了一个非常简单的浮点函数:

.data
TWO_DOUBLE real8 2.0

.code
mul2 proc
    movsd xmm1, TWO_DOUBLE
    mulsd xmm0, xmm1
    ret 
mul2 endp

然后我从C ++调用了我的函数:

extern "C" double mul2(double x);

int main()
{
    double d2 = mul2(1.0);
}

在发布模式下进行编译,/O2已优化且/LTCG已启用,我的反汇编可执行文件如下所示:

<addr> movsd  xmm0, mmword ptr [__real@3ff0000000000000 (013F9F21A8h)]  
<addr> call   mul2 (013F9F1075h)

但是,如果我在C ++中编写相同的函数,它将被转换为单个内联mulsd指令。

(实际上,我必须从main返回结果以避免使整个程序成为无操作,并随机化输入变量以防止编译器在编译时计算结果。)

对于希望用手写程序集优化代码的程序员来说,这似乎是一个非常严重的缺陷。如果MSVC不能内联它,那么除非你在程序集中做了大量的工作,否则它可能不值得函数调用开销。

是否有某种方法可以让MSVC内联手写的程序集丢失?

编辑:我意识到使用堆栈的更复杂的汇编函数可能更难以内联,但是只使用易失性寄存器的简单操作应该非常简单......对吗?

1 个答案:

答案 0 :(得分:2)

对于要应用跨模块内联的WPO(整个程序优化),两者必须使用/LTGC编译调用和调用的模块。

/LTGC不产生最终的二进制代码,而是产生中间语言(CIL)的特殊目标文件。由于您的程序集已经是机器代码,因此它无法参与WPO,因此无法内联。

如果您想使用SIMD指令但仍然可以利用WPO,则可以使用compiler intrinsics而不是汇编。例如,mulsd对应_mm_mul_sd