Пример работы генератора
Исходный код программы:
def fact(n: int) -> int:
if n <= 1:
return 1
return n * fact(n - 1)
def main() -> None:
x: int
x = fact(3)
print(x)
Код LLVM IR, построенный генератором:
@.placeholder.int = private unnamed_addr constant [3 x i8] c"%d\00", align 1
declare i32 @printf(i8*, ...)
declare i32 @scanf(i8*, ...)
define i64 @fact(i64 %0) {
fact_entry:
%n = alloca i64, align 8
store i64 %0, i64* %n, align 4
br label %block
block: ; preds = %fact_entry
br label %ifcond
ifcond: ; preds = %block
%1 = load i64, i64* %n, align 4
%2 = icmp sle i64 %1, 1
br i1 %2, label %ifbody, label %endif
ifbody: ; preds = %ifcond
ret i64 1
br label %endif
endif: ; preds = %ifbody, %ifcond
%3 = load i64, i64* %n, align 4
%4 = sub i64 %3, 1
%5 = call i64 @fact(i64 %4)
%6 = load i64, i64* %n, align 4
%7 = mul i64 %6, %5
ret i64 %7
}
define void @main() {
main_entry:
br label %block
block: ; preds = %main_entry
%x = alloca i64, align 8
%0 = call i64 @fact(i64 3)
store i64 %0, i64* %x, align 4
%1 = load i64, i64* %x, align 4
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.placeholder.int, i32 0, i32 0), i64 %1)
%3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.placeholder.newline, i32 0, i32 0))
ret void
}