Hello, I'm using DIBuilder to create debugging information, I'm not clear about two things: [1] Could you help explain the meaning and the difference between"alignment" and "offset" of a type ? e.g class Actor{ int age; const char* name; } Besides, I found the denotation of createMemberType and createStructType both have "Member Alignment" and "Member Size" fields, are they the same thing ? If they are, then for the "Actor", which member is it referring to ? [2] In createMemberType, the last arg “Ty” is parent type, does it mean "Actor" in the example ? thanks -- Best regards Hui Zhang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141218/0da54ef0/attachment.html>
RICHARD STUCKEY
2014-Dec-19 15:04 UTC
[LLVMdev] question about the DIBuilder::createStructType
Hi, Hui Zang, It helps to remember that at runtime a variable of a structure type has to be allocated store, and to think about how that variable is laid out in store. You must use createMemberType to create a DIType for *each* field (aka member) in the structure; you then store those DIType's as the elements of a DIArray which you pass as the 'Elements' parameter to createStructType. When creating a structure member, you have to specify this information : SizeinBits - the actual size of the member OffsetInBits - the number of bits between the start of the member in the layout of the structure and the start of the structure AlignInBits - the address boundary (if any) to which the element has to be aligned. Remember that on some processor architectures (e.g. Sun), basic data items (e.g shorts, ints, floats) have to be allocated to store at addresses which are multiples of their size; e.g. shorts must be allocated at addresses which are multiples of two bytes, ints allocated at addresses which are multiples of 4 bytes, etc. If this rule is not followed, e.g. a 4-byte integer is allocated at an odd address, then any attempt to load or store that variable will result in a bus error. On architectures which do not have this constraint, it is sufficient for objects to be byte-aligned. So in your example, you might have age : size 32, offset 0, align 32 name: size 32, offset 32, align 32 or age : size 32, offset 0, align 8 name: size 32, offset 32, align 8 depending on your target processor. The sizeInBits and AliginInBits parameters to createStructType describe the whole structure (e.g. Actor: sizeInBits:64 aligInBits: 32). Note that the size of the structure may be more than the sum of the size of the individual members - there may be gaps in the structure layout, depending on the sizes and alignments of its members. The alignment of a structure is generally the largest alignment of any of its members; the structure type must be laid out so that if a structure variable starts at an address which is a multiple of the structure's alignment then each of its members starts at an address which is a multiple of its alignment. E.g. if you have a structure struct S { int I1; short S; int I2; } V; and an int is 4 bytes and a short 2 bytes, then either you must leave a 2-byte gap between S and I2 in the layout or you must re-order the fields (if the language you are implementing allows that) so that S comes after I1 and I2 in the layout; otherwise either I1 or I2 will be misaligned in store regardless of the address at which V is allocated. The 'Ty' parameter to createMemberType specifies the type of the member. In your example, you will need to create DIType objects for the types 'int' and 'const char*'; use the first one in the call to createMemberType for "age" and the second one in the call for "name". As a general principle, when creating the DIType object for a given type, you must work from the bottom up (or recursively, from the top down) through the hierarchy of types which you are compiling : you must create the DIype for a type *before* you create the DItype for any other type which uses that type (e.g. as a member of a structure, or an element of an array, or the target type of a pointer type, etc.). Note that you can have cycles of type dependencies in your hierarchy; e.g. a struct S could have a field P which is of type S* - so before you try to create the DIType for a given type you must check whether you have already created it, otherwise you could recurse endlessly around the cycles! (until your stack blows up...) Hope this helps, Richard On 18 December 2014 at 20:44, Hui Zhang <wayne.huizhang at gmail.com> wrote:> Hello, > > I'm using DIBuilder to create debugging information, I'm not clear about > two things: > > [1] Could you help explain the meaning and the difference > between"alignment" and "offset" of a type ? > > e.g class Actor{ > int age; > const char* name; > } > > Besides, I found the denotation of createMemberType and createStructType > both have "Member Alignment" and "Member Size" fields, are they the same > thing ? If they are, then for the "Actor", which member is it referring to ? > > [2] In createMemberType, the last arg “Ty” is parent type, does it mean > "Actor" in the example ? > > thanks > > -- > Best regards > > > Hui Zhang > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141219/0453e843/attachment.html>
Hello, Richard Thanks a lot ! On Fri, Dec 19, 2014 at 10:04 AM, RICHARD STUCKEY < richard.stuckey at virgin.net> wrote:> > Hi, Hui Zang, > > It helps to remember that at runtime a variable of a structure type has to > be allocated store, and to think about how that variable is laid out in > store. > > You must use createMemberType to create a DIType for *each* field (aka > member) in the structure; you then store those DIType's as the elements of > a DIArray which you pass as the 'Elements' parameter to createStructType. > > When creating a structure member, you have to specify this information : > > SizeinBits - the actual size of the member > OffsetInBits - the number of bits between the start of the > member in the layout of the structure and the start of the structure > AlignInBits - the address boundary (if any) to which the > element has to be aligned. > > Remember that on some processor architectures (e.g. Sun), > > basic data items (e.g shorts, ints, floats) have to be allocated to store > at addresses which are multiples of their size; e.g. shorts must be > allocated at addresses > which are multiples of two bytes, ints allocated at addresses which are > multiples of 4 bytes, etc. If this rule is not followed, e.g. a 4-byte > integer is allocated at an odd address, then any attempt to load or store > that variable will result in a bus error. On architectures which do not > have this constraint, it is sufficient for objects to be byte-aligned. > > So in your example, you might have > > age : size 32, offset 0, align 32 > name: size 32, offset 32, align 32 > > or > > age : size 32, offset 0, align 8 > name: size 32, offset 32, align 8 > > depending on your target processor. > > > The sizeInBits and AliginInBits parameters to createStructType describe > the whole structure (e.g. Actor: sizeInBits:64 aligInBits: 32). Note > that the size of the structure may be more than the sum of the size of the > individual members - there may be gaps in the structure layout, depending > on the sizes and alignments of its members. The alignment of a structure > is generally the largest alignment of any of its members; the structure > type must be laid out so that if a structure variable starts at an address > which is a multiple of the structure's alignment then each of its members > starts at an address which is a multiple of its alignment. > > E.g. if you have a structure > > struct S > { > int I1; > short S; > int I2; > } V; > > and an int is 4 bytes and a short 2 bytes, then either you must leave a > 2-byte gap between S and I2 in the layout or you must re-order the fields > (if the language you are implementing allows that) so that S comes after I1 > and I2 in the layout; otherwise either I1 or I2 will be misaligned in store > regardless of the address at which V is allocated. > Is this just the example for Sun processors that basic data items (e.g shorts, ints, floats) have to be allocated to store at addresses which are multiples of their size ? what if intel processor like your example 2(align 8)?> > The 'Ty' parameter to createMemberType specifies the type of the member. > In your example, you will need to create DIType objects for the types 'int' > and 'const char*'; use the first one in the call to createMemberType for > "age" and the second one in the call for "name". > > As a general principle, when creating the DIType object for a given type, > you must work from the bottom up (or recursively, from the top down) > through the hierarchy of types which you are compiling : you must create > the DIype for a type *before* you create the DItype for any other type > which uses that type (e.g. as a member of a structure, or an element of an > array, or the target type of a pointer type, etc.). Note that you can > have cycles of type dependencies in your hierarchy; e.g. a struct S could > have a field P which is of type S* - so before you try to create the DIType > for a given type you must check whether you have already created it, > otherwise you could recurse endlessly around the cycles! (until your > stack blows up...) >I have a situation that in my language(Chapel), I don't have the llvm::Type, only Chapel::Type, so what do you suggest that how I'm gonna get the Member aligh and Member size ? Thanks !> > Hope this helps, > > Richard > > > > > > On 18 December 2014 at 20:44, Hui Zhang <wayne.huizhang at gmail.com> wrote: > >> Hello, >> >> I'm using DIBuilder to create debugging information, I'm not clear about >> two things: >> >> [1] Could you help explain the meaning and the difference >> between"alignment" and "offset" of a type ? >> >> e.g class Actor{ >> int age; >> const char* name; >> } >> >> Besides, I found the denotation of createMemberType and createStructType >> both have "Member Alignment" and "Member Size" fields, are they the same >> thing ? If they are, then for the "Actor", which member is it referring to ? >> >> [2] In createMemberType, the last arg “Ty” is parent type, does it mean >> "Actor" in the example ? >> >> thanks >> >> -- >> Best regards >> >> >> Hui Zhang >> >> _______________________________________________ >> LLVM Developers mailing list >> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu >> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >> >> >-- Best regards Hui Zhang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141219/79e1c2a8/attachment.html>