Hi everybody! I recently started using llvm in a project on inferring additional information about pointers based on their types, casts, etc. The following simple example is giving me a headache :): typedef struct { int a; short b, c; int d, e, f; } foo; void bar(foo f) { short s; s = f.b; } int main(void) { foo p; bar(p); } Because llvm doesn't allow structures and arrays to be passed as arguments, the llvm intermediate format output for this C program looks like this: - the signature of function bar becomes void @bar(i64 %f.0.0, i64 %f.0.1, i32 %f.1) - before the call to function bar, structure foo is casted to structure { [2 x i64], i32 } and each element of that structure is read into integer variables, which are then used as parameters for the call - in the beginning of function bar, the same process is repeated, just backwards Is this the default llvm-gcc behaviour? Could it be changed somehow? For instance, instead of casting a structure essentially to an array of integers, one could maybe read the structure field by field, and than pass those as arguments.... If the way llvm translates such function calls can't be changed, is there any way to get the original function signature? Thanks! Cheers, -- Zvonimir
Hi all, I have the same problem. My guess is that when a structure is passed as a parameter, you cast it into an array for optimization reasons (less parameters, less stack space). This is, certainly, a reasonable optimization, but makes inter-procedural static analysis more complex. Is there a way to disable it (my guess is that this should be doable by passing some parameter to llvm-gcc)? If there is no way to disable it, could anyone suggest where should I look into the code and whether you would accept a patch that would add an option that disables the optimization? Thank you, -- Domagoj Babic http://www.domagoj.info/ http://www.calysto.org/
On Oct 2, 2007, at 1:03 AM, Domagoj Babic wrote:> Hi all, > > I have the same problem. My guess is that when a structure > is passed as a parameter, you cast it into an array for optimization > reasons (less parameters, less stack space).This is not an optimization. This behavior is to be ABI complaint when emitting code for your OS. That said, this is not a very good way to do this. Rafael is working on adding the 'byref' attribute which will support this much more gracefully in the future.> This is, certainly, a reasonable optimization, but makes > inter-procedural static analysis more complex. Is there a way to > disable it (my guess is that this should be doable by passing > some parameter to llvm-gcc)?The easiest way to disable this is to hack it out of llvm-gcc. Change this (gcc/llvm-abi.h): #ifndef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS #define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) \ !isSingleElementStructOrArray(type) #endif to: #undef LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS #define LLVM_SHOULD_PASS_AGGREGATE_IN_INTEGER_REGS(X) 0 Note that you won't be able to mix and match .o files with GCC where structs are passed by value. -Chris
On 29/09/2007, Zvonimir Rakamaric <zrakamar at gmail.com> wrote:> Hi everybody! > > I recently started using llvm in a project on inferring additional > information about pointers based on their types, casts, etc. The > following simple example is giving me a headache :):Me too :-) As Chris reported, I am working at adding support for a "byval" attribute that will make this more explicit on llvm IL and make it possible to correctly implement all of the X86-64 ABI. I have most of the code gen for X86 and X86-64 working. The only missing part is the passing of structures with small alignments. I hope to implement that this Friday. After that I have to change the other backends and then the front ends. Cheers, -- Rafael Avila de Espindola Google Ireland Ltd. Gordon House Barrow Street Dublin 4 Ireland Registered in Dublin, Ireland Registration Number: 368047