[LLVMdev] Question about the old C back-end
Roel Jordans
r.jordans at tue.nl
Thu Oct 11 07:58:55 PDT 2012
Hi Duncan,
On 11/10/12 15:47, Duncan Sands wrote:
> Hi Roel,
>
>> When going through the internals of the old C back-end, I see that the CBE
>> encapsulates arrays into a struct. The source code has the following comment to
>> explain this behaviour.
>>
>> // Arrays are wrapped in structs to allow them to have normal
>> // value semantics (avoiding the array "decay").
>>
>> For example, the CBE translates:
>> @a = common global [10 x i32] zeroinitializer, align 16
>>
>> into:
>> struct { unsigned int array[10]; } a;
>>
>> However, the reason for this behaviour is not completely clear to me. Can anyone
>> give me further explanation of that is meant by 'array decay' and why it is not
>> possible (or easy) to generate normal C-style arrays?
>
> an IR function might return an array, or have a parameter of array type. Eg it
> might be:
> declare [4 x i8] @foo([8 x i8] %x)
> If you tried to turn that into the C
> char[4] foo(char[8] x);
> then (1) the compiler would reject it, and (2) even if it didn't reject it it
> would probably just return a pointer to the first element of the array rather
> than the array elements themselves, in keeping with C's usual confusion between
> arrays and pointers. Wrapping the array in a struct gets around these problems.
>
Ok, that clarifies things a bit although it seems that the current
implementation of the struct wrappers also doesn't avoid this problem.
declare [4 x i8] @foo([8 x i8] %x)
Currently gets translated into the following:
struct { unsigned char array[4]; } foo(struct { unsigned char
array[8]; } );
Which is not acceptable C as it is not allowed to define structures
inside a function definition. I guess that I will have to make sure
that there is a typedef for these arrays and that the typedef is used in
stead of printing the struct again...
On a second note, what kind of code would I need to feed clang to
actually produce the example IR?
Compiling the following example with clang:
typedef struct {int array[4];} array_t;
array_t f(array_t b) {
return b;
}
results in:
%struct.array_t = type { [4 x i32] }
define void @f(%struct.array_t* noalias sret %agg.result,
%struct.array_t* byval align 4 %b) nounwind {
entry:
%0 = bitcast %struct.array_t* %agg.result to i8*
%1 = bitcast %struct.array_t* %b to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 16, i32 4,
i1 false)
ret void
}
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture,
i32, i32, i1) nounwind
Which does not provide the struct as a return value but moves the return
value to the argument list. Could you show me an example clang input
which does provide the function definition from your example?
Cheers,
Roel
> Ciao, Duncan.
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
More information about the llvm-dev
mailing list