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>
RICHARD STUCKEY
2014-Dec-19 18:55 UTC
[LLVMdev] question about the DIBuilder::createStructType
Hi, Hui Zang, Here's a helpful article: http://xathrya.web.id/blog/2013/12/17/data-structure-alignment-in-c-on-x86-and-x64-machine/ I am not familiar with Chapel, and don't know what a Chapel::Type is. If the APIs you use to manipulate instances of that type support traversal (e.g. given a Chapel::Type that represents a structure, there is an operation that gives you a list of Chapel::Type's that represent the members of that structure) you might be able to get the information from that. In my case, I work with an abstract syntax tree that has been generated by a parser; traversing it gets me to nodes in the tree which represent structure types, and the necessary size/offset/alignment information for the structure members is generated by a layout algorithm. Regards, Richard On 19 December 2014 at 17:55, Hui Zhang <wayne.huizhang at gmail.com> wrote:> 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/afdfd61f/attachment.html>
Hello, Richard Thanks ! My case is similar, there is a AST that I traverse. Could you tell me more about that layout algorithm ? On Fri, Dec 19, 2014 at 1:55 PM, RICHARD STUCKEY <richard.stuckey at virgin.net> wrote: > > Hi, Hui Zang, > > Here's a helpful article: > > > http://xathrya.web.id/blog/2013/12/17/data-structure-alignment-in-c-on-x86-and-x64-machine/ > > > I am not familiar with Chapel, and don't know what a Chapel::Type is. If > the APIs you use to manipulate instances of that type support traversal > (e.g. given a Chapel::Type that represents a structure, there is an > operation that gives you a list of Chapel::Type's that represent the > members of that structure) you might be able to get the information from > that. > > In my case, I work with an abstract syntax tree that has been generated by > a parser; traversing it gets me to nodes in the tree which represent > structure types, and the necessary size/offset/alignment information for > the structure members is generated by a layout algorithm. > > Regards, > > Richard > > > > > > On 19 December 2014 at 17:55, Hui Zhang <wayne.huizhang at gmail.com> wrote: > >> 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 >> > >-- Best regards Hui Zhang -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20141219/bf13acd5/attachment.html>