public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [fortran,patch] Don't write common more than once in a module file (PR 30285)
@ 2007-11-10 15:56 FX Coudert
  2007-11-10 18:34 ` Tobias Schlüter
  2007-11-12  9:52 ` Jerry DeLisle
  0 siblings, 2 replies; 8+ messages in thread
From: FX Coudert @ 2007-11-10 15:56 UTC (permalink / raw)
  To: fortran@gcc.gnu.org List; +Cc: gcc-patches list

[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]

PR 30285 is about deeply nested module files containing commons,  
which take a huge amount of memory when they're read back (and loads  
of disk space, but that's not so much of a problem). This commonly  
happens with MPICH and openmpi, and leads some people to run out of  
memory when compiling mpi-enabled programs.

The problem is that we write each common name more than once (a  
number of times that grows exponentially with the nesting). I tried  
to change the way we load modules, to avoid creating these duplicate  
symbols, but the diagnostics code for commons with binding labels  
requires this creation of multiple symbols, so I went for something  
that is a bit of a hack: we get rid of duplicate common names  
(specificaly: duplicate pairs of name and binding label) when writing  
the module files, by creating a list of them as we go through and  
checking them against that list.

I agree it's not a perfect solution, but I couldn't make it work in  
any other way (see the PR for a tentative patch), and I think it's  
worth committing now, as it's a serious problem for our users.  
Regtested on x86_64-linux, OK to commit?

FX



:ADDPATCH fortran:

[-- Attachment #2: pr30285.ChangeLog --]
[-- Type: application/octet-stream, Size: 226 bytes --]

2007-11-10  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>

	PR fortran/30285
	* module.c (struct written_common, write_common0): New structure
	and function.
	(write_common): Avoid to write the same common more than once.


[-- Attachment #3: pr30285.diff --]
[-- Type: application/octet-stream, Size: 2387 bytes --]

Index: module.c
===================================================================
--- module.c	(revision 129869)
+++ module.c	(working copy)
@@ -3767,30 +3767,50 @@ gfc_check_access (gfc_access specific_ac
 }
 
 
-/* Write a common block to the module.  */
+struct written_common
+{
+  const char *name, *label;
+  struct written_common *next;
+};
+
+static struct written_common *written_common;
+
+/* Write a common block to the module -- recursive helper function.  */
 
 static void
-write_common (gfc_symtree *st)
+write_common_0 (gfc_symtree *st)
 {
   gfc_common_head *p;
   const char * name;
   int flags;
   const char *label;
+  struct written_common *w;
 	      
   if (st == NULL)
     return;
 
-  write_common (st->left);
-  write_common (st->right);
-
-  mio_lparen ();
+  write_common_0 (st->left);
+  write_common_0 (st->right);
 
   /* Write the unmangled name.  */
   name = st->n.common->name;
+  p = st->n.common;
+
+  /* We will write out the binding label, or the name if no label given.  */
+  if (p->is_bind_c)
+    label = p->binding_label;
+  else
+    label = p->name;
+
+  /* Check if we've already output this common.  */
+  for (w = written_common; w; w = w->next)
+    if (strcmp (w->name, name) == 0 && strcmp (w->label, label) == 0)
+      return;
+
+  mio_lparen ();
 
   mio_pool_string (&name);
 
-  p = st->n.common;
   mio_symbol_ref (&p->head);
   flags = p->saved ? 1 : 0;
   if (p->threadprivate) flags |= 2;
@@ -3799,19 +3819,34 @@ write_common (gfc_symtree *st)
   /* Write out whether the common block is bind(c) or not.  */
   mio_integer (&(p->is_bind_c));
 
-  /* Write out the binding label, or the com name if no label given.  */
-  if (p->is_bind_c)
-    {
-      label = p->binding_label;
-      mio_pool_string (&label);
-    }
-  else
+  mio_pool_string (&label);
+  mio_rparen ();
+
+  /* Record that we have written this common.  */
+  w = gfc_getmem (sizeof (struct written_common));
+  w->next = written_common;
+  written_common = w;
+  w->name = p->name;
+  w->label = label;
+}
+
+
+/* Set up */
+static void
+write_common (gfc_symtree *st)
+{
+  struct written_common *w, *w2;
+
+  written_common = NULL;
+  write_common_0 (st);
+
+  w = written_common;
+  while (w)
     {
-      label = p->name;
-      mio_pool_string (&label);
+      w2 = w->next;
+      gfc_free (w);
+      w = w2;
     }
-
-  mio_rparen ();
 }
 
 

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2007-11-17 13:47 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-10 15:56 [fortran,patch] Don't write common more than once in a module file (PR 30285) FX Coudert
2007-11-10 18:34 ` Tobias Schlüter
2007-11-17 13:46   ` FX Coudert
2007-11-17 13:47     ` FX Coudert
2007-11-17 16:33     ` Tobias Schlüter
2007-11-17 17:22       ` Tobias Schlüter
2007-11-17 17:38         ` FX Coudert
2007-11-12  9:52 ` Jerry DeLisle

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).