aboutsummaryrefslogtreecommitdiff
path: root/gcc/c-common.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>2000-05-31 18:37:31 +0000
committerRichard Kenner <kenner@gcc.gnu.org>2000-05-31 14:37:31 -0400
commit3bdf5ad13852aaa871ab41a6e8f509809c8c104d (patch)
treeb0b7fe92ad1922c85f0e4c70693ee5b33b128261 /gcc/c-common.c
parent99923eedd0700c7055810224f548f70bcd009267 (diff)
downloadgcc-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.c184
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;