[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