[gcc(refs/users/mikael/heads/refactor_descriptor_v01)] Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class
Mikael Morin
mikael@gcc.gnu.org
Thu Jan 9 20:43:07 GMT 2025
https://gcc.gnu.org/g:4dda0ed3b6e09c1fd68f195ec0d19a4cec4ed0e3
commit 4dda0ed3b6e09c1fd68f195ec0d19a4cec4ed0e3
Author: Mikael Morin <mikael@gcc.gnu.org>
Date: Wed Dec 11 16:03:10 2024 +0100
Utilisation gfc_clear_descriptor dans gfc_conv_derived_to_class
essai suppression
Suppression fonction inutilisée
Sauvegarde compilation OK
Correction régression
Sauvegarde correction null_actual_6
Commentage fonction inutilisée
Correction bornes descripteur null
Diff:
---
gcc/fortran/trans-array.cc | 339 +++++++++++++++++++++++++++++++++++++++------
gcc/fortran/trans-array.h | 4 +-
gcc/fortran/trans-expr.cc | 87 ++++++++++--
3 files changed, 373 insertions(+), 57 deletions(-)
diff --git a/gcc/fortran/trans-array.cc b/gcc/fortran/trans-array.cc
index d15576adde10..0370d10d9ebd 100644
--- a/gcc/fortran/trans-array.cc
+++ b/gcc/fortran/trans-array.cc
@@ -592,10 +592,10 @@ get_size_info (gfc_typespec &ts)
if (POINTER_TYPE_P (type))
type = TREE_TYPE (type);
gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
- tree elt_type = TREE_TYPE (type);
+ tree char_type = TREE_TYPE (type);
tree len = ts.u.cl->backend_decl;
return fold_build2_loc (input_location, MULT_EXPR, size_type_node,
- size_in_bytes (elt_type),
+ size_in_bytes (char_type),
fold_convert (size_type_node, len));
}
@@ -613,8 +613,61 @@ get_size_info (gfc_typespec &ts)
}
+class init_info
+{
+public:
+ virtual bool initialize_data () const { return false; }
+ virtual tree get_data_value () const { return NULL_TREE; }
+ virtual gfc_typespec *get_type () const { return nullptr; }
+};
+
+
+class default_init : public init_info
+{
+private:
+ const symbol_attribute &attr;
+
+public:
+ default_init (const symbol_attribute &arg_attr) : attr(arg_attr) { }
+ virtual bool initialize_data () const { return !attr.pointer; }
+ virtual tree get_data_value () const {
+ if (!initialize_data ())
+ return NULL_TREE;
+
+ return null_pointer_node;
+ }
+};
+
+class nullification : public init_info
+{
+private:
+ gfc_typespec &ts;
+
+public:
+ nullification(gfc_typespec &arg_ts) : ts(arg_ts) { }
+ virtual bool initialize_data () const { return true; }
+ virtual tree get_data_value () const { return null_pointer_node; }
+ virtual gfc_typespec *get_type () const { return &ts; }
+};
+
+class scalar_value : public init_info
+{
+private:
+ gfc_typespec &ts;
+ tree value;
+
+public:
+ scalar_value(gfc_typespec &arg_ts, tree arg_value)
+ : ts(arg_ts), value(arg_value) { }
+ virtual bool initialize_data () const { return true; }
+ virtual tree get_data_value () const { return value; }
+ virtual gfc_typespec *get_type () const { return &ts; }
+};
+
+
static tree
-build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
+build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &,
+ const init_info &init)
{
vec<constructor_elt, va_gc> *v = nullptr;
@@ -622,11 +675,17 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
tree fields = TYPE_FIELDS (type);
- if (ts.type != BT_CLASS)
+ gfc_typespec *type_info = init.get_type ();
+ if (type_info == nullptr)
+ type_info = &ts;
+
+ if (!(type_info->type == BT_CLASS
+ || (type_info->type == BT_CHARACTER
+ && type_info->deferred)))
{
tree elem_len_field = gfc_advance_chain (fields, GFC_DTYPE_ELEM_LEN);
tree elem_len_val = fold_convert (TREE_TYPE (elem_len_field),
- get_size_info (ts));
+ get_size_info (*type_info));
CONSTRUCTOR_APPEND_ELT (v, elem_len_field, elem_len_val);
}
@@ -641,11 +700,11 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
CONSTRUCTOR_APPEND_ELT (v, rank_field, rank_val);
}
- if (ts.type != BT_CLASS)
+ if (type_info->type != BT_CLASS)
{
tree type_info_field = gfc_advance_chain (fields, GFC_DTYPE_TYPE);
tree type_info_val = build_int_cst (TREE_TYPE (type_info_field),
- get_type_info (ts));
+ get_type_info (*type_info));
CONSTRUCTOR_APPEND_ELT (v, type_info_field, type_info_val);
}
@@ -656,8 +715,8 @@ build_dtype (gfc_typespec &ts, int rank, const symbol_attribute &)
/* Build a null array descriptor constructor. */
vec<constructor_elt, va_gc> *
-get_default_descriptor_init (tree type, gfc_typespec &ts, int rank,
- const symbol_attribute &attr)
+get_descriptor_init (tree type, gfc_typespec &ts, int rank,
+ const symbol_attribute &attr, const init_info &init)
{
vec<constructor_elt, va_gc> *v = nullptr;
@@ -666,15 +725,15 @@ get_default_descriptor_init (tree type, gfc_typespec &ts, int rank,
tree fields = TYPE_FIELDS (type);
/* Don't init pointers by default. */
- if (!attr.pointer)
+ if (init.initialize_data ())
{
tree data_field = gfc_advance_chain (fields, DATA_FIELD);
- tree data_value = fold_convert (TREE_TYPE (data_field), null_pointer_node);
+ tree data_value = init.get_data_value ();
CONSTRUCTOR_APPEND_ELT (v, data_field, data_value);
}
tree dtype_field = gfc_advance_chain (fields, DTYPE_FIELD);
- tree dtype_value = build_dtype (ts, rank, attr);
+ tree dtype_value = build_dtype (ts, rank, attr, init);
CONSTRUCTOR_APPEND_ELT (v, dtype_field, dtype_value);
if (flag_coarray == GFC_FCOARRAY_LIB && attr.codimension)
@@ -694,43 +753,53 @@ get_default_descriptor_init (tree type, gfc_typespec &ts, int rank,
vec<constructor_elt, va_gc> *
-get_null_descriptor_init (tree type, gfc_typespec &ts, int rank,
- const symbol_attribute &attr)
+get_default_array_descriptor_init (tree type, gfc_typespec &ts, int rank,
+ const symbol_attribute &attr)
{
- symbol_attribute attr2 = attr;
- attr2.pointer = 0;
+ gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
+ gcc_assert (DATA_FIELD == 0);
+
+ return get_descriptor_init (type, ts, rank, attr, default_init (attr));
+}
+
- return get_default_descriptor_init (type, ts, rank, attr2);
+vec<constructor_elt, va_gc> *
+get_null_array_descriptor_init (tree type, gfc_typespec &ts, int rank,
+ const symbol_attribute &attr)
+{
+ return get_descriptor_init (type, ts, rank, attr, nullification (ts));
}
tree
-gfc_build_default_descriptor (tree type, gfc_typespec &ts, int rank,
- const symbol_attribute &attr)
+gfc_build_default_array_descriptor (tree type, gfc_typespec &ts, int rank,
+ const symbol_attribute &attr)
{
gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
return build_constructor (type,
- get_default_descriptor_init (type, ts, rank, attr));
+ get_descriptor_init (type, ts, rank, attr,
+ default_init (attr)));
}
tree
-gfc_build_null_descriptor (tree type, gfc_typespec &ts, int rank,
- const symbol_attribute &attr)
+gfc_build_null_array_descriptor (tree type, gfc_typespec &ts, int rank,
+ const symbol_attribute &attr)
{
gcc_assert (GFC_DESCRIPTOR_TYPE_P (type));
return build_constructor (type,
- get_null_descriptor_init (type, ts, rank, attr));
+ get_null_array_descriptor_init (type, ts, rank,
+ attr));
}
tree
-gfc_build_null_descriptor (tree type, gfc_typespec &ts,
- const symbol_attribute &attr)
+gfc_build_null_array_descriptor (tree type, gfc_typespec &ts,
+ const symbol_attribute &attr)
{
- return gfc_build_null_descriptor (type, ts, -1, attr);
+ return gfc_build_null_array_descriptor (type, ts, -1, attr);
}
@@ -754,10 +823,10 @@ gfc_build_default_class_descriptor (tree type, gfc_typespec &ts)
&& flag_coarray != GFC_FCOARRAY_LIB))
{
gcc_assert (GFC_DESCRIPTOR_TYPE_P (data_type));
- data_value = gfc_build_null_descriptor (data_type,
- ts,
- ts.u.derived->components->as->rank,
- ts.u.derived->components->attr);
+ gfc_component *data_comp = ts.u.derived->components;
+ data_value = gfc_build_null_array_descriptor (data_type, ts,
+ data_comp->as->rank,
+ data_comp->attr);
}
else
{
@@ -797,12 +866,161 @@ gfc_clear_descriptor (gfc_expr *var_ref, gfc_se &var)
attr = gfc_expr_attr (var_ref);
gfc_add_modify (&var.pre, var.expr,
- gfc_build_null_descriptor (TREE_TYPE (var.expr), var_ref->ts,
- rank, attr));
+ gfc_build_null_array_descriptor (TREE_TYPE (var.expr),
+ var_ref->ts,
+ rank, attr));
}
-void
+static int
+field_count (tree type)
+{
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+
+ int count = 0;
+ tree field = TYPE_FIELDS (type);
+ while (field != NULL_TREE)
+ {
+ count++;
+ field = DECL_CHAIN (field);
+ }
+
+ return count;
+}
+
+
+bool
+complete_init_p (tree type, vec<constructor_elt, va_gc> *init_values)
+{
+ return (unsigned) field_count (type) == vec_safe_length (init_values);
+}
+
+
+static bool
+modifiable_p (tree data_ref)
+{
+ switch (TREE_CODE (data_ref))
+ {
+ case CONST_DECL:
+ return false;
+
+ case VAR_DECL:
+ case PARM_DECL:
+ case RESULT_DECL:
+ return !TREE_CONSTANT (data_ref) && !TREE_READONLY (data_ref);
+
+ case COMPONENT_REF:
+ {
+ tree field_decl = TREE_OPERAND (data_ref, 1);
+
+ if (TREE_CONSTANT (field_decl) || TREE_READONLY (field_decl))
+ return false;
+ }
+
+ /* fallthrough */
+ case ARRAY_REF:
+ case ARRAY_RANGE_REF:
+ case REALPART_EXPR:
+ case IMAGPART_EXPR:
+ case VIEW_CONVERT_EXPR:
+ case NOP_EXPR:
+ {
+ tree parent_ref = TREE_OPERAND (data_ref, 0);
+ return modifiable_p (parent_ref);
+ }
+
+ default:
+ gcc_unreachable ();
+ }
+}
+
+
+typedef enum
+{
+ SINGLE,
+ MULTIPLE
+} init_kind;
+
+typedef union
+{
+ tree single;
+ vec<constructor_elt, va_gc> *multiple;
+} init_values;
+
+static void
+init_struct (stmtblock_t *block, tree data_ref, tree value);
+
+static void
+init_struct (stmtblock_t *block, tree data_ref, init_kind kind,
+ init_values values)
+{
+ tree type = TREE_TYPE (data_ref);
+
+ if (kind == SINGLE)
+ {
+ tree value = values.single;
+ if (TREE_STATIC (data_ref)
+ || !modifiable_p (data_ref))
+ DECL_INITIAL (data_ref) = value;
+ else if (TREE_CODE (value) == CONSTRUCTOR)
+ {
+ unsigned i;
+ tree field, field_init;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (value), i, field, field_init)
+ {
+ tree ref = fold_build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (field), data_ref,
+ field, NULL_TREE);
+ init_struct (block, ref, field_init);
+ }
+ }
+ else
+ gfc_add_modify (block, data_ref, value);
+ }
+ else if (TREE_STATIC (data_ref))
+ return init_struct (block, data_ref,
+ build_constructor (type, values.multiple));
+ else
+ {
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+
+ unsigned i;
+ constructor_elt *ce;
+ FOR_EACH_VEC_ELT (*values.multiple, i, ce)
+ {
+ tree field_decl = ce->index;
+ tree ref = fold_build3_loc (input_location, COMPONENT_REF,
+ TREE_TYPE (field_decl), data_ref,
+ field_decl, NULL_TREE);
+ init_struct (block, ref, ce->value);
+ }
+ }
+}
+
+
+static void
+init_struct (stmtblock_t *block, tree data_ref, tree value)
+{
+ init_values wrapped_values;
+ wrapped_values.single = value;
+
+ return init_struct (block, data_ref, SINGLE, wrapped_values);
+}
+
+
+static void
+init_struct (stmtblock_t *block, tree data_ref,
+ vec<constructor_elt, va_gc> *values)
+{
+ init_values wrapped_values;
+ wrapped_values.multiple = values;
+
+ return init_struct (block, data_ref, MULTIPLE, wrapped_values);
+}
+
+
+#if 0
+static void
set_from_constructor_elts (stmtblock_t *block, tree data_ref,
vec<constructor_elt, va_gc> *constructor_values)
{
@@ -817,6 +1035,7 @@ set_from_constructor_elts (stmtblock_t *block, tree data_ref,
gfc_add_modify (block, ref, ce->value);
}
}
+#endif
void
@@ -831,14 +1050,46 @@ gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym, tree descriptor)
attr = gfc_symbol_attr (sym);
- if (TREE_STATIC (descriptor))
- gfc_add_modify (block, descriptor,
- gfc_build_null_descriptor (TREE_TYPE (descriptor), sym->ts,
- rank, attr));
- else
- set_from_constructor_elts (block, descriptor,
- get_null_descriptor_init (TREE_TYPE (descriptor),
- sym->ts, rank, attr));
+ init_struct (block, descriptor,
+ get_null_array_descriptor_init (TREE_TYPE (descriptor),
+ sym->ts, rank, attr));
+}
+
+
+void
+gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym,
+ gfc_expr *expr, tree descriptor)
+{
+ symbol_attribute attr;
+
+ gfc_array_spec *as = sym->ts.type == BT_CLASS
+ ? CLASS_DATA (sym)->as
+ : sym->as;
+ int rank = as == nullptr
+ ? 0
+ : as->type == AS_ASSUMED_RANK
+ ? expr->rank
+ : as->rank;
+
+ attr = gfc_symbol_attr (sym);
+
+ init_struct (block, descriptor,
+ get_null_array_descriptor_init (TREE_TYPE (descriptor),
+ expr->ts, rank, attr));
+}
+
+
+void
+gfc_set_scalar_descriptor (stmtblock_t *block, tree descriptor,
+ gfc_symbol *sym, gfc_expr *expr, tree value)
+{
+ symbol_attribute attr;
+
+ attr = gfc_symbol_attr (sym);
+
+ init_struct (block, descriptor,
+ get_descriptor_init (TREE_TYPE (descriptor), sym->ts, 0,
+ attr, scalar_value (expr->ts, value)));
}
@@ -1356,12 +1607,8 @@ gfc_get_array_span (tree desc, gfc_expr *expr)
void
gfc_trans_static_array_pointer (gfc_symbol * sym)
{
- tree type;
-
gcc_assert (TREE_STATIC (sym->backend_decl));
- /* Just zero the data member. */
- type = TREE_TYPE (sym->backend_decl);
- DECL_INITIAL (sym->backend_decl) = gfc_build_null_descriptor (type);
+ gfc_clear_descriptor (nullptr, sym, sym->backend_decl);
}
diff --git a/gcc/fortran/trans-array.h b/gcc/fortran/trans-array.h
index 63a77d562a7b..78646275b4ec 100644
--- a/gcc/fortran/trans-array.h
+++ b/gcc/fortran/trans-array.h
@@ -141,7 +141,9 @@ void gfc_conv_resolve_dependencies (gfc_loopinfo *, gfc_ss *, gfc_ss *);
/* Build a null array descriptor constructor. */
tree gfc_build_null_descriptor (tree);
tree gfc_build_default_class_descriptor (tree, gfc_typespec &);
-void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *sym, tree descriptor);
+void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, tree);
+void gfc_clear_descriptor (stmtblock_t *block, gfc_symbol *, gfc_expr *, tree);
+void gfc_set_scalar_descriptor (stmtblock_t *block, tree, gfc_symbol *, gfc_expr *, tree);
/* Get a single array element. */
void gfc_conv_array_ref (gfc_se *, gfc_array_ref *, gfc_expr *, locus *);
diff --git a/gcc/fortran/trans-expr.cc b/gcc/fortran/trans-expr.cc
index bef49d32a589..6978f83cdc8c 100644
--- a/gcc/fortran/trans-expr.cc
+++ b/gcc/fortran/trans-expr.cc
@@ -104,6 +104,74 @@ get_scalar_to_descriptor_type (tree scalar, symbol_attribute attr)
akind, !(attr.pointer || attr.target));
}
+
+tree
+gfc_conv_scalar_null_to_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr *expr, tree scalar)
+{
+ symbol_attribute attr = sym->attr;
+
+ tree type = get_scalar_to_descriptor_type (scalar, attr);
+ tree desc = gfc_create_var (type, "desc");
+ DECL_ARTIFICIAL (desc) = 1;
+
+ if (CONSTANT_CLASS_P (scalar))
+ {
+ tree tmp;
+ tmp = gfc_create_var (TREE_TYPE (scalar), "scalar");
+ gfc_add_modify (&se->pre, tmp, scalar);
+ scalar = tmp;
+ }
+ if (!POINTER_TYPE_P (TREE_TYPE (scalar)))
+ scalar = gfc_build_addr_expr (NULL_TREE, scalar);
+
+ gfc_set_scalar_descriptor (&se->pre, desc, sym, expr, scalar);
+
+ /* Copy pointer address back - but only if it could have changed and
+ if the actual argument is a pointer and not, e.g., NULL(). */
+ if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
+ gfc_add_modify (&se->post, scalar,
+ fold_convert (TREE_TYPE (scalar),
+ gfc_conv_descriptor_data_get (desc)));
+ return desc;
+}
+
+
+tree
+gfc_conv_null_array_descriptor (gfc_se *se, gfc_symbol *sym, gfc_expr *expr)
+{
+#if 0
+ symbol_attribute attr = sym->attr;
+#endif
+ tree lower[GFC_MAX_DIMENSIONS], upper[GFC_MAX_DIMENSIONS];
+
+ for (int i = 0; i < expr->rank; i++)
+ {
+ lower[i] = NULL_TREE;
+ upper[i] = NULL_TREE;
+ }
+
+ tree elt_type = gfc_typenode_for_spec (&sym->ts);
+ tree desc_type = gfc_get_array_type_bounds (elt_type, expr->rank, 0,
+ lower, upper, 0,
+ GFC_ARRAY_UNKNOWN, false);
+ tree desc = gfc_create_var (desc_type, "desc");
+ DECL_ARTIFICIAL (desc) = 1;
+
+ gfc_clear_descriptor (&se->pre, sym, expr, desc);
+
+#if 0
+ /* Copy pointer address back - but only if it could have changed and
+ if the actual argument is a pointer and not, e.g., NULL(). */
+ if ((attr.pointer || attr.allocatable) && attr.intent != INTENT_IN)
+ gfc_add_modify (&se->post, scalar,
+ fold_convert (TREE_TYPE (scalar),
+ gfc_conv_descriptor_data_get (desc)));
+#endif
+
+ return desc;
+}
+
+
tree
gfc_conv_scalar_to_descriptor (gfc_se *se, tree scalar, symbol_attribute attr)
{
@@ -969,10 +1037,9 @@ gfc_conv_derived_to_class (gfc_se *parmse, gfc_expr *e, gfc_symbol *fsym,
tmp = gfc_finish_block (&block);
gfc_init_block (&block);
- gfc_conv_descriptor_data_set (&block, ctree, null_pointer_node);
+ gfc_clear_descriptor (&block, fsym, ctree);
if (derived_array && *derived_array != NULL_TREE)
- gfc_conv_descriptor_data_set (&block, *derived_array,
- null_pointer_node);
+ gfc_clear_descriptor (&block, fsym, *derived_array);
tmp = build3_v (COND_EXPR, cond_optional, tmp,
gfc_finish_block (&block));
@@ -5761,6 +5828,7 @@ expr_may_alias_variables (gfc_expr *e, bool array_may_alias)
/* A helper function to set the dtype for unallocated or unassociated
entities. */
+#if 0
static void
set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
@@ -5803,7 +5871,7 @@ set_dtype_for_unallocated (gfc_se *parmse, gfc_expr *e)
build_empty_stmt (input_location));
gfc_add_expr_to_block (&parmse->pre, cond);
}
-
+#endif
/* Provide an interface between gfortran array descriptors and the F2018:18.4
@@ -6435,12 +6503,11 @@ conv_null_actual (gfc_se * parmse, gfc_expr * e, gfc_symbol * fsym)
correct rank. */
if (fsym->as && fsym->as->type == AS_ASSUMED_RANK)
{
- tree rank;
tree tmp = parmse->expr;
- tmp = gfc_conv_scalar_to_descriptor (parmse, tmp, fsym->attr);
- rank = gfc_conv_descriptor_rank (tmp);
- gfc_add_modify (&parmse->pre, rank,
- build_int_cst (TREE_TYPE (rank), e->rank));
+ if (e->rank == 0)
+ tmp = gfc_conv_scalar_null_to_descriptor (parmse, fsym, e, tmp);
+ else
+ tmp = gfc_conv_null_array_descriptor (parmse, fsym, e);
parmse->expr = gfc_build_addr_expr (NULL_TREE, tmp);
}
else
@@ -7623,7 +7690,7 @@ gfc_conv_procedure_call (gfc_se * se, gfc_symbol * sym,
/* Unallocated allocatable arrays and unassociated pointer
arrays need their dtype setting if they are argument
associated with assumed rank dummies to set the rank. */
- set_dtype_for_unallocated (&parmse, e);
+ //set_dtype_for_unallocated (&parmse, e);
}
else if (e->expr_type == EXPR_VARIABLE
&& e->symtree->n.sym->attr.dummy
More information about the Gcc-cvs
mailing list