2014-07-07 8 views
3

저는 LLVM IR에 코드 생성을 망설였습니다. 로컬 변수를 할당해야 할 때의 구분과 이해할 수없는 부분이 있습니다. 리터럴 값을 로컬 변수에로드합니다. 그래서 내 질문은 생각LLVM의 로컬 변수에 리터럴 값 할당 IR

target triple = "x86_64-apple-macosx10.10.0" 

define i32 @main() { 
    %t1 = alloca i32 
    store i32 3, i32* %t1 
    %x = add nsw i32 0, 3 

    %y = add nsw i32 %x, 4 
    ret i32 %y 
} 

; ModuleID = 'test.c' 
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" 
target triple = "x86_64-apple-macosx10.10.0" 

; Function Attrs: nounwind ssp uwtable 
define i32 @main() #0 { 
    %1 = alloca i32, align 4 
    %x = alloca i32, align 4 
    %y = alloca i32, align 4 
    store i32 0, i32* %1 
    store i32 3, i32* %x, align 4 
    %2 = load i32* %x, align 4 
    %3 = add nsw i32 %2, 4 
    store i32 %3, i32* %y, align 4 
    %4 = load i32* %y, align 4 
    ret i32 %4 
} 

attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" } 

!llvm.ident = !{!0} 

!0 = metadata !{metadata !"Apple LLVM version 5.1 (clang-503.0.40) (based on LLVM 3.4svn)"} 

내가 트리밍 할 수 아래로 : 나는 LLVM IR에 다음과 같은 간단한 C 코드를 컴파일하는 경우

//test.c 
int main() { 
    int x = 3; 
    int y = x + 4; 
    return y; 
} 

나는이 출력을 얻을 , 왜 변수에 리터럴 숫자를로드하는 등의 순환 방식입니까? 더 나은 /보다 직접적인 방법이 있습니까? 또한 %t1alloca -ed 일 필요가 있지만 %x%y은 필요하지 않은 이유는 무엇입니까?

답변

4

Clang은 첫 번째 코드 세그먼트를 생성합니다. Clang은 이러한 명령어에 대해 IR을 생성하는 가장 쉬운 방법을 선택합니다. 각 명령어에 대해 메모리를 할당 한 다음이 메모리에 저장하고로드합니다. 이렇게하면 C 변수의 의미를 에뮬레이트 할 수있는 IR이 생성되어 수명 내내 다른 값을 재 할당 할 수 있습니다. LLVM IR에는 아무 것도 없습니다 (변수가 없습니다 - read more about SSA).

하지만 Clang이하는 일은 컴파일의 첫 단계에 불과합니다. 이 IR은 수많은 변형 (패스라고 함)을 통과합니다. 하나는 getting rid of the memory use을 담당 할 것이며, 두 번째 스 니펫에 나와 있습니다. 나중에이 값에 대해 스택 대신 레지스터를 사용할 수 있습니다. 또 다른 패스는 get rid of the unused value%t1이고, 또 다른 패스는 identify that constants are being used here and will replace the entire function body with return i32 7 ... 등입니다.

요약하자면, 이것은 "원형 교차로"가 아니며, Clang이 IR을 생성하는 가장 쉬운 방법이며, IR을 더 잘 만드는 것은 나중에 LLVM이 통과하는 책임입니다.

+0

좋아요, 그건 아주 의미가 있습니다. 뭔가 빠져있는 것처럼 느껴졌지 만 이해하면 코드 생성이 쉬워집니다. 감사! – Jumhyn