[gcc(refs/users/mikael/heads/refactor_descriptor_v08)] Extraction build_array_ref
Mikael Morin
mikael@gcc.gnu.org
Mon Sep 22 09:41:59 GMT 2025
https://gcc.gnu.org/g:e715877472ae527cdea32235d1484955f3a73ef8
commit e715877472ae527cdea32235d1484955f3a73ef8
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Mon Sep 22 11:12:09 2025 +0200
Extraction build_array_ref
Diff:
---
gcc/fortran/trans-array.cc | 223 ++++++++++++++++++++++++++++-----------------
1 file changed, 141 insertions(+), 82 deletions(-)
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index 486d944d5132..71e5fa59bf39 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -3452,21 +3452,6 @@ array_bound_check_elemental (gfc_se * se, gfc_ss * ss, gfc_expr * expr)
}
-static tree
-build_array_ref (gfc_array_ref_info * array_ref)
-{
- switch (array_ref->access)
- {
- case gfc_array_ref_info::ARRAY_INDEX:
- break;
- case gfc_array_ref_info::POINTER_OFFSET:
- break;
- }
-
- return NULL_TREE;
-}
-
-
/* Add T to the offset pair *OFFSET, *CST_OFFSET. */
void
@@ -3654,16 +3639,12 @@ conv_array_index_offset (gfc_se * se, gfc_ss * ss, int dim, int i,
}
-/* Build a scalarized array reference using the vptr 'size'. */
-
static bool
-build_class_array_ref (gfc_se *se, tree base, tree index)
+is_class_array_ref (tree base, gfc_expr *expr, tree *class_descr)
{
- tree size;
tree decl = NULL_TREE;
tree tmp;
- gfc_expr *expr = se->ss->info->expr;
- gfc_expr *class_expr;
+ gfc_expr *class_expr = nullptr;
gfc_typespec *ts;
gfc_symbol *sym;
@@ -3687,7 +3668,7 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
class_expr = gfc_find_and_cut_at_last_class_ref (expr, false, &ts);
if (!ts)
- return false;
+ goto give_up;
sym = (!class_expr && expr) ? expr->symtree->n.sym : NULL;
if (sym && sym->attr.function
@@ -3716,6 +3697,31 @@ build_class_array_ref (gfc_se *se, tree base, tree index)
return false;
}
+ if (class_descr)
+ *class_descr = decl;
+ if (class_expr != nullptr)
+ gfc_free_expr (class_expr);
+ return true;
+
+give_up:
+ if (class_expr != nullptr)
+ gfc_free_expr (class_expr);
+ return false;
+}
+
+
+/* Build a scalarized array reference using the vptr 'size'. */
+
+static bool
+build_class_array_ref (gfc_se *se, tree base, tree index)
+{
+ tree size;
+ tree decl = NULL_TREE;
+ gfc_expr *expr = se->ss->info->expr;
+
+ if (!is_class_array_ref (base, expr, &decl))
+ return false;
+
se->class_vptr = gfc_evaluate_now (gfc_class_vptr_get (decl), &se->pre);
size = gfc_class_vtab_size_get (decl);
@@ -3771,6 +3777,106 @@ non_negative_strides_array_p (tree expr)
}
+enum gfc_array_ref_sort
+{
+ /* A regular array reference. */
+ ARS_REGULAR_ARRAY_REF,
+ /* Pointer arithmetics, with the element size picked from the class
+ descriptor's _size field. */
+ ARS_CLASS_PTR_ARITH,
+ /* Pointer arithmetics, with the element size picked from the array
+ descriptor's span field. */
+ ARS_SPANNED_PTR_ARITH,
+ /* Pointer arithmetics, using the CFI descriptor's sm fields. */
+ ARS_CFI_PTR_ARITH
+};
+
+
+static gfc_array_ref_sort
+classify_array_ref (tree array, tree ref_base, gfc_expr *expr,
+ gfc_array_ref *ar, bool tmp_array)
+{
+ if (is_class_array_ref (ref_base, expr, nullptr))
+ return ARS_CLASS_PTR_ARITH;
+
+ if (get_CFI_desc (NULL, expr, nullptr, ar))
+ return ARS_CFI_PTR_ARITH;
+
+ if (is_pointer_array (array)
+ || (expr && expr->ts.deferred && array
+ && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))))
+ return ARS_SPANNED_PTR_ARITH;
+
+ if (tmp_array || non_negative_strides_array_p (array))
+ return ARS_SPANNED_PTR_ARITH;
+
+ return ARS_REGULAR_ARRAY_REF;
+}
+
+
+static void
+build_array_ref (gfc_se *se, tree array, tree ref_base, gfc_expr *expr,
+ gfc_array_ref *ar, bool is_temp_array, tree index)
+{
+ switch (classify_array_ref (array, ref_base, expr, ar, is_temp_array))
+ {
+
+ case ARS_CLASS_PTR_ARITH:
+ {
+ bool success = build_class_array_ref (se, ref_base, index);
+ gcc_assert (success);
+ }
+ break;
+
+ case ARS_CFI_PTR_ARITH:
+ {
+ tree cfi_decl = NULL_TREE;
+ if (get_CFI_desc (NULL, expr, &cfi_decl, ar))
+ cfi_decl = build_fold_indirect_ref_loc (input_location, cfi_decl);
+ bool non_negative_stride = is_temp_array
+ || non_negative_strides_array_p (array);
+ se->expr = gfc_build_array_ref (ref_base, index, non_negative_stride,
+ cfi_decl);
+ }
+ break;
+
+ case ARS_SPANNED_PTR_ARITH:
+ {
+ tree decl = NULL_TREE;
+ if (is_pointer_array (array)
+ || (expr && expr->ts.deferred && array
+ && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (array))))
+ {
+ if (TREE_CODE (array) == COMPONENT_REF)
+ decl = array;
+ else if (INDIRECT_REF_P (array))
+ decl = TREE_OPERAND (array, 0);
+
+ if (decl == NULL_TREE)
+ decl = array;
+ }
+
+ bool non_negative_stride = is_temp_array
+ || non_negative_strides_array_p (array);
+ se->expr = gfc_build_array_ref (ref_base, index, non_negative_stride,
+ decl);
+ }
+ break;
+
+ case ARS_REGULAR_ARRAY_REF:
+ {
+ bool non_negative_stride = is_temp_array
+ || non_negative_strides_array_p (array);
+ se->expr = gfc_build_array_ref (ref_base, index, non_negative_stride);
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+
/* Build a scalarized reference to an array. */
static void
@@ -3778,7 +3884,6 @@ 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;
@@ -3797,32 +3902,7 @@ gfc_conv_scalarized_array_ref (gfc_se * se, gfc_array_ref * ar,
base = build_fold_indirect_ref_loc (input_location, info->current_elem.base);
- /* 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, non_negative_stride, decl);
+ build_array_ref (se, info->descriptor, base, expr, ar, tmp_array, index);
}
@@ -3837,39 +3917,13 @@ gfc_conv_tmp_array_ref (gfc_se * se)
}
-static tree
-build_array_ref (tree desc, tree offset, tree decl, tree vptr)
+static void
+build_array_ref (gfc_se *se, tree array, gfc_expr *expr, gfc_array_ref *ar,
+ tree index)
{
- 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);
+ tree tmp = gfc_conv_array_data (array);
tmp = build_fold_indirect_ref_loc (input_location, tmp);
- tmp = gfc_build_array_ref (tmp, offset, non_negative_strides_array_p (desc),
- decl, vptr);
- return tmp;
+ build_array_ref (se, array, tmp, expr, ar, false, index);
}
@@ -4064,7 +4118,7 @@ gfc_conv_array_ref (gfc_se * se, gfc_array_ref * ar, gfc_expr *expr,
}
free (var_name);
- se->expr = build_array_ref (se->expr, index, decl, se->class_vptr);
+ build_array_ref (se, se->expr, expr, ar, index);
}
@@ -7146,7 +7200,12 @@ gfc_get_dataptr_offset (stmtblock_t *block, tree parm, tree desc, tree offset,
return;
}
- tmp = build_array_ref (desc, offset, NULL, NULL);
+ gfc_se se;
+ gfc_init_se (&se, nullptr);
+ build_array_ref (&se, desc, expr, gfc_find_array_ref (expr, false), offset);
+ gfc_add_block_to_block (block, &se.pre);
+ tmp = gfc_evaluate_now (se.expr, block);
+ gfc_add_block_to_block (block, &se.post);
/* Offset the data pointer for pointer assignments from arrays with
subreferences; e.g. my_integer => my_type(:)%integer_component. */
More information about the Gcc-cvs
mailing list