From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 78183 invoked by alias); 12 Oct 2015 17:46:34 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 78172 invoked by uid 89); 12 Oct 2015 17:46:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.8 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Mon, 12 Oct 2015 17:46:31 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 9C7FCAAC7 for ; Mon, 12 Oct 2015 17:46:27 +0000 (UTC) Date: Mon, 12 Oct 2015 17:46:00 -0000 From: Martin Jambor To: GCC Patches Cc: Martin Liska Subject: [hsa] Introduce alignment to hsa_insn_mem Message-ID: <20151012174628.GE14248@virgil.suse.cz> Mail-Followup-To: GCC Patches , Martin Liska MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline User-Agent: Mutt/1.5.24 (2015-08-30) X-IsSubscribed: yes X-SW-Source: 2015-10/txt/msg01162.txt.bz2 Hi, the newest version of the finalizer actually honors alignment information and therefore the compiler has to provide the correct values, which is what the following patch does. We may need to be more conservative in the cases when we expand memset and memcpy inline, but I have committed this patch anyway, because everywhere else it should be correct and the performance without it was horrible. Thanks, Martin 2015-10-12 Martin Jambor * hsa-brig.c (get_alignment): Removed. (emit_directive_variable): Use hsa_natural_alignment. (emit_memory_insn): Use alignment from mem. * hsa-gen.c (hsa_insn_mem::hsa_insn_mem): Initialize align. (gen_hsa_insns_for_bitfield_load): New argument, set alignment. (gen_hsa_insns_for_load): Set alignment. (gen_hsa_insns_for_store): Likewise. * hsa.c (hsa_alignment_encoding): New function. (hsa_natural_alignment): Likewise. (hsa_insn_mem::set_align): Likewise. * hsa.h (hsa_insn_mem): New members align and set_align. (hsa_alignment_encoding): Declare. (hsa_natural_alignment): Likewise. --- gcc/hsa-brig.c | 29 ++++------------------------- gcc/hsa-gen.c | 23 +++++++++++++++++------ gcc/hsa.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ gcc/hsa.h | 9 +++++++++ 4 files changed, 79 insertions(+), 31 deletions(-) diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c index b6eabfd..49d9e1d 100644 --- a/gcc/hsa-brig.c +++ b/gcc/hsa-brig.c @@ -477,29 +477,6 @@ brig_release_data (void) brig_initialized = 0; } -/* Find the alignment base on the type. */ - -static BrigAlignment8_t -get_alignment (BrigType16_t type) -{ - unsigned bit_size ; - bit_size = hsa_type_bit_size (type & ~BRIG_TYPE_ARRAY); - - if (bit_size == 1) - return BRIG_ALIGNMENT_1; - if (bit_size == 8) - return BRIG_ALIGNMENT_1; - if (bit_size == 16) - return BRIG_ALIGNMENT_2; - if (bit_size == 32) - return BRIG_ALIGNMENT_4; - if (bit_size == 64) - return BRIG_ALIGNMENT_8; - if (bit_size == 128) - return BRIG_ALIGNMENT_16; - gcc_unreachable (); -} - /* Enqueue operation OP. Return the offset at which it will be stored. */ static unsigned int @@ -595,7 +572,9 @@ emit_directive_variable (struct hsa_symbol *symbol) dirvar.init = 0; dirvar.type = htole16 (symbol->type); dirvar.segment = symbol->segment; - dirvar.align = get_alignment (dirvar.type); + /* TODO: Once we are able to access global variables, we must copy their + alignment. */ + dirvar.align = MAX (hsa_natural_alignment (dirvar.type), BRIG_ALIGNMENT_4); dirvar.linkage = symbol->linkage; dirvar.dim.lo = (uint32_t) symbol->dim; dirvar.dim.hi = (uint32_t) ((unsigned long long) symbol->dim >> 32); @@ -1161,7 +1140,7 @@ emit_memory_insn (hsa_insn_mem *mem) repr.segment = BRIG_SEGMENT_FLAT; repr.modifier.allBits = 0 ; repr.equivClass = mem->equiv_class; - repr.align = BRIG_ALIGNMENT_1; + repr.align = mem->align; if (mem->opcode == BRIG_OPCODE_LD) repr.width = BRIG_WIDTH_1; else diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index cf36882..d20efd8 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-cfg.h" #include "cfgloop.h" #include "cfganal.h" +#include "builtins.h" /* Print a warning message and set that we have seen an error. */ @@ -1324,6 +1325,7 @@ hsa_insn_mem::hsa_insn_mem (int opc, BrigType16_t t, hsa_op_base *arg0, gcc_checking_assert (opc == BRIG_OPCODE_LD || opc == BRIG_OPCODE_ST || opc == BRIG_OPCODE_EXPAND); + align = hsa_natural_alignment (t); equiv_class = 0; } @@ -1337,6 +1339,7 @@ hsa_insn_mem::hsa_insn_mem (unsigned nops, int opc, BrigType16_t t, hsa_op_base *arg2, hsa_op_base *arg3) : hsa_insn_basic (nops, opc, t, arg0, arg1, arg2, arg3) { + align = hsa_natural_alignment (t); equiv_class = 0; } @@ -2007,18 +2010,20 @@ gen_hsa_insns_for_bitfield (hsa_op_reg *dest, hsa_op_reg *value_reg, /* Generate HSAIL instructions loading a bit field into register DEST. ADDR is - prepared memory address which is used to load the bit field. To identify - a bit field BITPOS is offset to the loaded memory and BITSIZE is number - of bits of the bit field. Add instructions to HBB. */ + prepared memory address which is used to load the bit field. To identify a + bit field BITPOS is offset to the loaded memory and BITSIZE is number of + bits of the bit field. Add instructions to HBB. Load must be performaed in + alignment ALIGN. */ static void gen_hsa_insns_for_bitfield_load (hsa_op_reg *dest, hsa_op_address *addr, - HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, - hsa_bb *hbb) + HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos, + hsa_bb *hbb, BrigAlignment8_t align) { hsa_op_reg *value_reg = new hsa_op_reg (dest->type); hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, dest->type, value_reg, addr); + mem->set_align (align); hbb->append_insn (mem); gen_hsa_insns_for_bitfield (dest, value_reg, bitsize, bitpos, hbb); } @@ -2140,8 +2145,11 @@ gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb, return; } + BrigAlignment8_t req_align; + req_align = hsa_alignment_encoding (get_object_alignment (rhs)); if (bitsize || bitpos) - gen_hsa_insns_for_bitfield_load (dest, addr, bitsize, bitpos, hbb); + gen_hsa_insns_for_bitfield_load (dest, addr, bitsize, bitpos, hbb, + req_align); else { BrigType16_t mtype; @@ -2150,6 +2158,7 @@ gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb, false)); hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dest, addr); + mem->set_align (req_align); hbb->append_insn (mem); } } @@ -2221,6 +2230,7 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb, /* Load value from memory. */ hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, mem_type, value_reg, addr); + mem->set_align (hsa_alignment_encoding (get_object_alignment (lhs))); hbb->append_insn (mem); /* AND the loaded value with prepared mask. */ @@ -2263,6 +2273,7 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb, } hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src, addr); + mem->set_align (hsa_alignment_encoding (get_object_alignment (lhs))); /* XXX The HSAIL disasm has another constraint: if the source is an immediate then it must match the destination type. If diff --git a/gcc/hsa.c b/gcc/hsa.c index 7da7b6c..1617ec6 100644 --- a/gcc/hsa.c +++ b/gcc/hsa.c @@ -327,6 +327,21 @@ hsa_insn_basic::num_used_ops () return operand_count () - input_count (); } +/* Set alignment to VALUE. */ + +void +hsa_insn_mem::set_align (BrigAlignment8_t value) +{ + /* TODO: Perhaps remove this dump later on: */ + if (dump_file && (dump_flags & TDF_DETAILS) + && value < align) + { + fprintf (dump_file, "Decreasing alignment to %u in instruction ", value); + dump_hsa_insn (dump_file, this); + } + align = value; +} + /* Return size of HSA type T in bits. */ unsigned @@ -455,6 +470,40 @@ hsa_type_integer_p (BrigType16_t type) } } +/* Return HSA alignment encoding alignment to N bits. */ + +BrigAlignment8_t +hsa_alignment_encoding (unsigned n) +{ + gcc_assert (n >= 8 && !(n & (n - 1))); + if (n >= 256) + return BRIG_ALIGNMENT_32; + + switch (n) + { + case 8: + return BRIG_ALIGNMENT_1; + case 16: + return BRIG_ALIGNMENT_2; + case 32: + return BRIG_ALIGNMENT_4; + case 64: + return BRIG_ALIGNMENT_8; + case 128: + return BRIG_ALIGNMENT_16; + default: + gcc_unreachable (); + } +} + +/* Return natural alignment of HSA TYPE. */ + +BrigAlignment8_t +hsa_natural_alignment (BrigType16_t type) +{ + return hsa_alignment_encoding (hsa_type_bit_size (type & ~BRIG_TYPE_ARRAY)); +} + /* Call the correct destructor on a statement STMT. */ void diff --git a/gcc/hsa.h b/gcc/hsa.h index 3c49d1b..d966454 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -541,9 +541,16 @@ public: void *operator new (size_t); + /* Set alignment to VALUE. */ + + void set_align (BrigAlignment8_t value); + /* The segment is of the memory access is either the segment of the symbol in the address operand or flat address is there is no symbol there. */ + /* Required alignment of the memory operation. */ + BrigAlignment8_t align; + /* HSA equiv class, basically an alias set number. */ uint8_t equiv_class; @@ -1056,6 +1063,8 @@ unsigned hsa_type_bit_size (BrigType16_t t); BrigType16_t hsa_bittype_for_type (BrigType16_t t); bool hsa_type_float_p (BrigType16_t type); bool hsa_type_integer_p (BrigType16_t type); +BrigAlignment8_t hsa_alignment_encoding (unsigned n); +BrigAlignment8_t hsa_natural_alignment (BrigType16_t type); void hsa_destroy_insn (hsa_insn_basic *insn); void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned); unsigned hsa_get_number_decl_kernel_mappings (void); -- 2.6.0