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