Memory management 为什么是叮当声';s`-O3`alloca比g+快2倍+;
Memory management 为什么是叮当声';s`-O3`alloca比g+快2倍+;,memory-management,compiler-construction,clang,micro-optimization,Memory Management,Compiler Construction,Clang,Micro Optimization,在前一个问题的底部有一些基准。在-O3优化器配置文件中,clang显然有更好的实现。有什么好处?叮当有什么捷径吗?另外,由于clang是一个现代编译器,它的alloca实现中是否有任何安全性或其他有趣的属性 德尔南的猜测是正确的。但他并没有说明测试非常糟糕,而且clang可以从alloca\u test优化实际的alloca操作 alloca\u test只有llvm ir操作alloca,但没有alloca()函数调用: %11 = call i32 @_Z18random_string_si
在前一个问题的底部有一些基准。在
-O3
优化器配置文件中,clang显然有更好的实现。有什么好处?叮当有什么捷径吗?另外,由于clang是一个现代编译器,它的alloca实现中是否有任何安全性或其他有趣的属性 德尔南的猜测是正确的。但他并没有说明测试非常糟糕,而且clang可以从alloca\u test
优化实际的alloca
操作
alloca\u test
只有llvm ir操作alloca,但没有alloca()
函数调用:
%11 = call i32 @_Z18random_string_sizev()
%12 = alloca i8, i32 %11
与malloc_测试比较:
%11 = call i32 @_Z18random_string_sizev()
%12 = call i8* @malloc(i32 %11)
define void @_Z11alloca_testv() nounwind {
; <label>:0
%1 = tail call i32 @_Z18random_vector_sizev()
%2 = icmp sgt i32 %1, 0
br i1 %2, label %.lr.ph, label %._crit_edge
.lr.ph: ; preds = %.lr.ph, %0
%i.01 = phi i32 [ %4, %.lr.ph ], [ 0, %0 ]
%3 = tail call i32 @_Z18random_string_sizev()
%4 = add nsw i32 %i.01, 1
%exitcond = icmp eq i32 %4, %1
br i1 %exitcond, label %._crit_edge, label %.lr.ph
._crit_edge: ; preds = %.lr.ph, %0
ret void
}
即使使用了-O1
,在alloca\u测试中也没有更多的alloca
:
%11 = call i32 @_Z18random_string_sizev()
%12 = call i8* @malloc(i32 %11)
define void @_Z11alloca_testv() nounwind {
; <label>:0
%1 = tail call i32 @_Z18random_vector_sizev()
%2 = icmp sgt i32 %1, 0
br i1 %2, label %.lr.ph, label %._crit_edge
.lr.ph: ; preds = %.lr.ph, %0
%i.01 = phi i32 [ %4, %.lr.ph ], [ 0, %0 ]
%3 = tail call i32 @_Z18random_string_sizev()
%4 = add nsw i32 %i.01, 1
%exitcond = icmp eq i32 %4, %1
br i1 %exitcond, label %._crit_edge, label %.lr.ph
._crit_edge: ; preds = %.lr.ph, %0
ret void
}
我还应该说
g++-O3
(测试4.1和4.5.2)并没有优化堆栈大小的变化(alloca主效应)。这只是一个猜测,但是:如果clang将alloca
映射到LLVMalloca
指令,则(广泛使用,因为它负责创建格式良好的SSA)Reg2Mem
pass可以将其转换为使用LLVM级别的寄存器,这些寄存器可以获得LLVM为正常变量提供的所有优化?内联alloca语义与使用llvm il调用相比,内存仍然在堆栈帧上创建?我不知道llvm是否允许“调用”alloca(调用函数如何更改调用方的堆栈大小),但alloca ir op在基本ir操作集中。