From 3c5b29f56103d60f4f4dca7136ae4dcc7987a728 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 7 Jul 2016 07:43:35 +0000 Subject: [PATCH] tree-ssa-pre.c: Include alias.h. 2016-07-07 Richard Biener * tree-ssa-pre.c: Include alias.h. (compute_avail): If we have multiple VN_REFERENCEs with the same hashtable entry adjust that to make it a valid replacement for all of them with respect to alignment and aliasing when doing insertion. * tree-ssa-sccvn.h (vn_reference_operands_for_lookup): Declare. * tree-ssa-sccvn.c (vn_reference_operands_for_lookup): New function. From-SVN: r238078 --- gcc/ChangeLog | 10 ++++++ gcc/tree-ssa-pre.c | 79 +++++++++++++++++++++++++++++++++++++++++--- gcc/tree-ssa-sccvn.c | 11 ++++++ gcc/tree-ssa-sccvn.h | 1 + 4 files changed, 96 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cbb4dcf4936..4fa2c4dcee4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-07-07 Richard Biener + + * tree-ssa-pre.c: Include alias.h. + (compute_avail): If we have multiple VN_REFERENCEs with the + same hashtable entry adjust that to make it a valid replacement + for all of them with respect to alignment and aliasing + when doing insertion. + * tree-ssa-sccvn.h (vn_reference_operands_for_lookup): Declare. + * tree-ssa-sccvn.c (vn_reference_operands_for_lookup): New function. + 2016-07-06 Segher Boessenkool PR target/70098 diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 3ce87d9d23f..0c97f4fbcce 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-utils.h" #include "tree-cfgcleanup.h" #include "langhooks.h" +#include "alias.h" /* TODO: @@ -3724,12 +3725,19 @@ compute_avail (void) case VN_REFERENCE: { + tree rhs1 = gimple_assign_rhs1 (stmt); + alias_set_type set = get_alias_set (rhs1); + vec operands + = vn_reference_operands_for_lookup (rhs1); vn_reference_t ref; - vn_reference_lookup (gimple_assign_rhs1 (stmt), - gimple_vuse (stmt), - VN_WALK, &ref, true); + vn_reference_lookup_pieces (gimple_vuse (stmt), set, + TREE_TYPE (rhs1), + operands, &ref, VN_WALK); if (!ref) - continue; + { + operands.release (); + continue; + } /* If the value of the reference is not invalidated in this block until it is computed, add the expression @@ -3753,7 +3761,68 @@ compute_avail (void) = SSA_NAME_DEF_STMT (gimple_vuse (def_stmt)); } if (!ok) - continue; + { + operands.release (); + continue; + } + } + + /* If the load was value-numbered to another + load make sure we do not use its expression + for insertion if it wouldn't be a valid + replacement. */ + /* At the momemt we have a testcase + for hoist insertion of aligned vs. misaligned + variants in gcc.dg/torture/pr65270-1.c thus + with just alignment to be considered we can + simply replace the expression in the hashtable + with the most conservative one. */ + vn_reference_op_t ref1 = &ref->operands.last (); + while (ref1->opcode != TARGET_MEM_REF + && ref1->opcode != MEM_REF + && ref1 != &ref->operands[0]) + --ref1; + vn_reference_op_t ref2 = &operands.last (); + while (ref2->opcode != TARGET_MEM_REF + && ref2->opcode != MEM_REF + && ref2 != &operands[0]) + --ref2; + if ((ref1->opcode == TARGET_MEM_REF + || ref1->opcode == MEM_REF) + && (TYPE_ALIGN (ref1->type) + > TYPE_ALIGN (ref2->type))) + { + ref->operands.release (); + ref->operands = operands; + ref1 = ref2; + } + else + operands.release (); + /* TBAA behavior is an obvious part so make sure + that the hashtable one covers this as well + by adjusting the ref alias set and its base. */ + if (ref->set == set + || alias_set_subset_of (set, ref->set)) + ; + else if (alias_set_subset_of (ref->set, set)) + { + ref->set = set; + if (ref1->opcode == MEM_REF) + ref1->op0 = fold_convert (TREE_TYPE (ref2->op0), + ref1->op0); + else + ref1->op2 = fold_convert (TREE_TYPE (ref2->op2), + ref1->op2); + } + else + { + ref->set = 0; + if (ref1->opcode == MEM_REF) + ref1->op0 = fold_convert (ptr_type_node, + ref1->op0); + else + ref1->op2 = fold_convert (ptr_type_node, + ref1->op2); } result = pre_expr_pool.allocate (); diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 0cbd2cd56f2..e9e18526a0b 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -2285,6 +2285,17 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, return (void *)-1; } +/* Return a reference op vector from OP that can be used for + vn_reference_lookup_pieces. The caller is responsible for releasing + the vector. */ + +vec +vn_reference_operands_for_lookup (tree op) +{ + bool valueized; + return valueize_shared_reference_ops_from_ref (op, &valueized).copy (); +} + /* Lookup a reference operation by it's parts, in the current hash table. Returns the resulting value number if it exists in the hash table, NULL_TREE otherwise. VNRESULT will be filled in with the actual diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h index 1f6af4043fa..069590a0b01 100644 --- a/gcc/tree-ssa-sccvn.h +++ b/gcc/tree-ssa-sccvn.h @@ -214,6 +214,7 @@ vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code, tree, tree *, tree, unsigned int); bool ao_ref_init_from_vn_reference (ao_ref *, alias_set_type, tree, vec ); +vec vn_reference_operands_for_lookup (tree); tree vn_reference_lookup_pieces (tree, alias_set_type, tree, vec , vn_reference_t *, vn_lookup_kind); -- 2.30.2