Commit d61ae8dd by Francois-Xavier Coudert Committed by François-Xavier Coudert

re PR fortran/30285 (gfortran excessive memory usage with COMMON blocks in modules)

	PR fortran/30285
	* module.c (struct written_common, written_commons): New structure.
	(compare_written_commons, free_written_common, write_common_0):
	New functions.
	(write_common): Call recursive function write_common_0.

From-SVN: r130257
parent 04901f81
2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> 2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/30285
* module.c (struct written_common, written_commons): New structure.
(compare_written_commons, free_written_common, write_common_0):
New functions.
(write_common): Call recursive function write_common_0.
2007-11-17 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org>
PR fortran/34108 PR fortran/34108
* io.c (check_format_string): Only check character expressions. * io.c (check_format_string): Only check character expressions.
(match_dt_format): Return MATCH_ERROR if that is what (match_dt_format): Return MATCH_ERROR if that is what
......
...@@ -3767,51 +3767,119 @@ gfc_check_access (gfc_access specific_access, gfc_access default_access) ...@@ -3767,51 +3767,119 @@ gfc_check_access (gfc_access specific_access, gfc_access default_access)
} }
/* Write a common block to the module. */ /* A structure to remember which commons we've already written. */
struct written_common
{
BBT_HEADER(written_common);
const char *name, *label;
};
static struct written_common *written_commons = NULL;
/* Comparison function used for balancing the binary tree. */
static int
compare_written_commons (void *a1, void *b1)
{
const char *aname = ((struct written_common *) a1)->name;
const char *alabel = ((struct written_common *) a1)->label;
const char *bname = ((struct written_common *) b1)->name;
const char *blabel = ((struct written_common *) b1)->label;
int c = strcmp (aname, bname);
return (c != 0 ? c : strcmp (alabel, blabel));
}
/* Free a list of written commons. */
static void static void
write_common (gfc_symtree *st) free_written_common (struct written_common *w)
{
if (!w)
return;
if (w->left)
free_written_common (w->left);
if (w->right)
free_written_common (w->right);
gfc_free (w);
}
/* Write a common block to the module -- recursive helper function. */
static void
write_common_0 (gfc_symtree *st)
{ {
gfc_common_head *p; gfc_common_head *p;
const char * name; const char * name;
int flags; int flags;
const char *label; const char *label;
struct written_common *w;
bool write_me = true;
if (st == NULL) if (st == NULL)
return; return;
write_common (st->left); write_common_0 (st->left);
write_common (st->right);
mio_lparen ();
/* Write the unmangled name. */ /* We will write out the binding label, or the name if no label given. */
name = st->n.common->name; name = st->n.common->name;
mio_pool_string (&name);
p = st->n.common; p = st->n.common;
mio_symbol_ref (&p->head); label = p->is_bind_c ? p->binding_label : p->name;
flags = p->saved ? 1 : 0;
if (p->threadprivate) flags |= 2;
mio_integer (&flags);
/* 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. */ /* Check if we've already output this common. */
if (p->is_bind_c) w = written_commons;
while (w)
{ {
label = p->binding_label; int c = strcmp (name, w->name);
mio_pool_string (&label); c = (c != 0 ? c : strcmp (label, w->label));
if (c == 0)
write_me = false;
w = (c < 0) ? w->left : w->right;
} }
else
if (write_me)
{ {
label = p->name; /* Write the common to the module. */
mio_lparen ();
mio_pool_string (&name);
mio_symbol_ref (&p->head);
flags = p->saved ? 1 : 0;
if (p->threadprivate)
flags |= 2;
mio_integer (&flags);
/* Write out whether the common block is bind(c) or not. */
mio_integer (&(p->is_bind_c));
mio_pool_string (&label); mio_pool_string (&label);
mio_rparen ();
/* Record that we have written this common. */
w = gfc_getmem (sizeof (struct written_common));
w->name = p->name;
w->label = label;
gfc_insert_bbt (&written_commons, w, compare_written_commons);
} }
mio_rparen (); write_common_0 (st->right);
}
/* Write a common, by initializing the list of written commons, calling
the recursive function write_common_0() and cleaning up afterwards. */
static void
write_common (gfc_symtree *st)
{
written_commons = NULL;
write_common_0 (st);
free_written_common (written_commons);
written_commons = NULL;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment