From: Andrew Benson <abenson@carnegiescience.edu>
To: Janus Weil <janus@gcc.gnu.org>
Cc: Richard Biener <richard.guenther@gmail.com>,
"fortran@gcc.gnu.org" <fortran@gcc.gnu.org>
Subject: Re: Optimization of add_dt_to_dt_list() in resolve.c
Date: Thu, 31 May 2018 18:04:00 -0000 [thread overview]
Message-ID: <6422270.9Mc4pgMANL@andrew-precision-3520> (raw)
In-Reply-To: <CAKwh3qgxiO4oyPFc103zoQx7OOFOPyRPp8AMAd_FGpWLDJDuYA@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 4140 bytes --]
On Thursday, May 31, 2018 10:56:47 AM PDT Janus Weil wrote:
> 2018-05-31 0:22 GMT+02:00 Andrew Benson <abenson@carnegiescience.edu>:
> >> - for (dt = gfc_derived_types; dt; dt = dt->next)
> >> - gfc_copy_dt_decls_ifequal (derived, dt->derived, false);
> >> -
> >> + if (gfc_derived_types) {
> >> + dt = gfc_derived_types;
> >> + for (;;)
> >> + {
> >> + gfc_copy_dt_decls_ifequal (derived, dt, false);
> >> + if (dt->dt_next == gfc_derived_types)
> >> + break;
> >> + dt = dt->dt_next;
> >> + }
> >> + }
> >>
> >> Is there a particular reason why you changed the loop to "for (;;)" ?
> >> I find the old style a bit clearer and more compact. Also I think it's
> >> more common in gfortran.
> >
> > I changed the original for loop since it wasn't possible (as far as I
> > could
> > see) to have an exit condition that worked now that list is circularly
> > linked (i.e. "dt" never becomes NULL, and testing for dt->dt_next ==
> > gfc_derived_types doesn't work as it would miss the final entry in the
> > list). So, I used for(;;) and added the exit condition explicitly into
> > the loop.
> >
> > But, I agree, it's not very clear. An alternative would be something such
> > as:
> >
> > - for (dt = gfc_derived_types; dt; dt = dt->next)
> > - gfc_copy_dt_decls_ifequal (derived, dt->derived, false);
> > -
> > + for (dt = gfc_derived_types; dt; dt = dt->dt_next)
> > + {
> > + gfc_copy_dt_decls_ifequal (derived, dt, false);
> > + if (dt->dt_next == gfc_derived_types)
> > + break;
> > + }
> > +
> >
> > which is more compact, and has the advantage that if doesn't require an
> > "if
> > (gfc_derived_types)". Do you think that's a better approach?
>
> Yes, definitely looks better to me. Note that there is another such
> case further up in gfc_get_derived_type. Actually I'd also move the
> declaration of dt ("gfc_symbol *dt") into the loops, in order to make
> it more local (it's not used outside).
Thanks - an updated patch is attached with those changes.
While staring at the patch again there's something about the following in
trans-types.c that seems possibly wrong:
@@ -2599,16 +2598,20 @@ gfc_get_derived_type (gfc_symbol * derived, int co
ns->translated && !got_canonical;
ns = ns->sibling)
{
- dt = ns->derived_types;
- for (; dt && !canonical; dt = dt->next)
+ if (ns->derived_types)
{
- gfc_copy_dt_decls_ifequal (dt->derived, derived, true);
- if (derived->backend_decl)
- got_canonical = true;
+ for (gfc_symbol *dt = ns->derived_types; dt; dt = dt->dt_next)
+ {
+ gfc_copy_dt_decls_ifequal (dt, derived, true);
+ if (derived->backend_decl)
+ got_canonical = true;
+ if (dt->dt_next == ns->derived_types)
+ break;
+ }
}
}
}
In the original, the loop exits if "dt" becomes NULL (i.e. end of linked list
found) or if "canonical" becomes non-null. I don't see any way for "canonical"
to change within the loop though, so I suspect that the original should have
been:
for (; dt && !got_canonical; dt = dt->next)
i.e. tested "got_canonical" instead of "canonical".
Currently my patch just removes the test of "canonical", and passes all tests
cleanly. If I'm correct about this, the original, wrong test didn't cause any
problems (since "canonical" is always NULL in this loop), but just means that
there's no early exit from the loop once the canonical type is found.
If you agree with that I can add a "!got_canonical" test back in to my patch
(I've already checked that it passes tests cleanly with that test in place).
> Btw, another thing that you'll need is a ChangeLog entry that lists
> every file and function touched by your patch and gives a short
> description of the modifications. You'll find plenty of examples for
> this in gcc/fortran/ChangeLog.
I've also attached a ChangeLog entry.
One other question: for copyright assignment, who do I need to talk to to get
the relevant form(s)?
Thanks,
Andrew
--
* Andrew Benson: http://users.obs.carnegiescience.edu/abenson/contact.html
* Galacticus: https://bitbucket.org/abensonca/galacticus
[-- Attachment #2: patch.diff --]
[-- Type: text/x-patch, Size: 8567 bytes --]
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h (revision 260682)
+++ gcc/fortran/gfortran.h (working copy)
@@ -1611,6 +1611,9 @@ typedef struct gfc_symbol
/* Link to corresponding association-list if this is an associate name. */
struct gfc_association_list *assoc;
+
+ /* Link to next entry in derived type list */
+ struct gfc_symbol *dt_next;
}
gfc_symbol;
@@ -1712,19 +1715,9 @@ typedef struct gfc_symtree
}
gfc_symtree;
-/* A linked list of derived types in the namespace. */
-typedef struct gfc_dt_list
-{
- struct gfc_symbol *derived;
- struct gfc_dt_list *next;
-}
-gfc_dt_list;
+/* A list of all derived types. */
+extern gfc_symbol *gfc_derived_types;
-#define gfc_get_dt_list() XCNEW (gfc_dt_list)
-
- /* A list of all derived types. */
- extern gfc_dt_list *gfc_derived_types;
-
typedef struct gfc_oacc_routine_name
{
struct gfc_symbol *sym;
@@ -1809,7 +1802,7 @@ typedef struct gfc_namespace
gfc_charlen *cl_list;
- gfc_dt_list *derived_types;
+ gfc_symbol *derived_types;
int save_all, seen_save, seen_implicit_none;
Index: gcc/fortran/parse.c
===================================================================
--- gcc/fortran/parse.c (revision 260682)
+++ gcc/fortran/parse.c (working copy)
@@ -6047,7 +6047,7 @@ add_global_program (void)
static void
resolve_all_program_units (gfc_namespace *gfc_global_ns_list)
{
- gfc_free_dt_list ();
+ gfc_derived_types = NULL;
gfc_current_ns = gfc_global_ns_list;
for (; gfc_current_ns; gfc_current_ns = gfc_current_ns->sibling)
{
Index: gcc/fortran/resolve.c
===================================================================
--- gcc/fortran/resolve.c (revision 260682)
+++ gcc/fortran/resolve.c (working copy)
@@ -2504,7 +2504,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *
/* Resolve the gsymbol namespace if needed. */
if (!gsym->ns->resolved)
{
- gfc_dt_list *old_dt_list;
+ gfc_symbol *old_dt_list;
/* Stash away derived types so that the backend_decls do not
get mixed up. */
@@ -13435,16 +13435,21 @@ resolve_typebound_procedures (gfc_symbol* derived)
static void
add_dt_to_dt_list (gfc_symbol *derived)
{
- gfc_dt_list *dt_list;
- for (dt_list = gfc_derived_types; dt_list; dt_list = dt_list->next)
- if (derived == dt_list->derived)
- return;
-
- dt_list = gfc_get_dt_list ();
- dt_list->next = gfc_derived_types;
- dt_list->derived = derived;
- gfc_derived_types = dt_list;
+ if (!derived->dt_next)
+ {
+ if (gfc_derived_types)
+ {
+ derived->dt_next = gfc_derived_types->dt_next;
+ gfc_derived_types->dt_next = derived;
+ }
+ else
+ {
+ derived->dt_next = derived;
+ }
+ gfc_derived_types = derived;
+ }
+
}
Index: gcc/fortran/symbol.c
===================================================================
--- gcc/fortran/symbol.c (revision 260682)
+++ gcc/fortran/symbol.c (working copy)
@@ -107,7 +107,7 @@ gfc_namespace *gfc_global_ns_list;
gfc_gsymbol *gfc_gsym_root = NULL;
-gfc_dt_list *gfc_derived_types;
+gfc_symbol *gfc_derived_types;
static gfc_undo_change_set default_undo_chgset_var = { vNULL, vNULL, NULL };
static gfc_undo_change_set *latest_undo_chgset = &default_undo_chgset_var;
@@ -3119,6 +3119,7 @@ gfc_new_symbol (const char *name, gfc_namespace *n
p->common_block = NULL;
p->f2k_derived = NULL;
p->assoc = NULL;
+ p->dt_next = NULL;
p->fn_result_spec = 0;
return p;
@@ -3878,23 +3879,6 @@ free_sym_tree (gfc_symtree *sym_tree)
}
-/* Free the derived type list. */
-
-void
-gfc_free_dt_list (void)
-{
- gfc_dt_list *dt, *n;
-
- for (dt = gfc_derived_types; dt; dt = n)
- {
- n = dt->next;
- free (dt);
- }
-
- gfc_derived_types = NULL;
-}
-
-
/* Free the gfc_equiv_info's. */
static void
@@ -4080,7 +4064,7 @@ gfc_symbol_done_2 (void)
gfc_free_namespace (gfc_current_ns);
gfc_current_ns = NULL;
}
- gfc_free_dt_list ();
+ gfc_derived_types = NULL;
enforce_single_undo_checkpoint ();
free_undo_change_set_data (*latest_undo_chgset);
@@ -4343,7 +4327,7 @@ gfc_get_gsymbol (const char *name)
static gfc_symbol *
get_iso_c_binding_dt (int sym_id)
{
- gfc_dt_list *dt_list;
+ gfc_symbol *dt_list;
dt_list = gfc_derived_types;
@@ -4350,13 +4334,16 @@ get_iso_c_binding_dt (int sym_id)
/* Loop through the derived types in the name list, searching for
the desired symbol from iso_c_binding. Search the parent namespaces
if necessary and requested to (parent_flag). */
- while (dt_list != NULL)
+ if (dt_list)
{
- if (dt_list->derived->from_intmod != INTMOD_NONE
- && dt_list->derived->intmod_sym_id == sym_id)
- return dt_list->derived;
-
- dt_list = dt_list->next;
+ while (dt_list->dt_next != gfc_derived_types)
+ {
+ if (dt_list->from_intmod != INTMOD_NONE
+ && dt_list->intmod_sym_id == sym_id)
+ return dt_list;
+
+ dt_list = dt_list->dt_next;
+ }
}
return NULL;
@@ -4762,11 +4749,16 @@ generate_isocbinding_symbol (const char *mod_name,
if (tmp_sym->attr.flavor == FL_DERIVED
&& !get_iso_c_binding_dt (tmp_sym->intmod_sym_id))
{
- gfc_dt_list *dt_list;
- dt_list = gfc_get_dt_list ();
- dt_list->derived = tmp_sym;
- dt_list->next = gfc_derived_types;
- gfc_derived_types = dt_list;
+ if (gfc_derived_types)
+ {
+ tmp_sym->dt_next = gfc_derived_types->dt_next;
+ gfc_derived_types->dt_next = tmp_sym;
+ }
+ else
+ {
+ tmp_sym->dt_next = tmp_sym;
+ }
+ gfc_derived_types = tmp_sym;
}
return tmp_symtree;
@@ -4874,7 +4866,6 @@ generate_isocbinding_symbol (const char *mod_name,
case ISOCBINDING_FUNPTR:
{
gfc_symbol *dt_sym;
- gfc_dt_list **dt_list_ptr = NULL;
gfc_component *tmp_comp = NULL;
/* Generate real derived type. */
@@ -4936,18 +4927,17 @@ generate_isocbinding_symbol (const char *mod_name,
dt_sym->ts.u.derived = dt_sym;
/* Add the symbol created for the derived type to the current ns. */
- dt_list_ptr = &(gfc_derived_types);
- while (*dt_list_ptr != NULL && (*dt_list_ptr)->next != NULL)
- dt_list_ptr = &((*dt_list_ptr)->next);
-
- /* There is already at least one derived type in the list, so append
- the one we're currently building for c_ptr or c_funptr. */
- if (*dt_list_ptr != NULL)
- dt_list_ptr = &((*dt_list_ptr)->next);
- (*dt_list_ptr) = gfc_get_dt_list ();
- (*dt_list_ptr)->derived = dt_sym;
- (*dt_list_ptr)->next = NULL;
-
+ if (gfc_derived_types)
+ {
+ dt_sym->dt_next = gfc_derived_types->dt_next;
+ gfc_derived_types->dt_next = dt_sym;
+ }
+ else
+ {
+ dt_sym->dt_next = dt_sym;
+ }
+ gfc_derived_types = dt_sym;
+
gfc_add_component (dt_sym, "c_address", &tmp_comp);
if (tmp_comp == NULL)
gcc_unreachable ();
Index: gcc/fortran/trans-types.c
===================================================================
--- gcc/fortran/trans-types.c (revision 260682)
+++ gcc/fortran/trans-types.c (working copy)
@@ -2534,7 +2534,6 @@ gfc_get_derived_type (gfc_symbol * derived, int co
bool got_canonical = false;
bool unlimited_entity = false;
gfc_component *c;
- gfc_dt_list *dt;
gfc_namespace *ns;
tree tmp;
bool coarray_flag;
@@ -2599,16 +2598,20 @@ gfc_get_derived_type (gfc_symbol * derived, int co
ns->translated && !got_canonical;
ns = ns->sibling)
{
- dt = ns->derived_types;
- for (; dt && !canonical; dt = dt->next)
+ if (ns->derived_types)
{
- gfc_copy_dt_decls_ifequal (dt->derived, derived, true);
- if (derived->backend_decl)
- got_canonical = true;
+ for (gfc_symbol *dt = ns->derived_types; dt; dt = dt->dt_next)
+ {
+ gfc_copy_dt_decls_ifequal (dt, derived, true);
+ if (derived->backend_decl)
+ got_canonical = true;
+ if (dt->dt_next == ns->derived_types)
+ break;
+ }
}
}
}
-
+
/* Store up the canonical type to be added to this one. */
if (got_canonical)
{
@@ -2866,10 +2869,14 @@ copy_derived_types:
TREE_NO_WARNING (c->caf_token) = 1;
}
}
-
- for (dt = gfc_derived_types; dt; dt = dt->next)
- gfc_copy_dt_decls_ifequal (derived, dt->derived, false);
-
+
+ for (gfc_symbol *dt = gfc_derived_types; dt; dt = dt->dt_next)
+ {
+ gfc_copy_dt_decls_ifequal (derived, dt, false);
+ if (dt->dt_next == gfc_derived_types)
+ break;
+ }
+
return derived->backend_decl;
}
[-- Attachment #3: ChangeLog --]
[-- Type: text/x-changelog, Size: 808 bytes --]
2018-05-31 Andrew Benson <abenson@carnegiescience.edu>
* gfortran.h: Add pointer to next derived type to
gfc_symbol. Remove gfc_dt_list.
* parse.c (resolve_all_program_units, resolve_global_procedure)
(resolve_typebound_procedures): Replace gfc_free_dt_list() with
simple nullification of gfc_derived_types. Change derived type
linked list insertion to utilize dt_next pointers in gfc_symbol.
* symbol.c (gfc_new_symbol, free_sym_tree, gfc_symbol_done2)
(gfc_get_gsymbol, get_iso_c_binding_dt)
(generate_isocbinding_symbol): Remove gfc_free_dt_list as
gfc_dt_list is obsoleted. Change derived type linked list
search/insertion to utilize dt_next pointers in gfc_symbol.
* trans-types.c (gfc_get_derived_type): Change derived type linked
list search to utilize dt_next pointers in gfc_symbol.
next prev parent reply other threads:[~2018-05-31 18:04 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-24 22:53 Andrew Benson
2018-05-25 7:06 ` Richard Biener
2018-05-25 7:13 ` Richard Biener
2018-05-25 21:54 ` Andrew Benson
2018-05-28 9:54 ` Richard Biener
2018-05-29 20:25 ` Andrew Benson
2018-05-30 9:44 ` Richard Biener
2018-05-30 17:01 ` Andrew Benson
2018-05-30 18:25 ` Steve Kargl
2018-05-30 18:37 ` Andrew Benson
2018-05-30 20:43 ` Janus Weil
2018-05-30 22:22 ` Andrew Benson
2018-05-31 8:56 ` Janus Weil
2018-05-31 18:04 ` Andrew Benson [this message]
2018-06-01 6:14 ` Janus Weil
2018-06-11 18:45 ` Steve Kargl
2018-06-11 19:22 ` Andrew Benson
2018-06-14 5:15 ` Andrew Benson
2018-06-15 0:12 ` Steve Kargl
2018-06-15 7:59 ` Andrew Benson
2018-07-11 2:33 ` Andrew Benson
2018-07-20 16:29 ` Andrew Benson
2018-07-20 18:59 ` Janus Weil
2018-07-20 19:02 ` Andrew Benson
2018-07-20 19:10 ` Janus Weil
2018-07-20 20:04 ` Janus Weil
2018-07-20 20:22 ` Andrew Benson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=6422270.9Mc4pgMANL@andrew-precision-3520 \
--to=abenson@carnegiescience.edu \
--cc=fortran@gcc.gnu.org \
--cc=janus@gcc.gnu.org \
--cc=richard.guenther@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).