aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-isel.cc
diff options
context:
space:
mode:
authorXionghu Luo <luoxhu@linux.ibm.com>2020-09-27 00:27:32 -0500
committerXionghu Luo <luoxhu@linux.ibm.com>2020-09-27 00:27:32 -0500
commit683e55facfd5c1d348796119424d7b3f9e889ffe (patch)
tree182e5ca06d98352268ad98a44f900859843331ec /gcc/gimple-isel.cc
parent91dd4a3864110704c921ab8467f568ff42c38e5c (diff)
downloadgcc-683e55facfd5c1d348796119424d7b3f9e889ffe.zip
gcc-683e55facfd5c1d348796119424d7b3f9e889ffe.tar.gz
gcc-683e55facfd5c1d348796119424d7b3f9e889ffe.tar.bz2
IFN: Implement IFN_VEC_SET for ARRAY_REF with VIEW_CONVERT_EXPR
This patch enables transformation from ARRAY_REF(VIEW_CONVERT_EXPR) to VEC_SET internal function in gimple-isel pass if target supports vec_set with variable index by checking can_vec_set_var_idx_p. gcc/ChangeLog: 2020-09-27 Xionghu Luo <luoxhu@linux.ibm.com> * gimple-isel.cc (gimple_expand_vec_set_expr): New function. (gimple_expand_vec_cond_exprs): Rename to ... (gimple_expand_vec_exprs): ... this and call gimple_expand_vec_set_expr. * internal-fn.c (vec_set_direct): New define. (expand_vec_set_optab_fn): New function. (direct_vec_set_optab_supported_p): New define. * internal-fn.def (VEC_SET): New DEF_INTERNAL_OPTAB_FN. * optabs.c (can_vec_set_var_idx_p): New function. * optabs.h (can_vec_set_var_idx_p): New declaration.
Diffstat (limited to 'gcc/gimple-isel.cc')
-rw-r--r--gcc/gimple-isel.cc75
1 files changed, 73 insertions, 2 deletions
diff --git a/gcc/gimple-isel.cc b/gcc/gimple-isel.cc
index 9792263..b64e31f 100644
--- a/gcc/gimple-isel.cc
+++ b/gcc/gimple-isel.cc
@@ -35,6 +35,74 @@ along with GCC; see the file COPYING3. If not see
#include "tree-cfg.h"
#include "bitmap.h"
#include "tree-ssa-dce.h"
+#include "memmodel.h"
+#include "optabs.h"
+
+/* Expand all ARRAY_REF(VIEW_CONVERT_EXPR) gimple assignments into calls to
+ internal function based on vector type of selected expansion.
+ i.e.:
+ VIEW_CONVERT_EXPR<int[4]>(u)[_1] = = i_4(D);
+ =>
+ _7 = u;
+ _8 = .VEC_SET (_7, i_4(D), _1);
+ u = _8; */
+
+static gimple *
+gimple_expand_vec_set_expr (gimple_stmt_iterator *gsi)
+{
+ enum tree_code code;
+ gcall *new_stmt = NULL;
+ gassign *ass_stmt = NULL;
+
+ /* Only consider code == GIMPLE_ASSIGN. */
+ gassign *stmt = dyn_cast<gassign *> (gsi_stmt (*gsi));
+ if (!stmt)
+ return NULL;
+
+ tree lhs = gimple_assign_lhs (stmt);
+ code = TREE_CODE (lhs);
+ if (code != ARRAY_REF)
+ return NULL;
+
+ tree val = gimple_assign_rhs1 (stmt);
+ tree op0 = TREE_OPERAND (lhs, 0);
+ if (TREE_CODE (op0) == VIEW_CONVERT_EXPR && DECL_P (TREE_OPERAND (op0, 0))
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0)))
+ && TYPE_MODE (TREE_TYPE (lhs))
+ == TYPE_MODE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (op0, 0)))))
+ {
+ tree pos = TREE_OPERAND (lhs, 1);
+ tree view_op0 = TREE_OPERAND (op0, 0);
+ machine_mode outermode = TYPE_MODE (TREE_TYPE (view_op0));
+ if (auto_var_in_fn_p (view_op0, cfun->decl)
+ && !TREE_ADDRESSABLE (view_op0) && can_vec_set_var_idx_p (outermode))
+ {
+ location_t loc = gimple_location (stmt);
+ tree var_src = make_ssa_name (TREE_TYPE (view_op0));
+ tree var_dst = make_ssa_name (TREE_TYPE (view_op0));
+
+ ass_stmt = gimple_build_assign (var_src, view_op0);
+ gimple_set_vuse (ass_stmt, gimple_vuse (stmt));
+ gimple_set_location (ass_stmt, loc);
+ gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT);
+
+ new_stmt
+ = gimple_build_call_internal (IFN_VEC_SET, 3, var_src, val, pos);
+ gimple_call_set_lhs (new_stmt, var_dst);
+ gimple_set_location (new_stmt, loc);
+ gsi_insert_before (gsi, new_stmt, GSI_SAME_STMT);
+
+ ass_stmt = gimple_build_assign (view_op0, var_dst);
+ gimple_set_location (ass_stmt, loc);
+ gsi_insert_before (gsi, ass_stmt, GSI_SAME_STMT);
+
+ gimple_move_vops (ass_stmt, stmt);
+ gsi_remove (gsi, true);
+ }
+ }
+
+ return ass_stmt;
+}
/* Expand all VEC_COND_EXPR gimple assignments into calls to internal
function based on type of selected expansion. */
@@ -165,7 +233,7 @@ gimple_expand_vec_cond_expr (gimple_stmt_iterator *gsi,
VEC_COND_EXPR assignments. */
static unsigned int
-gimple_expand_vec_cond_exprs (void)
+gimple_expand_vec_exprs (void)
{
gimple_stmt_iterator gsi;
basic_block bb;
@@ -178,12 +246,15 @@ gimple_expand_vec_cond_exprs (void)
{
gimple *g = gimple_expand_vec_cond_expr (&gsi,
&vec_cond_ssa_name_uses);
+
if (g != NULL)
{
tree lhs = gimple_assign_lhs (gsi_stmt (gsi));
gimple_set_lhs (g, lhs);
gsi_replace (&gsi, g, false);
}
+
+ gimple_expand_vec_set_expr (&gsi);
}
}
@@ -226,7 +297,7 @@ public:
virtual unsigned int execute (function *)
{
- return gimple_expand_vec_cond_exprs ();
+ return gimple_expand_vec_exprs ();
}
}; // class pass_gimple_isel