diff options
author | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-25 15:14:41 +0000 |
---|---|---|
committer | mmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-06-25 15:14:41 +0000 |
commit | b5ba9f3a669e68503666852be6e3158f03526733 (patch) | |
tree | af8828e1df0f3e051eb29c58c7d958cd177e474d /gcc/c-common.c | |
parent | a85413a6ac28d432734c514cd140ee039daad06b (diff) | |
download | gcc-b5ba9f3a669e68503666852be6e3158f03526733.tar.gz |
* invoke.texi (-fstrict-aliasing): Document.
* rtl.texi (MEM_ALIAS_SET): Document.
* flags.h (flag_strict_aliasing): Declare.
* toplev.c (flag_strict_aliasing): Define.
(f_options): Add -strict-aliasing.
(main): Set flag_strict_aliasing if -O2 or higher.
* tree.h (tree_type): Add alias_set field.
(TYPE_ALIAS_SET): New macro.
(TYPE_ALIAS_SET_KNOWN_P): Likewise.
(get_alias_set): Declare.
* tree.c (lang_get_alias_set): Define.
(make_node): Initialize TYPE_ALIAS_SET.
(get_alias_set): New function.
* print-tree.c (print_node): Dump the alias set for a type.
* c-tree.h (c_get_alias_set): Declare.
* c-common.c (c_get_alias_set): New function.
* c-decl.c (init_decl_processing): Set lang_get_alias_set.
* expr.c (protect_from_queue): Propogage alias sets.
(expand_assignment): Calculate alias set for new MEMs.
(expand_expr): Likewise.
* function.c (put_var_into_stack): Likewise.
(put_reg_into_stack): Likewise.
(gen_mem_addressof): Likewise.
(assign_parms): Likewise.
* stmt.c (expand_decl): Likewise.
* varasm.c (make_decl_rtl): Eliminate redundant clearing of
DECL_RTL. Calculate alias set for new MEMs.
* rtl.def (REG): Add dummy operand.
(MEM): Add extra operand to store the MEM_ALIAS_SET.
* rtl.h (MEM_ALIAS_SET): New macro.
(gen_rtx_MEM): Declare.
* emit-rtl.c (gen_rtx_MEM): New function.
* gengenrtl.c (sepcial_rtx): Make MEMs special.
* alias.c (CHECK_ALIAS_SETS_FOR_CONSISTENCY): New macro.
(DIFFERENT_ALIAS_SETS_P): Likewise.
(canon_rtx): Propogate the alias set to the new MEM.
(true_dependence): Check the alias sets.
(anti_dependence): Likewise.
(output_dependence): Likewise.
* explow.c (stabilize): Progoate alias sets.
* integrate.c (copy_rtx_and_substitute): Likewise.
* final.c (alter_subreg): Make sure not to leave MEM_IN_STRUCT_P
in an unpredictable state. Propogate alias sets.
* reload1.c (reload): Clear MEM_ALIAS_SET for new MEMs about which
we have no alias information.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@20719 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c-common.c')
-rw-r--r-- | gcc/c-common.c | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/gcc/c-common.c b/gcc/c-common.c index 9a8d0731bdd..245fedb97be 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -2880,3 +2880,90 @@ c_build_type_variant (type, constp, volatilep) TYPE_DOMAIN (type)); return build_type_variant (type, constp, volatilep); } + +/* Return the typed-based alias set for T, which may be an expression + or a type. */ + +int +c_get_alias_set (t) + tree t; +{ + static int next_set = 0; + tree type; + + if (t == error_mark_node) + return 0; + + type = (TREE_CODE_CLASS (TREE_CODE (t)) == 't') + ? t : TREE_TYPE (t); + + if (type == error_mark_node) + return 0; + + if (TYPE_ALIAS_SET_KNOWN_P (type)) + /* If we've already calculated the value, just return it. */ + return TYPE_ALIAS_SET (type); + + if (TREE_CODE (t) == BIT_FIELD_REF) + /* Perhaps reads and writes to this piece of data alias fields + neighboring the bitfield. Perhaps that's impossible. For now, + let's just assume that bitfields can alias everything, which is + the conservative assumption. */ + return 0; + if (TREE_CODE (t) == COMPONENT_REF + && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == UNION_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 through it. Even the type-punning allowed here is a + GCC extension, albeit a common and useful one; the C standard + says that such accesses have implementation-defined behavior. */ + return 0; + 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)); + return TYPE_ALIAS_SET (type); + } + else if (TREE_CODE (type) == INTEGER_TYPE) + { + tree signed_variant; + + /* 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); + + if (signed_variant != type) + { + TYPE_ALIAS_SET (type) = c_get_alias_set (signed_variant); + return TYPE_ALIAS_SET (type); + } + else 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 TYPE_ALIAS_SET (type); + } + } + 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; + return TYPE_ALIAS_SET (type); + } + + /* TYPE is something we haven't seen before. Put it in a new alias + set. */ + TYPE_ALIAS_SET (type) = ++next_set; + return TYPE_ALIAS_SET (type); +} |