0

I'm writing a function pass, and would like to add a global variable of type int in the initialisation phase, for use in the actual work of the pass.

So far, I have

bool doInitialization(Module &M) { LLVMContext &c = M.getContext(); Type *intTy = TypeBuilder<int,false>::get(c); Value *p = M.getOrInsertGlobal("var1",intTy); return true } 

For whatever reason, var1 has type int*. For example, adding this after the declaration

Type *pt = p->getType(); if (isa<PointerType>(pt)) { errs().write_escaped("Is a pointer ty") << '\n'; } 

Will end up with a print when the compiled code is run, and

if ((intTy->getPointerTo()) == (p->getType())) { errs().write_escaped("This is confusing") << '\n'; } 

Will again print the string.

Is it possible to add a global variable of type int using this method, and if so, where am I going wrong?

2 Answers 2

2

You're doing it right. Global variables are always stored in memory -- you've inserted a global variable of type i32, and gotten back a pointer to that memory location. In C terms, you got back &var1 instead of var1. To manipulate the value stored in the pointer, you'll need to create load and store instructions.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your help! This is slightly off topic, but I feel it's related enough to stay on this page: In my function pass, I'm calling Value* vpointer = M->getGlobalVariable("var1"); LoadInst load(vpointer,"var1",&i); &i is from the iterator. This code segfaults. The LoadInst is the problem, removing it removes the segfault. I think the issue is from the string argument to LoadInst(), because I'm basically just guessing what to put there (there's little documentation). How should I fix this segfault?
@LLVMHacker30 I'd suggest looking into using IRBuilder rather than creating instructions manually.
Not sure what this answer adds that my earlier answer didn't :(
@dune.rocks The upvote isn't mine (I don't have the 'reputation' to upvote) and I asked the followup to Ismail because he happened to be higher up the page when I came back. Both answers are really useful.
0

When using getOrInsertGlobal, you pass the underlying type of the object you wish to create in the global namespace. The implementation then uses getPointerType to actually create the mapping in the module's symbol table, which is why you're seeing a pointer to the type you're passing in.

So you'll need to load and store to the global.

Comments