2012-05-06 2 views
6

나는 내가 복용하고있는 코스에 대한 간단한 C와 유사한 언어 용 컴파일러를 작성하고 있습니다. 이 코드 비트 :이 LLVM 레지스터 번호는 무엇이 문제입니까?

int main() { 
    printInt(not(0)); 
    return 0; 
} 

int not(int n) { 
    if (n == 0) { 
     return 1; 
    } else { 
     int result = 0; 
     return result; 
    } 
} 

는 .. 난 순진하게도이 비트 코드로 컴파일 :

declare void @printInt(i32) 
declare void @printDouble(double) 
declare void @printString(i8*) 
declare i32 @readInt() 
declare double @readDouble() 

define i32 @main() { 
entry: 
    %0 = call i32 @not(i32 0) 
    call void @printInt(i32 %0) 
    ret i32 0 
    unreachable 
} 

define i32 @not(i32 %n_0) { 
entry: 
    %0 = icmp eq i32 %n_0, 0 
    br i1 %0, label %lab0, label %lab1 
lab0: 
    ret i32 1 
    br label %lab2 
lab1: 
    %result_0 = alloca i32 
    store i32 0, i32* %result_0 
    %1 = load i32* %result_0 
    ret i32 %1 
    br label %lab2 
lab2: 
    unreachable 
} 

그러나, 선택 하는 코드를 허용하지 않습니다.

opt: core023.ll:25:5: error: instruction expected to be numbered '%2' 
%1 = load i32* %result_0 

이제 그들이 생각하는지 나는 익명의 임시 레지스터의 이해에서 여기에 케이스입니다 0에서 시작하여 순차적으로 번호가된다. 하지만 분명히 "% 1 = 하위"줄의 번호가 % 2입니다. 왜 그런가요? % 0과 % 1 사이의 명령 중 시퀀스 번호가 증가합니까? 아니면 다른 것의 후속 결함 일 수 있습니까?

답변

9

LLVM에서 모든 것 일 수 있지만 번호는 지정되지 않습니다. 여기에는 기본 블록도 포함됩니다. 귀하의 경우

lab0: 
    ret i32 1 
    br label %lab2 

terminator instruction이 모두 기본 블록을 종료하기 때문에 두 개의 기본 블록을 정의합니다. 이것은 즉 2

, 나는 항상 명시 적으로 기본 블록의 이름을 지정하는 것이 좋습니다 이런 이상한 행동을 방지하기 위해 후 개념적으로, 코드가

lab0: 
    ret i32 1 
1: 
    br label %lab2 

하고 다음 무료 전화 번호로 구문 분석, 의미한다.

+0

문제의 원인을 해석하는 또 다른 방법은 return 문 다음에 분기를 피할 필요가 있다는 것입니다. 귀하의 언어에 모든 제어 경로가 반환되도록하는 코드가 있다면 이전 분기가 아직 반환되었는지 여부를 확인하는 것이 쉽습니다. 반환 된 경우 branch (br) 명령어를 삽입 할 필요가 없습니다. LLVM을 기본 블록에 만족스럽게 만들기 위해서는 주 단위의 부기가 필요합니다. –

관련 문제