[LLVMdev] building a jump table in LLVM IR
Joshua Cranmer
pidgeot18 at gmail.com
Tue Jan 8 12:19:13 PST 2013
On 1/7/2013 10:51 AM, Tom Roeder wrote:
> AFAIK, this won't work: the way I want to use a jump table requires me
> to get a pointer into the table that I can use as a function pointer
> to call the original function in a normal call instruction. If I just
> add a new basic block in some containing function with a call
> instruction and somehow get a pointer to that instruction, then this
> does satisfy the goal of putting the new instructions somewhere, but a
> call through that pointer will not do the right thing, since it will
> be calling into the middle of the containing function, then calling
> the original function (whereas I want it to just jump to the original
> function directly so it doesn't mess up the call stack). The
> fundamental stumbling block is that it seems to be impossible (by
> design) to jump in this manner in LLVM IR.
Note that LLVM does do tail-call optimization, even if the called
function is an indirect function call. E.g.:
extern void (**jmptbl)();
void foo(int idx) {
jmptbl[idx]();
}
will produce the LLVM IR:
@jmptbl = external global void (...)**
define void @foo(i32 %x) nounwind uwtable {
%1 = sext i32 %x to i64
%2 = load void (...)*** @jmptbl, align 8
%3 = getelementptr inbounds void (...)** %2, i64 %1
%4 = load void (...)** %3, align 8
tail call void (...)* %4() nounwind
ret void
}
and the x86-64 assembly:
.type foo, at function
foo: # @foo
.cfi_startproc
# BB#0:
movslq %edi, %rcx
movq jmptbl(%rip), %rdx
xorb %al, %al
jmpq *(%rdx,%rcx,8) # TAILCALL
.Ltmp0:
.size foo, .Ltmp0-foo
.cfi_endproc
This does require optimization levels to be applied (-O1 does it, -O0
does not), and it won't guarantee that a stack frame will not be
produced for a glue function.
--
Joshua Cranmer
News submodule owner
DXR coauthor
More information about the llvm-dev
mailing list