re PR hsa/70399 (HSA: Wrong emission of st_align(4)_u8 HSAIL insn)
authorMartin Liska <mliska@suse.cz>
Thu, 31 Mar 2016 17:28:29 +0000 (19:28 +0200)
committerMartin Liska <marxin@gcc.gnu.org>
Thu, 31 Mar 2016 17:28:29 +0000 (17:28 +0000)
Fix PR hsa/70399

PR hsa/70399
* hsa-brig.c (hsa_op_immed::emit_to_buffer): Emit either
a tree value or an immediate integer value to a buffer
that is eventually copied to a BRIG section.
(emit_immediate_operand): Call the function here.
* hsa-dump.c (dump_hsa_immed): Remove checking assert.
* hsa-gen.c (hsa_op_immed::hsa_op_immed): Remove initialization
of class' fields that are removed.
(hsa_op_immed::~hsa_op_immed): Remove deinitialization.
* hsa.h (class hsa_op_immed): Remove m_brig_repr and
m_brig_repr_size fields.

From-SVN: r234647

gcc/ChangeLog
gcc/hsa-brig.c
gcc/hsa-dump.c
gcc/hsa-gen.c
gcc/hsa.h

index 822ad343105d3c6fb2217cfdcc1b627d775cc28b..dac7727950b024b4857963d25c4db7ba1ca48b54 100644 (file)
@@ -1,3 +1,17 @@
+2016-03-31  Martin Liska  <mliska@suse.cz>
+
+       PR hsa/70399
+       * hsa-brig.c (hsa_op_immed::emit_to_buffer): Emit either
+       a tree value or an immediate integer value to a buffer
+       that is eventually copied to a BRIG section.
+       (emit_immediate_operand): Call the function here.
+       * hsa-dump.c (dump_hsa_immed): Remove checking assert.
+       * hsa-gen.c (hsa_op_immed::hsa_op_immed): Remove initialization
+       of class' fields that are removed.
+       (hsa_op_immed::~hsa_op_immed): Remove deinitialization.
+       * hsa.h (class hsa_op_immed): Remove m_brig_repr and
+       m_brig_repr_size fields.
+
 2016-03-31  Martin Liska  <mliska@suse.cz>
 
        PR hsa/70391
index ee587dbc066ce12a3667511a5155bf2a5d7c42df..018b7be12fb6d0348a79e57f7e716dad0bc910a5 100644 (file)
@@ -929,62 +929,101 @@ emit_immediate_scalar_to_buffer (tree value, char *data, unsigned need_len)
   return len;
 }
 
-void
-hsa_op_immed::emit_to_buffer (tree value)
+char *
+hsa_op_immed::emit_to_buffer (unsigned *brig_repr_size)
 {
-  unsigned total_len = m_brig_repr_size;
-
-  /* As we can have a constructor with fewer elements, fill the memory
-     with zeros.  */
-  m_brig_repr = XCNEWVEC (char, total_len);
-  char *p = m_brig_repr;
+  char *brig_repr;
+  *brig_repr_size = hsa_get_imm_brig_type_len (m_type);
 
-  if (TREE_CODE (value) == VECTOR_CST)
+  if (m_tree_value != NULL_TREE)
     {
-      int i, num = VECTOR_CST_NELTS (value);
-      for (i = 0; i < num; i++)
+      /* Update brig_repr_size for special tree values.  */
+      if (TREE_CODE (m_tree_value) == STRING_CST)
+       *brig_repr_size = TREE_STRING_LENGTH (m_tree_value);
+      else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
+       *brig_repr_size
+         = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (m_tree_value)));
+
+      unsigned total_len = *brig_repr_size;
+
+      /* As we can have a constructor with fewer elements, fill the memory
+        with zeros.  */
+      brig_repr = XCNEWVEC (char, total_len);
+      char *p = brig_repr;
+
+      if (TREE_CODE (m_tree_value) == VECTOR_CST)
        {
+         int i, num = VECTOR_CST_NELTS (m_tree_value);
+         for (i = 0; i < num; i++)
+           {
+             tree v = VECTOR_CST_ELT (m_tree_value, i);
+             unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
+             total_len -= actual;
+             p += actual;
+           }
+         /* Vectors should have the exact size.  */
+         gcc_assert (total_len == 0);
+       }
+      else if (TREE_CODE (m_tree_value) == STRING_CST)
+       memcpy (brig_repr, TREE_STRING_POINTER (m_tree_value),
+               TREE_STRING_LENGTH (m_tree_value));
+      else if (TREE_CODE (m_tree_value) == COMPLEX_CST)
+       {
+         gcc_assert (total_len % 2 == 0);
          unsigned actual;
          actual
-           = emit_immediate_scalar_to_buffer (VECTOR_CST_ELT (value, i), p, 0);
-         total_len -= actual;
+           = emit_immediate_scalar_to_buffer (TREE_REALPART (m_tree_value), p,
+                                              total_len / 2);
+
+         gcc_assert (actual == total_len / 2);
          p += actual;
+
+         actual
+           = emit_immediate_scalar_to_buffer (TREE_IMAGPART (m_tree_value), p,
+                                              total_len / 2);
+         gcc_assert (actual == total_len / 2);
        }
-      /* Vectors should have the exact size.  */
-      gcc_assert (total_len == 0);
-    }
-  else if (TREE_CODE (value) == STRING_CST)
-    memcpy (m_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 if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
+       {
+         unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value));
+         for (unsigned i = 0; i < len; i++)
+           {
+             tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
+             unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
+             total_len -= actual;
+             p += actual;
+           }
+       }
+      else
+       emit_immediate_scalar_to_buffer (m_tree_value, p, total_len);
     }
-  else if (TREE_CODE (value) == CONSTRUCTOR)
+  else
     {
-      unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (value));
-      for (unsigned i = 0; i < len; i++)
+      hsa_bytes bytes;
+
+      switch (*brig_repr_size)
        {
-         tree v = CONSTRUCTOR_ELT (value, i)->value;
-         unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
-         total_len -= actual;
-         p += actual;
+       case 1:
+         bytes.b8 = (uint8_t) m_int_value;
+         break;
+       case 2:
+         bytes.b16 = (uint16_t) m_int_value;
+         break;
+       case 4:
+         bytes.b32 = (uint32_t) m_int_value;
+         break;
+       case 8:
+         bytes.b64 = (uint64_t) m_int_value;
+         break;
+       default:
+         gcc_unreachable ();
        }
+
+      brig_repr = XNEWVEC (char, *brig_repr_size);
+      memcpy (brig_repr, &bytes, *brig_repr_size);
     }
-  else
-    emit_immediate_scalar_to_buffer (value, p, total_len);
+
+  return brig_repr;
 }
 
 /* Emit an immediate BRIG operand IMM.  The BRIG type of the immediate might
@@ -996,17 +1035,21 @@ hsa_op_immed::emit_to_buffer (tree value)
 static void
 emit_immediate_operand (hsa_op_immed *imm)
 {
+  unsigned brig_repr_size;
+  char *brig_repr = imm->emit_to_buffer (&brig_repr_size);
   struct BrigOperandConstantBytes out;
 
   memset (&out, 0, sizeof (out));
   out.base.byteCount = lendian16 (sizeof (out));
   out.base.kind = lendian16 (BRIG_KIND_OPERAND_CONSTANT_BYTES);
-  uint32_t byteCount = lendian32 (imm->m_brig_repr_size);
+  uint32_t byteCount = lendian32 (brig_repr_size);
   out.type = lendian16 (imm->m_type);
   out.bytes = lendian32 (brig_data.add (&byteCount, sizeof (byteCount)));
   brig_operand.add (&out, sizeof (out));
-  brig_data.add (imm->m_brig_repr, imm->m_brig_repr_size);
+  brig_data.add (brig_repr, brig_repr_size);
   brig_data.round_size_up (4);
+
+  free (brig_repr);
 }
 
 /* Emit a register BRIG operand REG.  */
index d33ac4b7857e7ebd8d9875a641df53cf4193de94..71b971234d4cf1219c851e7ea74ab07cd70bae61 100644 (file)
@@ -647,8 +647,6 @@ dump_hsa_immed (FILE *f, hsa_op_immed *imm)
     print_generic_expr (f, imm->m_tree_value, 0);
   else
     {
-      gcc_checking_assert (imm->m_brig_repr_size <= 8);
-
       if (unsigned_int_type)
        fprintf (f, HOST_WIDE_INT_PRINT_DEC, imm->m_int_value);
       else
index 4c86023d08808697ce1757217a9f23d7ac3e0eb0..bc95c5c1955139e4a84655b9be2b1b258b809bbe 100644 (file)
@@ -1075,8 +1075,7 @@ hsa_op_with_type::get_in_type (BrigType16_t dtype, hsa_bb *hbb)
 hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int)
   : hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES,
                      hsa_type_for_tree_type (TREE_TYPE (tree_val), NULL,
-                                             min32int)),
-  m_brig_repr (NULL)
+                                             min32int))
 {
   if (hsa_seen_error ())
     return;
@@ -1086,30 +1085,20 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int)
                           || TREE_CODE (tree_val) == INTEGER_CST))
                       || TREE_CODE (tree_val) == CONSTRUCTOR);
   m_tree_value = tree_val;
-  m_brig_repr_size = hsa_get_imm_brig_type_len (m_type);
 
-  if (TREE_CODE (m_tree_value) == STRING_CST)
-    m_brig_repr_size = TREE_STRING_LENGTH (m_tree_value);
-  else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
-    {
-      m_brig_repr_size
-       = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (m_tree_value)));
-
-      /* Verify that all elements of a constructor are constants.  */
-      for (unsigned i = 0;
-          i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++)
-       {
-         tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
-         if (!CONSTANT_CLASS_P (v))
-           {
-             HSA_SORRY_AT (EXPR_LOCATION (tree_val),
-                           "HSA ctor should have only constants");
-             return;
-           }
-       }
-    }
-
-  emit_to_buffer (m_tree_value);
+  /* Verify that all elements of a constructor are constants.  */
+  if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
+    for (unsigned i = 0;
+        i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++)
+      {
+       tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
+       if (!CONSTANT_CLASS_P (v))
+         {
+           HSA_SORRY_AT (EXPR_LOCATION (tree_val),
+                         "HSA ctor should have only constants");
+           return;
+         }
+      }
 }
 
 /* Constructor of class representing HSA immediate values.  INTEGER_VALUE is the
@@ -1117,38 +1106,14 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int)
 
 hsa_op_immed::hsa_op_immed (HOST_WIDE_INT integer_value, BrigType16_t type)
   : hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES, type),
-    m_tree_value (NULL), m_brig_repr (NULL)
+    m_tree_value (NULL)
 {
   gcc_assert (hsa_type_integer_p (type));
   m_int_value = integer_value;
-  m_brig_repr_size = hsa_type_bit_size (type) / BITS_PER_UNIT;
-
-  hsa_bytes bytes;
-
-  switch (m_brig_repr_size)
-    {
-    case 1:
-      bytes.b8 = (uint8_t) m_int_value;
-      break;
-    case 2:
-      bytes.b16 = (uint16_t) m_int_value;
-      break;
-    case 4:
-      bytes.b32 = (uint32_t) m_int_value;
-      break;
-    case 8:
-      bytes.b64 = (uint64_t) m_int_value;
-      break;
-    default:
-      gcc_unreachable ();
-    }
-
-  m_brig_repr = XNEWVEC (char, m_brig_repr_size);
-  memcpy (m_brig_repr, &bytes, m_brig_repr_size);
 }
 
 hsa_op_immed::hsa_op_immed ()
-  : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE), m_brig_repr (NULL)
+  : hsa_op_with_type (BRIG_KIND_NONE, BRIG_TYPE_NONE)
 {
 }
 
@@ -1164,7 +1129,6 @@ hsa_op_immed::operator new (size_t)
 
 hsa_op_immed::~hsa_op_immed ()
 {
-  free (m_brig_repr);
 }
 
 /* Change type of the immediate value to T.  */
index b7b1e3c76397280407d749ff30eefe998ab9c2a6..77ef6f184bdc23de09a3b92c06d3f6dfed8b1b03 100644 (file)
--- a/gcc/hsa.h
+++ b/gcc/hsa.h
@@ -175,25 +175,23 @@ public:
   ~hsa_op_immed ();
   void set_type (BrigKind16_t t);
 
+  /* Function returns pointer to a buffer that contains binary representation
+     of the immeadiate value.  The buffer has length of BRIG_SIZE and
+     a caller is responsible for deallocation of the buffer.  */
+  char *emit_to_buffer (unsigned *brig_size);
+
   /* Value as represented by middle end.  */
   tree m_tree_value;
 
   /* Integer value representation.  */
   HOST_WIDE_INT m_int_value;
 
-  /* Brig data representation.  */
-  char *m_brig_repr;
-
-  /* Brig data representation size in bytes.  */
-  unsigned m_brig_repr_size;
-
 private:
   /* Make the default constructor inaccessible.  */
   hsa_op_immed ();
   /* 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.  */