I am trying to generate LLVM code that references a global array. Unfortunately, while I am generating the code I do not know the final length of the array, as I add elements to it as my compiler goes along. What is the best way to do this in LLVM? Ideally, I would be able to define the GlobalVariable array and change its length later on. I would love for it to have the correct length so I can leverage some of LLVM's static checking. I've been thinking that one level of indirection would solve the problem for me. What I could do is reference the global array via a function call while generating the code. Then, at the end, I would generate both the array and the function body: int array[size] = { ... }; int* globalArray( int index ) { return &array[index]; } Ideally, LLVM could then inline the function. Is there a better way to arrange for this to occur? Should I not care about array lengths and just have my global variable be a pointer? Thanks for the advice, Evan Jones -- Evan Jones http://evanjones.ca/
On Wed, 2 Nov 2005, Evan Jones wrote:> I am trying to generate LLVM code that references a global array. > Unfortunately, while I am generating the code I do not know the final length > of the array, as I add elements to it as my compiler goes along. What is the > best way to do this in LLVM? Ideally, I would be able to define the > GlobalVariable array and change its length later on. I would love for it to > have the correct length so I can leverage some of LLVM's static checking. > > I've been thinking that one level of indirection would solve the problem for > me. What I could do is reference the global array via a function call while > generating the code. Then, at the end, I would generate both the array and > the function body:I would suggest something like this. 1. Create the global variable array with size 0. 2. Use an std::vector<Constant*> to accumulate all of the initializers for the array. When you need a reference to the array, use the global created by #1. 3. When you have the final array, create a *new* global with the correct size and the initializer formed from the vector. 4. Replace the old GV with the new GV using code that looks like this: OldGV->replaceAllUsesWith(ConstantExpr::getCast(NewGV, OldGV->getType()); OldGV->eraseFromParent(); At the end of this, any instructions or other globals that referenced the temporary global will now reference the new one.> int array[size] = { ... }; > > int* globalArray( int index ) > { > return &array[index]; > } > > Ideally, LLVM could then inline the function.You could do something like this, but it's more indirect than the above process.> Is there a better way to > arrange for this to occur? Should I not care about array lengths and just > have my global variable be a pointer?If making the global a pointer works for you, that's certainly an option. The problem is that you can't have a static initializer in that case, requiring you to make some other global to hold the initializer. This also adds an extra level of indirection at runtime that you might not want. -Chris -- http://nondot.org/sabre/ http://llvm.org/
On Nov 2, 2005, at 16:39, Chris Lattner wrote:> 4. Replace the old GV with the new GV using code that looks like this: > > OldGV->replaceAllUsesWith(ConstantExpr::getCast(NewGV, > OldGV->getType()); > OldGV->eraseFromParent(); > > At the end of this, any instructions or other globals that referenced > the temporary global will now reference the new one.Ah ha! I was looking for something like this. Why didn't I see that there? I must be blind. In a vaguely related node, why does Module::getGlobalVariable *not* return types with internal linkage? There must be some logic behind that choice that I can't figure out. It is easy to copy the code out of Module.cpp if you need to find variables with internal linkage, but it seems unnecessary to me. Thanks, Evan -- Evan Jones http://evanjones.ca/
Apparently Analagous Threads
- [LLVMdev] Statically Initialized Arrays
- [LLVMdev] Statically Initialized Arrays
- [LLVMdev] [llvm-commits] [Patch, RFC] Re: Adding support for explicitly specified TLS models (PR9788)
- GlobalOPT and sections
- [LLVMdev] [llvm-commits] [Patch, RFC] Re: Adding support for explicitly specified TLS models (PR9788)