tree-gimple.c: Rename from tree-simple.c.
authorDiego Novillo <dnovillo@redhat.com>
Fri, 14 May 2004 02:29:32 +0000 (02:29 +0000)
committerDiego Novillo <dnovillo@gcc.gnu.org>
Fri, 14 May 2004 02:29:32 +0000 (22:29 -0400)
* tree-gimple.c: Rename from tree-simple.c.
* tree-gimple.h: Rename from tree-simple.h.
* c-gimplify.c: Rename from c-simplify.c
* Makefile.in, c-decl.c, gimple-low.c, gimplify.c,
langhooks.c, tree-alias-ander.c, tree-alias-common.c,
tree-complex.c, tree-dfa.c, tree-flow.h, tree-inline.c,
tree-into-ssa.c, tree-iterator.c, tree-mudflap.c,
tree-nested.c, tree-nomudflap.c, tree-outof-ssa.c, tree-sra.c,
tree-ssa-alias.c, tree-ssa-ccp.c, tree-ssa-copyrename.c,
tree-ssa-dce.c, tree-ssa-live.c, tree-ssa-pre.c, tree-ssa.c:
Update.

cp/ChangeLog

* cp-gimplify.c: Rename from cp-simplify.c.
* Make-lang.in, optimize.c: Update.

fortran/ChangeLog

* Make-lang.in, f95-lang.c, trans-array.c, trans-decl.c,
trans-expr.c, trans-intrinsic.c, trans-io.c, trans-stmt.c,
trans.c: Rename tree-simple.[ch] to tree-gimple.[ch].

java/ChangeLog

* Make-lang.in, expr.c, java-gimplify.c: Rename
tree-simple.[ch] to tree-gimple.[ch].

From-SVN: r81829

51 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/c-decl.c
gcc/c-gimplify.c [new file with mode: 0644]
gcc/c-simplify.c [deleted file]
gcc/cp/ChangeLog
gcc/cp/Make-lang.in
gcc/cp/cp-gimplify.c [new file with mode: 0644]
gcc/cp/cp-simplify.c [deleted file]
gcc/cp/optimize.c
gcc/fortran/ChangeLog
gcc/fortran/Make-lang.in
gcc/fortran/f95-lang.c
gcc/fortran/trans-array.c
gcc/fortran/trans-decl.c
gcc/fortran/trans-expr.c
gcc/fortran/trans-intrinsic.c
gcc/fortran/trans-io.c
gcc/fortran/trans-stmt.c
gcc/fortran/trans.c
gcc/gimple-low.c
gcc/gimplify.c
gcc/java/ChangeLog
gcc/java/Make-lang.in
gcc/java/expr.c
gcc/java/java-gimplify.c
gcc/langhooks.c
gcc/tree-alias-ander.c
gcc/tree-alias-common.c
gcc/tree-complex.c
gcc/tree-dfa.c
gcc/tree-flow.h
gcc/tree-gimple.c [new file with mode: 0644]
gcc/tree-gimple.h [new file with mode: 0644]
gcc/tree-inline.c
gcc/tree-into-ssa.c
gcc/tree-iterator.c
gcc/tree-mudflap.c
gcc/tree-nested.c
gcc/tree-nomudflap.c
gcc/tree-outof-ssa.c
gcc/tree-simple.c [deleted file]
gcc/tree-simple.h [deleted file]
gcc/tree-sra.c
gcc/tree-ssa-alias.c
gcc/tree-ssa-ccp.c
gcc/tree-ssa-copyrename.c
gcc/tree-ssa-dce.c
gcc/tree-ssa-live.c
gcc/tree-ssa-pre.c
gcc/tree-ssa.c

index 28ff3c0cd88cc79173ad39c12f8b04b7860a7694..433d599a6cdd493c68c6abd3debe274ce6265525 100644 (file)
@@ -1,3 +1,17 @@
+2004-05-13  Diego Novillo  <dnovillo@redhat.com>
+
+       * tree-gimple.c: Rename from tree-simple.c.
+       * tree-gimple.h: Rename from tree-simple.h.
+       * c-gimplify.c: Rename from c-simplify.c
+       * Makefile.in, c-decl.c, gimple-low.c, gimplify.c,
+       langhooks.c, tree-alias-ander.c, tree-alias-common.c,
+       tree-complex.c, tree-dfa.c, tree-flow.h, tree-inline.c,
+       tree-into-ssa.c, tree-iterator.c, tree-mudflap.c,
+       tree-nested.c, tree-nomudflap.c, tree-outof-ssa.c, tree-sra.c,
+       tree-ssa-alias.c, tree-ssa-ccp.c, tree-ssa-copyrename.c,
+       tree-ssa-dce.c, tree-ssa-live.c, tree-ssa-pre.c, tree-ssa.c:
+       Update.
+
 2004-05-14  Ranjit Mathew  <rmathew@hotmail.com>
 
        * doc/sourcebuild.texi: Mention libbanshee and libmudflap.
index bfeaa0c37ca8996da90b6650ca8ac3d1486d837d..5379c8e59d4ef56f5c96ee8b7cf407fb32248375 100644 (file)
@@ -702,9 +702,9 @@ SYSTEM_H = system.h hwint.h $(srcdir)/../include/libiberty.h
 PREDICT_H = predict.h predict.def
 CPPLIB_H = cpplib.h line-map.h
 TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
-TREE_SIMPLE_H = tree-simple.h tree-iterator.h
+TREE_GIMPLE_H = tree-gimple.h tree-iterator.h
 TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
-               bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_SIMPLE_H) \
+               bitmap.h $(BASIC_BLOCK_H) hard-reg-set.h $(TREE_GIMPLE_H) \
                $(HASHTAB_H)
 PRETTY_PRINT_H = pretty-print.h input.h $(OBSTACK_H)
 DIAGNOSTIC_H = diagnostic.h diagnostic.def $(PRETTY_PRINT_H)
@@ -859,7 +859,7 @@ C_AND_OBJC_OBJS = attribs.o c-errors.o c-lex.o c-pragma.o c-decl.o c-typeck.o \
   c-convert.o c-aux-info.o c-common.o c-opts.o c-format.o c-semantics.o \
   c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
   c-objc-common.o c-dump.o c-pch.o $(C_TARGET_OBJS) \
-  c-simplify.o tree-mudflap.o c-mudflap.o c-pretty-print.o
+  c-gimplify.o tree-mudflap.o c-mudflap.o c-pretty-print.o
 
 # Language-specific object files for C.
 C_OBJS = c-parse.o c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
@@ -867,7 +867,7 @@ C_OBJS = c-parse.o c-lang.o stub-objc.o $(C_AND_OBJC_OBJS)
 # Language-independent object files.
 
 OBJS-common = \
- tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-simple.o  \
+ tree-cfg.o tree-dfa.o tree-eh.o tree-ssa.o tree-optimize.o tree-gimple.o  \
  tree-alias-type.o gimplify.o tree-pretty-print.o tree-into-ssa.o          \
  tree-outof-ssa.o tree-alias-common.o tree-ssa-ccp.o                      \
  @ANDER@ tree-ssa-dce.o  tree-ssa-copy.o tree-nrv.o tree-ssa-copyrename.o  \
@@ -1545,7 +1545,7 @@ tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
    $(TREE_H) $(RTL_H) $(EXPR_H) flags.h $(PARAMS_H) input.h insn-config.h \
    $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \
    langhooks.h $(C_COMMON_H) tree-inline.h cgraph.h intl.h function.h \
-   $(TREE_SIMPLE_H)
+   $(TREE_GIMPLE_H)
 print-tree.o : print-tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
    $(GGC_H) langhooks.h real.h
 stor-layout.o : stor-layout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
@@ -1622,9 +1622,9 @@ tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_DUMP_H) diagnostic.h except.h tree-pass.h flags.h langhooks.h
 tree-nested.o: tree-nested.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
    $(RTL_H) $(TM_P_H) function.h tree-dump.h tree-inline.h tree-iterator.h \
-   tree-simple.h cgraph.h $(EXPR_H) langhooks.h $(GGC_H) gt-tree-nested.h
+   tree-gimple.h cgraph.h $(EXPR_H) langhooks.h $(GGC_H) gt-tree-nested.h
 tree-iterator.o : tree-iterator.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
-   coretypes.h $(GGC_H) tree-iterator.h tree-simple.h gt-tree-iterator.h
+   coretypes.h $(GGC_H) tree-iterator.h tree-gimple.h gt-tree-iterator.h
 tree-dfa.o : tree-dfa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) $(GGC_H) output.h diagnostic.h \
    errors.h tree-inline.h $(HASHTAB_H) flags.h function.h $(TIMEVAR_H) \
@@ -1650,32 +1650,32 @@ tree-optimize.o : tree-optimize.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) toplev.h function.h \
    langhooks.h flags.h cgraph.h tree-inline.h tree-mudflap.h $(GGC_H) \
    cgraph.h tree-pass.h
-c-simplify.o : c-simplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
-   $(C_TREE_H) $(C_COMMON_H) diagnostic.h $(TREE_SIMPLE_H) varray.h flags.h \
+c-gimplify.o : c-gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
+   $(C_TREE_H) $(C_COMMON_H) diagnostic.h $(TREE_GIMPLE_H) varray.h flags.h \
    langhooks.h toplev.h rtl.h $(TREE_FLOW_H) langhooks-def.h \
    $(TM_H) coretypes.h $(C_PRETTY_PRINT_H) cgraph.h
 gimplify.o : gimplify.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
-   diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
+   diagnostic.h $(TREE_GIMPLE_H) tree-inline.h varray.h langhooks.h \
    langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
    flags.h $(RTL_H) function.h $(EXPR_H) output.h $(GGC_H) gt-gimplify.h
 gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) errors.h \
-   diagnostic.h $(TREE_SIMPLE_H) tree-inline.h varray.h langhooks.h \
+   diagnostic.h $(TREE_GIMPLE_H) tree-inline.h varray.h langhooks.h \
    langhooks-def.h $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h except.h \
    flags.h $(RTL_H) function.h tree-pass.h
 tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) errors.h tree-inline.h diagnostic.h $(HASHTAB_H) \
    $(TM_H) coretypes.h
-tree-simple.o : tree-simple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
-       $(RTL_H) $(TREE_SIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H)
+tree-gimple.o : tree-gimple.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(EXPR_H) \
+       $(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H)
 tree-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
-   $(C_TREE_H) $(C_COMMON_H) $(TREE_SIMPLE_H) diagnostic.h $(HASHTAB_H) \
+   $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
    output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h \
    $(TREE_DUMP_H) tree-pass.h
 c-mudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
-   $(C_TREE_H) $(C_COMMON_H) $(TREE_SIMPLE_H) diagnostic.h $(HASHTAB_H) \
+   $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
    output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
 tree-nomudflap.o : $(CONFIG_H) errors.h $(SYSTEM_H) $(TREE_H) tree-inline.h \
-   $(C_TREE_H) $(C_COMMON_H) $(TREE_SIMPLE_H) diagnostic.h $(HASHTAB_H) \
+   $(C_TREE_H) $(C_COMMON_H) $(TREE_GIMPLE_H) diagnostic.h $(HASHTAB_H) \
    output.h varray.h langhooks.h tree-mudflap.h $(TM_H) coretypes.h
 tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    errors.h $(TREE_H) diagnostic.h real.h $(HASHTAB_H) $(TREE_FLOW_H) \
@@ -1850,14 +1850,14 @@ tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) system.h errors.h $(TREE_H) \
     coretypes.h $(TREE_DUMP_H) tree-pass.h flags.h
 tree-ssa-ccp.o : tree-ssa-ccp.c $(CONFIG_H) system.h errors.h $(TREE_H) \
     $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) diagnostic.h tree-inline.h \
-    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SIMPLE_H) \
+    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
     $(EXPR_H) tree-pass.h flags.h langhooks.h
 tree-sra.o : tree-sra.c $(CONFIG_H) system.h errors.h $(TREE_H) $(RTL_H) \
     $(TM_P_H) $(TREE_FLOW_H) diagnostic.h tree-inline.h \
-    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_SIMPLE_H) \
+    $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_GIMPLE_H) \
     langhooks.h tree-pass.h flags.h
 tree-complex.o : tree-complex.c $(CONFIG_H) system.h $(TREE_H) \
-    $(TM_H) $(TREE_FLOW_H) $(TREE_SIMPLE_H) tree-iterator.h tree-pass.h \
+    $(TM_H) $(TREE_FLOW_H) $(TREE_GIMPLE_H) tree-iterator.h tree-pass.h \
     flags.h
 df.o : df.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
    insn-config.h $(RECOG_H) function.h $(REGS_H) alloc-pool.h hard-reg-set.h \
index d0fc708ea052911298fce3be2d238d95650d0611..8ca5b086ca2416799a30cd41dbb6e535a72b63a8 100644 (file)
@@ -51,7 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "c-pragma.h"
 #include "langhooks.h"
 #include "tree-mudflap.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "diagnostic.h"
 #include "tree-dump.h"
 #include "cgraph.h"
diff --git a/gcc/c-gimplify.c b/gcc/c-gimplify.c
new file mode 100644 (file)
index 0000000..49b3a67
--- /dev/null
@@ -0,0 +1,1102 @@
+/* Tree lowering pass.  This pass gimplifies the tree representation built
+   by the C-based front ends.  The structure of gimplified, or
+   language-independent, trees is dictated by the grammar described in this
+   file.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
+   Re-written to support lowering of whole function trees, documentation
+   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
+
+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 2, 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 COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "errors.h"
+#include "varray.h"
+#include "c-tree.h"
+#include "c-common.h"
+#include "tree-gimple.h"
+#include "hard-reg-set.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "tree-inline.h"
+#include "diagnostic.h"
+#include "langhooks.h"
+#include "langhooks-def.h"
+#include "flags.h"
+#include "rtl.h"
+#include "toplev.h"
+#include "tree-dump.h"
+#include "c-pretty-print.h"
+#include "cgraph.h"
+
+
+/*  The gimplification pass converts the language-dependent trees
+    (ld-trees) emitted by the parser into language-independent trees
+    (li-trees) that are the target of SSA analysis and transformations.
+
+    Language-independent trees are based on the SIMPLE intermediate
+    representation used in the McCAT compiler framework:
+
+    "Designing the McCAT Compiler Based on a Family of Structured
+    Intermediate Representations,"
+    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
+    Proceedings of the 5th International Workshop on Languages and
+    Compilers for Parallel Computing, no. 757 in Lecture Notes in
+    Computer Science, New Haven, Connecticut, pp. 406-420,
+    Springer-Verlag, August 3-5, 1992.
+
+    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
+
+    Basically, we walk down gimplifying the nodes that we encounter.  As we
+    walk back up, we check that they fit our constraints, and copy them
+    into temporaries if not.  */
+
+/* Local declarations.  */
+
+static enum gimplify_status gimplify_expr_stmt (tree *);
+static enum gimplify_status gimplify_decl_stmt (tree *);
+static enum gimplify_status gimplify_for_stmt (tree *, tree *);
+static enum gimplify_status gimplify_while_stmt (tree *);
+static enum gimplify_status gimplify_do_stmt (tree *);
+static enum gimplify_status gimplify_if_stmt (tree *);
+static enum gimplify_status gimplify_switch_stmt (tree *);
+static enum gimplify_status gimplify_return_stmt (tree *);
+static enum gimplify_status gimplify_stmt_expr (tree *);
+static enum gimplify_status gimplify_compound_literal_expr (tree *);
+#if defined ENABLE_CHECKING
+static int is_last_stmt_of_scope (tree);
+#endif
+static enum gimplify_status gimplify_block (tree *, tree *);
+static enum gimplify_status gimplify_cleanup (tree *, tree *);
+static tree gimplify_c_loop (tree, tree, tree, bool);
+static void push_context (void);
+static void pop_context (void);
+static tree c_build_bind_expr (tree, tree);
+static void add_block_to_enclosing (tree);
+static void gimplify_condition (tree *);
+
+enum bc_t { bc_break = 0, bc_continue = 1 };
+static tree begin_bc_block (enum bc_t);
+static tree finish_bc_block (tree, tree);
+static tree build_bc_goto (enum bc_t);
+
+static struct c_gimplify_ctx
+{
+  /* For handling break and continue.  */
+  tree current_bc_label;
+  tree bc_id[2];
+} *ctxp;
+
+static void
+push_context (void)
+{
+  if (ctxp)
+    abort ();
+  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");
+}
+
+static void
+pop_context (void)
+{
+  if (!ctxp || ctxp->current_bc_label)
+    abort ();
+  free (ctxp);
+  ctxp = NULL;
+}
+
+/* Gimplification of statement trees.  */
+
+/* Convert the tree representation of FNDECL from C frontend trees to
+   GENERIC.  */
+
+void
+c_genericize (tree fndecl)
+{
+  FILE *dump_file;
+  int local_dump_flags;
+  struct cgraph_node *cgn;
+
+  /* Dump the C-specific tree IR.  */
+  dump_file = dump_begin (TDI_original, &local_dump_flags);
+  if (dump_file)
+    {
+      fprintf (dump_file, "\n;; Function %s",
+              (*lang_hooks.decl_printable_name) (fndecl, 2));
+      fprintf (dump_file, " (%s)\n",
+              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
+      fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
+      fprintf (dump_file, "\n");
+
+      if (local_dump_flags & TDF_RAW)
+       dump_node (DECL_SAVED_TREE (fndecl),
+                  TDF_SLIM | local_dump_flags, dump_file);
+      else
+       print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
+      fprintf (dump_file, "\n");
+
+      dump_end (TDI_original, dump_file);
+    }
+
+  /* Go ahead and gimplify for now.  */
+  push_context ();
+  gimplify_function_tree (fndecl);
+  pop_context ();
+
+  /* Dump the genericized tree IR.  */
+  dump_function (TDI_generic, fndecl);
+
+  /* Genericize all nested functions now.  We do things in this order so
+     that items like VLA sizes are expanded properly in the context of
+     the correct function.  */
+  cgn = cgraph_node (fndecl);
+  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
+    c_genericize (cgn->decl);
+}
+
+/*  Entry point for the tree lowering pass.  Recursively scan
+    *STMT_P and convert it to a GIMPLE tree.  */
+
+int
+c_gimplify_stmt (tree *stmt_p)
+{
+  tree stmt, next;
+  tree outer_pre = NULL_TREE;
+
+  /* PRE and POST are tree chains that contain the side-effects of the
+     gimplified tree.  For instance, given the expression tree:
+
+               c = ++a * 3 + b++;
+
+     After gimplification, the tree will be re-written as:
+
+               a = a + 1;
+               t1 = a * 3;     <-- PRE
+               c = t1 + b;
+               b = b + 1;      <-- POST  */
+
+  for (stmt = *stmt_p; stmt && stmt != error_mark_node; stmt = next)
+    {
+      tree pre, post;
+      int saved_stmts_are_full_exprs_p;
+      location_t stmt_locus;
+      enum gimplify_status ret;
+
+      /* Set up context appropriately for handling this statement.  */
+      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
+      prep_stmt (stmt);
+      stmt_locus = input_location;
+
+      pre = NULL_TREE;
+      post = NULL_TREE;
+
+      next = TREE_CHAIN (stmt);
+
+      switch (TREE_CODE (stmt))
+       {
+       case COMPOUND_STMT:
+         stmt = COMPOUND_BODY (stmt);
+         ret = GS_OK;
+         break;
+
+       case SCOPE_STMT:
+         ret = gimplify_block (&stmt, &next);
+         break;
+
+       case FOR_STMT:
+         ret = gimplify_for_stmt (&stmt, &next);
+         break;
+
+       case WHILE_STMT:
+         ret = gimplify_while_stmt (&stmt);
+         break;
+
+       case DO_STMT:
+         ret = gimplify_do_stmt (&stmt);
+         break;
+
+       case IF_STMT:
+         ret = gimplify_if_stmt (&stmt);
+         break;
+
+       case SWITCH_STMT:
+         ret = gimplify_switch_stmt (&stmt);
+         break;
+
+       case EXPR_STMT:
+         ret = gimplify_expr_stmt (&stmt);
+         break;
+
+       case RETURN_STMT:
+         ret = gimplify_return_stmt (&stmt);
+         break;
+
+       case DECL_STMT:
+         ret = gimplify_decl_stmt (&stmt);
+         break;
+
+       case LABEL_STMT:
+         stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
+         ret = GS_OK;
+         break;
+
+       case GOTO_STMT:
+         stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
+         ret = GS_OK;
+         break;
+
+       case CASE_LABEL:
+         {
+           tree label = create_artificial_label ();
+           stmt = build (CASE_LABEL_EXPR, void_type_node,
+                         CASE_LOW (stmt), CASE_HIGH (stmt), label);
+           ret = GS_OK;
+         }
+         break;
+
+       case CONTINUE_STMT:
+         stmt = build_bc_goto (bc_continue);
+         ret = GS_OK;
+         break;
+
+       case BREAK_STMT:
+         stmt = build_bc_goto (bc_break);
+         ret = GS_OK;
+         break;
+
+       case CLEANUP_STMT:
+         ret = gimplify_cleanup (&stmt, &next);
+         break;
+
+       case ASM_STMT:
+         {
+           tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
+                                  ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
+                                  ASM_CLOBBERS (stmt));
+           ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
+           ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
+           stmt = new_stmt;
+           ret = GS_OK;
+         }
+         break;
+
+       default:
+         if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
+           {
+             ret = GS_OK;
+             break;
+           }
+
+         fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
+         debug_tree (stmt);
+         abort ();
+         break;
+       }
+
+      switch (ret)
+       {
+       case GS_ERROR:
+         goto cont;
+       case GS_OK:
+          gimplify_stmt (&stmt);
+         break;
+       case GS_ALL_DONE:
+         break;
+       default:
+         abort ();
+       }
+
+      /* PRE and POST now contain a list of statements for all the
+        side-effects in STMT.  */
+
+      append_to_statement_list (stmt, &pre);
+      append_to_statement_list (post, &pre);
+      annotate_all_with_locus (&pre, stmt_locus);
+
+      append_to_statement_list (pre, &outer_pre);
+    cont:
+      /* Restore saved state.  */
+      current_stmt_tree ()->stmts_are_full_exprs_p
+       = saved_stmts_are_full_exprs_p;
+    }
+  append_to_statement_list (stmt, &outer_pre);
+  *stmt_p = outer_pre;
+
+  return GS_ALL_DONE;
+}
+
+static void
+add_block_to_enclosing (tree block)
+{
+  tree enclosing;
+
+  for (enclosing = gimple_current_bind_expr ();
+       enclosing; enclosing = TREE_CHAIN (enclosing))
+    if (BIND_EXPR_BLOCK (enclosing))
+      break;
+
+  enclosing = BIND_EXPR_BLOCK (enclosing);
+  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
+}
+
+/* Genericize a scope by creating a new BIND_EXPR.
+   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
+     In the latter case, we need to create a new BLOCK and add it to the
+     BLOCK_SUBBLOCKS of the enclosing block.
+   BODY is a chain of C _STMT nodes for the contents of the scope, to be
+     genericized.  */
+
+static tree
+c_build_bind_expr (tree block, tree body)
+{
+  tree decls, bind;
+
+  if (block == NULL_TREE)
+    decls = NULL_TREE;
+  else if (TREE_CODE (block) == BLOCK)
+    decls = BLOCK_VARS (block);
+  else
+    {
+      decls = block;
+      if (DECL_ARTIFICIAL (decls))
+       block = NULL_TREE;
+      else
+       {
+         block = make_node (BLOCK);
+         BLOCK_VARS (block) = decls;
+         add_block_to_enclosing (block);
+       }
+    }
+
+  if (!body)
+    body = build_empty_stmt ();
+
+  bind = build (BIND_EXPR, void_type_node, decls, body, block);
+  TREE_SIDE_EFFECTS (bind) = 1;
+
+  return bind;
+}
+
+/* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
+   wrapping the intervening code in a BIND_EXPR.  This function assumes
+   that matching SCOPE_STMTs will always appear in the same statement
+   sequence.  */
+
+static enum gimplify_status
+gimplify_block (tree *stmt_p, tree *next_p)
+{
+  tree *p;
+  tree block;
+  tree bind;
+  int depth;
+  location_t stmt_locus;
+
+  if (!SCOPE_BEGIN_P (*stmt_p))
+    {
+      /* Can wind up mismatched with syntax errors.  */
+      if (!errorcount && !sorrycount)
+       abort ();
+      *stmt_p = NULL;
+      return GS_ERROR;
+    }
+
+  block = SCOPE_STMT_BLOCK (*stmt_p);
+
+  /* Find the matching ending SCOPE_STMT.  */
+  depth = 1;
+  for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
+    {
+      if (*p == NULL)
+       break;
+      if (TREE_CODE (*p) == SCOPE_STMT)
+       {
+         if (SCOPE_BEGIN_P (*p))
+           ++depth;
+         else if (--depth == 0)
+           break;
+       }
+    }
+
+  stmt_locus = input_location;
+  if (*p)
+    {
+      if (SCOPE_STMT_BLOCK (*p) != block)
+       abort ();
+      if (EXPR_LOCUS (*p))
+       stmt_locus = *EXPR_LOCUS (*p);
+      *next_p = TREE_CHAIN (*p);
+      *p = NULL_TREE;
+    }
+  else
+    {
+      /* Can wind up mismatched with syntax errors.  */
+      if (!errorcount && !sorrycount)
+       abort ();
+    }
+
+  bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
+  *stmt_p = bind;
+  input_location = stmt_locus;
+
+  return GS_OK;
+}
+
+/* Genericize a CLEANUP_STMT.  Just wrap everything from here to the end of
+   the block in a TRY_FINALLY_EXPR.  Or a TRY_CATCH_EXPR, if it's an
+   EH-only cleanup.  */
+
+static enum gimplify_status
+gimplify_cleanup (tree *stmt_p, tree *next_p)
+{
+  tree stmt = *stmt_p;
+  tree body = TREE_CHAIN (stmt);
+  tree cleanup = CLEANUP_EXPR (stmt);
+  enum tree_code code
+    = (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
+
+  if (!body)
+    body = build_empty_stmt ();
+  if (!cleanup)
+    cleanup = build_empty_stmt ();
+
+  *stmt_p = build (code, void_type_node, body, cleanup);
+  *next_p = NULL_TREE;
+
+  return GS_OK;
+}
+
+/*  Gimplify an EXPR_STMT node.
+
+    STMT is the statement node.
+
+    PRE_P points to the list where side effects that must happen before
+       STMT should be stored.
+
+    POST_P points to the list where side effects that must happen after
+       STMT should be stored.  */
+
+static enum gimplify_status
+gimplify_expr_stmt (tree *stmt_p)
+{
+  tree stmt = EXPR_STMT_EXPR (*stmt_p);
+
+  if (stmt == error_mark_node)
+    stmt = NULL;
+
+  /* Gimplification of a statement expression will nullify the
+     statement if all its side effects are moved to *PRE_P and *POST_P.
+
+     In this case we will not want to emit the gimplified statement.
+     However, we may still want to emit a warning, so we do that before
+     gimplification.  */
+  if (stmt && (extra_warnings || warn_unused_value))
+    {
+      if (!TREE_SIDE_EFFECTS (stmt))
+       {
+         if (!IS_EMPTY_STMT (stmt)
+             && !VOID_TYPE_P (TREE_TYPE (stmt))
+             && !TREE_NO_WARNING (stmt))
+           warning ("statement with no effect");
+       }
+      else if (warn_unused_value)
+       {
+         /* Kludge for 20020220-2.c.  warn_if_unused_value shouldn't use
+            the stmt file location info.  */
+         set_file_and_line_for_stmt (input_location);
+         warn_if_unused_value (stmt);
+       }
+    }
+
+  if (stmt == NULL_TREE)
+    stmt = build_empty_stmt ();
+  else if (stmts_are_full_exprs_p ())
+    stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
+
+  *stmt_p = stmt;
+
+  return GS_OK;
+}
+
+/* If the condition for a loop (or the like) is a decl, it will be a
+   TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
+   a use of the decl.  Turn such a thing into a COMPOUND_EXPR.  */
+
+static void
+gimplify_condition (tree *cond_p)
+{
+  tree cond = *cond_p;
+  if (cond && TREE_CODE (cond) == TREE_LIST)
+    {
+      tree decl = TREE_PURPOSE (cond);
+      tree value = TREE_VALUE (cond);
+      c_gimplify_stmt (&decl);
+      *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
+    }
+}
+
+/* Begin a scope which can be exited by a break or continue statement.  BC
+   indicates which.
+
+   Just creates a label and pushes it into the current context.  */
+
+static tree
+begin_bc_block (enum bc_t bc)
+{
+  tree label = create_artificial_label ();
+  DECL_NAME (label) = ctxp->bc_id[bc];
+  TREE_CHAIN (label) = ctxp->current_bc_label;
+  ctxp->current_bc_label = label;
+  return label;
+}
+
+/* Finish a scope which can be exited by a break or continue statement.
+   LABEL was returned from the most recent call to begin_bc_block.  BODY is
+   an expression for the contents of the scope.
+
+   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
+   body.  Otherwise, just forget the label.  */
+
+static tree
+finish_bc_block (tree label, tree body)
+{
+  if (label != ctxp->current_bc_label)
+    abort ();
+
+  if (TREE_USED (label))
+    {
+      tree t, sl = NULL;
+
+      /* Clear the name so flow can delete the label.  */
+      DECL_NAME (label) = NULL_TREE;
+      t = build1 (LABEL_EXPR, void_type_node, label);
+
+      append_to_statement_list (body, &sl);
+      append_to_statement_list (t, &sl);
+      body = sl;
+    }
+
+  ctxp->current_bc_label = TREE_CHAIN (label);
+  TREE_CHAIN (label) = NULL_TREE;
+  return body;
+}
+
+/* Build a GOTO_EXPR to represent a break or continue statement.  BC
+   indicates which.  */
+
+static tree
+build_bc_goto (enum bc_t bc)
+{
+  tree label;
+  tree target_name = ctxp->bc_id[bc];
+
+  /* Look for the appropriate type of label.  */
+  for (label = ctxp->current_bc_label;
+       label;
+       label = TREE_CHAIN (label))
+    if (DECL_NAME (label) == target_name)
+      break;
+
+  if (label == NULL_TREE)
+    {
+      if (bc == bc_break)
+       error ("break statement not within loop or switch");
+      else
+       error ("continue statement not within loop or switch");
+
+      return NULL_TREE;
+    }
+
+  /* Mark the label used for finish_bc_block.  */
+  TREE_USED (label) = 1;
+  return build1 (GOTO_EXPR, void_type_node, label);
+}
+
+/* Build a generic representation of one of the C loop forms.  COND is the
+   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
+   controlled by the loop.  INCR is the increment expression of a for-loop,
+   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
+   evaluated before the loop body as in while and for loops, or after the
+   loop body as in do-while loops.  */
+
+static tree
+gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
+{
+  tree top, entry, exit, cont_block, break_block, stmt_list, t;
+  location_t stmt_locus;
+
+  stmt_locus = input_location;
+
+  /* Detect do { ... } while (0) and don't generate loop construct.  */
+  if (!cond_is_first && cond && integer_zerop (cond))
+    top = cond = NULL;
+  else
+    {
+      /* If we use a LOOP_EXPR here, we have to feed the whole thing
+        back through the main gimplifier to lower it.  Given that we
+        have to gimplify the loop body NOW so that we can resolve
+        break/continue stmts, seems easier to just expand to gotos.  */
+      top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+    }
+
+  break_block = begin_bc_block (bc_break);
+
+  if (top)
+    {
+      /* If we have an exit condition, then we build an IF with gotos either
+        out of the loop, or to the top of it.  If there's no exit condition,
+        then we just build a jump back to the top.  */
+      exit = build_and_jump (&LABEL_EXPR_LABEL (top));
+      if (cond)
+       {
+         gimplify_condition (&cond);
+         t = build_bc_goto (bc_break);
+         exit = build (COND_EXPR, void_type_node, cond, exit, t);
+         exit = fold (exit);
+         gimplify_stmt (&exit);
+       }
+    }
+  else
+    exit = NULL_TREE;
+
+  cont_block = begin_bc_block (bc_continue);
+
+  gimplify_stmt (&body);
+  if (incr && stmts_are_full_exprs_p ())
+    incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
+  gimplify_stmt (&incr);
+
+  body = finish_bc_block (cont_block, body);
+
+  stmt_list = NULL;
+
+  if (cond_is_first && cond)
+    {
+      entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
+      t = build_and_jump (&LABEL_EXPR_LABEL (entry));
+      append_to_statement_list (t, &stmt_list);
+    }
+  else
+    entry = NULL_TREE;
+
+  append_to_statement_list (top, &stmt_list);
+  append_to_statement_list (body, &stmt_list);
+  append_to_statement_list (incr, &stmt_list);
+  append_to_statement_list (entry, &stmt_list);
+  append_to_statement_list (exit, &stmt_list);
+
+  annotate_all_with_locus (&stmt_list, stmt_locus);
+
+  return finish_bc_block (break_block, stmt_list);
+}
+
+/* Gimplify a FOR_STMT node.  Move the stuff in the for-init-stmt into the
+   prequeue and hand off to gimplify_c_loop.  */
+
+static enum gimplify_status
+gimplify_for_stmt (tree *stmt_p, tree *next_p)
+{
+  tree stmt = *stmt_p;
+  tree init = FOR_INIT_STMT (stmt);
+
+  if (init)
+    {
+      /* Reorganize the statements so that we do the right thing with a
+        CLEANUP_STMT.  We want the FOR_STMT and nothing else to be in the
+        scope of the cleanup, so play with pointers to accomplish that. */
+      FOR_INIT_STMT (stmt) = NULL_TREE;
+      chainon (init, stmt);
+      *stmt_p = init;
+      *next_p = TREE_CHAIN (stmt);
+      TREE_CHAIN (stmt) = NULL_TREE;
+      c_gimplify_stmt (stmt_p);
+    }
+  else
+    *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
+                              FOR_EXPR (stmt), 1);
+
+  return GS_ALL_DONE;
+}
+
+/* Gimplify a WHILE_STMT node.  */
+
+static enum gimplify_status
+gimplify_while_stmt (tree *stmt_p)
+{
+  tree stmt = *stmt_p;
+  *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
+                            NULL_TREE, 1);
+  return GS_ALL_DONE;
+}
+
+/* Gimplify a DO_STMT node.  */
+
+static enum gimplify_status
+gimplify_do_stmt (tree *stmt_p)
+{
+  tree stmt = *stmt_p;
+  *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
+                            NULL_TREE, 0);
+  return GS_ALL_DONE;
+}
+
+/* Genericize an IF_STMT by turning it into a COND_EXPR.  */
+
+static enum gimplify_status
+gimplify_if_stmt (tree *stmt_p)
+{
+  tree stmt, then_, else_;
+
+  stmt = *stmt_p;
+ restart:
+  then_ = THEN_CLAUSE (stmt);
+  else_ = ELSE_CLAUSE (stmt);
+
+  if (!then_)
+    then_ = build_empty_stmt ();
+  if (!else_)
+    else_ = build_empty_stmt ();
+
+  stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
+  gimplify_condition (& TREE_OPERAND (stmt, 0));
+  *stmt_p = stmt;
+
+  /* Handle properly nested if-else chains via iteration instead of
+     mutual recursion between gimplify.c and c-simplify.c.  */
+  annotate_with_locus (stmt, input_location);
+  if (TREE_CODE (else_) == IF_STMT && !TREE_CHAIN (else_))
+    {
+      stmt_p = &COND_EXPR_ELSE (stmt);
+      stmt = else_;
+      prep_stmt (stmt);
+      goto restart;
+    }
+
+  return GS_OK;
+}
+
+/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
+
+static enum gimplify_status
+gimplify_switch_stmt (tree *stmt_p)
+{
+  tree stmt = *stmt_p;
+  tree break_block, body;
+  location_t stmt_locus = input_location;
+
+  break_block = begin_bc_block (bc_break);
+
+  gimplify_condition (&SWITCH_COND (stmt));
+
+  body = SWITCH_BODY (stmt);
+  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);
+  gimplify_stmt (stmt_p);
+
+  *stmt_p = finish_bc_block (break_block, *stmt_p);
+  return GS_ALL_DONE;
+}
+
+/* Genericize a RETURN_STMT by turning it into a RETURN_EXPR.  */
+
+static enum gimplify_status
+gimplify_return_stmt (tree *stmt_p)
+{
+  tree expr = RETURN_STMT_EXPR (*stmt_p);
+  expr = build1 (RETURN_EXPR, void_type_node, expr);
+  if (stmts_are_full_exprs_p ())
+    expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
+  *stmt_p = expr;
+  return GS_OK;
+}
+
+/* Gimplifies a DECL_STMT node T.
+
+   If a declaration V has an initial value I, create an expression 'V = I'
+   and insert it after the DECL_STMT.
+
+   PRE_P is a queue for effects that should happen before the DECL_STMT.
+
+   MID_P is a queue for effects that should happen after the DECL_STMT,
+   but before uses of the initialized decl.
+
+   POST_P is a queue for effects that should happen after uses of the
+   initialized decl.
+
+   Usually these last two will be the same, but they may need to be
+   different if the DECL_STMT is somehow embedded in an expression.  */
+
+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);
+             if (stmts_are_full_exprs_p ())
+               init = build1 (CLEANUP_POINT_EXPR, void_type_node, 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
+   instead.  */
+
+static enum gimplify_status
+gimplify_compound_literal_expr (tree *expr_p)
+{
+  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
+  tree decl = DECL_STMT_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
+     anonymous artificial vars aren't pushed, but everything else is.  */
+  if (DECL_NAME (decl) == NULL_TREE)
+    gimple_add_tmp_var (decl);
+
+  gimplify_decl_stmt (&decl_s);
+  *expr_p = decl_s ? decl_s : decl;
+  return GS_OK;
+}
+
+/* Do C-specific gimplification.  Args are as for gimplify_expr.  */
+
+int
+c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
+                tree *post_p ATTRIBUTE_UNUSED)
+{
+  enum tree_code code = TREE_CODE (*expr_p);
+
+  if (STATEMENT_CODE_P (code))
+    return c_gimplify_stmt (expr_p);
+
+  switch (code)
+    {
+    case COMPOUND_LITERAL_EXPR:
+      return gimplify_compound_literal_expr (expr_p);
+
+    case STMT_EXPR:
+      return gimplify_stmt_expr (expr_p);
+
+    default:
+      return GS_UNHANDLED;
+    }
+}
+
+/* Returns the final EXPR_STMT which represents the return value of a
+   STMT_EXPR, or NULL_TREE if none.  */
+
+tree
+stmt_expr_last_stmt (tree stmt_expr)
+{
+  tree body = STMT_EXPR_STMT (stmt_expr);
+  tree last_stmt, substmt;
+
+  /* Splice the last expression out of the STMT chain.  */
+  last_stmt = NULL_TREE;
+  for (substmt = COMPOUND_BODY (body); substmt;
+       substmt = TREE_CHAIN (substmt))
+    if (TREE_CODE (substmt) != SCOPE_STMT)
+      last_stmt = substmt;
+
+  if (last_stmt == NULL_TREE
+      || TREE_CODE (last_stmt) != EXPR_STMT
+      || (TREE_TYPE (last_stmt)
+         && VOID_TYPE_P (TREE_TYPE (last_stmt))))
+    {
+      location_t loc;
+      if (last_stmt && EXPR_LOCUS (last_stmt))
+       loc = *EXPR_LOCUS (last_stmt);
+      else if (EXPR_LOCUS (stmt_expr))
+       loc = *EXPR_LOCUS (stmt_expr);
+      else
+       loc = input_location;
+      warning ("%Hstatement-expressions should end with a "
+              "non-void expression", &loc);
+      last_stmt = NULL_TREE;
+    }
+
+#if defined ENABLE_CHECKING
+  if (last_stmt && !is_last_stmt_of_scope (last_stmt))
+    abort ();
+#endif
+
+  return last_stmt;
+}
+
+/* Gimplify a STMT_EXPR.  EXPR_P points to the expression to gimplify.
+   After gimplification, if the STMT_EXPR returns a value, EXPR_P will
+   point to a new temporary that holds that value; otherwise it will be
+   null.
+
+   PRE_P points to the list where side effects that must happen before
+     *EXPR_P should be stored.  */
+
+static enum gimplify_status
+gimplify_stmt_expr (tree *expr_p)
+{
+  tree body = STMT_EXPR_STMT (*expr_p);
+
+  if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
+    {
+      *expr_p = body;
+      return c_gimplify_stmt (expr_p);
+    }
+  else
+    {
+      tree last_stmt = stmt_expr_last_stmt (*expr_p);
+      tree last_expr = NULL_TREE;
+
+      if (last_stmt)
+       {
+         last_expr = EXPR_STMT_EXPR (last_stmt);
+
+         if (stmts_are_full_exprs_p ())
+           last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
+                               last_expr);
+         EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
+       }
+
+      /* Genericize the block.  */
+      c_gimplify_stmt (&body);
+
+      /* Now retrofit that last expression into the BIND_EXPR.  */
+      if (last_expr)
+       {
+         tree *sub_p;
+
+         if (!STMT_EXPR_NO_SCOPE (*expr_p))
+           {
+             /* Our BIND_EXPR will always be hidden within
+                a STATEMENT_LIST.  Discard that.  */
+             body = expr_first (body);
+             sub_p = &BIND_EXPR_BODY (body);
+
+             /* Append the last expression to the end of the BIND_EXPR.
+                We'll now re-process this, and let voidify_wrapper_expr
+                do its job.  */
+             append_to_statement_list_force (last_expr, sub_p);
+             TREE_TYPE (body) = TREE_TYPE (last_expr);
+           }
+         else
+           append_to_compound_expr (last_expr, &body);
+       }
+
+      *expr_p = body;
+      return GS_OK;
+    }
+}
+
+/* Code generation.  */
+
+/* Miscellaneous helpers.  */
+
+#if defined ENABLE_CHECKING
+/*  Return nonzero if STMT is the last statement of its scope.  */
+
+static int
+is_last_stmt_of_scope (tree stmt)
+{
+  return (TREE_CHAIN (stmt) == NULL_TREE
+         || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
+             && SCOPE_END_P (TREE_CHAIN (stmt))));
+}
+#endif
diff --git a/gcc/c-simplify.c b/gcc/c-simplify.c
deleted file mode 100644 (file)
index bd50b5e..0000000
+++ /dev/null
@@ -1,1102 +0,0 @@
-/* Tree lowering pass.  This pass gimplifies the tree representation built
-   by the C-based front ends.  The structure of gimplified, or
-   language-independent, trees is dictated by the grammar described in this
-   file.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   Lowering of expressions contributed by Sebastian Pop <s.pop@laposte.net>
-   Re-written to support lowering of whole function trees, documentation
-   and miscellaneous cleanups by Diego Novillo <dnovillo@redhat.com>
-
-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 2, 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 COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
-#include "errors.h"
-#include "varray.h"
-#include "c-tree.h"
-#include "c-common.h"
-#include "tree-simple.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "tree-flow.h"
-#include "tree-inline.h"
-#include "diagnostic.h"
-#include "langhooks.h"
-#include "langhooks-def.h"
-#include "flags.h"
-#include "rtl.h"
-#include "toplev.h"
-#include "tree-dump.h"
-#include "c-pretty-print.h"
-#include "cgraph.h"
-
-
-/*  The gimplification pass converts the language-dependent trees
-    (ld-trees) emitted by the parser into language-independent trees
-    (li-trees) that are the target of SSA analysis and transformations.
-
-    Language-independent trees are based on the SIMPLE intermediate
-    representation used in the McCAT compiler framework:
-
-    "Designing the McCAT Compiler Based on a Family of Structured
-    Intermediate Representations,"
-    L. Hendren, C. Donawa, M. Emami, G. Gao, Justiani, and B. Sridharan,
-    Proceedings of the 5th International Workshop on Languages and
-    Compilers for Parallel Computing, no. 757 in Lecture Notes in
-    Computer Science, New Haven, Connecticut, pp. 406-420,
-    Springer-Verlag, August 3-5, 1992.
-
-    http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
-
-    Basically, we walk down gimplifying the nodes that we encounter.  As we
-    walk back up, we check that they fit our constraints, and copy them
-    into temporaries if not.  */
-
-/* Local declarations.  */
-
-static enum gimplify_status gimplify_expr_stmt (tree *);
-static enum gimplify_status gimplify_decl_stmt (tree *);
-static enum gimplify_status gimplify_for_stmt (tree *, tree *);
-static enum gimplify_status gimplify_while_stmt (tree *);
-static enum gimplify_status gimplify_do_stmt (tree *);
-static enum gimplify_status gimplify_if_stmt (tree *);
-static enum gimplify_status gimplify_switch_stmt (tree *);
-static enum gimplify_status gimplify_return_stmt (tree *);
-static enum gimplify_status gimplify_stmt_expr (tree *);
-static enum gimplify_status gimplify_compound_literal_expr (tree *);
-#if defined ENABLE_CHECKING
-static int is_last_stmt_of_scope (tree);
-#endif
-static enum gimplify_status gimplify_block (tree *, tree *);
-static enum gimplify_status gimplify_cleanup (tree *, tree *);
-static tree gimplify_c_loop (tree, tree, tree, bool);
-static void push_context (void);
-static void pop_context (void);
-static tree c_build_bind_expr (tree, tree);
-static void add_block_to_enclosing (tree);
-static void gimplify_condition (tree *);
-
-enum bc_t { bc_break = 0, bc_continue = 1 };
-static tree begin_bc_block (enum bc_t);
-static tree finish_bc_block (tree, tree);
-static tree build_bc_goto (enum bc_t);
-
-static struct c_gimplify_ctx
-{
-  /* For handling break and continue.  */
-  tree current_bc_label;
-  tree bc_id[2];
-} *ctxp;
-
-static void
-push_context (void)
-{
-  if (ctxp)
-    abort ();
-  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");
-}
-
-static void
-pop_context (void)
-{
-  if (!ctxp || ctxp->current_bc_label)
-    abort ();
-  free (ctxp);
-  ctxp = NULL;
-}
-
-/* Gimplification of statement trees.  */
-
-/* Convert the tree representation of FNDECL from C frontend trees to
-   GENERIC.  */
-
-void
-c_genericize (tree fndecl)
-{
-  FILE *dump_file;
-  int local_dump_flags;
-  struct cgraph_node *cgn;
-
-  /* Dump the C-specific tree IR.  */
-  dump_file = dump_begin (TDI_original, &local_dump_flags);
-  if (dump_file)
-    {
-      fprintf (dump_file, "\n;; Function %s",
-              (*lang_hooks.decl_printable_name) (fndecl, 2));
-      fprintf (dump_file, " (%s)\n",
-              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)));
-      fprintf (dump_file, ";; enabled by -%s\n", dump_flag_name (TDI_original));
-      fprintf (dump_file, "\n");
-
-      if (local_dump_flags & TDF_RAW)
-       dump_node (DECL_SAVED_TREE (fndecl),
-                  TDF_SLIM | local_dump_flags, dump_file);
-      else
-       print_c_tree (dump_file, DECL_SAVED_TREE (fndecl));
-      fprintf (dump_file, "\n");
-
-      dump_end (TDI_original, dump_file);
-    }
-
-  /* Go ahead and gimplify for now.  */
-  push_context ();
-  gimplify_function_tree (fndecl);
-  pop_context ();
-
-  /* Dump the genericized tree IR.  */
-  dump_function (TDI_generic, fndecl);
-
-  /* Genericize all nested functions now.  We do things in this order so
-     that items like VLA sizes are expanded properly in the context of
-     the correct function.  */
-  cgn = cgraph_node (fndecl);
-  for (cgn = cgn->nested; cgn ; cgn = cgn->next_nested)
-    c_genericize (cgn->decl);
-}
-
-/*  Entry point for the tree lowering pass.  Recursively scan
-    *STMT_P and convert it to a GIMPLE tree.  */
-
-int
-c_gimplify_stmt (tree *stmt_p)
-{
-  tree stmt, next;
-  tree outer_pre = NULL_TREE;
-
-  /* PRE and POST are tree chains that contain the side-effects of the
-     gimplified tree.  For instance, given the expression tree:
-
-               c = ++a * 3 + b++;
-
-     After gimplification, the tree will be re-written as:
-
-               a = a + 1;
-               t1 = a * 3;     <-- PRE
-               c = t1 + b;
-               b = b + 1;      <-- POST  */
-
-  for (stmt = *stmt_p; stmt && stmt != error_mark_node; stmt = next)
-    {
-      tree pre, post;
-      int saved_stmts_are_full_exprs_p;
-      location_t stmt_locus;
-      enum gimplify_status ret;
-
-      /* Set up context appropriately for handling this statement.  */
-      saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
-      prep_stmt (stmt);
-      stmt_locus = input_location;
-
-      pre = NULL_TREE;
-      post = NULL_TREE;
-
-      next = TREE_CHAIN (stmt);
-
-      switch (TREE_CODE (stmt))
-       {
-       case COMPOUND_STMT:
-         stmt = COMPOUND_BODY (stmt);
-         ret = GS_OK;
-         break;
-
-       case SCOPE_STMT:
-         ret = gimplify_block (&stmt, &next);
-         break;
-
-       case FOR_STMT:
-         ret = gimplify_for_stmt (&stmt, &next);
-         break;
-
-       case WHILE_STMT:
-         ret = gimplify_while_stmt (&stmt);
-         break;
-
-       case DO_STMT:
-         ret = gimplify_do_stmt (&stmt);
-         break;
-
-       case IF_STMT:
-         ret = gimplify_if_stmt (&stmt);
-         break;
-
-       case SWITCH_STMT:
-         ret = gimplify_switch_stmt (&stmt);
-         break;
-
-       case EXPR_STMT:
-         ret = gimplify_expr_stmt (&stmt);
-         break;
-
-       case RETURN_STMT:
-         ret = gimplify_return_stmt (&stmt);
-         break;
-
-       case DECL_STMT:
-         ret = gimplify_decl_stmt (&stmt);
-         break;
-
-       case LABEL_STMT:
-         stmt = build1 (LABEL_EXPR, void_type_node, LABEL_STMT_LABEL (stmt));
-         ret = GS_OK;
-         break;
-
-       case GOTO_STMT:
-         stmt = build1 (GOTO_EXPR, void_type_node, GOTO_DESTINATION (stmt));
-         ret = GS_OK;
-         break;
-
-       case CASE_LABEL:
-         {
-           tree label = create_artificial_label ();
-           stmt = build (CASE_LABEL_EXPR, void_type_node,
-                         CASE_LOW (stmt), CASE_HIGH (stmt), label);
-           ret = GS_OK;
-         }
-         break;
-
-       case CONTINUE_STMT:
-         stmt = build_bc_goto (bc_continue);
-         ret = GS_OK;
-         break;
-
-       case BREAK_STMT:
-         stmt = build_bc_goto (bc_break);
-         ret = GS_OK;
-         break;
-
-       case CLEANUP_STMT:
-         ret = gimplify_cleanup (&stmt, &next);
-         break;
-
-       case ASM_STMT:
-         {
-           tree new_stmt = build (ASM_EXPR, void_type_node, ASM_STRING (stmt),
-                                  ASM_OUTPUTS (stmt), ASM_INPUTS (stmt),
-                                  ASM_CLOBBERS (stmt));
-           ASM_INPUT_P (new_stmt) = ASM_INPUT_P (stmt);
-           ASM_VOLATILE_P (new_stmt) = ASM_VOLATILE_P (stmt);
-           stmt = new_stmt;
-           ret = GS_OK;
-         }
-         break;
-
-       default:
-         if (lang_gimplify_stmt && (*lang_gimplify_stmt) (&stmt, &next))
-           {
-             ret = GS_OK;
-             break;
-           }
-
-         fprintf (stderr, "unhandled statement node in c_gimplify_stmt:\n");
-         debug_tree (stmt);
-         abort ();
-         break;
-       }
-
-      switch (ret)
-       {
-       case GS_ERROR:
-         goto cont;
-       case GS_OK:
-          gimplify_stmt (&stmt);
-         break;
-       case GS_ALL_DONE:
-         break;
-       default:
-         abort ();
-       }
-
-      /* PRE and POST now contain a list of statements for all the
-        side-effects in STMT.  */
-
-      append_to_statement_list (stmt, &pre);
-      append_to_statement_list (post, &pre);
-      annotate_all_with_locus (&pre, stmt_locus);
-
-      append_to_statement_list (pre, &outer_pre);
-    cont:
-      /* Restore saved state.  */
-      current_stmt_tree ()->stmts_are_full_exprs_p
-       = saved_stmts_are_full_exprs_p;
-    }
-  append_to_statement_list (stmt, &outer_pre);
-  *stmt_p = outer_pre;
-
-  return GS_ALL_DONE;
-}
-
-static void
-add_block_to_enclosing (tree block)
-{
-  tree enclosing;
-
-  for (enclosing = gimple_current_bind_expr ();
-       enclosing; enclosing = TREE_CHAIN (enclosing))
-    if (BIND_EXPR_BLOCK (enclosing))
-      break;
-
-  enclosing = BIND_EXPR_BLOCK (enclosing);
-  BLOCK_SUBBLOCKS (enclosing) = chainon (BLOCK_SUBBLOCKS (enclosing), block);
-}
-
-/* Genericize a scope by creating a new BIND_EXPR.
-   BLOCK is either a BLOCK representing the scope or a chain of _DECLs.
-     In the latter case, we need to create a new BLOCK and add it to the
-     BLOCK_SUBBLOCKS of the enclosing block.
-   BODY is a chain of C _STMT nodes for the contents of the scope, to be
-     genericized.  */
-
-static tree
-c_build_bind_expr (tree block, tree body)
-{
-  tree decls, bind;
-
-  if (block == NULL_TREE)
-    decls = NULL_TREE;
-  else if (TREE_CODE (block) == BLOCK)
-    decls = BLOCK_VARS (block);
-  else
-    {
-      decls = block;
-      if (DECL_ARTIFICIAL (decls))
-       block = NULL_TREE;
-      else
-       {
-         block = make_node (BLOCK);
-         BLOCK_VARS (block) = decls;
-         add_block_to_enclosing (block);
-       }
-    }
-
-  if (!body)
-    body = build_empty_stmt ();
-
-  bind = build (BIND_EXPR, void_type_node, decls, body, block);
-  TREE_SIDE_EFFECTS (bind) = 1;
-
-  return bind;
-}
-
-/* Genericize a syntactic block by removing the bracketing SCOPE_STMTs and
-   wrapping the intervening code in a BIND_EXPR.  This function assumes
-   that matching SCOPE_STMTs will always appear in the same statement
-   sequence.  */
-
-static enum gimplify_status
-gimplify_block (tree *stmt_p, tree *next_p)
-{
-  tree *p;
-  tree block;
-  tree bind;
-  int depth;
-  location_t stmt_locus;
-
-  if (!SCOPE_BEGIN_P (*stmt_p))
-    {
-      /* Can wind up mismatched with syntax errors.  */
-      if (!errorcount && !sorrycount)
-       abort ();
-      *stmt_p = NULL;
-      return GS_ERROR;
-    }
-
-  block = SCOPE_STMT_BLOCK (*stmt_p);
-
-  /* Find the matching ending SCOPE_STMT.  */
-  depth = 1;
-  for (p = &TREE_CHAIN (*stmt_p);; p = &TREE_CHAIN (*p))
-    {
-      if (*p == NULL)
-       break;
-      if (TREE_CODE (*p) == SCOPE_STMT)
-       {
-         if (SCOPE_BEGIN_P (*p))
-           ++depth;
-         else if (--depth == 0)
-           break;
-       }
-    }
-
-  stmt_locus = input_location;
-  if (*p)
-    {
-      if (SCOPE_STMT_BLOCK (*p) != block)
-       abort ();
-      if (EXPR_LOCUS (*p))
-       stmt_locus = *EXPR_LOCUS (*p);
-      *next_p = TREE_CHAIN (*p);
-      *p = NULL_TREE;
-    }
-  else
-    {
-      /* Can wind up mismatched with syntax errors.  */
-      if (!errorcount && !sorrycount)
-       abort ();
-    }
-
-  bind = c_build_bind_expr (block, TREE_CHAIN (*stmt_p));
-  *stmt_p = bind;
-  input_location = stmt_locus;
-
-  return GS_OK;
-}
-
-/* Genericize a CLEANUP_STMT.  Just wrap everything from here to the end of
-   the block in a TRY_FINALLY_EXPR.  Or a TRY_CATCH_EXPR, if it's an
-   EH-only cleanup.  */
-
-static enum gimplify_status
-gimplify_cleanup (tree *stmt_p, tree *next_p)
-{
-  tree stmt = *stmt_p;
-  tree body = TREE_CHAIN (stmt);
-  tree cleanup = CLEANUP_EXPR (stmt);
-  enum tree_code code
-    = (CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR : TRY_FINALLY_EXPR);
-
-  if (!body)
-    body = build_empty_stmt ();
-  if (!cleanup)
-    cleanup = build_empty_stmt ();
-
-  *stmt_p = build (code, void_type_node, body, cleanup);
-  *next_p = NULL_TREE;
-
-  return GS_OK;
-}
-
-/*  Gimplify an EXPR_STMT node.
-
-    STMT is the statement node.
-
-    PRE_P points to the list where side effects that must happen before
-       STMT should be stored.
-
-    POST_P points to the list where side effects that must happen after
-       STMT should be stored.  */
-
-static enum gimplify_status
-gimplify_expr_stmt (tree *stmt_p)
-{
-  tree stmt = EXPR_STMT_EXPR (*stmt_p);
-
-  if (stmt == error_mark_node)
-    stmt = NULL;
-
-  /* Gimplification of a statement expression will nullify the
-     statement if all its side effects are moved to *PRE_P and *POST_P.
-
-     In this case we will not want to emit the gimplified statement.
-     However, we may still want to emit a warning, so we do that before
-     gimplification.  */
-  if (stmt && (extra_warnings || warn_unused_value))
-    {
-      if (!TREE_SIDE_EFFECTS (stmt))
-       {
-         if (!IS_EMPTY_STMT (stmt)
-             && !VOID_TYPE_P (TREE_TYPE (stmt))
-             && !TREE_NO_WARNING (stmt))
-           warning ("statement with no effect");
-       }
-      else if (warn_unused_value)
-       {
-         /* Kludge for 20020220-2.c.  warn_if_unused_value shouldn't use
-            the stmt file location info.  */
-         set_file_and_line_for_stmt (input_location);
-         warn_if_unused_value (stmt);
-       }
-    }
-
-  if (stmt == NULL_TREE)
-    stmt = build_empty_stmt ();
-  else if (stmts_are_full_exprs_p ())
-    stmt = build1 (CLEANUP_POINT_EXPR, void_type_node, stmt);
-
-  *stmt_p = stmt;
-
-  return GS_OK;
-}
-
-/* If the condition for a loop (or the like) is a decl, it will be a
-   TREE_LIST where the TREE_PURPOSE is a DECL_STMT and the TREE_VALUE is
-   a use of the decl.  Turn such a thing into a COMPOUND_EXPR.  */
-
-static void
-gimplify_condition (tree *cond_p)
-{
-  tree cond = *cond_p;
-  if (cond && TREE_CODE (cond) == TREE_LIST)
-    {
-      tree decl = TREE_PURPOSE (cond);
-      tree value = TREE_VALUE (cond);
-      c_gimplify_stmt (&decl);
-      *cond_p = build (COMPOUND_EXPR, TREE_TYPE (value), decl, value);
-    }
-}
-
-/* Begin a scope which can be exited by a break or continue statement.  BC
-   indicates which.
-
-   Just creates a label and pushes it into the current context.  */
-
-static tree
-begin_bc_block (enum bc_t bc)
-{
-  tree label = create_artificial_label ();
-  DECL_NAME (label) = ctxp->bc_id[bc];
-  TREE_CHAIN (label) = ctxp->current_bc_label;
-  ctxp->current_bc_label = label;
-  return label;
-}
-
-/* Finish a scope which can be exited by a break or continue statement.
-   LABEL was returned from the most recent call to begin_bc_block.  BODY is
-   an expression for the contents of the scope.
-
-   If we saw a break (or continue) in the scope, append a LABEL_EXPR to
-   body.  Otherwise, just forget the label.  */
-
-static tree
-finish_bc_block (tree label, tree body)
-{
-  if (label != ctxp->current_bc_label)
-    abort ();
-
-  if (TREE_USED (label))
-    {
-      tree t, sl = NULL;
-
-      /* Clear the name so flow can delete the label.  */
-      DECL_NAME (label) = NULL_TREE;
-      t = build1 (LABEL_EXPR, void_type_node, label);
-
-      append_to_statement_list (body, &sl);
-      append_to_statement_list (t, &sl);
-      body = sl;
-    }
-
-  ctxp->current_bc_label = TREE_CHAIN (label);
-  TREE_CHAIN (label) = NULL_TREE;
-  return body;
-}
-
-/* Build a GOTO_EXPR to represent a break or continue statement.  BC
-   indicates which.  */
-
-static tree
-build_bc_goto (enum bc_t bc)
-{
-  tree label;
-  tree target_name = ctxp->bc_id[bc];
-
-  /* Look for the appropriate type of label.  */
-  for (label = ctxp->current_bc_label;
-       label;
-       label = TREE_CHAIN (label))
-    if (DECL_NAME (label) == target_name)
-      break;
-
-  if (label == NULL_TREE)
-    {
-      if (bc == bc_break)
-       error ("break statement not within loop or switch");
-      else
-       error ("continue statement not within loop or switch");
-
-      return NULL_TREE;
-    }
-
-  /* Mark the label used for finish_bc_block.  */
-  TREE_USED (label) = 1;
-  return build1 (GOTO_EXPR, void_type_node, label);
-}
-
-/* Build a generic representation of one of the C loop forms.  COND is the
-   loop condition or NULL_TREE.  BODY is the (possibly compound) statement
-   controlled by the loop.  INCR is the increment expression of a for-loop,
-   or NULL_TREE.  COND_IS_FIRST indicates whether the condition is
-   evaluated before the loop body as in while and for loops, or after the
-   loop body as in do-while loops.  */
-
-static tree
-gimplify_c_loop (tree cond, tree body, tree incr, bool cond_is_first)
-{
-  tree top, entry, exit, cont_block, break_block, stmt_list, t;
-  location_t stmt_locus;
-
-  stmt_locus = input_location;
-
-  /* Detect do { ... } while (0) and don't generate loop construct.  */
-  if (!cond_is_first && cond && integer_zerop (cond))
-    top = cond = NULL;
-  else
-    {
-      /* If we use a LOOP_EXPR here, we have to feed the whole thing
-        back through the main gimplifier to lower it.  Given that we
-        have to gimplify the loop body NOW so that we can resolve
-        break/continue stmts, seems easier to just expand to gotos.  */
-      top = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
-    }
-
-  break_block = begin_bc_block (bc_break);
-
-  if (top)
-    {
-      /* If we have an exit condition, then we build an IF with gotos either
-        out of the loop, or to the top of it.  If there's no exit condition,
-        then we just build a jump back to the top.  */
-      exit = build_and_jump (&LABEL_EXPR_LABEL (top));
-      if (cond)
-       {
-         gimplify_condition (&cond);
-         t = build_bc_goto (bc_break);
-         exit = build (COND_EXPR, void_type_node, cond, exit, t);
-         exit = fold (exit);
-         gimplify_stmt (&exit);
-       }
-    }
-  else
-    exit = NULL_TREE;
-
-  cont_block = begin_bc_block (bc_continue);
-
-  gimplify_stmt (&body);
-  if (incr && stmts_are_full_exprs_p ())
-    incr = fold (build1 (CLEANUP_POINT_EXPR, void_type_node, incr));
-  gimplify_stmt (&incr);
-
-  body = finish_bc_block (cont_block, body);
-
-  stmt_list = NULL;
-
-  if (cond_is_first && cond)
-    {
-      entry = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
-      t = build_and_jump (&LABEL_EXPR_LABEL (entry));
-      append_to_statement_list (t, &stmt_list);
-    }
-  else
-    entry = NULL_TREE;
-
-  append_to_statement_list (top, &stmt_list);
-  append_to_statement_list (body, &stmt_list);
-  append_to_statement_list (incr, &stmt_list);
-  append_to_statement_list (entry, &stmt_list);
-  append_to_statement_list (exit, &stmt_list);
-
-  annotate_all_with_locus (&stmt_list, stmt_locus);
-
-  return finish_bc_block (break_block, stmt_list);
-}
-
-/* Gimplify a FOR_STMT node.  Move the stuff in the for-init-stmt into the
-   prequeue and hand off to gimplify_c_loop.  */
-
-static enum gimplify_status
-gimplify_for_stmt (tree *stmt_p, tree *next_p)
-{
-  tree stmt = *stmt_p;
-  tree init = FOR_INIT_STMT (stmt);
-
-  if (init)
-    {
-      /* Reorganize the statements so that we do the right thing with a
-        CLEANUP_STMT.  We want the FOR_STMT and nothing else to be in the
-        scope of the cleanup, so play with pointers to accomplish that. */
-      FOR_INIT_STMT (stmt) = NULL_TREE;
-      chainon (init, stmt);
-      *stmt_p = init;
-      *next_p = TREE_CHAIN (stmt);
-      TREE_CHAIN (stmt) = NULL_TREE;
-      c_gimplify_stmt (stmt_p);
-    }
-  else
-    *stmt_p = gimplify_c_loop (FOR_COND (stmt), FOR_BODY (stmt),
-                              FOR_EXPR (stmt), 1);
-
-  return GS_ALL_DONE;
-}
-
-/* Gimplify a WHILE_STMT node.  */
-
-static enum gimplify_status
-gimplify_while_stmt (tree *stmt_p)
-{
-  tree stmt = *stmt_p;
-  *stmt_p = gimplify_c_loop (WHILE_COND (stmt), WHILE_BODY (stmt),
-                            NULL_TREE, 1);
-  return GS_ALL_DONE;
-}
-
-/* Gimplify a DO_STMT node.  */
-
-static enum gimplify_status
-gimplify_do_stmt (tree *stmt_p)
-{
-  tree stmt = *stmt_p;
-  *stmt_p = gimplify_c_loop (DO_COND (stmt), DO_BODY (stmt),
-                            NULL_TREE, 0);
-  return GS_ALL_DONE;
-}
-
-/* Genericize an IF_STMT by turning it into a COND_EXPR.  */
-
-static enum gimplify_status
-gimplify_if_stmt (tree *stmt_p)
-{
-  tree stmt, then_, else_;
-
-  stmt = *stmt_p;
- restart:
-  then_ = THEN_CLAUSE (stmt);
-  else_ = ELSE_CLAUSE (stmt);
-
-  if (!then_)
-    then_ = build_empty_stmt ();
-  if (!else_)
-    else_ = build_empty_stmt ();
-
-  stmt = build (COND_EXPR, void_type_node, IF_COND (stmt), then_, else_);
-  gimplify_condition (& TREE_OPERAND (stmt, 0));
-  *stmt_p = stmt;
-
-  /* Handle properly nested if-else chains via iteration instead of
-     mutual recursion between gimplify.c and c-simplify.c.  */
-  annotate_with_locus (stmt, input_location);
-  if (TREE_CODE (else_) == IF_STMT && !TREE_CHAIN (else_))
-    {
-      stmt_p = &COND_EXPR_ELSE (stmt);
-      stmt = else_;
-      prep_stmt (stmt);
-      goto restart;
-    }
-
-  return GS_OK;
-}
-
-/* Genericize a SWITCH_STMT by turning it into a SWITCH_EXPR.  */
-
-static enum gimplify_status
-gimplify_switch_stmt (tree *stmt_p)
-{
-  tree stmt = *stmt_p;
-  tree break_block, body;
-  location_t stmt_locus = input_location;
-
-  break_block = begin_bc_block (bc_break);
-
-  gimplify_condition (&SWITCH_COND (stmt));
-
-  body = SWITCH_BODY (stmt);
-  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);
-  gimplify_stmt (stmt_p);
-
-  *stmt_p = finish_bc_block (break_block, *stmt_p);
-  return GS_ALL_DONE;
-}
-
-/* Genericize a RETURN_STMT by turning it into a RETURN_EXPR.  */
-
-static enum gimplify_status
-gimplify_return_stmt (tree *stmt_p)
-{
-  tree expr = RETURN_STMT_EXPR (*stmt_p);
-  expr = build1 (RETURN_EXPR, void_type_node, expr);
-  if (stmts_are_full_exprs_p ())
-    expr = build1 (CLEANUP_POINT_EXPR, void_type_node, expr);
-  *stmt_p = expr;
-  return GS_OK;
-}
-
-/* Gimplifies a DECL_STMT node T.
-
-   If a declaration V has an initial value I, create an expression 'V = I'
-   and insert it after the DECL_STMT.
-
-   PRE_P is a queue for effects that should happen before the DECL_STMT.
-
-   MID_P is a queue for effects that should happen after the DECL_STMT,
-   but before uses of the initialized decl.
-
-   POST_P is a queue for effects that should happen after uses of the
-   initialized decl.
-
-   Usually these last two will be the same, but they may need to be
-   different if the DECL_STMT is somehow embedded in an expression.  */
-
-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);
-             if (stmts_are_full_exprs_p ())
-               init = build1 (CLEANUP_POINT_EXPR, void_type_node, 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
-   instead.  */
-
-static enum gimplify_status
-gimplify_compound_literal_expr (tree *expr_p)
-{
-  tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
-  tree decl = DECL_STMT_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
-     anonymous artificial vars aren't pushed, but everything else is.  */
-  if (DECL_NAME (decl) == NULL_TREE)
-    gimple_add_tmp_var (decl);
-
-  gimplify_decl_stmt (&decl_s);
-  *expr_p = decl_s ? decl_s : decl;
-  return GS_OK;
-}
-
-/* Do C-specific gimplification.  Args are as for gimplify_expr.  */
-
-int
-c_gimplify_expr (tree *expr_p, tree *pre_p ATTRIBUTE_UNUSED,
-                tree *post_p ATTRIBUTE_UNUSED)
-{
-  enum tree_code code = TREE_CODE (*expr_p);
-
-  if (STATEMENT_CODE_P (code))
-    return c_gimplify_stmt (expr_p);
-
-  switch (code)
-    {
-    case COMPOUND_LITERAL_EXPR:
-      return gimplify_compound_literal_expr (expr_p);
-
-    case STMT_EXPR:
-      return gimplify_stmt_expr (expr_p);
-
-    default:
-      return GS_UNHANDLED;
-    }
-}
-
-/* Returns the final EXPR_STMT which represents the return value of a
-   STMT_EXPR, or NULL_TREE if none.  */
-
-tree
-stmt_expr_last_stmt (tree stmt_expr)
-{
-  tree body = STMT_EXPR_STMT (stmt_expr);
-  tree last_stmt, substmt;
-
-  /* Splice the last expression out of the STMT chain.  */
-  last_stmt = NULL_TREE;
-  for (substmt = COMPOUND_BODY (body); substmt;
-       substmt = TREE_CHAIN (substmt))
-    if (TREE_CODE (substmt) != SCOPE_STMT)
-      last_stmt = substmt;
-
-  if (last_stmt == NULL_TREE
-      || TREE_CODE (last_stmt) != EXPR_STMT
-      || (TREE_TYPE (last_stmt)
-         && VOID_TYPE_P (TREE_TYPE (last_stmt))))
-    {
-      location_t loc;
-      if (last_stmt && EXPR_LOCUS (last_stmt))
-       loc = *EXPR_LOCUS (last_stmt);
-      else if (EXPR_LOCUS (stmt_expr))
-       loc = *EXPR_LOCUS (stmt_expr);
-      else
-       loc = input_location;
-      warning ("%Hstatement-expressions should end with a "
-              "non-void expression", &loc);
-      last_stmt = NULL_TREE;
-    }
-
-#if defined ENABLE_CHECKING
-  if (last_stmt && !is_last_stmt_of_scope (last_stmt))
-    abort ();
-#endif
-
-  return last_stmt;
-}
-
-/* Gimplify a STMT_EXPR.  EXPR_P points to the expression to gimplify.
-   After gimplification, if the STMT_EXPR returns a value, EXPR_P will
-   point to a new temporary that holds that value; otherwise it will be
-   null.
-
-   PRE_P points to the list where side effects that must happen before
-     *EXPR_P should be stored.  */
-
-static enum gimplify_status
-gimplify_stmt_expr (tree *expr_p)
-{
-  tree body = STMT_EXPR_STMT (*expr_p);
-
-  if (VOID_TYPE_P (TREE_TYPE (*expr_p)))
-    {
-      *expr_p = body;
-      return c_gimplify_stmt (expr_p);
-    }
-  else
-    {
-      tree last_stmt = stmt_expr_last_stmt (*expr_p);
-      tree last_expr = NULL_TREE;
-
-      if (last_stmt)
-       {
-         last_expr = EXPR_STMT_EXPR (last_stmt);
-
-         if (stmts_are_full_exprs_p ())
-           last_expr = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (last_expr),
-                               last_expr);
-         EXPR_STMT_EXPR (last_stmt) = NULL_TREE;
-       }
-
-      /* Genericize the block.  */
-      c_gimplify_stmt (&body);
-
-      /* Now retrofit that last expression into the BIND_EXPR.  */
-      if (last_expr)
-       {
-         tree *sub_p;
-
-         if (!STMT_EXPR_NO_SCOPE (*expr_p))
-           {
-             /* Our BIND_EXPR will always be hidden within
-                a STATEMENT_LIST.  Discard that.  */
-             body = expr_first (body);
-             sub_p = &BIND_EXPR_BODY (body);
-
-             /* Append the last expression to the end of the BIND_EXPR.
-                We'll now re-process this, and let voidify_wrapper_expr
-                do its job.  */
-             append_to_statement_list_force (last_expr, sub_p);
-             TREE_TYPE (body) = TREE_TYPE (last_expr);
-           }
-         else
-           append_to_compound_expr (last_expr, &body);
-       }
-
-      *expr_p = body;
-      return GS_OK;
-    }
-}
-
-/* Code generation.  */
-
-/* Miscellaneous helpers.  */
-
-#if defined ENABLE_CHECKING
-/*  Return nonzero if STMT is the last statement of its scope.  */
-
-static int
-is_last_stmt_of_scope (tree stmt)
-{
-  return (TREE_CHAIN (stmt) == NULL_TREE
-         || (TREE_CODE (TREE_CHAIN (stmt)) == SCOPE_STMT
-             && SCOPE_END_P (TREE_CHAIN (stmt))));
-}
-#endif
index 9d990ee36429e4d815e9dee2b7a84c1514cc02a7..25c72524de40a320154a10c3a07d6833df39f73f 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-13  Diego Novillo  <dnovillo@redhat.com>
+
+       * cp-gimplify.c: Rename from cp-simplify.c.
+       * Make-lang.in, optimize.c: Update.
+
 2004-05-13  Diego Novillo  <dnovillo@redhat.com>
 
        Merge from tree-ssa-20020619-branch.  See
index bf4b0fe850f5e0f6ae0dc7add5e8239fc019cb83..12decae82f147fa20d3c02a2765cdab9b7f7d91e 100644 (file)
@@ -74,7 +74,7 @@ g++-cross$(exeext): g++$(exeext)
 CXX_C_OBJS = attribs.o c-common.o c-format.o c-pragma.o c-semantics.o c-lex.o \
        c-dump.o $(CXX_TARGET_OBJS) c-pretty-print.o c-opts.o c-pch.o \
        c-incpath.o cppdefault.o c-ppoutput.o c-cppbuiltin.o prefix.o \
-       c-simplify.o tree-inline.o
+       c-gimplify.o tree-inline.o
 
 # Language-specific object files.
 CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
@@ -82,7 +82,7 @@ CXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
  cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
  cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
  cp/mangle.o cp/cp-lang.o cp/name-lookup.o cp/cxx-pretty-print.o \
- cp/cp-simplify.o tree-mudflap.o cp/cp-mudflap.o
+ cp/cp-gimplify.o tree-mudflap.o cp/cp-mudflap.o
 
 # Use strict warnings for this front end.
 cp-warn = $(STRICT_WARN) $(WERROR)
@@ -259,13 +259,13 @@ cp/semantics.o: cp/semantics.c $(CXX_TREE_H) $(TM_H) cp/lex.h except.h toplev.h
   tree-inline.h cgraph.h
 cp/dump.o: cp/dump.c $(CXX_TREE_H) $(TM_H) tree-dump.h
 cp/optimize.o: cp/optimize.c $(CXX_TREE_H) $(TM_H) rtl.h integrate.h insn-config.h \
-  input.h $(PARAMS_H) debug.h tree-inline.h tree-simple.h
+  input.h $(PARAMS_H) debug.h tree-inline.h tree-gimple.h
 cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) toplev.h real.h gt-cp-mangle.h \
   $(TARGET_H) $(TM_P_H)
 
 cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) diagnostic.h gt-cp-parser.h \
   output.h
-cp/cp-simplify.o: cp/cp-simplify.c $(CXX_TREE_H) toplev.h c-common.h \
+cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) toplev.h c-common.h \
        $(TM_H) coretypes.h
 cp/cp-mudflap.o: cp/cp-mudflap.c $(CXX_TREE_H) toplev.h c-common.h \
        $(TM_H) coretypes.h
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
new file mode 100644 (file)
index 0000000..f82ed61
--- /dev/null
@@ -0,0 +1,236 @@
+/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
+
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Jason Merrill <jason@redhat.com>
+
+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 2, 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 COPYING.  If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "cp-tree.h"
+#include "c-common.h"
+#include "toplev.h"
+#include "tree-gimple.h"
+
+static void genericize_try_block (tree *);
+static void genericize_catch_block (tree *);
+static void genericize_eh_spec_block (tree *);
+static void gimplify_must_not_throw_expr (tree *, tree *);
+static void cp_gimplify_init_expr (tree *, tree *, tree *);
+
+/* Genericize a C++ _STMT.  Called from c_gimplify_stmt.  */
+
+int
+cp_gimplify_stmt (tree *stmt_p, tree *next_p ATTRIBUTE_UNUSED)
+{
+  tree stmt = *stmt_p;
+  switch (TREE_CODE (stmt))
+    {
+    case TRY_BLOCK:
+      genericize_try_block (stmt_p);
+      return 1;
+
+    case HANDLER:
+      genericize_catch_block (stmt_p);
+      return 1;
+
+    case EH_SPEC_BLOCK:
+      genericize_eh_spec_block (stmt_p);
+      return 1;
+
+    case USING_STMT:
+      /* Just ignore for now.  Eventually we will want to pass this on to
+        the debugger.  */
+      *stmt_p = build_empty_stmt ();
+      return 1;
+
+    default:
+      break;
+    }
+  return 0;
+}
+
+/* Genericize a TRY_BLOCK.  */
+
+static void
+genericize_try_block (tree *stmt_p)
+{
+  tree body = TRY_STMTS (*stmt_p);
+  tree cleanup = TRY_HANDLERS (*stmt_p);
+
+  c_gimplify_stmt (&body);
+
+  if (CLEANUP_P (*stmt_p))
+    /* A cleanup is an expression, so it doesn't need to be genericized.  */;
+  else
+    c_gimplify_stmt (&cleanup);
+
+  *stmt_p = build (TRY_CATCH_EXPR, void_type_node, body, cleanup);
+}
+
+/* Genericize a HANDLER by converting to a CATCH_EXPR.  */
+
+static void
+genericize_catch_block (tree *stmt_p)
+{
+  tree type = HANDLER_TYPE (*stmt_p);
+  tree body = HANDLER_BODY (*stmt_p);
+
+  c_gimplify_stmt (&body);
+
+  /* FIXME should the caught type go in TREE_TYPE?  */
+  *stmt_p = build (CATCH_EXPR, void_type_node, type, body);
+}
+
+/* Genericize an EH_SPEC_BLOCK by converting it to a
+   TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
+
+static void
+genericize_eh_spec_block (tree *stmt_p)
+{
+  tree body = EH_SPEC_STMTS (*stmt_p);
+  tree allowed = EH_SPEC_RAISES (*stmt_p);
+  tree failure = build_call (call_unexpected_node,
+                            tree_cons (NULL_TREE, build_exc_ptr (),
+                                       NULL_TREE));
+  c_gimplify_stmt (&body);
+
+  *stmt_p = gimple_build_eh_filter (body, allowed, failure);
+}
+
+/* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
+
+int
+cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+  switch (TREE_CODE (*expr_p))
+    {
+    case PTRMEM_CST:
+      *expr_p = cplus_expand_constant (*expr_p);
+      return GS_OK;
+
+    case AGGR_INIT_EXPR:
+      simplify_aggr_init_expr (expr_p);
+      return GS_OK;
+
+    case THROW_EXPR:
+      /* FIXME communicate throw type to backend, probably by moving
+        THROW_EXPR into ../tree.def.  */
+      *expr_p = TREE_OPERAND (*expr_p, 0);
+      return GS_OK;
+
+    case MUST_NOT_THROW_EXPR:
+      gimplify_must_not_throw_expr (expr_p, pre_p);
+      return GS_OK;
+
+    case INIT_EXPR:
+    case MODIFY_EXPR:
+      cp_gimplify_init_expr (expr_p, pre_p, post_p);
+      return GS_OK;
+
+    case EMPTY_CLASS_EXPR:
+      {
+       /* Yes, an INTEGER_CST with RECORD_TYPE.  */
+       tree i = build_int_2 (0, 0);
+       TREE_TYPE (i) = TREE_TYPE (*expr_p);
+       *expr_p = i;
+      }
+      return GS_OK;
+
+    case BASELINK:
+      *expr_p = BASELINK_FUNCTIONS (*expr_p);
+      return GS_OK;
+
+    default:
+      return c_gimplify_expr (expr_p, pre_p, post_p);
+    }
+}
+
+/* Gimplify initialization from an AGGR_INIT_EXPR.  */
+
+static void
+cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
+{
+  tree from = TREE_OPERAND (*expr_p, 1);
+  tree to = TREE_OPERAND (*expr_p, 0);
+  tree sub;
+
+  /* If we are initializing something from a TARGET_EXPR, strip the
+     TARGET_EXPR and initialize it directly.  */
+  /* What about code that pulls out the temp and uses it elsewhere?  I
+     think that such code never uses the TARGET_EXPR as an initializer.  If
+     I'm wrong, we'll abort because the temp won't have any RTL.  In that
+     case, I guess we'll need to replace references somehow.  */
+  if (TREE_CODE (from) == TARGET_EXPR)
+    from = TARGET_EXPR_INITIAL (from);
+
+  sub = from;
+
+  /* If we are initializing from a STMT_EXPR, extract the returned
+     expression.  */
+  if (TREE_CODE (from) == STMT_EXPR)
+    sub = EXPR_STMT_EXPR (stmt_expr_last_stmt (from));
+
+  /* Look through any COMPOUND_EXPRs.  */
+  while (TREE_CODE (sub) == COMPOUND_EXPR)
+    sub = TREE_OPERAND (sub, 1);
+
+  /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
+     replace the slot operand with our target.
+
+     Should we add a target parm to gimplify_expr instead?  No, as in this
+     case we want to replace the INIT_EXPR.  */
+  if (TREE_CODE (sub) == AGGR_INIT_EXPR)
+    {
+      gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+      TREE_OPERAND (sub, 2) = to;
+      *expr_p = from;
+
+      /* The initialization is now a side-effect, so the container can
+         become void.  This is important for a STMT_EXPR, so we don't try
+         to voidify it later by creating a temporary.  */
+      if (from != sub)
+       TREE_TYPE (from) = void_type_node;
+    }
+}
+
+/* Gimplify a MUST_NOT_THROW_EXPR.  */
+
+static void
+gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
+{
+  tree stmt = *expr_p;
+  tree temp = voidify_wrapper_expr (stmt);
+  tree body = TREE_OPERAND (stmt, 0);
+
+  gimplify_stmt (&body);
+
+  stmt = gimple_build_eh_filter (body, NULL_TREE,
+                                build_call (terminate_node, NULL_TREE));
+
+  if (temp)
+    {
+      append_to_statement_list (stmt, pre_p);
+      *expr_p = temp;
+    }
+  else
+    *expr_p = stmt;
+}
diff --git a/gcc/cp/cp-simplify.c b/gcc/cp/cp-simplify.c
deleted file mode 100644 (file)
index af302ee..0000000
+++ /dev/null
@@ -1,236 +0,0 @@
-/* C++-specific tree lowering bits; see also c-simplify.c and tree-simple.c.
-
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   Contributed by Jason Merrill <jason@redhat.com>
-
-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 2, 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 COPYING.  If not, write to the Free
-Software Foundation, 59 Temple Place - Suite 330, Boston, MA
-02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
-#include "cp-tree.h"
-#include "c-common.h"
-#include "toplev.h"
-#include "tree-simple.h"
-
-static void genericize_try_block (tree *);
-static void genericize_catch_block (tree *);
-static void genericize_eh_spec_block (tree *);
-static void gimplify_must_not_throw_expr (tree *, tree *);
-static void cp_gimplify_init_expr (tree *, tree *, tree *);
-
-/* Genericize a C++ _STMT.  Called from c_gimplify_stmt.  */
-
-int
-cp_gimplify_stmt (tree *stmt_p, tree *next_p ATTRIBUTE_UNUSED)
-{
-  tree stmt = *stmt_p;
-  switch (TREE_CODE (stmt))
-    {
-    case TRY_BLOCK:
-      genericize_try_block (stmt_p);
-      return 1;
-
-    case HANDLER:
-      genericize_catch_block (stmt_p);
-      return 1;
-
-    case EH_SPEC_BLOCK:
-      genericize_eh_spec_block (stmt_p);
-      return 1;
-
-    case USING_STMT:
-      /* Just ignore for now.  Eventually we will want to pass this on to
-        the debugger.  */
-      *stmt_p = build_empty_stmt ();
-      return 1;
-
-    default:
-      break;
-    }
-  return 0;
-}
-
-/* Genericize a TRY_BLOCK.  */
-
-static void
-genericize_try_block (tree *stmt_p)
-{
-  tree body = TRY_STMTS (*stmt_p);
-  tree cleanup = TRY_HANDLERS (*stmt_p);
-
-  c_gimplify_stmt (&body);
-
-  if (CLEANUP_P (*stmt_p))
-    /* A cleanup is an expression, so it doesn't need to be genericized.  */;
-  else
-    c_gimplify_stmt (&cleanup);
-
-  *stmt_p = build (TRY_CATCH_EXPR, void_type_node, body, cleanup);
-}
-
-/* Genericize a HANDLER by converting to a CATCH_EXPR.  */
-
-static void
-genericize_catch_block (tree *stmt_p)
-{
-  tree type = HANDLER_TYPE (*stmt_p);
-  tree body = HANDLER_BODY (*stmt_p);
-
-  c_gimplify_stmt (&body);
-
-  /* FIXME should the caught type go in TREE_TYPE?  */
-  *stmt_p = build (CATCH_EXPR, void_type_node, type, body);
-}
-
-/* Genericize an EH_SPEC_BLOCK by converting it to a
-   TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
-
-static void
-genericize_eh_spec_block (tree *stmt_p)
-{
-  tree body = EH_SPEC_STMTS (*stmt_p);
-  tree allowed = EH_SPEC_RAISES (*stmt_p);
-  tree failure = build_call (call_unexpected_node,
-                            tree_cons (NULL_TREE, build_exc_ptr (),
-                                       NULL_TREE));
-  c_gimplify_stmt (&body);
-
-  *stmt_p = gimple_build_eh_filter (body, allowed, failure);
-}
-
-/* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
-
-int
-cp_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p)
-{
-  switch (TREE_CODE (*expr_p))
-    {
-    case PTRMEM_CST:
-      *expr_p = cplus_expand_constant (*expr_p);
-      return GS_OK;
-
-    case AGGR_INIT_EXPR:
-      simplify_aggr_init_expr (expr_p);
-      return GS_OK;
-
-    case THROW_EXPR:
-      /* FIXME communicate throw type to backend, probably by moving
-        THROW_EXPR into ../tree.def.  */
-      *expr_p = TREE_OPERAND (*expr_p, 0);
-      return GS_OK;
-
-    case MUST_NOT_THROW_EXPR:
-      gimplify_must_not_throw_expr (expr_p, pre_p);
-      return GS_OK;
-
-    case INIT_EXPR:
-    case MODIFY_EXPR:
-      cp_gimplify_init_expr (expr_p, pre_p, post_p);
-      return GS_OK;
-
-    case EMPTY_CLASS_EXPR:
-      {
-       /* Yes, an INTEGER_CST with RECORD_TYPE.  */
-       tree i = build_int_2 (0, 0);
-       TREE_TYPE (i) = TREE_TYPE (*expr_p);
-       *expr_p = i;
-      }
-      return GS_OK;
-
-    case BASELINK:
-      *expr_p = BASELINK_FUNCTIONS (*expr_p);
-      return GS_OK;
-
-    default:
-      return c_gimplify_expr (expr_p, pre_p, post_p);
-    }
-}
-
-/* Gimplify initialization from an AGGR_INIT_EXPR.  */
-
-static void
-cp_gimplify_init_expr (tree *expr_p, tree *pre_p, tree *post_p)
-{
-  tree from = TREE_OPERAND (*expr_p, 1);
-  tree to = TREE_OPERAND (*expr_p, 0);
-  tree sub;
-
-  /* If we are initializing something from a TARGET_EXPR, strip the
-     TARGET_EXPR and initialize it directly.  */
-  /* What about code that pulls out the temp and uses it elsewhere?  I
-     think that such code never uses the TARGET_EXPR as an initializer.  If
-     I'm wrong, we'll abort because the temp won't have any RTL.  In that
-     case, I guess we'll need to replace references somehow.  */
-  if (TREE_CODE (from) == TARGET_EXPR)
-    from = TARGET_EXPR_INITIAL (from);
-
-  sub = from;
-
-  /* If we are initializing from a STMT_EXPR, extract the returned
-     expression.  */
-  if (TREE_CODE (from) == STMT_EXPR)
-    sub = EXPR_STMT_EXPR (stmt_expr_last_stmt (from));
-
-  /* Look through any COMPOUND_EXPRs.  */
-  while (TREE_CODE (sub) == COMPOUND_EXPR)
-    sub = TREE_OPERAND (sub, 1);
-
-  /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
-     replace the slot operand with our target.
-
-     Should we add a target parm to gimplify_expr instead?  No, as in this
-     case we want to replace the INIT_EXPR.  */
-  if (TREE_CODE (sub) == AGGR_INIT_EXPR)
-    {
-      gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
-      TREE_OPERAND (sub, 2) = to;
-      *expr_p = from;
-
-      /* The initialization is now a side-effect, so the container can
-         become void.  This is important for a STMT_EXPR, so we don't try
-         to voidify it later by creating a temporary.  */
-      if (from != sub)
-       TREE_TYPE (from) = void_type_node;
-    }
-}
-
-/* Gimplify a MUST_NOT_THROW_EXPR.  */
-
-static void
-gimplify_must_not_throw_expr (tree *expr_p, tree *pre_p)
-{
-  tree stmt = *expr_p;
-  tree temp = voidify_wrapper_expr (stmt);
-  tree body = TREE_OPERAND (stmt, 0);
-
-  gimplify_stmt (&body);
-
-  stmt = gimple_build_eh_filter (body, NULL_TREE,
-                                build_call (terminate_node, NULL_TREE));
-
-  if (temp)
-    {
-      append_to_statement_list (stmt, pre_p);
-      *expr_p = temp;
-    }
-  else
-    *expr_p = stmt;
-}
index 1be4d8afdcc53e1e3c260ec30695359b570b582a..7f45ae9123c055556e015f7583f96da9850f0a81 100644 (file)
@@ -40,7 +40,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "langhooks.h"
 #include "diagnostic.h"
 #include "tree-dump.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 
 /* Prototypes.  */
 
index 8939fc452d35cb9847e6ad1ecee4b020a1035333..d8185353d25d2b6e6eae8e1cc9dcab7864b4ba62 100644 (file)
@@ -1,3 +1,9 @@
+2004-05-13  Diego Novillo  <dnovillo@redhat.com>
+
+       * Make-lang.in, f95-lang.c, trans-array.c, trans-decl.c,
+       trans-expr.c, trans-intrinsic.c, trans-io.c, trans-stmt.c,
+       trans.c: Rename tree-simple.[ch] to tree-gimple.[ch].
+
 2004-05-13  Victor Leikehman  <lei@haifasphere.co.il>
 
        PR fortran/15314
index a38834b471371bb1be293f66cfd80e9414bb3556..f1acba838bf0d6bb95b4c469c6979882a63740b5 100644 (file)
@@ -81,7 +81,7 @@ F95_OBJS = $(F95_PARSER_OBJS) \
 # We rely on c-semantics to expand from GIMPLE to RTL.
 # This should go away once a real GIMPLE expander is available. 
 F95_ADDITIONAL_OBJS = \
-       tree-cfg.o tree-dfa.o tree-optimize.o tree-simple.o \
+       tree-cfg.o tree-dfa.o tree-optimize.o tree-gimple.o \
        tree-ssa.o tree-ssa-ccp.o tree-ssa-dce.o \
        tree-alias-common.o tree-alias-type.o gimplify.o stor-layout.o
 
index 51ce3c4e5302ee562273a76fb32e54081c6da89c..f5cc66ec53d808de8a68c26ab0d485e6f2b1c425 100644 (file)
@@ -28,7 +28,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "flags.h"
 #include "langhooks.h"
 #include "langhooks-def.h"
index 452b0fec81c9b5566b2d857b884fbbedfdca1605..2d95550bc1bdb54451316a0193e35374185f190a 100644 (file)
@@ -80,7 +80,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include <stdio.h>
 #include "ggc.h"
 #include "toplev.h"
index 79e8cf6927eec140101d6c1db8799d8d263fb16f..c1e80508457c41022318a8f7492b9cca5df1a844 100644 (file)
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 #include "coretypes.h"
 #include "tree.h"
 #include "tree-dump.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "ggc.h"
 #include "toplev.h"
 #include "tm.h"
index 1f98f9e1a89c6baaea1a0445afc95a237d0c338b..b0f4139d24d4528c4e8fc714685c3674035ca820 100644 (file)
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "toplev.h"
 #include "real.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "flags.h"
 #include <gmp.h>
 #include <assert.h>
@@ -374,7 +374,7 @@ gfc_conv_unary_op (enum tree_code code, gfc_se * se, gfc_expr * expr)
 
   /* TRUTH_NOT_EXPR is not a "true" unary operator in GCC.
      We must convert it to a compare to 0 (e.g. EQ_EXPR (op1, 0)).
-     All other unary operators have an equivalent SIMPLE unary operator  */
+     All other unary operators have an equivalent GIMPLE unary operator  */
   if (code == TRUTH_NOT_EXPR)
     se->expr = build (EQ_EXPR, type, operand.expr, integer_zero_node);
   else
@@ -796,7 +796,7 @@ gfc_conv_expr_op (gfc_se * se, gfc_expr * expr)
       break;
 
       /* EQV and NEQV only work on logicals, but since we represent them
-         as integers, we can use EQ_EXPR and NE_EXPR for them in SIMPLE.  */
+         as integers, we can use EQ_EXPR and NE_EXPR for them in GIMPLE.  */
     case INTRINSIC_EQ:
     case INTRINSIC_EQV:
       code = EQ_EXPR;
index fb3ceb2f6b1b53fd4f248dc16596828974375771..b58c298b0b7457d29b6a194c1cb6414dc7734cd5 100644 (file)
@@ -31,7 +31,7 @@ Boston, MA 02111-1307, USA.  */
 #include "ggc.h"
 #include "toplev.h"
 #include "real.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "flags.h"
 #include <gmp.h>
 #include <assert.h>
index d18bb7941956d7a3de1a70f38e6d3f192c07b06d..66fffab12e1599a2b6a587fc7094e7095b18645d 100644 (file)
@@ -24,7 +24,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include <stdio.h>
 #include "ggc.h"
 #include "toplev.h"
index 0de62a5367cc05a77f33b812962650891f82ddf4..6c2e669994bf60bd7925ab9fefdeb962ca277eae 100644 (file)
@@ -25,7 +25,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include <stdio.h>
 #include "ggc.h"
 #include "toplev.h"
index aed764d0a36f6a4b294a64a4284a1c3cc5b8b079..a423ac95062e5558e37f77511f6673f8f04f8d66 100644 (file)
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include <stdio.h>
 #include "ggc.h"
 #include "toplev.h"
@@ -443,7 +443,7 @@ gfc_trans_code (gfc_code * code)
 
   gfc_start_block (&block);
 
-  /* Translate statements one by one to SIMPLE trees until we reach
+  /* Translate statements one by one to GIMPLE trees until we reach
      the end of this gfc_code branch.  */
   for (; code; code = code->next)
     {
index af2760279bc10ca92f744d528449d7acaaf44582..56f02b7a1ee47bdde6f8cd575e7cffb3fe48442e 100644 (file)
@@ -27,7 +27,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtl.h"
 #include "errors.h"
 #include "varray.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "diagnostic.h"
 #include "langhooks.h"
index dda218beab4e0dd282919a2b18789484a00faa0e..787dbc3499921b296f0ac8a1caa862d1de0f20f3 100644 (file)
@@ -30,7 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "rtl.h"
 #include "errors.h"
 #include "varray.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "diagnostic.h"
 #include "langhooks.h"
@@ -3029,7 +3029,7 @@ gimplify_to_stmt_list (tree *stmt_p)
 
     GIMPLE_TEST_F points to a function that takes a tree T and
        returns nonzero if T is in the GIMPLE form requested by the
-       caller.  The GIMPLE predicates are in tree-simple.c.
+       caller.  The GIMPLE predicates are in tree-gimple.c.
 
        This test is used twice.  Before gimplification, the test is
        invoked to determine whether *EXPR_P is already gimple enough.  If
index b7cb8c4630ceb611fab322c57af243c672d8966b..dfbf10d5acd1cc68d4548d25f7b12480c01f9133 100644 (file)
@@ -1,3 +1,8 @@
+2004-05-13  Diego Novillo  <dnovillo@redhat.com>
+
+       * Make-lang.in, expr.c, java-gimplify.c: Rename
+       tree-simple.[ch] to tree-gimple.[ch].
+
 2004-05-14  Ranjit Mathew  <rmathew@hotmail.com>
 
        * java-gimplify.c (java_gimplify_expr): Correct minor typos.
index db3ac9d55312789cbcb5eaff5dcf96587d7920b4..367627362dcb15ff3cfcb8db907e8951951c37bf 100644 (file)
@@ -334,7 +334,7 @@ java/xref.o: java/xref.c java/xref.h $(CONFIG_H) $(JAVA_TREE_H) toplev.h \
 java/zextract.o: java/zextract.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
   java/zipfile.h
 java/java-gimplify.o: java/java-gimplify.c $(CONFIG_H) $(SYSTEM_H) \
-  coretypes.h $(TM_H) $(JAVA_TREE_H) tree-simple.h toplev.h
+  coretypes.h $(TM_H) $(JAVA_TREE_H) tree-gimple.h toplev.h
 
 java/parse-scan.o: java/parse-scan.c $(CONFIG_H) $(SYSTEM_H) \
   coretypes.h $(TM_H) toplev.h $(JAVA_LEX_C) java/parse.h java/lex.h input.h
index a63309ec9a43661ceba6c07b9f3dc5fe37c4467e..aa0697420a07d6f7bdfbdf4b5207679e61b43dde 100644 (file)
@@ -43,7 +43,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "toplev.h"
 #include "except.h"
 #include "ggc.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "target.h"
 
 static void flush_quick_stack (void);
index f32a4c809b0d31772d702de1cb0d8d8c0271404d..987351c2102f40238b6a70972044a297188b676b 100644 (file)
@@ -30,7 +30,7 @@ The Free Software Foundation is independent of Sun Microsystems, Inc.  */
 #include "tree.h"
 #include "java-tree.h"
 #include "tree-dump.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "toplev.h"
 
 static tree java_gimplify_case_expr (tree);
index 58e4eb6b21d896be862e48f410e308be21016a69..c82b5fd4f3fdb8af1803f5844dd98030e5b7efea 100644 (file)
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 #include "toplev.h"
 #include "tree.h"
 #include "tree-inline.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "rtl.h"
 #include "insn-config.h"
 #include "integrate.h"
index b3b14d1fa123ec687452f99328ab049872803bda..3f2773428360cbbc6a0471ddbc8ae92489308301 100644 (file)
@@ -41,7 +41,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #include "tree-flow.h"
 #include "tree-inline.h"
 #include "varray.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "splay-tree.h"
 #include "engine/util.h"
 #include "libcompat/regions.h"
index cd36eef594243d884150a9fc2500c0208505c3f3..f7b6fed5f34168df57b9d7760c441b60ac76cb02 100644 (file)
@@ -45,7 +45,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #include "tree-inline.h"
 #include "varray.h"
 #include "c-tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "hashtab.h"
 #include "function.h"
 #include "cgraph.h"
index fe963041a051f22e36a5ea2e566b32ec018d9658..8094d950da3b60632b8f18d3e892c5d2771b8185 100644 (file)
@@ -24,7 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree.h"
 #include "tm.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-iterator.h"
 #include "tree-pass.h"
 #include "flags.h"
index cda68487efb41a419e4e47e73e0490c5581e6f72..2a71ef20fe681d6f2596c1090481b99c705e6b95 100644 (file)
@@ -39,7 +39,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "diagnostic.h"
 #include "tree-dump.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-flow.h"
 #include "tree-inline.h"
 #include "tree-alias-common.h"
index 853eb1a41eb4a1dabe959a855056ff8b8d5bcd47..76f97a4ebf59227fc77dd567fb881613bc3d1d01 100644 (file)
@@ -26,7 +26,7 @@ Boston, MA 02111-1307, USA.  */
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "hashtab.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-ssa-operands.h"
 
 /* Forward declare structures for the garbage collector GTY markers.  */
diff --git a/gcc/tree-gimple.c b/gcc/tree-gimple.c
new file mode 100644 (file)
index 0000000..dbe2966
--- /dev/null
@@ -0,0 +1,642 @@
+/* Functions to analyze and validate GIMPLE trees.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Diego Novillo <dnovillo@redhat.com>
+   Rewritten by Jason Merrill <jason@redhat.com>
+
+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 2, 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 COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "ggc.h"
+#include "tm.h"
+#include "tree.h"
+#include "tree-gimple.h"
+#include "output.h"
+#include "rtl.h"
+#include "expr.h"
+#include "bitmap.h"
+
+/* GCC GIMPLE structure
+
+   Inspired by the SIMPLE C grammar at
+
+       http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
+
+   function:
+     FUNCTION_DECL
+       DECL_SAVED_TREE -> block
+   block:
+     BIND_EXPR
+       BIND_EXPR_VARS -> DECL chain
+       BIND_EXPR_BLOCK -> BLOCK
+       BIND_EXPR_BODY -> compound-stmt
+   compound-stmt:
+     COMPOUND_EXPR
+       op0 -> non-compound-stmt
+       op1 -> stmt
+     | EXPR_VEC
+       (or other alternate solution)
+   stmt: compound-stmt | non-compound-stmt
+   non-compound-stmt:
+     block
+     | if-stmt
+     | switch-stmt
+     | jump-stmt
+     | label-stmt
+     | try-stmt
+     | modify-stmt
+     | call-stmt
+   if-stmt:
+     COND_EXPR
+       op0 -> condition
+       op1 -> stmt
+       op2 -> stmt
+   switch-stmt:
+     SWITCH_EXPR
+       op0 -> val
+       op1 -> stmt
+       op2 -> array of case labels (as LABEL_DECLs?)
+         FIXME: add case value info
+   jump-stmt:
+       GOTO_EXPR
+         op0 -> LABEL_DECL | '*' ID
+     | RETURN_EXPR
+         op0 -> modify-stmt | NULL_TREE
+        (maybe -> RESULT_DECL | NULL_TREE? seems like some of expand_return
+         depends on getting a MODIFY_EXPR.)
+     | THROW_EXPR?  do we need/want such a thing for opts, perhaps
+         to generate an ERT_THROW region?  I think so.
+        Hmm...this would only work at the GIMPLE level, where we know that
+          the call args don't have any EH impact.  Perhaps
+          annotation of the CALL_EXPR would work better.
+     | RESX_EXPR
+   label-stmt:
+     LABEL_EXPR
+         op0 -> LABEL_DECL
+     | CASE_LABEL_EXPR
+         CASE_LOW -> val | NULL_TREE
+         CASE_HIGH -> val | NULL_TREE
+        CASE_LABEL -> LABEL_DECL  FIXME
+   try-stmt:
+     TRY_CATCH_EXPR
+       op0 -> stmt
+       op1 -> handler
+     | TRY_FINALLY_EXPR
+       op0 -> stmt
+       op1 -> stmt
+   handler:
+     catch-seq
+     | EH_FILTER_EXPR
+     | stmt
+   modify-stmt:
+     MODIFY_EXPR
+       op0 -> lhs
+       op1 -> rhs
+   call-stmt: CALL_EXPR
+     op0 -> ID | '&' ID
+     op1 -> arglist
+
+   addr-expr-arg : compref | ID
+   lhs: addr-expr-arg | '*' ID | bitfieldref
+   min-lval: ID | '*' ID
+   bitfieldref :
+     BIT_FIELD_REF
+       op0 -> compref | min-lval
+       op1 -> CONST
+       op2 -> CONST
+   compref :
+     COMPONENT_REF
+       op0 -> compref | min-lval
+     | ARRAY_REF
+       op0 -> compref | min-lval
+       op1 -> val
+     | REALPART_EXPR
+     | IMAGPART_EXPR
+
+   condition : val | val relop val
+   val : ID | CONST
+
+   rhs        : varname | CONST
+             | '*' ID
+             | '&' addr-expr-arg
+             | call_expr
+             | unop val
+             | val binop val
+             | '(' cast ')' val
+
+             (cast here stands for all valid C typecasts)
+
+      unop
+             : '+'
+             | '-'
+             | '!'
+             | '~'
+
+      binop
+             : relop | '-'
+             | '+'
+             | '/'
+             | '*'
+             | '%'
+             | '&'
+             | '|'
+             | '<<'
+             | '>>'
+             | '^'
+
+      relop
+             : '<'
+             | '<='
+             | '>'
+             | '>='
+             | '=='
+             | '!='
+
+*/
+
+static inline bool is_gimple_id (tree);
+
+/* Validation of GIMPLE expressions.  */
+
+/* Return nonzero if T is a GIMPLE RHS:
+
+      rhs     : varname | CONST
+             | '*' ID
+             | '&' varname_or_temp
+             | call_expr
+             | unop val
+             | val binop val
+             | '(' cast ')' val
+             | <CONSTRUCTOR <gimple_val ...>>
+
+   The last option is only valid GIMPLE for vector and complex types;
+   aggregate types should have their constructors decomposed.  */
+
+bool
+is_gimple_rhs (tree t)
+{
+  enum tree_code code = TREE_CODE (t);
+
+  switch (TREE_CODE_CLASS (code))
+    {
+    case '1':
+    case '2':
+    case '<':
+      return 1;
+
+    default:
+      break;
+    }
+
+  switch (code)
+    {
+    case TRUTH_NOT_EXPR:
+    case TRUTH_AND_EXPR:
+    case TRUTH_OR_EXPR:
+    case TRUTH_XOR_EXPR:
+    case ADDR_EXPR:
+    case CALL_EXPR:
+    case CONSTRUCTOR:
+    case COMPLEX_EXPR:
+      /* FIXME lower VA_ARG_EXPR.  */
+    case VA_ARG_EXPR:
+    case INTEGER_CST:
+    case REAL_CST:
+    case STRING_CST:
+    case COMPLEX_CST:
+    case VECTOR_CST:
+      return 1;
+
+    default:
+      break;
+    }
+
+  if (is_gimple_lvalue (t) || is_gimple_val (t))
+    return 1;
+
+  return 0;
+}
+
+/* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either
+   a val or another CONSTRUCTOR.  */
+
+bool
+is_gimple_constructor_elt (tree t)
+{
+  return (is_gimple_val (t)
+         || TREE_CODE (t) == CONSTRUCTOR);
+}
+
+/*  Return nonzero if T is a valid LHS for a GIMPLE assignment expression.  */
+
+bool
+is_gimple_lvalue (tree t)
+{
+  return (is_gimple_addr_expr_arg (t)
+         || TREE_CODE (t) == INDIRECT_REF
+         /* These are complex lvalues, but don't have addresses, so they
+            go here.  */
+         || TREE_CODE (t) == BIT_FIELD_REF);
+}
+
+
+/*  Return nonzero if T is a GIMPLE condition:
+
+      condexpr
+             : val
+             | val relop val  */
+
+bool
+is_gimple_condexpr (tree t)
+{
+  return (is_gimple_val (t)
+         || TREE_CODE_CLASS (TREE_CODE (t)) == '<');
+}
+
+
+/*  Return nonzero if T is a valid operand for '&':
+
+      varname
+             : arrayref
+             | compref
+             | ID     */
+
+bool
+is_gimple_addr_expr_arg (tree t)
+{
+  return (is_gimple_id (t)
+         || TREE_CODE (t) == ARRAY_REF
+         || TREE_CODE (t) == COMPONENT_REF
+         || TREE_CODE (t) == REALPART_EXPR
+         || TREE_CODE (t) == IMAGPART_EXPR);
+}
+
+/* Return nonzero if T is function invariant.  Or rather a restricted
+   form of function invariant.  */
+
+bool
+is_gimple_min_invariant (tree t)
+{
+  switch (TREE_CODE (t))
+    {
+    case ADDR_EXPR:
+      return TREE_INVARIANT (t);
+
+    case INTEGER_CST:
+    case REAL_CST:
+    case STRING_CST:
+    case COMPLEX_CST:
+    case VECTOR_CST:
+      return !TREE_OVERFLOW (t);
+
+    default:
+      return false;
+    }
+}
+
+/* Return nonzero if T looks like a valid GIMPLE statement.  */
+
+bool
+is_gimple_stmt (tree t)
+{
+  enum tree_code code = TREE_CODE (t);
+
+  if (IS_EMPTY_STMT (t))
+    return 1;
+
+  switch (code)
+    {
+    case BIND_EXPR:
+    case COND_EXPR:
+      /* These are only valid if they're void.  */
+      return VOID_TYPE_P (TREE_TYPE (t));
+
+    case SWITCH_EXPR:
+    case GOTO_EXPR:
+    case RETURN_EXPR:
+    case LABEL_EXPR:
+    case CASE_LABEL_EXPR:
+    case TRY_CATCH_EXPR:
+    case TRY_FINALLY_EXPR:
+    case EH_FILTER_EXPR:
+    case CATCH_EXPR:
+    case ASM_EXPR:
+    case RESX_EXPR:
+    case PHI_NODE:
+    case STATEMENT_LIST:
+      /* These are always void.  */
+      return 1;
+
+    case VA_ARG_EXPR:
+      /* FIXME this should be lowered.  */
+      return 1;
+
+    case COMPOUND_EXPR:
+      /* FIXME should we work harder to make COMPOUND_EXPRs void?  */
+    case CALL_EXPR:
+    case MODIFY_EXPR:
+      /* These are valid regardless of their type.  */
+      return 1;
+
+    default:
+      return 0;
+    }
+}
+
+/* Return nonzero if T is a variable.  */
+
+bool
+is_gimple_variable (tree t)
+{
+  return (TREE_CODE (t) == VAR_DECL
+         || TREE_CODE (t) == PARM_DECL
+         || TREE_CODE (t) == RESULT_DECL
+         || TREE_CODE (t) == SSA_NAME);
+}
+
+/*  Return nonzero if T is a GIMPLE identifier (something with an address).  */
+
+static inline bool
+is_gimple_id (tree t)
+{
+  return (is_gimple_variable (t)
+         || TREE_CODE (t) == FUNCTION_DECL
+         || TREE_CODE (t) == LABEL_DECL
+         /* Allow string constants, since they are addressable.  */
+         || TREE_CODE (t) == STRING_CST);
+}
+
+/* Return nonzero if TYPE is a suitable type for a scalar register
+   variable.  */
+
+bool
+is_gimple_reg_type (tree type)
+{
+  return (!AGGREGATE_TYPE_P (type)
+          && TREE_CODE (type) != COMPLEX_TYPE);
+}
+
+
+/* Return nonzero if T is a scalar register variable.  */
+
+bool
+is_gimple_reg (tree t)
+{
+  if (TREE_CODE (t) == SSA_NAME)
+    t = SSA_NAME_VAR (t);
+
+  return (is_gimple_variable (t)
+         && is_gimple_reg_type (TREE_TYPE (t))
+         /* A volatile decl is not acceptable because we can't reuse it as
+            needed.  We need to copy it into a temp first.  */
+         && ! TREE_THIS_VOLATILE (t)
+         && ! TREE_ADDRESSABLE (t)
+         && ! needs_to_live_in_memory (t));
+}
+
+/* Return nonzero if T is a GIMPLE variable whose address is not needed.  */
+
+bool
+is_gimple_non_addressable (tree t)
+{
+  if (TREE_CODE (t) == SSA_NAME)
+    t = SSA_NAME_VAR (t);
+
+  return (is_gimple_variable (t)
+         && ! TREE_ADDRESSABLE (t)
+         && ! needs_to_live_in_memory (t));
+}
+
+/*  Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a
+    constant.  */
+
+bool
+is_gimple_val (tree t)
+{
+  /* Make loads from volatiles and memory vars explicit.  */
+  if (is_gimple_variable (t)
+      && is_gimple_reg_type (TREE_TYPE (t))
+      && !is_gimple_reg (t))
+    return 0;
+
+  /* FIXME make these decls.  That can happen only when we expose the
+     entire landing-pad construct at the tree level.  */
+  if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
+    return 1;
+
+  return (is_gimple_variable (t) || is_gimple_min_invariant (t));
+}
+
+
+/*  Return true if T is a GIMPLE minimal lvalue, of the form
+
+    min_lval: ID | '(' '*' ID ')'
+
+    This never actually appears in the original SIMPLE grammar, but is
+    repeated in several places.  */
+
+bool
+is_gimple_min_lval (tree t)
+{
+  return (is_gimple_id (t)
+         || TREE_CODE (t) == INDIRECT_REF);
+}
+
+/*  Return nonzero if T is a typecast operation of the form
+    '(' cast ')' val.  */
+
+bool
+is_gimple_cast (tree t)
+{
+  return (TREE_CODE (t) == NOP_EXPR
+         || TREE_CODE (t) == CONVERT_EXPR
+          || TREE_CODE (t) == FIX_TRUNC_EXPR
+          || TREE_CODE (t) == FIX_CEIL_EXPR
+          || TREE_CODE (t) == FIX_FLOOR_EXPR
+          || TREE_CODE (t) == FIX_ROUND_EXPR);
+}
+
+
+/* If T makes a function call, return the corresponding CALL_EXPR operand.
+   Otherwise, return NULL_TREE.  */
+
+tree
+get_call_expr_in (tree t)
+{
+  if (TREE_CODE (t) == CALL_EXPR)
+    return t;
+  else if (TREE_CODE (t) == MODIFY_EXPR
+          && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
+    return TREE_OPERAND (t, 1);
+  else if (TREE_CODE (t) == RETURN_EXPR
+           && TREE_OPERAND (t, 0)
+          && TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
+          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == CALL_EXPR)
+    return TREE_OPERAND (TREE_OPERAND (t, 0), 1);
+
+  return NULL_TREE;
+}
+
+
+/* Given an _EXPR TOP, reorganize all of the nested _EXPRs with the same
+   code so that they only appear as the second operand.  This should only
+   be used for tree codes which are truly associative, such as
+   COMPOUND_EXPR and TRUTH_ANDIF_EXPR.  Arithmetic is not associative
+   enough, due to the limited precision of arithmetic data types.
+
+   This transformation is conservative; the operand 0 of a matching tree
+   node will only change if it is also a matching node.  */
+
+tree
+right_assocify_expr (tree top)
+{
+  tree *p = &top;
+  enum tree_code code = TREE_CODE (*p);
+  while (TREE_CODE (*p) == code)
+    {
+      tree cur = *p;
+      tree lhs = TREE_OPERAND (cur, 0);
+      if (TREE_CODE (lhs) == code)
+       {
+         /* There's a left-recursion.  If we have ((a, (b, c)), d), we
+            want to rearrange to (a, (b, (c, d))).  */
+         tree *q;
+
+         /* Replace cur with the lhs; move (a, *) up.  */
+         *p = lhs;
+
+         if (code == COMPOUND_EXPR)
+           {
+             /* We need to give (b, c) the type of c; previously lhs had
+                the type of b.  */
+             TREE_TYPE (lhs) = TREE_TYPE (cur);
+             if (TREE_SIDE_EFFECTS (cur))
+               TREE_SIDE_EFFECTS (lhs) = 1;
+           }
+
+         /* Walk through the op1 chain from there until we find something
+            with a different code.  In this case, c.  */
+         for (q = &TREE_OPERAND (lhs, 1); TREE_CODE (*q) == code;
+              q = &TREE_OPERAND (*q, 1))
+           TREE_TYPE (*q) = TREE_TYPE (cur);
+
+         /* Change (*, d) into (c, d).  */
+         TREE_OPERAND (cur, 0) = *q;
+
+         /* And plug it in where c used to be.  */
+         *q = cur;
+       }
+      else
+       p = &TREE_OPERAND (cur, 1);
+    }
+  return top;
+}
+
+/* Normalize the statement TOP.  If it is a COMPOUND_EXPR, reorganize it so
+   that we can traverse it without recursion.  If it is null, replace it
+   with a nop.  */
+
+tree
+rationalize_compound_expr (tree top)
+{
+  if (top == NULL_TREE)
+    top = build_empty_stmt ();
+  else if (TREE_CODE (top) == COMPOUND_EXPR)
+    top = right_assocify_expr (top);
+
+  return top;
+}
+
+/* Given a memory reference expression, return the base address.  Note that,
+   in contrast with get_base_var, this will not recurse inside INDIRECT_REF
+   expressions.  Therefore, given the reference PTR->FIELD, this function
+   will return *PTR.  Whereas get_base_var would've returned PTR.  */
+
+tree
+get_base_address (tree t)
+{
+  do
+    {
+      if (SSA_VAR_P (t)
+         || TREE_CODE (t) == INDIRECT_REF)
+       return t;
+
+      switch (TREE_CODE (t))
+       {
+       case ARRAY_REF:
+       case COMPONENT_REF:
+       case REALPART_EXPR:
+       case IMAGPART_EXPR:
+       case BIT_FIELD_REF:
+         t = TREE_OPERAND (t, 0);
+         break;
+
+       default:
+         return NULL_TREE;
+       }
+    }
+  while (t);
+
+  return t;
+}
+
+
+void
+recalculate_side_effects (tree t)
+{
+  enum tree_code code = TREE_CODE (t);
+  int fro = first_rtl_op (code);
+  int i;
+
+  switch (TREE_CODE_CLASS (code))
+    {
+    case 'e':
+      switch (code)
+       {
+       case INIT_EXPR:
+       case MODIFY_EXPR:
+       case VA_ARG_EXPR:
+       case RTL_EXPR:
+       case PREDECREMENT_EXPR:
+       case PREINCREMENT_EXPR:
+       case POSTDECREMENT_EXPR:
+       case POSTINCREMENT_EXPR:
+         /* All of these have side-effects, no matter what their
+            operands are.  */
+         return;
+
+       default:
+         break;
+       }
+      /* Fall through.  */
+
+    case '<':  /* a comparison expression */
+    case '1':  /* a unary arithmetic expression */
+    case '2':  /* a binary arithmetic expression */
+    case 'r':  /* a reference */
+      TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
+      for (i = 0; i < fro; ++i)
+       {
+         tree op = TREE_OPERAND (t, i);
+         if (op && TREE_SIDE_EFFECTS (op))
+           TREE_SIDE_EFFECTS (t) = 1;
+       }
+      break;
+   }
+}
diff --git a/gcc/tree-gimple.h b/gcc/tree-gimple.h
new file mode 100644 (file)
index 0000000..d2c9103
--- /dev/null
@@ -0,0 +1,127 @@
+/* Functions to analyze and validate GIMPLE trees.
+   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+   Contributed by Diego Novillo <dnovillo@redhat.com>
+
+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 2, 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 COPYING.  If not, write to
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifndef _TREE_SIMPLE_H
+#define _TREE_SIMPLE_H 1
+
+
+#include "tree-iterator.h"
+
+extern tree create_tmp_var_raw (tree, const char *);
+extern tree create_tmp_var (tree, const char *);
+extern bool is_gimple_tmp_var (tree);
+extern tree get_initialized_tmp_var (tree, tree *, tree *);
+extern tree get_formal_tmp_var (tree, tree *);
+extern void declare_tmp_vars (tree, tree);
+
+extern tree rationalize_compound_expr (tree);
+extern tree right_assocify_expr (tree);
+extern void annotate_all_with_locus (tree *, location_t);
+
+/* Validation of GIMPLE expressions.  Note that these predicates only check
+   the basic form of the expression, they don't recurse to make sure that
+   underlying nodes are also of the right form.  */
+
+/* Returns true iff T is a valid GIMPLE statement.  */
+bool is_gimple_stmt (tree);
+
+/* Returns true iff TYPE is a valid type for a scalar register variable.  */
+bool is_gimple_reg_type (tree);
+/* Returns true iff T is a scalar register variable.  */
+bool is_gimple_reg (tree);
+/* Returns true iff T is any sort of variable.  */
+bool is_gimple_variable (tree);
+/* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
+bool is_gimple_min_lval (tree);
+/* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
+bool is_gimple_addr_expr_arg (tree);
+/* Returns true iff T is any valid GIMPLE lvalue.  */
+bool is_gimple_lvalue (tree);
+
+/* Returns true iff T is a GIMPLE restricted function invariant.  */
+bool is_gimple_min_invariant (tree);
+/* Returns true iff T is a GIMPLE rvalue.  */
+bool is_gimple_val (tree);
+/* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
+bool is_gimple_rhs (tree);
+
+/* Returns true iff T is a valid if-statement condition.  */
+bool is_gimple_condexpr (tree);
+
+/* Returns true iff T is a type conversion.  */
+bool is_gimple_cast (tree);
+/* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
+   another CONSTRUCTOR).  */
+bool is_gimple_constructor_elt (tree);
+/* Returns true iff T is a variable that does not need to live in memory.  */
+bool is_gimple_non_addressable (tree t);
+
+/* If T makes a function call, returns the CALL_EXPR operand.  */
+tree get_call_expr_in (tree t);
+
+void recalculate_side_effects (tree);
+
+void append_to_statement_list (tree, tree *);
+void append_to_statement_list_force (tree, tree *);
+void append_to_compound_expr (tree, tree *);
+
+/* FIXME we should deduce this from the predicate.  */
+typedef enum fallback_t {
+  fb_none = 0,
+  fb_rvalue = 1,
+  fb_lvalue = 2,
+  fb_mayfail = 4,
+  fb_either= fb_rvalue | fb_lvalue
+} fallback_t;
+
+enum gimplify_status {
+  GS_ERROR     = -2,   /* Something Bad Seen.  */
+  GS_UNHANDLED = -1,   /* A langhook result for "I dunno".  */
+  GS_OK                = 0,    /* We did something, maybe more to do.  */
+  GS_ALL_DONE  = 1     /* The expression is fully gimplified.  */
+};
+
+enum gimplify_status gimplify_expr (tree *, tree *, tree *,
+                                   bool (*) (tree), fallback_t);
+void gimplify_stmt (tree *);
+void gimplify_to_stmt_list (tree *);
+void gimplify_body (tree *, tree);
+void push_gimplify_context (void);
+void pop_gimplify_context (tree);
+
+/* Miscellaneous helpers.  */
+tree get_base_address (tree t);
+void gimple_add_tmp_var (tree);
+tree gimple_current_bind_expr (void);
+void gimple_push_bind_expr (tree);
+void gimple_pop_bind_expr (void);
+void unshare_all_trees (tree);
+tree voidify_wrapper_expr (tree);
+tree gimple_build_eh_filter (tree, tree, tree);
+tree build_and_jump (tree *);
+tree alloc_stmt_list (void);
+void free_stmt_list (tree);
+tree force_labels_r (tree *, int *, void *);
+
+/* In tree-nested.c.  */
+extern void lower_nested_functions (tree);
+
+#endif /* _TREE_SIMPLE_H  */
index feb395f5c4b6bb4b4af9f199f3d820b5f3f7706c..cf50b9b18c247693b7aacf2699cc1b2c9a104c2e 100644 (file)
@@ -46,7 +46,7 @@ Boston, MA 02111-1307, USA.  */
 /* I'm not real happy about this, but we need to handle gimple and
    non-gimple trees.  */
 #include "tree-iterator.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 
 /* 0 if we should not perform inlining.
    1 if we should expand functions calls inline at the tree level.
index 4e19142afd0f6bcdaa4eac84421a9289cc478290..a569d0536b1937693989c40071a9ede4b0fac89e 100644 (file)
@@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "varray.h"
 #include "timevar.h"
index 3f0eb5c9dc37b129ff9b1a7d9b5a006e050735d3..ebc477b68d043ceb707569359ac2512bbf8a7e14 100644 (file)
@@ -23,7 +23,7 @@ Boston, MA 02111-1307, USA.  */
 #include "system.h"
 #include "coretypes.h"
 #include "tree.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-iterator.h"
 #include "ggc.h"
 
index 9172541af39b6e264f530c982b25ad2343ff8e96..474c7c455469d2e70913ab94ced1cfaa5765de66 100644 (file)
@@ -30,7 +30,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "flags.h"
 #include "function.h"
 #include "tree-inline.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-flow.h"
 #include "tree-mudflap.h"
 #include "tree-dump.h"
index 7b92a75db30d4b06caa51cdd60bd1584cec1d7f4..1a00ff30f864fed5dc11740f1db38d4fac81ed71 100644 (file)
@@ -28,7 +28,7 @@
 #include "function.h"
 #include "tree-dump.h"
 #include "tree-inline.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-iterator.h"
 #include "tree-flow.h"
 #include "cgraph.h"
index 420fc39a88b5d3ef8da0256d4890dfd00396b71f..1e30194f77eac3aaf565ceb6e3456a7945507468 100644 (file)
@@ -29,7 +29,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree-inline.h"
 #include "c-tree.h"
 #include "c-common.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "diagnostic.h"
 #include "hashtab.h"
 #include "output.h"
index af5bf51f2acf3ed9503fcec3e7da8f9b9cd35492..97b0b4a3e82cdb5b38ca7108cb6a2499fbb54972 100644 (file)
@@ -38,7 +38,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "varray.h"
 #include "timevar.h"
diff --git a/gcc/tree-simple.c b/gcc/tree-simple.c
deleted file mode 100644 (file)
index 0215088..0000000
+++ /dev/null
@@ -1,642 +0,0 @@
-/* Functions to analyze and validate GIMPLE trees.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   Contributed by Diego Novillo <dnovillo@redhat.com>
-   Rewritten by Jason Merrill <jason@redhat.com>
-
-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 2, 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 COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "ggc.h"
-#include "tm.h"
-#include "tree.h"
-#include "tree-simple.h"
-#include "output.h"
-#include "rtl.h"
-#include "expr.h"
-#include "bitmap.h"
-
-/* GCC GIMPLE structure
-
-   Inspired by the SIMPLE C grammar at
-
-       http://www-acaps.cs.mcgill.ca/info/McCAT/McCAT.html
-
-   function:
-     FUNCTION_DECL
-       DECL_SAVED_TREE -> block
-   block:
-     BIND_EXPR
-       BIND_EXPR_VARS -> DECL chain
-       BIND_EXPR_BLOCK -> BLOCK
-       BIND_EXPR_BODY -> compound-stmt
-   compound-stmt:
-     COMPOUND_EXPR
-       op0 -> non-compound-stmt
-       op1 -> stmt
-     | EXPR_VEC
-       (or other alternate solution)
-   stmt: compound-stmt | non-compound-stmt
-   non-compound-stmt:
-     block
-     | if-stmt
-     | switch-stmt
-     | jump-stmt
-     | label-stmt
-     | try-stmt
-     | modify-stmt
-     | call-stmt
-   if-stmt:
-     COND_EXPR
-       op0 -> condition
-       op1 -> stmt
-       op2 -> stmt
-   switch-stmt:
-     SWITCH_EXPR
-       op0 -> val
-       op1 -> stmt
-       op2 -> array of case labels (as LABEL_DECLs?)
-         FIXME: add case value info
-   jump-stmt:
-       GOTO_EXPR
-         op0 -> LABEL_DECL | '*' ID
-     | RETURN_EXPR
-         op0 -> modify-stmt | NULL_TREE
-        (maybe -> RESULT_DECL | NULL_TREE? seems like some of expand_return
-         depends on getting a MODIFY_EXPR.)
-     | THROW_EXPR?  do we need/want such a thing for opts, perhaps
-         to generate an ERT_THROW region?  I think so.
-        Hmm...this would only work at the GIMPLE level, where we know that
-          the call args don't have any EH impact.  Perhaps
-          annotation of the CALL_EXPR would work better.
-     | RESX_EXPR
-   label-stmt:
-     LABEL_EXPR
-         op0 -> LABEL_DECL
-     | CASE_LABEL_EXPR
-         CASE_LOW -> val | NULL_TREE
-         CASE_HIGH -> val | NULL_TREE
-        CASE_LABEL -> LABEL_DECL  FIXME
-   try-stmt:
-     TRY_CATCH_EXPR
-       op0 -> stmt
-       op1 -> handler
-     | TRY_FINALLY_EXPR
-       op0 -> stmt
-       op1 -> stmt
-   handler:
-     catch-seq
-     | EH_FILTER_EXPR
-     | stmt
-   modify-stmt:
-     MODIFY_EXPR
-       op0 -> lhs
-       op1 -> rhs
-   call-stmt: CALL_EXPR
-     op0 -> ID | '&' ID
-     op1 -> arglist
-
-   addr-expr-arg : compref | ID
-   lhs: addr-expr-arg | '*' ID | bitfieldref
-   min-lval: ID | '*' ID
-   bitfieldref :
-     BIT_FIELD_REF
-       op0 -> compref | min-lval
-       op1 -> CONST
-       op2 -> CONST
-   compref :
-     COMPONENT_REF
-       op0 -> compref | min-lval
-     | ARRAY_REF
-       op0 -> compref | min-lval
-       op1 -> val
-     | REALPART_EXPR
-     | IMAGPART_EXPR
-
-   condition : val | val relop val
-   val : ID | CONST
-
-   rhs        : varname | CONST
-             | '*' ID
-             | '&' addr-expr-arg
-             | call_expr
-             | unop val
-             | val binop val
-             | '(' cast ')' val
-
-             (cast here stands for all valid C typecasts)
-
-      unop
-             : '+'
-             | '-'
-             | '!'
-             | '~'
-
-      binop
-             : relop | '-'
-             | '+'
-             | '/'
-             | '*'
-             | '%'
-             | '&'
-             | '|'
-             | '<<'
-             | '>>'
-             | '^'
-
-      relop
-             : '<'
-             | '<='
-             | '>'
-             | '>='
-             | '=='
-             | '!='
-
-*/
-
-static inline bool is_gimple_id (tree);
-
-/* Validation of GIMPLE expressions.  */
-
-/* Return nonzero if T is a GIMPLE RHS:
-
-      rhs     : varname | CONST
-             | '*' ID
-             | '&' varname_or_temp
-             | call_expr
-             | unop val
-             | val binop val
-             | '(' cast ')' val
-             | <CONSTRUCTOR <gimple_val ...>>
-
-   The last option is only valid GIMPLE for vector and complex types;
-   aggregate types should have their constructors decomposed.  */
-
-bool
-is_gimple_rhs (tree t)
-{
-  enum tree_code code = TREE_CODE (t);
-
-  switch (TREE_CODE_CLASS (code))
-    {
-    case '1':
-    case '2':
-    case '<':
-      return 1;
-
-    default:
-      break;
-    }
-
-  switch (code)
-    {
-    case TRUTH_NOT_EXPR:
-    case TRUTH_AND_EXPR:
-    case TRUTH_OR_EXPR:
-    case TRUTH_XOR_EXPR:
-    case ADDR_EXPR:
-    case CALL_EXPR:
-    case CONSTRUCTOR:
-    case COMPLEX_EXPR:
-      /* FIXME lower VA_ARG_EXPR.  */
-    case VA_ARG_EXPR:
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-    case VECTOR_CST:
-      return 1;
-
-    default:
-      break;
-    }
-
-  if (is_gimple_lvalue (t) || is_gimple_val (t))
-    return 1;
-
-  return 0;
-}
-
-/* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either
-   a val or another CONSTRUCTOR.  */
-
-bool
-is_gimple_constructor_elt (tree t)
-{
-  return (is_gimple_val (t)
-         || TREE_CODE (t) == CONSTRUCTOR);
-}
-
-/*  Return nonzero if T is a valid LHS for a GIMPLE assignment expression.  */
-
-bool
-is_gimple_lvalue (tree t)
-{
-  return (is_gimple_addr_expr_arg (t)
-         || TREE_CODE (t) == INDIRECT_REF
-         /* These are complex lvalues, but don't have addresses, so they
-            go here.  */
-         || TREE_CODE (t) == BIT_FIELD_REF);
-}
-
-
-/*  Return nonzero if T is a GIMPLE condition:
-
-      condexpr
-             : val
-             | val relop val  */
-
-bool
-is_gimple_condexpr (tree t)
-{
-  return (is_gimple_val (t)
-         || TREE_CODE_CLASS (TREE_CODE (t)) == '<');
-}
-
-
-/*  Return nonzero if T is a valid operand for '&':
-
-      varname
-             : arrayref
-             | compref
-             | ID     */
-
-bool
-is_gimple_addr_expr_arg (tree t)
-{
-  return (is_gimple_id (t)
-         || TREE_CODE (t) == ARRAY_REF
-         || TREE_CODE (t) == COMPONENT_REF
-         || TREE_CODE (t) == REALPART_EXPR
-         || TREE_CODE (t) == IMAGPART_EXPR);
-}
-
-/* Return nonzero if T is function invariant.  Or rather a restricted
-   form of function invariant.  */
-
-bool
-is_gimple_min_invariant (tree t)
-{
-  switch (TREE_CODE (t))
-    {
-    case ADDR_EXPR:
-      return TREE_INVARIANT (t);
-
-    case INTEGER_CST:
-    case REAL_CST:
-    case STRING_CST:
-    case COMPLEX_CST:
-    case VECTOR_CST:
-      return !TREE_OVERFLOW (t);
-
-    default:
-      return false;
-    }
-}
-
-/* Return nonzero if T looks like a valid GIMPLE statement.  */
-
-bool
-is_gimple_stmt (tree t)
-{
-  enum tree_code code = TREE_CODE (t);
-
-  if (IS_EMPTY_STMT (t))
-    return 1;
-
-  switch (code)
-    {
-    case BIND_EXPR:
-    case COND_EXPR:
-      /* These are only valid if they're void.  */
-      return VOID_TYPE_P (TREE_TYPE (t));
-
-    case SWITCH_EXPR:
-    case GOTO_EXPR:
-    case RETURN_EXPR:
-    case LABEL_EXPR:
-    case CASE_LABEL_EXPR:
-    case TRY_CATCH_EXPR:
-    case TRY_FINALLY_EXPR:
-    case EH_FILTER_EXPR:
-    case CATCH_EXPR:
-    case ASM_EXPR:
-    case RESX_EXPR:
-    case PHI_NODE:
-    case STATEMENT_LIST:
-      /* These are always void.  */
-      return 1;
-
-    case VA_ARG_EXPR:
-      /* FIXME this should be lowered.  */
-      return 1;
-
-    case COMPOUND_EXPR:
-      /* FIXME should we work harder to make COMPOUND_EXPRs void?  */
-    case CALL_EXPR:
-    case MODIFY_EXPR:
-      /* These are valid regardless of their type.  */
-      return 1;
-
-    default:
-      return 0;
-    }
-}
-
-/* Return nonzero if T is a variable.  */
-
-bool
-is_gimple_variable (tree t)
-{
-  return (TREE_CODE (t) == VAR_DECL
-         || TREE_CODE (t) == PARM_DECL
-         || TREE_CODE (t) == RESULT_DECL
-         || TREE_CODE (t) == SSA_NAME);
-}
-
-/*  Return nonzero if T is a GIMPLE identifier (something with an address).  */
-
-static inline bool
-is_gimple_id (tree t)
-{
-  return (is_gimple_variable (t)
-         || TREE_CODE (t) == FUNCTION_DECL
-         || TREE_CODE (t) == LABEL_DECL
-         /* Allow string constants, since they are addressable.  */
-         || TREE_CODE (t) == STRING_CST);
-}
-
-/* Return nonzero if TYPE is a suitable type for a scalar register
-   variable.  */
-
-bool
-is_gimple_reg_type (tree type)
-{
-  return (!AGGREGATE_TYPE_P (type)
-          && TREE_CODE (type) != COMPLEX_TYPE);
-}
-
-
-/* Return nonzero if T is a scalar register variable.  */
-
-bool
-is_gimple_reg (tree t)
-{
-  if (TREE_CODE (t) == SSA_NAME)
-    t = SSA_NAME_VAR (t);
-
-  return (is_gimple_variable (t)
-         && is_gimple_reg_type (TREE_TYPE (t))
-         /* A volatile decl is not acceptable because we can't reuse it as
-            needed.  We need to copy it into a temp first.  */
-         && ! TREE_THIS_VOLATILE (t)
-         && ! TREE_ADDRESSABLE (t)
-         && ! needs_to_live_in_memory (t));
-}
-
-/* Return nonzero if T is a GIMPLE variable whose address is not needed.  */
-
-bool
-is_gimple_non_addressable (tree t)
-{
-  if (TREE_CODE (t) == SSA_NAME)
-    t = SSA_NAME_VAR (t);
-
-  return (is_gimple_variable (t)
-         && ! TREE_ADDRESSABLE (t)
-         && ! needs_to_live_in_memory (t));
-}
-
-/*  Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a
-    constant.  */
-
-bool
-is_gimple_val (tree t)
-{
-  /* Make loads from volatiles and memory vars explicit.  */
-  if (is_gimple_variable (t)
-      && is_gimple_reg_type (TREE_TYPE (t))
-      && !is_gimple_reg (t))
-    return 0;
-
-  /* FIXME make these decls.  That can happen only when we expose the
-     entire landing-pad construct at the tree level.  */
-  if (TREE_CODE (t) == EXC_PTR_EXPR || TREE_CODE (t) == FILTER_EXPR)
-    return 1;
-
-  return (is_gimple_variable (t) || is_gimple_min_invariant (t));
-}
-
-
-/*  Return true if T is a GIMPLE minimal lvalue, of the form
-
-    min_lval: ID | '(' '*' ID ')'
-
-    This never actually appears in the original SIMPLE grammar, but is
-    repeated in several places.  */
-
-bool
-is_gimple_min_lval (tree t)
-{
-  return (is_gimple_id (t)
-         || TREE_CODE (t) == INDIRECT_REF);
-}
-
-/*  Return nonzero if T is a typecast operation of the form
-    '(' cast ')' val.  */
-
-bool
-is_gimple_cast (tree t)
-{
-  return (TREE_CODE (t) == NOP_EXPR
-         || TREE_CODE (t) == CONVERT_EXPR
-          || TREE_CODE (t) == FIX_TRUNC_EXPR
-          || TREE_CODE (t) == FIX_CEIL_EXPR
-          || TREE_CODE (t) == FIX_FLOOR_EXPR
-          || TREE_CODE (t) == FIX_ROUND_EXPR);
-}
-
-
-/* If T makes a function call, return the corresponding CALL_EXPR operand.
-   Otherwise, return NULL_TREE.  */
-
-tree
-get_call_expr_in (tree t)
-{
-  if (TREE_CODE (t) == CALL_EXPR)
-    return t;
-  else if (TREE_CODE (t) == MODIFY_EXPR
-          && TREE_CODE (TREE_OPERAND (t, 1)) == CALL_EXPR)
-    return TREE_OPERAND (t, 1);
-  else if (TREE_CODE (t) == RETURN_EXPR
-           && TREE_OPERAND (t, 0)
-          && TREE_CODE (TREE_OPERAND (t, 0)) == MODIFY_EXPR
-          && TREE_CODE (TREE_OPERAND (TREE_OPERAND (t, 0), 1)) == CALL_EXPR)
-    return TREE_OPERAND (TREE_OPERAND (t, 0), 1);
-
-  return NULL_TREE;
-}
-
-
-/* Given an _EXPR TOP, reorganize all of the nested _EXPRs with the same
-   code so that they only appear as the second operand.  This should only
-   be used for tree codes which are truly associative, such as
-   COMPOUND_EXPR and TRUTH_ANDIF_EXPR.  Arithmetic is not associative
-   enough, due to the limited precision of arithmetic data types.
-
-   This transformation is conservative; the operand 0 of a matching tree
-   node will only change if it is also a matching node.  */
-
-tree
-right_assocify_expr (tree top)
-{
-  tree *p = &top;
-  enum tree_code code = TREE_CODE (*p);
-  while (TREE_CODE (*p) == code)
-    {
-      tree cur = *p;
-      tree lhs = TREE_OPERAND (cur, 0);
-      if (TREE_CODE (lhs) == code)
-       {
-         /* There's a left-recursion.  If we have ((a, (b, c)), d), we
-            want to rearrange to (a, (b, (c, d))).  */
-         tree *q;
-
-         /* Replace cur with the lhs; move (a, *) up.  */
-         *p = lhs;
-
-         if (code == COMPOUND_EXPR)
-           {
-             /* We need to give (b, c) the type of c; previously lhs had
-                the type of b.  */
-             TREE_TYPE (lhs) = TREE_TYPE (cur);
-             if (TREE_SIDE_EFFECTS (cur))
-               TREE_SIDE_EFFECTS (lhs) = 1;
-           }
-
-         /* Walk through the op1 chain from there until we find something
-            with a different code.  In this case, c.  */
-         for (q = &TREE_OPERAND (lhs, 1); TREE_CODE (*q) == code;
-              q = &TREE_OPERAND (*q, 1))
-           TREE_TYPE (*q) = TREE_TYPE (cur);
-
-         /* Change (*, d) into (c, d).  */
-         TREE_OPERAND (cur, 0) = *q;
-
-         /* And plug it in where c used to be.  */
-         *q = cur;
-       }
-      else
-       p = &TREE_OPERAND (cur, 1);
-    }
-  return top;
-}
-
-/* Normalize the statement TOP.  If it is a COMPOUND_EXPR, reorganize it so
-   that we can traverse it without recursion.  If it is null, replace it
-   with a nop.  */
-
-tree
-rationalize_compound_expr (tree top)
-{
-  if (top == NULL_TREE)
-    top = build_empty_stmt ();
-  else if (TREE_CODE (top) == COMPOUND_EXPR)
-    top = right_assocify_expr (top);
-
-  return top;
-}
-
-/* Given a memory reference expression, return the base address.  Note that,
-   in contrast with get_base_var, this will not recurse inside INDIRECT_REF
-   expressions.  Therefore, given the reference PTR->FIELD, this function
-   will return *PTR.  Whereas get_base_var would've returned PTR.  */
-
-tree
-get_base_address (tree t)
-{
-  do
-    {
-      if (SSA_VAR_P (t)
-         || TREE_CODE (t) == INDIRECT_REF)
-       return t;
-
-      switch (TREE_CODE (t))
-       {
-       case ARRAY_REF:
-       case COMPONENT_REF:
-       case REALPART_EXPR:
-       case IMAGPART_EXPR:
-       case BIT_FIELD_REF:
-         t = TREE_OPERAND (t, 0);
-         break;
-
-       default:
-         return NULL_TREE;
-       }
-    }
-  while (t);
-
-  return t;
-}
-
-
-void
-recalculate_side_effects (tree t)
-{
-  enum tree_code code = TREE_CODE (t);
-  int fro = first_rtl_op (code);
-  int i;
-
-  switch (TREE_CODE_CLASS (code))
-    {
-    case 'e':
-      switch (code)
-       {
-       case INIT_EXPR:
-       case MODIFY_EXPR:
-       case VA_ARG_EXPR:
-       case RTL_EXPR:
-       case PREDECREMENT_EXPR:
-       case PREINCREMENT_EXPR:
-       case POSTDECREMENT_EXPR:
-       case POSTINCREMENT_EXPR:
-         /* All of these have side-effects, no matter what their
-            operands are.  */
-         return;
-
-       default:
-         break;
-       }
-      /* Fall through.  */
-
-    case '<':  /* a comparison expression */
-    case '1':  /* a unary arithmetic expression */
-    case '2':  /* a binary arithmetic expression */
-    case 'r':  /* a reference */
-      TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
-      for (i = 0; i < fro; ++i)
-       {
-         tree op = TREE_OPERAND (t, i);
-         if (op && TREE_SIDE_EFFECTS (op))
-           TREE_SIDE_EFFECTS (t) = 1;
-       }
-      break;
-   }
-}
diff --git a/gcc/tree-simple.h b/gcc/tree-simple.h
deleted file mode 100644 (file)
index d2c9103..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* Functions to analyze and validate GIMPLE trees.
-   Copyright (C) 2002, 2003 Free Software Foundation, Inc.
-   Contributed by Diego Novillo <dnovillo@redhat.com>
-
-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 2, 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 COPYING.  If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
-
-#ifndef _TREE_SIMPLE_H
-#define _TREE_SIMPLE_H 1
-
-
-#include "tree-iterator.h"
-
-extern tree create_tmp_var_raw (tree, const char *);
-extern tree create_tmp_var (tree, const char *);
-extern bool is_gimple_tmp_var (tree);
-extern tree get_initialized_tmp_var (tree, tree *, tree *);
-extern tree get_formal_tmp_var (tree, tree *);
-extern void declare_tmp_vars (tree, tree);
-
-extern tree rationalize_compound_expr (tree);
-extern tree right_assocify_expr (tree);
-extern void annotate_all_with_locus (tree *, location_t);
-
-/* Validation of GIMPLE expressions.  Note that these predicates only check
-   the basic form of the expression, they don't recurse to make sure that
-   underlying nodes are also of the right form.  */
-
-/* Returns true iff T is a valid GIMPLE statement.  */
-bool is_gimple_stmt (tree);
-
-/* Returns true iff TYPE is a valid type for a scalar register variable.  */
-bool is_gimple_reg_type (tree);
-/* Returns true iff T is a scalar register variable.  */
-bool is_gimple_reg (tree);
-/* Returns true iff T is any sort of variable.  */
-bool is_gimple_variable (tree);
-/* Returns true iff T is a variable or an INDIRECT_REF (of a variable).  */
-bool is_gimple_min_lval (tree);
-/* Returns true iff T is an lvalue other than an INDIRECT_REF.  */
-bool is_gimple_addr_expr_arg (tree);
-/* Returns true iff T is any valid GIMPLE lvalue.  */
-bool is_gimple_lvalue (tree);
-
-/* Returns true iff T is a GIMPLE restricted function invariant.  */
-bool is_gimple_min_invariant (tree);
-/* Returns true iff T is a GIMPLE rvalue.  */
-bool is_gimple_val (tree);
-/* Returns true iff T is a valid rhs for a MODIFY_EXPR.  */
-bool is_gimple_rhs (tree);
-
-/* Returns true iff T is a valid if-statement condition.  */
-bool is_gimple_condexpr (tree);
-
-/* Returns true iff T is a type conversion.  */
-bool is_gimple_cast (tree);
-/* Returns true iff T is a valid CONSTRUCTOR element (either an rvalue or
-   another CONSTRUCTOR).  */
-bool is_gimple_constructor_elt (tree);
-/* Returns true iff T is a variable that does not need to live in memory.  */
-bool is_gimple_non_addressable (tree t);
-
-/* If T makes a function call, returns the CALL_EXPR operand.  */
-tree get_call_expr_in (tree t);
-
-void recalculate_side_effects (tree);
-
-void append_to_statement_list (tree, tree *);
-void append_to_statement_list_force (tree, tree *);
-void append_to_compound_expr (tree, tree *);
-
-/* FIXME we should deduce this from the predicate.  */
-typedef enum fallback_t {
-  fb_none = 0,
-  fb_rvalue = 1,
-  fb_lvalue = 2,
-  fb_mayfail = 4,
-  fb_either= fb_rvalue | fb_lvalue
-} fallback_t;
-
-enum gimplify_status {
-  GS_ERROR     = -2,   /* Something Bad Seen.  */
-  GS_UNHANDLED = -1,   /* A langhook result for "I dunno".  */
-  GS_OK                = 0,    /* We did something, maybe more to do.  */
-  GS_ALL_DONE  = 1     /* The expression is fully gimplified.  */
-};
-
-enum gimplify_status gimplify_expr (tree *, tree *, tree *,
-                                   bool (*) (tree), fallback_t);
-void gimplify_stmt (tree *);
-void gimplify_to_stmt_list (tree *);
-void gimplify_body (tree *, tree);
-void push_gimplify_context (void);
-void pop_gimplify_context (tree);
-
-/* Miscellaneous helpers.  */
-tree get_base_address (tree t);
-void gimple_add_tmp_var (tree);
-tree gimple_current_bind_expr (void);
-void gimple_push_bind_expr (tree);
-void gimple_pop_bind_expr (void);
-void unshare_all_trees (tree);
-tree voidify_wrapper_expr (tree);
-tree gimple_build_eh_filter (tree, tree, tree);
-tree build_and_jump (tree *);
-tree alloc_stmt_list (void);
-void free_stmt_list (tree);
-tree force_labels_r (tree *, int *, void *);
-
-/* In tree-nested.c.  */
-extern void lower_nested_functions (tree);
-
-#endif /* _TREE_SIMPLE_H  */
index 2131d0047f20b48a6dcfd337859a5383d34f23e4..d447b82d7682588c6a9c7e442c108d17263f1f41 100644 (file)
@@ -38,7 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "langhooks.h"
 #include "tree-inline.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
 #include "timevar.h"
index 02eb5139698f9d5de5f9d234fdffa82ec59082e3..2bcb4efec9bb4682cc69d7a55dc520d54e5cd45d 100644 (file)
@@ -36,7 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "function.h"
 #include "diagnostic.h"
 #include "tree-dump.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-flow.h"
 #include "tree-inline.h"
 #include "tree-alias-common.h"
index ef655629abd0c3848754a674256a5b128e8eea1e..bb7939cd10c10e730a4efc7d5ef49d3b4864b61b 100644 (file)
@@ -51,7 +51,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "diagnostic.h"
 #include "tree-inline.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
 #include "timevar.h"
index 91c0f74ac5519bcd92bb91031796eed6d667a0f2..dd698835f0682ce89f0f982386b689a1b65b43db 100644 (file)
@@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "timevar.h"
 #include "tree-alias-common.h"
index c8ff7eb9d9827e1c3417e11e9a2a75eb1e0f9caf..7921a9f0cf6c0034ffbd198f184a6c3124c5dff5 100644 (file)
@@ -59,7 +59,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tree.h"
 #include "diagnostic.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-dump.h"
 #include "tree-pass.h"
 #include "timevar.h"
index aedcbc1e3979eef7cc43d101e9f0bb64beb1a68a..28c3d578581693a19bc6d4961b286c4702b9f8c5 100644 (file)
@@ -30,7 +30,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "varray.h"
 #include "timevar.h"
index 76a9a56c7e25f1b282cc7efd3ee0b71c77678658..c249441dd7ca487819ec2812ff2b6a7443afed85 100644 (file)
@@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "tree-inline.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-dump.h"
 #include "timevar.h"
 #include "fibheap.h"
index 58d44c2d5e6d50525bd10ce46af03c6cb88b6f7c..8ecce07e4f4dd8118ad0e57678c996bc177838de 100644 (file)
@@ -37,7 +37,7 @@ Boston, MA 02111-1307, USA.  */
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-simple.h"
+#include "tree-gimple.h"
 #include "tree-inline.h"
 #include "varray.h"
 #include "timevar.h"