Commit 320c1a36 by Martin Liska Committed by Martin Liska

HSA: support alignment for hsa_symbols (PR hsa/70391)

	PR hsa/70391
	* hsa-brig.c (emit_directive_variable): Emit alignment
	according to hsa_symbol::m_align.
	* hsa-dump.c (hsa_byte_alignment): Move the function to
	another file.
	(dump_hsa_symbol): Dump alignment of HSA symbols.
	* hsa-gen.c (get_symbol_for_decl): Set-up alignment
	of a symbol.
	(gen_hsa_addr_with_align): New function.
	(hsa_bitmemref_alignment): Use newly added function.
	(gen_hsa_insns_for_load): Likewise.
	(gen_hsa_insns_for_store): Likewise.
	(gen_hsa_memory_copy): New argument added.
	(gen_hsa_insns_for_single_assignment): Respect
	alignment for assignments processed via
	gen_hsa_memory_copy.
	(gen_hsa_insns_for_direct_call): Likewise.
	(gen_hsa_insns_for_return): Likewise.
	(gen_function_def_parameters): Set default
	alignment.
	* hsa.c (hsa_object_alignment): New function.
	(hsa_byte_alignment): Pasted function.
	* hsa.h (hsa_symbol::m_align): New field.

From-SVN: r234643
parent 8f80cbdb
2016-03-31 Martin Liska <mliska@suse.cz>
PR hsa/70391
* hsa-brig.c (emit_directive_variable): Emit alignment
according to hsa_symbol::m_align.
* hsa-dump.c (hsa_byte_alignment): Move the function to
another file.
(dump_hsa_symbol): Dump alignment of HSA symbols.
* hsa-gen.c (get_symbol_for_decl): Set-up alignment
of a symbol.
(gen_hsa_addr_with_align): New function.
(hsa_bitmemref_alignment): Use newly added function.
(gen_hsa_insns_for_load): Likewise.
(gen_hsa_insns_for_store): Likewise.
(gen_hsa_memory_copy): New argument added.
(gen_hsa_insns_for_single_assignment): Respect
alignment for assignments processed via
gen_hsa_memory_copy.
(gen_hsa_insns_for_direct_call): Likewise.
(gen_hsa_insns_for_return): Likewise.
(gen_function_def_parameters): Set default
alignment.
* hsa.c (hsa_object_alignment): New function.
(hsa_byte_alignment): Pasted function.
* hsa.h (hsa_symbol::m_align): New field.
2016-03-31 Bin Cheng <bin.cheng@arm.com> 2016-03-31 Bin Cheng <bin.cheng@arm.com>
* tree-ssa-loop-ivopts.c (get_computation_cost_at): Initialize * tree-ssa-loop-ivopts.c (get_computation_cost_at): Initialize
......
...@@ -605,10 +605,7 @@ emit_directive_variable (struct hsa_symbol *symbol) ...@@ -605,10 +605,7 @@ emit_directive_variable (struct hsa_symbol *symbol)
dirvar.init = 0; dirvar.init = 0;
dirvar.type = lendian16 (symbol->m_type); dirvar.type = lendian16 (symbol->m_type);
dirvar.segment = symbol->m_segment; dirvar.segment = symbol->m_segment;
/* TODO: Once we are able to access global variables, we must copy their dirvar.align = symbol->m_align;
alignment. */
dirvar.align = MAX (hsa_natural_alignment (dirvar.type),
(BrigAlignment8_t) BRIG_ALIGNMENT_4);
dirvar.linkage = symbol->m_linkage; dirvar.linkage = symbol->m_linkage;
dirvar.dim.lo = symbol->m_dim; dirvar.dim.lo = symbol->m_dim;
dirvar.dim.hi = symbol->m_dim >> 32; dirvar.dim.hi = symbol->m_dim >> 32;
......
...@@ -621,16 +621,6 @@ hsa_m_atomicop_name (enum BrigAtomicOperation op) ...@@ -621,16 +621,6 @@ hsa_m_atomicop_name (enum BrigAtomicOperation op)
} }
} }
/* Return byte alignment for given BrigAlignment8_t value. */
static unsigned
hsa_byte_alignment (BrigAlignment8_t alignment)
{
gcc_assert (alignment != BRIG_ALIGNMENT_NONE);
return 1 << (alignment - 1);
}
/* Dump textual representation of HSA IL register REG to file F. */ /* Dump textual representation of HSA IL register REG to file F. */
static void static void
...@@ -716,7 +706,8 @@ dump_hsa_symbol (FILE *f, hsa_symbol *symbol) ...@@ -716,7 +706,8 @@ dump_hsa_symbol (FILE *f, hsa_symbol *symbol)
name = buf; name = buf;
} }
fprintf (f, "%s_%s %s", hsa_seg_name (symbol->m_segment), fprintf (f, "align(%u) %s_%s %s", hsa_byte_alignment (symbol->m_align),
hsa_seg_name (symbol->m_segment),
hsa_type_name (symbol->m_type & ~BRIG_TYPE_ARRAY_MASK), name); hsa_type_name (symbol->m_type & ~BRIG_TYPE_ARRAY_MASK), name);
if (symbol->m_type & BRIG_TYPE_ARRAY_MASK) if (symbol->m_type & BRIG_TYPE_ARRAY_MASK)
......
...@@ -169,12 +169,12 @@ hsa_symbol::hsa_symbol () ...@@ -169,12 +169,12 @@ hsa_symbol::hsa_symbol ()
hsa_symbol::hsa_symbol (BrigType16_t type, BrigSegment8_t segment, hsa_symbol::hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
BrigLinkage8_t linkage, bool global_scope_p, BrigLinkage8_t linkage, bool global_scope_p,
BrigAllocation allocation) BrigAllocation allocation, BrigAlignment8_t align)
: m_decl (NULL_TREE), m_name (NULL), m_name_number (0), : m_decl (NULL_TREE), m_name (NULL), m_name_number (0),
m_directive_offset (0), m_type (type), m_segment (segment), m_directive_offset (0), m_type (type), m_segment (segment),
m_linkage (linkage), m_dim (0), m_cst_value (NULL), m_linkage (linkage), m_dim (0), m_cst_value (NULL),
m_global_scope_p (global_scope_p), m_seen_error (false), m_global_scope_p (global_scope_p), m_seen_error (false),
m_allocation (allocation), m_emitted_to_brig (false) m_allocation (allocation), m_emitted_to_brig (false), m_align (align)
{ {
} }
...@@ -908,21 +908,29 @@ get_symbol_for_decl (tree decl) ...@@ -908,21 +908,29 @@ get_symbol_for_decl (tree decl)
{ {
hsa_symbol *sym; hsa_symbol *sym;
gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (decl) == VAR_DECL);
BrigAlignment8_t align = hsa_object_alignment (decl);
if (is_in_global_vars) if (is_in_global_vars)
{ {
sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_GLOBAL, sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_GLOBAL,
BRIG_LINKAGE_PROGRAM, true, BRIG_LINKAGE_PROGRAM, true,
BRIG_ALLOCATION_PROGRAM); BRIG_ALLOCATION_PROGRAM, align);
hsa_cfun->m_global_symbols.safe_push (sym); hsa_cfun->m_global_symbols.safe_push (sym);
} }
else else
{ {
/* As generation of efficient memory copy instructions relies
on alignment greater or equal to 8 bytes,
we need to increase alignment of all aggregate types.. */
if (AGGREGATE_TYPE_P (TREE_TYPE (decl)))
align = MAX ((BrigAlignment8_t) BRIG_ALIGNMENT_8, align);
/* PARM_DECL and RESULT_DECL should be already in m_local_symbols. */ /* PARM_DECL and RESULT_DECL should be already in m_local_symbols. */
gcc_assert (TREE_CODE (decl) == VAR_DECL); gcc_assert (TREE_CODE (decl) == VAR_DECL);
sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_PRIVATE, sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_PRIVATE,
BRIG_LINKAGE_FUNCTION); BRIG_LINKAGE_FUNCTION);
sym->m_align = align;
hsa_cfun->m_private_variables.safe_push (sym); hsa_cfun->m_private_variables.safe_push (sym);
} }
...@@ -2192,6 +2200,30 @@ out: ...@@ -2192,6 +2200,30 @@ out:
return new hsa_op_address (symbol, reg, hwi_offset); return new hsa_op_address (symbol, reg, hwi_offset);
} }
/* Generate HSA address operand for a given tree memory reference REF. If
instructions need to be created to calculate the address, they will be added
to the end of HBB. OUTPUT_ALIGN is alignment of the created address. */
static hsa_op_address *
gen_hsa_addr_with_align (tree ref, hsa_bb *hbb, BrigAlignment8_t *output_align)
{
hsa_op_address *addr = gen_hsa_addr (ref, hbb);
if (addr->m_reg || !addr->m_symbol)
*output_align = hsa_object_alignment (ref);
else
{
/* If the address consists only of a symbol and an offset, we
compute the alignment ourselves to take into account any alignment
promotions we might have done for the HSA symbol representation. */
unsigned align = hsa_byte_alignment (addr->m_symbol->m_align);
unsigned misalign = addr->m_imm_offset & (align - 1);
if (misalign)
align = (misalign & -misalign);
*output_align = hsa_alignment_encoding (BITS_PER_UNIT * align);
}
return addr;
}
/* Generate HSA address for a function call argument of given TYPE. /* Generate HSA address for a function call argument of given TYPE.
INDEX is used to generate corresponding name of the arguments. INDEX is used to generate corresponding name of the arguments.
Special value -1 represents fact that result value is created. */ Special value -1 represents fact that result value is created. */
...@@ -2398,7 +2430,7 @@ hsa_bitmemref_alignment (tree ref) ...@@ -2398,7 +2430,7 @@ hsa_bitmemref_alignment (tree ref)
unsigned HOST_WIDE_INT bits = bit_offset % BITS_PER_UNIT; unsigned HOST_WIDE_INT bits = bit_offset % BITS_PER_UNIT;
unsigned HOST_WIDE_INT byte_bits = bit_offset - bits; unsigned HOST_WIDE_INT byte_bits = bit_offset - bits;
BrigAlignment8_t base = hsa_alignment_encoding (get_object_alignment (ref)); BrigAlignment8_t base = hsa_object_alignment (ref);
if (byte_bits == 0) if (byte_bits == 0)
return base; return base;
return MIN (base, hsa_alignment_encoding (byte_bits & -byte_bits)); return MIN (base, hsa_alignment_encoding (byte_bits & -byte_bits));
...@@ -2537,7 +2569,7 @@ gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb) ...@@ -2537,7 +2569,7 @@ gen_hsa_insns_for_load (hsa_op_reg *dest, tree rhs, tree type, hsa_bb *hbb)
false)); false));
hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dest, hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_LD, mtype, dest,
addr); addr);
mem->set_align (hsa_alignment_encoding (get_object_alignment (rhs))); mem->set_align (hsa_object_alignment (rhs));
hbb->append_insn (mem); hbb->append_insn (mem);
} }
} }
...@@ -2656,7 +2688,7 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb) ...@@ -2656,7 +2688,7 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb)
mtype = mem_type; mtype = mem_type;
} }
else else
req_align = hsa_alignment_encoding (get_object_alignment (lhs)); req_align = hsa_object_alignment (lhs);
hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src, addr); hsa_insn_mem *mem = new hsa_insn_mem (BRIG_OPCODE_ST, mtype, src, addr);
mem->set_align (req_align); mem->set_align (req_align);
...@@ -2697,16 +2729,18 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb) ...@@ -2697,16 +2729,18 @@ gen_hsa_insns_for_store (tree lhs, hsa_op_base *src, hsa_bb *hbb)
/* Generate memory copy instructions that are going to be used /* Generate memory copy instructions that are going to be used
for copying a HSA symbol SRC_SYMBOL (or SRC_REG) to TARGET memory, for copying a HSA symbol SRC_SYMBOL (or SRC_REG) to TARGET memory,
represented by pointer in a register. */ represented by pointer in a register. MIN_ALIGN is minimal alignment
of provided HSA addresses. */
static void static void
gen_hsa_memory_copy (hsa_bb *hbb, hsa_op_address *target, hsa_op_address *src, gen_hsa_memory_copy (hsa_bb *hbb, hsa_op_address *target, hsa_op_address *src,
unsigned size) unsigned size, BrigAlignment8_t min_align)
{ {
hsa_op_address *addr; hsa_op_address *addr;
hsa_insn_mem *mem; hsa_insn_mem *mem;
unsigned offset = 0; unsigned offset = 0;
unsigned min_byte_align = hsa_byte_alignment (min_align);
while (size) while (size)
{ {
...@@ -2720,6 +2754,9 @@ gen_hsa_memory_copy (hsa_bb *hbb, hsa_op_address *target, hsa_op_address *src, ...@@ -2720,6 +2754,9 @@ gen_hsa_memory_copy (hsa_bb *hbb, hsa_op_address *target, hsa_op_address *src,
else else
s = 1; s = 1;
if (s > min_byte_align)
s = min_byte_align;
BrigType16_t t = get_integer_type_by_bytes (s, false); BrigType16_t t = get_integer_type_by_bytes (s, false);
hsa_op_reg *tmp = new hsa_op_reg (t); hsa_op_reg *tmp = new hsa_op_reg (t);
...@@ -2837,16 +2874,21 @@ gen_hsa_insns_for_single_assignment (tree lhs, tree rhs, hsa_bb *hbb) ...@@ -2837,16 +2874,21 @@ gen_hsa_insns_for_single_assignment (tree lhs, tree rhs, hsa_bb *hbb)
} }
else else
{ {
hsa_op_address *addr_lhs = gen_hsa_addr (lhs, hbb); BrigAlignment8_t lhs_align;
hsa_op_address *addr_lhs = gen_hsa_addr_with_align (lhs, hbb,
&lhs_align);
if (TREE_CODE (rhs) == CONSTRUCTOR) if (TREE_CODE (rhs) == CONSTRUCTOR)
gen_hsa_ctor_assignment (addr_lhs, rhs, hbb); gen_hsa_ctor_assignment (addr_lhs, rhs, hbb);
else else
{ {
hsa_op_address *addr_rhs = gen_hsa_addr (rhs, hbb); BrigAlignment8_t rhs_align;
hsa_op_address *addr_rhs = gen_hsa_addr_with_align (rhs, hbb,
&rhs_align);
unsigned size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (rhs))); unsigned size = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (rhs)));
gen_hsa_memory_copy (hbb, addr_lhs, addr_rhs, size); gen_hsa_memory_copy (hbb, addr_lhs, addr_rhs, size,
MIN (lhs_align, rhs_align));
} }
} }
} }
...@@ -3513,9 +3555,10 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb) ...@@ -3513,9 +3555,10 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb)
if (AGGREGATE_TYPE_P (TREE_TYPE (parm))) if (AGGREGATE_TYPE_P (TREE_TYPE (parm)))
{ {
addr = gen_hsa_addr_for_arg (TREE_TYPE (parm), i); addr = gen_hsa_addr_for_arg (TREE_TYPE (parm), i);
hsa_op_address *src = gen_hsa_addr (parm, hbb); BrigAlignment8_t align;
hsa_op_address *src = gen_hsa_addr_with_align (parm, hbb, &align);
gen_hsa_memory_copy (hbb, addr, src, gen_hsa_memory_copy (hbb, addr, src,
addr->m_symbol->total_byte_size ()); addr->m_symbol->total_byte_size (), align);
} }
else else
{ {
...@@ -3574,9 +3617,11 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb) ...@@ -3574,9 +3617,11 @@ gen_hsa_insns_for_direct_call (gimple *stmt, hsa_bb *hbb)
if (AGGREGATE_TYPE_P (lhs_type)) if (AGGREGATE_TYPE_P (lhs_type))
{ {
hsa_op_address *result_addr = gen_hsa_addr (result, hbb); BrigAlignment8_t align;
hsa_op_address *result_addr
= gen_hsa_addr_with_align (result, hbb, &align);
gen_hsa_memory_copy (hbb, result_addr, addr, gen_hsa_memory_copy (hbb, result_addr, addr,
addr->m_symbol->total_byte_size ()); addr->m_symbol->total_byte_size (), align);
} }
else else
{ {
...@@ -3685,9 +3730,12 @@ gen_hsa_insns_for_return (greturn *stmt, hsa_bb *hbb) ...@@ -3685,9 +3730,12 @@ gen_hsa_insns_for_return (greturn *stmt, hsa_bb *hbb)
if (AGGREGATE_TYPE_P (TREE_TYPE (retval))) if (AGGREGATE_TYPE_P (TREE_TYPE (retval)))
{ {
hsa_op_address *retval_addr = gen_hsa_addr (retval, hbb); BrigAlignment8_t align;
hsa_op_address *retval_addr = gen_hsa_addr_with_align (retval, hbb,
&align);
gen_hsa_memory_copy (hbb, addr, retval_addr, gen_hsa_memory_copy (hbb, addr, retval_addr,
hsa_cfun->m_output_arg->total_byte_size ()); hsa_cfun->m_output_arg->total_byte_size (),
align);
} }
else else
{ {
...@@ -5143,7 +5191,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb) ...@@ -5143,7 +5191,7 @@ gen_hsa_insns_for_call (gimple *stmt, hsa_bb *hbb)
hsa_op_address *dst_addr = get_address_from_value (dst, hbb); hsa_op_address *dst_addr = get_address_from_value (dst, hbb);
hsa_op_address *src_addr = get_address_from_value (src, hbb); hsa_op_address *src_addr = get_address_from_value (src, hbb);
gen_hsa_memory_copy (hbb, dst_addr, src_addr, n); gen_hsa_memory_copy (hbb, dst_addr, src_addr, n, BRIG_ALIGNMENT_1);
tree lhs = gimple_call_lhs (stmt); tree lhs = gimple_call_lhs (stmt);
if (lhs) if (lhs)
...@@ -5597,9 +5645,11 @@ gen_function_def_parameters () ...@@ -5597,9 +5645,11 @@ gen_function_def_parameters ()
private_arg = hsa_cfun->create_hsa_temporary (arg->m_type); private_arg = hsa_cfun->create_hsa_temporary (arg->m_type);
private_arg->fillup_for_decl (parm); private_arg->fillup_for_decl (parm);
BrigAlignment8_t align = MIN (arg->m_align, private_arg->m_align);
hsa_op_address *private_arg_addr = new hsa_op_address (private_arg); hsa_op_address *private_arg_addr = new hsa_op_address (private_arg);
gen_hsa_memory_copy (prologue, private_arg_addr, parm_addr, gen_hsa_memory_copy (prologue, private_arg_addr, parm_addr,
arg->total_byte_size ()); arg->total_byte_size (), align);
} }
else else
private_arg = arg; private_arg = arg;
......
...@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "hsa.h" #include "hsa.h"
#include "internal-fn.h" #include "internal-fn.h"
#include "ctype.h" #include "ctype.h"
#include "builtins.h"
/* Structure containing intermediate HSA representation of the generated /* Structure containing intermediate HSA representation of the generated
function. */ function. */
...@@ -570,6 +571,25 @@ hsa_alignment_encoding (unsigned n) ...@@ -570,6 +571,25 @@ hsa_alignment_encoding (unsigned n)
} }
} }
/* Return HSA alignment encoding alignment of T got
by get_object_alignment. */
BrigAlignment8_t
hsa_object_alignment (tree t)
{
return hsa_alignment_encoding (get_object_alignment (t));
}
/* Return byte alignment for given BrigAlignment8_t value. */
unsigned
hsa_byte_alignment (BrigAlignment8_t alignment)
{
gcc_assert (alignment != BRIG_ALIGNMENT_NONE);
return 1 << (alignment - 1);
}
/* Return natural alignment of HSA TYPE. */ /* Return natural alignment of HSA TYPE. */
BrigAlignment8_t BrigAlignment8_t
......
...@@ -60,7 +60,8 @@ struct hsa_symbol ...@@ -60,7 +60,8 @@ struct hsa_symbol
/* Constructor. */ /* Constructor. */
hsa_symbol (BrigType16_t type, BrigSegment8_t segment, hsa_symbol (BrigType16_t type, BrigSegment8_t segment,
BrigLinkage8_t linkage, bool global_scope_p = false, BrigLinkage8_t linkage, bool global_scope_p = false,
BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC); BrigAllocation allocation = BRIG_ALLOCATION_AUTOMATIC,
BrigAlignment8_t align = BRIG_ALIGNMENT_8);
/* Return total size of the symbol. */ /* Return total size of the symbol. */
unsigned HOST_WIDE_INT total_byte_size (); unsigned HOST_WIDE_INT total_byte_size ();
...@@ -113,6 +114,9 @@ struct hsa_symbol ...@@ -113,6 +114,9 @@ struct hsa_symbol
/* Flag used for global variables if a variable is already emitted or not. */ /* Flag used for global variables if a variable is already emitted or not. */
bool m_emitted_to_brig; bool m_emitted_to_brig;
/* Alignment of the symbol. */
BrigAlignment8_t m_align;
private: private:
/* Default constructor. */ /* Default constructor. */
hsa_symbol (); hsa_symbol ();
...@@ -1347,6 +1351,8 @@ bool hsa_type_integer_p (BrigType16_t type); ...@@ -1347,6 +1351,8 @@ bool hsa_type_integer_p (BrigType16_t type);
bool hsa_btype_p (BrigType16_t type); bool hsa_btype_p (BrigType16_t type);
BrigAlignment8_t hsa_alignment_encoding (unsigned n); BrigAlignment8_t hsa_alignment_encoding (unsigned n);
BrigAlignment8_t hsa_natural_alignment (BrigType16_t type); BrigAlignment8_t hsa_natural_alignment (BrigType16_t type);
BrigAlignment8_t hsa_object_alignment (tree t);
unsigned hsa_byte_alignment (BrigAlignment8_t alignment);
void hsa_destroy_operand (hsa_op_base *op); void hsa_destroy_operand (hsa_op_base *op);
void hsa_destroy_insn (hsa_insn_basic *insn); void hsa_destroy_insn (hsa_insn_basic *insn);
void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool); void hsa_add_kern_decl_mapping (tree decl, char *name, unsigned, bool);
......
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