From patchwork Sat Sep 11 19:40:02 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Koenig X-Patchwork-Id: 64528 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 242BEB70A2 for ; Sun, 12 Sep 2010 05:40:21 +1000 (EST) Received: (qmail 2367 invoked by alias); 11 Sep 2010 19:40:18 -0000 Received: (qmail 2346 invoked by uid 22791); 11 Sep 2010 19:40:13 -0000 X-SWARE-Spam-Status: No, hits=-1.9 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp6.netcologne.de (HELO smtp6.netcologne.de) (194.8.194.26) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 11 Sep 2010 19:40:06 +0000 Received: from [192.168.0.196] (xdsl-195-14-197-186.netcologne.de [195.14.197.186]) by smtp6.netcologne.de (Postfix) with ESMTP id 02EAD2A0ABE; Sat, 11 Sep 2010 21:40:02 +0200 (CEST) Subject: [patch, fortran] Make frontend walker more general From: Thomas Koenig To: fortran@gcc.gnu.org Cc: gcc-patches@gcc.gnu.org Date: Sat, 11 Sep 2010 21:40:02 +0200 Message-ID: <1284234002.5873.3.camel@linux-fd1f.site> Mime-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Hello world, the current expression walker for front end stuff is not general. Here's an attempt to make it so. I have also added a few cases which were not handled before. Regression-tested. No test necessary, because this is only a cleanup. OK for trunk? Thomas 2010-09-11 Thomas Koenig * frontend-passes.c (process_functions): New struct and type. (process_namespace): Rename from optimize_namespace, add process_functions * argument. Call renamed functions. Adjust prototype. (process_code): Rename from optimize_code, add process_functions * argument. Call renamed functions. Adjust prototype. (process_code_node): Rename from optimize_code_node, add process_functions * argument. Call functions from the pass function pointers. Add code for the EXEC_READ, EXEC_WRITE, EXEC_OPEN, EXEC_INQUIRE, EXEC_REWIND, EXEC_ENDFILE, EXEC_BACKSPACE, EXEC_CLOSE, EXEC_WAIT. Adjust prototype. (optimize_expr_0): Return early for NULL expression. (optimize_pass): New struct. (gfc_run_passes): Call process namespace with optimize_pass argument instead of optimize_namespace. Index: frontend-passes.c =================================================================== --- frontend-passes.c (Revision 164119) +++ frontend-passes.c (Arbeitskopie) @@ -25,19 +25,35 @@ along with GCC; see the file COPYING3. If not see #include "flags.h" #include "dependency.h" + +/* A struct for holding the pass-specific functions. */ +typedef struct process_functions +{ + void (*process_assignment) (gfc_code *); + void (*process_expr) (gfc_expr *); + void (*process_actual_arglist) (gfc_actual_arglist *); + void (*process_pointer_assign) (gfc_code *); +} process_functions; + /* Forward declarations. */ static void strip_function_call (gfc_expr *); -static void optimize_namespace (gfc_namespace *); +static void process_namespace (gfc_namespace *, process_functions *); static void optimize_assignment (gfc_code *); static void optimize_expr_0 (gfc_expr *); static bool optimize_expr (gfc_expr *); static bool optimize_op (gfc_expr *); static bool optimize_equality (gfc_expr *, bool); -static void optimize_code (gfc_code *); -static void optimize_code_node (gfc_code *); +static void process_code (gfc_code *, process_functions *); +static void process_code_node (gfc_code *, process_functions *); static void optimize_actual_arglist (gfc_actual_arglist *); +struct process_functions optimize_pass = + { optimize_assignment, + optimize_expr_0, + optimize_actual_arglist, + NULL }; + /* Entry point - run all passes for a namespace. So far, only an optimization pass is run. */ @@ -45,32 +61,32 @@ void gfc_run_passes (gfc_namespace *ns) { if (optimize) - optimize_namespace (ns); + process_namespace (ns, &optimize_pass); } /* Optimize a namespace, including all contained namespaces. */ static void -optimize_namespace (gfc_namespace *ns) +process_namespace (gfc_namespace *ns, process_functions *pass) { - optimize_code (ns->code); + process_code (ns->code, pass); for (ns = ns->contained; ns; ns = ns->sibling) - optimize_namespace (ns); + process_namespace (ns, pass); } static void -optimize_code (gfc_code *c) +process_code (gfc_code *c, process_functions *pass) { for (; c; c = c->next) - optimize_code_node (c); + process_code_node (c, pass); } -/* Do the optimizations for a code node. */ +/* Handle a code node. */ static void -optimize_code_node (gfc_code *c) +process_code_node (gfc_code *c, process_functions *pass) { gfc_forall_iterator *fa; @@ -80,17 +96,17 @@ static void switch (c->op) { case EXEC_ASSIGN: - optimize_assignment (c); + pass->process_assignment (c); break; case EXEC_CALL: case EXEC_ASSIGN_CALL: case EXEC_CALL_PPC: - optimize_actual_arglist (c->ext.actual); + pass->process_actual_arglist (c->ext.actual); break; case EXEC_ARITHMETIC_IF: - optimize_expr_0 (c->expr1); + pass->process_expr (c->expr1); break; case EXEC_PAUSE: @@ -98,50 +114,48 @@ static void case EXEC_ERROR_STOP: case EXEC_STOP: case EXEC_COMPCALL: - optimize_expr_0 (c->expr1); + pass->process_expr (c->expr1); break; case EXEC_SYNC_ALL: case EXEC_SYNC_MEMORY: case EXEC_SYNC_IMAGES: - optimize_expr_0 (c->expr2); + pass->process_expr (c->expr2); break; case EXEC_IF: d = c->block; - optimize_expr_0 (d->expr1); - optimize_code (d->next); + pass->process_expr (d->expr1); + process_code (d->next, pass); for (d = d->block; d; d = d->block) { - optimize_expr_0 (d->expr1); - - optimize_code (d->next); + pass->process_expr (d->expr1); + process_code (d->next, pass); } - break; case EXEC_SELECT: case EXEC_SELECT_TYPE: d = c->block; - optimize_expr_0 (c->expr1); + pass->process_expr (c->expr1); for (; d; d = d->block) - optimize_code (d->next); + process_code (d->next, pass); break; case EXEC_WHERE: d = c->block; - optimize_expr_0 (d->expr1); - optimize_code (d->next); + pass->process_expr (d->expr1); + process_code (d->next, pass); for (d = d->block; d; d = d->block) { - optimize_expr_0 (d->expr1); - optimize_code (d->next); + pass->process_expr (d->expr1); + process_code (d->next, pass); } break; @@ -149,51 +163,138 @@ static void for (fa = c->ext.forall_iterator; fa; fa = fa->next) { - optimize_expr_0 (fa->start); - optimize_expr_0 (fa->end); - optimize_expr_0 (fa->stride); + pass->process_expr (fa->start); + pass->process_expr (fa->end); + pass->process_expr (fa->stride); } - if (c->expr1 != NULL) - optimize_expr_0 (c->expr1); + pass->process_expr (c->expr1); + process_code (c->block->next, pass); - optimize_code (c->block->next); - break; case EXEC_CRITICAL: - optimize_code (c->block->next); + process_code (c->block->next, pass); break; case EXEC_DO: - optimize_expr_0 (c->ext.iterator->start); - optimize_expr_0 (c->ext.iterator->end); - optimize_expr_0 (c->ext.iterator->step); - optimize_code (c->block->next); - + pass->process_expr (c->ext.iterator->start); + pass->process_expr (c->ext.iterator->end); + pass->process_expr (c->ext.iterator->step); + process_code (c->block->next, pass); break; case EXEC_DO_WHILE: - optimize_expr_0 (c->expr1); - optimize_code (c->block->next); + pass->process_expr (c->expr1); + process_code (c->block->next, pass); break; case EXEC_ALLOCATE: for (a = c->ext.alloc.list; a; a = a->next) - optimize_expr_0 (a->expr); + pass->process_expr (a->expr); break; - /* Todo: Some of these may need to be optimized, as well. */ case EXEC_WRITE: case EXEC_READ: + pass->process_expr (c->ext.dt->io_unit); + pass->process_expr (c->ext.dt->format_expr); + pass->process_expr (c->ext.dt->rec); + pass->process_expr (c->ext.dt->advance); + pass->process_expr (c->ext.dt->iostat); + pass->process_expr (c->ext.dt->size); + pass->process_expr (c->ext.dt->iomsg); + pass->process_expr (c->ext.dt->id); + pass->process_expr (c->ext.dt->pos); + pass->process_expr (c->ext.dt->asynchronous); + pass->process_expr (c->ext.dt->blank); + pass->process_expr (c->ext.dt->decimal); + pass->process_expr (c->ext.dt->delim); + pass->process_expr (c->ext.dt->pad); + pass->process_expr (c->ext.dt->round); + pass->process_expr (c->ext.dt->sign); + pass->process_expr (c->ext.dt->extra_comma); + break; + case EXEC_OPEN: + pass->process_expr (c->ext.open->unit); + pass->process_expr (c->ext.open->file); + pass->process_expr (c->ext.open->status); + pass->process_expr (c->ext.open->access); + pass->process_expr (c->ext.open->form); + pass->process_expr (c->ext.open->recl); + pass->process_expr (c->ext.open->blank); + pass->process_expr (c->ext.open->position); + pass->process_expr (c->ext.open->action); + pass->process_expr (c->ext.open->delim); + pass->process_expr (c->ext.open->pad); + pass->process_expr (c->ext.open->iostat); + pass->process_expr (c->ext.open->iomsg); + pass->process_expr (c->ext.open->convert); + pass->process_expr (c->ext.open->decimal); + pass->process_expr (c->ext.open->encoding); + pass->process_expr (c->ext.open->round); + pass->process_expr (c->ext.open->sign); + pass->process_expr (c->ext.open->asynchronous); + pass->process_expr (c->ext.open->id); + pass->process_expr (c->ext.open->newunit); + break; + case EXEC_INQUIRE: + pass->process_expr (c->ext.inquire->unit); + pass->process_expr (c->ext.inquire->file); + pass->process_expr (c->ext.inquire->iomsg); + pass->process_expr (c->ext.inquire->iostat); + pass->process_expr (c->ext.inquire->exist); + pass->process_expr (c->ext.inquire->opened); + pass->process_expr (c->ext.inquire->number); + pass->process_expr (c->ext.inquire->named); + pass->process_expr (c->ext.inquire->name); + pass->process_expr (c->ext.inquire->access); + pass->process_expr (c->ext.inquire->sequential); + pass->process_expr (c->ext.inquire->direct); + pass->process_expr (c->ext.inquire->form); + pass->process_expr (c->ext.inquire->formatted); + pass->process_expr (c->ext.inquire->unformatted); + pass->process_expr (c->ext.inquire->recl); + pass->process_expr (c->ext.inquire->nextrec); + pass->process_expr (c->ext.inquire->blank); + pass->process_expr (c->ext.inquire->position); + pass->process_expr (c->ext.inquire->action); + pass->process_expr (c->ext.inquire->read); + pass->process_expr (c->ext.inquire->write); + pass->process_expr (c->ext.inquire->readwrite); + pass->process_expr (c->ext.inquire->delim); + pass->process_expr (c->ext.inquire->encoding); + pass->process_expr (c->ext.inquire->pad); + pass->process_expr (c->ext.inquire->iolength); + pass->process_expr (c->ext.inquire->convert); + pass->process_expr (c->ext.inquire->strm_pos); + pass->process_expr (c->ext.inquire->asynchronous); + pass->process_expr (c->ext.inquire->decimal); + pass->process_expr (c->ext.inquire->pending); + pass->process_expr (c->ext.inquire->id); + pass->process_expr (c->ext.inquire->sign); + pass->process_expr (c->ext.inquire->size); + pass->process_expr (c->ext.inquire->round); + break; + case EXEC_REWIND: case EXEC_ENDFILE: case EXEC_BACKSPACE: case EXEC_CLOSE: case EXEC_WAIT: + pass->process_expr (c->ext.wait->unit); + pass->process_expr (c->ext.wait->iostat); + pass->process_expr (c->ext.wait->iomsg); + pass->process_expr (c->ext.wait->id); + break; + + case EXEC_POINTER_ASSIGN: + if (pass->process_pointer_assign) + pass->process_pointer_assign (c); + break; + case EXEC_TRANSFER: case EXEC_FLUSH: case EXEC_IOLENGTH: @@ -203,7 +304,6 @@ static void case EXEC_ENTRY: case EXEC_INIT_ASSIGN: case EXEC_LABEL_ASSIGN: - case EXEC_POINTER_ASSIGN: case EXEC_GOTO: case EXEC_CYCLE: case EXEC_EXIT: @@ -228,9 +328,11 @@ static void case EXEC_OMP_END_NOWAIT: case EXEC_OMP_END_SINGLE: case EXEC_DEALLOCATE: + break; + case EXEC_DT_END: for (d = c->block; d; d = d->block) - optimize_code (d->next); + process_code (d->next, pass); break; default: @@ -338,7 +440,7 @@ optimize_assignment (gfc_code * c) optimize_binop_array_assignment (c, &rhs, false); /* If we insert a statement after the current one, the surrounding loop in - optimize_code will call optimize_assignment on the inserted statement + process_code will call optimize_assignment on the inserted statement anyway, so there is no need to call optimize_assignment again. */ /* All direct optimizations have been done. Now it's time @@ -382,6 +484,9 @@ strip_function_call (gfc_expr *e) static void optimize_expr_0 (gfc_expr * e) { + if (e == NULL) + return; + if (optimize_expr (e)) gfc_simplify_expr (e, 0); @@ -389,7 +494,7 @@ optimize_expr_0 (gfc_expr * e) } /* Recursive optimization of expressions. - TODO: Make this handle many more things. */ + TODO: Make this handle many more things. */ static bool optimize_expr (gfc_expr *e)