Saving a reference to a Basic Block?

Is there a way to save a reference to a Basic Block that gets all fixed up in the linker, so that you can branch to it during execution? (Or maybe just a better way to do what I’m trying to do?)

In my old-school BASIC compiler that I’m writing with LLVM, for each GOSUB, I keep a map of an integer ID and a pointer to the basic block following the GOSUB to return to.
Then, when a BASIC RETURN is executed, it pops the integer ID off a software stack and executes a switch statement based on that ID to branch to the Base Block to return to for that integer ID.

(I attached a text file with the input file, output file, and generated LLVM code, if you want to see all the details).

But to explain it in psudeo code:

The BASIC code is:

gosub sub1
gosub sub2

sub1:
sub2:
return

(Note the “subroutine” has multiple entry points, or put another way, the subroutines can share common code or return statements)

Which translates to this llvm psuedo code:

basicblock1: ext_runtime_function_push(101): br sub1 ← 101 could be anything, the compiler stores a map of 101-to-basicblock1_ret
basicblock1_ret:
basicblock2: ext_runtime_function_push(102): br sub2 ← 102 could be anything, the compiler stores a map of 102-to-basicblock2_ret
basicblock2_ret:
br somewhere

basicblock.sub1: …

basicblock.sub2: …
br basicblock.ret

basicblock.ret:
switch( ext_runtime_func_pop() )
case 101: br basicblock1_ret ← generated from the compiler’s map of 101-to-basicblock1_ret

case 102: br basicblock2_ret ← generated from the compiler’s map of 102-to-basicblock2_ret
default: error

Which works just fine. But what would be nice would be:

basicblock1: ext_func_push(handleof(basicblock1_ret) ): br sub1
basicblock1_ret:
basicblock2: ext_func_push(handleof(basicblock2_ret)): br sub2
basicblock2_ret:
br somewhere

basicblock.sub1: br basicblock.ret

basicblock.sub2: br basicblock.ret

basicblock.ret:
br ext_func_pop()

Where, in the generated & linked Intel 386 assembly, its obvious that the ext_func_push could push the 32-bit address of the basicblock1_ret label, and the br would jump to that address. But how to get there from here?

Since I have a working solution, this is just a “shouldn’t there be a more elegant way to do this?” question.

Thanks!!!

my-llvm-example.txt (6.01 KB)

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of John Slagel
Subject: [LLVMdev] Saving a reference to a Basic Block?

Is there a way to save a reference to a Basic Block that gets all fixed
up in the linker, so that you can branch to it during execution?

We use the blockaddress() constant generator, coupled with the indirectbr instruction:

http://llvm.org/releases/3.1/docs/LangRef.html#blockaddress
http://llvm.org/releases/3.1/docs/LangRef.html#i_indirectbr

Note that all target basic blocks of indirectbr must be provided to the instruction as part of the IR construction.

Also, at least the x86_64 target for the legacy JIT is missing some required functionality for handling blockaddress(); we've fixed that locally, but need to check what the MCJIT does before submitting a patch.

- Chuck

THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.

Sorry for bringing up an old topic, but I was wondering the status? (See below)
Thanks!!

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of John Slagel
Subject: [LLVMdev] Saving a reference to a Basic Block?

Is there a way to save a reference to a Basic Block that gets all fixed
up in the linker, so that you can branch to it during execution?

We use the blockaddress() constant generator, coupled with the indirectbr instruction:

http://llvm.org/releases/3.1/docs/LangRef.html#blockaddress
http://llvm.org/releases/3.1/docs/LangRef.html#i_indirectbr

Note that all target basic blocks of indirectbr must be provided to the instruction as part of the IR construction.

Also, at least the x86_64 target for the legacy JIT is missing some required functionality for handling blockaddress(); we’ve fixed that locally, but need to check what the MCJIT does before submitting a patch.

Has this been resolved?
Thanks!!

From: llvmdev-bounces@cs.uiuc.edu [mailto:llvmdev-bounces@cs.uiuc.edu]
On Behalf Of John Slagel
Subject: Re: [LLVMdev] Saving a reference to a Basic Block?

> Also, at least the x86_64 target for the legacy JIT is missing some
> required functionality for handling blockaddress(); we've fixed that
> locally, but need to check what the MCJIT does before submitting a patch.

Has this been resolved?

We have not submitted our patches for blockaddress handling yet, since our upgrade to MCJIT has been delayed.

- Chuck

THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers.