https://gcc.gnu.org/g:3a34dc4c0f63c13976d827048591b54972f9c364
commit 3a34dc4c0f63c13976d827048591b54972f9c364 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Thu Apr 3 15:34:46 2025 +0200 Sauvegarde spacing compilation OK Diff: --- gcc/fortran/trans-array.cc | 399 +++++++++++++++------------------------- gcc/fortran/trans-array.h | 3 +- gcc/fortran/trans-decl.cc | 10 +- gcc/fortran/trans-descriptor.cc | 317 +++++++++++++++++++------------ gcc/fortran/trans-descriptor.h | 5 +- gcc/fortran/trans-expr.cc | 10 +- gcc/fortran/trans-intrinsic.cc | 17 +- gcc/fortran/trans-io.cc | 11 +- gcc/fortran/trans-openmp.cc | 42 +++-- gcc/fortran/trans-types.cc | 61 ++++-- gcc/fortran/trans.cc | 111 +---------- gcc/fortran/trans.h | 27 +-- 12 files changed, 472 insertions(+), 541 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index b33ba5730f24..8d48d8e05a95 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -932,7 +932,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, gfc_loopinfo *loop; gfc_ss *s; gfc_array_info *info; - tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS], sm[GFC_MAX_DIMENSIONS]; + tree from[GFC_MAX_DIMENSIONS], to[GFC_MAX_DIMENSIONS], spacing[GFC_MAX_DIMENSIONS]; tree type; tree desc; tree tmp; @@ -1149,7 +1149,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, info->descriptor = desc; info->array_access = array_access; - size = elemsize; + size = fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, + elemsize, build_int_cst (gfc_array_index_type, + TYPE_ALIGN_UNIT (eltype))); /* Fill in the bounds and stride. This is a packed array, so: @@ -1193,7 +1195,7 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, { for (n = 0; n < total_dim; n++) { - sm[n] = size; + spacing[n] = size; tree extent = to[n]; if (!shift_bounds && !integer_zerop (from[n])) @@ -1245,8 +1247,9 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, nelem, initial, dynamic, dealloc); - gfc_set_temporary_descriptor (pre, desc, class_expr, elemsize, data_ptr, - from, to, sm, total_dim, !bounds_known, + gfc_set_temporary_descriptor (pre, desc, class_expr, elemsize, + GFC_TYPE_ARRAY_ALIGN (desc), data_ptr, + from, to, spacing, total_dim, !bounds_known, rank_changer, shift_bounds); while (ss->parent) @@ -1393,7 +1396,7 @@ gfc_trans_array_ctor_element (stmtblock_t * pblock, tree desc, /* Store the value. */ tmp = build_fold_indirect_ref_loc (input_location, gfc_conv_descriptor_data_get (desc)); - tmp = gfc_build_array_ref (tmp, offset, NULL); + tmp = gfc_build_array_ref (tmp, offset, NULL_TREE, NULL_TREE); if (expr->expr_type == EXPR_FUNCTION && expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp) @@ -1724,7 +1727,7 @@ gfc_trans_array_constructor_value (stmtblock_t * pblock, tmp = gfc_conv_descriptor_data_get (desc); tmp = build_fold_indirect_ref_loc (input_location, tmp); - tmp = gfc_build_array_ref (tmp, *poffset, NULL); + tmp = gfc_build_array_ref (tmp, *poffset, NULL_TREE, NULL_TREE); tmp = gfc_build_addr_expr (NULL_TREE, tmp); init = gfc_build_addr_expr (NULL_TREE, init); @@ -2830,7 +2833,7 @@ gfc_add_loop_ss_code (gfc_loopinfo * loop, gfc_ss * ss, bool subscript, info->stride[dim] = gfc_index_one_node; - tree spacing = gfc_conv_descriptor_sm_get (tmp, tree_dim); + tree spacing = gfc_conv_descriptor_spacing_get (tmp, tree_dim); spacing = gfc_evaluate_now (spacing, &outer_loop->pre); info->spacing[dim] = spacing; } @@ -2988,7 +2991,6 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) && !ss->is_alloc_lhs) data = gfc_evaluate_now (data, block); info->data = data; - info->saved_data = data; tmp = gfc_conv_array_offset (se.expr); if (!ss->is_alloc_lhs) @@ -2999,6 +3001,11 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) so that the variable is still accessible after the loops are translated. */ info->saved_offset = info->offset; + + tmp = gfc_conv_array_align (se.expr); + if (!ss->is_alloc_lhs) + tmp = gfc_evaluate_now (tmp, block); + info->align = tmp; } } @@ -3073,10 +3080,24 @@ gfc_conv_array_offset (tree descriptor) } +/* Return an expression for the base alignment of an array. */ + +tree +gfc_conv_array_align (tree descriptor) +{ + tree type = TREE_TYPE (descriptor); + tree tmp = GFC_TYPE_ARRAY_ALIGN (type); + if (tmp != NULL_TREE) + return tmp; + + return gfc_conv_descriptor_align_get (descriptor); +} + + /* Get an expression for the array stride. */ tree -gfc_conv_array_sm (tree descriptor, int dim) +gfc_conv_array_spacing (tree descriptor, int dim) { tree tmp; tree type; @@ -3084,11 +3105,11 @@ gfc_conv_array_sm (tree descriptor, int dim) type = TREE_TYPE (descriptor); /* For descriptorless arrays use the array size. */ - tmp = GFC_TYPE_ARRAY_SM (type, dim); + tmp = GFC_TYPE_ARRAY_SPACING (type, dim); if (tmp != NULL_TREE) return tmp; - tmp = gfc_conv_descriptor_sm_get (descriptor, gfc_rank_cst[dim]); + tmp = gfc_conv_descriptor_spacing_get (descriptor, gfc_rank_cst[dim]); return tmp; } @@ -3466,38 +3487,14 @@ non_negative_strides_array_p (tree expr) static tree -build_array_ref (tree desc, tree offset, tree decl, tree vptr) +build_array_ref (tree desc, tree offset) { tree tmp; - tree type; - tree cdesc; - - /* For class arrays the class declaration is stored in the saved - descriptor. */ - if (INDIRECT_REF_P (desc) - && DECL_LANG_SPECIFIC (TREE_OPERAND (desc, 0)) - && GFC_DECL_SAVED_DESCRIPTOR (TREE_OPERAND (desc, 0))) - cdesc = gfc_class_data_get (GFC_DECL_SAVED_DESCRIPTOR ( - TREE_OPERAND (desc, 0))); - else - cdesc = desc; - - /* Class container types do not always have the GFC_CLASS_TYPE_P - but the canonical type does. */ - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (cdesc)) - && TREE_CODE (cdesc) == COMPONENT_REF) - { - type = TREE_TYPE (TREE_OPERAND (cdesc, 0)); - if (TYPE_CANONICAL (type) - && GFC_CLASS_TYPE_P (TYPE_CANONICAL (type))) - vptr = gfc_class_vptr_get (TREE_OPERAND (cdesc, 0)); - } tmp = gfc_conv_array_data (desc); tmp = build_fold_indirect_ref_loc (input_location, tmp); - tmp = gfc_build_array_ref (tmp, offset, decl, - non_negative_strides_array_p (desc), - vptr); + tmp = gfc_build_array_ref (tmp, offset, non_negative_strides_array_p (desc), + gfc_index_one_node, gfc_conv_array_align (desc)); return tmp; } @@ -3513,7 +3510,6 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, gfc_array_info *info; tree index; tree data; - tree tmp; info = &ss->info->data.array; @@ -3548,23 +3544,14 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, gfc_array_index_type, se->loop->loopvar[i], se->loop->from[i]); - /* Multiply the index by the stride. */ - tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, index, - info->subscript[dim]->info->data.array.spacing[0]); - data = info->subscript[dim]->info->data.array.data; - if (info->subscript[dim]->info->data.array.array_access) - index = fold_convert_loc (input_location, gfc_array_index_type, tmp); - else - { - data = fold_build2_loc (input_location, POINTER_PLUS_EXPR, - TREE_TYPE (data), data, tmp); - index = gfc_index_zero_node; - } + index = fold_convert_loc (input_location, gfc_array_index_type, index); + /* Read the vector to get an index into info->descriptor. */ data = build_fold_indirect_ref_loc (input_location, data); - index = gfc_build_array_ref (data, index, NULL); + index = gfc_build_array_ref (data, index, + info->subscript[dim]->info->data.array.spacing[0], + info->subscript[dim]->info->data.array.align); index = gfc_evaluate_now (index, &se->pre); index = fold_convert (gfc_array_index_type, index); @@ -3621,75 +3608,36 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar, bool tmp_array = false) { gfc_array_info *info; - tree decl = NULL_TREE; tree base; gfc_ss *ss; - gfc_expr *expr; int n; ss = se->ss; - expr = ss->info->expr; info = &ss->info->data.array; if (ar) n = se->loop->order[0]; else n = 0; - tree tmp = conv_array_index_offset (se, ss, ss->dim[n], n, ar, - info->spacing[ss->dim[n]]); - tree index, data; - if (info->array_access) - { - index = tmp; - - /* Add the offset for this dimension to the stored offset for all other - dimensions. */ - if (info->offset && !integer_zerop (info->offset)) - index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, - index, info->offset); - - data = info->data; - } - else - { - tree offset = fold_convert (size_type_node, tmp); + tree index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, + info->spacing[ss->dim[n]]); - data = info->data; - data = fold_build2_loc (input_location, POINTER_PLUS_EXPR, TREE_TYPE (data), - data, offset); + /* Add the offset for this dimension to the stored offset for all other + dimensions. */ + if (info->offset && !integer_zerop (info->offset)) + index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, + index, info->offset); - index = gfc_index_zero_node; - } - - base = build_fold_indirect_ref_loc (input_location, data); + base = build_fold_indirect_ref_loc (input_location, info->data); /* Use the vptr 'size' field to access the element of a class array. */ if (build_class_array_ref (se, base, index)) return; - if (get_CFI_desc (NULL, expr, &decl, ar)) - decl = build_fold_indirect_ref_loc (input_location, decl); - - /* A pointer array component can be detected from its field decl. Fix - the descriptor, mark the resulting variable decl and pass it to - gfc_build_array_ref. */ - if (is_pointer_array (info->descriptor) - || (expr && expr->ts.deferred && info->descriptor - && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (info->descriptor)))) - { - if (TREE_CODE (info->descriptor) == COMPONENT_REF) - decl = info->descriptor; - else if (INDIRECT_REF_P (info->descriptor)) - decl = TREE_OPERAND (info->descriptor, 0); - - if (decl == NULL_TREE) - decl = info->descriptor; - } - bool non_negative_stride = tmp_array || non_negative_strides_array_p (info->descriptor); - se->expr = gfc_build_array_ref (base, index, decl, - non_negative_stride); + se->expr = gfc_build_array_ref (base, index, non_negative_stride, + gfc_index_one_node, info->align); } @@ -3800,9 +3748,6 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, cst_offset = offset = gfc_index_zero_node; tmp = gfc_conv_array_offset (decl); - if (use_array_ref) - tmp = fold_build2_loc (input_location, EXACT_DIV_EXPR, - gfc_array_index_type, tmp, elem_len); add_to_offset (&cst_offset, &offset, tmp); /* Calculate the offsets from all the dimensions. Make sure to associate @@ -3870,11 +3815,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, } } - /* Multiply the index by the sm. */ - tree tmp = gfc_conv_array_sm (decl, n); - if (use_array_ref) - tmp = fold_build2_loc (input_location, EXACT_DIV_EXPR, - gfc_array_index_type, tmp, elem_len); + /* Multiply the index by the spacing. */ + tree tmp = gfc_conv_array_spacing (decl, n); tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, indexse.expr, tmp); @@ -3887,61 +3829,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, offset = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, offset, cst_offset); - /* A pointer array component can be detected from its field decl. Fix - the descriptor, mark the resulting variable decl and pass it to - build_array_ref. */ - decl = NULL_TREE; - if (get_CFI_desc (sym, expr, &decl, ar)) - decl = build_fold_indirect_ref_loc (input_location, decl); - if (!expr->ts.deferred && !sym->attr.codimension - && is_pointer_array (se->expr)) - { - if (TREE_CODE (se->expr) == COMPONENT_REF) - decl = se->expr; - else if (INDIRECT_REF_P (se->expr)) - decl = TREE_OPERAND (se->expr, 0); - else - decl = se->expr; - } - else if (expr->ts.deferred - || (sym->ts.type == BT_CHARACTER - && sym->attr.select_type_temporary)) - { - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (se->expr))) - { - decl = se->expr; - if (INDIRECT_REF_P (decl)) - decl = TREE_OPERAND (decl, 0); - } - else - decl = sym->backend_decl; - } - else if (sym->ts.type == BT_CLASS) - { - if (UNLIMITED_POLY (sym)) - { - gfc_expr *class_expr = gfc_find_and_cut_at_last_class_ref (expr); - gfc_init_se (&tmpse, NULL); - gfc_conv_expr (&tmpse, class_expr); - if (!se->class_vptr) - se->class_vptr = gfc_class_vptr_get (tmpse.expr); - gfc_free_expr (class_expr); - decl = tmpse.expr; - } - else - decl = NULL_TREE; - } - free (var_name); - if (use_array_ref) - se->expr = build_array_ref (se->expr, offset, decl, se->class_vptr); - else - { - offset = fold_convert_loc (input_location, size_type_node, offset); - tree ptr = fold_build2_loc (input_location, POINTER_PLUS_EXPR, - TREE_TYPE (se->expr), se->expr, offset); - se->expr = build_array_ref (ptr, gfc_array_index_type, decl, NULL_TREE); - } + se->expr = build_array_ref (se->expr, offset); } @@ -4080,10 +3969,7 @@ gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag, /* Remember this offset for the second loop. */ if (dim == loop->temp_dim - 1 && loop->parent == NULL) - { - info->saved_offset = info->offset; - info->saved_data = info->data; - } + info->saved_offset = info->offset; } } @@ -4313,7 +4199,6 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body) continue; ss_info->data.array.offset = ss_info->data.array.saved_offset; - ss_info->data.array.data = ss_info->data.array.saved_data; } /* Restart all the inner loops we just finished. */ @@ -4392,29 +4277,26 @@ conv_array_spacing (stmtblock_t * block, gfc_ss * ss, int dim) tree value = NULL_TREE; - if (info->array_access) + value = gfc_conv_array_spacing (desc, dim); + +#if 0 + if (GFC_ARRAY_TYPE_P (type) + && GFC_TYPE_ARRAY_SPACING (type, dim) != NULL_TREE) + value = GFC_TYPE_ARRAY_SPACING (type, dim); + else if (dim == 0) + value = gfc_index_one_node; + else { - tree type = TREE_TYPE (desc); - if (GFC_ARRAY_TYPE_P (type) - && GFC_TYPE_ARRAY_STRIDE (type, dim) != NULL_TREE) - value = GFC_TYPE_ARRAY_STRIDE (type, dim); - else if (dim == 0) - value = gfc_index_one_node; - else - { - if (info->spacing[dim - 1] == NULL_TREE) - conv_array_spacing (block, ss, dim - 1); + if (info->spacing[dim - 1] == NULL_TREE) + conv_array_spacing (block, ss, dim - 1); - tree previous_spacing = info->spacing[dim - 1]; - tree previous_extent = gfc_conv_array_extent (desc, dim - 1); - value = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, previous_spacing, - previous_extent); - } + tree previous_spacing = info->spacing[dim - 1]; + tree previous_extent = gfc_conv_array_extent (desc, dim - 1); + value = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, previous_spacing, + previous_extent); } - else - value = gfc_conv_descriptor_sm_get (info->descriptor, - gfc_rank_cst[dim]); +#endif if (save_value) info->spacing[dim] = gfc_evaluate_now (value, block); @@ -6323,7 +6205,7 @@ gfc_trans_array_cobounds (tree type, stmtblock_t * pblock, /* Generate code to evaluate non-constant array bounds. Sets *poffset and - returns the size (in elements) of the array. */ + returns the size (in align units) of the array. */ tree gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset, @@ -6331,7 +6213,6 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset, { gfc_array_spec *as; tree size; - tree sm; tree offset; tree ubound; tree lbound; @@ -6342,14 +6223,11 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset, as = IS_CLASS_COARRAY_OR_ARRAY (sym) ? CLASS_DATA (sym)->as : sym->as; - size = gfc_index_one_node; + tree eltype = gfc_get_element_type (type); + + size = fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, + TYPE_SIZE_UNIT (eltype), GFC_TYPE_ARRAY_ALIGN (type)); offset = gfc_index_zero_node; - sm = GFC_TYPE_ARRAY_SM (type, 0); - if (sm && VAR_P (sm)) - { - tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); - gfc_add_modify (pblock, sm, tmp); - } for (dim = 0; dim < as->rank; dim++) { /* Evaluate non-constant array bound expressions. @@ -6382,37 +6260,34 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset, offset, tmp); /* The size of this dimension, and the stride of the next. */ + tree spacing; if (dim + 1 < as->rank) - sm = GFC_TYPE_ARRAY_SM (type, dim + 1); + spacing = GFC_TYPE_ARRAY_SPACING (type, dim + 1); else - sm = GFC_TYPE_ARRAY_SIZE (type); + spacing = GFC_TYPE_ARRAY_SIZE (type); - if (ubound != NULL_TREE && !(sm && INTEGER_CST_P (sm))) + if (ubound != NULL_TREE && !(spacing && INTEGER_CST_P (spacing))) { - /* Calculate sm = size * (ubound + 1 - lbound). */ - tmp = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - gfc_index_one_node, lbound); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, ubound, tmp); + /* Calculate spacing = size * (ubound + 1 - lbound). */ + tmp = gfc_conv_array_extent_dim (lbound, ubound, nullptr); tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, size, tmp); - if (sm) - gfc_add_modify (pblock, sm, tmp); + if (spacing) + gfc_add_modify (pblock, spacing, tmp); else - sm = gfc_evaluate_now (tmp, pblock); + spacing = gfc_evaluate_now (tmp, pblock); /* Make sure that negative size arrays are translated to being zero size. */ tmp = fold_build2_loc (input_location, GE_EXPR, logical_type_node, - sm, gfc_index_zero_node); + spacing, gfc_index_zero_node); tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, tmp, - sm, gfc_index_zero_node); - gfc_add_modify (pblock, sm, tmp); + spacing, gfc_index_zero_node); + gfc_add_modify (pblock, spacing, tmp); } - size = sm; + size = spacing; } gfc_trans_array_cobounds (type, pblock, sym); @@ -6509,15 +6384,13 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, } if (sym->attr.omp_allocate) { - /* The size is the number of elements in the array, so multiply by the - size of an element to get the total size. */ - tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, fold_convert (gfc_array_index_type, tmp)); size = gfc_evaluate_now (size, &init); tree omp_alloc = lookup_attribute ("omp allocate", DECL_ATTRIBUTES (decl)); + size = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, size, + GFC_TYPE_ARRAY_ALIGN (type)); TREE_CHAIN (TREE_CHAIN (TREE_VALUE (omp_alloc))) = build_tree_list (size, NULL_TREE); space = NULL_TREE; @@ -6532,12 +6405,9 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, } else { - /* The size is the number of elements in the array, so multiply by the - size of an element to get the total size. */ - tmp = TYPE_SIZE_UNIT (gfc_get_element_type (type)); - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, fold_convert (gfc_array_index_type, tmp)); - + size = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, size, + GFC_TYPE_ARRAY_ALIGN (type)); /* Allocate memory to hold the data. */ tmp = gfc_call_malloc (&init, TREE_TYPE (decl), size); gfc_add_modify (&init, decl, tmp); @@ -6673,7 +6543,7 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, tree dextent; tree dumdesc; tree tmp; - tree stride2, sm; + tree stride2, spacing = NULL_TREE; tree stmt_packed; tree stmt_unpacked; tree partial; @@ -6734,7 +6604,9 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, anything as we still don't know the array stride. */ partial = gfc_create_var (logical_type_node, "partial"); TREE_USED (partial) = 1; - tmp = gfc_conv_descriptor_sm_get (dumdesc, gfc_rank_cst[0]); + tmp = gfc_conv_descriptor_spacing_get (dumdesc, gfc_rank_cst[0]); + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + tmp, gfc_conv_descriptor_align_get (dumdesc)); tmp = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, tmp, gfc_conv_descriptor_span_get (dumdesc)); gfc_add_modify (&init, partial, tmp); @@ -6747,23 +6619,27 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, if (no_repack) { /* Set the first stride. */ - sm = gfc_conv_descriptor_sm_get (dumdesc, gfc_rank_cst[0]); - tmp = gfc_evaluate_now (sm, &init); - sm = GFC_TYPE_ARRAY_SM (type, 0); - gfc_add_modify (&init, sm, tmp); + spacing = gfc_conv_descriptor_spacing_get (dumdesc, gfc_rank_cst[0]); + tmp = gfc_evaluate_now (spacing, &init); + spacing = GFC_TYPE_ARRAY_SPACING (type, 0); + gfc_add_modify (&init, spacing, tmp); /* Allow the user to disable array repacking. */ stmt_unpacked = NULL_TREE; } else { - gcc_assert (GFC_TYPE_ARRAY_SM (type, 0) == GFC_TYPE_ARRAY_ELEM_LEN (type)); /* A library call to repack the array if necessary. */ tmp = GFC_DECL_SAVED_DESCRIPTOR (tmpdesc); stmt_unpacked = build_call_expr_loc (input_location, gfor_fndecl_in_pack, 1, tmp); - sm = GFC_TYPE_ARRAY_ELEM_LEN (type); + spacing = gfc_conv_descriptor_span_get (dumdesc); + spacing = fold_convert_loc (input_location, gfc_array_index_type, + spacing); + spacing = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, spacing, + GFC_TYPE_ARRAY_ALIGN (type)); if (warn_array_temporaries) { @@ -6794,6 +6670,10 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, offset = gfc_index_zero_node; size = gfc_index_one_node; + tree spacing_units = gfc_conv_descriptor_span_get (dumdesc); + spacing_units = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, spacing_units, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (tmpdesc))); /* Evaluate the bounds of the array. */ for (n = 0; n < as->rank; n++) @@ -6863,42 +6743,59 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, gfc_array_index_type, tmp, lbound); gfc_add_modify (&init, ubound, tmp); } - /* The offset of this dimension. offset = offset - lbound * sm. */ + /* The offset of this dimension. offset = offset - lbound * spacing. */ tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - lbound, sm); + lbound, spacing); offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, offset, tmp); - /* The size of this dimension, and the sm of the next. */ + /* The size of this dimension, and the spacing of the next. */ if (n + 1 < as->rank) { - sm = GFC_TYPE_ARRAY_SM (type, n + 1); + spacing = GFC_TYPE_ARRAY_SPACING (type, n + 1); if (no_repack || partial != NULL_TREE) stmt_unpacked = - gfc_conv_descriptor_sm_get (dumdesc, gfc_rank_cst[n+1]); + gfc_conv_descriptor_spacing_get (dumdesc, gfc_rank_cst[n+1]); - /* Figure out the sm if not a known constant. */ - if (!INTEGER_CST_P (sm)) + /* Figure out the spacing if not a known constant. */ + if (!INTEGER_CST_P (spacing)) { if (no_repack) stmt_packed = NULL_TREE; else { - /* Calculate sm = size * (ubound + 1 - lbound). */ + /* Calculate spacing = size * (ubound + 1 - lbound). */ size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, size, extent); - stmt_packed = size; + spacing_units = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + spacing_units, extent); + + stmt_packed = spacing_units; } - /* Assign the sm. */ + /* Assign the spacing. */ if (stmt_packed != NULL_TREE && stmt_unpacked != NULL_TREE) tmp = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, partial, stmt_unpacked, stmt_packed); else tmp = (stmt_packed != NULL_TREE) ? stmt_packed : stmt_unpacked; - gfc_add_modify (&init, sm, tmp); + gfc_add_modify (&init, spacing, tmp); + } + } + else + { + spacing = GFC_TYPE_ARRAY_SIZE (type); + + if (spacing && !INTEGER_CST_P (spacing)) + { + /* Calculate size = stride * (ubound + 1 - lbound). */ + tmp = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + size, extent); + gfc_add_modify (&init, spacing, tmp); } } } @@ -7001,7 +6898,7 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset, return; } - tmp = build_array_ref (desc, offset, NULL, NULL); + tmp = build_array_ref (desc, offset); /* Offset the data pointer for pointer assignments from arrays with subreferences; e.g. my_integer => my_type(:)%integer_component. */ @@ -7034,7 +6931,7 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset, gfc_init_se (&start, NULL); gfc_conv_expr_type (&start, ref->u.ss.start, gfc_charlen_type_node); gfc_add_block_to_block (block, &start.pre); - tmp = gfc_build_array_ref (tmp, start.expr, NULL); + tmp = gfc_build_array_ref (tmp, start.expr, true); break; case REF_ARRAY: @@ -7079,7 +6976,7 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset, } /* Apply the index to obtain the array element. */ - tmp = gfc_build_array_ref (tmp, index, NULL); + tmp = gfc_build_array_ref (tmp, index, true); break; case REF_INQUIRY: @@ -8955,13 +8852,13 @@ structure_alloc_comps (gfc_symbol * der_type, tree decl, tree dest, /* Build the body of the loop. */ gfc_init_block (&loopbody); - vref = gfc_build_array_ref (var, index, NULL); + vref = gfc_build_array_ref (var, index, NULL_TREE, NULL_TREE); if (purpose == COPY_ALLOC_COMP || purpose == COPY_ONLY_ALLOC_COMP) { tmp = build_fold_indirect_ref_loc (input_location, gfc_conv_array_data (dest)); - dref = gfc_build_array_ref (tmp, index, NULL); + dref = gfc_build_array_ref (tmp, index, NULL_TREE, NULL_TREE); tmp = structure_alloc_comps (der_type, vref, dref, rank, COPY_ALLOC_COMP, caf_mode, args, no_finalization); @@ -10316,7 +10213,7 @@ update_reallocated_descriptor (stmtblock_t *block, gfc_loopinfo *loop) UPDATE_VALUE (info->end[dim], gfc_conv_descriptor_ubound_get (desc, tree_dim)); UPDATE_VALUE (info->spacing[dim], - gfc_conv_descriptor_sm_get (desc, tree_dim)); + gfc_conv_descriptor_spacing_get (desc, tree_dim)); info->delta[dim] = gfc_evaluate_now (info->delta[dim], block); } diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h index 709166f07551..d52c1a859459 100644 --- a/gcc/fortran/trans-array.h +++ b/gcc/fortran/trans-array.h @@ -160,8 +160,9 @@ void gfc_conv_array_parameter (gfc_se *, gfc_expr *, bool, const gfc_symbol *, /* These work with both descriptors and descriptorless arrays. */ tree gfc_conv_array_data (tree); tree gfc_conv_array_offset (tree); +tree gfc_conv_array_align (tree); /* Return either an INT_CST or an expression for that part of the descriptor. */ -tree gfc_conv_array_sm (tree, int); +tree gfc_conv_array_spacing (tree, int); tree gfc_conv_array_lbound (tree, int); tree gfc_conv_array_ubound (tree, int); tree gfc_conv_array_extent (tree, int); diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index 1e92b8c63925..b34cb15e34ca 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -1128,10 +1128,10 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim)); } - if (GFC_TYPE_ARRAY_SM (type, dim) == NULL_TREE) + if (GFC_TYPE_ARRAY_SPACING (type, dim) == NULL_TREE) { - GFC_TYPE_ARRAY_SM (type, dim) = create_index_var ("sm", nest); - suppress_warning (GFC_TYPE_ARRAY_SM (type, dim)); + GFC_TYPE_ARRAY_SPACING (type, dim) = create_index_var ("spacing", nest); + suppress_warning (GFC_TYPE_ARRAY_SPACING (type, dim)); } } for (dim = GFC_TYPE_ARRAY_RANK (type); @@ -7597,7 +7597,9 @@ done: tmp = gfc_conv_descriptor_extent_get (gfc_desc, idx); gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp); /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */ - tmp = gfc_conv_descriptor_sm_get (gfc_desc, idx); + tmp = gfc_conv_descriptor_spacing_get (gfc_desc, idx); + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + tmp, gfc_conv_descriptor_align_get (gfc_desc)); gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp); /* Generate loop. */ diff --git a/gcc/fortran/trans-descriptor.cc b/gcc/fortran/trans-descriptor.cc index e5c1eb5b3835..1f35b6722998 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -106,7 +106,7 @@ static tree gfc_get_cfi_dim_item (tree desc, tree idx, unsigned field_idx) { tree tmp = gfc_get_cfi_descriptor_field (desc, CFI_FIELD_DIM); - tmp = gfc_build_array_ref (tmp, idx, NULL_TREE, true); + tmp = gfc_build_array_ref (tmp, idx, true); tree field = gfc_advance_chain (TYPE_FIELDS (TREE_TYPE (tmp)), field_idx); gcc_assert (field != NULL_TREE); return fold_build3_loc (input_location, COMPONENT_REF, TREE_TYPE (field), @@ -165,10 +165,11 @@ gfc_get_cfi_dim_sm (tree desc, tree idx) #define OFFSET_FIELD 1 #define DTYPE_FIELD 2 #define SPAN_FIELD 3 -#define DIMENSION_FIELD 4 -#define CAF_TOKEN_FIELD 5 +#define ALIGN_FIELD 4 +#define DIMENSION_FIELD 5 +#define CAF_TOKEN_FIELD 6 -#define SM_SUBFIELD 0 +#define SPACING_SUBFIELD 0 #define LBOUND_SUBFIELD 1 #define UBOUND_SUBFIELD 2 @@ -303,6 +304,27 @@ conv_span_set (stmtblock_t *block, tree desc, tree value) gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value)); } +tree +get_align (tree desc) +{ + tree field = get_component (desc, ALIGN_FIELD); + gcc_assert (TREE_TYPE (field) == gfc_array_index_type); + return field; +} + +tree +conv_align_get (tree desc) +{ + return non_lvalue_loc (input_location, get_align (desc)); +} + +void +conv_align_set (stmtblock_t *block, tree desc, tree value) +{ + tree t = get_align (desc); + gfc_add_modify (block, t, fold_convert (TREE_TYPE (t), value)); +} + tree get_rank (tree desc) { @@ -510,7 +532,7 @@ get_dimension (tree desc, tree dim) tmp = get_dimensions (desc); - return gfc_build_array_ref (tmp, dim, NULL_TREE, true); + return gfc_build_array_ref (tmp, dim, true); } tree @@ -573,15 +595,15 @@ get_subfield (tree desc, tree dim, unsigned field_idx) } tree -get_sm (tree desc, tree dim) +get_spacing (tree desc, tree dim) { - tree field = get_subfield (desc, dim, SM_SUBFIELD); + tree field = get_subfield (desc, dim, SPACING_SUBFIELD); gcc_assert (TREE_TYPE (field) == gfc_array_index_type); return field; } tree -conv_sm_get (tree desc, tree dim) +conv_spacing_get (tree desc, tree dim) { tree type = TREE_TYPE (desc); gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); @@ -594,14 +616,14 @@ conv_sm_get (tree desc, tree dim) || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)) return conv_span_get (desc); - return non_lvalue_loc (input_location, get_sm (desc, dim)); + return non_lvalue_loc (input_location, get_spacing (desc, dim)); } void -conv_sm_set (stmtblock_t *block, tree desc, tree dim, tree value) +conv_spacing_set (stmtblock_t *block, tree desc, tree dim, tree value) { location_t loc = input_location; - tree t = get_sm (desc, dim); + tree t = get_spacing (desc, dim); gfc_add_modify_loc (loc, block, t, fold_convert_loc (loc, TREE_TYPE (t), value)); } @@ -620,10 +642,14 @@ conv_stride_get (tree desc, tree dim) || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)) return gfc_index_one_node; - tree sm = conv_sm_get (desc, dim); - tree span = conv_span_get (desc); + tree spacing = conv_spacing_get (desc, dim); + tree align = conv_align_get (desc); + tree len = conv_elem_len_get (desc); return fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, - sm, span); + fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, spacing, + align), + len); } tree @@ -747,6 +773,26 @@ gfc_conv_descriptor_span_set (stmtblock_t *block, tree desc, tree value) return gfc_descriptor::conv_span_set (block, desc, value); } +tree +gfc_conv_descriptor_align_get (tree desc) +{ + return gfc_descriptor::conv_align_get (desc); +} + +static void +gfc_conv_descriptor_align_set (stmtblock_t *block, tree desc, tree value) +{ + return gfc_descriptor::conv_align_set (block, desc, value); +} + +static void +gfc_conv_descriptor_align_set (stmtblock_t *block, tree desc, int value) +{ + return gfc_conv_descriptor_align_set (block, desc, + build_int_cst (gfc_array_index_type, + value)); +} + tree gfc_conv_descriptor_dimension_get (tree desc, tree dim) { @@ -864,16 +910,16 @@ gfc_conv_descriptor_token_set (stmtblock_t *block, tree desc, tree value) } tree -gfc_conv_descriptor_sm_get (tree desc, tree dim) +gfc_conv_descriptor_spacing_get (tree desc, tree dim) { - return gfc_descriptor::conv_sm_get (desc, dim); + return gfc_descriptor::conv_spacing_get (desc, dim); } void -gfc_conv_descriptor_sm_set (stmtblock_t *block, tree desc, +gfc_conv_descriptor_spacing_set (stmtblock_t *block, tree desc, tree dim, tree value) { - gfc_descriptor::conv_sm_set (block, desc, dim, value); + gfc_descriptor::conv_spacing_set (block, desc, dim, value); } tree @@ -1958,8 +2004,8 @@ gfc_build_null_descriptor (tree type) static void set_bounds_update_offset (stmtblock_t *block, tree desc, int dim, - tree lbound, tree ubound, tree sm, tree lbound_diff, - tree *offset, tree *next_sm, bool sm_unchanged) + tree lbound, tree ubound, tree spacing, tree lbound_diff, + tree *offset, tree *next_spacing, bool spacing_unchanged) { /* Stabilize values in case the expressions depend on the existing bounds. */ lbound = fold_convert (gfc_array_index_type, lbound); @@ -1968,8 +2014,8 @@ set_bounds_update_offset (stmtblock_t *block, tree desc, int dim, ubound = fold_convert (gfc_array_index_type, ubound); ubound = gfc_evaluate_now (ubound, block); - sm = fold_convert (gfc_array_index_type, sm); - sm = gfc_evaluate_now (sm, block); + spacing = fold_convert (gfc_array_index_type, spacing); + spacing = gfc_evaluate_now (spacing, block); lbound_diff = fold_convert (gfc_array_index_type, lbound_diff); lbound_diff = gfc_evaluate_now (lbound_diff, block); @@ -1978,39 +2024,38 @@ set_bounds_update_offset (stmtblock_t *block, tree desc, int dim, gfc_rank_cst[dim], lbound); gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[dim], ubound); - if (!sm_unchanged) - gfc_conv_descriptor_sm_set (block, desc, - gfc_rank_cst[dim], sm); + if (!spacing_unchanged) + gfc_conv_descriptor_spacing_set (block, desc, gfc_rank_cst[dim], spacing); - if (!offset && !next_sm) + if (!offset && !next_spacing) return; /* Update offset. */ if (!integer_zerop (lbound_diff)) { tree tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, lbound_diff, sm); + gfc_array_index_type, lbound_diff, spacing); tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, *offset, tmp); *offset = gfc_evaluate_now (tmp, block); } - if (!next_sm) + if (!next_spacing) return; /* Set sm for next dimension. */ tree tmp = gfc_conv_array_extent_dim (lbound, ubound, NULL); - *next_sm = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, sm, tmp); + *next_spacing = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, spacing, tmp); } static void set_descriptor_dimension (stmtblock_t *block, tree desc, int dim, - tree lbound, tree ubound, tree sm, tree *offset, + tree lbound, tree ubound, tree spacing, tree *offset, tree *next_sm) { - set_bounds_update_offset (block, desc, dim, lbound, ubound, sm, lbound, + set_bounds_update_offset (block, desc, dim, lbound, ubound, spacing, lbound, offset, next_sm, false); } @@ -2027,7 +2072,7 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree from_desc, tree to_desc, tree lbound = gfc_conv_descriptor_lbound_get (from_desc, gfc_rank_cst[dim]); tree ubound = gfc_conv_descriptor_ubound_get (from_desc, gfc_rank_cst[dim]); - tree sm = gfc_conv_descriptor_sm_get (from_desc, gfc_rank_cst[dim]); + tree spacing = gfc_conv_descriptor_spacing_get (from_desc, gfc_rank_cst[dim]); tree diff; if (zero_based) @@ -2045,7 +2090,7 @@ conv_shift_descriptor_lbound (stmtblock_t* block, tree from_desc, tree to_desc, tree tmp1 = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, ubound, diff); - set_bounds_update_offset (block, to_desc, dim, new_lbound, tmp1, sm, diff, + set_bounds_update_offset (block, to_desc, dim, new_lbound, tmp1, spacing, diff, offset, nullptr, from_desc == to_desc); } @@ -2391,6 +2436,9 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, } gfc_conv_descriptor_span_set (block, dest, span); + gfc_conv_descriptor_align_set (block, dest, + gfc_conv_descriptor_align_get (dest)); + /* Copy offset but adjust it such that it would correspond to a lbound of zero. */ tree offset; @@ -2401,10 +2449,10 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, tree offs = gfc_conv_descriptor_offset_get (src); for (int dim = 0; dim < src_rank; ++dim) { - tree sm = gfc_conv_descriptor_sm_get (src, gfc_rank_cst[dim]); + tree spacing = gfc_conv_descriptor_spacing_get (src, gfc_rank_cst[dim]); tree lbound = gfc_conv_descriptor_lbound_get (src, gfc_rank_cst[dim]); tmp = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, sm, lbound); + gfc_array_index_type, spacing, lbound); offs = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, offs, tmp); } @@ -2412,7 +2460,7 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, } /* Set the bounds as declared for the LHS and calculate strides as well as another offset update accordingly. */ - tree sm = gfc_conv_descriptor_sm_get (src, gfc_rank_cst[0]); + tree spacing = gfc_conv_descriptor_spacing_get (src, gfc_rank_cst[0]); int last_dim = dest_rank - 1; for (int dim = 0; dim < dest_rank; ++dim) { @@ -2431,8 +2479,8 @@ gfc_conv_remap_descriptor (stmtblock_t *block, tree dest, tree src, gfc_add_block_to_block (block, &upper_se.pre); set_descriptor_dimension (block, dest, dim, lower_se.expr, upper_se.expr, - sm, &offset, - dim < last_dim ? &sm : nullptr); + spacing, &offset, + dim < last_dim ? &spacing : nullptr); } gfc_conv_descriptor_offset_set (block, dest, offset); } @@ -2489,6 +2537,9 @@ gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, else tmp2 = gfc_get_array_span (src, src_expr); gfc_conv_descriptor_span_set (block, dest, tmp2); + + gfc_conv_descriptor_align_set (block, dest, + gfc_conv_descriptor_align_get (src)); } @@ -2498,10 +2549,13 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, locus *where) { /* Set the span field. */ - tree elem_len = TYPE_SIZE_UNIT (gfc_get_element_type (TREE_TYPE (desc))); + tree elem_type = gfc_get_element_type (TREE_TYPE (desc)); + tree elem_len = TYPE_SIZE_UNIT (elem_type); elem_len = fold_convert (gfc_array_index_type, elem_len); gfc_conv_descriptor_span_set (block, desc, elem_len); + gfc_conv_descriptor_align_set (block, desc, TYPE_ALIGN_UNIT (elem_type)); + /* Set data value, dtype, and offset. */ tree tmp = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (desc)); gfc_conv_descriptor_data_set (block, desc, fold_convert (tmp, ptr)); @@ -2524,9 +2578,13 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, gfc_copy_loopinfo_to_se (&shapese, &loop); shapese.ss = shape_ss; - tree sm = gfc_create_var (gfc_array_index_type, "sm"); + tree spacing = gfc_create_var (gfc_array_index_type, "spacing"); tree offset = gfc_create_var (gfc_array_index_type, "offset"); - gfc_add_modify (block, sm, elem_len); + tmp = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, elem_len, + build_int_cst (gfc_array_index_type, + TYPE_ALIGN_UNIT (elem_type))); + gfc_add_modify (block, spacing, tmp); gfc_add_modify (block, offset, gfc_index_zero_node); /* Loop body. */ @@ -2536,9 +2594,9 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree dim = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, loop.loopvar[0], loop.from[0]); - /* Set bounds and sm. */ + /* Set bounds and spacing. */ gfc_conv_descriptor_lbound_set (&body, desc, dim, gfc_index_one_node); - gfc_conv_descriptor_sm_set (&body, desc, dim, sm); + gfc_conv_descriptor_spacing_set (&body, desc, dim, spacing); gfc_conv_expr (&shapese, shape); gfc_add_block_to_block (&body, &shapese.pre); @@ -2548,11 +2606,11 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, /* Calculate offset. */ gfc_add_modify (&body, offset, fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, offset, sm)); - /* Update sm. */ - gfc_add_modify (&body, sm, + gfc_array_index_type, offset, spacing)); + /* Update spacing. */ + gfc_add_modify (&body, spacing, fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, sm, + gfc_array_index_type, spacing, fold_convert (gfc_array_index_type, shapese.expr))); /* Finish scalarization loop. */ @@ -2607,27 +2665,26 @@ gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc, gfc_conv_descriptor_lbound_set (&block, arr, gfc_index_zero_node, gfc_index_zero_node); tree size = gfc_conv_descriptor_size (rhs_desc, rhs_rank); - tree span = gfc_conv_descriptor_span_get (rhs_desc); + tree spacing0 = + gfc_conv_descriptor_spacing_get (rhs_desc, gfc_index_zero_node); size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, span); + size, spacing0); gfc_conv_descriptor_ubound_set (&block, arr, gfc_index_zero_node, size); - gfc_conv_descriptor_sm_set ( - &block, arr, gfc_index_zero_node, - gfc_conv_descriptor_sm_get (rhs_desc, gfc_index_zero_node)); + gfc_conv_descriptor_spacing_set ( &block, arr, gfc_index_zero_node, spacing0); for (int i = 1; i < lhs_rank; i++) { gfc_conv_descriptor_lbound_set (&block, arr, gfc_rank_cst[i], gfc_index_zero_node); gfc_conv_descriptor_ubound_set (&block, arr, gfc_rank_cst[i], gfc_index_zero_node); - gfc_conv_descriptor_sm_set (&block, arr, gfc_rank_cst[i], size); + gfc_conv_descriptor_spacing_set (&block, arr, gfc_rank_cst[i], size); } gfc_conv_descriptor_dtype_set (&block, arr, gfc_conv_descriptor_dtype_get (rhs_desc)); tree rank_value = build_int_cst (signed_char_type_node, lhs_rank); gfc_conv_descriptor_rank_set (&block, arr, rank_value); - gfc_conv_descriptor_span_set (&block, arr, - gfc_conv_descriptor_span_get (arr)); + gfc_conv_descriptor_align_set (&block, arr, + gfc_conv_descriptor_align_get (rhs_desc)); gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node); desc = arr; } @@ -2644,6 +2701,8 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block, { tree tmp = gfc_get_cfi_desc_base_addr (cfi); gfc_conv_descriptor_data_set (unconditional_block, gfc, tmp); + gfc_conv_descriptor_align_set (unconditional_block, gfc, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (gfc))); if (init_static) { @@ -2782,6 +2841,9 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block, } gfc_conv_descriptor_span_set (conditional_block, gfc, tmp); + gfc_conv_descriptor_align_set (conditional_block, gfc, + TYPE_ALIGN (gfc_get_element_type (TREE_TYPE (gfc)))); + /* Calculate offset + set lbound, ubound and stride. */ gfc_conv_descriptor_offset_set (conditional_block, gfc, gfc_index_zero_node); if (gfc_sym @@ -2830,29 +2892,36 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block, if (contiguous_gfc) { - /* gfc->dim[i].sm - = idx == 0 ? cfi->elem_len : gfc->dim[i-1].stride * cfi->dim[i-1].extent */ + /* gfc->dim[i].spacing + = idx == 0 ? cfi->elem_len / gfc->align : gfc->dim[i-1].spacing * cfi->dim[i-1].extent */ tree cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, idx, build_zero_cst (TREE_TYPE (idx))); tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (idx), idx, build_int_cst (TREE_TYPE (idx), 1)); tree tmp2 = gfc_get_cfi_dim_extent (cfi, tmp); - tmp = gfc_conv_descriptor_sm_get (gfc, tmp); + tmp = gfc_conv_descriptor_spacing_get (gfc, tmp); tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp2), tmp2, tmp); + tmp2 = fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, + gfc_get_cfi_desc_elem_len (cfi), + fold_convert_loc (input_location, gfc_array_index_type, + GFC_TYPE_ARRAY_ALIGN (gfc))); tmp = build3_loc (input_location, COND_EXPR, gfc_array_index_type, cond, - gfc_get_cfi_desc_elem_len (cfi), tmp); + tmp2, tmp); } else { - /* gfc->dim[i].stride = cfi->dim[i].sm / cfi>elem_len */ - tmp = gfc_get_cfi_dim_sm (cfi, idx); + /* gfc->dim[i].spacing = cfi->dim[i].sm / gfc->align */ + tmp = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, + gfc_get_cfi_dim_sm (cfi, idx), + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (gfc))); } - gfc_conv_descriptor_sm_set (&loop_body, gfc, idx, tmp); + gfc_conv_descriptor_spacing_set (&loop_body, gfc, idx, tmp); - /* gfc->offset -= gfc->dim[i].stride * gfc->dim[i].lbound. */ + /* gfc->offset -= gfc->dim[i].spacing * gfc->dim[i].lbound. */ tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - gfc_conv_descriptor_sm_get (gfc, idx), + gfc_conv_descriptor_spacing_get (gfc, idx), gfc_conv_descriptor_lbound_get (gfc, idx)); tmp = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, gfc_conv_descriptor_offset_get (gfc), tmp); @@ -2870,7 +2939,7 @@ void gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, tree *dtype_off, tree *span_off, tree *dim_off, tree *dim_size, - tree *sm_suboff, tree *lower_suboff, + tree *spacing_suboff, tree *lower_suboff, tree *upper_suboff) { tree field; @@ -2887,8 +2956,8 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, *dim_off = byte_position (field); type = TREE_TYPE (TREE_TYPE (field)); *dim_size = TYPE_SIZE_UNIT (type); - field = gfc_advance_chain (TYPE_FIELDS (type), SM_SUBFIELD); - *sm_suboff = byte_position (field); + field = gfc_advance_chain (TYPE_FIELDS (type), SPACING_SUBFIELD); + *spacing_suboff = byte_position (field); field = gfc_advance_chain (TYPE_FIELDS (type), LBOUND_SUBFIELD); *lower_suboff = byte_position (field); field = gfc_advance_chain (TYPE_FIELDS (type), UBOUND_SUBFIELD); @@ -2910,10 +2979,10 @@ gfc_get_descriptor_offsets_for_info (const_tree desc_type, tree *data_off, void gfc_set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src, - tree elemsize, tree data_ptr, + tree elemsize, tree elem_align, tree data_ptr, tree lbound[GFC_MAX_DIMENSIONS], tree ubound[GFC_MAX_DIMENSIONS], - tree sm[GFC_MAX_DIMENSIONS], int rank, + tree spacing[GFC_MAX_DIMENSIONS], int rank, bool omit_bounds, bool rank_changer, bool shift_bounds) { @@ -2949,12 +3018,14 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src, /* Store the stride and bound components in the descriptor. */ tree this_lbound = shift_bounds ? gfc_index_zero_node : lbound[n]; set_descriptor_dimension (block, desc, n, this_lbound, ubound[n], - sm[n], &offset, nullptr); + spacing[n], &offset, nullptr); } } gfc_conv_descriptor_span_set (block, desc, elemsize); - + + gfc_conv_descriptor_align_set (block, desc, elem_align); + gfc_conv_descriptor_data_set (block, desc, data_ptr); /* The offset is zero because we create temporaries with a zero @@ -3032,6 +3103,9 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, if (tmp) gfc_conv_descriptor_span_set (block, dest, tmp); + tree eltype = gfc_get_element_type (TREE_TYPE (dest)); + gfc_conv_descriptor_align_set (block, dest, TYPE_ALIGN (eltype)); + /* The following can be somewhat confusing. We have two descriptors, a new one and the original array. {dest, parmtype, dim} refer to the new one. @@ -3065,7 +3139,7 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, for (int n = 0; n < ndim; n++) { - tree sm = gfc_conv_array_sm (src, n); + tree spacing = gfc_conv_array_spacing (src, n); /* Work out the 1st element in the section. */ tree start; @@ -3080,14 +3154,14 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, { /* Evaluate and remember the start of the section. */ start = info->start[n]; - sm = gfc_evaluate_now (sm, block); + spacing = gfc_evaluate_now (spacing, block); } tmp = gfc_conv_array_lbound (src, n); tmp = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (tmp), start, tmp); tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), - tmp, sm); + tmp, spacing); offset = fold_build2_loc (input_location, PLUS_EXPR, TREE_TYPE (tmp), offset, tmp); @@ -3123,19 +3197,19 @@ gfc_set_descriptor (stmtblock_t *block, tree dest, tree src, gfc_expr *src_expr, gfc_conv_descriptor_ubound_set (block, dest, gfc_rank_cst[dim], to); - /* Multiply the sm by the section stride to get the + /* Multiply the spacing by the section stride to get the total stride. */ - sm = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, - sm, info->stride[n]); + spacing = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + spacing, info->stride[n]); tmp = fold_build2_loc (input_location, MULT_EXPR, - TREE_TYPE (offset), sm, from); + TREE_TYPE (offset), spacing, from); offset = fold_build2_loc (input_location, MINUS_EXPR, TREE_TYPE (offset), offset, tmp); - /* Store the new sm. */ - gfc_conv_descriptor_sm_set (block, dest, gfc_rank_cst[dim], sm); + /* Store the new spacing. */ + gfc_conv_descriptor_spacing_set (block, dest, gfc_rank_cst[dim], spacing); } for (int n = rank; n < rank + corank; n++) @@ -3220,7 +3294,7 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, tree size; tree offset; tree stride; - tree sm; + tree spacing; tree cond; gfc_expr *ubound; gfc_se se; @@ -3231,6 +3305,9 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, stride = gfc_index_one_node; offset = gfc_index_zero_node; + gfc_conv_descriptor_align_set (descriptor_block, descriptor, + GFC_TYPE_ARRAY_ALIGN (type)); + /* Set the dtype before the alloc, because registration of coarrays needs it initialized. */ if (expr->ts.type == BT_CHARACTER @@ -3276,8 +3353,11 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, gfc_conv_descriptor_dtype_set (pblock, descriptor, gfc_get_dtype (type)); tree empty_cond = logical_false_node; - sm = gfc_conv_descriptor_elem_len_get (descriptor); - sm = fold_convert_loc (input_location, gfc_array_index_type, sm); + spacing = gfc_conv_descriptor_elem_len_get (descriptor); + spacing = fold_convert_loc (input_location, gfc_array_index_type, spacing); + spacing = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, spacing, + GFC_TYPE_ARRAY_ALIGN (type)); for (n = 0; n < rank; n++) { @@ -3326,7 +3406,7 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, /* Work out the offset for this component. */ tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - se.expr, sm); + se.expr, spacing); offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, offset, tmp); @@ -3365,9 +3445,9 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, gfc_rank_cst[n], se.expr); conv_ubound = se.expr; - /* Store the sm. */ - gfc_conv_descriptor_sm_set (descriptor_block, descriptor, - gfc_rank_cst[n], sm); + /* Store the spacing. */ + gfc_conv_descriptor_spacing_set (descriptor_block, descriptor, + gfc_rank_cst[n], spacing); /* Calculate size and check whether extent is negative. */ size = gfc_conv_array_extent_dim (conv_lbound, conv_ubound, @@ -3385,7 +3465,7 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, TYPE_MAX_VALUE (gfc_array_index_type)), size); cond = gfc_unlikely (fold_build2_loc (input_location, LT_EXPR, - logical_type_node, tmp, sm), + logical_type_node, tmp, spacing), PRED_FORTRAN_OVERFLOW); tmp = fold_build3_loc (input_location, COND_EXPR, integer_type_node, cond, integer_one_node, integer_zero_node); @@ -3404,9 +3484,9 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, gfc_array_index_type, stride, size); stride = gfc_evaluate_now (stride, pblock); - sm = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, sm, size); - sm = gfc_evaluate_now (sm, pblock); + spacing = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, spacing, size); + spacing = gfc_evaluate_now (spacing, pblock); } for (n = rank; n < rank + corank; n++) @@ -3458,6 +3538,9 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, tmp = fold_convert (gfc_array_index_type, element_size); gfc_conv_descriptor_span_set (descriptor_block, descriptor, tmp); + gfc_conv_descriptor_align_set (descriptor_block, descriptor, + TYPE_ALIGN (gfc_get_element_type (TREE_TYPE (descriptor)))); + return gfc_evaluate_now (stride, pblock); } @@ -3496,15 +3579,18 @@ gfc_set_contiguous_array (stmtblock_t *block, tree desc, tree size, tree data_ptr) { tree dtype_value = gfc_get_dtype_rank_type (1, TREE_TYPE (desc)); + gfc_conv_descriptor_align_set (block, desc, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); gfc_conv_descriptor_dtype_set (block, desc, dtype_value); gfc_conv_descriptor_lbound_set (block, desc, gfc_index_zero_node, gfc_index_one_node); - gfc_conv_descriptor_sm_set (block, desc, - gfc_index_zero_node, - gfc_conv_descriptor_span_get (desc)); - gfc_conv_descriptor_ubound_set (block, desc, - gfc_index_zero_node, size); + tree span = gfc_conv_descriptor_span_get (desc); + tree spacing = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, span, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); + gfc_conv_descriptor_spacing_set (block, desc, gfc_index_zero_node, spacing); + gfc_conv_descriptor_ubound_set (block, desc, gfc_index_zero_node, size); gfc_conv_descriptor_data_set (block, desc, data_ptr); } @@ -3583,7 +3669,7 @@ gfc_copy_descriptor (stmtblock_t *block, tree dst, tree src, int rank) { dim = gfc_rank_cst[n]; tmp = gfc_conv_descriptor_lbound_get (src, dim); - tmp2 = gfc_conv_descriptor_sm_get (src, dim); + tmp2 = gfc_conv_descriptor_spacing_get (src, dim); tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), tmp, tmp2); offset = fold_build2_loc (input_location, MINUS_EXPR, @@ -3603,7 +3689,7 @@ get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size) { tree lbound; tree ubound; - tree sm; + tree spacing; tree cond, cond1, cond3, cond4; tree tmp; gfc_ref *ref; @@ -3613,15 +3699,15 @@ get_std_lbound (gfc_expr *expr, tree desc, int dim, bool assumed_size) tmp = gfc_rank_cst[dim]; lbound = gfc_conv_descriptor_lbound_get (desc, tmp); ubound = gfc_conv_descriptor_ubound_get (desc, tmp); - sm = gfc_conv_descriptor_sm_get (desc, tmp); + spacing = gfc_conv_descriptor_spacing_get (desc, tmp); cond1 = fold_build2_loc (input_location, GE_EXPR, logical_type_node, ubound, lbound); cond3 = fold_build2_loc (input_location, GE_EXPR, logical_type_node, - sm, gfc_index_zero_node); + spacing, gfc_index_zero_node); cond3 = fold_build2_loc (input_location, TRUTH_AND_EXPR, logical_type_node, cond3, cond1); cond4 = fold_build2_loc (input_location, LT_EXPR, logical_type_node, - sm, gfc_index_zero_node); + spacing, gfc_index_zero_node); if (assumed_size) cond = fold_build2_loc (input_location, EQ_EXPR, logical_type_node, tmp, build_int_cst (gfc_array_index_type, @@ -3697,7 +3783,9 @@ gfc_set_descriptor_for_assign_realloc (stmtblock_t *block, gfc_loopinfo *loop, to the corresponding element of LBOUND(expr)." Reuse size1 to keep a dimension-by-dimension track of the stride of the new array. */ - tree size1 = elemsize2; + tree size1 = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, elemsize2, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); tree offset = gfc_index_zero_node; for (int n = 0; n < expr2->rank; n++) @@ -3724,7 +3812,7 @@ gfc_set_descriptor_for_assign_realloc (stmtblock_t *block, gfc_loopinfo *loop, gfc_conv_descriptor_lbound_set (block, desc, gfc_rank_cst[n], lbound); gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[n], ubound); - gfc_conv_descriptor_sm_set (block, desc, gfc_rank_cst[n], size1); + gfc_conv_descriptor_spacing_set (block, desc, gfc_rank_cst[n], size1); lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[n]); tree tmp2 = fold_build2_loc (input_location, MULT_EXPR, @@ -3742,7 +3830,11 @@ gfc_set_descriptor_for_assign_realloc (stmtblock_t *block, gfc_loopinfo *loop, gfc_conv_descriptor_offset_set (block, desc, offset); if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))) - gfc_conv_descriptor_span_set (block, desc, elemsize2); + { + gfc_conv_descriptor_span_set (block, desc, elemsize2); + gfc_conv_descriptor_align_set (block, desc, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); + } /* For deferred character length, the 'size' field of the dtype might have changed so set the dtype. */ @@ -3822,9 +3914,13 @@ gfc_set_pdt_array_descriptor (stmtblock_t *block, tree desc, fields can then be filled from the values so obtained. */ gcc_assert (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))); + gfc_conv_descriptor_align_set (block, desc, + GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); gfc_conv_descriptor_dtype_set (block, desc, gfc_get_dtype (TREE_TYPE (desc))); tree size = gfc_conv_descriptor_elem_len_get (desc); + size = fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, + desc, GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); tree offset = gfc_index_zero_node; for (int i = 0; i < as->rank; i++) { @@ -3844,17 +3940,12 @@ gfc_set_pdt_array_descriptor (stmtblock_t *block, tree desc, gfc_free_expr (e); tree upper = tse.expr; gfc_conv_descriptor_ubound_set (block, desc, gfc_rank_cst[i], upper); - gfc_conv_descriptor_sm_set (block, desc, gfc_rank_cst[i], size); size = gfc_evaluate_now (size, block); + gfc_conv_descriptor_spacing_set (block, desc, gfc_rank_cst[i], size); offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, offset, size); offset = gfc_evaluate_now (offset, block); - tree tmp = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - upper, lower); - tmp = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, - tmp, gfc_index_one_node); + tree tmp = gfc_conv_array_extent_dim (lower, upper, nullptr); size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, size, tmp); } diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index b991d2a41895..5f1d7f3f17b9 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -41,6 +41,7 @@ void gfc_copy_descriptor (stmtblock_t *block, tree dest, tree src, tree gfc_conv_descriptor_data_get (tree); tree gfc_conv_descriptor_offset_get (tree); tree gfc_conv_descriptor_span_get (tree); +tree gfc_conv_descriptor_align_get (tree); tree gfc_conv_descriptor_dtype_get (tree); tree gfc_conv_descriptor_rank_get (tree); tree gfc_conv_descriptor_elem_len_get (tree); @@ -54,7 +55,7 @@ tree gfc_conv_descriptor_stride_get (tree, tree); tree gfc_conv_descriptor_lbound_get (tree, tree); tree gfc_conv_descriptor_ubound_get (tree, tree); tree gfc_conv_descriptor_extent_get (tree, tree); -tree gfc_conv_descriptor_sm_get (tree, tree); +tree gfc_conv_descriptor_spacing_get (tree, tree); tree gfc_conv_descriptor_token_get (tree); tree gfc_conv_descriptor_token_field (tree); @@ -84,7 +85,7 @@ void gfc_conv_shift_descriptor (stmtblock_t*, tree, tree, int, tree); void gfc_conv_shift_descriptor_subarray (stmtblock_t*, tree, gfc_expr *, gfc_expr *); void gfc_conv_shift_descriptor (stmtblock_t *, tree, int, tree *, tree *); -void gfc_set_temporary_descriptor (stmtblock_t *, tree, tree, tree, tree, +void gfc_set_temporary_descriptor (stmtblock_t *, tree, tree, tree, tree, tree, tree[GFC_MAX_DIMENSIONS], tree[GFC_MAX_DIMENSIONS], tree[GFC_MAX_DIMENSIONS], int, bool, bool, bool); diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc index e49d447bb85e..acd6ee937d28 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -2785,7 +2785,7 @@ gfc_conv_substring (gfc_se * se, gfc_ref * ref, int kind, /* For BIND(C), a BT_CHARACTER is not an ARRAY_TYPE. */ if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) { - tmp = gfc_build_array_ref (tmp, start.expr, NULL_TREE, true); + tmp = gfc_build_array_ref (tmp, start.expr, true); se->expr = gfc_build_addr_expr (type, tmp); } } @@ -4798,7 +4798,7 @@ gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc) for (n = 0; n < GFC_TYPE_ARRAY_RANK (type); n++) { dim = gfc_rank_cst[n]; - GFC_TYPE_ARRAY_SM (type, n) = gfc_conv_array_sm (desc, n); + GFC_TYPE_ARRAY_SPACING (type, n) = gfc_conv_array_spacing (desc, n); if (GFC_TYPE_ARRAY_LBOUND (type, n) == NULL_TREE) { GFC_TYPE_ARRAY_LBOUND (type, n) @@ -4820,7 +4820,7 @@ gfc_set_interface_mapping_bounds (stmtblock_t * block, tree type, tree desc) } tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, GFC_TYPE_ARRAY_LBOUND (type, n), - GFC_TYPE_ARRAY_SM (type, n)); + GFC_TYPE_ARRAY_SPACING (type, n)); offset = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, offset, tmp); } @@ -6245,7 +6245,9 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) tmp = gfc_conv_descriptor_extent_get (gfc, idx); gfc_add_modify (&loop_body, gfc_get_cfi_dim_extent (cfi, idx), tmp); /* d->dim[n].sm = gfc->dim[i].stride * gfc->span); */ - tmp = gfc_conv_descriptor_sm_get (gfc, idx); + tmp = gfc_conv_descriptor_spacing_get (gfc, idx); + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + tmp, gfc_conv_descriptor_align_get (gfc)); gfc_add_modify (&loop_body, gfc_get_cfi_dim_sm (cfi, idx), tmp); /* Generate loop. */ diff --git a/gcc/fortran/trans-intrinsic.cc b/gcc/fortran/trans-intrinsic.cc index 7e0089161777..9b8874910cee 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -2347,19 +2347,21 @@ gfc_conv_is_contiguous_expr (gfc_se *se, gfc_expr *arg) gfc_add_block_to_block (&se->post, &argse.post); desc = gfc_evaluate_now (argse.expr, &se->pre); - tree sm = gfc_conv_descriptor_sm_get (desc, gfc_rank_cst[0]); + tree spacing = gfc_conv_descriptor_spacing_get (desc, gfc_rank_cst[0]); + tmp = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + spacing, gfc_conv_descriptor_align_get (desc)); cond = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, - sm, gfc_conv_descriptor_span_get (desc)); + tmp, gfc_conv_descriptor_span_get (desc)); for (i = 0; i < arg->rank - 1; i++) { extent = gfc_conv_descriptor_extent_get (desc, gfc_rank_cst[i]); - tmp = gfc_conv_descriptor_sm_get (desc, gfc_rank_cst[i]); + tmp = gfc_conv_descriptor_spacing_get (desc, gfc_rank_cst[i]); tmp = fold_build2_loc (input_location, MULT_EXPR, TREE_TYPE (tmp), tmp, extent); - sm = gfc_conv_descriptor_sm_get (desc, gfc_rank_cst[i+1]); + spacing = gfc_conv_descriptor_spacing_get (desc, gfc_rank_cst[i+1]); tmp = fold_build2_loc (input_location, EQ_EXPR, boolean_type_node, - sm, tmp); + spacing, tmp); cond = fold_build2_loc (input_location, TRUTH_AND_EXPR, boolean_type_node, cond, tmp); } @@ -5533,8 +5535,7 @@ gfc_conv_intrinsic_minmaxloc (gfc_se * se, gfc_expr * expr, enum tree_code op) for (int i = 0; i < arrayexpr->rank; i++) { tree res_idx = build_int_cst (gfc_array_index_type, i); - tree res_arr_ref = gfc_build_array_ref (result_var, res_idx, - NULL_TREE, true); + tree res_arr_ref = gfc_build_array_ref (result_var, res_idx, true); tree value = convert (type, pos[i]); gfc_add_modify (&se->pre, res_arr_ref, value); @@ -9003,7 +9004,7 @@ gfc_conv_associated (gfc_se *se, gfc_expr *expr) } else tmp = gfc_rank_cst[arg1->expr->rank - 1]; - tmp = gfc_conv_descriptor_sm_get (arg1se.expr, tmp); + tmp = gfc_conv_descriptor_spacing_get (arg1se.expr, tmp); if (arg2->expr->rank != 0) nonzero_arraylen = fold_build2_loc (input_location, NE_EXPR, logical_type_node, tmp, diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc index 99df15dcd86b..52b011217e55 100644 --- a/gcc/fortran/trans-io.cc +++ b/gcc/fortran/trans-io.cc @@ -772,10 +772,13 @@ gfc_convert_array_to_string (gfc_se * se, gfc_expr * e) else { gcc_assert (GFC_DESCRIPTOR_TYPE_P (type)); - tree sm = gfc_conv_array_sm (array, rank); + tree spacing = gfc_conv_array_spacing (array, rank); tree tmp = gfc_conv_array_extent (array, rank); full_size = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, tmp, sm); + gfc_array_index_type, tmp, spacing); + full_size = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, full_size, + GFC_TYPE_ARRAY_ALIGN (type)); } gcc_assert (elts_count || full_size); @@ -1652,7 +1655,7 @@ nml_get_addr_expr (gfc_symbol * sym, gfc_component * c, tmp = gfc_build_addr_expr (NULL_TREE, tmp); if (TREE_CODE (TREE_TYPE (tmp)) == ARRAY_TYPE) - tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL); + tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, NULL_TREE, NULL_TREE); if (!POINTER_TYPE_P (TREE_TYPE (tmp))) tmp = build_fold_indirect_ref_loc (input_location, @@ -1818,7 +1821,7 @@ transfer_namelist_element (stmtblock_t * block, const char * var_name, iocall[IOCALL_SET_NML_VAL_DIM], 5, dt_parm_addr, build_int_cst (gfc_int4_type_node, n_dim), - gfc_conv_array_sm (decl, n_dim), + gfc_conv_array_spacing (decl, n_dim), gfc_conv_array_lbound (decl, n_dim), gfc_conv_array_ubound (decl, n_dim)); gfc_add_expr_to_block (block, tmp); diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index e6afb84c031d..96b23a4fde77 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -779,17 +779,18 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer) gfc_add_modify (&cond_block, decl, outer); tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1]; size = gfc_conv_descriptor_extent_get (decl, rank); + tree spacing; if (GFC_TYPE_ARRAY_RANK (type) >= 1) - size = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, size, - gfc_conv_descriptor_sm_get (decl, rank)); + spacing = gfc_conv_descriptor_spacing_get (decl, rank); else { tree esize = gfc_conv_descriptor_span_get (decl); - esize = fold_convert_loc (input_location, gfc_array_index_type, esize); - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, esize); + spacing = fold_convert_loc (input_location, gfc_array_index_type, esize); } + size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + size, spacing); + size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + size, gfc_conv_descriptor_align_get (decl)); size = unshare_expr (size); size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block); @@ -968,17 +969,16 @@ gfc_omp_clause_copy_ctor (tree clause, tree dest, tree src) { tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1]; size = gfc_conv_descriptor_extent_get (dest, rank); + tree spacing; if (GFC_TYPE_ARRAY_RANK (type) >= 1) - size = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, size, - gfc_conv_descriptor_sm_get (dest, rank)); + spacing = gfc_conv_descriptor_spacing_get (dest, rank); else { tree esize = gfc_conv_descriptor_span_get (dest); - esize = fold_convert_loc (input_location, gfc_array_index_type, esize); - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, esize); + spacing = fold_convert_loc (input_location, gfc_array_index_type, esize); } + size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + size, spacing); size = unshare_expr (size); size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block); @@ -1089,17 +1089,21 @@ gfc_omp_clause_assign_op (tree clause, tree dest, tree src) { tree rank = gfc_rank_cst[GFC_TYPE_ARRAY_RANK (type) - 1]; size = gfc_conv_descriptor_extent_get (src, rank); + tree spacing; if (GFC_TYPE_ARRAY_RANK (type) >= 1) - size = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, size, - gfc_conv_descriptor_sm_get (src, rank)); + { + spacing = gfc_conv_descriptor_spacing_get (src, rank); + spacing = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, spacing, + gfc_conv_descriptor_align_get (src)); + } else { tree esize = gfc_conv_descriptor_span_get (src); - esize = fold_convert_loc (input_location, gfc_array_index_type, esize); - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, esize); + spacing = fold_convert_loc (input_location, gfc_array_index_type, esize); } + size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, + size, spacing); size = unshare_expr (size); size = gfc_evaluate_now (fold_convert (size_type_node, size), &cond_block); @@ -1869,7 +1873,7 @@ gfc_omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type) { omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_LBOUND (type, r)); omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_UBOUND (type, r)); - omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SM (type, r)); + omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SPACING (type, r)); } omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_SIZE (type)); omp_firstprivatize_variable (ctx, GFC_TYPE_ARRAY_OFFSET (type)); diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index 72b7d715fe1b..648a09fc2a7d 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -1855,15 +1855,18 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, int known_offset; mpz_t offset; mpz_t stride; - mpz_t sm; + mpz_t spacing; mpz_t delta; gfc_expr *expr; mpz_init_set_ui (offset, 0); mpz_init_set_ui (stride, 1); wide_int elem_len = wi::to_wide (TYPE_SIZE_UNIT (etype)); - gcc_assert (wi::fits_shwi_p (elem_len)); - mpz_init_set_ui (sm, elem_len.to_shwi ()); + wide_int align = wi::uhwi (TYPE_ALIGN_UNIT (etype), + TYPE_PRECISION (gfc_array_index_type)); + wide_int aligned_len = wi::udiv_trunc (elem_len, align); + gcc_assert (wi::fits_shwi_p (aligned_len)); + mpz_init_set_ui (spacing, aligned_len.to_shwi ()); mpz_init (delta); /* We don't use build_array_type because this does not include @@ -1881,12 +1884,12 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, known_offset = 1; for (n = 0; n < as->rank; n++) { - /* Fill in the sm and bound components of the type. */ + /* Fill in the spacing and bound components of the type. */ if (known_stride) - tmp = gfc_conv_mpz_to_tree (sm, gfc_index_integer_kind); + tmp = gfc_conv_mpz_to_tree (spacing, gfc_index_integer_kind); else tmp = NULL_TREE; - GFC_TYPE_ARRAY_SM (type, n) = tmp; + GFC_TYPE_ARRAY_SPACING (type, n) = tmp; expr = as->lower[n]; if (expr && expr->expr_type == EXPR_CONSTANT) @@ -1904,7 +1907,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, if (known_stride) { /* Calculate the offset. */ - mpz_mul (delta, sm, as->lower[n]->value.integer); + mpz_mul (delta, spacing, as->lower[n]->value.integer); mpz_sub (offset, offset, delta); } else @@ -1930,7 +1933,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, as->lower[n]->value.integer); mpz_add_ui (delta, delta, 1); mpz_mul (stride, stride, delta); - mpz_mul (sm, sm, delta); + mpz_mul (spacing, spacing, delta); } /* Only the first stride is known for partial packed arrays. */ @@ -1976,6 +1979,9 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, if (packed != PACKED_NO) GFC_TYPE_ARRAY_ELEM_LEN (type) = TYPE_SIZE_UNIT (etype); + wide_int index_one = wi::one (TYPE_PRECISION (gfc_array_index_type)); + GFC_TYPE_ARRAY_ALIGN (type) = wide_int_to_tree (gfc_array_index_type, + wi::lshift (index_one, align)); GFC_TYPE_ARRAY_RANK (type) = as->rank; GFC_TYPE_ARRAY_CORANK (type) = as->corank; GFC_TYPE_ARRAY_DTYPE (type) = NULL_TREE; @@ -2055,7 +2061,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, array_type_done: mpz_clear (offset); mpz_clear (stride); - mpz_clear (sm); + mpz_clear (spacing); mpz_clear (delta); return type; @@ -2119,6 +2125,12 @@ gfc_get_array_descriptor_base (int dimen, int codimen, bool restricted) gfc_array_index_type, &chain); suppress_warning (decl); + /* Add the span component. */ + decl = gfc_add_field_to_struct_1 (fat_type, + get_identifier ("align"), + gfc_array_index_type, &chain); + suppress_warning (decl); + /* Build the array type for the stride and bound components. */ if (dimen + codimen > 0) { @@ -2205,27 +2217,36 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, GFC_DESCRIPTOR_TYPE_P (fat_type) = 1; TYPE_LANG_SPECIFIC (fat_type) = ggc_cleared_alloc<struct lang_type> (); + int index_precision = TYPE_PRECISION (gfc_array_index_type); + wide_int align = wi::uhwi (TYPE_ALIGN_UNIT (etype), index_precision); + wide_int index_one = wi::one (index_precision); + GFC_TYPE_ARRAY_ALIGN (fat_type) = wide_int_to_tree (gfc_array_index_type, + wi::lshift (index_one, align)); GFC_TYPE_ARRAY_RANK (fat_type) = dimen; GFC_TYPE_ARRAY_CORANK (fat_type) = codimen; GFC_TYPE_ARRAY_DTYPE (fat_type) = NULL_TREE; GFC_TYPE_ARRAY_AKIND (fat_type) = akind; /* Build an array descriptor record type. */ - tree sm; + tree spacing; if (packed != 0) { stride = gfc_index_one_node; - sm = TYPE_SIZE_UNIT (etype); + spacing = TYPE_SIZE_UNIT (etype); + spacing = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, spacing, + build_int_cst (gfc_array_index_type, + TYPE_ALIGN_UNIT (etype))); } else { stride = NULL_TREE; - sm = NULL_TREE; + spacing = NULL_TREE; } for (n = 0; n < dimen + codimen; n++) { if (n < dimen) - GFC_TYPE_ARRAY_SM (fat_type, n) = sm; + GFC_TYPE_ARRAY_SPACING (fat_type, n) = spacing; if (lbound) lower = lbound[n]; @@ -2260,15 +2281,15 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, tmp = gfc_conv_array_extent_dim (lower, upper, nullptr); stride = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, tmp, stride); - sm = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, tmp, sm); + spacing = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, tmp, spacing); /* Check the folding worked. */ gcc_assert (INTEGER_CST_P (stride)); } else { stride = NULL_TREE; - sm = NULL_TREE; + spacing = NULL_TREE; } } GFC_TYPE_ARRAY_SIZE (fat_type) = stride; @@ -3847,7 +3868,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) bool indirect = false; tree etype, ptype, t, base_decl; tree data_off, span_off, dim_off, dtype_off, dim_size; - tree lower_suboff, upper_suboff, sm_suboff; + tree lower_suboff, upper_suboff, spacing_suboff; tree dtype, field, rank_off; if (! GFC_DESCRIPTOR_TYPE_P (type)) @@ -3902,7 +3923,7 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) base_decl = build1 (INDIRECT_REF, ptype, base_decl); gfc_get_descriptor_offsets_for_info (type, &data_off, &dtype_off, &span_off, - &dim_off, &dim_size, &sm_suboff, + &dim_off, &dim_size, &spacing_suboff, &lower_suboff, &upper_suboff); t = base_decl; @@ -3974,8 +3995,10 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) } t = fold_build_pointer_plus (base_decl, size_binop (PLUS_EXPR, - dim_off, sm_suboff)); + dim_off, spacing_suboff)); t = build1 (INDIRECT_REF, gfc_array_index_type, t); + t = build2 (MULT_EXPR, gfc_array_index_type, t, + GFC_TYPE_ARRAY_ALIGN (type)); info->dimen[dim].stride = t; if (dim + 1 < rank) dim_off = size_binop (PLUS_EXPR, dim_off, dim_size); diff --git a/gcc/fortran/trans.cc b/gcc/fortran/trans.cc index b4ba84964175..7120824b8195 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -387,81 +387,6 @@ gfc_build_addr_expr (tree type, tree t) } -static tree -get_array_span (tree type, tree decl) -{ - tree span; - - /* Component references are guaranteed to have a reliable value for - 'span'. Likewise indirect references since they emerge from the - conversion of a CFI descriptor or the hidden dummy descriptor. */ - if (TREE_CODE (decl) == COMPONENT_REF - && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) - return gfc_conv_descriptor_span_get (decl); - else if (INDIRECT_REF_P (decl) - && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) - return gfc_conv_descriptor_span_get (decl); - - /* Return the span for deferred character length array references. */ - if (type - && (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == INTEGER_TYPE) - && TYPE_STRING_FLAG (type)) - { - if (TREE_CODE (decl) == PARM_DECL) - decl = build_fold_indirect_ref_loc (input_location, decl); - if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) - span = gfc_conv_descriptor_span_get (decl); - else - span = gfc_get_character_len_in_bytes (type); - span = (span && !integer_zerop (span)) - ? (fold_convert (gfc_array_index_type, span)) : (NULL_TREE); - } - /* Likewise for class array or pointer array references. */ - else if (TREE_CODE (decl) == FIELD_DECL - || VAR_OR_FUNCTION_DECL_P (decl) - || TREE_CODE (decl) == PARM_DECL) - { - if (GFC_DECL_CLASS (decl)) - { - /* When a temporary is in place for the class array, then the - original class' declaration is stored in the saved - descriptor. */ - if (DECL_LANG_SPECIFIC (decl) && GFC_DECL_SAVED_DESCRIPTOR (decl)) - decl = GFC_DECL_SAVED_DESCRIPTOR (decl); - else - { - /* Allow for dummy arguments and other good things. */ - if (POINTER_TYPE_P (TREE_TYPE (decl))) - decl = build_fold_indirect_ref_loc (input_location, decl); - - /* Check if '_data' is an array descriptor. If it is not, - the array must be one of the components of the class - object, so return a null span. */ - if (!GFC_DESCRIPTOR_TYPE_P (TREE_TYPE ( - gfc_class_data_get (decl)))) - return NULL_TREE; - } - span = gfc_class_vtab_size_get (decl); - /* For unlimited polymorphic entities then _len component needs - to be multiplied with the size. */ - span = gfc_resize_class_size_with_len (NULL, decl, span); - } - else if (GFC_DECL_PTR_ARRAY_P (decl)) - { - if (TREE_CODE (decl) == PARM_DECL) - decl = build_fold_indirect_ref_loc (input_location, decl); - span = gfc_conv_descriptor_span_get (decl); - } - else - span = NULL_TREE; - } - else - span = NULL_TREE; - - return span; -} - - tree gfc_build_spanned_array_ref (tree base, tree offset, tree span) { @@ -487,11 +412,10 @@ gfc_build_spanned_array_ref (tree base, tree offset, tree span) have to play it safe and use pointer arithmetic. */ tree -gfc_build_array_ref (tree base, tree offset, tree decl, - bool non_negative_offset, tree vptr) +gfc_build_array_ref (tree base, tree offset, bool non_negative_offset, + tree spacing, tree align) { tree type = TREE_TYPE (base); - tree span = NULL_TREE; if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0) { @@ -503,7 +427,6 @@ gfc_build_array_ref (tree base, tree offset, tree decl, /* Scalar coarray, there is nothing to do. */ if (TREE_CODE (type) != ARRAY_TYPE) { - gcc_assert (decl == NULL_TREE); gcc_assert (integer_zerop (offset)); return base; } @@ -516,28 +439,9 @@ gfc_build_array_ref (tree base, tree offset, tree decl, /* Strip NON_LVALUE_EXPR nodes. */ STRIP_TYPE_NOPS (offset); - /* If decl or vptr are non-null, pointer arithmetic for the array reference - is likely. Generate the 'span' for the array reference. */ - if (vptr) - { - span = gfc_vptr_size_get (vptr); - - /* Check if this is an unlimited polymorphic object carrying a character - payload. In this case, the 'len' field is non-zero. */ - if (decl && GFC_CLASS_TYPE_P (TREE_TYPE (decl))) - span = gfc_resize_class_size_with_len (NULL, decl, span); - } - else if (decl) - span = get_array_span (type, decl); - - /* If a non-null span has been generated reference the element with - pointer arithmetic. */ - if (span != NULL_TREE) - return gfc_build_spanned_array_ref (base, offset, span); - /* Else use a straightforward array reference if possible. */ - else if (non_negative_offset) + if (non_negative_offset) return build4_loc (input_location, ARRAY_REF, type, base, offset, - NULL_TREE, NULL_TREE); + NULL_TREE, spacing); /* Otherwise use pointer arithmetic. */ else { @@ -554,12 +458,13 @@ gfc_build_array_ref (tree base, tree offset, tree decl, fold_convert (gfc_array_index_type, min)) : fold_convert (gfc_array_index_type, offset); - tree elt_size = fold_convert (gfc_array_index_type, - TYPE_SIZE_UNIT (type)); + tree offset_align = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, + zero_based_index, spacing); tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - zero_based_index, elt_size); + offset_align, align); tree base_addr = gfc_build_addr_expr (pvoid_type_node, base); diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index 3e985bdb9127..e254f9f1dc60 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -196,12 +196,11 @@ typedef struct gfc_array_info tree descriptor; /* holds the pointer to the data array. */ tree data; - /* Original data pointer without additional offset. */ - tree saved_data; /* To move some of the array index calculation out of the innermost loop. */ tree offset; /* Original offset. */ tree saved_offset; + tree align; /* Holds the SS for a subscript. Indexed by actual dimension. */ struct gfc_ss *subscript[GFC_MAX_DIMENSIONS]; @@ -214,9 +213,8 @@ typedef struct gfc_array_info references. */ tree stride[GFC_MAX_DIMENSIONS]; /* The spacing in memory of elements of consecutive indexes, for each - dimension. This is the intrinsic spacing of the array given by its stride - multiplier (sm). In units whose size is given by the element type if - array_access is true, otherwise in bytes. */ + dimension. This is the intrinsic spacing of the array. In alignment-sized + units. */ tree spacing[GFC_MAX_DIMENSIONS]; tree delta[GFC_MAX_DIMENSIONS]; @@ -649,9 +647,8 @@ tree gfc_get_extern_function_decl (gfc_symbol *, tree gfc_build_addr_expr (tree, tree); /* Build an ARRAY_REF. */ -tree gfc_build_array_ref (tree, tree, tree, - bool non_negative_offset = false, - tree vptr = NULL_TREE); +tree gfc_build_array_ref (tree, tree, bool non_negative_offset = false, + tree spacing = NULL_TREE, tree align = NULL_TREE); /* Build an array ref using pointer arithmetic. */ tree gfc_build_spanned_array_ref (tree base, tree offset, tree span); @@ -1038,8 +1035,9 @@ struct GTY(()) lang_type { enum gfc_array_kind akind; tree lbound[GFC_MAX_DIMENSIONS]; tree ubound[GFC_MAX_DIMENSIONS]; - tree sm[GFC_MAX_DIMENSIONS]; + tree spacing[GFC_MAX_DIMENSIONS]; tree elem_len; + tree align; tree size; tree offset; tree dtype; @@ -1111,8 +1109,8 @@ struct GTY(()) lang_decl { (TYPE_LANG_SPECIFIC(node)->lbound[dim]) #define GFC_TYPE_ARRAY_UBOUND(node, dim) \ (TYPE_LANG_SPECIFIC(node)->ubound[dim]) -#define GFC_TYPE_ARRAY_SM(node, dim) \ - (TYPE_LANG_SPECIFIC(node)->sm[dim]) +#define GFC_TYPE_ARRAY_SPACING(node, dim) \ + (TYPE_LANG_SPECIFIC(node)->spacing[dim]) #define GFC_TYPE_ARRAY_EXTENT(node, dim) \ (fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, \ fold_build2_loc (input_location, MINUS_EXPR, \ @@ -1120,13 +1118,16 @@ struct GTY(()) lang_decl { GFC_TYPE_ARRAY_UBOUND((node), (dim)), \ GFC_TYPE_ARRAY_LBOUND((node), (dim))), \ gfc_index_one_node)) +#if 0 #define GFC_TYPE_ARRAY_STRIDE(node, dim) \ (fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, \ - GFC_TYPE_ARRAY_SM((node), (dim)), \ - GFC_TYPE_ARRAY_ELEM_LEN((node)))) + GFC_TYPE_ARRAY_SPACING((node), (dim)), \ + GFC_TYPE_ARRAY_ALIGN((node)))) +#endif #define GFC_TYPE_ARRAY_ELEM_LEN(node) (TYPE_LANG_SPECIFIC(node)->elem_len) #define GFC_TYPE_ARRAY_RANK(node) (TYPE_LANG_SPECIFIC(node)->rank) #define GFC_TYPE_ARRAY_CORANK(node) (TYPE_LANG_SPECIFIC(node)->corank) +#define GFC_TYPE_ARRAY_ALIGN(node) (TYPE_LANG_SPECIFIC(node)->align) #define GFC_TYPE_ARRAY_CAF_TOKEN(node) (TYPE_LANG_SPECIFIC(node)->caf_token) #define GFC_TYPE_ARRAY_CAF_OFFSET(node) (TYPE_LANG_SPECIFIC(node)->caf_offset) #define GFC_TYPE_ARRAY_SIZE(node) (TYPE_LANG_SPECIFIC(node)->size)