Hi, the following patch is a cleanup of hsa_get_segment_addr_type which should not attempt to handle arrays in any way. While doing that, I also bit the bullet and extended hsa_type_for_tree_type so that it is able to create aggregate HSA symbols. Both records and arrays are represented as arrays, records as arrays of bytes.
Martin 2015-06-19 Martin Jambor <mjam...@suse.cz> * hsa-gen.c (hsa_type_for_scalar_tree_type): Use hsa_get_segment_addr_type. Assert type is not scalar. Rename last argument. (hsa_type_for_tree_type): Handle aggregates. Return dimension in only one parameter. (fillup_sym_for_decl): Adapt to changes in hsa_symbol. (gen_hsa_addr_for_arg): Likewise. * hsa-brig.c (get_alignment): Handle array type. (emit_directive_variable): Adapt to changes in hsa_symbol. * hsa.h (hsa_symbol): Make dimension represented by one number. --- gcc/ChangeLog.hsa | 12 +++++++ gcc/hsa-brig.c | 6 ++-- gcc/hsa-gen.c | 105 ++++++++++++++++++++++++++++++++++++++++-------------- gcc/hsa.h | 4 +-- 4 files changed, 95 insertions(+), 32 deletions(-) diff --git a/gcc/hsa-brig.c b/gcc/hsa-brig.c index e17d941..53a11aa7 100644 --- a/gcc/hsa-brig.c +++ b/gcc/hsa-brig.c @@ -446,7 +446,7 @@ static BrigAlignment8_t get_alignment (BrigType16_t type) { unsigned bit_size ; - bit_size = hsa_type_bit_size (type) ; + bit_size = hsa_type_bit_size (type & ~BRIG_TYPE_ARRAY); if (bit_size == 1) return BRIG_ALIGNMENT_1; @@ -515,8 +515,8 @@ emit_directive_variable (struct hsa_symbol *symbol) dirvar.align = get_alignment (dirvar.type); gcc_assert (symbol->linkage); dirvar.linkage = symbol->linkage; - dirvar.dim.lo = htole32 (symbol->dimLo); - dirvar.dim.hi = htole32 (symbol->dimHi); + dirvar.dim.lo = (uint32_t) symbol->dim; + dirvar.dim.hi = (uint32_t) ((unsigned long long) symbol->dim >> 32); dirvar.modifier.allBits |= BRIG_VARIABLE_DEFINITION; dirvar.reserved = 0; diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c index 9fb8096..169b62b 100644 --- a/gcc/hsa-gen.c +++ b/gcc/hsa-gen.c @@ -235,24 +235,22 @@ hsa_get_segment_addr_type (BrigSegment8_t segment) } /* Return HSA type for tree TYPE, which has to fit into BrigType16_t. Pointers - are assumed to use flat addressing. */ + are assumed to use flat addressing. If min32int is true, always expand + integer types to one that has at least 32 bits. */ static BrigType16_t -hsa_type_for_scalar_tree_type (const_tree type, bool for_operand) +hsa_type_for_scalar_tree_type (const_tree type, bool min32int) { HOST_WIDE_INT bsize; const_tree base; BrigType16_t res = BRIG_TYPE_NONE; gcc_checking_assert (TYPE_P (type)); + gcc_checking_assert (!AGGREGATE_TYPE_P (type)); if (POINTER_TYPE_P (type)) - /* Don't use hsa_get_segment_addr_type here, it gives addresses - as B32/B64, but we need U32/U64. */ - return hsa_machine_large_p () ? BRIG_TYPE_U64 : BRIG_TYPE_U32; + return hsa_get_segment_addr_type (BRIG_SEGMENT_FLAT); - /* XXX ARRAY_TYPEs need to decend into pointers, at least for - global variables. Same for RECORD_TYPES. */ - if (TREE_CODE (type) == VECTOR_TYPE || TREE_CODE (type) == ARRAY_TYPE) + if (TREE_CODE (type) == VECTOR_TYPE) base = TREE_TYPE (type); else base = type; @@ -350,7 +348,8 @@ hsa_type_for_scalar_tree_type (const_tree type, bool for_operand) sorry ("Support for HSA does not implement type %T", type); } } - else if (for_operand) + + if (min32int) { /* Registers/immediate operands can only be 32bit or more except for f16. */ @@ -378,6 +377,74 @@ mem_type_for_type (BrigType16_t type) return type; } +/* Return HSA type for tree TYPE. If it cannot fit into BrigType16_t, some + kind of array will be generated, setting DIM appropriately. Otherwise, it + will be set to zero. */ + +static BrigType16_t +hsa_type_for_tree_type (const_tree type, unsigned HOST_WIDE_INT *dim_p) +{ + gcc_checking_assert (TYPE_P (type)); + if (!tree_fits_uhwi_p (TYPE_SIZE_UNIT (type))) + { + sorry ("Support for HSA does not implement huge or variable-sized type %T", + type); + return BRIG_TYPE_NONE; + } + + if (RECORD_OR_UNION_TYPE_P (type)) + { + *dim_p = tree_to_uhwi (TYPE_SIZE_UNIT (type)); + gcc_assert (*dim_p); + return BRIG_TYPE_U8 | BRIG_TYPE_ARRAY; + } + + if (TREE_CODE (type) == ARRAY_TYPE) + { + /* We try to be nice and use the real base-type when this is an array of + scalars and only resort to an array of bytes if the type is more + complex. */ + + unsigned HOST_WIDE_INT dim = 1; + + while (TREE_CODE (type) == ARRAY_TYPE) + { + tree domain = TYPE_DOMAIN (type); + if (!TYPE_MIN_VALUE (domain) + || !TYPE_MAX_VALUE (domain) + || !tree_fits_shwi_p (TYPE_MIN_VALUE (domain)) + || !tree_fits_shwi_p (TYPE_MAX_VALUE (domain))) + { + sorry ("Support for HSA does not implement array %T with unknown " + "bounds", type); + return BRIG_TYPE_NONE; + } + HOST_WIDE_INT min = tree_to_shwi (TYPE_MIN_VALUE (domain)); + HOST_WIDE_INT max = tree_to_shwi (TYPE_MAX_VALUE (domain)); + dim = dim * (unsigned HOST_WIDE_INT) (max - min + 1); + type = TREE_TYPE (type); + } + + BrigType16_t res; + if (RECORD_OR_UNION_TYPE_P (type)) + { + dim = dim * tree_to_uhwi (TYPE_SIZE_UNIT (type)); + res = BRIG_TYPE_U8; + } + else + res = hsa_type_for_scalar_tree_type (type, false); + + *dim_p = dim; + return res | BRIG_TYPE_ARRAY; + } + + /* Scalar case: */ + *dim_p = 0; + return hsa_type_for_scalar_tree_type (type, false); +} + +/* Return true iff TYPE is a floating point number type. */ + static bool hsa_type_float_p (BrigType16_t type) { @@ -407,20 +474,6 @@ hsa_needs_cvt (BrigType16_t dtype, BrigType16_t stype) return false; } -/* Return HSA type for tree TYPE. If it cannot fit into BrigType16_t, some - kind of array will be generated, setting DIMLO and DIMHI appropriately. - Otherwise, they will be set to zero. */ - -static BrigType16_t -hsa_type_for_tree_type (const_tree type, uint32_t *dimLo, uint32_t *dimHi, - bool for_operand) -{ - /* FIXME: Not yet implemented for non-scalars. */ - *dimLo = 0; - *dimHi = 0; - return hsa_type_for_scalar_tree_type (type, for_operand); -} - /* Fill in those values into SYM according to DECL, which are determined independently from whether it is parameter, result, or a variable, local or global. */ @@ -429,8 +482,7 @@ static void fillup_sym_for_decl (tree decl, struct hsa_symbol *sym) { sym->decl = decl; - sym->type = hsa_type_for_tree_type (TREE_TYPE (decl), &sym->dimLo, - &sym->dimHi, false); + sym->type = hsa_type_for_tree_type (TREE_TYPE (decl), &sym->dim); } /* Lookup or create the associated hsa_symbol structure with a given VAR_DECL @@ -1073,8 +1125,7 @@ gen_hsa_addr_for_arg (tree tree_type, int index) sym->segment = BRIG_SEGMENT_ARG; sym->linkage = BRIG_LINKAGE_ARG; - sym->type = hsa_type_for_tree_type (tree_type, &sym->dimLo, - &sym->dimHi, false); + sym->type = hsa_type_for_tree_type (tree_type, &sym->dim); if (index == -1) /* Function result. */ sym->name = "res"; diff --git a/gcc/hsa.h b/gcc/hsa.h index c0a8ead..05a6aa3 100644 --- a/gcc/hsa.h +++ b/gcc/hsa.h @@ -60,8 +60,8 @@ struct hsa_symbol /* The HSA kind of linkage. */ BrigLinkage8_t linkage; - /* Array dimensions, if non-zero. */ - uint32_t dimLo, dimHi; + /* Array dimension, if non-zero. */ + unsigned HOST_WIDE_INT dim; }; /* Abstract class for HSA instruction operands. */ -- 2.1.4