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 | |
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')
38 files changed, 885 insertions, 638 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 60a8b91..0059eb0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,71 @@ +Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * 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. + 2000-02-27 Zack Weinberg <zack@wolery.cumb.org> * c-lex.c (putback_buffer): Make 'buffer' an unsigned char *. diff --git a/gcc/builtins.c b/gcc/builtins.c index 3473740..e32d0bd 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -164,6 +164,8 @@ get_pointer_alignment (exp, max_align) way, because it could contain a zero byte in the middle. TREE_STRING_LENGTH is the size of the character array, not the string. + The value returned is of type `ssizetype'. + Unfortunately, string_constant can't access the values of const char arrays with initializers, so neither can we do so here. */ @@ -178,25 +180,29 @@ c_strlen (src) src = string_constant (src, &offset_node); if (src == 0) return 0; + max = TREE_STRING_LENGTH (src); ptr = TREE_STRING_POINTER (src); + if (offset_node && TREE_CODE (offset_node) != INTEGER_CST) { /* If the string has an internal zero byte (e.g., "foo\0bar"), we can't compute the offset to the following null if we don't know where to start searching for it. */ int i; + for (i = 0; i < max; i++) if (ptr[i] == 0) return 0; + /* We don't know the starting offset, but we do know that the string has no internal zero bytes. We can assume that the offset falls within the bounds of the string; otherwise, the programmer deserves what he gets. Subtract the offset from the length of the string, - and return that. */ - /* This would perhaps not be valid if we were dealing with named - arrays in addition to literal string constants. */ - return size_binop (MINUS_EXPR, size_int (max), offset_node); + and return that. This would perhaps not be valid if we were dealing + with named arrays in addition to literal string constants. */ + + return size_diffop (size_int (max), offset_node); } /* We have a known offset into the string. Start searching there for @@ -210,6 +216,7 @@ c_strlen (src) return 0; offset = TREE_INT_CST_LOW (offset_node); } + /* If the offset is known to be out of bounds, warn, and call strlen at runtime. */ if (offset < 0 || offset > max) @@ -217,18 +224,20 @@ c_strlen (src) warning ("offset outside bounds of constant string"); return 0; } + /* Use strlen to search for the first zero byte. Since any strings constructed with build_string will have nulls appended, we win even if we get handed something like (char[4])"abcd". Since OFFSET is our starting index into the string, no further calculation is needed. */ - return size_int (strlen (ptr + offset)); + return ssize_int (strlen (ptr + offset)); } /* Given TEM, a pointer to a stack frame, follow the dynamic chain COUNT times to get the address of either a higher stack frame, or a return address located within it (depending on FNDECL_CODE). */ + rtx expand_builtin_return_addr (fndecl_code, count, tem) enum built_in_function fndecl_code; @@ -1437,6 +1446,7 @@ expand_builtin_memcpy (arglist) /* Expand expression EXP, which is a call to the strcpy builtin. Return 0 if we failed the caller should emit a normal call. */ + static rtx expand_builtin_strcpy (exp) tree exp; @@ -1448,7 +1458,8 @@ expand_builtin_strcpy (exp) /* Arg could be non-pointer if user redeclared this fcn wrong. */ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE || TREE_CHAIN (arglist) == 0 - || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE) + || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) + != POINTER_TYPE)) return 0; else { @@ -1457,11 +1468,12 @@ expand_builtin_strcpy (exp) if (len == 0) return 0; - len = size_binop (PLUS_EXPR, len, integer_one_node); - + len = size_binop (PLUS_EXPR, len, ssize_int (1)); chainon (arglist, build_tree_list (NULL_TREE, len)); } + result = expand_builtin_memcpy (arglist); + if (! result) TREE_CHAIN (TREE_CHAIN (arglist)) = 0; return result; @@ -1469,6 +1481,7 @@ expand_builtin_strcpy (exp) /* Expand expression EXP, which is a call to the memset builtin. Return 0 if we failed the caller should emit a normal call. */ + static rtx expand_builtin_memset (exp) tree exp; @@ -1610,6 +1623,7 @@ expand_builtin_memcmp (exp, arglist, target) /* Expand expression EXP, which is a call to the strcmp builtin. Return 0 if we failed the caller should emit a normal call, otherwise try to get the result in TARGET, if convenient. */ + static rtx expand_builtin_strcmp (exp, target) tree exp; @@ -1625,21 +1639,24 @@ expand_builtin_strcmp (exp, target) /* Arg could be non-pointer if user redeclared this fcn wrong. */ || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE || TREE_CHAIN (arglist) == 0 - || TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) != POINTER_TYPE) + || (TREE_CODE (TREE_TYPE (TREE_VALUE (TREE_CHAIN (arglist)))) + != POINTER_TYPE)) return 0; - else if (!HAVE_cmpstrsi) + + else if (! HAVE_cmpstrsi) return 0; { tree arg1 = TREE_VALUE (arglist); tree arg2 = TREE_VALUE (TREE_CHAIN (arglist)); - tree len, len2; + tree len = c_strlen (arg1); + tree len2 = c_strlen (arg2); rtx result; - len = c_strlen (arg1); + if (len) - len = size_binop (PLUS_EXPR, integer_one_node, len); - len2 = c_strlen (arg2); + len = size_binop (PLUS_EXPR, ssize_int (1), len); + if (len2) - len2 = size_binop (PLUS_EXPR, integer_one_node, len2); + len2 = size_binop (PLUS_EXPR, ssize_int (1), len2); /* If we don't have a constant length for the first, use the length of the second, if we know it. We don't require a constant for @@ -1651,6 +1668,7 @@ expand_builtin_strcmp (exp, target) two fixed strings, or if the code was machine-generated. We should add some code to the `memcmp' handler below to deal with such situations, someday. */ + if (!len || TREE_CODE (len) != INTEGER_CST) { if (len2) @@ -1658,16 +1676,15 @@ expand_builtin_strcmp (exp, target) else if (len == 0) return 0; } - else if (len2 && TREE_CODE (len2) == INTEGER_CST) - { - if (tree_int_cst_lt (len2, len)) - len = len2; - } + else if (len2 && TREE_CODE (len2) == INTEGER_CST + && tree_int_cst_lt (len2, len)) + len = len2; chainon (arglist, build_tree_list (NULL_TREE, len)); result = expand_builtin_memcmp (exp, arglist, target); if (! result) TREE_CHAIN (TREE_CHAIN (arglist)) = 0; + return result; } } @@ -1675,6 +1692,7 @@ expand_builtin_strcmp (exp, target) /* Expand a call to __builtin_saveregs, generating the result in TARGET, if that's convenient. */ + rtx expand_builtin_saveregs () { diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 87fcef8..8308fc7 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -2887,6 +2887,7 @@ init_decl_processing () tree ptr_ftype_void, ptr_ftype_ptr; int wchar_type_size; tree array_domain_type; + tree t; current_function_decl = NULL; named_labels = NULL; @@ -2939,14 +2940,17 @@ init_decl_processing () Traditionally, use a signed type. Note that stddef.h uses `unsigned long', and this must agree, even if long and int are the same size. */ - set_sizetype - (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)))); - if (flag_traditional && TREE_UNSIGNED (sizetype)) - set_sizetype (signed_type (sizetype)); + t = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE))); + if (flag_traditional && TREE_UNSIGNED (t)) + t = signed_type (t); + + set_sizetype (t); /* Create the widest literal types. */ - widest_integer_literal_type_node = make_signed_type (HOST_BITS_PER_WIDE_INT * 2); - widest_unsigned_literal_type_node = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2); + widest_integer_literal_type_node + = make_signed_type (HOST_BITS_PER_WIDE_INT * 2); + widest_unsigned_literal_type_node + = make_unsigned_type (HOST_BITS_PER_WIDE_INT * 2); pushdecl (build_decl (TYPE_DECL, NULL_TREE, widest_integer_literal_type_node)); pushdecl (build_decl (TYPE_DECL, NULL_TREE, @@ -3661,13 +3665,14 @@ complete_array_type (type, initial_value, do_default) else if (TREE_CODE (initial_value) == CONSTRUCTOR) { tree elts = CONSTRUCTOR_ELTS (initial_value); - maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node); + maxindex = build_int_2 (-1, -1); for (; elts; elts = TREE_CHAIN (elts)) { if (TREE_PURPOSE (elts)) maxindex = TREE_PURPOSE (elts); else - maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node); + maxindex = fold (build (PLUS_EXPR, integer_type_node, + maxindex, integer_one_node)); } maxindex = copy_node (maxindex); } diff --git a/gcc/c-typeck.c b/gcc/c-typeck.c index 6ce22c5..01446f2 100644 --- a/gcc/c-typeck.c +++ b/gcc/c-typeck.c @@ -691,36 +691,33 @@ c_sizeof (type) tree type; { enum tree_code code = TREE_CODE (type); - tree t; if (code == FUNCTION_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("sizeof applied to a function type"); - return size_int (1); + return size_one_node; } if (code == VOID_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("sizeof applied to a void type"); - return size_int (1); + return size_one_node; } + if (code == ERROR_MARK) - return size_int (1); + return size_one_node; + if (TYPE_SIZE (type) == 0) { error ("sizeof applied to an incomplete type"); - return size_int (0); + return size_zero_node; } /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - /* size_binop does not put the constant in range, so do it now. */ - if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) - TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; - return t; + return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } tree @@ -728,21 +725,17 @@ c_sizeof_nowarn (type) tree type; { enum tree_code code = TREE_CODE (type); - tree t; - if (code == FUNCTION_TYPE - || code == VOID_TYPE - || code == ERROR_MARK) - return size_int (1); + if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) + return size_one_node; + if (TYPE_SIZE (type) == 0) - return size_int (0); + return size_zero_node; /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - force_fit_type (t, 0); - return t; + return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } /* Compute the size to increment a pointer by. */ @@ -752,26 +745,20 @@ c_size_in_bytes (type) tree type; { enum tree_code code = TREE_CODE (type); - tree t; - if (code == FUNCTION_TYPE) - return size_int (1); - if (code == VOID_TYPE) - return size_int (1); - if (code == ERROR_MARK) - return size_int (1); + if (code == FUNCTION_TYPE || code == VOID_TYPE || code == ERROR_MARK) + return size_one_node; + if (TYPE_SIZE (type) == 0) { error ("arithmetic on pointer to an incomplete type"); - return size_int (1); + return size_one_node; } /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (BITS_PER_UNIT)); - t = convert (sizetype, t); - force_fit_type (t, 0); - return t; + return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } /* Implement the __alignof keyword: Return the minimum required @@ -787,7 +774,7 @@ c_alignof (type) return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); if (code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); + return size_one_node; return size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); } @@ -808,7 +795,7 @@ c_alignof_expr (expr) && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) { error ("`__alignof' applied to a bit-field"); - return size_int (1); + return size_one_node; } else if (TREE_CODE (expr) == COMPONENT_REF && TREE_CODE (TREE_OPERAND (expr, 1)) == FIELD_DECL) @@ -3032,8 +3019,9 @@ build_unary_op (code, xarg, noconvert) { tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); int flag = TREE_CONSTANT (addr); + addr = fold (build (PLUS_EXPR, argtype, addr, convert (argtype, offset))); TREE_CONSTANT (addr) = flag; @@ -5038,8 +5026,7 @@ really_start_incremental_init (type) && DECL_NAME (constructor_fields) == 0) constructor_fields = TREE_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; - constructor_bit_index = copy_node (integer_zero_node); - TREE_TYPE (constructor_bit_index) = sbitsizetype; + constructor_bit_index = copy_node (size_zero_node); } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { @@ -5049,10 +5036,13 @@ really_start_incremental_init (type) constructor_max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); constructor_index - = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); + = copy_node (convert (bitsizetype, + TYPE_MIN_VALUE + (TYPE_DOMAIN (constructor_type)))); } else - constructor_index = copy_node (integer_zero_node); + constructor_index = copy_node (bitsize_int (0)); + constructor_unfilled_index = copy_node (constructor_index); } else @@ -5210,8 +5200,7 @@ push_init_level (implicit) && DECL_NAME (constructor_fields) == 0) constructor_fields = TREE_CHAIN (constructor_fields); constructor_unfilled_fields = constructor_fields; - constructor_bit_index = copy_node (integer_zero_node); - TREE_TYPE (constructor_bit_index) = sbitsizetype; + constructor_bit_index = copy_node (size_zero_node); } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { @@ -5221,10 +5210,13 @@ push_init_level (implicit) constructor_max_index = TYPE_MAX_VALUE (TYPE_DOMAIN (constructor_type)); constructor_index - = copy_node (TYPE_MIN_VALUE (TYPE_DOMAIN (constructor_type))); + = copy_node (convert (bitsizetype, + TYPE_MIN_VALUE + (TYPE_DOMAIN (constructor_type)))); } else - constructor_index = copy_node (integer_zero_node); + constructor_index = bitsize_int (0); + constructor_unfilled_index = copy_node (constructor_index); } else @@ -5401,14 +5393,14 @@ pop_init_level (implicit) else { tree filled; + if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) - { - /* Find the offset of the end of that field. */ - filled = size_binop (CEIL_DIV_EXPR, - constructor_bit_index, - size_int (BITS_PER_UNIT)); - } + /* Find the offset of the end of that field. */ + filled = size_binop (CEIL_DIV_EXPR, + constructor_bit_index, + size_int (BITS_PER_UNIT)); + else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { /* If initializing an array of unknown size, @@ -5417,11 +5409,9 @@ pop_init_level (implicit) && TYPE_DOMAIN (constructor_type) == 0) { tree maxindex - = size_binop (MINUS_EXPR, - constructor_unfilled_index, - integer_one_node); + = copy_node (size_diffop (constructor_unfilled_index, + bitsize_int (1))); - maxindex = copy_node (maxindex); TYPE_DOMAIN (constructor_type) = build_index_type (maxindex); TREE_TYPE (maxindex) = TYPE_DOMAIN (constructor_type); @@ -5437,8 +5427,11 @@ pop_init_level (implicit) size = int_size_in_bytes (constructor_type); } - filled = size_binop (MULT_EXPR, constructor_unfilled_index, - size_in_bytes (TREE_TYPE (constructor_type))); + filled + = size_binop (MULT_EXPR, constructor_unfilled_index, + convert (bitsizetype, + TYPE_SIZE_UNIT + (TREE_TYPE (constructor_type)))); } else filled = 0; @@ -5961,7 +5954,8 @@ output_init_element (value, type, field, pending) if (TREE_CODE (constructor_type) == ARRAY_TYPE) { tree tem = size_binop (PLUS_EXPR, constructor_unfilled_index, - integer_one_node); + bitsize_int (1)); + TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (tem); TREE_INT_CST_HIGH (constructor_unfilled_index) @@ -6117,12 +6111,13 @@ output_pending_init_elements (all) if (constructor_incremental) { tree filled; - tree nextpos_tree = size_int (0); + tree nextpos_tree = bitsize_int (0); if (TREE_CODE (constructor_type) == RECORD_TYPE || TREE_CODE (constructor_type) == UNION_TYPE) { tree tail; + /* Find the last field written out, if any. */ for (tail = TYPE_FIELDS (constructor_type); tail; tail = TREE_CHAIN (tail)) @@ -6135,13 +6130,13 @@ output_pending_init_elements (all) size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (tail), DECL_SIZE (tail)), - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); else - filled = size_int (0); + filled = bitsize_int (0); nextpos_tree = size_binop (CEIL_DIV_EXPR, DECL_FIELD_BITPOS (next), - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); TREE_INT_CST_HIGH (constructor_bit_index) = TREE_INT_CST_HIGH (DECL_FIELD_BITPOS (next)); @@ -6151,11 +6146,15 @@ output_pending_init_elements (all) } else if (TREE_CODE (constructor_type) == ARRAY_TYPE) { - filled = size_binop (MULT_EXPR, constructor_unfilled_index, - size_in_bytes (TREE_TYPE (constructor_type))); + filled + = size_binop (MULT_EXPR, constructor_unfilled_index, + convert (bitsizetype, + TYPE_SIZE_UNIT + (TREE_TYPE (constructor_type)))); nextpos_tree = size_binop (MULT_EXPR, next, - size_in_bytes (TREE_TYPE (constructor_type))); + convert (bitsizetype, TYPE_SIZE_UNIT + (TREE_TYPE (constructor_type)))); TREE_INT_CST_LOW (constructor_unfilled_index) = TREE_INT_CST_LOW (next); TREE_INT_CST_HIGH (constructor_unfilled_index) @@ -6306,6 +6305,7 @@ process_init_element (value) tree temp = size_binop (PLUS_EXPR, DECL_FIELD_BITPOS (constructor_fields), DECL_SIZE (constructor_fields)); + TREE_INT_CST_LOW (constructor_bit_index) = TREE_INT_CST_LOW (temp); TREE_INT_CST_HIGH (constructor_bit_index) @@ -6444,8 +6444,7 @@ process_init_element (value) RESTORE_SPELLING_DEPTH (constructor_depth); } - tem = size_binop (PLUS_EXPR, constructor_index, - integer_one_node); + tem = size_binop (PLUS_EXPR, constructor_index, bitsize_int (1)); TREE_INT_CST_LOW (constructor_index) = TREE_INT_CST_LOW (tem); TREE_INT_CST_HIGH (constructor_index) = TREE_INT_CST_HIGH (tem); diff --git a/gcc/calls.c b/gcc/calls.c index 40744e8..07f4c48 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -1158,9 +1158,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args, args[i].slot_offset.constant = -args_size->constant; if (args_size->var) - { - SUB_PARM_SIZE (args[i].slot_offset, args_size->var); - } + SUB_PARM_SIZE (args[i].slot_offset, args_size->var); #endif /* Increment ARGS_SO_FAR, which has info about which arg-registers @@ -1205,14 +1203,14 @@ compute_argument_block_size (reg_parm_stack_space, args_size, { args_size->var = size_binop (MAX_EXPR, args_size->var, - size_int (reg_parm_stack_space)); + ssize_int (reg_parm_stack_space)); #ifndef OUTGOING_REG_PARM_STACK_SPACE /* The area corresponding to register parameters is not to count in the size of the block we need. So make the adjustment. */ args_size->var = size_binop (MINUS_EXPR, args_size->var, - size_int (reg_parm_stack_space)); + ssize_int (reg_parm_stack_space)); #endif } } diff --git a/gcc/ch/ChangeLog b/gcc/ch/ChangeLog index e8501c9..35df1ba 100644 --- a/gcc/ch/ChangeLog +++ b/gcc/ch/ChangeLog @@ -1,3 +1,17 @@ +Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * actions.c (chill_convert_for_assignment): Don't use size_binop + for things that aren't sizes. + (expand_varying_length_assignment): Likewise. + * convert.c (digest_array_tuple, convert): Likewise. + * 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. + * expr.c (build_concat_expr, build_chill_repetition_op): Likewise. + (build_chill_sizeof): Use TYPE_SIZE_UNIT. + * tree.c (build_string_type): Pass proper type to size_binop. + Sat Feb 19 18:43:13 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> * decl.c (layout_enum): Set DECL_SIZE_UNIT. diff --git a/gcc/ch/actions.c b/gcc/ch/actions.c index b07a532..c97c1b6 100644 --- a/gcc/ch/actions.c +++ b/gcc/ch/actions.c @@ -1,5 +1,6 @@ /* Implement actions for CHILL. - Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 + Free Software Foundation, Inc. Authors: Per Bothner, Bill Cox, Michael Tiemann, Michael North This file is part of GNU CC. @@ -466,13 +467,12 @@ check_non_null (expr) return expr; } -/* - * There are four conditions to generate a runtime check: - * 1) assigning a longer INT to a shorter (signs irrelevant) - * 2) assigning a signed to an unsigned - * 3) assigning an unsigned to a signed of the same size. - * 4) TYPE is a discrete subrange - */ +/* There are four conditions to generate a runtime check: + 1) assigning a longer INT to a shorter (signs irrelevant) + 2) assigning a signed to an unsigned + 3) assigning an unsigned to a signed of the same size. + 4) TYPE is a discrete subrange */ + tree chill_convert_for_assignment (type, expr, place) tree type, expr; @@ -558,10 +558,10 @@ chill_convert_for_assignment (type, expr, place) } result = convert (type, expr); - /* If the type is a array of PACK bits and the expression is an array constructor, - then build a CONSTRUCTOR for a bitstring. Bitstrings are zero based, so - decrement the value of each CONSTRUCTOR element by the amount of the lower - bound of the array. */ + /* If the type is a array of PACK bits and the expression is an array + constructor, then build a CONSTRUCTOR for a bitstring. Bitstrings are + zero based, so decrement the value of each CONSTRUCTOR element by the + amount of the lower bound of the array. */ if (TREE_CODE (type) == ARRAY_TYPE && TYPE_PACKED (type) && TREE_CODE (result) == CONSTRUCTOR) { @@ -569,6 +569,7 @@ chill_convert_for_assignment (type, expr, place) tree new_list = NULL_TREE; long index; tree element; + for (element = TREE_OPERAND (result, 1); element != NULL_TREE; element = TREE_CHAIN (element)) @@ -579,18 +580,21 @@ chill_convert_for_assignment (type, expr, place) switch (TREE_CODE (purpose)) { case INTEGER_CST: - new_list = tree_cons (NULL_TREE, - size_binop (MINUS_EXPR, purpose, domain_min), - new_list); + new_list + = tree_cons (NULL_TREE, + fold (build (MINUS_EXPR, TREE_TYPE (purpose), + purpose, domain_min)), + new_list); break; case RANGE_EXPR: for (index = TREE_INT_CST_LOW (TREE_OPERAND (purpose, 0)); index <= TREE_INT_CST_LOW (TREE_OPERAND (purpose, 1)); index++) new_list = tree_cons (NULL_TREE, - size_binop (MINUS_EXPR, - build_int_2 (index, 0), - domain_min), + fold (build (MINUS_EXPR, + integer_type_node, + build_int_2 (index, 0), + domain_min)), new_list); break; default: @@ -1697,11 +1701,12 @@ chill_expand_assignment (lhs, modifycode, rhs) tree from_pos = save_expr (TREE_OPERAND (lhs, 0)); tree set = TREE_OPERAND (lhs, 1); tree domain = TYPE_DOMAIN (TREE_TYPE (set)); - tree set_length = size_binop (PLUS_EXPR, - size_binop (MINUS_EXPR, - TYPE_MAX_VALUE (domain), - TYPE_MIN_VALUE (domain)), - integer_one_node); + tree set_length + = fold (build (PLUS_EXPR, integer_type_node, + fold (build (MINUS_EXPR, integer_type_node, + TYPE_MAX_VALUE (domain), + TYPE_MIN_VALUE (domain))), + integer_one_node)); tree filename = force_addr_of (get_chill_filename()); if (TREE_CODE (TREE_TYPE (lhs)) != BOOLEAN_TYPE) @@ -1750,19 +1755,22 @@ chill_expand_assignment (lhs, modifycode, rhs) tree numbits = TREE_OPERAND (lhs, 1); tree from_pos = save_expr (TREE_OPERAND (lhs, 2)); tree domain = TYPE_DOMAIN (TREE_TYPE (set)); - tree set_length = size_binop (PLUS_EXPR, - size_binop (MINUS_EXPR, - TYPE_MAX_VALUE (domain), - TYPE_MIN_VALUE (domain)), - integer_one_node); + tree set_length + = fold (build (PLUS_EXPR, integer_type_node, + fold (build (MINUS_EXPR, integer_type_node, + TYPE_MAX_VALUE (domain), + TYPE_MIN_VALUE (domain))), + integer_one_node)); tree filename = force_addr_of (get_chill_filename()); tree to_pos; + switch (TREE_CODE (TREE_TYPE (rhs))) { case SET_TYPE: - to_pos = size_binop (MINUS_EXPR, - size_binop (PLUS_EXPR, from_pos, numbits), - integer_one_node); + to_pos = fold (build (MINUS_EXPR, integer_type_node, + fold (build (PLUS_EXPR, integer_type_node, + from_pos, numbits)), + integer_one_node)); break; case BOOLEAN_TYPE: to_pos = from_pos; @@ -1812,7 +1820,7 @@ expand_varying_length_assignment (lhs, rhs) min_domain_val = TYPE_MIN_VALUE (TYPE_DOMAIN (base_array)); lhs = build_component_ref (lhs, var_length_id); - rhs = size_binop (MINUS_EXPR, rhs, min_domain_val); + rhs = fold (build (MINUS_EXPR, TREE_TYPE (rhs), rhs, min_domain_val)); expand_expr_stmt (build_chill_modify_expr (lhs, rhs)); } diff --git a/gcc/ch/convert.c b/gcc/ch/convert.c index 80405da..dcea057 100644 --- a/gcc/ch/convert.c +++ b/gcc/ch/convert.c @@ -1,5 +1,6 @@ /* Language-level data type conversion for GNU CHILL. - Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -858,14 +859,12 @@ digest_array_tuple (type, init, allow_missing_elements) } /* Calculate the last element of the gap. */ if (*ptr) - { - /* Actually end up with correct type. */ - last = size_binop (MINUS_EXPR, - CONSTRUCTOR_ELT_LO (*ptr), - integer_one_node); - } + last = fold (build (MINUS_EXPR, integer_type_node, + CONSTRUCTOR_ELT_LO (*ptr), + integer_one_node)); else last = domain_max; + if (TREE_CODE (last) == INTEGER_CST && tree_int_cst_lt (last, first)) ; /* Empty "gap" - no missing elements. */ else if (default_value) @@ -1058,16 +1057,17 @@ convert (type, expr) { /* Note that array_type_nelts returns 1 less than the size. */ nentries = array_type_nelts (TREE_TYPE (e)); - needed_padding = size_binop (MINUS_EXPR, - array_type_nelts (target_array_type), - nentries); + needed_padding = fold (build (MINUS_EXPR, integer_type_node, + array_type_nelts (target_array_type), + nentries)); if (TREE_CODE (needed_padding) != INTEGER_CST) { padding_max_size = size_in_bytes (TREE_TYPE (e)); if (TREE_CODE (padding_max_size) != INTEGER_CST) padding_max_size = TYPE_ARRAY_MAX_SIZE (TREE_TYPE (e)); } - nentries = size_binop (PLUS_EXPR, nentries, integer_one_node); + nentries = fold (build (PLUS_EXPR, integer_type_node, + nentries, integer_one_node)); } else if (TREE_CODE (e) == CONSTRUCTOR) { diff --git a/gcc/ch/expr.c b/gcc/ch/expr.c index 13e5bd8..b4bdf35 100644 --- a/gcc/ch/expr.c +++ b/gcc/ch/expr.c @@ -1,6 +1,7 @@ /* Convert language-specific tree expression to rtl instructions, for GNU CHILL compiler. - Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -2264,8 +2265,9 @@ build_chill_sizeof (type) return error_mark_node; } - temp = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); + temp = size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); if (signame != NULL_TREE) { /* we have a signal definition. This signal may have no @@ -3344,9 +3346,9 @@ build_concat_expr (op0, op1) if (TREE_CODE (type0) == SET_TYPE) { - result_size = size_binop (PLUS_EXPR, - discrete_count (TYPE_DOMAIN (type0)), - discrete_count (TYPE_DOMAIN (type1))); + result_size = fold (build (PLUS_EXPR, integer_type_node, + discrete_count (TYPE_DOMAIN (type0)), + discrete_count (TYPE_DOMAIN (type1)))); result_class.mode = build_bitstring_type (result_size); } else @@ -4250,15 +4252,16 @@ build_chill_repetition_op (count_op, string) for (temp = vallist; temp; temp = TREE_CHAIN (temp)) { tree new_value - = fold (size_binop (PLUS_EXPR, origin, TREE_VALUE (temp))); + = fold (build (PLUS_EXPR, TREE_TYPE (origin), + TREE_VALUE (temp))); tree new_purpose = NULL_TREE; + if (! TREE_CONSTANT (TREE_VALUE (temp))) tree_const = 0; if (TREE_PURPOSE (temp)) { - new_purpose = fold (size_binop (PLUS_EXPR, - origin, - TREE_PURPOSE (temp))); + new_purpose = fold (build (PLUS_EXPR, TREE_TYPE (origin), + origin, TREE_PURPOSE (temp))); if (! TREE_CONSTANT (TREE_PURPOSE (temp))) tree_const = 0; } diff --git a/gcc/ch/tree.c b/gcc/ch/tree.c index 88fd5ff..53485db 100644 --- a/gcc/ch/tree.c +++ b/gcc/ch/tree.c @@ -1,5 +1,6 @@ /* Language-dependent node constructors for parse phase of GNU compiler. - Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -65,9 +66,9 @@ build_string_type (elt_type, length) /* Subtract 1 from length to get max index value. Note we cannot use size_binop for pass 1 expressions. */ if (TREE_CODE (length) == INTEGER_CST || pass != 1) - length = size_binop (MINUS_EXPR, length, integer_one_node); + length = size_binop (MINUS_EXPR, length, size_one_node); else - length = build (MINUS_EXPR, sizetype, length, integer_one_node); + length = build (MINUS_EXPR, sizetype, length, size_one_node); t = make_node (elt_type == boolean_type_node ? SET_TYPE : ARRAY_TYPE); TREE_TYPE (t) = elt_type; @@ -289,7 +290,9 @@ discrete_count (t) tree t; { tree hi = convert (sizetype, TYPE_MAX_VALUE (t)); + if (TYPE_MIN_VALUE (t)) hi = size_binop (MINUS_EXPR, hi, convert (sizetype, TYPE_MIN_VALUE (t))); + return size_binop (PLUS_EXPR, hi, integer_one_node); } diff --git a/gcc/ch/typeck.c b/gcc/ch/typeck.c index 5082b78..8c74896 100644 --- a/gcc/ch/typeck.c +++ b/gcc/ch/typeck.c @@ -1,5 +1,6 @@ /* Build expressions with type checking for CHILL compiler. - Copyright (C) 1992, 93, 94, 98, 99, 2000 Free Software Foundation, Inc. + Copyright (C) 1992, 1993, 1994, 1998, 1999, 2000 + Free Software Foundation, Inc. This file is part of GNU CC. @@ -215,17 +216,17 @@ build_chill_slice (array, min_value, length) The static allocation info is passed by using the parent array's limits to compute a temp_size, which is passed in the lang_specific - field of the slice_type. - */ + field of the slice_type. */ if (TREE_CODE (array_type) == ARRAY_TYPE) { tree domain_type = TYPE_DOMAIN (array_type); tree domain_min = TYPE_MIN_VALUE (domain_type); - tree domain_max = fold (build (PLUS_EXPR, domain_type, - domain_min, - size_binop (MINUS_EXPR, - length, integer_one_node))); + tree domain_max + = fold (build (PLUS_EXPR, domain_type, + domain_min, + fold (build (MINUS_EXPR, integer_type_node, + length, integer_one_node)))); tree index_type = build_chill_range_type (TYPE_DOMAIN (array_type), domain_min, domain_max); @@ -408,13 +409,15 @@ build_chill_slice_with_range (array, min_value, max_value) && tree_int_cst_lt (max_value, min_value)) return build_empty_string (TREE_TYPE (TREE_TYPE (array))); - return build_chill_slice (array, min_value, - save_expr (size_binop (PLUS_EXPR, - size_binop (MINUS_EXPR, max_value, min_value), - integer_one_node))); + return + build_chill_slice + (array, min_value, + save_expr (fold (build (PLUS_EXPR, integer_type_node, + fold (build (MINUS_EXPR, integer_type_node, + max_value, min_value)), + integer_one_node)))); } - tree build_chill_slice_with_length (array, min_value, length) tree array, min_value, length; @@ -450,9 +453,10 @@ build_chill_slice_with_length (array, min_value, length) length = integer_one_node; } - max_index = size_binop (MINUS_EXPR, - size_binop (PLUS_EXPR, length, min_value), - integer_one_node); + max_index = fold (build (MINUS_EXPR, integer_type_node, + fold (build (PLUS_EXPR, integer_type_node, + length, min_value)), + integer_one_node)); max_index = convert_to_class (chill_expr_class (min_value), max_index); min_value = valid_array_index_p (array, min_value, @@ -1208,22 +1212,22 @@ build_chill_cast (type, expr) return expr; } -/* - * given a set_type, build an integer array from it that C will grok. - */ +/* Given a set_type, build an integer array from it that C will grok. */ + tree build_array_from_set (type) tree type; { tree bytespint, bit_array_size, int_array_count; - if (type == NULL_TREE || type == error_mark_node || TREE_CODE (type) != SET_TYPE) + if (type == NULL_TREE || type == error_mark_node + || TREE_CODE (type) != SET_TYPE) return error_mark_node; - bytespint = build_int_2 (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR, 0); + /* ??? Should this really be *HOST*?? */ + bytespint = size_int (HOST_BITS_PER_INT / HOST_BITS_PER_CHAR); bit_array_size = size_in_bytes (type); - int_array_count = fold (size_binop (TRUNC_DIV_EXPR, bit_array_size, - bytespint)); + int_array_count = size_binop (TRUNC_DIV_EXPR, bit_array_size, bytespint); if (integer_zerop (int_array_count)) int_array_count = size_one_node; type = build_array_type (integer_type_node, @@ -3371,9 +3375,9 @@ smash_dummy_type (type) { tree oldindex = TYPE_DOMAIN (origin); new_max = check_range (new_max, new_max, NULL_TREE, - size_binop (PLUS_EXPR, - TYPE_MAX_VALUE (oldindex), - integer_one_node)); + fold (build (PLUS_EXPR, integer_type_node, + TYPE_MAX_VALUE (oldindex), + integer_one_node))); origin = build_string_type (TREE_TYPE (origin), new_max); } else if (TREE_CODE (origin) == ARRAY_TYPE) diff --git a/gcc/config/i960/i960.h b/gcc/config/i960/i960.h index d436a41..8ccd758 100644 --- a/gcc/config/i960/i960.h +++ b/gcc/config/i960/i960.h @@ -493,7 +493,11 @@ extern int target_flags; #define ROUND_TYPE_SIZE(TYPE, COMPUTED, SPECIFIED) \ ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode) \ - ? build_int_2 (128, 0) : round_up (COMPUTED, SPECIFIED)) + ? bitsize_int (128) : round_up (COMPUTED, SPECIFIED)) +#define ROUND_TYPE_SIZE_UNIT(TYPE, COMPUTED, SPECIFIED) \ + ((TREE_CODE (TYPE) == REAL_TYPE && TYPE_MODE (TYPE) == XFmode) \ + ? bitsize_int (16) : round_up (COMPUTED, SPECIFIED)) + /* Standard register usage. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f5c9bcf..14ba119 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,40 @@ +Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * 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-tree.h (skip_rtti_stuff): Arg N is pointer to signed. + * cvt.c (cp_convert_to_pointer): Pass proper types to size_binop. + * decl.c (complete_arry_type): Pass proper types to size_binop. + (xref_basetypes): BINFO_OFFSET is sizetype. + * error.c (dump_expr): Don't use size_binop non-sizes. + * expr.c (cplus_expand_constant): Pass proper types to size_binop. + * init.c (construct_virtual_bases): Fix type error. + (build_vec_delete_1): Pass proper type to size_binop and don't + fold result. + * lex.c (cp_make_lang_type): BINFO_OFFSET is sizetype. + * rtti.c (get_base_offset): Pass proper type to size_binop. + * 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. + * tree.c (debug_binfo): Variable N is signed. + Use HOST_WIDE_INT_PRINT_DEC. + * 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. + 2000-02-26 Jason Merrill <jason@casey.cygnus.com> Implement class scope using-declarations for functions. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index d186027..5b0ab16 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -274,17 +274,16 @@ dfs_build_vbase_offset_vtbl_entries (binfo, data) else { BINFO_VPTR_FIELD (vbase) = TREE_PURPOSE (TREE_VALUE (list)); - BINFO_VPTR_FIELD (vbase) = ssize_binop (MINUS_EXPR, - BINFO_VPTR_FIELD (vbase), - integer_one_node); + BINFO_VPTR_FIELD (vbase) + = fold (build (MINUS_EXPR, integer_type_node, + BINFO_VPTR_FIELD (vbase), integer_one_node)); } /* And record the offset at which this virtual base lies in the vtable. */ init = BINFO_OFFSET (binfo); TREE_VALUE (list) = tree_cons (BINFO_VPTR_FIELD (vbase), - init, - TREE_VALUE (list)); + init, TREE_VALUE (list)); } SET_BINFO_VTABLE_PATH_MARKED (binfo); @@ -338,17 +337,14 @@ build_vbase_offset_vtbl_entries (binfo, t) object, and we need offsets from this BINFO. */ for (init = inits; init; init = TREE_CHAIN (init)) { - tree exp = TREE_VALUE (init); - - exp = ssize_binop (MINUS_EXPR, exp, BINFO_OFFSET (binfo)); - exp = build1 (NOP_EXPR, vtable_entry_type, exp); - exp = fold (exp); - TREE_CONSTANT (exp) = 1; /* The dfs_build_vbase_offset_vtbl_entries routine uses the TREE_PURPOSE to scribble in. But, we need to clear it now so that the values are not perceived as labeled initializers. */ TREE_PURPOSE (init) = NULL_TREE; - TREE_VALUE (init) = exp; + TREE_VALUE (init) + = fold (build1 (NOP_EXPR, vtable_entry_type, + size_diffop (TREE_VALUE (init), + BINFO_OFFSET (binfo)))); } return inits; @@ -406,25 +402,19 @@ dfs_build_vcall_offset_vtbl_entries (binfo, data) virtuals; virtuals = TREE_CHAIN (virtuals)) { - tree fn; - tree base; - tree base_binfo; - tree offset; - /* Figure out what function we're looking at. */ - fn = TREE_VALUE (virtuals); - base = DECL_CONTEXT (fn); - + tree fn = TREE_VALUE (virtuals); + tree base = DECL_CONTEXT (fn); /* The FN comes from BASE. So, we must caculate the adjustment from the virtual base that derived from BINFO to BASE. */ - base_binfo = get_binfo (base, vod->derived, /*protect=*/0); - offset = ssize_binop (MINUS_EXPR, - BINFO_OFFSET (base_binfo), - BINFO_OFFSET (vod->vbase)); - offset = build1 (NOP_EXPR, vtable_entry_type, offset); - offset = fold (offset); - TREE_CONSTANT (offset) = 1; - binfo_inits = tree_cons (NULL_TREE, offset, binfo_inits); + tree base_binfo = get_binfo (base, vod->derived, /*protect=*/0); + + binfo_inits + = tree_cons (NULL_TREE, + fold (build1 (NOP_EXPR, vtable_entry_type, + size_diffop (BINFO_OFFSET (base_binfo), + BINFO_OFFSET (vod->vbase)))), + binfo_inits); } /* Now add the initializers we've just created to the list that will @@ -634,11 +624,10 @@ build_vbase_path (code, type, expr, path, nonnull) if (changed) { tree intype = TREE_TYPE (TREE_TYPE (expr)); + if (TYPE_MAIN_VARIANT (intype) != BINFO_TYPE (last)) - { - tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0); - offset = BINFO_OFFSET (binfo); - } + offset + = BINFO_OFFSET (get_binfo (last, TYPE_MAIN_VARIANT (intype), 0)); } else offset = BINFO_OFFSET (last); @@ -647,10 +636,6 @@ build_vbase_path (code, type, expr, path, nonnull) { /* Bash types to make the backend happy. */ offset = cp_convert (type, offset); -#if 0 - /* This shouldn't be necessary. (mrs) */ - expr = build1 (NOP_EXPR, type, expr); -#endif /* If expr might be 0, we need to preserve that zeroness. */ if (nonnull == 0) @@ -921,16 +906,18 @@ get_vfield_offset (binfo) tree tmp = size_binop (FLOOR_DIV_EXPR, DECL_FIELD_BITPOS (TYPE_VFIELD (BINFO_TYPE (binfo))), - size_int (BITS_PER_UNIT)); - tmp = convert (sizetype, tmp); - return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo)); + bitsize_int (BITS_PER_UNIT)); + + return size_binop (PLUS_EXPR, convert (sizetype, tmp), + BINFO_OFFSET (binfo)); } /* Get the offset to the start of the original binfo that we derived this binfo from. If we find TYPE first, return the offset only that far. The shortened search is useful because the this pointer on method calling is expected to point to a DECL_CONTEXT (fndecl) - object, and not a baseclass of it. */ + object, and not a baseclass of it. */ + static tree get_derived_offset (binfo, type) @@ -939,14 +926,16 @@ get_derived_offset (binfo, type) tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); tree offset2; int i; + while (BINFO_BASETYPES (binfo) - && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) + && (i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) { tree binfos = BINFO_BASETYPES (binfo); if (BINFO_TYPE (binfo) == type) break; binfo = TREE_VEC_ELT (binfos, i); } + offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); return size_binop (MINUS_EXPR, offset1, offset2); } @@ -1085,7 +1074,7 @@ build_primary_vtable (binfo, type) /* Now do rtti stuff. */ offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); - offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); + offset = size_diffop (size_zero_node, offset); set_rtti_entry (virtuals, offset, type); } else @@ -1175,7 +1164,7 @@ build_secondary_vtable (binfo, for_type) offset = BINFO_OFFSET (binfo); set_rtti_entry (BINFO_VIRTUALS (binfo), - ssize_binop (MINUS_EXPR, integer_zero_node, offset), + size_diffop (size_zero_node, offset), for_type); /* In the new ABI, secondary vtables are laid out as part of the @@ -2620,12 +2609,8 @@ tree size_extra_vtbl_entries (binfo) tree binfo; { - tree offset; - - offset = size_binop (EXACT_DIV_EXPR, - TYPE_SIZE (vtable_entry_type), - size_int (BITS_PER_UNIT)); - offset = size_binop (MULT_EXPR, offset, num_extra_vtbl_entries (binfo)); + tree offset = size_binop (MULT_EXPR, TYPE_SIZE_UNIT (vtable_entry_type), + num_extra_vtbl_entries (binfo)); return fold (offset); } @@ -3039,7 +3024,7 @@ tree skip_rtti_stuff (binfo, t, n) tree binfo; tree t; - unsigned HOST_WIDE_INT *n; + HOST_WIDE_INT *n; { tree virtuals; @@ -3121,7 +3106,7 @@ dfs_modify_vtables (binfo, data) tree overrider; tree vindex; tree delta; - int i; + HOST_WIDE_INT i; /* Find the function which originally caused this vtable entry to be present. */ @@ -3151,9 +3136,7 @@ dfs_modify_vtables (binfo, data) get_derived_offset (binfo, DECL_VIRTUAL_CONTEXT (fn)), BINFO_OFFSET (binfo)); - delta = ssize_binop (MINUS_EXPR, - BINFO_OFFSET (TREE_VALUE (overrider)), - delta); + delta = size_diffop (BINFO_OFFSET (TREE_VALUE (overrider)), delta); modify_vtable_entry (t, binfo, @@ -4568,8 +4551,7 @@ dfs_propagate_binfo_offsets (binfo, data) tree offset = (tree) data; /* Update the BINFO_OFFSET for this base. */ - BINFO_OFFSET (binfo) - = size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), offset); + BINFO_OFFSET (binfo) = size_binop (PLUS_EXPR, BINFO_OFFSET (binfo), offset); SET_BINFO_MARKED (binfo); @@ -4714,9 +4696,8 @@ dfs_set_offset_for_unshared_vbases (binfo, data) tree offset; vbase = BINFO_FOR_VBASE (BINFO_TYPE (binfo), t); - offset = ssize_binop (MINUS_EXPR, - BINFO_OFFSET (vbase), - BINFO_OFFSET (binfo)); + offset = size_binop (MINUS_EXPR, + BINFO_OFFSET (vbase), BINFO_OFFSET (binfo)); propagate_binfo_offsets (binfo, offset); } @@ -4789,9 +4770,10 @@ layout_virtual_bases (t) /* Now, make sure that the total size of the type is a multiple of its alignment. */ dsize = CEIL (dsize, TYPE_ALIGN (t)) * TYPE_ALIGN (t); - TYPE_SIZE (t) = size_int (dsize); - TYPE_SIZE_UNIT (t) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t), - size_int (BITS_PER_UNIT)); + TYPE_SIZE (t) = bitsize_int (dsize); + TYPE_SIZE_UNIT (t) = convert (sizetype, + size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (t), + bitsize_int (BITS_PER_UNIT))); } /* Finish the work of layout_record, now taking virtual bases into account. @@ -4915,7 +4897,7 @@ layout_class_type (t, empty_p, has_virtual_p, if (*empty_p && flag_new_abi) { CLASSTYPE_SIZE (t) = bitsize_int (0); - CLASSTYPE_SIZE_UNIT (t) = size_int (0); + CLASSTYPE_SIZE_UNIT (t) = size_zero_node; } else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t) && TYPE_HAS_COMPLEX_ASSIGN_REF (t)) @@ -5026,13 +5008,14 @@ finish_struct_1 (t) && DECL_FIELD_CONTEXT (vfield) != t) { tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); - tree offset = BINFO_OFFSET (binfo); + tree offset = convert (bitsizetype, BINFO_OFFSET (binfo)); vfield = copy_node (vfield); copy_lang_decl (vfield); if (! integer_zerop (offset)) - offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); + offset = size_binop (MULT_EXPR, offset, bitsize_int (BITS_PER_UNIT)); + DECL_FIELD_CONTEXT (vfield) = t; DECL_FIELD_BITPOS (vfield) = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index f320918..c1ae4d2 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3618,7 +3618,8 @@ extern void push_lang_context PARAMS ((tree)); extern void pop_lang_context PARAMS ((void)); extern tree instantiate_type PARAMS ((tree, tree, int)); extern void print_class_statistics PARAMS ((void)); -extern tree skip_rtti_stuff PARAMS ((tree, tree, unsigned HOST_WIDE_INT *)); +extern tree skip_rtti_stuff PARAMS ((tree, tree, + HOST_WIDE_INT *)); extern void build_self_reference PARAMS ((void)); extern void warn_hidden PARAMS ((tree)); extern tree get_enclosing_class PARAMS ((tree)); diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index 6902232..9743f37 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -211,7 +211,8 @@ cp_convert_to_pointer (type, expr) expr = cplus_expand_constant (expr); if (binfo && ! TREE_VIA_VIRTUAL (binfo)) - expr = size_binop (code, expr, BINFO_OFFSET (binfo)); + expr = size_binop (code, convert (sizetype,expr), + BINFO_OFFSET (binfo)); } else if (TYPE_PTRMEMFUNC_P (type)) { diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index cafe393..548aa82 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -8244,13 +8244,14 @@ complete_array_type (type, initial_value, do_default) else if (TREE_CODE (initial_value) == CONSTRUCTOR) { tree elts = CONSTRUCTOR_ELTS (initial_value); - maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node); + + maxindex = ssize_int (-1); for (; elts; elts = TREE_CHAIN (elts)) { if (TREE_PURPOSE (elts)) maxindex = TREE_PURPOSE (elts); else - maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node); + maxindex = size_binop (PLUS_EXPR, maxindex, ssize_int (1)); } maxindex = copy_node (maxindex); } @@ -12481,7 +12482,7 @@ xref_basetypes (code_type_node, name, ref, binfo) the `accessibility' of that particular inheritance is.) */ base_binfo - = make_binfo (integer_zero_node, basetype, + = make_binfo (size_zero_node, basetype, CLASS_TYPE_P (basetype) ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE, CLASS_TYPE_P (basetype) diff --git a/gcc/cp/error.c b/gcc/cp/error.c index c15657a..ae6b511 100644 --- a/gcc/cp/error.c +++ b/gcc/cp/error.c @@ -2,7 +2,6 @@ This code is non-reentrant. Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of GNU CC. GNU CC is free software; you can redistribute it and/or modify @@ -1651,8 +1650,9 @@ dump_expr (t, flags) if (TREE_CODE (type) == ARRAY_REF) type = build_cplus_array_type (TREE_OPERAND (type, 0), - build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1), - integer_one_node))); + build_index_type (fold (build (MINUS_EXPR, integer_type_node, + TREE_OPERAND (type, 1), + integer_one_node)))); dump_type (type, flags); if (TREE_OPERAND (t, 2)) { diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c index 041a7a0..05411e3 100644 --- a/gcc/cp/expr.c +++ b/gcc/cp/expr.c @@ -63,13 +63,12 @@ cplus_expand_constant (cst) offset = convert (sizetype, size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (member), - size_int (BITS_PER_UNIT))); + bitsize_int (BITS_PER_UNIT))); /* We offset all pointer to data members by 1 so that we can distinguish between a null pointer to data member and the first data member of a structure. */ - offset = size_binop (PLUS_EXPR, offset, size_int (1)); - + offset = size_binop (PLUS_EXPR, offset, size_one_node); cst = cp_convert (type, offset); } else diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 69a4e3a..1f2eff4 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -801,7 +801,7 @@ construct_virtual_bases (type, this_ref, this_ptr, init_list, flag) exp = build (PLUS_EXPR, TREE_TYPE (this_ptr), this_ptr, - BINFO_OFFSET (vbases)); + fold (build1 (NOP_EXPR, this_ptr, BINFO_OFFSET (vbases)))); exp = build1 (NOP_EXPR, build_pointer_type (BINFO_TYPE (vbases)), exp); @@ -2482,7 +2482,8 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete) } /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); + virtual_size = size_binop (MULT_EXPR, size_exp, + convert (sizetype, maxindex)); tbase = create_temporary_var (ptype); tbase_init = build_modify_expr (tbase, NOP_EXPR, @@ -2525,7 +2526,8 @@ build_vec_delete_1 (base, maxindex, type, auto_delete_vec, use_global_delete) tree base_tbd; /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); + virtual_size = size_binop (MULT_EXPR, size_exp, + convert (sizetype, maxindex)); if (! TYPE_VEC_NEW_USES_COOKIE (type)) /* no header */ diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c index f522031..2e5a2e6 100644 --- a/gcc/cp/lex.c +++ b/gcc/cp/lex.c @@ -4792,7 +4792,7 @@ cp_make_lang_type (code) canonical binfo for them. Ideally, this would be done lazily for all types. */ if (IS_AGGR_TYPE_CODE (code) || code == TEMPLATE_TYPE_PARM) - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE); + TYPE_BINFO (t) = make_binfo (size_zero_node, t, NULL_TREE, NULL_TREE); return t; } diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index 0896fe2..cd83081 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -1,6 +1,6 @@ /* RunTime Type Identification - Copyright (C) 1995, 1996, 1997, 1998, - 1999, 2000 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000 + Free Software Foundation, Inc. Mostly written by Jason Merrill (jason@cygnus.com). This file is part of GNU CC. @@ -559,7 +559,7 @@ get_base_offset (binfo, parent) field = lookup_field (parent, get_identifier (name), 0, 0); offset = size_binop (FLOOR_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); offset = convert (sizetype, offset); } else diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 4b604eb..1a9b13f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1,6 +1,6 @@ /* Breadth-first and depth-first routines for searching multiple-inheritance lattice for GNU C++. - Copyright (C) 1987, 89, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com) @@ -2704,10 +2704,11 @@ dfs_find_vbases (binfo, data) { tree vbase = BINFO_TYPE (base_binfo); tree binfo = binfo_member (vbase, vi->vbase_types); + tree ptr_type = build_pointer_type (vbase); CLASSTYPE_SEARCH_SLOT (vbase) - = build (PLUS_EXPR, build_pointer_type (vbase), - vi->decl_ptr, BINFO_OFFSET (binfo)); + = build (PLUS_EXPR, ptr_type, vi->decl_ptr, + convert (ptr_type, BINFO_OFFSET (binfo))); } } SET_BINFO_VTABLE_PATH_MARKED (binfo); @@ -2895,7 +2896,7 @@ expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t, tree virtuals; tree vc; tree delta; - unsigned HOST_WIDE_INT n; + HOST_WIDE_INT n; while (BINFO_PRIMARY_MARKED_P (binfo)) { @@ -3153,7 +3154,7 @@ dfs_get_vbase_types (binfo, data) if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo)) { - tree new_vbase = make_binfo (integer_zero_node, + tree new_vbase = make_binfo (size_zero_node, BINFO_TYPE (binfo), BINFO_VTABLE (binfo), BINFO_VIRTUALS (binfo)); diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 6097302..c739db7 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -910,16 +910,18 @@ void debug_binfo (elem) tree elem; { - unsigned HOST_WIDE_INT n; + HOST_WIDE_INT n; tree virtuals; - fprintf (stderr, "type \"%s\"; offset = %ld\n", - TYPE_NAME_STRING (BINFO_TYPE (elem)), - (long) TREE_INT_CST_LOW (BINFO_OFFSET (elem))); - fprintf (stderr, "vtable type:\n"); + fprintf (stderr, "type \"%s\", offset = ", + TYPE_NAME_STRING (BINFO_TYPE (elem))); + fprintf (stderr, HOST_WIDE_INT_PRINT_DEC, + TREE_INT_CST_LOW (BINFO_OFFSET (elem))); + fprintf (stderr, "\nvtable type:\n"); debug_tree (BINFO_TYPE (elem)); if (BINFO_VTABLE (elem)) - fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem)))); + fprintf (stderr, "vtable decl \"%s\"\n", + IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem)))); else fprintf (stderr, "no vtable decl yet\n"); fprintf (stderr, "virtuals:\n"); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ae01800..bb2de74 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -934,6 +934,18 @@ comptypes (t1, t2, strict) if (t2 == error_mark_node) return 0; + /* If this is a strict comparison with a sizetype, the actual types + won't be the same (since we need to set TYPE_IS_SIZETYPE, so verify + if they are both the same size and signedness. */ + if (strict == COMPARE_STRICT + && TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2) + && TREE_CODE (t1) == INTEGER_TYPE + && TREE_UNSIGNED (t1) == TREE_UNSIGNED (t2) + && TYPE_MODE (t1) == TYPE_MODE (t2) + && TYPE_MIN_VALUE (t1) == TYPE_MIN_VALUE (t2) + && TYPE_MAX_VALUE (t1) == TYPE_MAX_VALUE (t2)) + return 1; + if (strict & COMPARE_RELAXED) { /* Treat an enum type as the unsigned integer type of the same width. */ @@ -1539,7 +1551,6 @@ c_sizeof (type) tree type; { enum tree_code code = TREE_CODE (type); - tree t; if (processing_template_decl) return build_min (SIZEOF_EXPR, sizetype, type); @@ -1548,22 +1559,22 @@ c_sizeof (type) { if (pedantic || warn_pointer_arith) pedwarn ("ISO C++ forbids applying `sizeof' to a function type"); - return size_int (1); + return size_one_node; } if (code == METHOD_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("ISO C++ forbids applying `sizeof' to a member function"); - return size_int (1); + return size_one_node; } if (code == VOID_TYPE) { if (pedantic || warn_pointer_arith) pedwarn ("ISO C++ forbids applying `sizeof' to type `void' which is an incomplete type"); - return size_int (1); + return size_one_node; } if (code == ERROR_MARK) - return size_int (1); + return size_one_node; /* ARM $5.3.2: ``When applied to a reference, the result is the size of the referenced object.'' */ @@ -1573,23 +1584,19 @@ c_sizeof (type) if (code == OFFSET_TYPE) { cp_error ("`sizeof' applied to non-static member"); - return size_int (0); + return size_zero_node; } if (TYPE_SIZE (complete_type (type)) == 0) { cp_error ("`sizeof' applied to incomplete type `%T'", type); - return size_int (0); + return size_zero_node; } /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - /* size_binop does not put the constant in range, so do it now. */ - if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) - TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; - return t; + return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } tree @@ -1605,12 +1612,12 @@ expr_sizeof (e) if (is_overloaded_fn (e)) { pedwarn ("ISO C++ forbids applying `sizeof' to an expression of function type"); - return size_int (1); + return size_one_node; } else if (type_unknown_p (e)) { incomplete_type_error (e, TREE_TYPE (e)); - return size_int (1); + return size_one_node; } /* It's illegal to say `sizeof (X::i)' for `i' a non-static data member unless you're in a non-static member of X. So hand off to @@ -1629,25 +1636,23 @@ c_sizeof_nowarn (type) tree type; { enum tree_code code = TREE_CODE (type); - tree t; if (code == FUNCTION_TYPE || code == METHOD_TYPE || code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); + return size_one_node; + if (code == REFERENCE_TYPE) type = TREE_TYPE (type); if (TYPE_SIZE (type) == 0) - return size_int (0); + return size_zero_node; /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - force_fit_type (t, 0); - return t; + return size_binop (CEIL_DIV_EXPR, TYPE_SIZE_UNIT (type), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); } /* Implement the __alignof keyword: Return the minimum required @@ -1667,7 +1672,7 @@ c_alignof (type) return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); if (code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); + return size_one_node; /* C++: this is really correct! */ if (code == REFERENCE_TYPE) @@ -4301,7 +4306,7 @@ build_component_addr (arg, argtype) if (! integer_zerop (DECL_FIELD_BITPOS (field))) { tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); int flag = TREE_CONSTANT (rval); offset = convert (sizetype, offset); rval = fold (build (PLUS_EXPR, argtype, @@ -6287,7 +6292,11 @@ build_ptrmemfunc (type, pfn, force) } /* Return the DELTA, IDX, PFN, and DELTA2 values for the PTRMEM_CST - given by CST. */ + given by CST. + + ??? There is no consistency as to the types returned for the above + values. Some code acts as if its a sizetype and some as if its + integer_type_node. */ void expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2) @@ -6315,7 +6324,7 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2) if (!DECL_VIRTUAL_P (fn)) { if (!flag_new_abi) - *idx = size_binop (MINUS_EXPR, integer_zero_node, integer_one_node); + *idx = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_int_2 (-1, -1)); else *idx = NULL_TREE; *pfn = convert (TYPE_PTRMEMFUNC_FN_TYPE (type), build_addr_func (fn)); @@ -6328,12 +6337,14 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2) fn; the call will do the opposite adjustment. */ tree orig_class = DECL_VIRTUAL_CONTEXT (fn); tree binfo = binfo_or_else (orig_class, fn_class); - *delta = size_binop (PLUS_EXPR, *delta, BINFO_OFFSET (binfo)); + *delta = fold (build (PLUS_EXPR, TREE_TYPE (*delta), + *delta, BINFO_OFFSET (binfo))); if (!flag_new_abi) { /* Map everything down one to make room for the null PMF. */ - *idx = size_binop (PLUS_EXPR, DECL_VINDEX (fn), integer_one_node); + *idx = fold (build (PLUS_EXPR, integer_type_node, + DECL_VINDEX (fn), integer_one_node)); *pfn = NULL_TREE; } else @@ -6341,14 +6352,17 @@ expand_ptrmemfunc_cst (cst, delta, idx, pfn, delta2) /* Under the new ABI, we set PFN to twice the index, plus one. */ *idx = NULL_TREE; - *pfn = size_binop (MULT_EXPR, DECL_VINDEX (fn), integer_two_node); - *pfn = size_binop (PLUS_EXPR, *pfn, integer_one_node); - *pfn = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type), *pfn); + *pfn = fold (build (MULT_EXPR, integer_type_node, + DECL_VINDEX (fn), integer_two_node)); + *pfn = fold (build (PLUS_EXPR, integer_type_node, *pfn, + integer_one_node)); + *pfn = fold (build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type), + *pfn)); } /* Offset from an object of PTR_CLASS to the vptr for ORIG_CLASS. */ - *delta2 = size_binop (PLUS_EXPR, *delta, - get_vfield_offset (TYPE_BINFO (orig_class))); + *delta2 = fold (build (PLUS_EXPR, integer_type_node, *delta, + get_vfield_offset (TYPE_BINFO (orig_class)))); } } @@ -3864,8 +3864,7 @@ store_expr (exp, target, want_value) tree copy_size = size_binop (MIN_EXPR, make_tree (sizetype, size), - convert (sizetype, - build_int_2 (TREE_STRING_LENGTH (exp), 0))); + size_int (TREE_STRING_LENGTH (exp))); rtx copy_size_rtx = expand_expr (copy_size, NULL_RTX, VOIDmode, 0); rtx label = 0; @@ -4215,11 +4214,12 @@ store_constructor (exp, target, align, cleared, size) rtx offset_rtx; if (contains_placeholder_p (offset)) - offset = build (WITH_RECORD_EXPR, sizetype, + offset = build (WITH_RECORD_EXPR, bitsizetype, offset, make_tree (TREE_TYPE (exp), target)); offset = size_binop (EXACT_DIV_EXPR, offset, - size_int (BITS_PER_UNIT)); + bitsize_int (BITS_PER_UNIT)); + offset = convert (sizetype, offset); offset_rtx = expand_expr (offset, NULL_RTX, VOIDmode, 0); if (GET_CODE (to_rtx) != MEM) @@ -4435,12 +4435,14 @@ store_constructor (exp, target, align, cleared, size) loop = expand_start_loop (0); /* Assign value to element index. */ - position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype), - size_int (BITS_PER_UNIT)); - position = size_binop (MULT_EXPR, - size_binop (MINUS_EXPR, index, - TYPE_MIN_VALUE (domain)), - position); + position + = convert (ssizetype, + fold (build (MINUS_EXPR, TREE_TYPE (index), + index, TYPE_MIN_VALUE (domain)))); + position = size_binop (MULT_EXPR, position, + convert (ssizetype, + TYPE_SIZE_UNIT (elttype))); + pos_rtx = expand_expr (position, 0, VOIDmode, 0); addr = gen_rtx_PLUS (Pmode, XEXP (target, 0), pos_rtx); xtarget = change_address (target, mode, addr); @@ -4473,14 +4475,15 @@ store_constructor (exp, target, align, cleared, size) tree position; if (index == 0) - index = size_int (i); + index = ssize_int (1); if (minelt) - index = size_binop (MINUS_EXPR, index, - TYPE_MIN_VALUE (domain)); - position = size_binop (EXACT_DIV_EXPR, TYPE_SIZE (elttype), - size_int (BITS_PER_UNIT)); - position = size_binop (MULT_EXPR, index, position); + index = convert (ssizetype, + fold (build (MINUS_EXPR, index, + TYPE_MIN_VALUE (domain)))); + position = size_binop (MULT_EXPR, index, + convert (ssizetype, + TYPE_SIZE_UNIT (elttype))); pos_rtx = expand_expr (position, 0, VOIDmode, 0); addr = gen_rtx_PLUS (Pmode, XEXP (target, 0), pos_rtx); xtarget = change_address (target, mode, addr); @@ -4528,8 +4531,8 @@ store_constructor (exp, target, align, cleared, size) domain_min = convert (sizetype, TYPE_MIN_VALUE (domain)); domain_max = convert (sizetype, TYPE_MAX_VALUE (domain)); bitlength = size_binop (PLUS_EXPR, - size_binop (MINUS_EXPR, domain_max, domain_min), - size_one_node); + size_diffop (domain_max, domain_min), + ssize_int (1)); if (nbytes < 0 || TREE_CODE (bitlength) != INTEGER_CST) abort (); @@ -4930,7 +4933,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, tree orig_exp = exp; tree size_tree = 0; enum machine_mode mode = VOIDmode; - tree offset = integer_zero_node; + tree offset = size_zero_node; unsigned int alignment = BIGGEST_ALIGNMENT; if (TREE_CODE (exp) == COMPONENT_REF) @@ -4975,7 +4978,7 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, tree pos = (TREE_CODE (exp) == COMPONENT_REF ? DECL_FIELD_BITPOS (TREE_OPERAND (exp, 1)) : TREE_OPERAND (exp, 2)); - tree constant = integer_zero_node, var = pos; + tree constant = bitsize_int (0), var = pos; /* If this field hasn't been filled in yet, don't go past it. This should only happen when folding expressions @@ -4989,12 +4992,14 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, && TREE_CODE (TREE_OPERAND (pos, 1)) == INTEGER_CST) constant = TREE_OPERAND (pos, 1), var = TREE_OPERAND (pos, 0); else if (TREE_CODE (pos) == INTEGER_CST) - constant = pos, var = integer_zero_node; + constant = pos, var = bitsize_int (0); *pbitpos += TREE_INT_CST_LOW (constant); - offset = size_binop (PLUS_EXPR, offset, - size_binop (EXACT_DIV_EXPR, var, - size_int (BITS_PER_UNIT))); + offset + = size_binop (PLUS_EXPR, offset, + convert (sizetype, + size_binop (EXACT_DIV_EXPR, var, + bitsize_int (BITS_PER_UNIT)))); } else if (TREE_CODE (exp) == ARRAY_REF) @@ -5051,14 +5056,16 @@ get_inner_reference (exp, pbitsize, pbitpos, poffset, pmode, it overflowed. In either case, redo the multiplication against the size in units. This is especially important in the non-constant case to avoid a division at runtime. */ - xindex = fold (build (MULT_EXPR, ssizetype, index, - convert (ssizetype, - TYPE_SIZE_UNIT (TREE_TYPE (exp))))); + xindex + = fold (build (MULT_EXPR, ssizetype, index, + convert (ssizetype, + TYPE_SIZE_UNIT (TREE_TYPE (exp))))); if (contains_placeholder_p (xindex)) - xindex = build (WITH_RECORD_EXPR, sizetype, xindex, exp); + xindex = build (WITH_RECORD_EXPR, ssizetype, xindex, exp); - offset = size_binop (PLUS_EXPR, offset, xindex); + offset + = size_binop (PLUS_EXPR, offset, convert (sizetype, xindex)); } } else if (TREE_CODE (exp) != NON_LVALUE_EXPR @@ -6457,8 +6464,7 @@ expand_expr (exp, target, tmode, modifier) tree array = TREE_OPERAND (exp, 0); tree domain = TYPE_DOMAIN (TREE_TYPE (array)); tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node; - tree index = TREE_OPERAND (exp, 1); - tree index_type = TREE_TYPE (index); + tree index = convert (sizetype, TREE_OPERAND (exp, 1)); HOST_WIDE_INT i; /* Optimize the special-case of a zero lower bound. @@ -6467,14 +6473,10 @@ expand_expr (exp, target, tmode, modifier) with constant folding. (E.g. suppose the lower bound is 1, and its mode is QI. Without the conversion, (ARRAY +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1)) - +INDEX), which becomes (ARRAY+255+INDEX). Oops!) - - But sizetype isn't quite right either (especially if - the lowbound is negative). FIXME */ + +INDEX), which becomes (ARRAY+255+INDEX). Oops!) */ if (! integer_zerop (low_bound)) - index = fold (build (MINUS_EXPR, index_type, index, - convert (sizetype, low_bound))); + index = size_diffop (index, convert (sizetype, low_bound)); /* Fold an expression like: "foo"[2]. This is not done in fold so it won't happen inside &. @@ -8508,8 +8510,7 @@ expand_expr_unaligned (exp, palign) tree array = TREE_OPERAND (exp, 0); tree domain = TYPE_DOMAIN (TREE_TYPE (array)); tree low_bound = domain ? TYPE_MIN_VALUE (domain) : integer_zero_node; - tree index = TREE_OPERAND (exp, 1); - tree index_type = TREE_TYPE (index); + tree index = convert (sizetype, TREE_OPERAND (exp, 1)); HOST_WIDE_INT i; if (TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) != ARRAY_TYPE) @@ -8521,14 +8522,10 @@ expand_expr_unaligned (exp, palign) with constant folding. (E.g. suppose the lower bound is 1, and its mode is QI. Without the conversion, (ARRAY +(INDEX-(unsigned char)1)) becomes ((ARRAY+(-(unsigned char)1)) - +INDEX), which becomes (ARRAY+255+INDEX). Oops!) - - But sizetype isn't quite right either (especially if - the lowbound is negative). FIXME */ + +INDEX), which becomes (ARRAY+255+INDEX). Oops!) */ if (! integer_zerop (low_bound)) - index = fold (build (MINUS_EXPR, index_type, index, - convert (sizetype, low_bound))); + index = size_diffop (index, convert (sizetype, low_bound)); /* If this is a constant index into a constant array, just get the value from the array. Handle both the cases when @@ -8778,8 +8775,10 @@ expand_expr_unaligned (exp, palign) return expand_expr (exp, NULL_RTX, VOIDmode, EXPAND_NORMAL); } -/* Return the tree node and offset if a given argument corresponds to - a string constant. */ +/* Return the tree node if a ARG corresponds to a string constant or zero + if it doesn't. If we return non-zero, set *PTR_OFFSET to the offset + in bytes within the string that ARG is accessing. The type of the + offset will be `sizetype'. */ tree string_constant (arg, ptr_offset) @@ -8791,7 +8790,7 @@ string_constant (arg, ptr_offset) if (TREE_CODE (arg) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (arg, 0)) == STRING_CST) { - *ptr_offset = integer_zero_node; + *ptr_offset = size_zero_node; return TREE_OPERAND (arg, 0); } else if (TREE_CODE (arg) == PLUS_EXPR) @@ -8805,13 +8804,13 @@ string_constant (arg, ptr_offset) if (TREE_CODE (arg0) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (arg0, 0)) == STRING_CST) { - *ptr_offset = arg1; + *ptr_offset = convert (sizetype, arg1); return TREE_OPERAND (arg0, 0); } else if (TREE_CODE (arg1) == ADDR_EXPR && TREE_CODE (TREE_OPERAND (arg1, 0)) == STRING_CST) { - *ptr_offset = arg0; + *ptr_offset = convert (sizetype, arg0); return TREE_OPERAND (arg1, 0); } } @@ -79,7 +79,9 @@ enum memory_use_mode {MEMORY_USE_BAD = 0, MEMORY_USE_RO = 1, #ifdef TREE_CODE /* Don't lose if tree.h not included. */ /* Structure to record the size of a sequence of arguments - as the sum of a tree-expression and a constant. */ + as the sum of a tree-expression and a constant. This structure is + also used to store offsets from the stack, which might be negative, + so the variable part must be ssizetype, not sizetype. */ struct args_size { @@ -104,21 +106,21 @@ struct args_size if (TREE_CODE (dec) == INTEGER_CST) \ (TO).constant -= TREE_INT_CST_LOW (dec); \ else if ((TO).var == 0) \ - (TO).var = size_binop (MINUS_EXPR, integer_zero_node, dec); \ + (TO).var = size_binop (MINUS_EXPR, ssize_int (0), dec); \ else \ (TO).var = size_binop (MINUS_EXPR, (TO).var, dec); } +/* Convert the implicit sum in a `struct args_size' into a tree + of type ssizetype. */ +#define ARGS_SIZE_TREE(SIZE) \ +((SIZE).var == 0 ? ssize_int ((SIZE).constant) \ + : size_binop (PLUS_EXPR, (SIZE).var, ssize_int ((SIZE).constant))) + /* Convert the implicit sum in a `struct args_size' into an rtx. */ -#define ARGS_SIZE_RTX(SIZE) \ -((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \ - : expand_expr (size_binop (PLUS_EXPR, (SIZE).var, \ - size_int ((SIZE).constant)), \ - NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD)) - -/* Convert the implicit sum in a `struct args_size' into a tree. */ -#define ARGS_SIZE_TREE(SIZE) \ -((SIZE).var == 0 ? size_int ((SIZE).constant) \ - : size_binop (PLUS_EXPR, (SIZE).var, size_int ((SIZE).constant))) +#define ARGS_SIZE_RTX(SIZE) \ +((SIZE).var == 0 ? GEN_INT ((SIZE).constant) \ + : expand_expr (ARGS_SIZE_TREE (SIZE), NULL_RTX, VOIDmode, \ + EXPAND_MEMORY_USE_BAD)) /* Supply a default definition for FUNCTION_ARG_PADDING: usually pad upward, but pad short args downward on diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog index aa023a5..9a4a86f 100644 --- a/gcc/f/ChangeLog +++ b/gcc/f/ChangeLog @@ -1,3 +1,12 @@ +Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * 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. + * ste.c (ffeste_io_dofio_, ffeste_io_douio_): Use TYPE_SIZE_UNIT. + (ffeste_io_ciclist_): Likewise. + 2000-02-23 Zack Weinberg <zack@wolery.cumb.org> * com.c (ffecom_type_permanent_copy_): Delete unused function. diff --git a/gcc/f/com.c b/gcc/f/com.c index 14193eb..ff2e45c 100644 --- a/gcc/f/com.c +++ b/gcc/f/com.c @@ -969,10 +969,10 @@ ffecom_arrayref_ (tree item, ffebld expr, int want_ptr) item, size_binop (MULT_EXPR, size_in_bytes (TREE_TYPE (array)), - fold (build (MINUS_EXPR, - tree_type_x, - element, - min)))); + convert (sizetype, + fold (build (MINUS_EXPR, + tree_type_x, + element, min))))); } if (! want_ptr) { @@ -9090,14 +9090,13 @@ ffecom_tree_canonize_ptr_ (tree *decl, tree *offset, if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) { /* An offset into COMMON. */ - *offset = size_binop (PLUS_EXPR, - *offset, - TREE_OPERAND (t, 1)); + *offset = fold (build (PLUS_EXPR, TREE_TYPE (*offset), + *offset, TREE_OPERAND (t, 1))); /* Convert offset (presumably in bytes) into canonical units (presumably bits). */ - *offset = size_binop (MULT_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))), - *offset); + *offset = fold (build (MULT_EXPR, TREE_TYPE (*offset), + TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))), + *offset)); break; } /* Not a COMMON reference, so an unrecognized pattern. */ @@ -9258,16 +9257,17 @@ ffecom_tree_canonize_ref_ (tree *decl, tree *offset, || (*decl == error_mark_node)) return; - *offset = size_binop (MULT_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))), - size_binop (MINUS_EXPR, - element, - TYPE_MIN_VALUE - (TYPE_DOMAIN - (TREE_TYPE (array))))); - - *offset = size_binop (PLUS_EXPR, - init_offset, + *offset + = size_binop (MULT_EXPR, + TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))), + convert (sizetype, + fold (build (MINUS_EXPR, TREE_TYPE (element), + element, + TYPE_MIN_VALUE + (TYPE_DOMAIN + (TREE_TYPE (array)))))));; + + *offset = size_binop (PLUS_EXPR, convert (sizetype, init_offset), *offset); *size = TYPE_SIZE (TREE_TYPE (t)); @@ -15633,6 +15633,11 @@ type_for_mode (mode, unsignedp) if (mode == TYPE_MODE (long_long_integer_type_node)) return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; +#if HOST_BITS_PER_WIDE_INT >= 64 + if (mode == TYPE_MODE (intTI_type_node)) + return unsignedp ? unsigned_intTI_type_node : intTI_type_node; +#endif + if (mode == TYPE_MODE (float_type_node)) return float_type_node; diff --git a/gcc/f/ste.c b/gcc/f/ste.c index 6db4d48..f25b929 100644 --- a/gcc/f/ste.c +++ b/gcc/f/ste.c @@ -1,5 +1,5 @@ /* ste.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 2000 Free Software Foundation, Inc. Contributed by James Craig Burley. This file is part of GNU Fortran. @@ -959,8 +959,9 @@ ffeste_io_dofio_ (ffebld expr) if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ { /* "(ftnlen) sizeof(type)" */ size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); + TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); #if 0 /* Assume that while it is possible that char * is wider than ftnlen, no object in Fortran space can get big enough for its size to be wider than ftnlen. I really hope nobody wastes @@ -977,13 +978,13 @@ ffeste_io_dofio_ (ffebld expr) = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node; else { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), - size); - num_elements = size_binop (CEIL_DIV_EXPR, - num_elements, - size_int (TYPE_PRECISION - (char_type_node))); + num_elements + = size_binop (CEIL_DIV_EXPR, + TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))), + convert (sizetype, size)); + num_elements = size_binop (CEIL_DIV_EXPR, num_elements, + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); num_elements = convert (ffecom_f2c_ftnlen_type_node, num_elements); } @@ -1050,8 +1051,9 @@ ffeste_io_dolio_ (ffebld expr) if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ { /* "(ftnlen) sizeof(type)" */ size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); + TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); #if 0 /* Assume that while it is possible that char * is wider than ftnlen, no object in Fortran space can get big enough for its size to be wider than ftnlen. I really hope nobody wastes @@ -1067,13 +1069,13 @@ ffeste_io_dolio_ (ffebld expr) num_elements = ffecom_integer_one_node; else { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), - size); - num_elements = size_binop (CEIL_DIV_EXPR, - num_elements, - size_int (TYPE_PRECISION - (char_type_node))); + num_elements + = size_binop (CEIL_DIV_EXPR, + TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))), + convert (sizetype, size)); + num_elements = size_binop (CEIL_DIV_EXPR, num_elements, + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); num_elements = convert (ffecom_f2c_ftnlen_type_node, num_elements); } @@ -1139,8 +1141,9 @@ ffeste_io_douio_ (ffebld expr) if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ { /* "(ftnlen) sizeof(type)" */ size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); + TYPE_SIZE_UNIT (ffecom_tree_type[bt][kt]), + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); #if 0 /* Assume that while it is possible that char * is wider than ftnlen, no object in Fortran space can get big enough for its size to be wider than ftnlen. I really hope nobody wastes @@ -1157,12 +1160,13 @@ ffeste_io_douio_ (ffebld expr) = is_complex ? ffecom_f2c_ftnlen_two_node : ffecom_f2c_ftnlen_one_node; else { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), - size); + num_elements + = size_binop (CEIL_DIV_EXPR, + TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (variable))), + convert (sizetype, size)); num_elements = size_binop (CEIL_DIV_EXPR, num_elements, - size_int (TYPE_PRECISION - (char_type_node))); + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); num_elements = convert (ffecom_f2c_ftnlen_type_node, num_elements); } @@ -1759,13 +1763,13 @@ ffeste_io_icilist_ (bool have_err, else if (unitexp && unitlenexp) { /* An array, but all the info is constant, so compute now. */ - unitnuminit = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))), - unitlenexp); - unitnuminit = size_binop (CEIL_DIV_EXPR, - unitnuminit, - size_int (TYPE_PRECISION - (char_type_node))); + unitnuminit + = size_binop (CEIL_DIV_EXPR, + TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (unitexp))), + convert (sizetype, unitlenexp)); + unitnuminit = size_binop (CEIL_DIV_EXPR, unitnuminit, + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); unitnumexp = unitnuminit; } else @@ -1874,13 +1878,13 @@ ffeste_io_icilist_ (bool have_err, && unitexp != error_mark_node && unitlenexp != error_mark_node) { - unitnumexp = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))), - unitlenexp); - unitnumexp = size_binop (CEIL_DIV_EXPR, - unitnumexp, - size_int (TYPE_PRECISION - (char_type_node))); + unitnumexp + = size_binop (CEIL_DIV_EXPR, + TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (unitexp))), + convert (sizetype, unitlenexp)); + unitnumexp = size_binop (CEIL_DIV_EXPR, unitnumexp, + size_int (TYPE_PRECISION (char_type_node) + / BITS_PER_UNIT)); ffeste_f2c_compile_ (unitnumfield, unitnumexp); } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index ff925c9..24bf6f1 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -1559,13 +1559,8 @@ int_const_binop (code, arg1, arg2, notrunc, forsize) abort (); } - if (TREE_TYPE (arg1) == sizetype && hi == 0 - && low >= 0 - && (TYPE_MAX_VALUE (sizetype) == NULL - || low <= TREE_INT_CST_LOW (TYPE_MAX_VALUE (sizetype))) - && ! overflow - && ! TREE_OVERFLOW (arg1) && ! TREE_OVERFLOW (arg2)) - t = size_int (low); + if (forsize && hi == 0 && low >= 0 && low < 1000) + return size_int_type_wide (low, TREE_TYPE (arg1)); else { t = build_int_2 (low, hi); @@ -1797,19 +1792,25 @@ const_binop (code, arg1, arg2, notrunc) } /* Return an INTEGER_CST with value whose low-order HOST_BITS_PER_WIDE_INT - bits are given by NUMBER. + bits are given by NUMBER and of the sizetype represented by KIND. */ - If BIT_P is nonzero, this represents a size in bit and the type of the - result will be bitsizetype, othewise it represents a size in bytes and - the type of the result will be sizetype. */ +tree +size_int_wide (number, kind) + HOST_WIDE_INT number; + enum size_type_kind kind; +{ + return size_int_type_wide (number, sizetype_tab[(int) kind]); +} + +/* Likewise, but the desired type is specified explicitly. */ tree -size_int_wide (number, bit_p) +size_int_type_wide (number, type) HOST_WIDE_INT number; - int bit_p; + tree type; { /* Type-size nodes already made for small sizes. */ - static tree size_table[2 * HOST_BITS_PER_WIDE_INT + 1][2]; + static tree size_table[2 * HOST_BITS_PER_WIDE_INT + 1]; static int init_p = 0; tree t; @@ -1826,8 +1827,10 @@ size_int_wide (number, bit_p) if (number >= 0 && number < (int) (sizeof size_table / sizeof size_table[0]) / 2) { - if (size_table[number][bit_p] != 0) - return size_table[number][bit_p]; + if (size_table[number] != 0) + for (t = size_table[number]; t != 0; t = TREE_CHAIN (t)) + if (TREE_TYPE (t) == type) + return t; if (! ggc_p) { @@ -1837,8 +1840,9 @@ size_int_wide (number, bit_p) } t = build_int_2 (number, 0); - TREE_TYPE (t) = bit_p ? bitsizetype : sizetype; - size_table[number][bit_p] = t; + TREE_TYPE (t) = type; + TREE_CHAIN (t) = size_table[number]; + size_table[number] = t; if (! ggc_p) pop_obstacks (); @@ -1846,14 +1850,15 @@ size_int_wide (number, bit_p) return t; } - t = build_int_2 (number, 0); - TREE_TYPE (t) = bit_p ? bitsizetype : sizetype; + t = build_int_2 (number, number < 0 ? -1 : 0); + TREE_TYPE (t) = type; TREE_OVERFLOW (t) = TREE_CONSTANT_OVERFLOW (t) = force_fit_type (t, 0); return t; } -/* Combine operands OP1 and OP2 with arithmetic operation CODE. - CODE is a tree code. Data type is taken from `sizetype', +/* Combine operands OP1 and OP2 with arithmetic operation CODE. CODE + is a tree code. The type of the result is taken from the operands. + Both must be the same type integer type and it must be a size type. If the operands are constant, so is the result. */ tree @@ -1861,6 +1866,12 @@ size_binop (code, arg0, arg1) enum tree_code code; tree arg0, arg1; { + tree type = TREE_TYPE (arg0); + + if (type != TREE_TYPE (arg1) + || TREE_CODE (type) != INTEGER_TYPE || ! TYPE_IS_SIZETYPE (type)) + abort (); + /* Handle the special case of two integer constants faster. */ if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) { @@ -1880,41 +1891,49 @@ size_binop (code, arg0, arg1) if (arg0 == error_mark_node || arg1 == error_mark_node) return error_mark_node; - return fold (build (code, sizetype, arg0, arg1)); + return fold (build (code, type, arg0, arg1)); } -/* Combine operands OP1 and OP2 with arithmetic operation CODE. - CODE is a tree code. Data type is taken from `ssizetype', - If the operands are constant, so is the result. */ +/* Given two values, either both of sizetype or both of bitsizetype, + compute the difference between the two values. Return the value + in signed type corresponding to the type of the operands. */ tree -ssize_binop (code, arg0, arg1) - enum tree_code code; +size_diffop (arg0, arg1) tree arg0, arg1; { - /* Handle the special case of two integer constants faster. */ - if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST) - { - /* And some specific cases even faster than that. */ - if (code == PLUS_EXPR && integer_zerop (arg0)) - return arg1; - else if ((code == MINUS_EXPR || code == PLUS_EXPR) - && integer_zerop (arg1)) - return arg0; - else if (code == MULT_EXPR && integer_onep (arg0)) - return arg1; + tree type = TREE_TYPE (arg0); + tree ctype; - /* Handle general case of two integer constants. We convert - arg0 to ssizetype because int_const_binop uses its type for the - return value. */ - arg0 = convert (ssizetype, arg0); - return int_const_binop (code, arg0, arg1, 0, 0); - } - - if (arg0 == error_mark_node || arg1 == error_mark_node) - return error_mark_node; + if (TREE_TYPE (arg1) != type || TREE_CODE (type) != INTEGER_TYPE + || ! TYPE_IS_SIZETYPE (type)) + abort (); - return fold (build (code, ssizetype, arg0, arg1)); + /* If the type is already signed, just do the simple thing. */ + if (! TREE_UNSIGNED (type)) + return size_binop (MINUS_EXPR, arg0, arg1); + + ctype = (type == bitsizetype || type == ubitsizetype + ? sbitsizetype : ssizetype); + + /* If either operand is not a constant, do the conversions to the signed + type and subtract. The hardware will do the right thing with any + overflow in the subtraction. */ + if (TREE_CODE (arg0) != INTEGER_CST || TREE_CODE (arg1) != INTEGER_CST) + return size_binop (MINUS_EXPR, convert (ctype, arg0), + convert (ctype, arg1)); + + /* If ARG0 is larger than ARG1, subtract and return the result in CTYPE. + Otherwise, subtract the other way, convert to CTYPE (we know that can't + overflow) and negate (which can't either). Special-case a result + of zero while we're here. */ + if (tree_int_cst_equal (arg0, arg1)) + return convert (ctype, integer_zero_node); + else if (tree_int_cst_lt (arg1, arg0)) + return convert (ctype, size_binop (MINUS_EXPR, arg0, arg1)); + else + return size_binop (MINUS_EXPR, convert (ctype, integer_zero_node), + convert (ctype, size_binop (MINUS_EXPR, arg1, arg0))); } /* This structure is used to communicate arguments to fold_convert_1. */ @@ -1959,6 +1978,14 @@ fold_convert (t, arg1) if (TYPE_PRECISION (type) > 2 * HOST_BITS_PER_WIDE_INT) return t; + /* If we are trying to make a sizetype for a small integer, use + size_int to pick up cached types to reduce duplicate nodes. */ + if (TREE_CODE (type) == INTEGER_CST && TYPE_IS_SIZETYPE (type) + && TREE_INT_CST_HIGH (arg1) == 0 + && TREE_INT_CST_LOW (arg1) >= 0 + && TREE_INT_CST_LOW (arg1) < 1000) + return size_int_type_wide (TREE_INT_CST_LOW (arg1), type); + /* Given an integer constant, make new constant with new type, appropriately sign-extended or truncated. */ t = build_int_2 (TREE_INT_CST_LOW (arg1), @@ -4471,8 +4498,13 @@ extract_muldiv (t, c, code, wide_type) /* If these operations "cancel" each other, we have the main optimizations of this pass, which occur when either constant is a multiple of the other, in which case we replace this with either an - operation or CODE or TCODE. */ - if ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR) + operation or CODE or TCODE. If we have an unsigned type that is + not a sizetype, we canot do this for division since it will change + the result if the original computation overflowed. */ + if ((code == MULT_EXPR && tcode == EXACT_DIV_EXPR + && (! TREE_UNSIGNED (ctype) + || (TREE_CODE (ctype) == INTEGER_TYPE + && TYPE_IS_SIZETYPE (ctype)))) || (tcode == MULT_EXPR && code != TRUNC_MOD_EXPR && code != CEIL_MOD_EXPR && code != FLOOR_MOD_EXPR && code != ROUND_MOD_EXPR)) diff --git a/gcc/function.c b/gcc/function.c index 1f18d25..dae6996 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -4835,8 +4835,8 @@ assign_parms (fndecl) #ifdef ARGS_GROW_DOWNWARD current_function_arg_offset_rtx = (stack_args_size.var == 0 ? GEN_INT (-stack_args_size.constant) - : expand_expr (size_binop (MINUS_EXPR, stack_args_size.var, - size_int (-stack_args_size.constant)), + : expand_expr (size_diffop (stack_args_size.var, + size_int (-stack_args_size.constant)), NULL_RTX, VOIDmode, EXPAND_MEMORY_USE_BAD)); #else current_function_arg_offset_rtx = ARGS_SIZE_RTX (stack_args_size); @@ -4968,7 +4968,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, { initial_offset_ptr->var = size_binop (MAX_EXPR, ARGS_SIZE_TREE (*initial_offset_ptr), - size_int (reg_parm_stack_space)); + ssize_int (reg_parm_stack_space)); initial_offset_ptr->constant = 0; } else if (initial_offset_ptr->constant < reg_parm_stack_space) @@ -4984,7 +4984,7 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, if (initial_offset_ptr->var) { offset_ptr->constant = 0; - offset_ptr->var = size_binop (MINUS_EXPR, integer_zero_node, + offset_ptr->var = size_binop (MINUS_EXPR, ssize_int (0), initial_offset_ptr->var); } else @@ -5000,18 +5000,16 @@ locate_and_pad_parm (passed_mode, type, in_regs, fndecl, if (where_pad != downward) pad_to_arg_alignment (offset_ptr, boundary, alignment_pad); if (initial_offset_ptr->var) - { - arg_size_ptr->var = size_binop (MINUS_EXPR, - size_binop (MINUS_EXPR, - integer_zero_node, - initial_offset_ptr->var), - offset_ptr->var); - } + arg_size_ptr->var = size_binop (MINUS_EXPR, + size_binop (MINUS_EXPR, + ssize_int (0), + initial_offset_ptr->var), + offset_ptr->var); + else - { - arg_size_ptr->constant = (- initial_offset_ptr->constant - - offset_ptr->constant); - } + arg_size_ptr->constant = (- initial_offset_ptr->constant + - offset_ptr->constant); + #else /* !ARGS_GROW_DOWNWARD */ pad_to_arg_alignment (initial_offset_ptr, boundary, alignment_pad); *offset_ptr = *initial_offset_ptr; @@ -5075,7 +5073,8 @@ pad_to_arg_alignment (offset_ptr, boundary, alignment_pad) boundary / BITS_PER_UNIT); offset_ptr->constant = 0; /*?*/ if (boundary > PARM_BOUNDARY && boundary > STACK_BOUNDARY) - alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, save_var); + alignment_pad->var = size_binop (MINUS_EXPR, offset_ptr->var, + save_var); } else { @@ -5120,18 +5119,6 @@ pad_below (offset_ptr, passed_mode, sizetree) } } #endif - -#ifdef ARGS_GROW_DOWNWARD -static tree -round_down (value, divisor) - tree value; - int divisor; -{ - return size_binop (MULT_EXPR, - size_binop (FLOOR_DIV_EXPR, value, size_int (divisor)), - size_int (divisor)); -} -#endif /* Walk the tree of blocks describing the binding levels within a function and warn about uninitialized variables. diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 9e9e877..31b6090 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -1,3 +1,7 @@ +Sun Feb 27 16:40:33 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> + + * expr.c (build_java_ret): Pass proper type to size_binop. + 2000-02-25 Anthony Green <green@cygnus.com> * expr.c (build_class_init): Mark the decl to be ignored by diff --git a/gcc/java/expr.c b/gcc/java/expr.c index 7dcf6f5..e32b6a9 100644 --- a/gcc/java/expr.c +++ b/gcc/java/expr.c @@ -579,7 +579,7 @@ build_java_ret (location) size_binop (CEIL_DIV_EXPR, \ (DECL_FIELD_BITPOS \ (TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (TREE_TYPE (A)))))), \ - size_int (BITS_PER_UNIT)) + bitsize_int (BITS_PER_UNIT)) tree decode_newarray_type (atype) 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); diff --git a/gcc/tm.texi b/gcc/tm.texi index 4c4d484..708b8d7 100644 --- a/gcc/tm.texi +++ b/gcc/tm.texi @@ -1,4 +1,5 @@ -@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000 Free Software Foundation, Inc. +@c Copyright (C) 1988,1989,1992,1993,1994,1995,1996,1997,1998,1999,2000 +@c Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @@ -1001,6 +1002,13 @@ usual way is @var{computed} and the alignment is @var{specified}. The default is to round @var{computed} up to a multiple of @var{specified}. +@findex ROUND_TYPE_SIZE_UNIT +@item ROUND_TYPE_SIZE_UNIT (@var{type}, @var{computed}, @var{specified}) +Similar to @code{ROUND_TYPE_SIZE}, but sizes and alignments are +specified in units (bytes). If you define @code{ROUND_TYPE_SIZE}, +you must also define this macro and they must be defined consistently +with each other. + @findex ROUND_TYPE_ALIGN @item ROUND_TYPE_ALIGN (@var{type}, @var{computed}, @var{specified}) Define this macro as an expression for the alignment of a type (given @@ -276,7 +276,6 @@ static void build_real_from_int_cst_1 PARAMS ((PTR)); static void set_type_quals PARAMS ((tree, int)); static void append_random_chars PARAMS ((char *)); static void mark_type_hash PARAMS ((void *)); -static void fix_sizetype PARAMS ((tree)); /* If non-null, these are language-specific helper functions for unsave_expr_now. If present, LANG_UNSAVE is called before its @@ -5387,6 +5386,8 @@ build_common_tree_nodes (signed_char) error_mark_node = make_node (ERROR_MARK); TREE_TYPE (error_mark_node) = error_mark_node; + initialize_sizetypes (); + /* Define both `signed char' and `unsigned char'. */ signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); @@ -5401,10 +5402,6 @@ build_common_tree_nodes (signed_char) short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); integer_type_node = make_signed_type (INT_TYPE_SIZE); - /* Define an unsigned integer first. make_unsigned_type and make_signed_type - both call set_sizetype for the first type that we create, and we want this - to be large enough to hold the sizes of various types until we switch to - the real sizetype. */ unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); @@ -5424,47 +5421,13 @@ build_common_tree_nodes (signed_char) unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); } -/* For type TYPE, fill in the proper type for TYPE_SIZE and TYPE_SIZE_UNIT. */ - -static void -fix_sizetype (type) - tree type; -{ - TREE_TYPE (TYPE_SIZE (type)) = bitsizetype; - TREE_TYPE (TYPE_SIZE_UNIT (type)) = sizetype; -} - /* Call this function after calling build_common_tree_nodes and set_sizetype. - It will fix the previously made nodes to have proper references to - sizetype, and it will create several other common tree nodes. */ + It will create several other common tree nodes. */ void build_common_tree_nodes_2 (short_double) int short_double; { - fix_sizetype (signed_char_type_node); - fix_sizetype (unsigned_char_type_node); - fix_sizetype (char_type_node); - fix_sizetype (short_integer_type_node); - fix_sizetype (short_unsigned_type_node); - fix_sizetype (integer_type_node); - fix_sizetype (unsigned_type_node); - fix_sizetype (long_unsigned_type_node); - fix_sizetype (long_integer_type_node); - fix_sizetype (long_long_integer_type_node); - fix_sizetype (long_long_unsigned_type_node); - - fix_sizetype (intQI_type_node); - fix_sizetype (intHI_type_node); - fix_sizetype (intSI_type_node); - fix_sizetype (intDI_type_node); - fix_sizetype (intTI_type_node); - fix_sizetype (unsigned_intQI_type_node); - fix_sizetype (unsigned_intHI_type_node); - fix_sizetype (unsigned_intSI_type_node); - fix_sizetype (unsigned_intDI_type_node); - fix_sizetype (unsigned_intTI_type_node); - integer_zero_node = build_int_2 (0, 0); TREE_TYPE (integer_zero_node) = integer_type_node; integer_one_node = build_int_2 (1, 0); @@ -874,6 +874,11 @@ struct tree_block its size. */ #define TYPE_NO_FORCE_BLK(NODE) (TYPE_CHECK (NODE)->type.no_force_blk_flag) +/* In an INTEGER_TYPE, it means the type represents a size. We use this + both for validity checking and to permit optimziations that are unsafe + for other types. */ +#define TYPE_IS_SIZETYPE(NODE) (TYPE_CHECK (NODE)->type.no_force_blk_flag) + /* Nonzero in a type considered volatile as a whole. */ #define TYPE_VOLATILE(NODE) ((NODE)->common.volatile_flag) @@ -1657,6 +1662,7 @@ extern tree build_expr_wfl PARAMS ((tree, const char *, int, int)); extern tree make_signed_type PARAMS ((int)); extern tree make_unsigned_type PARAMS ((int)); +extern void initialize_sizetypes PARAMS ((void)); extern void set_sizetype PARAMS ((tree)); extern tree signed_or_unsigned_type PARAMS ((int, tree)); extern void fixup_unsigned_type PARAMS ((tree)); @@ -1784,12 +1790,40 @@ extern tree convert PARAMS ((tree, tree)); extern unsigned int expr_align PARAMS ((tree)); extern tree size_in_bytes PARAMS ((tree)); extern HOST_WIDE_INT int_size_in_bytes PARAMS ((tree)); + +/* Define data structures, macros, and functions for handling sizes + and the various types used to represent sizes. */ + +enum size_type_kind +{ + SIZETYPE, /* Normal representation of sizes in bytes. */ + SSIZETYPE, /* Signed representation of sizes in bytes. */ + USIZETYPE, /* Unsigned representation of sizes in bytes. */ + BITSIZETYPE, /* Normal representation of sizes in bits. */ + SBITSIZETYPE, /* Signed representation of sizes in bits. */ + UBITSIZETYPE, /* Unsifgned representation of sizes in bits. */ + TYPE_KIND_LAST}; + +extern tree sizetype_tab[(int) TYPE_KIND_LAST]; + +#define sizetype sizetype_tab[(int) SIZETYPE] +#define bitsizetype sizetype_tab[(int) BITSIZETYPE] +#define ssizetype sizetype_tab[(int) SSIZETYPE] +#define usizetype sizetype_tab[(int) USIZETYPE] +#define sbitsizetype sizetype_tab[(int) SBITSIZETYPE] +#define ubitsizetype sizetype_tab[(int) UBITSIZETYPE] + extern tree size_binop PARAMS ((enum tree_code, tree, tree)); -extern tree ssize_binop PARAMS ((enum tree_code, tree, tree)); -extern tree size_int_wide PARAMS ((HOST_WIDE_INT, int)); +extern tree size_diffop PARAMS ((tree, tree)); +extern tree size_int_wide PARAMS ((HOST_WIDE_INT, + enum size_type_kind)); +extern tree size_int_type_wide PARAMS ((HOST_WIDE_INT, tree)); -#define size_int(L) size_int_wide ((HOST_WIDE_INT) (L), 0) -#define bitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), 1) +#define size_int_type(L, T) size_int_type_wide ((HOST_WIDE_INT) (L), T) +#define size_int(L) size_int_wide ((HOST_WIDE_INT) (L), SIZETYPE) +#define ssize_int(L) size_int_wide ((HOST_WIDE_INT) (L), SSIZETYPE) +#define bitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), BITSIZETYPE) +#define sbitsize_int(L) size_int_wide ((HOST_WIDE_INT) (L), SBITSIZETYPE) extern tree round_up PARAMS ((tree, int)); extern tree get_pending_sizes PARAMS ((void)); @@ -1802,22 +1836,6 @@ extern void put_pending_sizes PARAMS ((tree)); + (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) \ + (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256)) -struct sizetype_tab -{ - tree xsizetype, xbitsizetype; - tree xssizetype, xusizetype; - tree xsbitsizetype, xubitsizetype; -}; - -extern struct sizetype_tab sizetype_tab; - -#define sizetype sizetype_tab.xsizetype -#define bitsizetype sizetype_tab.xbitsizetype -#define ssizetype sizetype_tab.xssizetype -#define usizetype sizetype_tab.xusizetype -#define sbitsizetype sizetype_tab.xsbitsizetype -#define ubitsizetype sizetype_tab.xubitsizetype - /* If nonzero, an upper limit on alignment of structure fields, in bits. */ extern unsigned int maximum_field_alignment; |