OSDN Git Service

* tree-cfg.c (tree_split_edge): Speed up by using find_edge.
[pf3gnuchains/gcc-fork.git] / gcc / c-gimplify.c
index 3597331..d77d75c 100644 (file)
@@ -84,8 +84,7 @@ static struct c_gimplify_ctx
 static void
 push_context (void)
 {
-  if (ctxp)
-    abort ();
+  gcc_assert (!ctxp);
   ctxp = (struct c_gimplify_ctx *) xcalloc (1, sizeof (struct c_gimplify_ctx));
   ctxp->bc_id[bc_continue] = get_identifier ("continue");
   ctxp->bc_id[bc_break] = get_identifier ("break");
@@ -94,8 +93,7 @@ push_context (void)
 static void
 pop_context (void)
 {
-  if (!ctxp || ctxp->current_bc_label)
-    abort ();
+  gcc_assert (ctxp && !ctxp->current_bc_label);
   free (ctxp);
   ctxp = NULL;
 }
@@ -196,7 +194,7 @@ c_build_bind_expr (tree block, tree body)
     body = build_empty_stmt ();
   if (decls || block)
     {
-      bind = build (BIND_EXPR, void_type_node, decls, body, block);
+      bind = build3 (BIND_EXPR, void_type_node, decls, body, block);
       TREE_SIDE_EFFECTS (bind) = 1;
     }
   else
@@ -243,7 +241,7 @@ gimplify_expr_stmt (tree *stmt_p)
     }
 
   if (stmt == NULL_TREE)
-    stmt = build_empty_stmt ();
+    stmt = alloc_stmt_list ();
 
   *stmt_p = stmt;
 
@@ -275,8 +273,7 @@ begin_bc_block (enum bc_t bc)
 static tree
 finish_bc_block (tree label, tree body)
 {
-  if (label != ctxp->current_bc_label)
-    abort ();
+  gcc_assert (label == ctxp->current_bc_label);
 
   if (TREE_USED (label))
     {
@@ -365,7 +362,7 @@ gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
       if (cond)
        {
          t = build_bc_goto (bc_break);
-         exit = build (COND_EXPR, void_type_node, cond, exit, t);
+         exit = build3 (COND_EXPR, void_type_node, cond, exit, t);
          exit = fold (exit);
          gimplify_stmt (&exit);
        }
@@ -411,10 +408,8 @@ gimplify_for_stmt (tree *stmt_p, tree *pre_p)
   tree stmt = *stmt_p;
 
   if (FOR_INIT_STMT (stmt))
-    {
-      gimplify_stmt (&FOR_INIT_STMT (stmt));
-      append_to_statement_list (FOR_INIT_STMT (stmt), pre_p);
-    }
+    gimplify_and_add (FOR_INIT_STMT (stmt), pre_p);
+
   *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
                             FOR_EXPR (stmt), 1);
 
@@ -458,112 +453,26 @@ gimplify_switch_stmt (tree *stmt_p)
   if (!body)
     body = build_empty_stmt ();
 
-  *stmt_p = build (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
-                  body, NULL_TREE);
-  annotate_with_locus (*stmt_p, stmt_locus);
+  *stmt_p = build3 (SWITCH_EXPR, SWITCH_TYPE (stmt), SWITCH_COND (stmt),
+                   body, NULL_TREE);
+  SET_EXPR_LOCATION (*stmt_p, stmt_locus);
   gimplify_stmt (stmt_p);
 
   *stmt_p = finish_bc_block (break_block, *stmt_p);
   return GS_ALL_DONE;
 }
 
-/* Gimplifies a DECL_STMT node *STMT_P by making any necessary allocation
-   and initialization explicit.  */
-
-static enum gimplify_status
-gimplify_decl_stmt (tree *stmt_p)
-{
-  tree stmt = *stmt_p;
-  tree decl = DECL_STMT_DECL (stmt);
-  tree pre = NULL_TREE;
-  tree post = NULL_TREE;
-
-  if (TREE_TYPE (decl) == error_mark_node)
-    {
-      *stmt_p = NULL;
-      return GS_ERROR;
-    }
-    
-  if (TREE_CODE (decl) == TYPE_DECL)
-    {
-      tree type = TREE_TYPE (decl);
-      if (TYPE_SIZE_UNIT (type)
-          && !TREE_CONSTANT (TYPE_SIZE_UNIT (type)))
-        {
-          /* This is a variable-sized array type.  Simplify its size.  */
-          tree temp = TYPE_SIZE_UNIT (type);
-          gimplify_expr (&temp, &pre, &post, is_gimple_val, fb_rvalue);
-        }
-    }
-
-  if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
-    {
-      tree init = DECL_INITIAL (decl);
-
-      if (!TREE_CONSTANT (DECL_SIZE (decl)))
-       {
-         tree pt_type = build_pointer_type (TREE_TYPE (decl));
-         tree alloc, size;
-
-         /* This is a variable-sized decl.  Simplify its size and mark it
-            for deferred expansion.  Note that mudflap depends on the format
-            of the emitted code: see mx_register_decls().  */
-
-         size = get_initialized_tmp_var (DECL_SIZE_UNIT (decl), &pre, &post);
-         DECL_DEFER_OUTPUT (decl) = 1;
-         alloc = build_function_call_expr
-           (implicit_built_in_decls[BUILT_IN_STACK_ALLOC],
-            tree_cons (NULL_TREE,
-                       build1 (ADDR_EXPR, pt_type, decl),
-                       tree_cons (NULL_TREE, size, NULL_TREE)));
-         append_to_compound_expr (alloc, &pre);
-       }
-
-      if (init && init != error_mark_node)
-       {
-         if (!TREE_STATIC (decl))
-           {
-              /* Do not warn about int x = x; as it is a GCC extension
-                 to turn off this warning but only if warn_init_self
-                is zero.  */
-              if (init == decl && !warn_init_self)
-                TREE_NO_WARNING (decl) = 1;
-              
-             DECL_INITIAL (decl) = NULL_TREE;
-             init = build (MODIFY_EXPR, void_type_node, decl, init);
-             append_to_compound_expr (init, &pre);
-           }
-         else
-           {
-             /* We must still examine initializers for static variables
-                as they may contain a label address.  */
-             walk_tree (&init, force_labels_r, NULL, NULL);
-           }
-       }
-
-      /* This decl isn't mentioned in the enclosing block, so add it to the
-        list of temps.  FIXME it seems a bit of a kludge to say that
-        anonymous artificial vars aren't pushed, but everything else is.  */
-      if (DECL_ARTIFICIAL (decl) && DECL_NAME (decl) == NULL_TREE)
-       gimple_add_tmp_var (decl);
-    }
-
-  append_to_compound_expr (post, &pre);
-  *stmt_p = pre;
-  return GS_OK;
-}
-
 /* Gimplification of expression trees.  */
 
 /* Gimplify a C99 compound literal expression.  This just means adding the
-   DECL_STMT before the current EXPR_STMT and using its anonymous decl
+   DECL_EXPR before the current EXPR_STMT and using its anonymous decl
    instead.  */
 
 static enum gimplify_status
-gimplify_compound_literal_expr (tree *expr_p)
+gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
 {
   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
-  tree decl = DECL_STMT_DECL (decl_s);
+  tree decl = DECL_EXPR_DECL (decl_s);
 
   /* This decl isn't mentioned in the enclosing block, so add it to the
      list of temps.  FIXME it seems a bit of a kludge to say that
@@ -571,8 +480,8 @@ gimplify_compound_literal_expr (tree *expr_p)
   if (DECL_NAME (decl) == NULL_TREE)
     gimple_add_tmp_var (decl);
 
-  gimplify_decl_stmt (&decl_s);
-  *expr_p = decl_s ? decl_s : decl;
+  gimplify_and_add (decl_s, pre_p);
+  *expr_p = decl;
   return GS_OK;
 }
 
@@ -585,8 +494,21 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
 
   switch (code)
     {
+    case DECL_EXPR:
+      /* This is handled mostly by gimplify.c, but we have to deal with
+        not warning about int x = x; as it is a GCC extension to turn off
+        this warning but only if warn_init_self is zero.  */
+      if (TREE_CODE (DECL_EXPR_DECL (*expr_p)) == VAR_DECL
+         && !DECL_EXTERNAL (DECL_EXPR_DECL (*expr_p))
+         && !TREE_STATIC (DECL_EXPR_DECL (*expr_p))
+         && (DECL_INITIAL (DECL_EXPR_DECL (*expr_p))
+             == DECL_EXPR_DECL (*expr_p))
+         && !warn_init_self)
+       TREE_NO_WARNING (DECL_EXPR_DECL (*expr_p)) = 1;
+      return GS_UNHANDLED;
+      
     case COMPOUND_LITERAL_EXPR:
-      return gimplify_compound_literal_expr (expr_p);
+      return gimplify_compound_literal_expr (expr_p, pre_p);
 
     case FOR_STMT:
       return gimplify_for_stmt (expr_p, pre_p);
@@ -603,9 +525,6 @@ c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
     case EXPR_STMT:
       return gimplify_expr_stmt (expr_p);
 
-    case DECL_STMT:
-      return gimplify_decl_stmt (expr_p);
-
     case CONTINUE_STMT:
       *expr_p = build_bc_goto (bc_continue);
       return GS_ALL_DONE;