diff options
author | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-20 15:41:45 +0000 |
---|---|---|
committer | amker <amker@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-04-20 15:41:45 +0000 |
commit | bd6f374caa4faff59f20c8fba7396b721c0783ab (patch) | |
tree | 5fb76629343852155b74e65799acbfe8a3bd9d03 | |
parent | 4076531f63f07bcfc396c0bdb8fa146703542503 (diff) | |
download | gcc-bd6f374caa4faff59f20c8fba7396b721c0783ab.tar.gz |
PR tree-optimization/56625
PR tree-optimization/69489
* tree-data-ref.h (DR_INNERMOST): New macro.
* tree-if-conv.c (innermost_loop_behavior_hash): New class for
hashing struct innermost_loop_behavior.
(ref_DR_map): Remove.
(innermost_DR_map): New map.
(baseref_DR_map): Revise comment.
(hash_memrefs_baserefs_and_store_DRs_read_written_info): Store DR
to innermost_DR_map accroding to its innermost loop behavior.
(ifcvt_memrefs_wont_trap): Get DR from innermost_DR_map according
to its innermost loop behavior.
(if_convertible_loop_p_1): Remove intialization for ref_DR_map.
Add initialization for innermost_DR_map. Record memory reference
in DR_BASE_ADDRESS if the reference is compound one or it doesn't
have innermost loop behavior.
(if_convertible_loop_p): Remove release for ref_DR_map. Release
innermost_DR_map.
gcc/testsuite/ChangeLog
PR tree-optimization/56625
PR tree-optimization/69489
* gcc.dg/vect/pr56625.c: New test.
* gcc.dg/tree-ssa/ifc-pr69489-1.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235289 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-1.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/vect/pr56625.c | 16 | ||||
-rw-r--r-- | gcc/tree-data-ref.h | 1 | ||||
-rw-r--r-- | gcc/tree-if-conv.c | 110 |
6 files changed, 150 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ab668c3615b..1f3d66b24de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,24 @@ +2016-04-20 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/56625 + PR tree-optimization/69489 + * tree-data-ref.h (DR_INNERMOST): New macro. + * tree-if-conv.c (innermost_loop_behavior_hash): New class for + hashing struct innermost_loop_behavior. + (ref_DR_map): Remove. + (innermost_DR_map): New map. + (baseref_DR_map): Revise comment. + (hash_memrefs_baserefs_and_store_DRs_read_written_info): Store DR + to innermost_DR_map accroding to its innermost loop behavior. + (ifcvt_memrefs_wont_trap): Get DR from innermost_DR_map according + to its innermost loop behavior. + (if_convertible_loop_p_1): Remove intialization for ref_DR_map. + Add initialization for innermost_DR_map. Record memory reference + in DR_BASE_ADDRESS if the reference is compound one or it doesn't + have innermost loop behavior. + (if_convertible_loop_p): Remove release for ref_DR_map. Release + innermost_DR_map. + 2016-04-20 Uros Bizjak <ubizjak@gmail.com> * config/i386/i386.md (*lea<mode>_general_1): Rename from diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 543837ff579..50d37d21ff0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2016-04-20 Bin Cheng <bin.cheng@arm.com> + + PR tree-optimization/56625 + PR tree-optimization/69489 + * gcc.dg/vect/pr56625.c: New test. + * gcc.dg/tree-ssa/ifc-pr69489-1.c: New test. + 2016-04-20 Andrew Pinski <apinski@cavium.com> PR target/64971 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-1.c new file mode 100644 index 00000000000..4131afcbdff --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr69489-1.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ftree-vectorize -fdump-tree-ifcvt-stats" { target *-*-* } } */ + +void foo (int a[], int b[]) +{ + int i; + for (i = 0; i < 100; i++) + { + if (a[i] == 0) + a[i] = b[i]*4; + else + a[i] = b[i]*3; + } +} + +/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr56625.c b/gcc/testsuite/gcc.dg/vect/pr56625.c new file mode 100644 index 00000000000..b903be30adc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr56625.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_int } */ + +void foo (int a[], int b[]) +{ + int i; + for (i = 0; i < 100; i++) + { + if (a[i] == 0) + a[i] = b[i]*4; + else + a[i] = b[i]*3; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/tree-data-ref.h b/gcc/tree-data-ref.h index eb24d16486c..856dd58f3ad 100644 --- a/gcc/tree-data-ref.h +++ b/gcc/tree-data-ref.h @@ -144,6 +144,7 @@ struct data_reference #define DR_STEP(DR) (DR)->innermost.step #define DR_PTR_INFO(DR) (DR)->alias.ptr_info #define DR_ALIGNED_TO(DR) (DR)->innermost.aligned_to +#define DR_INNERMOST(DR) (DR)->innermost typedef struct data_reference *data_reference_p; diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 72e808ef883..691811322f7 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -114,16 +114,68 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "params.h" +/* Hash for struct innermost_loop_behavior. It depends on the user to + free the memory. */ + +struct innermost_loop_behavior_hash : nofree_ptr_hash <innermost_loop_behavior> +{ + static inline hashval_t hash (const value_type &); + static inline bool equal (const value_type &, + const compare_type &); +}; + +inline hashval_t +innermost_loop_behavior_hash::hash (const value_type &e) +{ + hashval_t hash; + + hash = iterative_hash_expr (e->base_address, 0); + hash = iterative_hash_expr (e->offset, hash); + hash = iterative_hash_expr (e->init, hash); + return iterative_hash_expr (e->step, hash); +} + +inline bool +innermost_loop_behavior_hash::equal (const value_type &e1, + const compare_type &e2) +{ + if ((e1->base_address && !e2->base_address) + || (!e1->base_address && e2->base_address) + || (!e1->offset && e2->offset) + || (e1->offset && !e2->offset) + || (!e1->init && e2->init) + || (e1->init && !e2->init) + || (!e1->step && e2->step) + || (e1->step && !e2->step)) + return false; + + if (e1->base_address && e2->base_address + && !operand_equal_p (e1->base_address, e2->base_address, 0)) + return false; + if (e1->offset && e2->offset + && !operand_equal_p (e1->offset, e2->offset, 0)) + return false; + if (e1->init && e2->init + && !operand_equal_p (e1->init, e2->init, 0)) + return false; + if (e1->step && e2->step + && !operand_equal_p (e1->step, e2->step, 0)) + return false; + + return true; +} + /* List of basic blocks in if-conversion-suitable order. */ static basic_block *ifc_bbs; /* Apply more aggressive (extended) if-conversion if true. */ static bool aggressive_if_conv; -/* Hash table to store references, DR pairs. */ -static hash_map<tree_operand_hash, data_reference_p> *ref_DR_map; +/* Hash table to store <DR's innermost loop behavior, DR> pairs. */ +static hash_map<innermost_loop_behavior_hash, + data_reference_p> *innermost_DR_map; -/* Hash table to store base reference, DR pairs. */ +/* Hash table to store <base reference, DR> pairs. */ static hash_map<tree_operand_hash, data_reference_p> *baseref_DR_map; /* Structure used to predicate basic blocks. This is attached to the @@ -623,17 +675,12 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a) { data_reference_p *master_dr, *base_master_dr; - tree ref = DR_REF (a); tree base_ref = DR_BASE_OBJECT (a); + innermost_loop_behavior *innermost = &DR_INNERMOST (a); tree ca = bb_predicate (gimple_bb (DR_STMT (a))); bool exist1, exist2; - while (TREE_CODE (ref) == COMPONENT_REF - || TREE_CODE (ref) == IMAGPART_EXPR - || TREE_CODE (ref) == REALPART_EXPR) - ref = TREE_OPERAND (ref, 0); - - master_dr = &ref_DR_map->get_or_insert (ref, &exist1); + master_dr = &innermost_DR_map->get_or_insert (innermost, &exist1); if (!exist1) *master_dr = a; @@ -695,21 +742,18 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs) data_reference_p *master_dr, *base_master_dr; data_reference_p a = drs[gimple_uid (stmt) - 1]; - tree ref_base_a = DR_REF (a); tree base = DR_BASE_OBJECT (a); + innermost_loop_behavior *innermost = &DR_INNERMOST (a); gcc_assert (DR_STMT (a) == stmt); + gcc_assert (DR_BASE_ADDRESS (a) || DR_OFFSET (a) + || DR_INIT (a) || DR_STEP (a)); - while (TREE_CODE (ref_base_a) == COMPONENT_REF - || TREE_CODE (ref_base_a) == IMAGPART_EXPR - || TREE_CODE (ref_base_a) == REALPART_EXPR) - ref_base_a = TREE_OPERAND (ref_base_a, 0); + master_dr = innermost_DR_map->get (innermost); + gcc_assert (master_dr != NULL); - master_dr = ref_DR_map->get (ref_base_a); base_master_dr = baseref_DR_map->get (base); - gcc_assert (master_dr != NULL); - /* If a is unconditionally written to it doesn't trap. */ if (DR_W_UNCONDITIONALLY (*master_dr)) return true; @@ -1238,13 +1282,16 @@ if_convertible_loop_p_1 (struct loop *loop, data_reference_p dr; - ref_DR_map = new hash_map<tree_operand_hash, data_reference_p>; + innermost_DR_map + = new hash_map<innermost_loop_behavior_hash, data_reference_p>; baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>; predicate_bbs (loop); for (i = 0; refs->iterate (i, &dr); i++) { + tree ref = DR_REF (dr); + dr->aux = XNEW (struct ifc_dr); DR_BASE_W_UNCONDITIONALLY (dr) = false; DR_RW_UNCONDITIONALLY (dr) = false; @@ -1254,6 +1301,27 @@ if_convertible_loop_p_1 (struct loop *loop, IFC_DR (dr)->base_w_predicate = boolean_false_node; if (gimple_uid (DR_STMT (dr)) == 0) gimple_set_uid (DR_STMT (dr), i + 1); + + /* If DR doesn't have innermost loop behavior or it's a compound + memory reference, we synthesize its innermost loop behavior + for hashing. */ + if (TREE_CODE (ref) == COMPONENT_REF + || TREE_CODE (ref) == IMAGPART_EXPR + || TREE_CODE (ref) == REALPART_EXPR + || !(DR_BASE_ADDRESS (dr) || DR_OFFSET (dr) + || DR_INIT (dr) || DR_STEP (dr))) + { + while (TREE_CODE (ref) == COMPONENT_REF + || TREE_CODE (ref) == IMAGPART_EXPR + || TREE_CODE (ref) == REALPART_EXPR) + ref = TREE_OPERAND (ref, 0); + + DR_BASE_ADDRESS (dr) = ref; + DR_OFFSET (dr) = NULL; + DR_INIT (dr) = NULL; + DR_STEP (dr) = NULL; + DR_ALIGNED_TO (dr) = NULL; + } hash_memrefs_baserefs_and_store_DRs_read_written_info (dr); } @@ -1348,8 +1416,8 @@ if_convertible_loop_p (struct loop *loop, bool *any_mask_load_store) free_data_refs (refs); - delete ref_DR_map; - ref_DR_map = NULL; + delete innermost_DR_map; + innermost_DR_map = NULL; delete baseref_DR_map; baseref_DR_map = NULL; |