diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2000-02-27 21:39:40 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2000-02-27 16:39:40 -0500 |
commit | fed3cef0dbbd17e3d7b8860f42cd8490f0325340 (patch) | |
tree | da73c398c9c03435ecc0d3821031b7c0fe89911d /gcc/stor-layout.c | |
parent | 43931371e2321b6c50c3e0b9095d46606ec48ce1 (diff) | |
download | gcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.zip gcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.tar.gz gcc-fed3cef0dbbd17e3d7b8860f42cd8490f0325340.tar.bz2 |
builtins.c (c_strlen): Use size_diffop and return ssizetype value.
* builtins.c (c_strlen): Use size_diffop and return ssizetype value.
(expand_builtin_strcpy): Pass correct type to size_binop.
(expand_builtin_strcmp): Likewise.
Clean up conditional structure.
* c-decl.c (init_decl_processing): Don't call set_sizetype twice.
(complete_array_type): Don't use size_binop for MAXINDEX.
* c-typeck.c (c_sizeof): Use size_one_node and TYPE_SIZE_UNIT.
(c_sizeof_nowarn, c_size_in_bytes): Likewise.
(c_alignof): Use size_one_node.
(build_unary_op): Pass arg of proper type to size_binop.
(really_start_incremental_init, push_init_level): Use sizetype for
constructor{,_bit,_unfilled}_index.
(pop_init_label, output_init_element): Likewise.
(output_pending_init_elements, process_init_element): Likewise.
* calls.c (compute_argument_block_size): Field VAR is ssizetype.
* expr.c (store_expr): Use size_int.
(store_constructor): Use proper types for size_binop args.
(get_inner_reference, expand_expr, case ARRAY_REF): Likewise.
(expand_expr_unaligned): Likewise.
(string_contant): Return object of sizetype.
* expr.h (SUB_PARM_SIZE): Call size_diffop and pass proper types.
(ARGS_SIZE_RTX): Call ARGS_SIZE_TREE.
(ARGS_SIZE_TREE): Pass proper types to size_binop.
* fold-const.c (int_const_binop): Refine when size_int is called.
(fold_convert): Likewise.
(size_int_wide): Rework to take KIND as arg, only take low order
bits, handle new sizetype_tab datatype, and chain entries in
size_table.
(size_int_type_wide): New function.
(size_binop): Validate types of arguments.
(ssize_binop): Deleted.
(size_diffop): New function.
(extract_muldiv): Only fold division into multiplication for sizetypes.
* function.c (assign_parms): Use size_diffop and make sure
VAR field is of ssizetype; also pass proper type to size_binop.
(locate_and_pad_parm, pad_to_arg_alignment): Likewise.
(round_down): Deleted from here.
* store-layout.c (sizetype_tab): Now an array.
(sizetype_set, early_root_list): New variables.
(variable_size): Use size_one_node.
(round_up): Pass proper type to size_binop.
(round_down): Moved to here and corrected as above.
(layout_record): Pass proper arg types to size_binop.
(layout_type): Likewise.
If sizetype_set is zero, record the type just laid out.
(make_unsigned_type): Don't call set_sizetype;
(make_signed_type): Likewise; also, call fixup_signed_type.
(initialize_sizetypes): New function.
(set_sizetype): Make copy of types, set TYPE_IS_SIZETYPE, and
set name of bitsizetype to "bit_size_type".
Fix up type of sizes of all types made before call.
* tm.texi (ROUND_TYPE_SIZE_UNIT): New macro.
* tree.c (fix_sizetype): Deleted.
(build_common_tree_nodes): Call initialize_sizetypes.
(build_common_tree_nodes_2): Don't call fix_sizetype.
* tree.h (TYPE_IS_SIZETYPE): New macro.
(initialize_sizetype): New declaration.
(enum size_type_kind): New type.
(struct sizetype_tab): Deleted.
(sizetype_tab): Now array; adjust sizetype macros.
(size_diffop, size_int_type_wide): New functions.
(size_int_wide): Change number of args and type; access macros changed.
(ssize_int, sbitsize_int): New macros.
* config/i960/i960.h (ROUND_TYPE_SIZE): Use size_int.
(ROUND_TYPE_SIZE_UNIT): New macro.
* ch/actions.c (chill_convert_for_assignment): Don't use size_binop
for things that aren't sizes.
(expand_varying_length_assignment): Likewise.
* ch/convert.c (digest_array_tuple, convert): Likewise.
* ch/typeck.c (build_chill_slice, smash_dummy_type): Likewise.
(build_chill_slice_with_range): Likewise.
(build_chill_slice_with_length): Likewise.
(build_array_from_set): Adjust types for size_binop.
* ch/expr.c (build_concat_expr, build_chill_repetition_op): Likewise.
(build_chill_sizeof): Use TYPE_SIZE_UNIT.
* ch/tree.c (build_string_type): Pass proper type to size_binop.
* cp/class.c (dfs_build_vtable_offset_vtbl_entries): Don't use
size_binop on things that are not sizes; ssize_binop deleted.
Call size_diffop when appropriate.
(dfs_build_vcall_offset_vtbl_entries): Likewise.
(build_primary_vtable, build_secondary_vtable): Likewise.
(dfs_set_offset_for_unshared_vbases, dfs_modify_vtables): Likewise.
Variable I is HOST_WIDE_INT.
(get_vfield_offset): Pass proper types to size_binop.
(size_extra_vtbl_entries, layout_virtual_bases): Likewise.
(finish_struct_1): Likewise.
(skip_rtti_stuff): Arg N is now pointer to signed.
(layout_class_type): Use size_zero_node.
* cp/cp-tree.h (skip_rtti_stuff): Arg N is pointer to signed.
* cp/cvt.c (cp_convert_to_pointer): Pass proper types to size_binop.
* cp/decl.c (complete_arry_type): Pass proper types to size_binop.
(xref_basetypes): BINFO_OFFSET is sizetype.
* cp/error.c (dump_expr): Don't use size_binop non-sizes.
* cp/expr.c (cplus_expand_constant): Pass proper types to size_binop.
* cp/init.c (construct_virtual_bases): Fix type error.
(build_vec_delete_1): Pass proper type to size_binop and don't
fold result.
* cp/lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype.
* cp/rtti.c (get_base_offset): Pass proper type to size_binop.
* cp/search.c (dfs_find_vbases): Fix type error.
(expand_upcast_fixups): Arg to skip_rtti_stuff is pointer to signed.
(dfs_get_vbase_types): BINFO_OFFSET is sizetype.
* cp/tree.c (debug_binfo): Variable N is signed.
Use HOST_WIDE_INT_PRINT_DEC.
* cp/typeck.c (comptypes): sizetype is same as equivalent integer type.
(c_sizeof, c_sizeof_nowarn, expr_sizeof): Use TYPE_SIZE_UNIT,
size_one_node and size_zero_node.
(c_alignof): Use size_one_node.
(build_component_addr): Pass proper types to size_binop.
(expand_ptrmemfunc_cst): Don't use size_binop on non-sizes.
* f/com.c (ffecom_arrayref_): Convert args to size_binop to proper
type.
(ffecom_tree_canonize_ptr_): Don't use size_binop for non-sizes.
(ffecom_tree_canonize_ref_): Likewise.
(type_for_mode): Handle TImode.
* f/ste.c (ffeste_io_dofio_, ffeste_io_douio_): Use TYPE_SIZE_UNIT.
(ffeste_io_ciclist_): Likewise.
* java/expr.c (build_java_ret): Pass proper type to size_binop.
From-SVN: r32225
Diffstat (limited to 'gcc/stor-layout.c')
-rw-r--r-- | gcc/stor-layout.c | 175 |
1 files changed, 113 insertions, 62 deletions
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 3783a2f..b86a422 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -31,10 +31,16 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "ggc.h" +/* Set to one when set_sizetype has been called. */ +static int sizetype_set; + +/* List of types created before set_sizetype has been called. We do not + make this a GGC root since we want these nodes to be reclaimed. */ +static tree early_type_list; + /* Data type for the expressions representing sizes of data types. It is the first integer type laid out. */ - -struct sizetype_tab sizetype_tab; +tree sizetype_tab[(int) TYPE_KIND_LAST]; /* If nonzero, this is an upper limit on alignment of structure fields. The value is measured in bits. */ @@ -114,7 +120,7 @@ variable_size (size) else error ("variable-size type declared outside of any function"); - return size_int (1); + return size_one_node; } if (immediate_size_expand) @@ -214,16 +220,29 @@ int_mode_for_mode (mode) return mode; } -/* Return the value of VALUE, rounded up to a multiple of DIVISOR. */ +/* Return the value of VALUE, rounded up to a multiple of DIVISOR. + This can only be applied to objects of a sizetype. */ tree round_up (value, divisor) tree value; int divisor; { - return size_binop (MULT_EXPR, - size_binop (CEIL_DIV_EXPR, value, size_int (divisor)), - size_int (divisor)); + tree arg = size_int_type (divisor, TREE_TYPE (value)); + + return size_binop (MULT_EXPR, size_binop (CEIL_DIV_EXPR, value, arg), arg); +} + +/* Likewise, but round down. */ + +tree +round_down (value, divisor) + tree value; + int divisor; +{ + tree arg = size_int_type (divisor, TREE_TYPE (value)); + + return size_binop (MULT_EXPR, size_binop (FLOOR_DIV_EXPR, value, arg), arg); } /* Set the size, mode and alignment of a ..._DECL node. @@ -632,8 +651,8 @@ layout_record (rec) else { if (const_size) - var_size - = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size)); + var_size = size_binop (PLUS_EXPR, var_size, bitsize_int (const_size)); + TYPE_SIZE (rec) = var_size; } @@ -652,7 +671,7 @@ layout_record (rec) TYPE_BINFO_SIZE_UNIT (rec) = convert (sizetype, size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rec), - size_int (BITS_PER_UNIT))); + bitsize_int (BITS_PER_UNIT))); } { @@ -964,8 +983,10 @@ layout_type (type) /* The initial subtraction should happen in the original type so that (possible) negative values are handled appropriately. */ length = size_binop (PLUS_EXPR, size_one_node, - fold (build (MINUS_EXPR, TREE_TYPE (lb), - ub, lb))); + convert (sizetype, + fold (build (MINUS_EXPR, + TREE_TYPE (lb), + ub, lb)))); /* If neither bound is a constant and sizetype is signed, make sure the size is never negative. We should really do this @@ -990,7 +1011,8 @@ layout_type (type) element_size = integer_one_node; } - TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size, length); + TYPE_SIZE (type) = size_binop (MULT_EXPR, element_size, + convert (bitsizetype, length)); /* If we know the size of the element, calculate the total size directly, rather than do some division thing below. @@ -1000,8 +1022,7 @@ layout_type (type) Note that we can't do this in the case where the size of the elements is one bit since TYPE_SIZE_UNIT cannot be set correctly in that case. */ - if (TYPE_SIZE_UNIT (element) != 0 - && element_size != integer_one_node) + if (TYPE_SIZE_UNIT (element) != 0 && ! integer_onep (element_size)) TYPE_SIZE_UNIT (type) = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (element), length); } @@ -1254,7 +1275,7 @@ layout_type (type) TYPE_SIZE_UNIT (type) = convert (sizetype, size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT))); + bitsize_int (BITS_PER_UNIT))); /* Once again evaluate only once, either now or as soon as safe. */ if (TYPE_SIZE_UNIT (type) != 0 @@ -1286,6 +1307,14 @@ layout_type (type) pop_obstacks (); resume_momentary (old); + + /* If this type is created before sizetype has been permanently set, + record it so set_sizetype can fix it up. */ + if (! sizetype_set) + { + TREE_CHAIN (type) = early_type_list; + early_type_list = type; + } } /* Create and return a type for signed integers of PRECISION bits. */ @@ -1298,35 +1327,7 @@ make_signed_type (precision) TYPE_PRECISION (type) = precision; - /* Create the extreme values based on the number of bits. */ - - TYPE_MIN_VALUE (type) - = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0 - ? 0 : (HOST_WIDE_INT) (-1) << (precision - 1)), - (((HOST_WIDE_INT) (-1) - << (precision - HOST_BITS_PER_WIDE_INT - 1 > 0 - ? precision - HOST_BITS_PER_WIDE_INT - 1 - : 0)))); - TYPE_MAX_VALUE (type) - = build_int_2 ((precision - HOST_BITS_PER_WIDE_INT > 0 - ? -1 : ((HOST_WIDE_INT) 1 << (precision - 1)) - 1), - (precision - HOST_BITS_PER_WIDE_INT - 1 > 0 - ? (((HOST_WIDE_INT) 1 - << (precision - HOST_BITS_PER_WIDE_INT - 1))) - 1 - : 0)); - - /* Give this type's extreme values this type as their type. */ - - TREE_TYPE (TYPE_MIN_VALUE (type)) = type; - TREE_TYPE (TYPE_MAX_VALUE (type)) = type; - - /* The first type made with this or `make_unsigned_type' - is the type for size values. */ - if (sizetype == 0) - set_sizetype (type); - - /* Lay out the type: set its alignment, size, etc. */ - layout_type (type); + fixup_signed_type (type); return type; } @@ -1340,18 +1341,40 @@ make_unsigned_type (precision) TYPE_PRECISION (type) = precision; - /* The first type made with this or `make_signed_type' - is the type for size values. */ - - if (sizetype == 0) - { - TREE_UNSIGNED (type) = 1; - set_sizetype (type); - } - fixup_unsigned_type (type); return type; } + +/* Initialize sizetype and bitsizetype to a reasonable and temporary + value to enable integer types to be created. */ + +void +initialize_sizetypes () +{ + tree t = make_node (INTEGER_TYPE); + + /* Set this so we do something reasonable for the build_int_2 calls + below. */ + integer_type_node = t; + + TYPE_MODE (t) = SImode; + TYPE_ALIGN (t) = GET_MODE_ALIGNMENT (SImode); + TYPE_SIZE (t) = build_int_2 (GET_MODE_BITSIZE (SImode), 0); + TYPE_SIZE_UNIT (t) = build_int_2 (GET_MODE_SIZE (SImode), 0); + TREE_UNSIGNED (t) = 1; + TYPE_PRECISION (t) = GET_MODE_BITSIZE (SImode); + TYPE_MIN_VALUE (t) = build_int_2 (0, 0); + + /* 1000 avoids problems with possible overflow and is certainly + larger than any size value we'd want to be storing. */ + TYPE_MAX_VALUE (t) = build_int_2 (1000, 0); + + /* These two must be different nodes because of the caching done in + size_int_wide. */ + sizetype = t; + bitsizetype = copy_node (t); + integer_type_node = 0; +} /* Set sizetype to TYPE, and initialize *sizetype accordingly. Also update the type of any standard type's sizes made so far. */ @@ -1367,8 +1390,14 @@ set_sizetype (type) precision. */ int precision = MIN (oprecision + BITS_PER_UNIT_LOG + 1, 2 * HOST_BITS_PER_WIDE_INT); + unsigned int i; + tree t, next; + + if (sizetype_set) + abort (); - sizetype = type; + /* Make copies of nodes since we'll be setting TYPE_IS_SIZETYPE. */ + sizetype = copy_node (type); bitsizetype = make_node (INTEGER_TYPE); TYPE_NAME (bitsizetype) = TYPE_NAME (type); TYPE_PRECISION (bitsizetype) = precision; @@ -1384,22 +1413,43 @@ set_sizetype (type) { usizetype = sizetype; ubitsizetype = bitsizetype; - ssizetype = make_signed_type (oprecision); - sbitsizetype = make_signed_type (precision); + ssizetype = copy_node (make_signed_type (oprecision)); + sbitsizetype = copy_node (make_signed_type (precision)); } else { ssizetype = sizetype; sbitsizetype = bitsizetype; - usizetype = make_unsigned_type (oprecision); - ubitsizetype = make_unsigned_type (precision); + usizetype = copy_node (make_unsigned_type (oprecision)); + ubitsizetype = copy_node (make_unsigned_type (precision)); } - TYPE_NAME (bitsizetype) = TYPE_NAME (sizetype); + + TYPE_NAME (bitsizetype) = get_identifier ("bit_size_type"); + + for (i = 0; i < sizeof sizetype_tab / sizeof sizetype_tab[0]; i++) + TYPE_IS_SIZETYPE (sizetype_tab[i]) = 1; ggc_add_tree_root ((tree *) &sizetype_tab, sizeof sizetype_tab / sizeof (tree)); -} + /* Go down each of the types we already made and set the proper type + for the sizes in them. */ + for (t = early_type_list; t != 0; t = next) + { + next = TREE_CHAIN (t); + TREE_CHAIN (t) = 0; + + if (TREE_CODE (t) != INTEGER_TYPE) + abort (); + + TREE_TYPE (TYPE_SIZE (t)) = bitsizetype; + TREE_TYPE (TYPE_SIZE_UNIT (t)) = sizetype; + } + + early_type_list = 0; + sizetype_set = 1; +} + /* Set the extreme values of TYPE based on its precision in bits, then lay it out. Used when make_signed_type won't do because the tree code is not INTEGER_TYPE. @@ -1531,7 +1581,8 @@ get_best_mode (bitsize, bitpos, align, largest_mode, volatilep) /* Return the alignment of MODE. This will be bounded by 1 and BIGGEST_ALIGNMENT. */ -unsigned get_mode_alignment (mode) +unsigned int +get_mode_alignment (mode) enum machine_mode mode; { unsigned alignment = GET_MODE_UNIT_SIZE (mode); |