Hello.

In these couple of patches I enhance debugging support for emitted HSAIL.
Starting from now, HSA tree pass contains BRIG offsets that are very
useful in case of a validation error occurs.

Thanks,
Martin
>From c88a7ec95058ad7da71c40723f4cc6b4aff3aa44 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Wed, 30 Sep 2015 13:07:32 +0200
Subject: [PATCH 1/3] HSA: enhance assignment of kernel dispatch debug arg.

gcc/ChangeLog:

2015-09-30  Martin Liska  <mli...@suse.cz>

	* hsa-gen.c (gen_hsa_insns_for_kernel_call): Remove
	assignment of the defaul argument.
	(init_omp_in_prologue): Assign it at the beginning of
	a kernel function.
---
 gcc/hsa-gen.c | 19 +++++++++++--------
 1 file changed, 11 insertions(+), 8 deletions(-)

diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 185b9cc..2446b4c 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -3338,14 +3338,6 @@ gen_hsa_insns_for_kernel_call (hsa_bb *hbb, gcall *call)
   mem = new hsa_insn_mem (BRIG_OPCODE_LD, BRIG_TYPE_U64, shadow_reg, addr);
   hbb->append_insn (mem);
 
-  /* Emit store to debug argument.  */
-  addr = new hsa_op_address (shadow_reg, offsetof (hsa_kernel_dispatch, debug));
-
-  /* Create a magic number that is going to be printed by libgomp.  */
-  c = new hsa_op_immed (1000 + index, BRIG_TYPE_U64);
-  mem = new hsa_insn_mem (BRIG_OPCODE_ST, BRIG_TYPE_U64, c, addr);
-  hbb->append_insn (mem);
-
   /* Load an address of the command queue to a register.  */
   hbb->append_insn (new hsa_insn_comment
 		    ("load base address of command queue"));
@@ -4540,6 +4532,17 @@ init_omp_in_prologue (void)
   basic = new hsa_insn_mem (BRIG_OPCODE_ST, hsa_num_threads->type, threads,
 			    new hsa_op_address (hsa_num_threads));
   prologue->append_insn (basic);
+
+  /* Emit store to debug argument.  */
+  addr = new hsa_op_address (shadow_reg_ptr, offsetof (hsa_kernel_dispatch,
+						       debug));
+
+  /* Create a magic number that is going to be printed by libgomp.  */
+  unsigned index = hsa_get_number_decl_kernel_mappings ();
+  hsa_op_immed *c = new hsa_op_immed (1000 + index, BRIG_TYPE_U64);
+  hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, BRIG_TYPE_U64, c,
+					addr);
+  prologue->append_insn (mem);
 }
 
 /* Go over gimple representation and generate our internal HSA one.  SSA_MAP
-- 
2.5.1

>From efd4668f5da25c52a94bc1f7f42cc2ea1a76f607 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Wed, 30 Sep 2015 13:44:29 +0200
Subject: [PATCH 2/3] HSA: add hsa_set_debug_value function.

gcc/ChangeLog:

2015-10-08  Martin Liska  <mli...@suse.cz>

	* hsa-gen.c (bool hsa_function_representation::has_shadow_reg_p):
	New function.
	(set_debug_value): New function.
	(gen_hsa_insns_for_known_library_call): Handle hsa_set_debug_value
	function.
	(init_omp_in_prologue): Use set_debug_value function.
	* hsa.h (hsa_function_representation::has_shadow_reg_p): Declare
	a new function.
---
 gcc/hsa-gen.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++--------
 gcc/hsa.h     |  4 ++++
 2 files changed, 52 insertions(+), 8 deletions(-)

diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 2446b4c..02587b9 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -239,6 +239,11 @@ hsa_function_representation::get_shadow_reg ()
   return r;
 }
 
+bool hsa_function_representation::has_shadow_reg_p ()
+{
+  return shadow_reg != NULL;
+}
+
 /* Allocate HSA structures that we need only while generating with this.  */
 
 static void
@@ -3259,6 +3264,21 @@ gen_get_team_num (gimple *stmt, hsa_bb *hbb, vec <hsa_op_reg_p> *ssa_map)
   hbb->append_insn (basic);
 }
 
+/* Set VALUE to a shadow kernel debug argument and append a new instruction
+   to HBB basic block.  */
+
+static void
+set_debug_value (hsa_bb *hbb, hsa_op_with_type *value)
+{
+  hsa_op_reg *shadow_reg_ptr = hsa_cfun->get_shadow_reg ();
+
+  hsa_op_address *addr = new hsa_op_address
+    (shadow_reg_ptr, offsetof (hsa_kernel_dispatch, debug));
+  hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, BRIG_TYPE_U64, value,
+					addr);
+  hbb->append_insn (mem);
+}
+
 /* If STMT is a call of a known library function, generate code to perform
    it and return true.  */
 
@@ -3300,6 +3320,31 @@ gen_hsa_insns_for_known_library_call (gimple *stmt, hsa_bb *hbb,
       gen_get_team_num (stmt, hbb, ssa_map);
       return true;
     }
+  else if (strcmp (name, "hsa_set_debug_value") == 0)
+    {
+      /* FIXME: show warning if user uses a different function description.  */
+
+      if (hsa_cfun->has_shadow_reg_p ())
+	{
+	  tree rhs1 = gimple_call_arg (stmt, 0);
+	  hsa_op_with_type *src = hsa_reg_or_immed_for_gimple_op (rhs1, hbb,
+								  ssa_map);
+
+	  BrigType16_t dtype = BRIG_TYPE_U64;
+	  if (hsa_needs_cvt (dtype, src->type))
+	    {
+	      hsa_op_reg *tmp = new hsa_op_reg (dtype);
+	      hbb->append_insn (new hsa_insn_basic (2, BRIG_OPCODE_CVT,
+						    tmp->type, tmp, src));
+	      src = tmp;
+	    }
+	  else
+	    src->type = dtype;
+
+	  set_debug_value (hbb, src);
+	  return true;
+	}
+    }
 
   return false;
 }
@@ -4533,16 +4578,11 @@ init_omp_in_prologue (void)
 			    new hsa_op_address (hsa_num_threads));
   prologue->append_insn (basic);
 
-  /* Emit store to debug argument.  */
-  addr = new hsa_op_address (shadow_reg_ptr, offsetof (hsa_kernel_dispatch,
-						       debug));
-
   /* Create a magic number that is going to be printed by libgomp.  */
   unsigned index = hsa_get_number_decl_kernel_mappings ();
-  hsa_op_immed *c = new hsa_op_immed (1000 + index, BRIG_TYPE_U64);
-  hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, BRIG_TYPE_U64, c,
-					addr);
-  prologue->append_insn (mem);
+
+  /* Emit store to debug argument.  */
+  set_debug_value (prologue, new hsa_op_immed (1000 + index, BRIG_TYPE_U64));
 }
 
 /* Go over gimple representation and generate our internal HSA one.  SSA_MAP
diff --git a/gcc/hsa.h b/gcc/hsa.h
index 1382ac1..243065e 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -911,6 +911,10 @@ public:
   /* Builds a shadow register that is utilized to a kernel dispatch.  */
   hsa_op_reg *get_shadow_reg ();
 
+  /* Return true if we are in a function that has kernel dispatch
+     shadow register.  */
+  bool has_shadow_reg_p ();
+
   /* Name of the function.  */
   char *name;
 
-- 
2.5.1

>From 154bfd46732a8d8525014851de1755cc1e2b51d4 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Wed, 30 Sep 2015 14:56:45 +0200
Subject: [PATCH 3/3] HSA: dump BRIG section offsets in hsagen dump file.

gcc/ChangeLog:

2015-10-08  Martin Liska  <mli...@suse.cz>

	* hsa-brig.c (emit_comment_insn): Do not release comment's
	string.
	(emit_insn): Save BRIG offset.
	(hsa_brig_emit_function): Dump generated HSAIL after BRIG
	emission.
	* hsa-dump.c (dump_hsa_insn): Dump BRIG offset of an
	instruction.
	* hsa-gen.c (hsa_insn_basic::hsa_insn_basic): Initialize
	brig_offset to zero.
	* hsa.h (hsa_insn_basic::brig_offset): New member variable.
---
 gcc/hsa-brig.c | 24 +++++++++++++++++++++++-
 gcc/hsa-dump.c | 32 +++++++++++++++++++-------------
 gcc/hsa-gen.c  |  2 ++
 gcc/hsa.h      |  3 +++
 4 files changed, 47 insertions(+), 14 deletions(-)

diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index 654132d..53c9d32 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -137,6 +137,9 @@ static hash_set <tree> *emitted_declarations;
 /* List of sbr instructions.  */
 static vec <hsa_insn_sbr *> *switch_instructions;
 
+/* List of comment instructions.  */
+static vec <hsa_insn_comment *> *comment_instructions;
+
 struct function_linkage_pair
 {
   function_linkage_pair (tree decl, unsigned int off):
@@ -1627,7 +1630,6 @@ emit_comment_insn (hsa_insn_comment *insn)
   repr.base.kind = htole16 (insn->opcode);
   repr.name = brig_emit_string (insn->comment, '\0', false);
   brig_code.add (&repr, sizeof (repr));
-  insn->release_string ();
 }
 
 /* Emit queue instruction INSN.  */
@@ -1748,6 +1750,9 @@ static void
 emit_insn (hsa_insn_basic *insn)
 {
   gcc_assert (!is_a <hsa_insn_phi *> (insn));
+
+  insn->brig_offset = brig_code.total_size;
+
   if (hsa_insn_signal *signal = dyn_cast <hsa_insn_signal *> (insn))
     {
       emit_signal_insn (signal);
@@ -1805,6 +1810,11 @@ emit_insn (hsa_insn_basic *insn)
     }
   if (hsa_insn_comment *comment = dyn_cast <hsa_insn_comment *> (insn))
     {
+      if (comment_instructions == NULL)
+	comment_instructions = new vec <hsa_insn_comment *> ();
+
+      comment_instructions->safe_push (comment);
+
       emit_comment_insn (comment);
       return;
     }
@@ -1917,8 +1927,20 @@ hsa_brig_emit_function (void)
 	}
     }
 
+  if (dump_file)
+    {
+      fprintf (dump_file, "------- After BRIG emission: -------\n");
+      dump_hsa_cfun (dump_file);
+    }
+
+  if (comment_instructions)
+    for (unsigned i = 0; i < comment_instructions->length (); i++)
+      (*comment_instructions)[i]->release_string ();
+
   delete switch_instructions;
   switch_instructions = NULL;
+  delete comment_instructions;
+  comment_instructions = NULL;
 
   emit_queued_operands ();
 }
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index db44347..e074241 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -791,7 +791,7 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
 	    first = false;
 	  dump_hsa_operand (f, phi->get_op (i), true);
 	}
-      fprintf (f, ">\n");
+      fprintf (f, ">");
     }
   else if (is_a <hsa_insn_signal *> (insn))
     {
@@ -804,7 +804,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       fprintf (f, "_%s ", hsa_type_name (mem->type));
 
       dump_hsa_operands (f, mem);
-      fprintf (f, "\n");
     }
 
   else if (is_a <hsa_insn_atomic *> (insn))
@@ -829,7 +828,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       fprintf (f, "_%s ", hsa_type_name (mem->type));
 
       dump_hsa_operands (f, mem);
-      fprintf (f, "\n");
     }
   else if (is_a <hsa_insn_mem *> (insn))
     {
@@ -846,7 +844,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       dump_hsa_operand (f, mem->get_op (0));
       fprintf (f, ", ");
       dump_hsa_address (f, addr);
-      fprintf (f, "\n");
     }
   else if (insn->opcode == BRIG_OPCODE_LDA)
     {
@@ -860,7 +857,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       dump_hsa_operand (f, insn->get_op (0));
       fprintf (f, ", ");
       dump_hsa_address (f, addr);
-      fprintf (f, "\n");
     }
   else if (is_a <hsa_insn_seg *> (insn))
     {
@@ -871,7 +867,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       dump_hsa_reg (f, as_a <hsa_op_reg *> (seg->get_op (0)));
       fprintf (f, ", ");
       dump_hsa_operand (f, seg->get_op (1));
-      fprintf (f, "\n");
     }
   else if (is_a <hsa_insn_cmp *> (insn))
     {
@@ -891,7 +886,6 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       dump_hsa_operand (f, cmp->get_op (1));
       fprintf (f, ", ");
       dump_hsa_operand (f, cmp->get_op (2));
-      fprintf (f, "\n");
     }
   else if (is_a <hsa_insn_br *> (insn))
     {
@@ -914,7 +908,7 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
 	    target = e->dest;
 	    break;
 	  }
-      fprintf (f, "BB %i\n", hsa_bb_for_bb (target)->index);
+      fprintf (f, "BB %i", hsa_bb_for_bb (target)->index);
     }
   else if (is_a <hsa_insn_sbr *> (insn))
     {
@@ -931,7 +925,7 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
 	    fprintf (f, ", ");
 	}
 
-      fprintf (f, "]\n");
+      fprintf (f, "]");
     }
   else if (is_a <hsa_insn_arg_block *> (insn))
     {
@@ -948,7 +942,7 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
       if (!start_p)
 	*indent -= 2;
 
-      fprintf (f, "%c\n", c);
+      fprintf (f, "%c", c);
     }
   else if (is_a <hsa_insn_call *> (insn))
     {
@@ -968,11 +962,12 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
 	  if (i != call->args_symbols.length () - 1)
 	    fprintf (f, ", ");
 	}
-      fprintf (f, ")\n");
+      fprintf (f, ")");
     }
   else if (is_a <hsa_insn_comment *> (insn))
     {
-      fprintf (f, "%s\n", as_a <hsa_insn_comment *> (insn)->comment);
+      hsa_insn_comment *c = as_a <hsa_insn_comment *> (insn);
+      fprintf (f, "%s", c->comment);
     }
   else
     {
@@ -1001,8 +996,19 @@ dump_hsa_insn (FILE *f, hsa_insn_basic *insn, int *indent)
 	  else
 	    fprintf (f, "UNKNOWN_OP_KIND");
 	}
-      fprintf (f, "\n");
     }
+
+  if (insn->brig_offset)
+    {
+      fprintf (f, "             /* BRIG offset: %u", insn->brig_offset);
+
+      for (unsigned i = 0; i < insn->operand_count (); i++)
+	fprintf (f, ", op%u: %u", i, insn->get_op (i)->brig_op_offset);
+
+      fprintf (f, " */");
+    }
+
+  fprintf (f, "\n");
 }
 
 /* Dump textual representation of HSA IL in HBB to file F.  */
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 02587b9..291d650 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -1047,6 +1047,7 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc)
   bb = NULL;
   number = 0;
   type = BRIG_TYPE_NONE;
+  brig_offset = 0;
 
   if (nops > 0)
     operands.safe_grow_cleared (nops);
@@ -1117,6 +1118,7 @@ hsa_insn_basic::hsa_insn_basic (unsigned nops, int opc, BrigType16_t t,
   prev = next = NULL;
   bb = NULL;
   number = 0;
+  brig_offset = 0;
 
   if (nops > 0)
     operands.safe_grow_cleared (nops);
diff --git a/gcc/hsa.h b/gcc/hsa.h
index 243065e..ce6414a 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -377,6 +377,9 @@ public:
   /* Type of the destination of the operations.  */
   BrigType16_t type;
 
+  /* BRIG offset of the instruction in code section.  */
+  unsigned int brig_offset;
+
 private:
   /* Make the default constructor inaccessible.  */
   hsa_insn_basic () {}
-- 
2.5.1

Reply via email to