Hello.

Following patch adds a new ctor for hsa_op_immed class.

Martin
>From dc72ba0001f5b98c97da9ea5c03fccf2340e893d Mon Sep 17 00:00:00 2001
From: mliska <mli...@suse.cz>
Date: Fri, 4 Sep 2015 13:33:08 +0200
Subject: [PATCH 1/7] HSA: introduce a new ctor for hsa_op_immed.

gcc/ChangeLog:

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

	* hsa-brig.c (emit_immediate_scalar_to_buffer): Add a new argument.
	(emit_immediate_scalar_to_data_section): Likewise.
	(hsa_op_immed::emit_to_buffer): New function.
	(emit_immediate_operand): Emit prepared byte buffer.
	* hsa-dump.c (dump_hsa_immed): Handle integer values.
	* hsa-gen.c (hsa_deinit_data_for_cfun): Release allocated byte buffers.
	(hsa_op_immed::hsa_op_immed): New.
	(hsa_op_immed::~hsa_op_immed): Likewise.
	(hsa_op_immed::set_type): New function.
	* hsa.h (union hsa_bytes): New
---
 gcc/hsa-brig.c | 96 ++++++++++++++++++++++++++++++----------------------------
 gcc/hsa-dump.c | 17 ++++++++++-
 gcc/hsa-gen.c  | 67 ++++++++++++++++++++++++++++++++++++++--
 gcc/hsa.h      | 24 ++++++++++++++-
 4 files changed, 154 insertions(+), 50 deletions(-)

diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c
index 728430c..0951039 100644
--- a/gcc/hsa-brig.c
+++ b/gcc/hsa-brig.c
@@ -785,7 +785,7 @@ regtype_for_type (BrigType16_t t)
 /* Return the length of the BRIG type TYPE that is going to be streamed out as
    an immediate constant (so it must not be B1).  */
 
-static unsigned
+unsigned
 hsa_get_imm_brig_type_len (BrigType16_t type)
 {
   BrigType16_t base_type = type & BRIG_TYPE_BASE_MASK;
@@ -833,20 +833,14 @@ hsa_get_imm_brig_type_len (BrigType16_t type)
     }
 }
 
-/* Emit one scalar VALUE to the data BRIG section.  If NEED_LEN is not equal to
-   zero, shrink or extend the value to NEED_LEN bytes.  Return how many bytes
-   were written.  */
+/* Emit one scalar VALUE to the buffer DATA intended for BRIG emission.
+   If NEED_LEN is not equal to zero, shrink or extend the value
+   to NEED_LEN bytes.  Return how many bytes were written.  */
 
 static int
-emit_immediate_scalar_to_data_section (tree value, unsigned need_len)
+emit_immediate_scalar_to_buffer (tree value, char *data, unsigned need_len)
 {
-  union
-  {
-    uint8_t b8;
-    uint16_t b16;
-    uint32_t b32;
-    uint64_t b64;
-  } bytes;
+  union hsa_bytes bytes;
 
   memset (&bytes, 0, sizeof (bytes));
   tree type = TREE_TYPE (value);
@@ -905,10 +899,51 @@ emit_immediate_scalar_to_data_section (tree value, unsigned need_len)
   else
     len = need_len;
 
-  brig_data.add (&bytes, len);
+  memcpy (data, &bytes, len);
   return len;
 }
 
+void
+hsa_op_immed::emit_to_buffer (tree value)
+{
+  unsigned total_len = brig_repr_size;
+  brig_repr = XNEWVEC (char, total_len);
+  char *p = brig_repr;
+
+  if (TREE_CODE (value) == VECTOR_CST)
+    {
+      int i, num = VECTOR_CST_NELTS (value);
+      for (i = 0; i < num; i++)
+	{
+	  unsigned actual;
+	  actual = emit_immediate_scalar_to_buffer
+	    (VECTOR_CST_ELT (value, i), p, 0);
+	  total_len -= actual;
+	  p += actual;
+	}
+      /* Vectors should have the exact size.  */
+      gcc_assert (total_len == 0);
+    }
+  else if (TREE_CODE (value) == STRING_CST)
+    memcpy (brig_repr, TREE_STRING_POINTER (value), TREE_STRING_LENGTH (value));
+  else if (TREE_CODE (value) == COMPLEX_CST)
+    {
+      gcc_assert (total_len % 2 == 0);
+      unsigned actual;
+      actual = emit_immediate_scalar_to_buffer
+	(TREE_REALPART (value), p, total_len / 2);
+
+      gcc_assert (actual == total_len / 2);
+      p += actual;
+
+      actual = emit_immediate_scalar_to_buffer
+	(TREE_IMAGPART (value), p, total_len / 2);
+      gcc_assert (actual == total_len / 2);
+    }
+  else
+    emit_immediate_scalar_to_buffer (value, p, total_len);
+}
+
 /* Emit an immediate BRIG operand IMM.  The BRIG type of the immediate might
    have been massaged to comply with various HSA/BRIG type requirements, so the
    only important aspect of that is the length (because HSAIL might expect
@@ -919,46 +954,15 @@ static void
 emit_immediate_operand (hsa_op_immed *imm)
 {
   struct BrigOperandConstantBytes out;
-  unsigned total_len = hsa_get_imm_brig_type_len (imm->type);
-
-  if (TREE_CODE (imm->value) == STRING_CST)
-    total_len = TREE_STRING_LENGTH (imm->value);
 
   memset (&out, 0, sizeof (out));
   out.base.byteCount = htole16 (sizeof (out));
   out.base.kind = htole16 (BRIG_KIND_OPERAND_CONSTANT_BYTES);
-  uint32_t byteCount = htole32 (total_len);
+  uint32_t byteCount = htole32 (imm->brig_repr_size);
   out.type = htole16 (imm->type);
   out.bytes = htole32 (brig_data.add (&byteCount, sizeof (byteCount)));
   brig_operand.add (&out, sizeof(out));
-
-  if (TREE_CODE (imm->value) == VECTOR_CST)
-    {
-      int i, num = VECTOR_CST_NELTS (imm->value);
-      for (i = 0; i < num; i++)
-	{
-	  unsigned actual;
-	  actual = emit_immediate_scalar_to_data_section
-	    (VECTOR_CST_ELT (imm->value, i), 0);
-	  total_len -= actual;
-	}
-      /* Vectors should have the exact size.  */
-      gcc_assert (total_len == 0);
-    }
-  else if (TREE_CODE (imm->value) == STRING_CST)
-    brig_data.add (TREE_STRING_POINTER (imm->value),
-		   TREE_STRING_LENGTH (imm->value));
-  else if (TREE_CODE (imm->value) == COMPLEX_CST)
-    {
-      gcc_assert (total_len % 2 == 0);
-      emit_immediate_scalar_to_data_section (TREE_REALPART (imm->value),
-					     total_len / 2);
-      emit_immediate_scalar_to_data_section (TREE_IMAGPART (imm->value),
-					     total_len / 2);
-    }
-  else
-    emit_immediate_scalar_to_data_section (imm->value, total_len);
-
+  brig_data.add (imm->brig_repr, imm->brig_repr_size);
   brig_data.round_size_up (4);
 }
 
diff --git a/gcc/hsa-dump.c b/gcc/hsa-dump.c
index 6a8844d..71e7fa3 100644
--- a/gcc/hsa-dump.c
+++ b/gcc/hsa-dump.c
@@ -677,7 +677,22 @@ dump_hsa_reg (FILE *f, hsa_op_reg *reg, bool dump_type = false)
 static void
 dump_hsa_immed (FILE *f, hsa_op_immed *imm)
 {
-  print_generic_expr (f, imm->value, 0);
+  bool unsigned_int_type = (BRIG_TYPE_U8 | BRIG_TYPE_U16 | BRIG_TYPE_U32
+    | BRIG_TYPE_U64) & imm->type;
+
+  if (imm->tree_value)
+    print_generic_expr (f, imm->tree_value, 0);
+  else
+    {
+      gcc_checking_assert (imm->brig_repr_size <= 8);
+
+      if (unsigned_int_type)
+	fprintf (f, HOST_WIDE_INT_PRINT_DEC, imm->int_value);
+      else
+	fprintf (f, HOST_WIDE_INT_PRINT_UNSIGNED,
+		 (unsigned HOST_WIDE_INT)imm->int_value);
+    }
+
   fprintf (f, " (%s)", hsa_type_name (imm->type));
 }
 
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 5fc46c4..ed1e121 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -163,6 +163,7 @@ static object_allocator<hsa_symbol> *hsa_allocp_symbols;
    a destruction.  */
 static vec <hsa_op_code_list *> hsa_list_operand_code_list;
 static vec <hsa_op_reg *> hsa_list_operand_reg;
+static vec <hsa_op_immed*> hsa_list_operand_immed;
 
 /* Constructor of class representing global HSA function/kernel information and
    state.  */
@@ -319,8 +320,12 @@ hsa_deinit_data_for_cfun (void)
   for (unsigned int i = 0; i < hsa_list_operand_reg.length (); i++)
     hsa_list_operand_reg[i]->~hsa_op_reg ();
 
+  for (unsigned int i = 0; i < hsa_list_operand_immed.length (); i++)
+    hsa_list_operand_immed[i]->~hsa_op_immed ();
+
   hsa_list_operand_code_list.release ();
   hsa_list_operand_reg.release ();
+  hsa_list_operand_immed.release ();
 
   delete hsa_allocp_operand_address;
   delete hsa_allocp_operand_immed;
@@ -757,7 +762,50 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int)
   gcc_checking_assert (is_gimple_min_invariant (tree_val)
 		       && (!POINTER_TYPE_P (TREE_TYPE (tree_val))
 			   || TREE_CODE (tree_val) == INTEGER_CST));
-  value = tree_val;
+  tree_value = tree_val;
+
+  brig_repr_size = hsa_get_imm_brig_type_len (type);
+
+  if (TREE_CODE (tree_value) == STRING_CST)
+    brig_repr_size = TREE_STRING_LENGTH (tree_value);
+
+  emit_to_buffer (tree_value);
+  hsa_list_operand_immed.safe_push (this);
+}
+
+/* Constructor of class representing HSA immediate values.  INTEGER_VALUE is the
+   integer representation of the immediate value.  TYPE is BRIG type.  */
+
+hsa_op_immed::hsa_op_immed (HOST_WIDE_INT integer_value, BrigKind16_t type)
+  : hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES, type), tree_value (NULL)
+{
+  gcc_assert (hsa_type_integer_p (type));
+  int_value = integer_value;
+  brig_repr_size = hsa_type_bit_size (type) / BITS_PER_UNIT;
+
+  hsa_bytes bytes;
+
+  switch (brig_repr_size)
+    {
+    case 1:
+      bytes.b8 = (uint8_t) int_value;
+      break;
+    case 2:
+      bytes.b16 = (uint16_t) int_value;
+      break;
+    case 4:
+      bytes.b32 = (uint32_t) int_value;
+      break;
+    case 8:
+      bytes.b64 = (uint64_t) int_value;
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
+  brig_repr = XNEWVEC (char, brig_repr_size);
+  memcpy (brig_repr, &bytes, brig_repr_size);
+  hsa_list_operand_immed.safe_push (this);
 }
 
 /* New operator to allocate immediate operands from pool alloc.  */
@@ -768,6 +816,21 @@ hsa_op_immed::operator new (size_t)
   return hsa_allocp_operand_immed->vallocate ();
 }
 
+/* Destructor.  */
+
+hsa_op_immed::~hsa_op_immed ()
+{
+  free (brig_repr);
+}
+
+/* Change type of the immediate value to T.  */
+
+void
+hsa_op_immed::set_type (BrigType16_t t)
+{
+  type = t;
+}
+
 /* Constructor of class representing HSA registers and pseudo-registers.  T is
    the BRIG type fo the new register.  */
 
@@ -2340,7 +2403,7 @@ gen_hsa_binary_operation (int opcode, hsa_op_reg *dest,
     {
       hsa_op_immed *i = dyn_cast <hsa_op_immed *> (op2);
       op2 = new hsa_op_immed
-	(build_int_cstu (unsigned_type_node, TREE_INT_CST_LOW (i->value)));
+	(build_int_cstu (unsigned_type_node, TREE_INT_CST_LOW (i->tree_value)));
     }
 
   hsa_insn_basic *insn = new hsa_insn_basic (3, opcode, dest->type, dest,
diff --git a/gcc/hsa.h b/gcc/hsa.h
index 0b435d6..e687672 100644
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -127,10 +127,22 @@ class hsa_op_immed : public hsa_op_with_type
 {
 public:
   hsa_op_immed (tree tree_val, bool min32int = true);
+  hsa_op_immed (HOST_WIDE_INT int_value, BrigKind16_t type);
   void *operator new (size_t);
+  ~hsa_op_immed ();
+  void set_type (BrigKind16_t t);
 
   /* Value as represented by middle end.  */
-  tree value;
+  tree tree_value;
+
+  /* Integer value representation.  */
+  HOST_WIDE_INT int_value;
+
+  /* Brig data representation.  */
+  char *brig_repr;
+
+  /* Brig data representation size in bytes.  */
+  unsigned brig_repr_size;
 
 private:
   /* Make the default constructor inaccessible.  */
@@ -138,6 +150,7 @@ private:
   /* All objects are deallocated by destroying their pool, so make delete
      inaccessible too.  */
   void operator delete (void *) {}
+  void emit_to_buffer (tree value);
 };
 
 /* Report whether or not P is a an immediate operand.  */
@@ -1007,10 +1020,19 @@ void hsa_regalloc (void);
 void hsa_brig_emit_function (void);
 void hsa_output_brig (void);
 BrigType16_t bittype_for_type (BrigType16_t t);
+unsigned hsa_get_imm_brig_type_len (BrigType16_t type);
 
 /*  In hsa-dump.c.  */
 const char *hsa_seg_name (BrigSegment8_t);
 void dump_hsa_bb (FILE *, hsa_bb *);
 void dump_hsa_cfun (FILE *);
 
+union hsa_bytes
+{
+  uint8_t b8;
+  uint16_t b16;
+  uint32_t b32;
+  uint64_t b64;
+};
+
 #endif /* HSA_H */
-- 
2.4.6

Reply via email to