zell
zell

Reputation: 10204

Create a LLVM function with a reference argument (e.g. double &x)

I want to create, from scratch, a new function in LLVM IR. The LLVM code should correspond to a C++ function with a reference argument, say

void foo(double &x){ x=0; }

The tutorial such as http://llvm.org/releases/2.6/docs/tutorial/JITTutorial1.html is too old (llvm 2.6) and does not consider pass-by-reference function.

Any hint on how to do this? Thanks.

Upvotes: 2

Views: 1907

Answers (1)

Hongxu Chen
Hongxu Chen

Reputation: 5350

In LLVM, Reference types are typically implemented with pointer types. For the following C++ source code,

int foo(int & i) {
    return i;
}

int bar(int *i) {
    return *i;
}

void baz(int i) {
    foo(i);
    bar(&i);
}

The corresponding IR is:

; Function Attrs: nounwind
define i32 @_Z3fooRi(i32* dereferenceable(4) %i) #0 {
entry:
  %i.addr = alloca i32*, align 8
  store i32* %i, i32** %i.addr, align 8
  %0 = load i32*, i32** %i.addr, align 8
  %1 = load i32, i32* %0, align 4
  ret i32 %1
}

; Function Attrs: nounwind
define i32 @_Z3barPi(i32* %i) #0 {
entry:
  %i.addr = alloca i32*, align 8
  store i32* %i, i32** %i.addr, align 8
  %0 = load i32*, i32** %i.addr, align 8
  %1 = load i32, i32* %0, align 4
  ret i32 %1
}

; Function Attrs: nounwind
define void @_Z3bazi(i32 %i) #0 {
entry:
  %i.addr = alloca i32, align 4
  store i32 %i, i32* %i.addr, align 4
  %call = call i32 @_Z3fooRi(i32* dereferenceable(4) %i.addr)
  %call1 = call i32 @_Z3barPi(i32* %i.addr)
  ret void
}

You can find that there is no essential difference for i between functions foo and bar: dereferenceable is just a parameter attribute that you can add yourself during the code generation from the frontend.

Upvotes: 1

Related Questions