diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2000-05-31 18:37:31 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2000-05-31 14:37:31 -0400 |
commit | 3bdf5ad13852aaa871ab41a6e8f509809c8c104d (patch) | |
tree | b0b7fe92ad1922c85f0e4c70693ee5b33b128261 /gcc/c-common.c | |
parent | 99923eedd0700c7055810224f548f70bcd009267 (diff) | |
download | gcc-3bdf5ad13852aaa871ab41a6e8f509809c8c104d.zip gcc-3bdf5ad13852aaa871ab41a6e8f509809c8c104d.tar.gz gcc-3bdf5ad13852aaa871ab41a6e8f509809c8c104d.tar.bz2 |
Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* Makefile.in (c-decl.o): Depend on rtl.h and expr.h.
* alias.c (struct alias_entry): alias_set is HOST_WIDE_INT.
(REG_BASE_VALUE): Remove unneeded cast to unsigned.
(get_alias_set_entry): ALIAS_SET arg is HOST_WIDE_INT.
(find_base_decl): New function, from c_find_base_decl in c-common.c.
(new_alias_set): Moved from tree.c; return is HOST_WIDE_INT.
(get_alias_set): Likewise.
Major rework to do more things and allow language-specific code
to just handle special-cases.
(record_alias_subset): Args are HOST_WIDE_INT.
(record_component_alias): Local vars are HOST_WIDE_INT.
Don't handle COMPLEX_EXPR.
(get_varargs_alias_set): Moved from builtins.c.
(get_frame_alias_set): New function.
* builtins.c (expand_builtin_return_address): Use frame alias set.
(expand_builtin_setjmp, expand_builtin_longjmp): Use alias set
for setjmp buffer.
(get_memory_rtx): Rework to use set_mem_attributes.
(get_varargs_alias_set): Deleted from here.
* c-common.c (c_apply_type_quals_to_decl): Alias sets now HOST_WIDE_INT.
(c_find_base_decl): Deleted from here.
(c_get_alias_set): Remove many cases and rework to just handle
C-specific cases.
* c-common.h (c_get_alias_set): Returns HOST_WIDE_INT.
* c-decl.c (rtl.h, expr.h): Now included.
(init_decl_processing): Call record_component_aliases on array types.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for all fields that are not bitfields.
* c-typeck.c (common_type): Call record_component_aliases for array.
* caller-save.c (setup_save_areas): Rework register loop for unsigned.
Set all save areas to the frame alias set.
* calls.c (initialie_argument_information): Call set_mem_attributes.
(compute_argument_addresses, expand_call): Likewise.
* explow.c (set_mem_attributes): New function.
(stabilize): Use MEM_COPY_ATTRIBUTES and force_reg.
* expr.c (struct move_by_pieces): Remove {to,from}_{struct,readonly}.
LEN and OFFSET now HOST_WIDE_INT.
(clear_by_pieces): Similar changes.
(move_by_pieces): LEN now HOST_WIDE_INT; don't set deleted fields.
(move_by_pieces_ninsns): Now returns unsigned HOST_WIDE_INT.
(move_by_pieces_1): Don't use deleted fields, use MEM_COPY_ATTRIBUTES.
(clear_by_pieces_1): Likewise.
(emit_push_insn): Call set_mem_attributes.
(expand_expr, case INDIRECT_REF): Likewise.
(expand_expr, case VAR_DECL): Call change_address.
* expr.h (ADD_PARM_SIZE, SUB_PARM_SIZE): Use host_integerp and
tree_low_cst.
(get_varargs_alias_set, get_frame_alias_set): New decls.
(record_base_value, record_alias_subset, lang_get_alias_set): Likewise.
(new_alias_set, set_mem_attributes): Likewse.
* function.c (struct temp_slot): ALIAS_SET is HOST_WIDE_INT.
(assign_stack_temp_for_type): Likewise.
Can split slot even if alias set since can copy.
Set MEM_ALIAS_SET and MEM_SET_IN_STRUCT_P.
(assign_temp): Use host_integerp and tree_low_cst.
(put_var_into_stack): Properly handle SAVE_EXPR.
(put_addressof_into_stack): Likewise.
(assign_parms): Call set_mem_attributes.
Delete #if 0 code.
(fix_lexical_address): Put reference to chain into frame alias set.
(expand_function_start): Call set_mem_attributes.
* integrate.c (expand_inline_function): Likewise.
* recog.c (adj_offsettable_operand): Use MEM_COPY_ATTRIBUTES.
* regmove.c (try_apply_stack_adjustment): Likewise.
* reload.c (push_reload, make_memloc): Likewise.
* reload1.c (alter_reg): Make alias sets for spilled pseudos.
* rtl.def (MEM): Update comment.
* rtl.h (MEM_ALIAS_SET): Now uses XCWINT.
(move_by_pieces): Change length to HOST_WIDE_INT.
(record_base_value, record_alias_subset): Delete from here.
* stmt.c (expand_decl): Call set_mem_attributes.
* stor-layout.c (finish_record_layout): Call record_component_aliases.i
* toplev.c (compile_file): Call init_alias_once earlier.
* tree.c (lang_get_alias_set, get_alias_set, new_alias_set): Deleted
from here: now in alias.c.
* tree.h (struct tree_type): alias_set is HOST_WIDE_INT.
(struct tree_decl): Likewise.
(get_alias_set, new_alias_set, lang_get_alias_set): Deleted from here.
* varasm.c (make_function_rtl, make_decl_rtl): Call set_mem_attributes.
(output_constant_def, force_const_mem): Likewise.
* cp/Makefile.in (decl.o): Include ../expr.h.
* cp/decl.c (expr.h): Include.
(init_decl_processing): Call record_component_aliases for arrays.
(grokdeclarator): Likewise.
Set TREE_ADDRESSABLE for fields that aren't bitfields.
* cp/tree.c (build_cplus_array_type_1): Call record_component_aliases.
From-SVN: r34305
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 184 |
1 files changed, 30 insertions, 154 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 6989d40..5cc34c9 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -156,7 +156,6 @@ static void init_attributes PARAMS ((void)); static void record_function_format PARAMS ((tree, tree, enum format_type, int, int)); static void record_international_format PARAMS ((tree, tree, int)); -static tree c_find_base_decl PARAMS ((tree)); static int default_valid_lang_attribute PARAMS ((tree, tree, tree, tree)); /* Keep a stack of if statements. We record the number of compound @@ -3245,10 +3244,10 @@ c_apply_type_quals_to_decl (type_quals, decl) alias set for the type pointed to by the type of the decl. */ - int pointed_to_alias_set + HOST_WIDE_INT pointed_to_alias_set = get_alias_set (TREE_TYPE (TREE_TYPE (decl))); - if (!pointed_to_alias_set) + if (pointed_to_alias_set == 0) /* It's not legal to make a subset of alias set zero. */ ; else @@ -3261,91 +3260,16 @@ c_apply_type_quals_to_decl (type_quals, decl) } } -/* T is an expression with pointer type. Find the DECL on which this - expression is based. (For example, in `a[i]' this would be `a'.) - If there is no such DECL, or a unique decl cannot be determined, - NULL_TREE is retured. */ - -static tree -c_find_base_decl (t) - tree t; -{ - int i; - tree decl; - - if (t == NULL_TREE || t == error_mark_node) - return NULL_TREE; - - if (!POINTER_TYPE_P (TREE_TYPE (t))) - return NULL_TREE; - - decl = NULL_TREE; - - if (TREE_CODE (t) == FIELD_DECL - || TREE_CODE (t) == PARM_DECL - || TREE_CODE (t) == VAR_DECL) - /* Aha, we found a pointer-typed declaration. */ - return t; - - /* It would be nice to deal with COMPONENT_REFs here. If we could - tell that `a' and `b' were the same, then `a->f' and `b->f' are - also the same. */ - - /* Handle general expressions. */ - switch (TREE_CODE_CLASS (TREE_CODE (t))) - { - case '1': - case '2': - case '3': - for (i = TREE_CODE_LENGTH (TREE_CODE (t)); --i >= 0;) - { - tree d = c_find_base_decl (TREE_OPERAND (t, i)); - if (d) - { - if (!decl) - decl = d; - else if (d && d != decl) - /* Two different declarations. That's confusing; let's - just assume we don't know what's going on. */ - decl = NULL_TREE; - } - } - break; - - default: - break; - } - - return decl; -} /* Return the typed-based alias set for T, which may be an expression - or a type. */ + or a type. Return -1 if we don't do anything special. */ -int +HOST_WIDE_INT c_get_alias_set (t) tree t; { - tree type; tree u; - if (t == error_mark_node) - return 0; - - /* For a bit field reference that's not to a specific field, - all we can say is the aliasing information for the underlying object. */ - if (TREE_CODE (t) == BIT_FIELD_REF) - t = TREE_OPERAND (t, 0); - - /* If this is a type, use it, otherwise get the type of the expression. - If the type is an error type, say this may alias anything. */ - type = TYPE_P (t) ? t : TREE_TYPE (t); - if (type == error_mark_node) - return 0; - - /* Deal with special cases first; for certain kinds of references - we're interested in more than just the type. */ - /* Permit type-punning when accessing a union, provided the access is directly through the union. For example, this code does not permit taking the address of a union member and then storing @@ -3359,81 +3283,37 @@ c_get_alias_set (t) && TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE) return 0; - if (TREE_CODE (t) == INDIRECT_REF) - { - /* Check for accesses through restrict-qualified pointers. */ - tree op = TREE_OPERAND (t, 0); - tree decl = c_find_base_decl (op); - - if (decl && DECL_POINTER_ALIAS_SET_KNOWN_P (decl)) - /* We use the alias set indicated in the declaration. */ - return DECL_POINTER_ALIAS_SET (decl); - - /* If this is a char *, the ANSI C standard says it can alias - anything. */ - if (TREE_CODE (TREE_TYPE (op)) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (op)) - == TYPE_PRECISION (char_type_node))) - return 0; - } + /* If this is a char *, the ANSI C standard says it can alias + anything. */ + else if (TREE_CODE (t) == INDIRECT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == INTEGER_TYPE + && (TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (t, 0))) + == TYPE_PRECISION (char_type_node))) + return 0; - /* From here on, only the type matters. */ - - if (TREE_CODE (t) == COMPONENT_REF - && DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1))) - /* Since build_modify_expr calls get_unwidened for stores to - component references, the type of a bit field can be changed - from (say) `unsigned int : 16' to `unsigned short' or from - `enum E : 16' to `short'. We want the real type of the - bit-field in this case, not some the integral equivalent. */ - type = DECL_BIT_FIELD_TYPE (TREE_OPERAND (t, 1)); - - if (TYPE_ALIAS_SET_KNOWN_P (type)) - /* If we've already calculated the value, just return it. */ - return TYPE_ALIAS_SET (type); - else if (TYPE_MAIN_VARIANT (type) != type) - /* The C standard specifically allows aliasing between - cv-qualified variants of types. */ - TYPE_ALIAS_SET (type) = c_get_alias_set (TYPE_MAIN_VARIANT (type)); - else if (TREE_CODE (type) == INTEGER_TYPE) - { - tree signed_variant; + /* That's all the expressions we handle specially. */ + if (! TYPE_P (t)) + return -1; + if (TREE_CODE (t) == INTEGER_TYPE) + { /* The C standard specifically allows aliasing between signed and unsigned variants of the same type. We treat the signed variant as canonical. */ - signed_variant = signed_type (type); + tree signed_variant = signed_type (t); - if (signed_variant != type) - TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant); - else if (signed_variant == signed_char_type_node) + if (signed_variant == signed_char_type_node) /* The C standard guarantess that any object may be accessed via an lvalue that has character type. We don't have to check for unsigned_char_type_node or char_type_node because we are specifically looking at the signed variant. */ - TYPE_ALIAS_SET (type) = 0; + return 0; + else if (signed_variant != t) + return get_alias_set (signed_variant); } - else if (TREE_CODE (type) == ARRAY_TYPE) - /* Anything that can alias one of the array elements can alias - the entire array as well. */ - TYPE_ALIAS_SET (type) = c_get_alias_set (TREE_TYPE (type)); - else if (TREE_CODE (type) == FUNCTION_TYPE) - /* There are no objects of FUNCTION_TYPE, so there's no point in - using up an alias set for them. (There are, of course, - pointers and references to functions, but that's - different.) */ - TYPE_ALIAS_SET (type) = 0; - else if (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - /* If TYPE is a struct or union type then we're reading or - writing an entire struct. Thus, we don't know anything about - aliasing. (In theory, such an access can only alias objects - whose type is the same as one of the fields, recursively, but - we don't yet make any use of that information.) */ - TYPE_ALIAS_SET (type) = 0; - else if (POINTER_TYPE_P (type)) + else if (POINTER_TYPE_P (t)) { - tree t; + tree t1; /* Unfortunately, there is no canonical form of a pointer type. In particular, if we have `typedef int I', then `int *', and @@ -3458,19 +3338,14 @@ c_get_alias_set (t) can dereference IPP and CIPP. So, we ignore cv-qualifiers on the pointed-to types. This issue has been reported to the C++ committee. */ - t = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - t = ((TREE_CODE (type) == POINTER_TYPE) - ? build_pointer_type (t) : build_reference_type (t)); - if (t != type) - TYPE_ALIAS_SET (type) = c_get_alias_set (t); + t1 = TYPE_MAIN_VARIANT (TREE_TYPE (t)); + t1 = ((TREE_CODE (t) == POINTER_TYPE) + ? build_pointer_type (t1) : build_reference_type (t1)); + if (t1 != t) + return get_alias_set (t1); } - if (! TYPE_ALIAS_SET_KNOWN_P (type)) - /* TYPE is something we haven't seen before. Put it in a new - alias set. */ - TYPE_ALIAS_SET (type) = new_alias_set (); - - return TYPE_ALIAS_SET (type); + return -1; } /* Build tree nodes and builtin functions common to both C and C++ language @@ -3480,6 +3355,7 @@ c_get_alias_set (t) NO_BUILTINS and NO_NONANSI_BUILTINS contain the respective values of the language frontend flags flag_no_builtin and flag_no_nonansi_builtin. */ + void c_common_nodes_and_builtins (cplus_mode, no_builtins, no_nonansi_builtins) int cplus_mode, no_builtins, no_nonansi_builtins; |