您的位置:首页 > 其它

Studying note of GCC-3.4.6 source (14)

2010-03-16 12:02 483 查看
2.2.3.1.5.2.2.5. Layout of UNION
Above line 854, rli->t is tree node of the type to be laid out., amd comes at here, field must be a FIELD_DECL. If rli->t is not a RECORD_TYPE, in C++, it must a node for a union. It has different layout policy than class and struct.

778 static void
779 place_union_field (record_layout_info rli, tree field) in stor-layout.c
780 {
781 update_alignment_for_field (rli, field, /*known_align=*/0);
782
783 DECL_FIELD_OFFSET (field) = size_zero_node;
784 DECL_FIELD_BIT_OFFSET (field) = bitsize_zero_node;
785 SET_DECL_OFFSET_ALIGN (field, BIGGEST_ALIGNMENT);
786
787 /* We assume the union's size will be a multiple of a byte so we don't
788 bother with BITPOS. */
789 if (TREE_CODE (rli->t) == UNION_TYPE)
790 rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field));
791 else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE)
792 rli->offset = fold (build (COND_EXPR, sizetype,
793 DECL_QUALIFIER (field),
794 DECL_SIZE_UNIT (field), rli->offset));
795 }

Below update_alignment_for_field updates the variable alignment fields in rli, and return the alignment to give the field. Note that above at line 785, BIGGEST_ALIGNMENT, for x86 is 128.

686 static unsigned int
687 update_alignment_for_field (record_layout_info rli, tree field, in stor-layout.c
688 unsigned int known_align)
689 {
690 /* The alignment required for FIELD. */
691 unsigned int desired_align;
692 /* The type of this field. */
693 tree type = TREE_TYPE (field);
694 /* True if the field was explicitly aligned by the user. */
695 bool user_align;
696 bool is_bitfield;
697
698 /* Lay out the field so we know what alignment it needs. */
699 layout_decl (field, known_align);
2.2.3.1.5.2.2.5.1. Layout FIELD_DECL
We have seen layout_decl is invoked when creating node for declaration of variable, parameter and function return type. The function will set the size, mode and alignment of the node. However in build_decl, no FIELD_DECL will be laid out directly, it is delayed till now. Notice that known_align here is zero which means "as much alignment as you like".

352 void
353 layout_decl (tree decl, unsigned int known_align) in stor-layout.c
354 {
355 tree type = TREE_TYPE (decl);
356 enum tree_code code = TREE_CODE (decl);
357 rtx rtl = NULL_RTX;
358
359 if (code == CONST_DECL)
360 return;
361 else if (code != VAR_DECL && code != PARM_DECL && code != RESULT_DECL
362 && code != TYPE_DECL && code != FIELD_DECL)
363 abort ();
364
365 rtl = DECL_RTL_IF_SET (decl);
366
367 if (type == error_mark_node)
368 type = void_type_node;
369
370 /* Usually the size and mode come from the data type without change,
371 however, the front-end may set the explicit width of the field, so its
372 size may not be the same as the size of its type. This happens with
373 bitfields, of course (an `int' bitfield may be only 2 bits, say), but it
374 also happens with other fields. For example, the C++ front-end creates
375 zero-sized fields corresponding to empty base classes, and depends on
376 layout_type setting DECL_FIELD_BITPOS correctly for the field. Set the
377 size in bytes from the size in bits. If we have already set the mode,
378 don't set it again since we can be called twice for FIELD_DECLs. */
379
380 TREE_UNSIGNED (decl) = TREE_UNSIGNED (type);
381 if (DECL_MODE (decl) == VOIDmode)
382 DECL_MODE (decl) = TYPE_MODE (type);
383
384 if (DECL_SIZE (decl) == 0)
385 {
386 DECL_SIZE (decl) = TYPE_SIZE (type);
387 DECL_SIZE_UNIT (decl) = TYPE_SIZE_UNIT (type);
388 }
389 else if (DECL_SIZE_UNIT (decl) == 0)
390 DECL_SIZE_UNIT (decl)
391 = convert (sizetype, size_binop (CEIL_DIV_EXPR, DECL_SIZE (decl),
392 bitsize_unit_node));

The first part of the function just initializes certain fields of DECL node with associated TYPE node appropriately.
2.2.3.1.5.2.2.5.2. Treatment for Bit Field Decl
Below at line 402, DECL_BIT_FIELD returns nonzero, if the FIELD_DECL is for bit field.

layout_decl (continue)

394 if (code != FIELD_DECL)
395 /* For non-fields, update the alignment from the type. */
396 do_type_align (type, decl);
397 else
398 /* For fields, it's a bit more complicated... */
399 {
400 bool old_user_align = DECL_USER_ALIGN (decl);
401
402 if (DECL_BIT_FIELD (decl))
403 {
404 DECL_BIT_FIELD_TYPE (decl) = type;
405
406 /* A zero-length bit-field affects the alignment of the next
407 field. */
408 if (integer_zerop (DECL_SIZE (decl))
409 && ! DECL_PACKED (decl)
410 && ! (*targetm.ms_bitfield_layout_p) (DECL_FIELD_CONTEXT (decl)))
411 {
412 #ifdef PCC_BITFIELD_TYPE_MATTERS
413 if (PCC_BITFIELD_TYPE_MATTERS)
414 do_type_align (type, decl);
415 else
416 #endif
417 {
418 #ifdef EMPTY_FIELD_BOUNDARY
419 if (EMPTY_FIELD_BOUNDARY > DECL_ALIGN (decl))
420 {
421 DECL_ALIGN (decl) = EMPTY_FIELD_BOUNDARY;
422 DECL_USER_ALIGN (decl) = 0;
423 }
424 #endif
425 }
426 }

Among bit field declarations, there is special case of declaring size 0 (line 408). If fields are not required to be packed at bit boundary, it needs to further check the attribution of the aggregate type. Note that at line 410, DECL_FIELD_CONTEXT retrieves the node of UNION_TYPE or RECORD_TYPE containing the FIELD_DECL. Object targetm is target platform specified, for x86 system, the function pointer ms_bitfield_layout_p points to ix86_ms_bitfield_layout_p.
The explaination given in [2] is shown below:
This target hook returns true if bit-fields in the given RECORD_TYPE are to be laid out following the rules of Microsoft Visual C/C++, namely: (i) a bit-field won't share the same storage unit with the previous bit-field if their underlying types have different sizes, and the bit-field will be aligned to the highest alignment of the underlying types of itself and of the previous bit-field; (ii) a zero-sized bit-field will affect the alignment of the whole enclosing structure, even if it is unnamed; except that (iii) a zero-sized bit-field will be disregarded unless it follows another bit-field of nonzero size. If this hook returns true, other macros that control bit-field layout are ignored.
When a bit-field is inserted into a packed record, the whole size of the underlying type is used by one or more same-size adjacent bit-fields (that is, if its long:3, 32 bits is used in the record, and any additional adjacent long bit-fields are packed into the same chunk of 32 bits. However, if the size changes, a new field of that size is allocated). In an unpacked record, this is the same as using alignment, but not equivalent when packing.
If both MS bit-fields and `__attribute__((packed))' are used, the latter will take precedence. If `__attribute__((packed))' is used on a single field when MS bit-fields are in use, it will take precedence for that field, but the alignment of the rest of the structure may affect its placement.[2]

15481 static bool
15482 ix86_ms_bitfield_layout_p (tree record_type) in i386.c
15483 {
15484 return (TARGET_USE_MS_BITFIELD_LAYOUT &&
15485 !lookup_attribute ("gcc_struct", TYPE_ATTRIBUTES (record_type)))
15486 || lookup_attribute ("ms_struct", TYPE_ATTRIBUTES (record_type));
15487 }

Above, TYPE_ATTRIBUTES fetches a TREE_LIST of IDENTIFIER nodes of the attributes that apply to the type. lookup_attribute iterates the TREE_LIST to find out the IDENTIFIER node of attr_name.

2733 tree
2734 lookup_attribute (const char *attr_name, tree list) in tree.c
2735 {
2736 tree l;
2737
2738 for (l = list; l; l = TREE_CHAIN (l))
2739 {
2740 if (TREE_CODE (TREE_PURPOSE (l)) != IDENTIFIER_NODE)
2741 abort ();
2742 if (is_attribute_p (attr_name, TREE_PURPOSE (l)))
2743 return l;
2744 }
2745
2746 return NULL_TREE;
2747 }

In GCC, the attribute name can be prefixed and postfixed with “__”, it is regarded as same as that without prefix and postfix. is_attribute_p recognizes attributes (attributes are defined by GNU C++, and supported by the compiler. Refer to [6] for the attributes available and the details).

2688 int
2689 is_attribute_p (const char *attr, tree ident) in tree.c
2690 {
2691 int ident_len, attr_len;
2692 const char *p;
2693
2694 if (TREE_CODE (ident) != IDENTIFIER_NODE)
2695 return 0;
2696
2697 if (strcmp (attr, IDENTIFIER_POINTER (ident)) == 0)
2698 return 1;
2699
2700 p = IDENTIFIER_POINTER (ident);
2701 ident_len = strlen (p);
2702 attr_len = strlen (attr);
2703
2704 /* If ATTR is `__text__', IDENT must be `text'; and vice versa. */
2705 if (attr[0] == '_')
2706 {
2707 if (attr[1] != '_'
2708 || attr[attr_len - 2] != '_'
2709 || attr[attr_len - 1] != '_')
2710 abort ();
2711 if (ident_len == attr_len - 4
2712 && strncmp (attr + 2, p, attr_len - 4) == 0)
2713 return 1;
2714 }
2715 else
2716 {
2717 if (ident_len == attr_len + 4
2718 && p[0] == '_' && p[1] == '_'
2719 && p[ident_len - 2] == '_' && p[ident_len - 1] == '_'
2720 && strncmp (attr, p + 2, attr_len) == 0)
2721 return 1;
2722 }
2723
2724 return 0;
2725 }

Back to ix86_ms_bitfield_layout_p, GCC supports two kinds layout of struct, one is adopted by MicroSoft (native), and the other used by GCC. TARGET_USE_MS_BITFIELD_LAYOUT is nonzero if using switch ms-bitfields (Table 7: target_switches for i386 system) which means using MS layout. ix86_ms_bitfield_layout_p returns nonzero if MS layout in used.
If GCC layout is required (not MS layout), PCC_BITFIELD_TYPE_MATTERS, at line 412, is 1 for x86 system. So alignment of bit-field unpacked and of zero size will be set with that of the type. For example, short i: 0, for GCC layout, the alignment will be 16 bits (same as short).
For PCC_BITFIELD_TYPE_MATTERS, the detail can be found in [2] as below.
[ Define this if you wish to imitate the way many other C compilers handle alignment of bit-fields and the structures that contain them.
The behavior is that the type written for a named bit-field (int, short, or other integer type) imposes an alignment for the entire structure, as if the structure really did contain an ordinary field of that type. In addition, the bit-field is placed within the structure so that it would fit within such a field, not crossing a boundary for it.
Thus, on most machines, a named bit-field whose type is written as int would not cross a four-byte boundary, and would force four-byte alignment for the whole structure. (The alignment used may not be four bytes; it is controlled by the other alignment parameters.) [Note: in below, we will see that the compiler will find the fittest integer type as the final type of the bit-filed]
An unnamed bit-field will not affect the alignment of the containing structure.
If the macro is defined, its definition should be a C expression; a nonzero value for the expression enables this behavior.
Note that if this macro is not defined, or its value is zero, some bit-fields may cross more than one alignment boundary. The compiler can support such references if there are `insv', `extv', and `extzv' insns that can directly reference memory.
The other known way of making bit-fields work is to define STRUCTURE_SIZE_BOUNDARY as large as BIGGEST_ALIGNMENT. Then every structure can be accessed with fullwords.
Unless the machine has bit-field instructions or you define STRUCTURE_SIZE_BOUNDARY that way, you must define PCC_BITFIELD_TYPE_MATTERS to have a nonzero value.
If your aim is to make GCC use the same conventions for laying out bit-fields as are used by another compiler, here is how to investigate what the other compiler does. Compile and run this program:
struct foo1 {
char x;
char :0;
char y;
};

struct foo2 {
char x;
int :0;
char y;
};

main () {
printf ("Size of foo1 is %d/n", sizeof (struct foo1));
printf ("Size of foo2 is %d/n", sizeof (struct foo2));
exit (0);
}
If this prints 2 and 5, then the compiler's behavior is what you would get from PCC_BITFIELD_TYPE_MATTERS.]
Following, for bit-field of nonzero size, the function tries to find out if certain integer mode can replace the bit field, for example, int j: 8; may be replaced by char j;. And note that only bit-filed of nonzero size will get handled.

layout_decl (continue)

428 /* See if we can use an ordinary integer mode for a bit-field.
429 Conditions are: a fixed size that is correct for another mode
430 and occupying a complete byte or bytes on proper boundary. */
431 if (TYPE_SIZE (type) != 0
432 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST
433 && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT)
434 {
435 enum machine_mode xmode
436 = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1);
437
438 if (xmode != BLKmode
439 && (known_align == 0
440 || known_align >= GET_MODE_ALIGNMENT (xmode)))
441 {
442 DECL_ALIGN (decl) = MAX (GET_MODE_ALIGNMENT (xmode),
443 DECL_ALIGN (decl));
444 DECL_MODE (decl) = xmode;
445 DECL_BIT_FIELD (decl) = 0;
446 }
447 }
448
449 /* Turn off DECL_BIT_FIELD if we won't need it set. */
450 if (TYPE_MODE (type) == BLKmode && DECL_MODE (decl) == BLKmode
451 && known_align >= TYPE_ALIGN (type)
452 && DECL_ALIGN (decl) >= TYPE_ALIGN (type))
453 DECL_BIT_FIELD (decl) = 0;
454 }

At line 436, we have seen that mode_for_size_tree finds out the integer mode larger but most close to size of the declaration. Then GET_MODE_ALIGNMENT at line 440 just invokes get_mode_alignment.

299 unsigned int
300 get_mode_alignment (enum machine_mode mode) in stor-layout.c
301 {
302 return MIN (BIGGEST_ALIGNMENT, MAX (1, mode_base_align[mode]*BITS_PER_UNIT));
303 }

mode_base_align is the data generated by genmode according to machmode.def and i386-mode.def, it records the alignment of modes. Notice that VOID and BLK modes have alignment of 0.
BIGGEST_ALIGNMENT defines minimum size in bits of the largest boundary to which any and all fundamental data types supported by the hardware might need to be aligned. No data type wants to be aligned rounder than this. For x86 system, Pentium+ prefers DFmode values to be aligned to 64 bit boundary and Pentium Pro XFmode values at 128 bit boundaries.
However, this hides an important fact. It is that if the bit field is not of zero size, neither it can be replaced by certain integer mode, the DECL_ALIGN is unset here (0 as initialized in make_node). For RECORD_TYPE, this fact is crucial for bit field layout.
2.2.3.1.5.2.2.5.3. Treatment for Other Field Decl
Fields other than bit-field then are handled by following code snippet.

layout_decl (continue)

455 else if (DECL_PACKED (decl) && DECL_USER_ALIGN (decl))
456 /* Don't touch DECL_ALIGN. For other packed fields, go ahead and
457 round up; we'll reduce it again below. We want packing to
458 supersede USER_ALIGN inherited from the type, but defer to
459 alignment explicitly specified on the field decl. */;
460 else
461 do_type_align (type, decl);

Take declaration like below as example:
struct sdla_cmd {
char opp_flag __attribute__((packed));
char cmd __attribute__((packed));
short length __attribute__((packed));
char retval __attribute__((packed));
short dlci __attribute__((packed));
char flags __attribute__((packed));
short rxlost_int __attribute__((packed));
long rxlost_app __attribute__((packed));
char reserve[2] __attribute__((packed));
char data[SDLA_MAX_DATA] __attribute__((packed)); /* transfer data buffer */
} __attribute__((aligned (2)));

For above declared fields, DECL_PACKED will be set, and DECL_USER_ALIGN is also set because the struct containing them is declared as aligned at boundary 2. For such case, we leave DECL_ALIGN to be handled below.
For other declarations, do_type_align updates the alignment attributions for declarations according to associated types, which also comes from mode_base_align
2.2.3.1.5.2.2.5.4. Further Adjustment
Next, further adjustment according to the target platform is expected.

layout_decl (continue)

463 /* If the field is of variable size, we can't misalign it since we
464 have no way to make a temporary to align the result. But this
465 isn't an issue if the decl is not addressable. Likewise if it
466 is of unknown size.
467
468 Note that do_type_align may set DECL_USER_ALIGN, so we need to
469 check old_user_align instead. */
470 if (DECL_PACKED (decl)
471 && !old_user_align
472 && (DECL_NONADDRESSABLE_P (decl)
473 || DECL_SIZE_UNIT (decl) == 0
474 || TREE_CODE (DECL_SIZE_UNIT (decl)) == INTEGER_CST))
475 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), BITS_PER_UNIT);
476
477 /* Should this be controlled by DECL_USER_ALIGN, too? */
478 if (maximum_field_alignment != 0)
479 DECL_ALIGN (decl) = MIN (DECL_ALIGN (decl), maximum_field_alignment);
480 if (!DECL_USER_ALIGN (decl))
481 {
482 /* Some targets (i.e. i386, VMS) limit struct field alignment
483 to a lower boundary than alignment of variables unless
484 it was overridden by attribute aligned. */
485 #ifdef BIGGEST_FIELD_ALIGNMENT
486 DECL_ALIGN (decl)
487 = MIN (DECL_ALIGN (decl), (unsigned) BIGGEST_FIELD_ALIGNMENT);
488 #endif
489 #ifdef ADJUST_FIELD_ALIGN
490 DECL_ALIGN (decl) = ADJUST_FIELD_ALIGN (decl, DECL_ALIGN (decl));
491 #endif
492 }
493 }

For condition at line 470 & 471, indicates that if the field is packed but the alignment is not specified by “packed” attribute. And condition from line 472 to 474 indicates that, at the same time, if the field is either nonaddressable (for instance, bit-field), or its DECL_SIZE_UNIT is 0 (ECL_SIZE_UNIT is unset, seems impossible), or its DECL_SIZE_UNIT is integer constant; then it must ensure that its alignment is at least 1 byte (consider empty base class within this packed derived).
Above, at line 478, maximum_field_alignment is set by #pragma pack(N). See that this directive works at last for user.
At line 485 following, BIGGEST_FIELD_ALIGNMENT is used by libobjc. It is not defined here for C++ language.
Then at line 489, for x86 system, ADJUST_FIELD_ALIGN is defined as following. It and BIGGEST_FIELD_ALIGNMENT are exclusive.

843 #define ADJUST_FIELD_ALIGN(FIELD, COMPUTED) / in i386.h
844 x86_field_alignment (FIELD, COMPUTED)
845 #endif

x86_field_alignment does platform special adjustment. When coming here, the declaration of unpacked type has been set after the type, which in turn comes from machmode.def. The file is constructed for all platforms. For certain types, upon certain platform, finer adjustment is expected. For example, double type, machmode.def says the alignment is 8 bytes. But on 32 bits x86 system, unless special specified, only 4 bytes is enough.

15705 int
15706 x86_field_alignment (tree field, int computed) in i386.c
15707 {
15708 enum machine_mode mode;
15709 tree type = TREE_TYPE (field);
15710
15711 if (TARGET_64BIT || TARGET_ALIGN_DOUBLE)
15712 return computed;
15713 mode = TYPE_MODE (TREE_CODE (type) == ARRAY_TYPE
15714 ? get_inner_array_type (type) : type);
15715 if (mode == DFmode || mode == DCmode
15716 || GET_MODE_CLASS (mode) == MODE_INT
15717 || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT)
15718 return MIN (32, computed);
15719 return computed;
15720 }

At line 15711, TARGET_64BIT holds for 64 bits chip. And if TARGET_ALIGN_DOUBLE holds, it indicates target switch “-malign-double” is in used (by default is closed), which makes double, long double and long long be placed at boundary of double, i.e. 8 bytes. Of course, for these cases, no further adjustment is required.
And at line 15714行, get_inner_array_type is used fetch the type of element of the array.

3827 tree
3828 get_inner_array_type (tree array) in tree.c
3829 {
3830 tree type = TREE_TYPE (array);
3831
3832 while (TREE_CODE (type) == ARRAY_TYPE)
3833 type = TREE_TYPE (type);
3834
3835 return type;
3836 }

Rest code of layout_decl handles variable size declaration. For example, GNU C++ supports local variable size array, for instance: int j = 5; char arrC[i]; however this extension is inapplicable to fields of class.
2.2.3.1.5.2.2.5.5. Update record_layout_info
Following, we need update the layout data into record_layout_info. In below, field holds data from layout_decl.

update_alignment_for_field (continue)

700 desired_align = DECL_ALIGN (field);
701 user_align = DECL_USER_ALIGN (field);
702
703 is_bitfield = (type != error_mark_node
704 && DECL_BIT_FIELD_TYPE (field)
705 && ! integer_zerop (TYPE_SIZE (type)));
706
707 /* Record must have at least as much alignment as any field.
708 Otherwise, the alignment of the field within the record is
709 meaningless. */
710 if (is_bitfield && (* targetm.ms_bitfield_layout_p) (rli->t))
711 {
712 /* Here, the alignment of the underlying type of a bitfield can
713 affect the alignment of a record; even a zero-sized field
714 can do this. The alignment should be to the alignment of
715 the type, except that for zero-size bitfields this only
716 applies if there was an immediately prior, nonzero-size
717 bitfield. (That's the way it is, experimentally.) */
718 if (!integer_zerop (DECL_SIZE (field))
719 ? ! DECL_PACKED (field)
720 : (rli->prev_field
721 && DECL_BIT_FIELD_TYPE (rli->prev_field)
722 && ! integer_zerop (DECL_SIZE (rli->prev_field))))
723 {
724 unsigned int type_align = TYPE_ALIGN (type);
725 type_align = MAX (type_align, desired_align);
726 if (maximum_field_alignment != 0)
727 type_align = MIN (type_align, maximum_field_alignment);
728 rli->record_align = MAX (rli->record_align, type_align);
729 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
730 }
731 }
732 #ifdef PCC_BITFIELD_TYPE_MATTERS
733 else if (is_bitfield && PCC_BITFIELD_TYPE_MATTERS)
734 {
735 /* Named bit-fields cause the entire structure to have the
736 alignment implied by their type. */
737 if (DECL_NAME (field) != 0)
738 {
739 unsigned int type_align = TYPE_ALIGN (type);
740
741 #ifdef ADJUST_FIELD_ALIGN
742 if (!TYPE_USER_ALIGN (type))
743 type_align = ADJUST_FIELD_ALIGN (field, type_align);
744 #endif
745
746 if (maximum_field_alignment != 0)
747 type_align = MIN (type_align, maximum_field_alignment);
748 else if (DECL_PACKED (field))
749 type_align = MIN (type_align, BITS_PER_UNIT);
750
751 /* The alignment of the record is increased to the maximum
752 of the current alignment, the alignment indicated on the
753 field (i.e., the alignment specified by an __aligned__
754 attribute), and the alignment indicated by the type of
755 the field. */
756 rli->record_align = MAX (rli->record_align, desired_align);
757 rli->record_align = MAX (rli->record_align, type_align);
758
759 if (warn_packed)
760 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
761 user_align |= TYPE_USER_ALIGN (type);
762 }
763 }
764 #endif
765 else
766 {
767 rli->record_align = MAX (rli->record_align, desired_align);
768 rli->unpacked_align = MAX (rli->unpacked_align, TYPE_ALIGN (type));
769 }
770
771 TYPE_USER_ALIGN (rli->t) |= user_align;
772
773 return desired_align;
774 }

At line 710 above, the condition tells that if it is MS struct layout and it is the bit-field declaration, then to enter block at line 724, it must be packed; or if it has zero size, and previous field is bit field of nonzero size. Notice that for GCC default bit field layout, only naming declaration should have impact upon the structure.
As we expect, the size of the union is determined by it biggest field. In place_union_field, rli->offset is set in this way.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: