Mercurial > hg > CbC > CbC_gcc
diff gcc/stor-layout.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/stor-layout.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/stor-layout.c Tue Mar 22 17:18:12 2011 +0900 @@ -31,7 +31,7 @@ #include "function.h" #include "expr.h" #include "output.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "ggc.h" #include "target.h" #include "langhooks.h" @@ -49,8 +49,6 @@ /* If nonzero, this is an upper limit on alignment of structure fields. The value is measured in bits. */ unsigned int maximum_field_alignment = TARGET_DEFAULT_PACK_STRUCT * BITS_PER_UNIT; -/* ... and its original value in bytes, specified via -fpack-struct=<value>. */ -unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT; /* Nonzero if all REFERENCE_TYPEs are internal and hence should be allocated in the address spaces' address_mode, not pointer_mode. Set only by @@ -172,6 +170,32 @@ /* An array of functions used for self-referential size computation. */ static GTY(()) VEC (tree, gc) *size_functions; +/* Look inside EXPR into simple arithmetic operations involving constants. + Return the outermost non-arithmetic or non-constant node. */ + +static tree +skip_simple_constant_arithmetic (tree expr) +{ + while (true) + { + if (UNARY_CLASS_P (expr)) + expr = TREE_OPERAND (expr, 0); + else if (BINARY_CLASS_P (expr)) + { + if (TREE_CONSTANT (TREE_OPERAND (expr, 1))) + expr = TREE_OPERAND (expr, 0); + else if (TREE_CONSTANT (TREE_OPERAND (expr, 0))) + expr = TREE_OPERAND (expr, 1); + else + break; + } + else + break; + } + + return expr; +} + /* Similar to copy_tree_r but do not copy component references involving PLACEHOLDER_EXPRs. These nodes are spotted in find_placeholder_in_expr and substituted in substitute_in_expr. */ @@ -233,13 +257,14 @@ { static unsigned HOST_WIDE_INT fnno = 0; VEC (tree, heap) *self_refs = NULL; - tree param_type_list = NULL, param_decl_list = NULL, arg_list = NULL; + tree param_type_list = NULL, param_decl_list = NULL; tree t, ref, return_type, fntype, fnname, fndecl; unsigned int i; char buf[128]; + VEC(tree,gc) *args = NULL; /* Do not factor out simple operations. */ - t = skip_simple_arithmetic (size); + t = skip_simple_constant_arithmetic (size); if (TREE_CODE (t) == CALL_EXPR) return size; @@ -255,7 +280,8 @@ /* Build the parameter and argument lists in parallel; also substitute the former for the latter in the expression. */ - for (i = 0; VEC_iterate (tree, self_refs, i, ref); i++) + args = VEC_alloc (tree, gc, VEC_length (tree, self_refs)); + FOR_EACH_VEC_ELT (tree, self_refs, i, ref) { tree subst, param_name, param_type, param_decl; @@ -290,7 +316,7 @@ param_type_list = tree_cons (NULL_TREE, param_type, param_type_list); param_decl_list = chainon (param_decl, param_decl_list); - arg_list = tree_cons (NULL_TREE, ref, arg_list); + VEC_quick_push (tree, args, ref); } VEC_free (tree, heap, self_refs); @@ -301,7 +327,6 @@ /* The 3 lists have been created in reverse order. */ param_type_list = nreverse (param_type_list); param_decl_list = nreverse (param_decl_list); - arg_list = nreverse (arg_list); /* Build the function type. */ return_type = TREE_TYPE (size); @@ -311,7 +336,7 @@ sprintf (buf, "SZ"HOST_WIDE_INT_PRINT_UNSIGNED, fnno++); fnname = get_file_function_name (buf); fndecl = build_decl (input_location, FUNCTION_DECL, fnname, fntype); - for (t = param_decl_list; t; t = TREE_CHAIN (t)) + for (t = param_decl_list; t; t = DECL_CHAIN (t)) DECL_CONTEXT (t) = fndecl; DECL_ARGUMENTS (fndecl) = param_decl_list; DECL_RESULT (fndecl) @@ -342,7 +367,7 @@ VEC_safe_push (tree, gc, size_functions, fndecl); /* Replace the original expression with a call to the size function. */ - return build_function_call_expr (input_location, fndecl, arg_list); + return build_call_expr_loc_vec (input_location, fndecl, args); } /* Take, queue and compile all the size functions. It is essential that @@ -369,10 +394,6 @@ VEC_free (tree, gc, size_functions); } -#ifndef MAX_FIXED_MODE_SIZE -#define MAX_FIXED_MODE_SIZE GET_MODE_BITSIZE (DImode) -#endif - /* Return the machine mode to use for a nonscalar of SIZE bits. The mode must be in class MCLASS, and have exactly that many value bits; it may have padding as well. If LIMIT is nonzero, modes of wider @@ -472,6 +493,50 @@ return mode; } +/* Find a mode that is suitable for representing a vector with + NUNITS elements of mode INNERMODE. Returns BLKmode if there + is no suitable mode. */ + +enum machine_mode +mode_for_vector (enum machine_mode innermode, unsigned nunits) +{ + enum machine_mode mode; + + /* First, look for a supported vector type. */ + if (SCALAR_FLOAT_MODE_P (innermode)) + mode = MIN_MODE_VECTOR_FLOAT; + else if (SCALAR_FRACT_MODE_P (innermode)) + mode = MIN_MODE_VECTOR_FRACT; + else if (SCALAR_UFRACT_MODE_P (innermode)) + mode = MIN_MODE_VECTOR_UFRACT; + else if (SCALAR_ACCUM_MODE_P (innermode)) + mode = MIN_MODE_VECTOR_ACCUM; + else if (SCALAR_UACCUM_MODE_P (innermode)) + mode = MIN_MODE_VECTOR_UACCUM; + else + mode = MIN_MODE_VECTOR_INT; + + /* Do not check vector_mode_supported_p here. We'll do that + later in vector_type_mode. */ + for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode)) + if (GET_MODE_NUNITS (mode) == nunits + && GET_MODE_INNER (mode) == innermode) + break; + + /* For integers, try mapping it to a same-sized scalar mode. */ + if (mode == VOIDmode + && GET_MODE_CLASS (innermode) == MODE_INT) + mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode), + MODE_INT, 0); + + if (mode == VOIDmode + || (GET_MODE_CLASS (mode) == MODE_INT + && !have_regs_of_mode[mode])) + return BLKmode; + + return mode; +} + /* Return the alignment of MODE. This will be bounded by 1 and BIGGEST_ALIGNMENT. */ @@ -593,11 +658,14 @@ } /* See if we can use an ordinary integer mode for a bit-field. - Conditions are: a fixed size that is correct for another mode - and occupying a complete byte or bytes on proper boundary. */ + Conditions are: a fixed size that is correct for another mode, + occupying a complete byte or bytes on proper boundary, + and not volatile or not -fstrict-volatile-bitfields. */ if (TYPE_SIZE (type) != 0 && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT) + && GET_MODE_CLASS (TYPE_MODE (type)) == MODE_INT + && !(TREE_THIS_VOLATILE (decl) + && flag_strict_volatile_bitfields > 0)) { enum machine_mode xmode = mode_for_size_tree (DECL_SIZE (decl), MODE_INT, 1); @@ -677,9 +745,9 @@ int size_as_int = TREE_INT_CST_LOW (size); if (compare_tree_int (size, size_as_int) == 0) - warning (OPT_Wlarger_than_eq, "size of %q+D is %d bytes", decl, size_as_int); + warning (OPT_Wlarger_than_, "size of %q+D is %d bytes", decl, size_as_int); else - warning (OPT_Wlarger_than_eq, "size of %q+D is larger than %wd bytes", + warning (OPT_Wlarger_than_, "size of %q+D is larger than %wd bytes", decl, larger_than_size); } } @@ -747,7 +815,7 @@ rli->offset = size_zero_node; rli->bitpos = bitsize_zero_node; rli->prev_field = 0; - rli->pending_statics = 0; + rli->pending_statics = NULL; rli->packed_maybe_necessary = 0; rli->remaining_in_alignment = 0; @@ -813,7 +881,7 @@ /* Print debugging information about the information in RLI. */ -void +DEBUG_FUNCTION void debug_rli (record_layout_info rli) { print_node_brief (stderr, "type", rli->t, 0); @@ -831,10 +899,10 @@ if (rli->packed_maybe_necessary) fprintf (stderr, "packed may be necessary\n"); - if (rli->pending_statics) + if (!VEC_empty (tree, rli->pending_statics)) { fprintf (stderr, "pending statics:\n"); - debug_tree (rli->pending_statics); + debug_vec_tree (rli->pending_statics); } } @@ -996,8 +1064,7 @@ if (TREE_CODE (rli->t) == UNION_TYPE) rli->offset = size_binop (MAX_EXPR, rli->offset, DECL_SIZE_UNIT (field)); else if (TREE_CODE (rli->t) == QUAL_UNION_TYPE) - rli->offset = fold_build3_loc (input_location, COND_EXPR, sizetype, - DECL_QUALIFIER (field), + rli->offset = fold_build3 (COND_EXPR, sizetype, DECL_QUALIFIER (field), DECL_SIZE_UNIT (field), rli->offset); } @@ -1045,8 +1112,7 @@ it *after* the record is laid out. */ if (TREE_CODE (field) == VAR_DECL) { - rli->pending_statics = tree_cons (NULL_TREE, field, - rli->pending_statics); + VEC_safe_push (tree, gc, rli->pending_statics, field); return; } @@ -1181,11 +1247,11 @@ if (warn_packed_bitfield_compat == 1) inform (input_location, - "Offset of packed bit-field %qD has changed in GCC 4.4", + "offset of packed bit-field %qD has changed in GCC 4.4", field); } else - rli->bitpos = round_up_loc (input_location, rli->bitpos, type_align); + rli->bitpos = round_up (rli->bitpos, type_align); } if (! DECL_PACKED (field)) @@ -1366,7 +1432,7 @@ if (maximum_field_alignment != 0) type_align = MIN (type_align, maximum_field_alignment); - rli->bitpos = round_up_loc (input_location, rli->bitpos, type_align); + rli->bitpos = round_up (rli->bitpos, type_align); /* If we really aligned, don't allow subsequent bitfields to undo that. */ @@ -1432,8 +1498,8 @@ /* If we ended a bitfield before the full length of the type then pad the struct out to the full length of the last type. */ - if ((TREE_CHAIN (field) == NULL - || TREE_CODE (TREE_CHAIN (field)) != FIELD_DECL) + if ((DECL_CHAIN (field) == NULL + || TREE_CODE (DECL_CHAIN (field)) != FIELD_DECL) && DECL_BIT_FIELD_TYPE (field) && !integer_zerop (DECL_SIZE (field))) rli->bitpos = size_binop (PLUS_EXPR, rli->bitpos, @@ -1480,10 +1546,9 @@ = size_binop (PLUS_EXPR, unpadded_size_unit, size_one_node); /* Round the size up to be a multiple of the required alignment. */ - TYPE_SIZE (rli->t) = round_up_loc (input_location, unpadded_size, - TYPE_ALIGN (rli->t)); + TYPE_SIZE (rli->t) = round_up (unpadded_size, TYPE_ALIGN (rli->t)); TYPE_SIZE_UNIT (rli->t) - = round_up_loc (input_location, unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t)); + = round_up (unpadded_size_unit, TYPE_ALIGN_UNIT (rli->t)); if (TREE_CONSTANT (unpadded_size) && simple_cst_equal (unpadded_size, TYPE_SIZE (rli->t)) == 0 @@ -1503,7 +1568,7 @@ rli->unpacked_align = MAX (TYPE_ALIGN (rli->t), rli->unpacked_align); #endif - unpacked_size = round_up_loc (input_location, TYPE_SIZE (rli->t), rli->unpacked_align); + unpacked_size = round_up (TYPE_SIZE (rli->t), rli->unpacked_align); if (simple_cst_equal (unpacked_size, TYPE_SIZE (rli->t))) { if (TYPE_NAME (rli->t)) @@ -1554,7 +1619,7 @@ /* A record which has any BLKmode members must itself be BLKmode; it can't go in a register. Unless the member is BLKmode only because it isn't aligned. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) { if (TREE_CODE (field) != FIELD_DECL) continue; @@ -1655,10 +1720,9 @@ if (TYPE_SIZE (type) != 0) { - TYPE_SIZE (type) = round_up_loc (input_location, - TYPE_SIZE (type), TYPE_ALIGN (type)); - TYPE_SIZE_UNIT (type) = round_up_loc (input_location, TYPE_SIZE_UNIT (type), - TYPE_ALIGN_UNIT (type)); + TYPE_SIZE (type) = round_up (TYPE_SIZE (type), TYPE_ALIGN (type)); + TYPE_SIZE_UNIT (type) + = round_up (TYPE_SIZE_UNIT (type), TYPE_ALIGN_UNIT (type)); } /* Evaluate nonconstant sizes only once, either now or as soon as safe. */ @@ -1722,15 +1786,15 @@ /* Lay out any static members. This is done now because their type may use the record's type. */ - while (rli->pending_statics) - { - layout_decl (TREE_VALUE (rli->pending_statics), 0); - rli->pending_statics = TREE_CHAIN (rli->pending_statics); - } + while (!VEC_empty (tree, rli->pending_statics)) + layout_decl (VEC_pop (tree, rli->pending_statics), 0); /* Clean up. */ if (free_p) - free (rli); + { + VEC_free (tree, gc, rli->pending_statics); + free (rli); + } } @@ -1749,8 +1813,8 @@ for (tail = NULL_TREE; fields; tail = fields, fields = next) { DECL_FIELD_CONTEXT (fields) = type; - next = TREE_CHAIN (fields); - TREE_CHAIN (fields) = tail; + next = DECL_CHAIN (fields); + DECL_CHAIN (fields) = tail; } TYPE_FIELDS (type) = tail; @@ -1851,44 +1915,8 @@ /* Find an appropriate mode for the vector type. */ if (TYPE_MODE (type) == VOIDmode) - { - enum machine_mode innermode = TYPE_MODE (innertype); - enum machine_mode mode; - - /* First, look for a supported vector type. */ - if (SCALAR_FLOAT_MODE_P (innermode)) - mode = MIN_MODE_VECTOR_FLOAT; - else if (SCALAR_FRACT_MODE_P (innermode)) - mode = MIN_MODE_VECTOR_FRACT; - else if (SCALAR_UFRACT_MODE_P (innermode)) - mode = MIN_MODE_VECTOR_UFRACT; - else if (SCALAR_ACCUM_MODE_P (innermode)) - mode = MIN_MODE_VECTOR_ACCUM; - else if (SCALAR_UACCUM_MODE_P (innermode)) - mode = MIN_MODE_VECTOR_UACCUM; - else - mode = MIN_MODE_VECTOR_INT; - - /* Do not check vector_mode_supported_p here. We'll do that - later in vector_type_mode. */ - for (; mode != VOIDmode ; mode = GET_MODE_WIDER_MODE (mode)) - if (GET_MODE_NUNITS (mode) == nunits - && GET_MODE_INNER (mode) == innermode) - break; - - /* For integers, try mapping it to a same-sized scalar mode. */ - if (mode == VOIDmode - && GET_MODE_CLASS (innermode) == MODE_INT) - mode = mode_for_size (nunits * GET_MODE_BITSIZE (innermode), - MODE_INT, 0); - - if (mode == VOIDmode || - (GET_MODE_CLASS (mode) == MODE_INT - && !have_regs_of_mode[mode])) - SET_TYPE_MODE (type, BLKmode); - else - SET_TYPE_MODE (type, mode); - } + SET_TYPE_MODE (type, + mode_for_vector (TYPE_MODE (innertype), nunits)); TYPE_SATURATING (type) = TYPE_SATURATING (TREE_TYPE (type)); TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type)); @@ -1974,10 +2002,9 @@ length = size_binop (PLUS_EXPR, size_one_node, fold_convert (sizetype, - fold_build2_loc (input_location, - MINUS_EXPR, - TREE_TYPE (lb), - ub, lb))); + fold_build2 (MINUS_EXPR, + TREE_TYPE (lb), + ub, lb))); TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size, fold_convert (bitsizetype, @@ -2001,11 +2028,6 @@ #else TYPE_ALIGN (type) = MAX (TYPE_ALIGN (element), BITS_PER_UNIT); #endif - if (!TYPE_SIZE (element)) - /* We don't know the size of the underlying element type, so - our alignment calculations will be wrong, forcing us to - fall back on structural equality. */ - SET_TYPE_STRUCTURAL_EQUALITY (type); TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (element); SET_TYPE_MODE (type, BLKmode); if (TYPE_SIZE (type) != 0 @@ -2064,7 +2086,7 @@ TYPE_FIELDS (type) = nreverse (TYPE_FIELDS (type)); /* Place all the fields. */ - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) + for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) place_field (rli, field); if (TREE_CODE (type) == QUAL_UNION_TYPE)