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)
