/* Optimize statements on expressions, using gfc. Copyright (C) 2010 Free Software Foundation, Inc. Contributed by Thomas König This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see . */ /* This contains files for a front end optimizer. */ #include "config.h" #include "system.h" #include "gfortran.h" #include "arith.h" /* Forward declarations. */ static void strip_function_call (gfc_expr *); static void optimize_assignment (gfc_code *); /* Go through all executable statements of a namespace, invoking specific optimizations along the way. */ void gfc_optimize_namespace (gfc_namespace * ns) { gfc_code * c; for (c = ns->code; c; c = c->next) { switch (c->op) { case EXEC_ASSIGN: optimize_assignment (c); default: break; } } } /* Do the optimizations for assignments. This function calls itself recursively for any successes. */ static void optimize_assignment (gfc_code * c) { gfc_expr *lhs, *rhs; lhs = c->expr1; rhs = c->expr2; /* Optimize away a = trim(b), where a is a character variable. */ if (lhs->ts.type == BT_CHARACTER) { if (rhs->expr_type == EXPR_FUNCTION && rhs->value.function.isym && rhs->value.function.isym->id == GFC_ISYM_TRIM) { strip_function_call (rhs); optimize_assignment (c); } } } /* Remove an unneeded function call, modifying the expression. This replaces the function call with the value of its first argument. The rest of the argument list is freed. */ static void strip_function_call (gfc_expr *e) { gfc_expr *e1; gfc_actual_arglist *a; a = e->value.function.actual; /* We should have at least one argument. */ gcc_assert (a->expr != NULL); e1 = a->expr; /* Free the remaining arglist, if any. */ if (a->next) gfc_free_actual_arglist (a->next); /* Graft the argument expression onto the original function. */ *e = *e1; gfc_free (e1); }