Adam
Adam

Reputation: 1744

How can I add reference to a variable defined in previous function in LLVM IR?

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

Answers (1)

Oak
Oak

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

Related Questions