4

On the use and abuse of alloca의 연타 왜`-O3` alloca를 2 배 빠르게 g ++

이전 질문의 하단에 몇 가지 벤치 마크를 얻었다보다. clang은 -O3 최적화 프로그램 프로필에서 더 나은 구현을 제공합니다. 뭐라 구요? clang이 어떤 코너를 자르고 있습니까? 또한 clang은 최신 컴파일러이기 때문에 alloca 구현시 안전 또는 다른 흥미로운 속성이 있습니까?

+3

이것은 clang이 LLVM alloca 명령어에 alloca 명령어를 매핑하면 (잘 구성된 SSA를 생성하는 데 널리 사용됨)'Reg2Mem' 패스가이를 변환 할 수 있습니다 LLVM이 일반 변수에 제공하는 모든 최적화를 얻는 LLVM 레벨 레지스터를 사용합니다. – delnan

답변

3

delnan의 추측 사실입니다. 하지만 그는 테스트가 매우 나쁘다는 것을 설명하지 않았고, 실제 alloca 수술을 alloca_test에서 최적화 할 수 있습니다.

alloca_test는 LLVM 적외선 조작 alloca 함수가 있지만 alloca() 함수 호출 :

%11 = call i32 @_Z18random_string_sizev() 
%12 = alloca i8, i32 %11 

malloc_test와 비교하지 :

%11 = call i32 @_Z18random_string_sizev() 
%12 = call i8* @malloc(i32 %11) 

을해도 -O1alloca_test에서 더 이상 alloca 함수가 없다 :

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 
} 

그리고 malloc_test를 들어, malloc을 호출은 여전히 ​​여기에 있습니다 :

%6 = tail call i32 @_Z18random_string_sizev() 
%7 = tail call i8* @malloc(i32 %6) 

나는 또한 g++ -O3이 (4.1 및 4.5.2 테스트)라고한다은 (주 효과 ALLOCA) 스택의 크기를 변경 밖으로 최적화하지 않습니다.

+0

잘 의미 론적으로 효과가 동일하지 않습니까? alloca 의미론을 llvm il 호출과 비교하여 인라인하면 메모리는 여전히 스택 프레임에 생성됩니까? –

+0

llvm이 alloca (호출자의 스택 크기를 변경하는 함수를 어떻게 호출 할 수 있는지)를 "호출"할 수 있지만 할당 동작은 기본 ir 작업 집합에 있습니다. http://llvm.org/docs/LangRef.html#i_alloca – osgx