aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-sccvn.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2015-09-29 13:04:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2015-09-29 13:04:18 +0000
commite7cbc0960edec3d2ce1edf00b6c536a6f2faca33 (patch)
tree5013d6531f4e348668278ebcc16763017f224884 /gcc/tree-ssa-sccvn.c
parenteada851cc9fb2822989d3ef81bb5b4b08dcc81a7 (diff)
downloadgcc-e7cbc0960edec3d2ce1edf00b6c536a6f2faca33.zip
gcc-e7cbc0960edec3d2ce1edf00b6c536a6f2faca33.tar.gz
gcc-e7cbc0960edec3d2ce1edf00b6c536a6f2faca33.tar.bz2
re PR fortran/67170 (PRE can't hoist out a readonly argument)
2015-09-29 Richard Biener <rguenther@suse.de> PR tree-optimization/67170 * tree-ssa-alias.h (get_continuation_for_phi): Adjust the translate function pointer parameter to get the bool whether to disambiguate only by reference. (walk_non_aliased_vuses): Likewise. * tree-ssa-alias.c (maybe_skip_until): Adjust. (get_continuation_for_phi_1): Likewise. (get_continuation_for_phi): Likewise. (walk_non_aliased_vuses): Likewise. * tree-ssa-sccvn.c (const_parms): New bitmap. (vn_reference_lookup_3): Adjust for interface change. Disambiguate parameters pointing to readonly memory. (free_scc_vn): Free const_parms. (run_scc_vn): Initialize const_parms from a fn spec attribute. * gfortran.dg/pr67170.f90: New testcase. From-SVN: r228244
Diffstat (limited to 'gcc/tree-ssa-sccvn.c')
-rw-r--r--gcc/tree-ssa-sccvn.c59
1 files changed, 52 insertions, 7 deletions
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index ce79842..5b06d29 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -120,6 +120,7 @@ along with GCC; see the file COPYING3. If not see
static tree *last_vuse_ptr;
static vn_lookup_kind vn_walk_kind;
static vn_lookup_kind default_vn_walk_kind;
+bitmap const_parms;
/* vn_nary_op hashtable helpers. */
@@ -1656,21 +1657,35 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse,
/* Callback for walk_non_aliased_vuses. Tries to perform a lookup
from the statement defining VUSE and if not successful tries to
translate *REFP and VR_ through an aggregate copy at the definition
- of VUSE. */
+ of VUSE. If *DISAMBIGUATE_ONLY is true then do not perform translation
+ of *REF and *VR. If only disambiguation was performed then
+ *DISAMBIGUATE_ONLY is set to true. */
static void *
vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
- bool disambiguate_only)
+ bool *disambiguate_only)
{
vn_reference_t vr = (vn_reference_t)vr_;
gimple *def_stmt = SSA_NAME_DEF_STMT (vuse);
- tree base;
+ tree base = ao_ref_base (ref);
HOST_WIDE_INT offset, maxsize;
static vec<vn_reference_op_s>
lhs_ops = vNULL;
ao_ref lhs_ref;
bool lhs_ref_ok = false;
+ /* If the reference is based on a parameter that was determined as
+ pointing to readonly memory it doesn't change. */
+ if (TREE_CODE (base) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME
+ && SSA_NAME_IS_DEFAULT_DEF (TREE_OPERAND (base, 0))
+ && bitmap_bit_p (const_parms,
+ SSA_NAME_VERSION (TREE_OPERAND (base, 0))))
+ {
+ *disambiguate_only = true;
+ return NULL;
+ }
+
/* First try to disambiguate after value-replacing in the definitions LHS. */
if (is_gimple_assign (def_stmt))
{
@@ -1687,7 +1702,10 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
TREE_TYPE (lhs), lhs_ops);
if (lhs_ref_ok
&& !refs_may_alias_p_1 (ref, &lhs_ref, true))
- return NULL;
+ {
+ *disambiguate_only = true;
+ return NULL;
+ }
}
else
{
@@ -1723,14 +1741,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
for (unsigned i = 0; i < gimple_call_num_args (def_stmt); ++i)
gimple_call_set_arg (def_stmt, i, oldargs[i]);
if (!res)
- return NULL;
+ {
+ *disambiguate_only = true;
+ return NULL;
+ }
}
}
- if (disambiguate_only)
+ if (*disambiguate_only)
return (void *)-1;
- base = ao_ref_base (ref);
offset = ref->offset;
maxsize = ref->max_size;
@@ -4342,6 +4362,8 @@ free_scc_vn (void)
XDELETE (valid_info);
free_vn_table (optimistic_info);
XDELETE (optimistic_info);
+
+ BITMAP_FREE (const_parms);
}
/* Set *ID according to RESULT. */
@@ -4677,6 +4699,29 @@ run_scc_vn (vn_lookup_kind default_vn_walk_kind_)
init_scc_vn ();
+ /* Collect pointers we know point to readonly memory. */
+ const_parms = BITMAP_ALLOC (NULL);
+ tree fnspec = lookup_attribute ("fn spec",
+ TYPE_ATTRIBUTES (TREE_TYPE (cfun->decl)));
+ if (fnspec)
+ {
+ fnspec = TREE_VALUE (TREE_VALUE (fnspec));
+ i = 1;
+ for (tree arg = DECL_ARGUMENTS (cfun->decl);
+ arg; arg = DECL_CHAIN (arg), ++i)
+ {
+ if (i >= (unsigned) TREE_STRING_LENGTH (fnspec))
+ break;
+ if (TREE_STRING_POINTER (fnspec)[i] == 'R'
+ || TREE_STRING_POINTER (fnspec)[i] == 'r')
+ {
+ tree name = ssa_default_def (cfun, arg);
+ if (name)
+ bitmap_set_bit (const_parms, SSA_NAME_VERSION (name));
+ }
+ }
+ }
+
/* Mark all edges as possibly executable. */
FOR_ALL_BB_FN (bb, cfun)
{