HI all,
in C/C++, arrays and matrices often are passed as pointer so functions.
Suppose I'd like to write a pass operating on arrays , for example an
array of doubles passed via double * and checking for the type i will
identify a pointer to double (isAggregateType()=false).
As this style of passing arrays using pointers is widely used, I wonder
if there is any chance to identify a pointer type function argument (or
even pointer to pointer in the case of a 2d array) as array?
Thx
Alexander
Hi Alex,
As this style of passing arrays using pointers is widely used, I wonder
if there is any chance to identify a pointer type function argument (or
even pointer to pointer in the case of a 2d array) as array?
Not usually. C has a rarely used feature to tell the compiler how big
an array going into a function is:
void foo(int arr[static 5]) {}
With this Clang will add a "dereferenceable(20)" attribute to the
parameter that does roughly what you're asking. But without that
you're not allowed to assume anything about the "array" so even
knowing it was an array is largely pointless at the LLVM level.
Another alternative if you control the C is to pass a pointer to an array:
void foo(int (*arr)[5]) {}
This will come through to LLVM as "[5 x i32]*" which you can in the type system.
Cheers.
Tim.
Not usually. C has a rarely used feature to tell the compiler how big
an array going into a function is:
void foo(int arr[static 5]) {}
With this Clang will add a "dereferenceable(20)" attribute to the
parameter that does roughly what you're asking. But without that
you're not allowed to assume anything about the "array" so even
knowing it was an array is largely pointless at the LLVM level.
Another alternative if you control the C is to pass a pointer to an array:
void foo(int (*arr)[5]) {}
This will come through to LLVM as "[5 x i32]*" which you can in the type system.
Cheers.
Tim.
Hi Tim,
hmm, currently, I'm using the fixed size arrays (as you suggested). This
is fine for self written c code (when we don't need dynamic sized arrays).
However, c code like
int i=5;
double dArr[i];
dArr[2]=42.0;
in IR translates to a double * of type pointer to double, not aggregate
type;
The last line in IR translates to (vla relates to the is the dynamically
allocated array):
%arrayidx = getelementptr inbounds double* %vla, i64 3
store double 4.200000e+01, double* %arrayidx, align 8
which is different to the usual aggregate style call (with leading i32 0):
%arrayidx = getelementptr inbounds [5 x double]* %0, i32 0, i64 3
I thought the getelemtptr call using 'inbounds' would return a poison
value if the index is out of bounds -> a naive approach would be to
iterate from 0 upwards, try to introduce a gep instruction and stopping
at the first poison value.
This approach however is cumbersome, as I would need to check every
pointer that way to see if it actually relates to an array....
Alex