need to store the address of a variable

Hello everybody,

my problem is, that I want to get an array of pointers to all local variables
in a function. This array will be used for transfering these Variables to
another execution engine.

I've code which generates this array, and a pointer to the target field of the
array.

name = variables.fname + "_pointerArray";
Instruction* pointerArray = new
    AllocaInst(PointerType::get(Type::Int32Ty,NULL),
    ConstantInt::get(Type::Int32Ty, variables.inst.size()),
    name,
    alloca_point);
    
    // fill array with the addresses of the functions
    for(unsigned int i = 0; i < variables.inst.size(); i++) {
      name = "store_" + variables.inst[i]->getName();
      Value* GEP = new GetElementPtrInst(pointerArray,
                 ConstantInt::get(Type::Int32Ty, i),
                 name,
                    alloca_point);
    }

the result of this is:

%minPos_pointerArray = alloca i32*, i32 26 ; <i32**> [#uses=26]
%store_tmp1 = getelementptr i32** %minPos_pointerArray, i32 1 ; <i32**> ...

But I could not find a way to get a pointer to a given variable.

When I translate the following C Code with llvm-gcc

int a;
int* d;
d = &a;

to LLVM I get the following LLVM Code

%a_addr = alloca i32 ; <i32*> [#uses=2]
%d = alloca i32* ; <i32**> [#uses=2]
store i32 %a, i32* %a_addr
store i32* %a_addr, i32** %d, align 4

how can I generate such an Instruction?

When I use

name = variables.inst[i]->getName() + "address_";
Instruction *AD = new AllocaInst(Type::Int32Ty,
ConstantInt::get(Type::Int32Ty, 1), name, alloca_point);
StoreInst *SI = new StoreInst(variables.inst[i], AD, alloca_point);
StoreInst(SI, GEP, alloca_point);

the compiler is happy, but I get the following error at run time:

Instructions.cpp:904: void llvm::StoreInst::AssertOK(): Assertion
`getOperand(0)->getType() ==
cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be
a pointer to Val type!"' failed.

I hope you understand what I want, and someone knows the right way to do that.

Many thanks for your time.

Paul

Paul Arndt wrote:

Hello everybody,

my problem is, that I want to get an array of pointers to all local variables in a function. This array will be used for transfering these Variables to another execution engine.

I've code which generates this array, and a pointer to the target field of the array.

name = variables.fname + "_pointerArray";
Instruction* pointerArray = new
    AllocaInst(PointerType::get(Type::Int32Ty,NULL),
    ConstantInt::get(Type::Int32Ty, variables.inst.size()),
    name,
    alloca_point);
    
    // fill array with the addresses of the functions
    for(unsigned int i = 0; i < variables.inst.size(); i++) {
      name = "store_" + variables.inst[i]->getName();
      Value* GEP = new GetElementPtrInst(pointerArray, ConstantInt::get(Type::Int32Ty, i),
                 name, alloca_point);
    }

the result of this is:

%minPos_pointerArray = alloca i32*, i32 26 ; <i32**> [#uses=26]
%store_tmp1 = getelementptr i32** %minPos_pointerArray, i32 1 ; <i32**> ...

But I could not find a way to get a pointer to a given variable.
  

You probably already know this, but I want to state it just in case. LLVM has no address-of operator, so if you see an instruction like "%sum = add i32 %x, %y" you can't get the address of %sum (it's a register, after all).

The C frontend doesn't interpret "int32_t i;" as creating an LLVM variable of type i32; it actually does "i32* %i_addr = alloca i32". LLVM's optimizers will remove the alloca and lower it to registers if nobody takes its address.

I think what you're saying is that you want a pointer to a given C variable, not a given LLVM variable, which is certainly possible.

When I translate the following C Code with llvm-gcc

int a;
int* d;
d = &a;

to LLVM I get the following LLVM Code

%a_addr = alloca i32 ; <i32*> [#uses=2]
%d = alloca i32* ; <i32**> [#uses=2]
store i32 %a, i32* %a_addr
store i32* %a_addr, i32** %d, align 4

how can I generate such an Instruction?
  

In general, what you can do is take that code:

define void @foo(i32 %a) {
  %a_addr = alloca i32 ; <i32*> [#uses=2]
  %d = alloca i32* ; <i32**> [#uses=2]
  store i32 %a, i32* %a_addr
  store i32* %a_addr, i32** %d, align 4
  ret void
}

then run "llc -march=cpp arndt.bc -f -o -" to see the C++ code that constructs the module from the input bytecode. In your case, the relevant section looks like this:

AllocaInst* ptr_a_addr = new AllocaInst(IntegerType::get(32), "a_addr", label_4);
AllocaInst* ptr_d = new AllocaInst(PointerTy_1, "d", label_4);
StoreInst* void_5 = new StoreInst(int32_a /* argument %a */, ptr_a_addr, false, label_4);
StoreInst* void_6 = new StoreInst(ptr_a_addr, ptr_d, false, label_4);

void_5 is putting the argument %a into the locally allocated %a_addr.
void_6 is taking %a_addr and storing it into %d.

When I use

name = variables.inst[i]->getName() + "address_";
Instruction *AD = new AllocaInst(Type::Int32Ty, ConstantInt::get(Type::Int32Ty, 1), name, alloca_point);
StoreInst *SI = new StoreInst(variables.inst[i], AD, alloca_point);
StoreInst(SI, GEP, alloca_point);
  

That looks wrong. The last line, "StoreInst(SI, GEP, alloca_point)" is trying to store the result of your first store (which is void) to the place pointed to by GEP.

Nick

then run "llc -march=cpp arndt.bc -f -o -" to see the C++ code that
constructs the module from the input bytecode. In your case, the
relevant section looks like this:

Many thanks Nick, the llvm2cpp tools is the piece I was searchig for. This
hint makes things much easier for me. So I can formulate want I need in C for
a simple example, translate it to LLVM and then generate CPP Code that is
easy to generalisize.

Paul