Reputation: 1744
I'm new to LLVM IR and I'm implementing PL0 language. http://en.wikipedia.org/wiki/PL/0
I'm generating the testfile as following:
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.
And the LLVM IR I generated is like this:
; 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
}
I got a painful error here (at destruction):
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.
I guess that using variable c
(defined in __global_main_entry__
) in procedure check2
adds a ref in llvm::Value, when destructing __global_main_entry__
the ref at check2
is causing the error.
I do not know how to solve the problem, and if you have time to be specific, please~
(Moreover, except for the official documentation of llvm. Are there any more resources on LLVM? I found that most tutorials are outdated.)
My full list of code is here: https://github.com/adamcavendish/PL0Compiler
Thanks in advance.
Upvotes: 1
Views: 564
Reputation: 26868
Your IR is malformed - you cannot refer to an instruction from the body of a function different from the one in which the instruction appears, so referring to %c
in @check2
is illegal. The failure just happened to occur during module destruction, but it can occur in other circumstances as well.
In general, I recommend running opt -verify
on your IR if you're not sure it's legal, it will give you nice error messages. My Eclipse plugin might also help if you want to experiment with IR to see when it is and isn't legal.
As for a solution, it looks like you should create a global variable to represent c
, not an instruction. Then you can store
into it and load
from it in every function in the module.
Upvotes: 2