mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
c1c341ab92
commit
6f652a5072
|
|
@ -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>
|
2016-03-31 Martin Liska <mliska@suse.cz>
|
||||||
|
|
||||||
PR hsa/70391
|
PR hsa/70391
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
if (m_tree_value != NULL_TREE)
|
||||||
|
{
|
||||||
|
/* 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
|
/* As we can have a constructor with fewer elements, fill the memory
|
||||||
with zeros. */
|
with zeros. */
|
||||||
m_brig_repr = XCNEWVEC (char, total_len);
|
brig_repr = XCNEWVEC (char, total_len);
|
||||||
char *p = m_brig_repr;
|
char *p = brig_repr;
|
||||||
|
|
||||||
if (TREE_CODE (value) == VECTOR_CST)
|
if (TREE_CODE (m_tree_value) == VECTOR_CST)
|
||||||
{
|
{
|
||||||
int i, num = VECTOR_CST_NELTS (value);
|
int i, num = VECTOR_CST_NELTS (m_tree_value);
|
||||||
for (i = 0; i < num; i++)
|
for (i = 0; i < num; i++)
|
||||||
{
|
{
|
||||||
unsigned actual;
|
tree v = VECTOR_CST_ELT (m_tree_value, i);
|
||||||
actual
|
unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
|
||||||
= emit_immediate_scalar_to_buffer (VECTOR_CST_ELT (value, i), p, 0);
|
|
||||||
total_len -= actual;
|
total_len -= actual;
|
||||||
p += actual;
|
p += actual;
|
||||||
}
|
}
|
||||||
/* Vectors should have the exact size. */
|
/* Vectors should have the exact size. */
|
||||||
gcc_assert (total_len == 0);
|
gcc_assert (total_len == 0);
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (value) == STRING_CST)
|
else if (TREE_CODE (m_tree_value) == STRING_CST)
|
||||||
memcpy (m_brig_repr, TREE_STRING_POINTER (value),
|
memcpy (brig_repr, TREE_STRING_POINTER (m_tree_value),
|
||||||
TREE_STRING_LENGTH (value));
|
TREE_STRING_LENGTH (m_tree_value));
|
||||||
else if (TREE_CODE (value) == COMPLEX_CST)
|
else if (TREE_CODE (m_tree_value) == COMPLEX_CST)
|
||||||
{
|
{
|
||||||
gcc_assert (total_len % 2 == 0);
|
gcc_assert (total_len % 2 == 0);
|
||||||
unsigned actual;
|
unsigned actual;
|
||||||
actual
|
actual
|
||||||
= emit_immediate_scalar_to_buffer (TREE_REALPART (value), p,
|
= emit_immediate_scalar_to_buffer (TREE_REALPART (m_tree_value), p,
|
||||||
total_len / 2);
|
total_len / 2);
|
||||||
|
|
||||||
gcc_assert (actual == total_len / 2);
|
gcc_assert (actual == total_len / 2);
|
||||||
p += actual;
|
p += actual;
|
||||||
|
|
||||||
actual
|
actual
|
||||||
= emit_immediate_scalar_to_buffer (TREE_IMAGPART (value), p,
|
= emit_immediate_scalar_to_buffer (TREE_IMAGPART (m_tree_value), p,
|
||||||
total_len / 2);
|
total_len / 2);
|
||||||
gcc_assert (actual == total_len / 2);
|
gcc_assert (actual == total_len / 2);
|
||||||
}
|
}
|
||||||
else if (TREE_CODE (value) == CONSTRUCTOR)
|
else if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
|
||||||
{
|
{
|
||||||
unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (value));
|
unsigned len = vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value));
|
||||||
for (unsigned i = 0; i < len; i++)
|
for (unsigned i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
tree v = CONSTRUCTOR_ELT (value, i)->value;
|
tree v = CONSTRUCTOR_ELT (m_tree_value, i)->value;
|
||||||
unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
|
unsigned actual = emit_immediate_scalar_to_buffer (v, p, 0);
|
||||||
total_len -= actual;
|
total_len -= actual;
|
||||||
p += actual;
|
p += actual;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
emit_immediate_scalar_to_buffer (value, p, total_len);
|
emit_immediate_scalar_to_buffer (m_tree_value, p, total_len);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hsa_bytes bytes;
|
||||||
|
|
||||||
|
switch (*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 ();
|
||||||
|
}
|
||||||
|
|
||||||
|
brig_repr = XNEWVEC (char, *brig_repr_size);
|
||||||
|
memcpy (brig_repr, &bytes, *brig_repr_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,16 +1085,9 @@ 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)
|
|
||||||
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. */
|
/* Verify that all elements of a constructor are constants. */
|
||||||
|
if (TREE_CODE (m_tree_value) == CONSTRUCTOR)
|
||||||
for (unsigned i = 0;
|
for (unsigned i = 0;
|
||||||
i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++)
|
i < vec_safe_length (CONSTRUCTOR_ELTS (m_tree_value)); i++)
|
||||||
{
|
{
|
||||||
|
|
@ -1107,9 +1099,6 @@ hsa_op_immed::hsa_op_immed (tree tree_val, bool min32int)
|
||||||
return;
|
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)
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
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. */
|
||||||
|
|
|
||||||
12
gcc/hsa.h
12
gcc/hsa.h
|
|
@ -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. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue