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