我的编译器的自定义 LLVM-IR 出现问题

问题描述 投票:0回答:1

我目前正在研究生成 LLVM-IR 的编程语言编译器。我没有使用任何库进行发射,所以我只是将指令写入文件。问题是可变变量,我用值注册

%i, %i.(index)
,然后用
%i
加载
%i.(index)
。这可能不是在 llvm 中拥有可变变量的正确方法,但这是我之前尝试过的最好的方法,因为我需要它们使用递归,例如在循环 i 时,只要值小于 10 即可这段代码做了什么

LLVM 输出代码:

@.str_0 = private unnamed_addr constant [4 x i8] c"%i\0A\00"
declare i32 @printf(i8*, ...) nounwind

define i32 @add(i32 %a, i32 %b) nounwind {
entry:
    %t1 = add i32 %a, %b
    ret i32 %t1
}

define i32 @main() nounwind {
entry:
    %i = alloca i32
    %i.0 = alloca i32
    store i32 0, i32* %i.0
    store i32 %i.0, i32* %i
    %t2 = icmp slt i32 %i, 10
    br i1 %t2, label %lb1, label %lb2
lb1:
    %t3 = getelementptr [4 x i8], [4 x i8]* @.str_0, i32 0, i32 0
    %t4 = call i32 @printf(i8* %t3, i32 %i)
    %t5 = call i32 @add(i32 %i, i32 1)
    %i.1 = alloca i32
    store i32 %t5, i32* %i
    store i32 %i.1, i32* %i
    %t6 = icmp slt i32 %i, 10
    br i1 %t6, label %lb1, label %lb2
lb2:
    ret i32 0
}

我的编译器生成的代码:

fn add(a: int, b: int): int {
    return a + b;
}

fn main(): void {
    let i: int = 0;
    while (i < 10) {
        printf("%i\n", i);
        i = add(i, 1);
    }
    return;
}

错误:

./out/test.zk.ll:15:15: error: '%i.0' defined with type 'ptr' but expected 'i32'
   15 |     store i32 %i.0, i32* %i
      |               ^
1 error generated.

我希望能够定义一个可变变量,然后在它以递归方式工作后更改它的值。

提前感谢您的帮助。

llvm programming-languages llvm-ir
1个回答
0
投票

你只需要在LLVM IR中操作%i = alloca i32的指针,读取时使用load,更新时使用store

有一个类似的循环示例while测试,它生成下面的IR代码。

define i32 @test_func(i32 %x, i32 %y) {
 entry:
  %0 = alloca i32, align 4
  %1 = alloca i32, align 4
  store i32 %x, ptr %1, align 4
  %2 = alloca i32, align 4
  store i32 %y, ptr %2, align 4
  br label %while_cond_0

 while_cond_0:                                     ; preds =        %while_body_0, %entry
   %3 = load i32, ptr %1, align 4
   %4 = icmp sgt i32 %3, 0
   br i1 %4, label %while_body_0, label %while_end_0

  while_body_0:                                     ; preds = %while_cond_0
   %5 = load i32, ptr %2, align 4
   %6 = add i32 %5, 10
   store i32 %6, ptr %2, align 4
   %7 = load i32, ptr %1, align 4
   %8 = sub i32 %7, 1
   store i32 %8, ptr %1, align 4
   br label %while_cond_0

 while_end_0:                                      ; preds = %while_cond_0
 %9 = load i32, ptr %2, align 4
 store i32 %9, ptr %0, align 4
 br label %exit

exit:                                             ; preds = %while_end_0
 %10 = load i32, ptr %0, align 4
 ret i32 %10

}

© www.soinside.com 2019 - 2024. All rights reserved.