diff options
author | Tamar Christina <tamar.christina@arm.com> | 2020-11-04 22:33:11 +0000 |
---|---|---|
committer | Tamar Christina <tamar.christina@arm.com> | 2020-11-04 22:33:11 +0000 |
commit | 4d76079fdfa3d36ebd95ac8b489519945e8ee88f (patch) | |
tree | 137fc0337746424a1379b9b5812f1bae11208f70 /gcc/tree-vect-loop.c | |
parent | 6682ef4363b32977aeca590fced2221329c92c02 (diff) | |
download | gcc-4d76079fdfa3d36ebd95ac8b489519945e8ee88f.zip gcc-4d76079fdfa3d36ebd95ac8b489519945e8ee88f.tar.gz gcc-4d76079fdfa3d36ebd95ac8b489519945e8ee88f.tar.bz2 |
middle-end: Move load/store-lanes check till late.
This moves the code that checks for load/store lanes further in the pipeline and
places it after slp_optimize. This would allow us to perform optimizations on
the SLP tree and only bail out if we really have a permute.
With this change it allows us to handle permutes such as {1,1,1,1} which should
be handled by a load and replicate.
This change however makes it all or nothing. Either all instances can be handled
or none at all. This is why some of the test cases have been adjusted.
gcc/ChangeLog:
* tree-vect-slp.c (vect_analyze_slp_instance): Moved load/store lanes
check to ...
* tree-vect-loop.c (vect_analyze_loop_2): ..Here
gcc/testsuite/ChangeLog:
* gcc.dg/vect/slp-11b.c: Update output scan.
* gcc.dg/vect/slp-perm-6.c: Likewise.
Diffstat (limited to 'gcc/tree-vect-loop.c')
-rw-r--r-- | gcc/tree-vect-loop.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c index 5e7188a..547894c 100644 --- a/gcc/tree-vect-loop.c +++ b/gcc/tree-vect-loop.c @@ -2365,6 +2365,78 @@ start_over: "unsupported SLP instances\n"); goto again; } + + /* Check whether any load in ALL SLP instances is possibly permuted. */ + slp_tree load_node, slp_root; + unsigned i, x; + slp_instance instance; + bool can_use_lanes = true; + FOR_EACH_VEC_ELT (LOOP_VINFO_SLP_INSTANCES (loop_vinfo), x, instance) + { + slp_root = SLP_INSTANCE_TREE (instance); + int group_size = SLP_TREE_LANES (slp_root); + tree vectype = SLP_TREE_VECTYPE (slp_root); + bool loads_permuted = false; + FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, load_node) + { + if (!SLP_TREE_LOAD_PERMUTATION (load_node).exists ()) + continue; + unsigned j; + stmt_vec_info load_info; + FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (load_node), j, load_info) + if (SLP_TREE_LOAD_PERMUTATION (load_node)[j] != j) + { + loads_permuted = true; + break; + } + } + + /* If the loads and stores can be handled with load/store-lane + instructions record it and move on to the next instance. */ + if (loads_permuted + && vect_store_lanes_supported (vectype, group_size, false)) + { + FOR_EACH_VEC_ELT (SLP_INSTANCE_LOADS (instance), i, load_node) + { + stmt_vec_info stmt_vinfo = DR_GROUP_FIRST_ELEMENT + (SLP_TREE_SCALAR_STMTS (load_node)[0]); + /* Use SLP for strided accesses (or if we can't + load-lanes). */ + if (STMT_VINFO_STRIDED_P (stmt_vinfo) + || ! vect_load_lanes_supported + (STMT_VINFO_VECTYPE (stmt_vinfo), + DR_GROUP_SIZE (stmt_vinfo), false)) + break; + } + + can_use_lanes + = can_use_lanes && i == SLP_INSTANCE_LOADS (instance).length (); + + if (can_use_lanes && dump_enabled_p ()) + dump_printf_loc (MSG_NOTE, vect_location, + "SLP instance %p can use load/store-lanes\n", + instance); + } + else + { + can_use_lanes = false; + break; + } + } + + /* If all SLP instances can use load/store-lanes abort SLP and try again + with SLP disabled. */ + if (can_use_lanes) + { + ok = opt_result::failure_at (vect_location, + "Built SLP cancelled: can use " + "load/store-lanes\n"); + if (dump_enabled_p ()) + dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location, + "Built SLP cancelled: all SLP instances support " + "load/store-lanes\n"); + goto again; + } } /* Dissolve SLP-only groups. */ |