https://gcc.gnu.org/g:bbffd5e2f96f55874352161d29b93f9065b80845
commit bbffd5e2f96f55874352161d29b93f9065b80845 Author: Mikael Morin <mik...@gcc.gnu.org> Date: Tue Apr 8 10:21:36 2025 +0200 Sauvegarde compil' OK Diff: --- gcc/fortran/trans-array.cc | 309 ++++++++++++-------------------- gcc/fortran/trans-decl.cc | 196 +++++++++++--------- gcc/fortran/trans-descriptor.cc | 157 +++++----------- gcc/fortran/trans-descriptor.h | 6 +- gcc/fortran/trans-expr.cc | 9 +- gcc/fortran/trans-intrinsic.cc | 20 +-- gcc/fortran/trans-io.cc | 8 +- gcc/fortran/trans-openmp.cc | 25 +-- gcc/fortran/trans-types.cc | 174 ++++++------------ gcc/fortran/trans.cc | 85 +++++---- gcc/fortran/trans.h | 25 ++- libgfortran/caf/single.c | 2 - libgfortran/generated/reshape_c10.c | 5 +- libgfortran/generated/reshape_c16.c | 5 +- libgfortran/generated/reshape_c17.c | 5 +- libgfortran/generated/reshape_c4.c | 5 +- libgfortran/generated/reshape_c8.c | 5 +- libgfortran/generated/reshape_i16.c | 5 +- libgfortran/generated/reshape_i4.c | 5 +- libgfortran/generated/reshape_i8.c | 5 +- libgfortran/generated/reshape_r10.c | 5 +- libgfortran/generated/reshape_r16.c | 5 +- libgfortran/generated/reshape_r17.c | 5 +- libgfortran/generated/reshape_r4.c | 5 +- libgfortran/generated/reshape_r8.c | 5 +- libgfortran/intrinsics/cshift0.c | 1 - libgfortran/intrinsics/eoshift0.c | 1 - libgfortran/intrinsics/eoshift2.c | 3 +- libgfortran/intrinsics/move_alloc.c | 1 - libgfortran/intrinsics/pack_generic.c | 2 - libgfortran/intrinsics/spread_generic.c | 7 +- libgfortran/intrinsics/unpack_generic.c | 2 +- libgfortran/libgfortran.h | 11 +- libgfortran/m4/reshape.m4 | 3 +- 34 files changed, 467 insertions(+), 645 deletions(-) diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc index fa7afc938e58..4c8136ba6a1d 100644 --- a/gcc/fortran/trans-array.cc +++ b/gcc/fortran/trans-array.cc @@ -964,10 +964,6 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, if (class_expr == NULL_TREE && GFC_CLASS_TYPE_P (eltype)) class_expr = get_class_info_from_ss (pre, ss, &eltype, &fcn_ss); - bool array_access = class_expr == NULL_TREE - && eltype != NULL_TREE - && !GFC_CLASS_TYPE_P (eltype); - /* If the dynamic type is not available, use the declared type. */ if (eltype && GFC_CLASS_TYPE_P (eltype)) eltype = gfc_get_element_type (TREE_TYPE (TYPE_FIELDS (eltype))); @@ -1148,10 +1144,8 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, } info->descriptor = desc; - info->array_access = array_access; - 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))); + size = elemsize; + nelem = gfc_index_one_node; /* Fill in the bounds and stride. This is a packed array, so: @@ -1217,9 +1211,14 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, or_expr = fold_build2_loc (input_location, TRUTH_OR_EXPR, logical_type_node, or_expr, cond); + extent = gfc_evaluate_now (extent, pre); + size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, size, extent); size = gfc_evaluate_now (size, pre); + + nelem = fold_build2_loc (input_location, MULT_EXPR, + gfc_array_index_type, nelem, extent); } } @@ -1228,27 +1227,24 @@ gfc_trans_create_temp_array (stmtblock_t * pre, stmtblock_t * post, gfc_ss * ss, /* Get the size of the array. */ if (size && !callee_alloc) { + or_expr = gfc_evaluate_now (or_expr, pre); + /* If or_expr is true, then the extent in at least one dimension is zero and the size is set to zero. */ size = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, or_expr, gfc_index_zero_node, size); - nelem = size; - size = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - size, elemsize); + nelem = fold_build3_loc (input_location, COND_EXPR, gfc_array_index_type, + or_expr, gfc_index_zero_node, nelem); } else - { - nelem = size; - size = NULL_TREE; - } + size = NULL_TREE; tree data_ptr = gfc_trans_allocate_array_storage (pre, post, info, size, nelem, initial, dynamic, dealloc); gfc_set_temporary_descriptor (pre, desc, class_expr, elemsize, - GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc)), data_ptr, from, to, spacing, total_dim, !bounds_known, rank_changer, shift_bounds); @@ -2183,35 +2179,6 @@ gfc_build_constant_array_constructor (gfc_expr * expr, tree type) } -static bool -array_access_safe_p (gfc_expr *expr) -{ - if (expr->ts.type == BT_CLASS) - return false; - - if (gfc_is_simply_contiguous (expr, false, true)) - return true; - - symbol_attribute attr = gfc_expr_attr (expr); - if (attr.pointer) - return false; - - if (expr->expr_type == EXPR_VARIABLE - && attr.dummy) - { - gfc_symbol *sym = expr->symtree->n.sym; - - gfc_array_spec *as = sym->as; - if (as - && !(as->type == AS_EXPLICIT - || as->type == AS_ASSUMED_SIZE)) - return false; - } - - return true; -} - - /* Translate a constant EXPR_ARRAY array constructor for the scalarizer. This mostly initializes the scalarizer state info structure with the appropriate values to directly use the array created by the function @@ -2229,7 +2196,6 @@ trans_constant_array_constructor (gfc_ss * ss, tree type) info = &ss->info->data.array; info->descriptor = tmp; - info->array_access = array_access_safe_p (ss->info->expr); info->data = gfc_build_addr_expr (NULL_TREE, tmp); info->offset = gfc_index_zero_node; @@ -2956,7 +2922,6 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) else info->descriptor = gfc_evaluate_now (se.expr, block); } - info->array_access = array_access_safe_p (ss_info->expr); ss_info->string_length = se.string_length; ss_info->class_container = se.class_container; @@ -2996,16 +2961,6 @@ gfc_conv_ss_descriptor (stmtblock_t * block, gfc_ss * ss, int base) if (!ss->is_alloc_lhs) tmp = gfc_evaluate_now (tmp, block); info->offset = tmp; - - /* Make absolutely sure that the saved_offset is indeed saved - 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; } } @@ -3080,20 +3035,6 @@ 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 @@ -3437,7 +3378,7 @@ build_class_array_ref (gfc_se *se, tree base, tree index) /* For unlimited polymorphic entities then _len component needs to be multiplied with the size. */ size = gfc_resize_class_size_with_len (&se->pre, decl, size); - size = fold_convert (TREE_TYPE (index), size); + size = fold_convert (gfc_array_index_type, size); /* Return the element in the se expression. */ se->expr = gfc_build_spanned_array_ref (base, index, size); @@ -3463,7 +3404,11 @@ non_negative_strides_array_p (tree expr) gfc_array_kind array_kind = GFC_TYPE_ARRAY_AKIND (type); if (array_kind == GFC_ARRAY_ALLOCATABLE - || array_kind == GFC_ARRAY_ASSUMED_SHAPE_CONT) + || array_kind == GFC_ARRAY_ASSUMED_SHAPE_CONT + || array_kind == GFC_ARRAY_ASSUMED_RANK_CONT + || array_kind == GFC_ARRAY_ASSUMED_RANK_ALLOCATABLE + || array_kind == GFC_ARRAY_ASSUMED_RANK_POINTER_CONT + || array_kind == GFC_ARRAY_POINTER_CONT) return true; } @@ -3493,8 +3438,8 @@ build_array_ref (tree desc, tree offset) tmp = gfc_conv_array_data (desc); tmp = build_fold_indirect_ref_loc (input_location, tmp); - tmp = gfc_build_array_ref (tmp, offset, non_negative_strides_array_p (desc), - gfc_index_one_node, gfc_conv_array_align (desc)); + + tmp = gfc_build_array_ref (tmp, offset, non_negative_strides_array_p (desc)); return tmp; } @@ -3504,13 +3449,14 @@ build_array_ref (tree desc, tree offset) DIM is the array dimension, I is the loop dimension. */ static tree -conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, - gfc_array_ref * ar, tree spacing) +conv_array_index (gfc_se * se, gfc_ss * ss, int dim, int i, + gfc_array_ref * ar) { gfc_array_info *info; tree index; tree descriptor; tree data; + tree offset; info = &ss->info->data.array; @@ -3540,20 +3486,18 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, gcc_assert (info->subscript[dim] && info->subscript[dim]->info->type == GFC_SS_VECTOR); - /* Get a zero-based index into the vector. */ - index = fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - se->loop->loopvar[i], se->loop->from[i]); + offset = fold_build1_loc (input_location, NEGATE_EXPR, + gfc_array_index_type, se->loop->from[i]); descriptor = info->subscript[dim]->info->data.array.descriptor; - index = fold_convert_loc (input_location, gfc_array_index_type, index); + index = fold_convert_loc (input_location, gfc_array_index_type, + se->loop->loopvar[i]); /* Read the vector to get an index into info->descriptor. */ data = build_fold_indirect_ref_loc (input_location, gfc_conv_array_data (descriptor)); - index = gfc_build_array_ref (data, index, - gfc_conv_array_spacing (descriptor, 0), - gfc_conv_array_align (descriptor)); + index = gfc_build_array_ref (data, index, false, offset, + gfc_conv_array_spacing (descriptor, 0)); index = gfc_evaluate_now (index, &se->pre); index = fold_convert (gfc_array_index_type, index); @@ -3569,10 +3513,6 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, /* Multiply the loop variable by the stride and delta. */ index = se->loop->loopvar[i]; - if (!integer_onep (info->stride[dim])) - index = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, index, - info->stride[dim]); if (!integer_zerop (info->delta[dim])) index = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, index, @@ -3594,12 +3534,7 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i, gfc_array_index_type, index, info->delta[dim]); } - /* Multiply by the spacing. */ - if (spacing != NULL && !integer_onep (spacing)) - return fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - index, spacing); - else - return index; + return index; } @@ -3621,14 +3556,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar, else n = 0; - tree index = conv_array_index_offset (se, ss, ss->dim[n], n, ar, - info->spacing[ss->dim[n]]); - - /* 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); + tree index = conv_array_index (se, ss, ss->dim[n], n, ar); base = build_fold_indirect_ref_loc (input_location, info->data); @@ -3639,8 +3567,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar, bool non_negative_stride = tmp_array || non_negative_strides_array_p (info->descriptor); se->expr = gfc_build_array_ref (base, index, non_negative_stride, - tmp_array ? NULL_TREE : gfc_index_one_node, - tmp_array ? NULL_TREE : info->align); + info->offset, info->spacing[ss->dim[0]]); } @@ -3654,23 +3581,6 @@ gfc_conv_tmp_array_ref (gfc_se * se) gfc_advance_se_ss_chain (se); } -/* Add T to the offset pair *OFFSET, *CST_OFFSET. */ - -static void -add_to_offset (tree *cst_offset, tree *offset, tree t) -{ - if (TREE_CODE (t) == INTEGER_CST) - *cst_offset = int_const_binop (PLUS_EXPR, *cst_offset, t); - else - { - if (!integer_zerop (*offset)) - *offset = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, *offset, t); - else - *offset = t; - } -} - /* Build an array reference. se->expr already holds the array descriptor. This should be either a variable, indirect variable reference or component @@ -3683,7 +3593,6 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, locus * where) { int n; - tree offset, cst_offset; tree tmp; tree decl = NULL_TREE; gfc_se indexse; @@ -3740,18 +3649,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, && ar->as->type != AS_DEFERRED) decl = sym->backend_decl; - bool use_array_ref = array_access_safe_p (expr); - tree elem_len = NULL_TREE; - if (use_array_ref) - { - elem_len = gfc_get_array_span (decl, expr); - elem_len = fold_convert_loc (input_location, gfc_array_index_type, - elem_len); - } - - cst_offset = offset = gfc_index_zero_node; - tmp = gfc_conv_array_offset (decl); - add_to_offset (&cst_offset, &offset, tmp); + tree array = gfc_conv_array_data (decl); + array = build_fold_indirect_ref_loc (input_location, array); /* Calculate the offsets from all the dimensions. Make sure to associate the final offset so that we form a chain of loop invariant summands. */ @@ -3762,6 +3661,8 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, gfc_conv_expr_type (&indexse, ar->start[n], gfc_array_index_type); gfc_add_block_to_block (&se->pre, &indexse.pre); + tree lbound = gfc_conv_array_lbound (decl, n); + if ((gfc_option.rtcheck & GFC_RTCHECK_BOUNDS) && ! expr->no_bounds_check) { /* Check array bounds. */ @@ -3772,7 +3673,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, indexse.expr = save_expr (indexse.expr); /* Lower bound. */ - tmp = gfc_conv_array_lbound (decl, n); + tmp = lbound; if (sym->attr.temporary) { gfc_init_se (&tmpse, se); @@ -3818,31 +3719,27 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr, } } - /* 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); + tree spacing = gfc_conv_array_spacing (decl, n); - /* And add it to the total. */ - add_to_offset (&cst_offset, &offset, tmp); + gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (array))); + tmp = gfc_build_array_ref (array, indexse.expr, + non_negative_strides_array_p (decl), + lbound, spacing); + array = tmp; } - if (!integer_zerop (cst_offset)) - offset = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, offset, cst_offset); - free (var_name); - se->expr = build_array_ref (se->expr, offset); + se->expr = array; } /* Add the offset corresponding to array's ARRAY_DIM dimension and loop's LOOP_DIM dimension (if any) to array's offset. */ -static void -add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss, - gfc_array_ref *ar, int array_dim, int loop_dim) +static tree +add_array_index (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss, + tree array, gfc_array_ref *ar, int array_dim, int loop_dim, + const vec<tree> * array_type_domains) { gfc_se se; gfc_array_info *info; @@ -3852,28 +3749,45 @@ add_array_offset (stmtblock_t *pblock, gfc_loopinfo *loop, gfc_ss *ss, gfc_init_se (&se, NULL); se.loop = loop; se.expr = info->descriptor; - tree tmp = conv_array_index_offset (&se, ss, array_dim, loop_dim, ar, - info->spacing[array_dim]); + tree tmp = conv_array_index (&se, ss, array_dim, loop_dim, ar); + gfc_add_block_to_block (pblock, &se.pre); - if (info->array_access) - { - tree index = fold_convert_loc (input_location, gfc_array_index_type, tmp); + tree index = fold_convert_loc (input_location, gfc_array_index_type, tmp); - info->offset = fold_build2_loc (input_location, PLUS_EXPR, - gfc_array_index_type, - info->offset, index); - info->offset = gfc_evaluate_now (info->offset, pblock); - } + tree elt_type = NULL_TREE; + if (!array_type_domains || array_type_domains->is_empty ()) + elt_type = TREE_TYPE (array); else { - tree offset = fold_convert_loc (input_location, size_type_node, tmp); + tree desc_type = TREE_TYPE (info->descriptor); + tree core_type = TREE_TYPE (GFC_TYPE_ARRAY_DATAPTR_TYPE (desc_type)); - info->data = fold_build2_loc (input_location, POINTER_PLUS_EXPR, - TREE_TYPE (info->data), - info->data, offset); - info->data = gfc_evaluate_now (info->data, pblock); + unsigned j; + tree *dom_p; + FOR_EACH_VEC_ELT (*array_type_domains, j, dom_p) + { + gcc_assert (GFC_ARRAY_TYPE_P (core_type) + && TYPE_DOMAIN (core_type) == *dom_p); + core_type = TREE_TYPE (core_type); + } + + core_type = TREE_TYPE (core_type); + + tree elt_type = core_type; + + FOR_EACH_VEC_ELT_REVERSE (*array_type_domains, j, dom_p) + elt_type = build_array_type (elt_type, *dom_p); } + + gfc_ss_type ss_type = ss->info->type; + bool non_negative_stride = ss_type == GFC_SS_FUNCTION + || ss_type == GFC_SS_CONSTRUCTOR + || ss_type == GFC_SS_INTRINSIC + || non_negative_strides_array_p (info->descriptor); + return gfc_build_array_ref (elt_type, array, index, + non_negative_stride, info->lbound[array_dim], + info->spacing[array_dim]); } @@ -3939,18 +3853,28 @@ gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag, { gcc_assert (0 == ploop->order[0]); - /* For the outermost loop calculate the offset due to any - elemental dimensions. It will have been initialized with the - base offset of the array. */ + info->spacing0 = gfc_conv_array_spacing (info->descriptor, 0); + info->spacing0 = gfc_evaluate_now (info->spacing0, &loop->pre); + if (info->ref) { - for (int i = 0; i < ar->dimen; i++) + auto_vec<tree> domains; + + tree array = build_fold_indirect_ref_loc (input_location, info->data); + tree array_type = TREE_TYPE (array); + + for (int i = ar->dimen - 1; i >= 0; i--) { - if (ar->dimen_type[i] != DIMEN_ELEMENT) - continue; + if (ar->dimen_type[i] == DIMEN_ELEMENT) + array = add_array_index (pblock, ploop, ss, array, ar, + pss->dim[i], i, &domains); + else + domains.safe_push (TYPE_DOMAIN (array_type)); - add_array_offset (pblock, loop, ss, ar, i, /* unused */ -1); + array_type = TREE_TYPE (array_type); } + + info->data = gfc_build_addr_expr (NULL_TREE, array); } } else @@ -3966,13 +3890,18 @@ gfc_trans_preloop_setup (gfc_loopinfo * loop, int dim, int flag, gcc_assert (i == ploop->order[i]); i = ploop->order[i]; + tree array = build_fold_indirect_ref_loc (input_location, + info->data); /* Add the offset for the previous loop dimension. */ - add_array_offset (pblock, ploop, ss, ar, pss->dim[i], i); + array = add_array_index (pblock, ploop, ss, array, ar, pss->dim[i], i, + nullptr); + + info->data = gfc_build_addr_expr (NULL_TREE, array); } /* 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; } } @@ -4201,7 +4130,7 @@ gfc_trans_scalarized_loop_boundary (gfc_loopinfo * loop, stmtblock_t * body) && ss_type != GFC_SS_COMPONENT) 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. */ @@ -4233,7 +4162,7 @@ evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values, tree desc, int dim, bool lbound, bool deferred, bool save_value) { gfc_se se; - gfc_expr * input_val = values[dim]; + gfc_expr * input_val = values ? values[dim] : nullptr; tree *output = &bounds[dim]; if (input_val) @@ -4350,6 +4279,8 @@ gfc_conv_section_startstride (stmtblock_t * block, gfc_ss * ss, int dim) evaluate_bound (block, info->end, ar->end, desc, dim, false, ar->as->type == AS_DEFERRED, save_value); + evaluate_bound (block, info->lbound, nullptr, desc, dim, true, + ar->as->type == AS_DEFERRED, save_value); /* Calculate the stride. */ if (stride == NULL) @@ -4637,7 +4568,6 @@ done: gfc_add_block_to_block (&outer_loop->post, &se.post); info->descriptor = se.expr; - info->array_access = true; info->data = gfc_conv_array_data (info->descriptor); info->data = gfc_evaluate_now (info->data, &outer_loop->pre); @@ -6229,10 +6159,11 @@ gfc_trans_array_bounds (tree type, gfc_symbol * sym, tree * poffset, tree eltype = gfc_get_element_type (type); tree elem_len = fold_convert_loc (input_location, gfc_array_index_type, TYPE_SIZE_UNIT (eltype)); - - size = fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, - elem_len, GFC_TYPE_ARRAY_ALIGN (type)); + size = elem_len; offset = gfc_index_zero_node; + tree spacing = GFC_TYPE_ARRAY_SPACING (type, 0); + if (spacing && VAR_P (spacing)) + gfc_add_modify (pblock, spacing, elem_len); for (dim = 0; dim < as->rank; dim++) { /* Evaluate non-constant array bound expressions. @@ -6393,9 +6324,6 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, 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; @@ -6410,9 +6338,6 @@ gfc_trans_auto_array_allocation (tree decl, gfc_symbol * sym, } else { - 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); @@ -6610,8 +6535,6 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, partial = gfc_create_var (logical_type_node, "partial"); TREE_USED (partial) = 1; 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); @@ -6645,9 +6568,6 @@ gfc_trans_dummy_array_bias (gfc_symbol * sym, tree tmpdesc, 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) { @@ -6679,9 +6599,6 @@ 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++) @@ -10211,7 +10128,7 @@ update_reallocated_descriptor (stmtblock_t *block, gfc_loopinfo *loop) while (0) UPDATE_VALUE (info->offset, gfc_conv_descriptor_offset_get (desc)); - info->saved_offset = info->offset; + info->saved_data = info->data; for (int i = 0; i < s->dimen; i++) { int dim = s->dim[i]; diff --git a/gcc/fortran/trans-decl.cc b/gcc/fortran/trans-decl.cc index b34cb15e34ca..378e5c164505 100644 --- a/gcc/fortran/trans-decl.cc +++ b/gcc/fortran/trans-decl.cc @@ -1028,6 +1028,79 @@ create_index_var (const char * pfx, int nest) } +static tree +update_type_bounds (tree type, tree lbound[GFC_MAX_DIMENSIONS], + tree ubound[GFC_MAX_DIMENSIONS], + tree spacing[GFC_MAX_DIMENSIONS], tree root_type, int dim) +{ + tree elt_type; + if (dim == 0) + elt_type = TREE_TYPE (type); + else + elt_type = update_type_bounds (TREE_TYPE (type), lbound, ubound, spacing, + root_type, dim - 1); + + tree current_lbound = lbound[dim]; + tree current_ubound = ubound[dim]; + if (current_lbound != NULL_TREE + || current_ubound != NULL_TREE + || elt_type != TREE_TYPE (type)) + { + tree new_type = build_variant_type_copy (type); + TREE_TYPE (new_type) = elt_type; + TYPE_DOMAIN (new_type) = build_variant_type_copy (TYPE_DOMAIN (type)); + TYPE_MIN_VALUE (TYPE_DOMAIN (new_type)) = current_lbound; + TYPE_MAX_VALUE (TYPE_DOMAIN (new_type)) = current_ubound; + type = new_type; + } + + if (current_lbound != NULL_TREE) + { + GFC_TYPE_ARRAY_LBOUND (root_type, dim) = current_lbound; + if (current_lbound + && VAR_P (current_lbound) + && DECL_ARTIFICIAL (current_lbound) + && DECL_IGNORED_P (current_lbound)) + { + if (DECL_NAME (current_lbound) + && strstr (IDENTIFIER_POINTER (DECL_NAME (current_lbound)), + "lbound") != 0) + DECL_NAMELESS (current_lbound) = 1; + } + } + if (current_ubound != NULL_TREE) + { + GFC_TYPE_ARRAY_UBOUND (type, dim) = current_ubound; + if (current_ubound + && VAR_P (current_ubound) + && DECL_ARTIFICIAL (current_ubound) + && DECL_IGNORED_P (current_ubound)) + { + if (DECL_NAME (current_ubound) + && strstr (IDENTIFIER_POINTER (DECL_NAME (current_ubound)), + "ubound") != 0) + DECL_NAMELESS (current_ubound) = 1; + } + } + tree current_spacing = spacing[dim]; + if (current_spacing != NULL_TREE) + { + GFC_TYPE_ARRAY_SPACING (type, dim) = current_spacing; + if (current_spacing + && VAR_P (current_spacing) + && DECL_ARTIFICIAL (current_spacing) + && DECL_IGNORED_P (current_spacing)) + { + if (DECL_NAME (current_spacing) + && strstr (IDENTIFIER_POINTER (DECL_NAME (current_spacing)), + "spacing") != 0) + DECL_NAMELESS (current_spacing) = 1; + } + } + + return type; +} + /* Create variables to hold all the non-constant bits of info for a descriptorless array. Remember these in the lang-specific part of the type. */ @@ -1035,6 +1108,9 @@ create_index_var (const char * pfx, int nest) static void gfc_build_qualified_array (tree decl, gfc_symbol * sym) { + tree lbound[GFC_MAX_DIMENSIONS]; + tree ubound[GFC_MAX_DIMENSIONS]; + tree spacing[GFC_MAX_DIMENSIONS]; tree type; int dim; int nest; @@ -1116,24 +1192,48 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) { if (GFC_TYPE_ARRAY_LBOUND (type, dim) == NULL_TREE) { - GFC_TYPE_ARRAY_LBOUND (type, dim) = create_index_var ("lbound", nest); - suppress_warning (GFC_TYPE_ARRAY_LBOUND (type, dim)); + lbound[dim] = create_index_var ("lbound", nest); + suppress_warning (lbound[dim]); } + else + lbound[dim] = NULL_TREE; + /* Don't try to use the unknown bound for assumed shape arrays. */ if (GFC_TYPE_ARRAY_UBOUND (type, dim) == NULL_TREE && (as->type != AS_ASSUMED_SIZE || dim < GFC_TYPE_ARRAY_RANK (type) - 1)) { - GFC_TYPE_ARRAY_UBOUND (type, dim) = create_index_var ("ubound", nest); - suppress_warning (GFC_TYPE_ARRAY_UBOUND (type, dim)); + ubound[dim] = create_index_var ("ubound", nest); + suppress_warning (ubound[dim]); } + else + ubound[dim] = NULL_TREE; if (GFC_TYPE_ARRAY_SPACING (type, dim) == NULL_TREE) { - GFC_TYPE_ARRAY_SPACING (type, dim) = create_index_var ("spacing", nest); - suppress_warning (GFC_TYPE_ARRAY_SPACING (type, dim)); + spacing[dim] = create_index_var ("spacing", nest); + suppress_warning (spacing[dim]); } + else + spacing[dim] = NULL_TREE; + } + + if (POINTER_TYPE_P (type)) + { + gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (type)) + && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) + == TYPE_LANG_SPECIFIC (type)); + type = TREE_TYPE (type); } + + tree new_type = update_type_bounds (type, lbound, ubound, spacing, type, + as->rank - 1); + if (POINTER_TYPE_P (TREE_TYPE (decl))) + TREE_TYPE (TREE_TYPE (decl)) = new_type; + else + TREE_TYPE (decl) = new_type; + type = new_type; + for (dim = GFC_TYPE_ARRAY_RANK (type); dim < GFC_TYPE_ARRAY_RANK (type) + GFC_TYPE_ARRAY_CORANK (type); dim++) { @@ -1168,86 +1268,6 @@ gfc_build_qualified_array (tree decl, gfc_symbol * sym) GFC_TYPE_ARRAY_SIZE (type) = create_index_var ("size", nest); suppress_warning (GFC_TYPE_ARRAY_SIZE (type)); } - - if (POINTER_TYPE_P (type)) - { - gcc_assert (GFC_ARRAY_TYPE_P (TREE_TYPE (type))); - gcc_assert (TYPE_LANG_SPECIFIC (type) - == TYPE_LANG_SPECIFIC (TREE_TYPE (type))); - type = TREE_TYPE (type); - } - - if (! COMPLETE_TYPE_P (type) && GFC_TYPE_ARRAY_SIZE (type)) - { - tree size, range; - - size = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, - GFC_TYPE_ARRAY_SIZE (type), gfc_index_one_node); - range = build_range_type (gfc_array_index_type, gfc_index_zero_node, - size); - TYPE_DOMAIN (type) = range; - layout_type (type); - } - - if (TYPE_NAME (type) != NULL_TREE && as->rank > 0 - && GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1) != NULL_TREE - && VAR_P (GFC_TYPE_ARRAY_UBOUND (type, as->rank - 1))) - { - tree gtype = DECL_ORIGINAL_TYPE (TYPE_NAME (type)); - - for (dim = 0; dim < as->rank - 1; dim++) - { - gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE); - gtype = TREE_TYPE (gtype); - } - gcc_assert (TREE_CODE (gtype) == ARRAY_TYPE); - if (TYPE_MAX_VALUE (TYPE_DOMAIN (gtype)) == NULL) - TYPE_NAME (type) = NULL_TREE; - } - - if (TYPE_NAME (type) == NULL_TREE) - { - tree gtype = TREE_TYPE (type), rtype, type_decl; - - for (dim = as->rank - 1; dim >= 0; dim--) - { - tree lbound, ubound; - lbound = GFC_TYPE_ARRAY_LBOUND (type, dim); - ubound = GFC_TYPE_ARRAY_UBOUND (type, dim); - rtype = build_range_type (gfc_array_index_type, lbound, ubound); - gtype = build_array_type (gtype, rtype); - /* Ensure the bound variables aren't optimized out at -O0. - For -O1 and above they often will be optimized out, but - can be tracked by VTA. Also set DECL_NAMELESS, so that - the artificial lbound.N or ubound.N DECL_NAME doesn't - end up in debug info. */ - if (lbound - && VAR_P (lbound) - && DECL_ARTIFICIAL (lbound) - && DECL_IGNORED_P (lbound)) - { - if (DECL_NAME (lbound) - && strstr (IDENTIFIER_POINTER (DECL_NAME (lbound)), - "lbound") != 0) - DECL_NAMELESS (lbound) = 1; - DECL_IGNORED_P (lbound) = 0; - } - if (ubound - && VAR_P (ubound) - && DECL_ARTIFICIAL (ubound) - && DECL_IGNORED_P (ubound)) - { - if (DECL_NAME (ubound) - && strstr (IDENTIFIER_POINTER (DECL_NAME (ubound)), - "ubound") != 0) - DECL_NAMELESS (ubound) = 1; - DECL_IGNORED_P (ubound) = 0; - } - } - TYPE_NAME (type) = type_decl = build_decl (input_location, - TYPE_DECL, NULL, gtype); - DECL_ORIGINAL_TYPE (type_decl) = gtype; - } } @@ -7596,10 +7616,8 @@ done: /* cfi->dim[i].extent = gfc->dim[i].ubound - gfc->dim[i].lbound + 1. */ 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); */ + /* d->dim[n].sm = gfc->dim[i].spacing */ 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 b1516e640625..66a1019207ad 100644 --- a/gcc/fortran/trans-descriptor.cc +++ b/gcc/fortran/trans-descriptor.cc @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see #include "gimplify.h" #include "trans-descriptor.h" #include "trans-array.h" +#include "stor-layout.h" tree @@ -304,27 +305,6 @@ 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) { @@ -614,9 +594,7 @@ conv_spacing_get (tree desc, tree dim) || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_ALLOCATABLE || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_ASSUMED_RANK_POINTER_CONT || GFC_TYPE_ARRAY_AKIND (type) == GFC_ARRAY_POINTER_CONT)) - return fold_build2_loc (input_location, EXACT_DIV_EXPR, - gfc_array_index_type, conv_span_get (desc), - GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); + return conv_span_get (desc); return non_lvalue_loc (input_location, get_spacing (desc, dim)); } @@ -645,13 +623,9 @@ conv_stride_get (tree desc, tree dim) return gfc_index_one_node; 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, - fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, spacing, - align), - len); + spacing, len); } tree @@ -775,26 +749,6 @@ 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) { @@ -1003,6 +957,40 @@ gfc_conv_descriptor_stride_get (tree desc, tree dim) } +tree +gfc_build_desc_array_type (tree desc_type, tree etype, int dimen, tree * lbound, + tree * ubound) +{ + tree type = etype; + + for (int i = 0; i < dimen; i++) + { + tree lower = lbound[i]; + if (!INTEGER_CST_P (lower)) + { + tree root = build0 (PLACEHOLDER_EXPR, desc_type); + tree dim = build_int_cst (integer_type_node, i); + lower = gfc_descriptor::get_lbound (root, dim); + } + + tree upper = ubound[i]; + if (!INTEGER_CST_P (lower)) + { + tree root = build0 (PLACEHOLDER_EXPR, desc_type); + tree dim = build_int_cst (integer_type_node, i); + upper = gfc_descriptor::get_ubound (root, dim); + } + + tree idx_type = build_range_type (gfc_array_index_type, lower, upper); + + type = build_array_type (type, idx_type); + layout_type (type); + } + + return type; +} + + static bt get_type_info (const bt &type) { @@ -2438,9 +2426,6 @@ 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; @@ -2539,9 +2524,6 @@ 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)); } @@ -2556,8 +2538,6 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, 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)); @@ -2582,11 +2562,7 @@ gfc_set_descriptor_with_shape (stmtblock_t *block, tree desc, tree spacing = gfc_create_var (gfc_array_index_type, "spacing"); tree offset = gfc_create_var (gfc_array_index_type, "offset"); - 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, spacing, elem_len); gfc_add_modify (block, offset, gfc_index_zero_node); /* Loop body. */ @@ -2685,8 +2661,6 @@ gfc_copy_sequence_descriptor (stmtblock_t &block, tree lhs_desc, tree rhs_desc, 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_align_set (&block, arr, - gfc_conv_descriptor_align_get (rhs_desc)); gfc_conv_descriptor_offset_set (&block, arr, gfc_index_zero_node); desc = arr; } @@ -2703,8 +2677,6 @@ 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) { @@ -2843,9 +2815,6 @@ 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 @@ -2904,20 +2873,13 @@ gfc_set_gfc_from_cfi (stmtblock_t *unconditional_block, 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, - tmp2, tmp); + gfc_get_cfi_desc_elem_len (cfi), tmp); } else { - /* 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->dim[i].spacing = cfi->dim[i].sm */ + tmp = gfc_get_cfi_dim_sm (cfi, idx); } gfc_conv_descriptor_spacing_set (&loop_body, gfc, idx, tmp); @@ -2981,7 +2943,7 @@ 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 elem_align, tree data_ptr, + tree elemsize, tree data_ptr, tree lbound[GFC_MAX_DIMENSIONS], tree ubound[GFC_MAX_DIMENSIONS], tree spacing[GFC_MAX_DIMENSIONS], int rank, @@ -3026,8 +2988,6 @@ gfc_set_temporary_descriptor (stmtblock_t *block, tree desc, tree class_src, 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 @@ -3105,9 +3065,6 @@ 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_UNIT (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. @@ -3307,9 +3264,6 @@ 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 @@ -3357,9 +3311,6 @@ gfc_descr_init_count (tree descriptor, int rank, int corank, gfc_expr ** lower, tree empty_cond = logical_false_node; 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++) { @@ -3540,9 +3491,6 @@ 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_UNIT(gfc_get_element_type (TREE_TYPE (descriptor)))); - return gfc_evaluate_now (stride, pblock); } @@ -3581,17 +3529,12 @@ 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); 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_spacing_set (block, desc, gfc_index_zero_node, span); gfc_conv_descriptor_ubound_set (block, desc, gfc_index_zero_node, size); gfc_conv_descriptor_data_set (block, desc, data_ptr); } @@ -3785,9 +3728,7 @@ 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 = fold_build2_loc (input_location, EXACT_DIV_EXPR, - gfc_array_index_type, elemsize2, - GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); + tree size1 = elemsize2; tree offset = gfc_index_zero_node; for (int n = 0; n < expr2->rank; n++) @@ -3832,11 +3773,7 @@ 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_align_set (block, desc, - GFC_TYPE_ARRAY_ALIGN (TREE_TYPE (desc))); - } + gfc_conv_descriptor_span_set (block, desc, elemsize2); /* For deferred character length, the 'size' field of the dtype might have changed so set the dtype. */ @@ -3916,13 +3853,9 @@ 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++) { diff --git a/gcc/fortran/trans-descriptor.h b/gcc/fortran/trans-descriptor.h index 5f1d7f3f17b9..5cdf324cf8e3 100644 --- a/gcc/fortran/trans-descriptor.h +++ b/gcc/fortran/trans-descriptor.h @@ -41,14 +41,13 @@ 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); tree gfc_conv_descriptor_version_get (tree); tree gfc_conv_descriptor_attribute_get (tree); tree gfc_conv_descriptor_type_get (tree); -tree gfc_conv_descriptor_dimension_get (tree); +tree gfc_conv_descriptor_dimension_get (tree, tree); tree gfc_conv_descriptor_dimensions_get (tree); tree gfc_conv_descriptor_dimensions_get (tree, tree); tree gfc_conv_descriptor_stride_get (tree, tree); @@ -79,13 +78,14 @@ tree gfc_get_cfi_dim_extent (tree, tree); tree gfc_get_cfi_dim_sm (tree, tree); /* Shift lower bound of descriptor, updating ubound and offset. */ +tree gfc_build_desc_array_type (tree, tree, int, tree *, tree *); void gfc_conv_shift_descriptor (stmtblock_t*, tree, const gfc_array_ref &); void gfc_conv_shift_descriptor (stmtblock_t*, tree, int); 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, tree, +void gfc_set_temporary_descriptor (stmtblock_t *, 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 0da3bf971a27..37fdda7e0cdd 100644 --- a/gcc/fortran/trans-expr.cc +++ b/gcc/fortran/trans-expr.cc @@ -1628,10 +1628,11 @@ gfc_copy_class_to_class (tree from, tree to, tree nelems, bool unlimited) { tmp = gfc_conv_array_data (to); tmp = build_fold_indirect_ref_loc (input_location, tmp); + tree ptr_type = GFC_TYPE_ARRAY_DATAPTR_TYPE (TREE_TYPE (to_data)); + tree len = TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (ptr_type))); to_ref = gfc_build_addr_expr (NULL_TREE, - gfc_build_array_ref (tmp, index, false, - GFC_TYPE_ARRAY_SPACING (to, 0), - GFC_TYPE_ARRAY_ALIGN (to))); + gfc_build_array_ref (tmp, index, true, + NULL_TREE, len)); } vec_safe_push (args, to_ref); @@ -6200,8 +6201,6 @@ gfc_conv_gfc_desc_to_cfi_desc (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym) 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_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 ca61dcda5ff4..475fa096ea4b 100644 --- a/gcc/fortran/trans-intrinsic.cc +++ b/gcc/fortran/trans-intrinsic.cc @@ -2155,8 +2155,7 @@ trans_image_index (gfc_se * se, gfc_expr *expr) lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]); tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1], false, - GFC_TYPE_ARRAY_SPACING (subse.expr, 0), - GFC_TYPE_ARRAY_ALIGN (subse.expr)); + NULL_TREE, GFC_TYPE_ARRAY_SPACING (subse.expr, 0)); invalid_bound = fold_build2_loc (input_location, LT_EXPR, logical_type_node, fold_convert (gfc_array_index_type, tmp), lbound); @@ -2166,8 +2165,8 @@ trans_image_index (gfc_se * se, gfc_expr *expr) lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[codim]); ubound = gfc_conv_descriptor_ubound_get (desc, gfc_rank_cst[codim]); tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], false, - GFC_TYPE_ARRAY_SPACING (subse.expr, 0), - GFC_TYPE_ARRAY_ALIGN (subse.expr)); + NULL_TREE, + GFC_TYPE_ARRAY_SPACING (subse.expr, 0)); cond = fold_build2_loc (input_location, LT_EXPR, logical_type_node, fold_convert (gfc_array_index_type, tmp), lbound); @@ -2187,9 +2186,8 @@ trans_image_index (gfc_se * se, gfc_expr *expr) /* coindex = sub(corank) - lcobound(n). */ coindex = fold_convert (gfc_array_index_type, gfc_build_array_ref (subdesc, gfc_rank_cst[corank-1], - false, - GFC_TYPE_ARRAY_SPACING (subse.expr, 0), - GFC_TYPE_ARRAY_ALIGN (subse.expr))); + false, NULL_TREE, + GFC_TYPE_ARRAY_SPACING (subse.expr, 0))); lbound = gfc_conv_descriptor_lbound_get (desc, gfc_rank_cst[rank+corank-1]); coindex = fold_build2_loc (input_location, MINUS_EXPR, gfc_array_index_type, fold_convert (gfc_array_index_type, coindex), @@ -2208,8 +2206,8 @@ trans_image_index (gfc_se * se, gfc_expr *expr) /* coindex += sub(codim). */ tmp = gfc_build_array_ref (subdesc, gfc_rank_cst[codim-rank], false, - GFC_TYPE_ARRAY_SPACING (subse.expr, 0), - GFC_TYPE_ARRAY_ALIGN (subse.expr)); + NULL_TREE, + GFC_TYPE_ARRAY_SPACING (subse.expr, 0)); coindex = fold_build2_loc (input_location, PLUS_EXPR, gfc_array_index_type, coindex, fold_convert (gfc_array_index_type, tmp)); @@ -2356,10 +2354,8 @@ gfc_conv_is_contiguous_expr (gfc_se *se, gfc_expr *arg) desc = gfc_evaluate_now (argse.expr, &se->pre); 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, - tmp, gfc_conv_descriptor_span_get (desc)); + spacing, gfc_conv_descriptor_span_get (desc)); for (i = 0; i < arg->rank - 1; i++) { diff --git a/gcc/fortran/trans-io.cc b/gcc/fortran/trans-io.cc index 44e65d9e01d2..147aff5f7118 100644 --- a/gcc/fortran/trans-io.cc +++ b/gcc/fortran/trans-io.cc @@ -776,9 +776,6 @@ gfc_convert_array_to_string (gfc_se * se, gfc_expr * e) tree tmp = gfc_conv_array_extent (array, rank); full_size = fold_build2_loc (input_location, MULT_EXPR, 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); @@ -1655,9 +1652,8 @@ 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, false, - GFC_TYPE_ARRAY_SPACING (tmp, 0), - GFC_TYPE_ARRAY_ALIGN (tmp)); + tmp = gfc_build_array_ref (tmp, gfc_index_zero_node, false, + NULL_TREE, GFC_TYPE_ARRAY_SPACING (tmp, 0)); if (!POINTER_TYPE_P (TREE_TYPE (tmp))) tmp = build_fold_indirect_ref_loc (input_location, diff --git a/gcc/fortran/trans-openmp.cc b/gcc/fortran/trans-openmp.cc index 4e27816c1f5a..01d9263fb838 100644 --- a/gcc/fortran/trans-openmp.cc +++ b/gcc/fortran/trans-openmp.cc @@ -593,17 +593,15 @@ gfc_walk_alloc_comps (tree decl, tree dest, tree var, gfc_init_block (&tmpblock); tem = gfc_conv_array_data (decl); tree declvar = build_fold_indirect_ref_loc (input_location, tem); - tree declvref = gfc_build_array_ref (declvar, index, false, - GFC_TYPE_ARRAY_SPACING (declvar, 0), - GFC_TYPE_ARRAY_ALIGN (declvar)); + tree declvref = gfc_build_array_ref (declvar, index, false, NULL_TREE, + GFC_TYPE_ARRAY_SPACING (declvar, 0)); tree destvar, destvref = NULL_TREE; if (dest) { tem = gfc_conv_array_data (dest); destvar = build_fold_indirect_ref_loc (input_location, tem); - destvref = gfc_build_array_ref (destvar, index, false, - GFC_TYPE_ARRAY_SPACING (declvar, 0), - GFC_TYPE_ARRAY_ALIGN (declvar)); + destvref = gfc_build_array_ref (destvar, index, false, NULL_TREE, + GFC_TYPE_ARRAY_SPACING (declvar, 0)); } gfc_add_expr_to_block (&tmpblock, gfc_walk_alloc_comps (declvref, destvref, @@ -793,8 +791,6 @@ gfc_omp_clause_default_ctor (tree clause, tree decl, tree outer) } 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); @@ -1097,9 +1093,6 @@ gfc_omp_clause_assign_op (tree clause, tree dest, tree src) if (GFC_TYPE_ARRAY_RANK (type) >= 1) { 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 { @@ -1236,12 +1229,10 @@ gfc_omp_linear_clause_add_loop (stmtblock_t *block, tree dest, tree src, gfc_init_block (&tmpblock); if (TREE_CODE (TREE_TYPE (dest)) == ARRAY_TYPE) { - desta = gfc_build_array_ref (dest, index, false, - GFC_TYPE_ARRAY_SPACING (dest, 0), - GFC_TYPE_ARRAY_ALIGN (dest)); - srca = gfc_build_array_ref (src, index, false, - GFC_TYPE_ARRAY_SPACING (src, 0), - GFC_TYPE_ARRAY_ALIGN (src)); + desta = gfc_build_array_ref (dest, index, false, NULL_TREE, + GFC_TYPE_ARRAY_SPACING (dest, 0)); + srca = gfc_build_array_ref (src, index, false, NULL_TREE, + GFC_TYPE_ARRAY_SPACING (src, 0)); } else { diff --git a/gcc/fortran/trans-types.cc b/gcc/fortran/trans-types.cc index f30be9293fe0..69021347d9fa 100644 --- a/gcc/fortran/trans-types.cc +++ b/gcc/fortran/trans-types.cc @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "dwarf2out.h" /* For struct array_descr_info. */ #include "attribs.h" #include "alias.h" +#include "trans-descriptor.h" #if (GFC_MAX_DIMENSIONS < 10) @@ -1840,6 +1841,23 @@ gfc_get_dtype (tree type, int * rank) } +static tree +build_nested_array_types (tree etype, tree lbound[GFC_MAX_DIMENSIONS], + tree ubound[GFC_MAX_DIMENSIONS], int rank) +{ + tree type = etype; + + for (int i = 0; i < rank; i++) + { + tree idx_type = build_range_type (gfc_array_index_type, lbound[i], ubound[i]); + type = build_array_type (type, idx_type); + layout_type (type); + } + + return build_variant_type_copy (type); +} + + /* Build an array type for use without a descriptor, packed according to the value of PACKED. */ @@ -1847,54 +1865,41 @@ tree gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, bool restricted) { - tree range; + tree lbound[GFC_MAX_DIMENSIONS]; + tree ubound[GFC_MAX_DIMENSIONS]; + tree spacing[GFC_MAX_DIMENSIONS]; tree type; tree tmp; int n; - int known_offset; mpz_t offset; mpz_t stride; - mpz_t spacing; + mpz_t spc; mpz_t delta; gfc_expr *expr; mpz_init_set_ui (offset, 0); mpz_init_set_ui (stride, 1); - mpz_init (spacing); - wide_int align = wi::uhwi (TYPE_ALIGN_UNIT (etype), - TYPE_PRECISION (gfc_array_index_type)); + mpz_init (spc); bool known_spacing = INTEGER_CST_P (TYPE_SIZE_UNIT (etype)); if (known_spacing) { wide_int elem_len = wi::to_wide (TYPE_SIZE_UNIT (etype)); - wide_int len_align = wi::udiv_trunc (elem_len, align); - gcc_assert (wi::fits_uhwi_p (len_align)); - mpz_set_ui (spacing, len_align.to_uhwi ()); + gcc_assert (wi::fits_uhwi_p (elem_len)); + mpz_set_ui (spc, elem_len.to_uhwi ()); } mpz_init (delta); - /* We don't use build_array_type because this does not include - lang-specific information (i.e. the bounds of the array) when checking - for duplicates. */ - if (as->rank) - type = make_node (ARRAY_TYPE); - else - type = build_variant_type_copy (etype); - - GFC_ARRAY_TYPE_P (type) = 1; - TYPE_LANG_SPECIFIC (type) = ggc_cleared_alloc<struct lang_type> (); - bool known_stride = (packed != PACKED_NO); - known_offset = 1; + bool known_offset = true; for (n = 0; n < as->rank; n++) { /* Fill in the spacing and bound components of the type. */ if (known_spacing) - tmp = gfc_conv_mpz_to_tree (spacing, gfc_index_integer_kind); + tmp = gfc_conv_mpz_to_tree (spc, gfc_index_integer_kind); else tmp = NULL_TREE; - GFC_TYPE_ARRAY_SPACING (type, n) = tmp; + spacing[n] = tmp; expr = as->lower[n]; if (expr && expr->expr_type == EXPR_CONSTANT) @@ -1908,16 +1913,16 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, known_spacing = false; tmp = NULL_TREE; } - GFC_TYPE_ARRAY_LBOUND (type, n) = tmp; + lbound[n] = tmp; if (known_spacing) { /* Calculate the offset. */ - mpz_mul (delta, spacing, as->lower[n]->value.integer); + mpz_mul (delta, spc, as->lower[n]->value.integer); mpz_sub (offset, offset, delta); } else - known_offset = 0; + known_offset = false; expr = as->upper[n]; if (expr && expr->expr_type == EXPR_CONSTANT) @@ -1931,7 +1936,7 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, known_stride = false; known_spacing = false; } - GFC_TYPE_ARRAY_UBOUND (type, n) = tmp; + ubound[n] = tmp; if (known_spacing || known_stride) { @@ -1942,16 +1947,28 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, if (known_stride) mpz_mul (stride, stride, delta); if (known_spacing) - mpz_mul (spacing, spacing, delta); + mpz_mul (spc, spc, delta); } /* Only the first stride is known for partial packed arrays. */ if (packed == PACKED_NO || packed == PACKED_PARTIAL) { - known_stride = 0; - known_spacing = 0; + known_stride = false; + known_spacing = false; } } + + type = build_nested_array_types (etype, lbound, ubound, as->rank); + + GFC_ARRAY_TYPE_P (type) = 1; + TYPE_LANG_SPECIFIC (type) = ggc_cleared_alloc<struct lang_type> (); + + for (n = 0; n < as->rank; n++) + { + GFC_TYPE_ARRAY_SPACING (type, n) = spacing[n]; + GFC_TYPE_ARRAY_LBOUND (type, n) = lbound[n]; + GFC_TYPE_ARRAY_UBOUND (type, n) = ubound[n]; + } for (n = as->rank; n < as->rank + as->corank; n++) { expr = as->lower[n]; @@ -1991,74 +2008,18 @@ 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, align); GFC_TYPE_ARRAY_RANK (type) = as->rank; GFC_TYPE_ARRAY_CORANK (type) = as->corank; GFC_TYPE_ARRAY_DTYPE (type) = NULL_TREE; - range = build_range_type (gfc_array_index_type, gfc_index_zero_node, - NULL_TREE); - /* TODO: use main type if it is unbounded. */ - GFC_TYPE_ARRAY_DATAPTR_TYPE (type) = - build_pointer_type (build_array_type (etype, range)); + GFC_TYPE_ARRAY_DATAPTR_TYPE (type) = build_pointer_type (type); if (restricted) GFC_TYPE_ARRAY_DATAPTR_TYPE (type) = build_qualified_type (GFC_TYPE_ARRAY_DATAPTR_TYPE (type), TYPE_QUAL_RESTRICT); - if (as->rank == 0) - { - if (packed != PACKED_STATIC || flag_coarray == GFC_FCOARRAY_LIB) - { - type = build_pointer_type (type); - - if (restricted) - type = build_qualified_type (type, TYPE_QUAL_RESTRICT); - - GFC_ARRAY_TYPE_P (type) = 1; - TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type)); - } - - goto array_type_done; - } - - if (known_stride) - { - mpz_sub_ui (stride, stride, 1); - range = gfc_conv_mpz_to_tree (stride, gfc_index_integer_kind); - } - else - range = NULL_TREE; - - range = build_range_type (gfc_array_index_type, gfc_index_zero_node, range); - TYPE_DOMAIN (type) = range; - - build_pointer_type (etype); - TREE_TYPE (type) = etype; - - layout_type (type); - - /* Represent packed arrays as multi-dimensional if they have rank > - 1 and with proper bounds, instead of flat arrays. This makes for - better debug info. */ - if (known_offset) - { - tree gtype = etype, rtype, type_decl; - - for (n = as->rank - 1; n >= 0; n--) - { - rtype = build_range_type (gfc_array_index_type, - GFC_TYPE_ARRAY_LBOUND (type, n), - GFC_TYPE_ARRAY_UBOUND (type, n)); - gtype = build_array_type (gtype, rtype); - } - TYPE_NAME (type) = type_decl = build_decl (input_location, - TYPE_DECL, NULL, gtype); - DECL_ORIGINAL_TYPE (type_decl) = gtype; - } - - if (packed != PACKED_STATIC || !known_stride - || (as->corank && flag_coarray == GFC_FCOARRAY_LIB)) + if (packed != PACKED_STATIC + || (!known_stride && as->rank != 0) + || ((as->corank || as->rank == 0) && flag_coarray == GFC_FCOARRAY_LIB)) { /* For dummy arrays and automatic (heap allocated) arrays we want a pointer to the array. */ @@ -2069,10 +2030,9 @@ gfc_get_nodesc_array_type (tree etype, gfc_array_spec * as, gfc_packed packed, TYPE_LANG_SPECIFIC (type) = TYPE_LANG_SPECIFIC (TREE_TYPE (type)); } -array_type_done: mpz_clear (offset); mpz_clear (stride); - mpz_clear (spacing); + mpz_clear (spc); mpz_clear (delta); return type; @@ -2136,12 +2096,6 @@ 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) { @@ -2185,7 +2139,7 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, enum gfc_array_kind akind, bool restricted) { char name[8 + 2*GFC_RANK_DIGITS + 1 + GFC_MAX_SYMBOL_LEN]; - tree fat_type, base_type, arraytype, lower, upper, stride, tmp, rtype; + tree fat_type, base_type, arraytype, lower, upper, stride, tmp; const char *type_name; int n; @@ -2228,11 +2182,6 @@ 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, - align); GFC_TYPE_ARRAY_RANK (fat_type) = dimen; GFC_TYPE_ARRAY_CORANK (fat_type) = codimen; GFC_TYPE_ARRAY_DTYPE (fat_type) = NULL_TREE; @@ -2244,11 +2193,6 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, { stride = gfc_index_one_node; spacing = TYPE_SIZE_UNIT (etype); - if (spacing != NULL_TREE) - 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 { @@ -2324,15 +2268,7 @@ gfc_get_array_type_bounds (tree etype, int dimen, int codimen, tree * lbound, return fat_type; } - /* We define data as an array with the correct size if possible. - Much better than doing pointer arithmetic. */ - if (stride) - rtype = build_range_type (gfc_array_index_type, gfc_index_zero_node, - int_const_binop (MINUS_EXPR, stride, - build_int_cst (TREE_TYPE (stride), 1))); - else - rtype = gfc_array_range_type; - arraytype = build_array_type (etype, rtype); + arraytype = gfc_build_desc_array_type (fat_type, etype, dimen, lbound, ubound); arraytype = build_pointer_type (arraytype); if (restricted) arraytype = build_qualified_type (arraytype, TYPE_QUAL_RESTRICT); @@ -4014,8 +3950,6 @@ gfc_get_array_descr_info (const_tree type, struct array_descr_info *info) size_binop (PLUS_EXPR, 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 7120824b8195..152e19f536ac 100644 --- a/gcc/fortran/trans.cc +++ b/gcc/fortran/trans.cc @@ -412,59 +412,49 @@ 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, bool non_negative_offset, - tree spacing, tree align) +gfc_build_array_ref (tree type, tree base, tree index, bool non_negative_offset, + tree offset, tree spacing) { - tree type = TREE_TYPE (base); - - if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0) - { - gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); - - return fold_convert (TYPE_MAIN_VARIANT (type), base); - } - - /* Scalar coarray, there is nothing to do. */ - if (TREE_CODE (type) != ARRAY_TYPE) - { - gcc_assert (integer_zerop (offset)); - return base; - } - - type = TREE_TYPE (type); - if (DECL_P (base)) TREE_ADDRESSABLE (base) = 1; /* Strip NON_LVALUE_EXPR nodes. */ - STRIP_TYPE_NOPS (offset); + STRIP_TYPE_NOPS (index); if (non_negative_offset) - return build4_loc (input_location, ARRAY_REF, type, base, offset, - NULL_TREE, spacing); + { + tree align = build_int_cst (gfc_array_index_type, + TYPE_ALIGN_UNIT (type)); + tree elt_unit_cnt = fold_build2_loc (input_location, EXACT_DIV_EXPR, + gfc_array_index_type, spacing, + align); + tree min_val = fold_build1_loc (input_location, NEGATE_EXPR, + gfc_array_index_type, offset); + return build4_loc (input_location, ARRAY_REF, type, base, index, + min_val, elt_unit_cnt); + } /* Otherwise use pointer arithmetic. */ else { gcc_assert (TREE_CODE (TREE_TYPE (base)) == ARRAY_TYPE); tree min = NULL_TREE; - if (TYPE_DOMAIN (TREE_TYPE (base)) - && !integer_zerop (TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base))))) + if (offset != NULL_TREE) + min = fold_build1_loc (input_location, NEGATE_EXPR, + gfc_array_index_type, offset); + else if (TYPE_DOMAIN (TREE_TYPE (base))) min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (base))); tree zero_based_index - = min ? fold_build2_loc (input_location, MINUS_EXPR, - gfc_array_index_type, - fold_convert (gfc_array_index_type, offset), - fold_convert (gfc_array_index_type, min)) - : fold_convert (gfc_array_index_type, offset); - - tree offset_align = fold_build2_loc (input_location, MULT_EXPR, - gfc_array_index_type, - zero_based_index, spacing); + = min && !integer_zerop (min) + ? fold_build2_loc (input_location, MINUS_EXPR, + gfc_array_index_type, + fold_convert (gfc_array_index_type, index), + fold_convert (gfc_array_index_type, min)) + : fold_convert (gfc_array_index_type, index); tree offset_bytes = fold_build2_loc (input_location, MULT_EXPR, gfc_array_index_type, - offset_align, align); + zero_based_index, spacing); tree base_addr = gfc_build_addr_expr (pvoid_type_node, base); @@ -476,6 +466,31 @@ gfc_build_array_ref (tree base, tree offset, bool non_negative_offset, } +tree +gfc_build_array_ref (tree base, tree index, bool non_negative_offset, + tree offset, tree spacing) +{ + tree type = TREE_TYPE (base); + + if (GFC_ARRAY_TYPE_P (type) && GFC_TYPE_ARRAY_RANK (type) == 0) + { + gcc_assert (GFC_TYPE_ARRAY_CORANK (type) > 0); + + return fold_convert (TYPE_MAIN_VARIANT (type), base); + } + + /* Scalar coarray, there is nothing to do. */ + if (TREE_CODE (type) != ARRAY_TYPE) + { + gcc_assert (integer_zerop (index)); + return base; + } + + return gfc_build_array_ref (TREE_TYPE (type), index, non_negative_offset, + offset, spacing); +} + + /* Generate a call to print a runtime error possibly including multiple arguments and a locus. */ diff --git a/gcc/fortran/trans.h b/gcc/fortran/trans.h index e254f9f1dc60..72f9b82098e3 100644 --- a/gcc/fortran/trans.h +++ b/gcc/fortran/trans.h @@ -194,33 +194,31 @@ typedef struct gfc_array_info gfc_ref *ref; /* The descriptor of this array. */ tree descriptor; - /* holds the pointer to the data array. */ + /* holds the pointer to the array. */ tree data; + /* value of the pointer to the array before the beginning of the loops. */ + 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; + + tree spacing0; + /* Holds the SS for a subscript. Indexed by actual dimension. */ struct gfc_ss *subscript[GFC_MAX_DIMENSIONS]; /* stride, spacing and delta are used to access this inside a scalarization loop. start is used in the calculation of these. Indexed by scalarizer dimension. */ + tree lbound[GFC_MAX_DIMENSIONS]; tree start[GFC_MAX_DIMENSIONS]; tree end[GFC_MAX_DIMENSIONS]; /* The spacing of indexes, that may be specified by the strides of array 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. In alignment-sized - units. */ + dimension. This is the intrinsic spacing of the array. */ tree spacing[GFC_MAX_DIMENSIONS]; tree delta[GFC_MAX_DIMENSIONS]; - - /* False: access with pointer arithmetics. - True: access with array reference. */ - bool array_access; } gfc_array_info; @@ -648,7 +646,9 @@ tree gfc_build_addr_expr (tree, tree); /* Build an ARRAY_REF. */ tree gfc_build_array_ref (tree, tree, bool non_negative_offset = false, - tree spacing = NULL_TREE, tree align = NULL_TREE); + tree offset = NULL_TREE, tree spacing = NULL_TREE); +tree gfc_build_array_ref (tree, tree, tree, bool non_negative_offset = false, + tree offset = NULL_TREE, tree spacing = NULL_TREE); /* Build an array ref using pointer arithmetic. */ tree gfc_build_spanned_array_ref (tree base, tree offset, tree span); @@ -1122,12 +1122,11 @@ struct GTY(()) lang_decl { #define GFC_TYPE_ARRAY_STRIDE(node, dim) \ (fold_build2_loc (input_location, EXACT_DIV_EXPR, gfc_array_index_type, \ GFC_TYPE_ARRAY_SPACING((node), (dim)), \ - GFC_TYPE_ARRAY_ALIGN((node)))) + GFC_TYPE_ARRAY_ELEM_LEN((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) diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index b2398a43a94d..2f05a4decadc 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -382,7 +382,6 @@ _gfortran_caf_failed_images (gfc_descriptor_t *array, array->dim[0]._ubound = -1; array->dim[0].spacing = 1; array->offset = 0; - array->align = local_kind; } @@ -405,7 +404,6 @@ _gfortran_caf_stopped_images (gfc_descriptor_t *array, array->dim[0]._ubound = -1; array->dim[0].spacing = 1; array->offset = 0; - array->align = local_kind; } diff --git a/libgfortran/generated/reshape_c10.c b/libgfortran/generated/reshape_c10.c index 0d928d3c3e36..4cdf2cfa3630 100644 --- a/libgfortran/generated/reshape_c10.c +++ b/libgfortran/generated/reshape_c10.c @@ -53,6 +53,7 @@ reshape_c10 (gfc_array_c10 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_COMPLEX_10 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_c10 (gfc_array_c10 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_c16.c b/libgfortran/generated/reshape_c16.c index db51e15add91..acd265d0a837 100644 --- a/libgfortran/generated/reshape_c16.c +++ b/libgfortran/generated/reshape_c16.c @@ -53,6 +53,7 @@ reshape_c16 (gfc_array_c16 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_COMPLEX_16 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_c16 (gfc_array_c16 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_c17.c b/libgfortran/generated/reshape_c17.c index 06693c825df9..f1543d355fa4 100644 --- a/libgfortran/generated/reshape_c17.c +++ b/libgfortran/generated/reshape_c17.c @@ -53,6 +53,7 @@ reshape_c17 (gfc_array_c17 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_COMPLEX_17 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_c17 (gfc_array_c17 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_c4.c b/libgfortran/generated/reshape_c4.c index fd66f80d172b..83a066f03fe6 100644 --- a/libgfortran/generated/reshape_c4.c +++ b/libgfortran/generated/reshape_c4.c @@ -53,6 +53,7 @@ reshape_c4 (gfc_array_c4 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_COMPLEX_4 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_c4 (gfc_array_c4 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_c8.c b/libgfortran/generated/reshape_c8.c index d1d2047459ea..f4f297160008 100644 --- a/libgfortran/generated/reshape_c8.c +++ b/libgfortran/generated/reshape_c8.c @@ -53,6 +53,7 @@ reshape_c8 (gfc_array_c8 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_COMPLEX_8 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_c8 (gfc_array_c8 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_i16.c b/libgfortran/generated/reshape_i16.c index cb12bc90698d..201f98e4cf91 100644 --- a/libgfortran/generated/reshape_i16.c +++ b/libgfortran/generated/reshape_i16.c @@ -53,6 +53,7 @@ reshape_16 (gfc_array_i16 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_INTEGER_16 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_16 (gfc_array_i16 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_i4.c b/libgfortran/generated/reshape_i4.c index 66cae896125d..33f2f750e40c 100644 --- a/libgfortran/generated/reshape_i4.c +++ b/libgfortran/generated/reshape_i4.c @@ -53,6 +53,7 @@ reshape_4 (gfc_array_i4 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_INTEGER_4 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_4 (gfc_array_i4 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_i8.c b/libgfortran/generated/reshape_i8.c index e3a928eea086..94448afc5046 100644 --- a/libgfortran/generated/reshape_i8.c +++ b/libgfortran/generated/reshape_i8.c @@ -53,6 +53,7 @@ reshape_8 (gfc_array_i8 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_INTEGER_8 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_8 (gfc_array_i8 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_r10.c b/libgfortran/generated/reshape_r10.c index fa640d8f7b6d..e3f70782dc4e 100644 --- a/libgfortran/generated/reshape_r10.c +++ b/libgfortran/generated/reshape_r10.c @@ -53,6 +53,7 @@ reshape_r10 (gfc_array_r10 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_REAL_10 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_r10 (gfc_array_r10 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_r16.c b/libgfortran/generated/reshape_r16.c index 266feb71f051..5d88a74cfbed 100644 --- a/libgfortran/generated/reshape_r16.c +++ b/libgfortran/generated/reshape_r16.c @@ -53,6 +53,7 @@ reshape_r16 (gfc_array_r16 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_REAL_16 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_r16 (gfc_array_r16 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_r17.c b/libgfortran/generated/reshape_r17.c index ac8017f29af9..3c6ef2f9634a 100644 --- a/libgfortran/generated/reshape_r17.c +++ b/libgfortran/generated/reshape_r17.c @@ -53,6 +53,7 @@ reshape_r17 (gfc_array_r17 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_REAL_17 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_r17 (gfc_array_r17 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_r4.c b/libgfortran/generated/reshape_r4.c index ade896a2c226..beefcc300887 100644 --- a/libgfortran/generated/reshape_r4.c +++ b/libgfortran/generated/reshape_r4.c @@ -53,6 +53,7 @@ reshape_r4 (gfc_array_r4 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_REAL_4 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_r4 (gfc_array_r4 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/generated/reshape_r8.c b/libgfortran/generated/reshape_r8.c index 7301276a7e2b..0c09de675166 100644 --- a/libgfortran/generated/reshape_r8.c +++ b/libgfortran/generated/reshape_r8.c @@ -53,6 +53,7 @@ reshape_r8 (gfc_array_r8 * const restrict ret, index_type rdim; index_type rsize; index_type rs; + index_type spacing; index_type rex; GFC_REAL_8 *rptr; /* s.* indicates the source array. */ @@ -100,13 +101,15 @@ reshape_r8 (gfc_array_r8 * const restrict ret, index_type alloc_size; rs = 1; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; - GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, rs); + GFC_DIMENSION_SET(ret->dim[n], 0, rex - 1, spacing); rs *= rex; + spacing *= rex; } ret->offset = 0; diff --git a/libgfortran/intrinsics/cshift0.c b/libgfortran/intrinsics/cshift0.c index 9d146390fbfa..044a9642a705 100644 --- a/libgfortran/intrinsics/cshift0.c +++ b/libgfortran/intrinsics/cshift0.c @@ -62,7 +62,6 @@ cshift0 (gfc_array_char * ret, const gfc_array_char * array, ret->offset = 0; GFC_DTYPE_COPY(ret,array); - ret->align = array->align; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { diff --git a/libgfortran/intrinsics/eoshift0.c b/libgfortran/intrinsics/eoshift0.c index 7f11af25a1c8..161d04fae8d1 100644 --- a/libgfortran/intrinsics/eoshift0.c +++ b/libgfortran/intrinsics/eoshift0.c @@ -67,7 +67,6 @@ eoshift0 (gfc_array_char * ret, const gfc_array_char * array, ret->offset = 0; GFC_DTYPE_COPY(ret,array); - ret->align = array->align; for (i = 0; i < GFC_DESCRIPTOR_RANK (array); i++) { diff --git a/libgfortran/intrinsics/eoshift2.c b/libgfortran/intrinsics/eoshift2.c index 4a9e763d07b6..ce27134f0687 100644 --- a/libgfortran/intrinsics/eoshift2.c +++ b/libgfortran/intrinsics/eoshift2.c @@ -73,7 +73,6 @@ eoshift2 (gfc_array_char *ret, const gfc_array_char *array, ret->offset = 0; GFC_DTYPE_COPY(ret,array); - ret->align = array->align; /* xmallocarray allocates a single byte for zero size. */ ret->base_addr = xmallocarray (arraysize, size); @@ -85,7 +84,7 @@ eoshift2 (gfc_array_char *ret, const gfc_array_char *array, ub = GFC_DESCRIPTOR_EXTENT(array,i) - 1; if (i == 0) - sp = GFC_DESCRIPTOR_SIZE(ret) / ret->align; + sp = GFC_DESCRIPTOR_SIZE(ret); else sp = GFC_DESCRIPTOR_EXTENT(ret,i-1) * GFC_DESCRIPTOR_SPACING(ret,i-1); diff --git a/libgfortran/intrinsics/move_alloc.c b/libgfortran/intrinsics/move_alloc.c index ad9062a15656..c515b9bae8c3 100644 --- a/libgfortran/intrinsics/move_alloc.c +++ b/libgfortran/intrinsics/move_alloc.c @@ -46,7 +46,6 @@ move_alloc (gfc_array_char * from, gfc_array_char * to) } to->offset = from->offset; - to->align = from->align; GFC_DTYPE_COPY(to,from); to->base_addr = from->base_addr; from->base_addr = NULL; diff --git a/libgfortran/intrinsics/pack_generic.c b/libgfortran/intrinsics/pack_generic.c index 3d6e5623342d..3de2a9f453b2 100644 --- a/libgfortran/intrinsics/pack_generic.c +++ b/libgfortran/intrinsics/pack_generic.c @@ -162,7 +162,6 @@ pack_internal (gfc_array_char *ret, const gfc_array_char *array, GFC_DIMENSION_SET(ret->dim[0], 0, total-1, 1); ret->offset = 0; - ret->align = array->align; /* xmallocarray allocates a single byte for zero size. */ ret->base_addr = xmallocarray (total, size); @@ -539,7 +538,6 @@ pack_s_internal (gfc_array_char *ret, const gfc_array_char *array, GFC_DIMENSION_SET(ret->dim[0],0,total-1,1); ret->offset = 0; - ret->align = array->align; ret->base_addr = xmallocarray (total, size); diff --git a/libgfortran/intrinsics/spread_generic.c b/libgfortran/intrinsics/spread_generic.c index fb4fd7093516..c537e5947bf8 100644 --- a/libgfortran/intrinsics/spread_generic.c +++ b/libgfortran/intrinsics/spread_generic.c @@ -78,7 +78,7 @@ spread_internal (gfc_array_char *ret, const gfc_array_char *source, dim = 0; rs = 1; - spacing = size / source->align; + spacing = size; for (n = 0; n < rrank; n++) { stride = rs; @@ -105,7 +105,6 @@ spread_internal (gfc_array_char *ret, const gfc_array_char *source, GFC_DIMENSION_SET(ret->dim[n], 0, ub, spacing); } ret->offset = 0; - ret->align = source->align; ret->base_addr = xmallocarray (rs, size); if (rs <= 0) @@ -253,9 +252,7 @@ spread_internal_scalar (gfc_array_char *ret, const char *source, { ret->base_addr = xmallocarray (ncopies, size); ret->offset = 0; - ret->align = source->align; - GFC_DIMENSION_SET(ret->dim[0], 0, ncopies - 1, - size / source->align); + GFC_DIMENSION_SET(ret->dim[0], 0, ncopies - 1, size); } else { diff --git a/libgfortran/intrinsics/unpack_generic.c b/libgfortran/intrinsics/unpack_generic.c index 81692cab09e2..ab747acf4c27 100644 --- a/libgfortran/intrinsics/unpack_generic.c +++ b/libgfortran/intrinsics/unpack_generic.c @@ -112,7 +112,7 @@ unpack_internal (gfc_array_char *ret, const gfc_array_char *vector, return array descriptor. */ dim = GFC_DESCRIPTOR_RANK (mask); rs = 1; - spacing = size / vector->align; + spacing = size; for (n = 0; n < dim; n++) { count[n] = 0; diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h index daa11b9ebc74..4ef6edb36189 100644 --- a/libgfortran/libgfortran.h +++ b/libgfortran/libgfortran.h @@ -389,7 +389,6 @@ struct {\ size_t offset;\ dtype_type dtype;\ index_type span;\ - index_type align; \ descriptor_dimension dim[];\ } @@ -464,21 +463,19 @@ typedef GFC_FULL_ARRAY_DESCRIPTOR (GFC_MAX_DIMENSIONS, GFC_INTEGER_4) gfc_full_a #define GFC_DESCRIPTOR_DATA(desc) ((desc)->base_addr) #define GFC_DESCRIPTOR_DTYPE(desc) ((desc)->dtype) #define GFC_DESCRIPTOR_SPAN(desc) ((desc)->span) -#define GFC_DESCRIPTOR_ALIGN(desc) ((desc)->align) -#define GFC_DIMENSION_SET(dim,lb,ub,sp) \ +#define GFC_DESCRIPTOR_DIMENSION_SET(desc,i,lb,ub,sp) \ do \ { \ - (dim).lower_bound = lb; \ - (dim)._ubound = ub; \ - (dim).spacing = sp; \ + (desc)->dim[i].lower_bound = lb; \ + (desc)->dim[i]._ubound = ub; \ + (desc)->dim[i].spacing = sp; \ } while (0) #define GFC_DESCRIPTOR_LBOUND(desc,i) ((desc)->dim[i].lower_bound) #define GFC_DESCRIPTOR_UBOUND(desc,i) ((desc)->dim[i]._ubound) #define GFC_DESCRIPTOR_SPACING(desc,i) ((desc)->dim[i].spacing) -#define GFC_DESCRIPTOR_SM(desc,i) (GFC_DESCRIPTOR_SPACING(desc,i) * GFC_DESCRIPTOR_ALIGN(desc)) #define GFC_DESCRIPTOR_EXTENT(desc,i) (GFC_DESCRIPTOR_UBOUND(desc,i) + (GFC_DESCRIPTOR_LBOUND(desc,i) - 1)) #define GFC_DESCRIPTOR_STRIDE(desc,i) (GFC_DESCRIPTOR_SM(desc,i) / GFC_DESCRIPTOR_SIZE(desc)) diff --git a/libgfortran/m4/reshape.m4 b/libgfortran/m4/reshape.m4 index dec5ed254483..ea81148ab9dd 100644 --- a/libgfortran/m4/reshape.m4 +++ b/libgfortran/m4/reshape.m4 @@ -105,7 +105,7 @@ reshape_'rtype_ccode` ('rtype` * const restrict ret, index_type alloc_size; rs = 1; - spacing = GFC_DESCRIPTOR_SIZE(source) / source->align; + spacing = GFC_DESCRIPTOR_SIZE(source); for (index_type n = 0; n < rdim; n++) { rex = shape_data[n]; @@ -116,7 +116,6 @@ reshape_'rtype_ccode` ('rtype` * const restrict ret, spacing *= rex; } ret->offset = 0; - ret->align = source->align; if (unlikely (rs < 1)) alloc_size = 0;