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
Tim Northover via llvm-dev
2017-Jul-25 13:49 UTC
[llvm-dev] Identify c-style pointer to array
Hi Alex, On 24 July 2017 at 23:28, alex via llvm-dev <llvm-dev at lists.llvm.org> wrote:> 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