diff mbox

[hsa-branch] Update existing hsa builtin handling

Message ID E1bUxHf-0005FO-3q@eggs.gnu.org
State New
Headers show

Commit Message

Martin Jambor July 21, 2016, 8:48 a.m. UTC
Hi,

this patch updates the neames of HSA builtins that are emitted by omp
lowering so that their names correspond to the HSA instruction names
they are implemented by.  This avoids a lot of confusion when we add
more HSA builtins for other special operations the architecture has.

Moreover, it cleans up how we handle them and also reimplements handling
of OpenMP builtins and calls to run-time OpenMP functions, so that they
work as expected in multi-dimensional grids.

Thanks,

Martin

2016-07-20  Martin Jambor  <mjambor@suse.cz>

	* hsa-builtins.def (BUILT_IN_HSA_GET_WORKGROUP_ID): Renamed to
	BUILT_IN_HSA_WORKGROUPID.
	(BUILT_IN_HSA_GET_WORKITEM_ID): Renamed to BUILT_IN_HSA_WORKITEMID.
	(BUILT_IN_HSA_GET_WORKITEM_ABSID): Renamed to
	BUILT_IN_HSA_WORKITEMABSID.
	* hsa-gen.c (query_hsa_grid): Renamed to
	query_hsa_grid_dim, reimplemented, cut down to two overloads.
	(query_hsa_grid_nodim): New function.
	(multiply_grid_dim_characteristics): Likewise.
	(gen_get_num_threads): Likewise.
	(gen_get_num_teams): Reimplemented.
	(gen_get_team_num): Likewise.
	(gen_hsa_insns_for_known_library_call): Updated calls to the above
	helper functions.
	(gen_hsa_insns_for_call): Updated names of builtins, use
	the above helper functions to handle them.
	* omp-low.c (grid_expand_omp_for_loop): Update builtin names.
---
 gcc/hsa-builtins.def |   6 +-
 gcc/hsa-gen.c        | 173 ++++++++++++++++++++++++++++++++++-----------------
 gcc/omp-low.c        |   6 +-
 3 files changed, 123 insertions(+), 62 deletions(-)
diff mbox

Patch

diff --git a/gcc/hsa-builtins.def b/gcc/hsa-builtins.def
index 3f183f1..dcd0c55 100644
--- a/gcc/hsa-builtins.def
+++ b/gcc/hsa-builtins.def
@@ -27,9 +27,9 @@  along with GCC; see the file COPYING3.  If not see
 /* The reason why they aren't in gcc/builtins.def is that the Fortran front end
    doesn't source those.  */
 
-DEF_HSA_BUILTIN (BUILT_IN_HSA_GET_WORKGROUP_ID, "hsa_get_workgroup_id",
+DEF_HSA_BUILTIN (BUILT_IN_HSA_WORKGROUPID, "hsa_workgroupid",
 	  	 BT_FN_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_HSA_BUILTIN (BUILT_IN_HSA_GET_WORKITEM_ID, "hsa_get_workitem_id",
+DEF_HSA_BUILTIN (BUILT_IN_HSA_WORKITEMID, "hsa_workitemid",
 	  	 BT_FN_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_HSA_BUILTIN (BUILT_IN_HSA_GET_WORKITEM_ABSID, "hsa_get_workitem_absid",
+DEF_HSA_BUILTIN (BUILT_IN_HSA_WORKITEMABSID, "hsa_workitemabsid",
 	  	 BT_FN_UINT_UINT, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index e16a5c7..24cc2c7 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3795,8 +3795,8 @@  hsa_insn_basic::set_output_in_type (hsa_op_reg *dest, unsigned op_index,
    HBB.  */
 
 static void
-query_hsa_grid (hsa_op_reg *dest, BrigType16_t opcode,  hsa_op_immed *dimension,
-		hsa_bb *hbb)
+query_hsa_grid_dim (hsa_op_reg *dest, int opcode, hsa_op_immed *dimension,
+		    hsa_bb *hbb)
 {
   hsa_insn_basic *insn = new hsa_insn_basic (2, opcode, BRIG_TYPE_U32, NULL,
 					     dimension);
@@ -3804,32 +3804,49 @@  query_hsa_grid (hsa_op_reg *dest, BrigType16_t opcode,  hsa_op_immed *dimension,
   insn->set_output_in_type (dest, 0, hbb);
 }
 
-/* Generate a special HSA-related instruction for gimple STMT.
-   Instructions are appended to basic block HBB.  */
+/* Generate instruction OPCODE to query a property of HSA grid along the given
+   dimension which is an immediate in first argument of STMT.  Store result
+   into the register corresponding to LHS of STMT and append the instruction to
+   HBB.  */
 
 static void
-query_hsa_grid (gimple *stmt, BrigOpcode16_t opcode, hsa_op_immed *dimension,
-		hsa_bb *hbb)
+query_hsa_grid_dim (gimple *stmt, int opcode, hsa_bb *hbb)
 {
   tree lhs = gimple_call_lhs (dyn_cast <gcall *> (stmt));
   if (lhs == NULL_TREE)
     return;
 
-  hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
+  tree arg = gimple_call_arg (stmt, 0);
+  unsigned HOST_WIDE_INT dim = 5;
+  if (tree_fits_uhwi_p (arg))
+    dim = tree_to_uhwi (arg);
+  if (dim > 2)
+    {
+      HSA_SORRY_AT (gimple_location (stmt),
+		    "HSA grid query dimension must be immediate constant 0, 1 "
+		    "or 2");
+      return;
+    }
 
-  query_hsa_grid (dest, opcode, dimension, hbb);
+  hsa_op_immed *hdim = new hsa_op_immed (dim, (BrigKind16_t) BRIG_TYPE_U32);
+  hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
+  query_hsa_grid_dim (dest, opcode, hdim, hbb);
 }
 
-/* Generate a special HSA-related instruction for gimple STMT.
-   Instructions are appended to basic block HBB.  */
+/* Generate instruction OPCODE to query a property of HSA grid that is
+   independent of any dimension.  Store result into the register corresponding
+   to LHS of STMT and append the instruction to HBB.  */
 
 static void
-query_hsa_grid (gimple *stmt, BrigOpcode16_t opcode, int dimension,
-		hsa_bb *hbb)
+query_hsa_grid_nodim (gimple *stmt, BrigOpcode16_t opcode, hsa_bb *hbb)
 {
-  hsa_op_immed *bdim = new hsa_op_immed (dimension,
-					 (BrigKind16_t) BRIG_TYPE_U32);
-  query_hsa_grid (stmt, opcode, bdim, hbb);
+  tree lhs = gimple_call_lhs (dyn_cast <gcall *> (stmt));
+  if (lhs == NULL_TREE)
+    return;
+  hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
+  BrigType16_t brig_type = hsa_unsigned_type_for_type (dest->m_type);
+  hsa_insn_basic *insn = new hsa_insn_basic (1, opcode, brig_type, dest);
+  hbb->append_insn (insn);
 }
 
 /* Emit instructions that set hsa_num_threads according to provided VALUE.
@@ -3976,6 +3993,44 @@  gen_num_threads_for_dispatch (hsa_bb *hbb)
   return as_a <hsa_op_reg *> (dest);
 }
 
+/* Build OPCODE query for all three hsa dimensions, multiply them and store the
+   result into DEST.  */
+
+static void
+multiply_grid_dim_characteristics (hsa_op_reg *dest, int opcode, hsa_bb *hbb)
+{
+  hsa_op_reg *dimx = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (dimx, opcode,
+		      new hsa_op_immed (0, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  hsa_op_reg *dimy = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (dimy, opcode,
+		      new hsa_op_immed (1, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  hsa_op_reg *dimz = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (dimz, opcode,
+		      new hsa_op_immed (2, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  hsa_op_reg *tmp = new hsa_op_reg (dest->m_type);
+  gen_hsa_binary_operation (BRIG_OPCODE_MUL, tmp,
+			    dimx->get_in_type (dest->m_type, hbb),
+			    dimy->get_in_type (dest->m_type, hbb), hbb);
+  gen_hsa_binary_operation (BRIG_OPCODE_MUL, dest, tmp,
+			    dimz->get_in_type (dest->m_type, hbb), hbb);
+}
+
+/* Emit instructions that assign number of threads to lhs of gimple STMT.
+   Instructions are appended to basic block HBB.  */
+
+static void
+gen_get_num_threads (gimple *stmt, hsa_bb *hbb)
+{
+  if (gimple_call_lhs (stmt) == NULL_TREE)
+    return;
+
+  hbb->append_insn (new hsa_insn_comment ("omp_get_num_threads"));
+  tree lhs = gimple_call_lhs (stmt);
+  hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
+  multiply_grid_dim_characteristics (dest, BRIG_OPCODE_CURRENTWORKGROUPSIZE,
+				     hbb);
+}
 
 /* Emit instructions that assign number of teams to lhs of gimple STMT.
    Instructions are appended to basic block HBB.  */
@@ -3987,15 +4042,9 @@  gen_get_num_teams (gimple *stmt, hsa_bb *hbb)
     return;
 
   hbb->append_insn (new hsa_insn_comment ("omp_get_num_teams"));
-
   tree lhs = gimple_call_lhs (stmt);
   hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
-  hsa_op_immed *one = new hsa_op_immed (1, dest->m_type);
-
-  hsa_insn_basic *basic
-    = new hsa_insn_basic (2, BRIG_OPCODE_MOV, dest->m_type, dest, one);
-
-  hbb->append_insn (basic);
+  multiply_grid_dim_characteristics (dest, BRIG_OPCODE_GRIDGROUPS, hbb);
 }
 
 /* Emit instructions that assign a team number to lhs of gimple STMT.
@@ -4008,15 +4057,42 @@  gen_get_team_num (gimple *stmt, hsa_bb *hbb)
     return;
 
   hbb->append_insn (new hsa_insn_comment ("omp_get_team_num"));
-
   tree lhs = gimple_call_lhs (stmt);
   hsa_op_reg *dest = hsa_cfun->reg_for_gimple_ssa (lhs);
-  hsa_op_immed *zero = new hsa_op_immed (0, dest->m_type);
-
-  hsa_insn_basic *basic
-    = new hsa_insn_basic (2, BRIG_OPCODE_MOV, dest->m_type, dest, zero);
 
-  hbb->append_insn (basic);
+  hsa_op_reg *gnum_x = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (gnum_x, BRIG_OPCODE_GRIDGROUPS,
+		      new hsa_op_immed (0, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  hsa_op_reg *gnum_y = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (gnum_y, BRIG_OPCODE_GRIDGROUPS,
+		      new hsa_op_immed (1, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+
+  hsa_op_reg *gno_z = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (gno_z, BRIG_OPCODE_WORKGROUPID,
+		      new hsa_op_immed (2, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+
+  hsa_op_reg *tmp1 = new hsa_op_reg (dest->m_type);
+  gen_hsa_binary_operation (BRIG_OPCODE_MUL, tmp1,
+			    gnum_x->get_in_type (dest->m_type, hbb),
+			    gnum_y->get_in_type (dest->m_type, hbb), hbb);
+  hsa_op_reg *tmp2 = new hsa_op_reg (dest->m_type);
+  gen_hsa_binary_operation (BRIG_OPCODE_MUL, tmp2, tmp1,
+			    gno_z->get_in_type (dest->m_type, hbb), hbb);
+
+  hsa_op_reg *gno_y = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (gno_y, BRIG_OPCODE_WORKGROUPID,
+		      new hsa_op_immed (1, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  hsa_op_reg *tmp3 = new hsa_op_reg (dest->m_type);
+  gen_hsa_binary_operation (BRIG_OPCODE_MUL, tmp3,
+			    gnum_x->get_in_type (dest->m_type, hbb),
+			    gno_y->get_in_type (dest->m_type, hbb), hbb);
+  hsa_op_reg *tmp4 = new hsa_op_reg (dest->m_type);
+  gen_hsa_binary_operation (BRIG_OPCODE_ADD, tmp4, tmp3, tmp2, hbb);
+  hsa_op_reg *gno_x = new hsa_op_reg (BRIG_TYPE_U32);
+  query_hsa_grid_dim (gno_x, BRIG_OPCODE_WORKGROUPID,
+		      new hsa_op_immed (0, (BrigKind16_t) BRIG_TYPE_U32), hbb);
+  gen_hsa_binary_operation (BRIG_OPCODE_ADD, dest, tmp4,
+			    gno_x->get_in_type (dest->m_type, hbb), hbb);
 }
 
 /* Emit instructions that get levels-var ICV to lhs of gimple STMT.
@@ -4362,12 +4438,12 @@  gen_hsa_insns_for_known_library_call (gimple *stmt, hsa_bb *hbb)
       else if (strcmp (name, "omp_get_thread_num") == 0)
 	{
 	  hbb->append_insn (new hsa_insn_comment (name));
-	  query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMABSID, 0, hbb);
+	  query_hsa_grid_nodim (stmt, BRIG_OPCODE_WORKITEMFLATABSID, hbb);
 	}
       else if (strcmp (name, "omp_get_num_threads") == 0)
 	{
 	  hbb->append_insn (new hsa_insn_comment (name));
-	  query_hsa_grid (stmt, BRIG_OPCODE_GRIDSIZE, 0, hbb);
+	  gen_get_num_threads (stmt, hbb);
 	}
       else if (strcmp (name, "omp_get_num_teams") == 0)
 	gen_get_num_teams (stmt, hbb);
@@ -5779,30 +5855,15 @@  gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb)
 	break;
       }
 
-    case BUILT_IN_HSA_GET_WORKGROUP_ID:
-      {
-	hsa_op_immed *bdim = new hsa_op_immed (gimple_call_arg (stmt, 0), true);
-	if (bdim->m_type != BRIG_TYPE_U32)
-	  bdim->get_in_type (BRIG_TYPE_U32, hbb);
-	query_hsa_grid (stmt, BRIG_OPCODE_WORKGROUPID, bdim, hbb);
-	break;
-      }
-    case BUILT_IN_HSA_GET_WORKITEM_ID:
-      {
-	hsa_op_immed *bdim = new hsa_op_immed (gimple_call_arg (stmt, 0), true);
-	if (bdim->m_type != BRIG_TYPE_U32)
-	  bdim->get_in_type (BRIG_TYPE_U32, hbb);
-	query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMID, bdim, hbb);
-	break;
-      }
-    case BUILT_IN_HSA_GET_WORKITEM_ABSID:
-      {
-	hsa_op_immed *bdim = new hsa_op_immed (gimple_call_arg (stmt, 0), true);
-	if (bdim->m_type != BRIG_TYPE_U32)
-	  bdim->get_in_type (BRIG_TYPE_U32, hbb);
-	query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMABSID, bdim, hbb);
-	break;
-      }
+    case BUILT_IN_HSA_WORKGROUPID:
+      query_hsa_grid_dim (stmt, BRIG_OPCODE_WORKGROUPID, hbb);
+      break;
+    case BUILT_IN_HSA_WORKITEMID:
+      query_hsa_grid_dim (stmt, BRIG_OPCODE_WORKITEMID, hbb);
+      break;
+    case BUILT_IN_HSA_WORKITEMABSID:
+      query_hsa_grid_dim (stmt, BRIG_OPCODE_WORKITEMABSID, hbb);
+      break;
 
     case BUILT_IN_GOMP_BARRIER:
       hbb->append_insn (new hsa_insn_br (0, BRIG_OPCODE_BARRIER, BRIG_TYPE_NONE,
@@ -5825,13 +5886,13 @@  gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb)
       }
     case BUILT_IN_OMP_GET_THREAD_NUM:
       {
-	query_hsa_grid (stmt, BRIG_OPCODE_WORKITEMABSID, 0, hbb);
+	query_hsa_grid_nodim (stmt, BRIG_OPCODE_WORKITEMFLATABSID, hbb);
 	break;
       }
 
     case BUILT_IN_OMP_GET_NUM_THREADS:
       {
-	query_hsa_grid (stmt, BRIG_OPCODE_GRIDSIZE, 0, hbb);
+	gen_get_num_threads (stmt, hbb);
 	break;
       }
     case BUILT_IN_GOMP_TEAMS:
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 7853143..5e6ba3f 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -13553,16 +13553,16 @@  grid_expand_omp_for_loop (struct omp_region *kfor, bool intra_group)
 	{
 	  gcc_checking_assert (!intra_group);
 	  threadid = build_call_expr (builtin_decl_explicit
-				      (BUILT_IN_HSA_GET_WORKGROUP_ID), 1,
+				      (BUILT_IN_HSA_WORKGROUPID), 1,
 				      build_int_cstu (unsigned_type_node, dim));
 	}
       else if (intra_group)
 	threadid = build_call_expr (builtin_decl_explicit
-				    (BUILT_IN_HSA_GET_WORKITEM_ID), 1,
+				    (BUILT_IN_HSA_WORKITEMID), 1,
 				    build_int_cstu (unsigned_type_node, dim));
       else
 	threadid = build_call_expr (builtin_decl_explicit
-				    (BUILT_IN_HSA_GET_WORKITEM_ABSID), 1,
+				    (BUILT_IN_HSA_WORKITEMABSID), 1,
 				    build_int_cstu (unsigned_type_node, dim));
       threadid = fold_convert (itype, threadid);
       threadid = force_gimple_operand_gsi (&gsi, threadid, true, NULL_TREE,