OSDN Git Service

2005-01-08 Jeff Law <law@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / gimple-low.c
index 67b7f2d..d86cc00 100644 (file)
@@ -69,8 +69,7 @@ lower_function_body (void)
   tree_stmt_iterator i;
   tree t, x;
 
-  if (TREE_CODE (bind) != BIND_EXPR)
-    abort ();
+  gcc_assert (TREE_CODE (bind) == BIND_EXPR);
 
   data.block = DECL_INITIAL (current_function_decl);
   BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
@@ -117,14 +116,11 @@ lower_function_body (void)
       tsi_link_after (&i, x, TSI_CONTINUE_LINKING);
     }
 
-  if (data.block != DECL_INITIAL (current_function_decl))
-    abort ();
+  gcc_assert (data.block == DECL_INITIAL (current_function_decl));
   BLOCK_SUBBLOCKS (data.block)
     = blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
 
   clear_block_marks (data.block);
-
-  reset_block_changes ();
 }
 
 struct tree_opt_pass pass_lower_cf = 
@@ -140,7 +136,8 @@ struct tree_opt_pass pass_lower_cf =
   PROP_gimple_lcf,                     /* properties_provided */
   PROP_gimple_any,                     /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func                       /* todo_flags_finish */
+  TODO_dump_func,                      /* todo_flags_finish */
+  0                                    /* letter */
 };
 
 
@@ -197,14 +194,16 @@ lower_stmt (tree_stmt_iterator *tsi, struct lower_data *data)
     case CALL_EXPR:
     case GOTO_EXPR:
     case LABEL_EXPR:
-    case VA_ARG_EXPR:
     case SWITCH_EXPR:
       break;
 
     default:
+#ifdef ENABLE_CHECKING
       print_node_brief (stderr, "", stmt, 0);
+      internal_error ("unexpected node");
+#endif
     case COMPOUND_EXPR:
-      abort ();
+      gcc_unreachable ();
     }
 
   tsi_next (tsi);
@@ -226,15 +225,13 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
          /* The outermost block of the original function may not be the
             outermost statement chain of the gimplified function.  So we
             may see the outermost block just inside the function.  */
-         if (new_block != DECL_INITIAL (current_function_decl))
-           abort ();
+         gcc_assert (new_block == DECL_INITIAL (current_function_decl));
          new_block = NULL;
        }
       else
        {
          /* We do not expect to handle duplicate blocks.  */
-         if (TREE_ASM_WRITTEN (new_block))
-           abort ();
+         gcc_assert (!TREE_ASM_WRITTEN (new_block));
          TREE_ASM_WRITTEN (new_block) = 1;
 
          /* Block tree may get clobbered by inlining.  Normally this would
@@ -254,8 +251,7 @@ lower_bind_expr (tree_stmt_iterator *tsi, struct lower_data *data)
 
   if (new_block)
     {
-      if (data->block != new_block)
-       abort ();
+      gcc_assert (data->block == new_block);
 
       BLOCK_SUBBLOCKS (new_block)
        = blocks_nreverse (BLOCK_SUBBLOCKS (new_block));
@@ -478,16 +474,13 @@ expand_var_p (tree var)
   if (TREE_CODE (var) != VAR_DECL)
     return true;
 
-  /* Remove all unused, unaliased temporaries.  Also remove unused, unaliased
-     local variables during highly optimizing compilations.  */
+  /* Leave statics and externals alone.  */
+  if (TREE_STATIC (var) || DECL_EXTERNAL (var))
+    return true;
+
+  /* Remove all unused local variables.  */
   ann = var_ann (var);
-  if (ann
-      && ! ann->may_aliases
-      && ! ann->used
-      && ! ann->has_hidden_use
-      && ! TREE_ADDRESSABLE (var)
-      && ! TREE_THIS_VOLATILE (var)
-      && (DECL_ARTIFICIAL (var) || optimize >= 2))
+  if (!ann || !ann->used)
     return false;
 
   return true;
@@ -499,6 +492,13 @@ static void
 remove_useless_vars (void)
 {
   tree var, *cell;
+  FILE *df = NULL;
+
+  if (dump_file && (dump_flags & TDF_DETAILS))
+    {
+      df = dump_file;
+      fputs ("Discarding as unused:\n", df);
+    }
 
   for (cell = &cfun->unexpanded_var_list; *cell; )
     {
@@ -506,34 +506,83 @@ remove_useless_vars (void)
 
       if (!expand_var_p (var))
        {
+         if (df)
+           {
+             fputs ("  ", df);
+             print_generic_expr (df, var, dump_flags);
+             fputc ('\n', df);
+           }
+
          *cell = TREE_CHAIN (*cell);
          continue;
        }
 
       cell = &TREE_CHAIN (*cell);
     }
-}
 
-/* Expand variables in the unexpanded_var_list.  */
+  if (df)
+    fputc ('\n', df);
+}
 
-void
-expand_used_vars (void)
+struct tree_opt_pass pass_remove_useless_vars = 
 {
-  tree cell;
+  "vars",                              /* name */
+  NULL,                                        /* gate */
+  remove_useless_vars,                 /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  0,                                   /* tv_id */
+  0,                                   /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_dump_func,                      /* todo_flags_finish */
+  0                                    /* letter */
+};
 
-  cfun->unexpanded_var_list = nreverse (cfun->unexpanded_var_list);
+/* Mark BLOCK used if it has a used variable in it, then recurse over its
+   subblocks.  */
 
-  for (cell = cfun->unexpanded_var_list; cell; cell = TREE_CHAIN (cell))
-    expand_var (TREE_VALUE (cell));
+static void
+mark_blocks_with_used_vars (tree block)
+{
+  tree var;
+  tree subblock;
 
-  cfun->unexpanded_var_list = NULL_TREE;
+  if (!TREE_USED (block))
+    {
+      for (var = BLOCK_VARS (block);
+          var;
+          var = TREE_CHAIN (var))
+       {
+         if (TREE_USED (var))
+           {
+             TREE_USED (block) = true;
+             break;
+           }
+       }
+    }
+  for (subblock = BLOCK_SUBBLOCKS (block);
+       subblock;
+       subblock = BLOCK_CHAIN (subblock))
+    mark_blocks_with_used_vars (subblock);
 }
 
-struct tree_opt_pass pass_remove_useless_vars = 
+/* Mark the used attribute on blocks correctly.  */
+  
+static void
+mark_used_blocks (void)
+{  
+  mark_blocks_with_used_vars (DECL_INITIAL (current_function_decl));
+}
+
+
+struct tree_opt_pass pass_mark_used_blocks = 
 {
-  "vars",                              /* name */
+  "blocks",                            /* name */
   NULL,                                        /* gate */
-  remove_useless_vars,                 /* execute */
+  mark_used_blocks,                    /* execute */
   NULL,                                        /* sub */
   NULL,                                        /* next */
   0,                                   /* static_pass_number */
@@ -542,5 +591,6 @@ struct tree_opt_pass pass_remove_useless_vars =
   0,                                   /* properties_provided */
   0,                                   /* properties_destroyed */
   0,                                   /* todo_flags_start */
-  TODO_dump_func                       /* todo_flags_finish */
+  TODO_dump_func,                      /* todo_flags_finish */
+  0                                    /* letter */
 };