如何在LLVM IR中添加对先前函数中定义的变量的引用?

时间:2014-01-31 17:21:14

标签: llvm llvm-ir

我是LLVM IR的新手,我正在实施PL0语言。 http://en.wikipedia.org/wiki/PL/0

我正在生成如下测试文件:

const a = 10;
var b, c;

procedure check1;
var dd;
   procedure check2;
       c := 2;
begin
   dd := 1
end;

begin
    b := -1024+53*(-514-766)/93+100;
    c := b
end.

我生成的LLVM IR是这样的:

; ModuleID = 'LLVM Module'

define void @__global_main_entry__() {
BlockUnitEntry:
  %b = alloca i32
  %c = alloca i32
  store i32 -1653, i32* %b
  %b1 = load i32* %b
  store i32 %b1, i32* %c
  ret void
}

define void @check1() {
ProcedureEntry:
  %dd = alloca i32
  store i32 1, i32* %dd
  ret void
}

define void @check2() {
ProcedureEntry:
  store i32 2, i32* %c
  ret void
}

我在这里遇到了一个痛苦的错误(在破坏时):

While deleting: i32* %c
Use still stuck around after Def is destroyed:  store i32 2, i32* %c
test004_llvm_generate: /files/Install/LLVM_Framework/llvm/lib/IR/Value.cpp:79: virtual llvm::Value::~Value(): Assertion `use_empty() && "Uses remain when a value is destroyed!"' failed.

我想在程序c中使用变量__global_main_entry__(在check2中定义)在llvm :: Value中添加一个ref,当__global_main_entry__在{check2处取消时1}}导致错误。

我不知道如何解决问题,如果你有时间具体,请~~

(此外,除了llvm的官方文档。在LLVM上还有更多资源吗?我发现大多数教程已经过时了。)

我的完整代码列表位于:https://github.com/adamcavendish/PL0Compiler

提前致谢。

1 个答案:

答案 0 :(得分:2)

你的IR格式错误 - 你不能参考与指令出现的函数体不同的指令,因此在%c中引用@check2是非法的。失败恰好发生在模块销毁期间,但也可能在其他情况下发生。

一般情况下,如果您不确定它是否合法,我建议您在IR上运行opt -verify,它会为您提供很好的错误消息。 My Eclipse plugin如果您想尝试使用IR来查看它何时合法并且不合法,那么global variable也可能会有所帮助。

对于解决方案,您应该创建一个{{3}}来表示c,而不是一条指令。然后,您可以在模块中的每个函数中store进入它并load