This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[hsa] Introduce a new ctor for hsa_op_immed.
- From: Martin LiÅka <mliska at suse dot cz>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 8 Sep 2015 22:08:56 +0200
- Subject: [hsa] Introduce a new ctor for hsa_op_immed.
- Authentication-results: sourceware.org; auth=none
Hello.
Following patch adds a new ctor for hsa_op_immed class.
Martin
>From dc72ba0001f5b98c97da9ea5c03fccf2340e893d Mon Sep 17 00:00:00 2001
From: mliska <mliska@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 <mliska@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