diff options
author | Richard Biener <rguenther@suse.de> | 2016-07-07 07:43:35 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2016-07-07 07:43:35 +0000 |
commit | 3c5b29f56103d60f4f4dca7136ae4dcc7987a728 (patch) | |
tree | 1418b84f009ff78ba988582b7613211c85a2c645 /gcc | |
parent | 5ddaee94e247a189a8a17af7dce8d45e0c30adee (diff) | |
download | gcc-3c5b29f56103d60f4f4dca7136ae4dcc7987a728.zip gcc-3c5b29f56103d60f4f4dca7136ae4dcc7987a728.tar.gz gcc-3c5b29f56103d60f4f4dca7136ae4dcc7987a728.tar.bz2 |
tree-ssa-pre.c: Include alias.h.
2016-07-07 Richard Biener <rguenther@suse.de>
* 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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/tree-ssa-pre.c | 79 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 11 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.h | 1 |
4 files changed, 96 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cbb4dcf4..4fa2c4d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2016-07-07 Richard Biener <rguenther@suse.de> + + * 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 <segher@kernel.crashing.org> PR target/70098 diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 3ce87d9..0c97f4f 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<vn_reference_op_s> 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 0cbd2cd..e9e18526 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_op_s> +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 1f6af40..069590a 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<vn_reference_op_s> ); +vec<vn_reference_op_s> vn_reference_operands_for_lookup (tree); tree vn_reference_lookup_pieces (tree, alias_set_type, tree, vec<vn_reference_op_s> , vn_reference_t *, vn_lookup_kind); |