diff options
author | Richard Kenner <kenner@vlsi1.ultra.nyu.edu> | 2000-12-30 13:10:51 +0000 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 2000-12-30 08:10:51 -0500 |
commit | 1da68f560dd41ef12f15138fb1b1aff06067f4b7 (patch) | |
tree | 23f23dc6bdc5d0a2afd4675766fb43eb2ef34bc3 /gcc/alias.c | |
parent | 2e9ab75de463a34abe8d5d0749999195d6e62942 (diff) | |
download | gcc-1da68f560dd41ef12f15138fb1b1aff06067f4b7.zip gcc-1da68f560dd41ef12f15138fb1b1aff06067f4b7.tar.gz gcc-1da68f560dd41ef12f15138fb1b1aff06067f4b7.tar.bz2 |
alias.c (alias_sets_conflict_p): New function.
* alias.c (alias_sets_conflict_p): New function.
(mems_in_disjoint_alias_sets_p): Use it.
(readonly_fields_p): Moved from expr.c; check for record type.
(objects_must_conflict_p): New function.
* calls.c (expand_call): Use assign_temp as much as possible, use
readonly variant if assigned once, and don't set memory attributes.
(emit_library_call_value_1, store_one_arg): Likewise.
* integrate.c (expand_inline_function): Likewise.
* stmt.c (expand_asm_operands, expand_return): Likewise.
* expr.c (copy_blkmode_from_reg, store_constructor): Likewise.
(store_field, save_noncopied_parts, expand_expr): Likewise.
(expand_expr_unaligned): Likewise.
(readonly_fields_p): Moved to alias.c.
(safe_from_p): Rework handling of SAVE_EXPR.
MEMs ony conflict if alias sets conflict; likewise for INDIRECT_REF.
* function.c (struct temp_slot): Delete field ALIAS_SET; add TYPE.
(assign_stack_for_temp): Use objects_must_confict_p.
Set all memory attributes from type, if specified.
(mark_temp_slot): Mark TYPE field.
* tree.h (alias_sets_conflict_p, readonly_fields_p): New decls.
(objects_must_conflict_p): Likewise.
* stmt.c (expand_decl): Don't use assign_stack_temp in error case.
(add_case_node): No need to copy nodes anymore.
From-SVN: r38559
Diffstat (limited to 'gcc/alias.c')
-rw-r--r-- | gcc/alias.c | 111 |
1 files changed, 86 insertions, 25 deletions
diff --git a/gcc/alias.c b/gcc/alias.c index d11d1b3..41cf596 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -211,8 +211,6 @@ mems_in_disjoint_alias_sets_p (mem1, mem2) rtx mem1; rtx mem2; { - alias_set_entry ase; - #ifdef ENABLE_CHECKING /* Perform a basic sanity check. Namely, that there are no alias sets if we're not using strict aliasing. This helps to catch bugs @@ -226,49 +224,112 @@ mems_in_disjoint_alias_sets_p (mem1, mem2) abort (); #endif - /* If have no alias set information for one of the MEMs, we have to assume - it can alias anything. */ - if (MEM_ALIAS_SET (mem1) == 0 || MEM_ALIAS_SET (mem2) == 0) - return 0; + return ! alias_sets_conflict_p (MEM_ALIAS_SET (mem1), MEM_ALIAS_SET (mem2)); +} - /* If the two alias sets are the same, they may alias. */ - if (MEM_ALIAS_SET (mem1) == MEM_ALIAS_SET (mem2)) - return 0; +/* Insert the NODE into the splay tree given by DATA. Used by + record_alias_subset via splay_tree_foreach. */ + +static int +insert_subset_children (node, data) + splay_tree_node node; + void *data; +{ + splay_tree_insert ((splay_tree) data, node->key, node->value); + + return 0; +} + +/* Return 1 if the two specified alias sets may conflict. */ + +int +alias_sets_conflict_p (set1, set2) + HOST_WIDE_INT set1, set2; +{ + alias_set_entry ase; + + /* If have no alias set information for one of the operands, we have + to assume it can alias anything. */ + if (set1 == 0 || set2 == 0 + /* If the two alias sets are the same, they may alias. */ + || set1 == set2) + return 1; /* See if the first alias set is a subset of the second. */ - ase = get_alias_set_entry (MEM_ALIAS_SET (mem1)); + ase = get_alias_set_entry (set1); if (ase != 0 && (ase->has_zero_child || splay_tree_lookup (ase->children, - (splay_tree_key) MEM_ALIAS_SET (mem2)))) - return 0; + (splay_tree_key) set2))) + return 1; /* Now do the same, but with the alias sets reversed. */ - ase = get_alias_set_entry (MEM_ALIAS_SET (mem2)); + ase = get_alias_set_entry (set2); if (ase != 0 && (ase->has_zero_child || splay_tree_lookup (ase->children, - (splay_tree_key) MEM_ALIAS_SET (mem1)))) - return 0; + (splay_tree_key) set1))) + return 1; - /* The two MEMs are in distinct alias sets, and neither one is the + /* The two alias sets are distinct and neither one is the child of the other. Therefore, they cannot alias. */ - return 1; + return 0; } + +/* Return 1 if TYPE is a RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE and has + has any readonly fields. If any of the fields have types that + contain readonly fields, return true as well. */ -/* Insert the NODE into the splay tree given by DATA. Used by - record_alias_subset via splay_tree_foreach. */ - -static int -insert_subset_children (node, data) - splay_tree_node node; - void *data; +int +readonly_fields_p (type) + tree type; { - splay_tree_insert ((splay_tree) data, node->key, node->value); + tree field; + + if (TREE_CODE (type) != RECORD_TYPE && TREE_CODE (type) != UNION_TYPE + && TREE_CODE (type) != QUAL_UNION_TYPE) + return 0; + + for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field)) + if (TREE_CODE (field) == FIELD_DECL + && (TREE_READONLY (field) + || readonly_fields_p (TREE_TYPE (field)))) + return 1; return 0; } +/* Return 1 if any MEM object of type T1 will always conflict (using the + dependency routines in this file) with any MEM object of type T2. + This is used when allocating temporary storage. If T1 and/or T2 are + NULL_TREE, it means we know nothing about the storage. */ + +int +objects_must_conflict_p (t1, t2) + tree t1, t2; +{ + /* If they are the same type, they must conflict. */ + if (t1 == t2 + /* Likewise if both are volatile. */ + || (t1 != 0 && TYPE_VOLATILE (t1) && t2 != 0 && TYPE_VOLATILE (t2))) + return 1; + + /* We now know they are different types. If one or both has readonly fields + or if one is readonly and the other not, they may not conflict. + Likewise if one is aggregate and the other is scalar. */ + if ((t1 != 0 && readonly_fields_p (t1)) + || (t2 != 0 && readonly_fields_p (t2)) + || ((t1 != 0 && TYPE_READONLY (t1)) + != (t2 != 0 && TYPE_READONLY (t2))) + || ((t1 != 0 && AGGREGATE_TYPE_P (t1)) + != (t2 != 0 && AGGREGATE_TYPE_P (t2)))) + return 0; + + /* Otherwise they conflict only if the alias sets conflict. */ + return alias_sets_conflict_p (t1 ? get_alias_set (t1) : 0, + t2 ? get_alias_set (t2) : 0); +} + /* 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, |