Commit 6f652a50 by Martin Liska Committed by Martin Liska

re PR hsa/70399 (HSA: Wrong emission of st_align(4)_u8 HSAIL insn)

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
parent c1c341ab
2016-03-31 Martin Liska <mliska@suse.cz> 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 PR hsa/70391
* hsa-gen.c (hsa_function_representation::update_dominance): New * hsa-gen.c (hsa_function_representation::update_dominance): New
function. function.
......
...@@ -929,62 +929,101 @@ emit_immediate_scalar_to_buffer (tree value, char *data, unsigned need_len) ...@@ -929,62 +929,101 @@ emit_immediate_scalar_to_buffer (tree value, char *data, unsigned need_len)
return len; return len;
} }
void char *
hsa_op_immed::emit_to_buffer (tree value) hsa_op_immed::emit_to_buffer (unsigned *brig_repr_size)
{ {
unsigned total_len = m_brig_repr_size; char *brig_repr;
*brig_repr_size = hsa_get_imm_brig_type_len (m_type);
/* 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;
if (TREE_CODE (value) == VECTOR_CST) if (m_tree_value != NULL_TREE)
{ {
int i, num = VECTOR_CST_NELTS (value); /* Update brig_repr_size for special tree values. */
for (i = 0; i < num; i++) 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; unsigned actual;
actual actual
= emit_immediate_scalar_to_buffer (VECTOR_CST_ELT (value, i), p, 0); = emit_immediate_scalar_to_buffer (TREE_REALPART (m_tree_value), p,
total_len -= actual; total_len / 2);
gcc_assert (actual == total_len / 2);
p += actual; 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. */ else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
gcc_assert (total_len == 0); {
} unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value));
else if (TREE_CODE (value) == STRING_CST) for (unsigned i = 0; i < len; i++)
memcpy (m_brig_repr, TREE_STRING_POINTER (value), {
TREE_STRING_LENGTH (value)); tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
else if (TREE_CODE (value) == COMPLEX_CST) unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
{ total_len -= actual;
gcc_assert (total_len % 2 == 0); p += actual;
unsigned actual; }
actual }
= emit_immediate_scalar_to_buffer (TREE_REALPART (value), p, else
total_len / 2); emit_immediate_scalar_to_buffer (m_tree_value, p, total_len);
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 (value) == CONSTRUCTOR) else
{ {
unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (value)); hsa_bytes bytes;
for (unsigned i = 0; i < len; i++)
switch (*brig_repr_size)
{ {
tree v = CONSTRUCTOR_ELT (value, i)->value; case 1:
unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0); bytes.b8 = (uint8_t) m_int_value;
total_len -= actual; break;
p += actual; 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 /* 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) ...@@ -996,17 +1035,21 @@ hsa_op_immed::emit_to_buffer (tree value)
static void static void
emit_immediate_operand (hsa_op_immed *imm) emit_immediate_operand (hsa_op_immed *imm)
{ {
unsigned brig_repr_size;
char *brig_repr = imm->emit_to_buffer (&brig_repr_size);
struct BrigOperandConstantBytes out; struct BrigOperandConstantBytes out;
memset (&out, 0, sizeof (out)); memset (&out, 0, sizeof (out));
out.base.byteCount = lendian16 (sizeof (out)); out.base.byteCount = lendian16 (sizeof (out));
out.base.kind = lendian16 (BRIG_KIND_OPERAND_CONSTANT_BYTES); 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.type = lendian16 (imm->m_type);
out.bytes = lendian32 (brig_data.add (&byteCount, sizeof (byteCount))); out.bytes = lendian32 (brig_data.add (&byteCount, sizeof (byteCount)));
brig_operand.add (&out, sizeof (out)); 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); brig_data.round_size_up (4);
free (brig_repr);
} }
/* Emit a register BRIG operand REG. */ /* Emit a register BRIG operand REG. */
......
...@@ -647,8 +647,6 @@ dump_hsa_immed (FILE *f, hsa_op_immed *imm) ...@@ -647,8 +647,6 @@ dump_hsa_immed (FILE *f, hsa_op_immed *imm)
print_generic_expr (f, imm->m_tree_value, 0); print_generic_expr (f, imm->m_tree_value, 0);
else else
{ {
gcc_checking_assert (imm->m_brig_repr_size <= 8);
if (unsigned_int_type) if (unsigned_int_type)
fprintf (f, HOST_WIDE_INT_PRINT_DEC, imm->m_int_value); fprintf (f, HOST_WIDE_INT_PRINT_DEC, imm->m_int_value);
else else
......
...@@ -1075,8 +1075,7 @@ hsa_op_with_type::get_in_type (BrigType16_t dtype, hsa_bb *hbb) ...@@ -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_immed::hsa_op_immed (tree tree_val, bool min32int)
: hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES, : hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES,
hsa_type_for_tree_type (TREE_TYPE (tree_val), NULL, hsa_type_for_tree_type (TREE_TYPE (tree_val), NULL,
min32int)), min32int))
m_brig_repr (NULL)
{ {
if (hsa_seen_error ()) if (hsa_seen_error ())
return; return;
...@@ -1086,30 +1085,20 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int) ...@@ -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) == INTEGER_CST))
|| TREE_CODE (tree_val) == CONSTRUCTOR); || TREE_CODE (tree_val) == CONSTRUCTOR);
m_tree_value = tree_val; 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) /* Verify that all elements of a constructor are constants. */
m_brig_repr_size = TREE_STRING_LENGTH (m_tree_value); if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
else if (TREE_CODE (m_tree_value) == CONSTRUCTOR) for (unsigned i = 0;
{ i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++)
m_brig_repr_size {
= tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (m_tree_value))); tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
if (!CONSTANT_CLASS_P (v))
/* Verify that all elements of a constructor are constants. */ {
for (unsigned i = 0; HSA_SORRY_AT (EXPR_LOCATION (tree_val),
i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++) "HSA ctor should have only constants");
{ return;
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);
} }
/* Constructor of class representing HSA immediate values. INTEGER_VALUE is the /* 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) ...@@ -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_immed::hsa_op_immed (HOST_WIDE_INT integer_value, BrigType16_t type)
: hsa_op_with_type (BRIG_KIND_OPERAND_CONSTANT_BYTES, 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)); gcc_assert (hsa_type_integer_p (type));
m_int_value = integer_value; 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_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) ...@@ -1164,7 +1129,6 @@ hsa_op_immed::operator new (size_t)
hsa_op_immed::~hsa_op_immed () hsa_op_immed::~hsa_op_immed ()
{ {
free (m_brig_repr);
} }
/* Change type of the immediate value to T. */ /* Change type of the immediate value to T. */
......
...@@ -175,25 +175,23 @@ public: ...@@ -175,25 +175,23 @@ public:
~hsa_op_immed (); ~hsa_op_immed ();
void set_type (BrigKind16_t t); 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. */ /* Value as represented by middle end. */
tree m_tree_value; tree m_tree_value;
/* Integer value representation. */ /* Integer value representation. */
HOST_WIDE_INT m_int_value; 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: private:
/* Make the default constructor inaccessible. */ /* Make the default constructor inaccessible. */
hsa_op_immed (); hsa_op_immed ();
/* All objects are deallocated by destroying their pool, so make delete /* All objects are deallocated by destroying their pool, so make delete
inaccessible too. */ inaccessible too. */
void operator delete (void *) {} void operator delete (void *) {}
void emit_to_buffer (tree value);
}; };
/* Report whether or not P is a an immediate operand. */ /* Report whether or not P is a an immediate operand. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment