This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch, fortran] use vec<> in frontend-passes.c
- From: Thomas Koenig <tkoenig at netcologne dot de>
- To: Trevor Saunders <tsaunders at mozilla dot com>
- Cc: "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sun, 24 Aug 2014 14:48:51 +0200
- Subject: Re: [patch, fortran] use vec<> in frontend-passes.c
- Authentication-results: sourceware.org; auth=none
- References: <53F919F5 dot 2050602 at netcologne dot de> <20140824030209 dot GA11895 at tsaunders-iceball dot corp dot tor1 dot mozilla dot com>
Hi,
Trevor Saunders wrote:
>> -static gfc_expr ***expr_array;
>> -static int expr_size, expr_count;
>> +static vec<gfc_expr **> expr_array = vec<gfc_expr **>();
>
> that's usually written as just static vec<T> foo; vec doesn't actually
> have ctors, and 0 initialization works fine.
Fixed (also below).
>> + // doloop_list = ;
>
> what is this comment supposed to mean?
Leftover from a commented piece of code, removed.
>> doloop_warn (ns);
>> - XDELETEVEC (doloop_list);
>> + doloop_list.truncate (0);
>
> .release () would be more typical.
Changed (also below).
>> - for (i=1; i<expr_count; i++)
>> + for (i=1; expr_array.iterate (i, &ei); i++)
>
> FOR_EACH_VEC_ELT, though Its not really clear to my why that's better
> than
> size_t length = vec.length ();
> for (size_t i = 0; i < length; i++)
Done in a slightly different way (see the patch).
>> + for (j=0; j<i && expr_array.iterate (j, &ej); j++)
>
> the .iterate call is useless since j must be < i, and the vector is
> at least i long right?
I was using the iterate call to get the current value of the vector.
I have now replaced this with using expr_array[j] below.
Steve wrote:
> Does this fix a bug in gfortran? "If it is not broken,
> don't fix it".
It doesn't fix a bug by itself, but it clears up the code by
avoiding hand-rolled memory management in two places. I also
want to do some more things in front-end optimization which
require vectors, so I think it makes sense to have a consistent
style, in a single file at least :-)
Therefore: OK for trunk?
Thomas
2014-08-24 Thomas Koenig <tkoenig@gcc.gnu.org>
* frontend_passes (expr_array): Replace by vec template.
(expr_size): Remove.
(expr_count): Remove.
(doloop_list): Replace by vec template.
(doloop_size): Remove.
(gfc_run_passes): Adjust to use of vec template.
(cfe_register_funcs): Likewise.
(cfe_expr_0): Likewise.
(doloop_code): Likewise.
Index: frontend-passes.c
===================================================================
--- frontend-passes.c (Revision 214281)
+++ frontend-passes.c (Arbeitskopie)
@@ -47,11 +47,9 @@ static int callback_reduction (gfc_expr **, int *,
static int count_arglist;
-/* Pointer to an array of gfc_expr ** we operate on, plus its size
- and counter. */
+/* Vector of gfc_expr ** we operate on. */
-static gfc_expr ***expr_array;
-static int expr_size, expr_count;
+static vec<gfc_expr **> expr_array;
/* Pointer to the gfc_code we currently work on - to be able to insert
a block before the statement. */
@@ -81,9 +79,10 @@ static int iterator_level;
/* Keep track of DO loop levels. */
-static gfc_code **doloop_list;
-static int doloop_size, doloop_level;
+static vec<gfc_code *> doloop_list;
+static int doloop_level;
+
/* Vector of gfc_expr * to keep track of DO loops. */
struct my_struct *evec;
@@ -101,23 +100,18 @@ gfc_run_passes (gfc_namespace *ns)
/* Warn about dubious DO loops where the index might
change. */
- doloop_size = 20;
doloop_level = 0;
- doloop_list = XNEWVEC(gfc_code *, doloop_size);
doloop_warn (ns);
- XDELETEVEC (doloop_list);
+ doloop_list.release ();
if (gfc_option.flag_frontend_optimize)
{
- expr_size = 20;
- expr_array = XNEWVEC(gfc_expr **, expr_size);
-
optimize_namespace (ns);
optimize_reduction (ns);
if (gfc_option.dump_fortran_optimized)
gfc_dump_parse_tree (ns, stdout);
- XDELETEVEC (expr_array);
+ expr_array.release ();
}
}
@@ -420,13 +414,7 @@ cfe_register_funcs (gfc_expr **e, int *walk_subtre
return 0;
}
- if (expr_count >= expr_size)
- {
- expr_size += expr_size;
- expr_array = XRESIZEVEC(gfc_expr **, expr_array, expr_size);
- }
- expr_array[expr_count] = e;
- expr_count ++;
+ expr_array.safe_push (e);
return 0;
}
@@ -599,6 +587,7 @@ cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
{
int i,j;
gfc_expr *newvar;
+ gfc_expr **ei, **ej;
/* Don't do this optimization within OMP workshare. */
@@ -608,36 +597,36 @@ cfe_expr_0 (gfc_expr **e, int *walk_subtrees,
return 0;
}
- expr_count = 0;
+ expr_array.truncate (0);
gfc_expr_walker (e, cfe_register_funcs, NULL);
/* Walk through all the functions. */
- for (i=1; i<expr_count; i++)
+ FOR_EACH_VEC_ELT_FROM (expr_array, i, ei, 1)
{
/* Skip if the function has been replaced by a variable already. */
- if ((*(expr_array[i]))->expr_type == EXPR_VARIABLE)
+ if ((*ei)->expr_type == EXPR_VARIABLE)
continue;
newvar = NULL;
for (j=0; j<i; j++)
{
- if (gfc_dep_compare_functions (*(expr_array[i]),
- *(expr_array[j]), true) == 0)
+ ej = expr_array[j];
+ if (gfc_dep_compare_functions (*ei, *ej, true) == 0)
{
if (newvar == NULL)
- newvar = create_var (*(expr_array[i]));
+ newvar = create_var (*ei);
if (gfc_option.warn_function_elimination)
- warn_function_elimination (*(expr_array[j]));
+ warn_function_elimination (*ej);
- free (*(expr_array[j]));
- *(expr_array[j]) = gfc_copy_expr (newvar);
+ free (*ej);
+ *ej = gfc_copy_expr (newvar);
}
}
if (newvar)
- *(expr_array[i]) = newvar;
+ *ei = newvar;
}
/* We did all the necessary walking in this function. */
@@ -1671,25 +1660,23 @@ doloop_code (gfc_code **c, int *walk_subtrees ATTR
int i;
gfc_formal_arglist *f;
gfc_actual_arglist *a;
+ gfc_code *cl;
co = *c;
+ /* If the doloop_list grew, we have to truncate it here. */
+
+ if ((unsigned) doloop_level < doloop_list.length())
+ doloop_list.truncate (doloop_level);
+
switch (co->op)
{
case EXEC_DO:
- /* Grow the temporary storage if necessary. */
- if (doloop_level >= doloop_size)
- {
- doloop_size = 2 * doloop_size;
- doloop_list = XRESIZEVEC (gfc_code *, doloop_list, doloop_size);
- }
-
- /* Mark the DO loop variable if there is one. */
if (co->ext.iterator && co->ext.iterator->var)
- doloop_list[doloop_level] = co;
+ doloop_list.safe_push (co);
else
- doloop_list[doloop_level] = NULL;
+ doloop_list.safe_push ((gfc_code *) NULL);
break;
case EXEC_CALL:
@@ -1708,14 +1695,14 @@ doloop_code (gfc_code **c, int *walk_subtrees ATTR
while (a && f)
{
- for (i=0; i<doloop_level; i++)
+ FOR_EACH_VEC_ELT (doloop_list, i, cl)
{
gfc_symbol *do_sym;
- if (doloop_list[i] == NULL)
+ if (cl == NULL)
break;
- do_sym = doloop_list[i]->ext.iterator->var->symtree->n.sym;
+ do_sym = cl->ext.iterator->var->symtree->n.sym;
if (a->expr && a->expr->symtree
&& a->expr->symtree->n.sym == do_sym)
@@ -1755,6 +1742,7 @@ do_function (gfc_expr **e, int *walk_subtrees ATTR
gfc_formal_arglist *f;
gfc_actual_arglist *a;
gfc_expr *expr;
+ gfc_code *dl;
int i;
expr = *e;
@@ -1777,15 +1765,14 @@ do_function (gfc_expr **e, int *walk_subtrees ATTR
while (a && f)
{
- for (i=0; i<doloop_level; i++)
+ FOR_EACH_VEC_ELT (doloop_list, i, dl)
{
gfc_symbol *do_sym;
-
-
- if (doloop_list[i] == NULL)
+
+ if (dl == NULL)
break;
- do_sym = doloop_list[i]->ext.iterator->var->symtree->n.sym;
+ do_sym = dl->ext.iterator->var->symtree->n.sym;
if (a->expr && a->expr->symtree
&& a->expr->symtree->n.sym == do_sym)