[LLVMdev] PROPOSAL: IR representation of detailed struct assignment information (new version)

Duncan Sands baldrick at free.fr
Fri Sep 7 04:01:19 PDT 2012

Hi Dan, another approach is to exploit the fact that intrinsics can have
metadata parameters.  We could then have a new "structmemcpy" intrinsic
which would take a variable number of parameters (yes, a variable number
of parameters is problematic, see below), basically a list describing
each field, something like this:

   void llvm.structmemcpy (
     i8* dest,
     i8* src,
     i64 offset0, i64 size0, i32 align0, i1 volatile0, metadata tbaa0, ; field0
     i64 offset1, i64 size1, i32 align1, i1 volatile1, metadata tbaa1, ; field1
     i64 offsetN, i64 sizeN, i32 alignN, i1 volatileN, metadata tbaaN  ; fieldN

The first "field" to be copied would be at bytes [offset0, offset0+size0).
The second field at [offset1, offset1+size1), though it might be better
to have offsets be from the end of the previous field, in which case it
would be: [offset0+size0+ offset1, offset0+size0+ offset1+size1).

The memory in [0, offset0) would thus be a gap ("padding"), and likewise
between the end of each field and the start of the next.  There is a small
hassle expressing a gap at the end of the struct, but this can be overcome
by the trick of placing a fake zero size field after the last byte in
the struct.

What I like about this is that it puts the vital information directly
into the intrinsic in a structured way, rather than having it be "on
the side" in metadata.

The big problem of course is that we aren't really set up to have
intrinsics for which different instances can have a different number
of parameters.  This can be handled to some extent by using multiple
declarations, sticking the number of parameters onto the name like
is done for intrinsics which can have different types, like:
  @llvm.struct.memcpy.p0i8.p0i8.i64.8 <- this one takes 8 parameters,
or maybe 8 field descriptions, or something like that.
But there may be many issues here.

Ciao, Duncan.

> Persuant to feedback,
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-August/052927.html
> here is a new proposal for detailed struct assignment information.
> Here's the example showing the basic problem:
> struct bar {
>   char x;
>   float y;
>   double z;
> };
> void copy_bar(struct bar *a, struct bar *b) {
>   *a = *b;
> }
> The solution I now propose here is to have front-ends describe the copy
> using metadata. For example:
>   call void @llvm.memcpy.p0i8.p0i8.i64(i8* %0, i8* %1, i64 16, i32 8, i1 false), !tbaa.struct !4
>   […]
>   !0 = metadata !{metadata !"Simple C/C++ TBAA"}
>   !1 = metadata !{metadata !"omnipotent char", metadata !0}
>   !2 = metadata !{metadata !"float", metadata !1}
>   !3 = metadata !{metadata !"double", metadata !1}
>   !4 = metadata !{metadata !5, i64 3, metadata !6, metadata !7}
>   !5 = metadata !{i64 1, metadata !1}
>   !6 = metadata !{i64 4, metadata !2}
>   !7 = metadata !{i64 8, metadata !3}
> Metadata nodes !0 through !3 are regular TBAA nodes as are already in use.
> Metadata node !4 here is a top-level description of the memcpy. It holds a
> list of virtual members. An integer represents a padding field of that
> size. A metadata tuple represents an actual data field. The tuple's members
> are an integer size and a TBAA tag for the field.
> Comments and questions are welcome.
> Dan
> _______________________________________________
> 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