Tôi đang viết một trình biên dịch cho một ngôn ngữ đơn giản giống như C cho một khóa học tôi đang dùng. bit này mã:Có gì sai với số đăng ký LLVM này?
int main() {
printInt(not(0));
return 0;
}
int not(int n) {
if (n == 0) {
return 1;
} else {
int result = 0;
return result;
}
}
..Tôi ngây thơ biên dịch để bitcode này:
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
}
Tuy nhiên, từ chối không chấp nhận mã.
opt: core023.ll:25:5: error: instruction expected to be numbered '%2'
%1 = load i32* %result_0
Bây giờ, từ những gì tôi hiểu về các thanh ghi tạm thời chưa được đặt tên, chúng được đánh số liên tục bắt đầu từ 0. Trường hợp ở đây. Nhưng dường như dòng "% 1 = sub .." phải được đánh số% 2. Tại sao vậy? Có bất kỳ hướng dẫn nào giữa% 0 và% 1 tăng số thứ tự không? Hoặc có thể nó chỉ là một lỗi tiếp theo từ cái gì khác?
Một cách khác để giải thích nguyên nhân gây ra sự cố là bạn cần tránh phân nhánh ngay lập tức sau câu lệnh trả về. Nếu ngôn ngữ của bạn có mã để đảm bảo rằng tất cả các đường dẫn điều khiển đều trở lại, thì nó sẽ là tầm thường để kiểm tra xem nhánh trước của bạn đã trả về chưa. Trong trường hợp nó đã trả về, không cần phải chèn lệnh nhánh (br). Có một số lượng sổ sách kế toán nhà nước bạn sẽ cần phải làm để làm cho LLVM hài lòng với các khối cơ bản của bạn. –