aboutsummaryrefslogtreecommitdiff
path: root/gcc/alias.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2009-07-14 09:59:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2009-07-14 09:59:18 +0000
commit55b34b5fd1ea3e4a1c7ee30e3a98d058892f5642 (patch)
tree9a0cf325e4020743f8ce27cb07e9a9ab48e57513 /gcc/alias.c
parent1700c2e7c94fa142927b940cd3ec1ba9af3add05 (diff)
downloadgcc-55b34b5fd1ea3e4a1c7ee30e3a98d058892f5642.zip
gcc-55b34b5fd1ea3e4a1c7ee30e3a98d058892f5642.tar.gz
gcc-55b34b5fd1ea3e4a1c7ee30e3a98d058892f5642.tar.bz2
tree-ssa-alias.h (refs_may_alias_p_1): Declare.
2009-07-14 Richard Guenther <rguenther@suse.de> Andrey Belevantsev <abel@ispras.ru> * tree-ssa-alias.h (refs_may_alias_p_1): Declare. (pt_solution_set): Likewise. * tree-ssa-alias.c (refs_may_alias_p_1): Export. * tree-ssa-structalias.c (pt_solution_set): New function. * final.c (rest_of_clean_state): Free SSA data structures. * print-rtl.c (print_decl_name): Remove. (print_mem_expr): Implement in terms of print_generic_expr. * alias.c (ao_ref_from_mem): New function. (rtx_refs_may_alias_p): Likewise. (true_dependence): Query alias-export info. (canon_true_dependence): Likewise. (write_dependence_p): Likewise. * tree-dfa.c (get_ref_base_and_extent): For void types leave size unknown. * emit-rtl.c (component_ref_for_mem_expr): Remove. (mem_expr_equal_p): Use operand_equal_p. (set_mem_attributes_minus_bitpos): Do not use component_ref_for_mem_expr. * cfgexpand.c (add_partitioned_vars_to_ptset): New function. (update_alias_info_with_stack_vars): Likewise. (partition_stack_vars): Call update_alias_info_with_stack_vars. * tree-ssa.c (delete_tree_ssa): Do not release SSA names explicitly nor clear stmt operands. Free the decl-to-pointer map. * tree-optimize.c (execute_free_datastructures): Do not free SSA data structures here. * tree-flow.h (struct gimple_df): Add decls_to_pointers member. * Makefile.in (emit-rtl.o): Add pointer-set.h dependency. (alias.o): Add tree-ssa-alias.h, pointer-set.h and $(TREE_FLOW_H) dependencies. (print-rtl.o): Add $(DIAGNOSTIC_H) dependency. Co-Authored-By: Andrey Belevantsev <abel@ispras.ru> From-SVN: r149624
Diffstat (limited to 'gcc/alias.c')
-rw-r--r--gcc/alias.c114
1 files changed, 108 insertions, 6 deletions
diff --git a/gcc/alias.c b/gcc/alias.c
index 2486001..e9cc2d8 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -46,6 +46,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "ipa-type-escape.h"
#include "df.h"
+#include "tree-ssa-alias.h"
+#include "pointer-set.h"
+#include "tree-flow.h"
/* The aliasing API provided here solves related but different problems:
@@ -249,6 +252,98 @@ DEF_VEC_ALLOC_P(alias_set_entry,gc);
/* The splay-tree used to store the various alias set entries. */
static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
+/* Build a decomposed reference object for querying the alias-oracle
+ from the MEM rtx and store it in *REF.
+ Returns false if MEM is not suitable for the alias-oracle. */
+
+static bool
+ao_ref_from_mem (ao_ref *ref, const_rtx mem)
+{
+ tree expr = MEM_EXPR (mem);
+ tree base;
+
+ if (!expr)
+ return false;
+
+ ao_ref_init (ref, expr);
+
+ /* Get the base of the reference and see if we have to reject or
+ adjust it. */
+ base = ao_ref_base (ref);
+ if (base == NULL_TREE)
+ return false;
+
+ /* If this is a pointer dereference of a non-SSA_NAME punt.
+ ??? We could replace it with a pointer to anything. */
+ if (INDIRECT_REF_P (base)
+ && TREE_CODE (TREE_OPERAND (base, 0)) != SSA_NAME)
+ return false;
+
+ /* If this is a reference based on a partitioned decl replace the
+ base with an INDIRECT_REF of the pointer representative we
+ created during stack slot partitioning. */
+ if (TREE_CODE (base) == VAR_DECL
+ && ! TREE_STATIC (base)
+ && cfun->gimple_df->decls_to_pointers != NULL)
+ {
+ void *namep;
+ namep = pointer_map_contains (cfun->gimple_df->decls_to_pointers, base);
+ if (namep)
+ {
+ ref->base_alias_set = get_alias_set (base);
+ ref->base = build1 (INDIRECT_REF, TREE_TYPE (base), *(tree *)namep);
+ }
+ }
+
+ ref->ref_alias_set = MEM_ALIAS_SET (mem);
+
+ /* For NULL MEM_OFFSET the MEM_EXPR may have been stripped arbitrarily
+ without recording offset or extent adjustments properly. */
+ if (MEM_OFFSET (mem) == NULL_RTX)
+ {
+ ref->offset = 0;
+ ref->max_size = -1;
+ }
+ else
+ {
+ ref->offset += INTVAL (MEM_OFFSET (mem)) * BITS_PER_UNIT;
+ }
+
+ /* NULL MEM_SIZE should not really happen with a non-NULL MEM_EXPR,
+ but just play safe here. The size may have been adjusted together
+ with the offset, so we need to take it if it is set and not rely
+ on MEM_EXPR here (which has the size determining parts potentially
+ stripped anyway). We lose precision for max_size which is only
+ available from the remaining MEM_EXPR. */
+ if (MEM_SIZE (mem) == NULL_RTX)
+ {
+ ref->size = -1;
+ ref->max_size = -1;
+ }
+ else
+ {
+ ref->size = INTVAL (MEM_SIZE (mem)) * BITS_PER_UNIT;
+ }
+
+ return true;
+}
+
+/* Query the alias-oracle on whether the two memory rtx X and MEM may
+ alias. If TBAA_P is set also apply TBAA. Returns true if the
+ two rtxen may alias, false otherwise. */
+
+static bool
+rtx_refs_may_alias_p (const_rtx x, const_rtx mem, bool tbaa_p)
+{
+ ao_ref ref1, ref2;
+
+ if (!ao_ref_from_mem (&ref1, x)
+ || !ao_ref_from_mem (&ref2, mem))
+ return true;
+
+ return refs_may_alias_p_1 (&ref1, &ref2, tbaa_p);
+}
+
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */
@@ -2191,8 +2286,10 @@ true_dependence (const_rtx mem, enum machine_mode mem_mode, const_rtx x,
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1;
- return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
- varies);
+ if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, true);
}
/* Canonical true dependence: X is read after store in MEM takes place.
@@ -2255,8 +2352,10 @@ canon_true_dependence (const_rtx mem, enum machine_mode mem_mode, rtx mem_addr,
if (mem_mode == BLKmode || GET_MODE (x) == BLKmode)
return 1;
- return ! fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
- varies);
+ if (fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr, varies))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, true);
}
/* Returns nonzero if a write to X might alias a previous read from
@@ -2316,8 +2415,11 @@ write_dependence_p (const_rtx mem, const_rtx x, int writep)
= fixed_scalar_and_varying_struct_p (mem, x, mem_addr, x_addr,
rtx_addr_varies_p);
- return (!(fixed_scalar == mem && !aliases_everything_p (x))
- && !(fixed_scalar == x && !aliases_everything_p (mem)));
+ if ((fixed_scalar == mem && !aliases_everything_p (x))
+ || (fixed_scalar == x && !aliases_everything_p (mem)))
+ return 0;
+
+ return rtx_refs_may_alias_p (x, mem, false);
}
/* Anti dependence: X is written after read in MEM takes place. */