I just added support for arrays to the front-end for a trading-specific DSL that I’m implementing using LLVM and ran into a minor bump.
Internally, I have been treating variables the same whether they end up being GlobalVariables or stack variables allocated with Alloca. I store the Value* I get from CreateAlloca or the Value* I get when I create a new GlobalVariable into my symbol table when emitting the LLVM IR and since they are both pointers the code is essentially the same.
When I implemented the code for stack-based arrays using Allocas, I saw the handy ArraySize argument to IRBuilder::CreateAlloca and used it.
Unfortunately, when I went to add global variable arrays, there was no equivalent ArraySize argument for the constructor, so what I had to do was create an array type that was sized properly and then make the global variable of that array type. This caused the allocation of the appropriate global variable but had the side effect of making the code that accessed array variables more complex. I now have two different ways I need to create the GEP to index into the array.
In the Alloca case, I index using the first parameter to the GEP instruction, since the pointer returned is a pointer to the type for the array ( for example, an i32*), this works fine.
In the GlobalVariable case, I can’t do this. The global value is typed as a pointer to a fixed-size array, not to the underlying type, so an index using the first argument of the GEP would index to the memory past the entire array. For example, if I passed 1 as the first argument for an array of [10 x i32], GEP would offset 40 bytes, not 4. This makes sense as this is the way that the GEP instruction is supposed to work.
It just makes my code more complex. So this leaves me with two questions:
How does everyone else handle this difference? I can go back into my code to make the Alloca case use the same typing mechanism I used for global variables to eliminate the difference in my code, but this seems ugly. What I’d really like is some way of getting a global variable that is sized just like the CreateAlloca instruction.
Is there some internal reason why there isn’t an ArraySize argument for the constructor for GlobalVariable like there is for CreateAlloca? If not, then would there be any objections if I added one and submitted a patch for it? Or is this perhaps much more difficult that it might first appear?