diff options
Diffstat (limited to 'gcc/tree-vect-data-refs.c')
-rw-r--r-- | gcc/tree-vect-data-refs.c | 100 |
1 files changed, 85 insertions, 15 deletions
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c index 1ed7c603de2..f6e21315ed5 100644 --- a/gcc/tree-vect-data-refs.c +++ b/gcc/tree-vect-data-refs.c @@ -2877,8 +2877,10 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, stmt_vec_info stmt_info; tree base, offset, init; bool gather = false; + bool simd_lane_access = false; int vf; +again: if (!dr || !DR_REF (dr)) { if (dump_enabled_p ()) @@ -2890,16 +2892,34 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, stmt = DR_STMT (dr); stmt_info = vinfo_for_stmt (stmt); + /* Discard clobbers from the dataref vector. We will remove + clobber stmts during vectorization. */ + if (gimple_clobber_p (stmt)) + { + if (i == datarefs.length () - 1) + { + datarefs.pop (); + break; + } + datarefs[i] = datarefs.pop (); + goto again; + } + /* Check that analysis of the data-ref succeeded. */ if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr) || !DR_STEP (dr)) { - /* If target supports vector gather loads, see if they can't - be used. */ - if (loop_vinfo - && DR_IS_READ (dr) + bool maybe_gather + = DR_IS_READ (dr) && !TREE_THIS_VOLATILE (DR_REF (dr)) - && targetm.vectorize.builtin_gather != NULL + && targetm.vectorize.builtin_gather != NULL; + bool maybe_simd_lane_access + = loop_vinfo && loop->simduid; + + /* If target supports vector gather loads, or if this might be + a SIMD lane access, see if they can't be used. */ + if (loop_vinfo + && (maybe_gather || maybe_simd_lane_access) && !nested_in_vect_loop_p (loop, stmt)) { struct data_reference *newdr @@ -2912,14 +2932,59 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, && DR_STEP (newdr) && integer_zerop (DR_STEP (newdr))) { - dr = newdr; - gather = true; + if (maybe_simd_lane_access) + { + tree off = DR_OFFSET (newdr); + STRIP_NOPS (off); + if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST + && TREE_CODE (off) == MULT_EXPR + && host_integerp (TREE_OPERAND (off, 1), 1)) + { + tree step = TREE_OPERAND (off, 1); + off = TREE_OPERAND (off, 0); + STRIP_NOPS (off); + if (CONVERT_EXPR_P (off) + && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off, + 0))) + < TYPE_PRECISION (TREE_TYPE (off))) + off = TREE_OPERAND (off, 0); + if (TREE_CODE (off) == SSA_NAME) + { + gimple def = SSA_NAME_DEF_STMT (off); + tree reft = TREE_TYPE (DR_REF (newdr)); + if (gimple_call_internal_p (def) + && gimple_call_internal_fn (def) + == IFN_GOMP_SIMD_LANE) + { + tree arg = gimple_call_arg (def, 0); + gcc_assert (TREE_CODE (arg) == SSA_NAME); + arg = SSA_NAME_VAR (arg); + if (arg == loop->simduid + /* For now. */ + && tree_int_cst_equal + (TYPE_SIZE_UNIT (reft), + step)) + { + DR_OFFSET (newdr) = ssize_int (0); + DR_STEP (newdr) = step; + dr = newdr; + simd_lane_access = true; + } + } + } + } + } + if (!simd_lane_access && maybe_gather) + { + dr = newdr; + gather = true; + } } - else + if (!gather && !simd_lane_access) free_data_ref (newdr); } - if (!gather) + if (!gather && !simd_lane_access) { if (dump_enabled_p ()) { @@ -2946,7 +3011,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) free_data_ref (dr); return false; } @@ -2979,7 +3044,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) free_data_ref (dr); return false; } @@ -2998,7 +3063,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) free_data_ref (dr); return false; } @@ -3019,7 +3084,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) free_data_ref (dr); return false; } @@ -3154,12 +3219,17 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) free_data_ref (dr); return false; } STMT_VINFO_DATA_REF (stmt_info) = dr; + if (simd_lane_access) + { + STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true; + datarefs[i] = dr; + } /* Set vectype for STMT. */ scalar_type = TREE_TYPE (DR_REF (dr)); @@ -3180,7 +3250,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo, if (bb_vinfo) break; - if (gather) + if (gather || simd_lane_access) { STMT_VINFO_DATA_REF (stmt_info) = NULL; free_data_ref (dr); |