[tuples] gimplifying MODIFY_EXPR and RETURN_EXPR

Aldy Hernandez aldyh@redhat.com
Thu May 3 22:41:00 GMT 2007


Hi folks.

Here is some more infrastructure work, this time showcasing how I expect
the gimplifier to do it's work with sequences, recursion, lvals, etc.  As a
proof of concept, with this patch we are already half assedly gimplifying both
MODIFY_EXPRs and RETURN_EXPRs.

There is a lot of noise in this patch, particularly to get cc1 to build
(expect lots of #if 0's to force the difference passes into submission).
I would, however, appreciate some feedback on the more relevant parts of this
patch:

	gimple-ir.c
	gimple-ir.h
	gimplify.c

BTW, using sequences obsoletes most places that previously used STMT_LISTs.
There's a few places where we could just pass a gimple statement (not a
sequence), and save a dereference, but it seems more elegant to use sequences
throughout.  Comments?

I'm really bad at explaining all this.  The code should make it clearer
to understand (I hope).

I'd appreciate feedback, cause if we agree on the implementation so far,
it's a lot of mostly mechanical changes that I'd hate to revert if I've
taken a wrong turn.

Thanks.
Aldy

Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 124007)
+++ doc/tm.texi	(working copy)
@@ -4074,7 +4074,7 @@ The default version of the hook returns 
 @deftypefn {Target Hook} tree TARGET_GIMPLIFY_VA_ARG_EXPR (tree @var{valist}, tree @var{type}, tree *@var{pre_p}, tree *@var{post_p})
 This hook performs target-specific gimplification of
 @code{VA_ARG_EXPR}.  The first two parameters correspond to the
-arguments to @code{va_arg}; the latter two are as in
+arguments to @code{va_arg}; the latter three are as in
 @code{gimplify.c:gimplify_expr}.
 @end deftypefn
 
Index: tree-pretty-print.c
===================================================================
--- tree-pretty-print.c	(revision 124007)
+++ tree-pretty-print.c	(working copy)
@@ -46,6 +46,7 @@ static void maybe_init_pretty_print (FIL
 static void print_declaration (pretty_printer *, tree, int, int);
 static void print_struct_decl (pretty_printer *, tree, int, int);
 static void do_niy (pretty_printer *, tree);
+static void do_gs_niy (pretty_printer *, gimple);
 static void dump_vops (pretty_printer *, tree, int, int);
 static void dump_generic_bb_buff (pretty_printer *, basic_block, int, int);
 
@@ -53,6 +54,7 @@ static void dump_generic_bb_buff (pretty
   int i; for (i = 0; i<SPACE; i++) pp_space (buffer); } while (0)
 
 #define NIY do_niy(buffer,node)
+#define GS_NIY do_gs_niy(buffer,gs)
 
 #define PRINT_FUNCTION_NAME(NODE)  pp_printf             \
   (buffer, "%s", TREE_CODE (NODE) == NOP_EXPR ?              \
@@ -85,6 +87,15 @@ do_niy (pretty_printer *buffer, tree nod
   pp_string (buffer, " >>>\n");
 }
 
+/* Try to print something for an unknown gimple statement.  */
+
+static void
+do_gs_niy (pretty_printer *buffer, gimple gs)
+{
+  pp_printf (buffer, "<<< Unknown gimple statement: %s >>>\n",
+	     gs_code_name[(int) GS_CODE (gs)]);
+}
+
 void
 debug_generic_expr (tree t)
 {
@@ -111,6 +122,25 @@ debug_tree_chain (tree t)
   fprintf (stderr, "\n");
 }
 
+void
+debug_gimple_stmt (gimple gs)
+{
+  print_gimple_stmt (stderr, gs, TDF_VOPS|TDF_MEMSYMS);
+  fprintf (stderr, "\n");
+}
+
+void
+debug_gimple_seq (gs_seq seq)
+{
+  gimple_stmt_iterator i;
+
+  for (i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+    {
+      gimple gs = gsi_stmt (i);
+      print_gimple_stmt (stderr, gs, TDF_VOPS|TDF_MEMSYMS);
+    }
+}
+
 /* Prints declaration DECL to the FILE with details specified by FLAGS.  */
 void
 print_generic_decl (FILE *file, tree decl, int flags)
@@ -131,6 +161,16 @@ print_generic_stmt (FILE *file, tree t, 
   pp_flush (&buffer);
 }
 
+/* Same, but for gimple statements.  */
+
+void
+print_gimple_stmt (FILE *file, gimple g, int flags)
+{
+  maybe_init_pretty_print (file);
+  dump_gimple_stmt (&buffer, g, 0, flags);
+  pp_flush (&buffer);
+}
+
 /* Print tree T, and its successors, on file FILE.  FLAGS specifies details
    to show in the dump.  See TDF_* in tree.h.  The output is indented by
    INDENT spaces.  */
@@ -2060,6 +2100,78 @@ dump_generic_node (pretty_printer *buffe
   return spc;
 }
 
+/* Dump the gimple statement GS on the pretty_printer BUFFER, SPC
+   spaces of indent.  FLAGS specifies details to show in the dump (see
+   TDF_* in tree.h).  */
+
+void
+dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  tree t;
+
+  if (!gs)
+    return;
+
+  switch (GS_CODE (gs))
+    {
+    case GS_ASSIGN:
+      {
+	enum gimple_statement_structure_enum gss;
+
+	dump_generic_node (buffer, gs_assign_operand_lhs (gs), spc, flags,
+			   false);
+	pp_space (buffer);
+	pp_character (buffer, '=');
+	pp_space (buffer);
+
+	gss = gss_for_assign (GS_SUBCODE_FLAGS (gs));
+	switch (gss)
+	  {
+	  case GSS_ASSIGN_BINARY:
+	    dump_generic_node (buffer, GS_ASSIGN_BINARY_RHS1 (gs), spc,
+			       flags, false);
+	    pp_space (buffer);
+	    pp_string (buffer, op_symbol_1 (GS_SUBCODE_FLAGS (gs)));
+	    pp_space (buffer);
+	    dump_generic_node (buffer, GS_ASSIGN_BINARY_RHS2 (gs), spc,
+			       flags, false);
+	    break;
+	  case GSS_ASSIGN_UNARY_REG:
+	    dump_generic_node (buffer, GS_ASSIGN_UNARY_REG_RHS (gs), spc,
+			       flags, false);
+	    break;
+	  case GSS_ASSIGN_UNARY_MEM:
+	    dump_generic_node (buffer, GS_ASSIGN_UNARY_MEM_RHS (gs), spc,
+			       flags, false);
+	    break;
+	  default:
+	    gcc_unreachable ();
+	  }
+
+	break;
+      }
+    case GS_RETURN:
+      pp_string (buffer, "return");
+      t = GS_RETURN_OPERAND_RETVAL (gs);
+      if (t)
+	{
+	  pp_space (buffer);
+	  if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+	    dump_generic_node (buffer, GIMPLE_STMT_OPERAND (t, 1),
+			       spc, flags, false);
+	  else
+	    dump_generic_node (buffer, t, spc, flags, false);
+	}
+      break;
+
+    default:
+      GS_NIY;
+    }
+
+  pp_semicolon (buffer);
+  pp_write_text_to_stream (buffer);
+}
+
 /* Print the declaration of a variable.  */
 
 static void
Index: tree.h
===================================================================
--- tree.h	(revision 124007)
+++ tree.h	(working copy)
@@ -4513,7 +4513,7 @@ extern tree build_call_expr (tree, int, 
 extern tree mathfn_built_in (tree, enum built_in_function fn);
 extern tree strip_float_extensions (tree);
 extern tree c_strlen (tree, int);
-extern tree std_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+extern tree std_gimplify_va_arg_expr (tree, tree, gs_seq, gs_seq);
 extern tree build_va_arg_indirect_ref (tree);
 extern tree build_string_literal (int, const char *);
 extern bool validate_arglist (tree, ...);
@@ -4611,7 +4611,7 @@ extern void push_function_context (void)
 extern void pop_function_context (void);
 extern void push_function_context_to (tree);
 extern void pop_function_context_from (tree);
-extern tree gimplify_parameters (void);
+extern struct gs_sequence gimplify_parameters (void);
 
 /* In print-rtl.c */
 #ifdef BUFSIZ
Index: target.h
===================================================================
--- target.h	(revision 124007)
+++ target.h	(working copy)
@@ -638,8 +638,8 @@ struct gcc_target
   tree (* build_builtin_va_list) (void);
 
   /* Gimplifies a VA_ARG_EXPR.  */
-  tree (* gimplify_va_arg_expr) (tree valist, tree type, tree *pre_p,
-				 tree *post_p);
+  tree (* gimplify_va_arg_expr) (tree valist, tree type,
+      				 gs_seq pre_p, gs_seq post_p);
 
   /* Validity-checking routines for PCH files, target-specific.
      get_pch_validity returns a pointer to the data to be stored,
Index: builtins.c
===================================================================
--- builtins.c	(revision 124007)
+++ builtins.c	(working copy)
@@ -4657,7 +4657,7 @@ expand_builtin_va_start (tree exp)
    current (padded) address and increment by the (padded) size.  */
 
 tree
-std_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
+std_gimplify_va_arg_expr (tree valist, tree type, gs_seq pre_p, gs_seq post_p)
 {
   tree addr, t, type_size, rounded_size, valist_tmp;
   unsigned HOST_WIDE_INT align, boundary;
@@ -4713,7 +4713,8 @@ std_gimplify_va_arg_expr (tree valist, t
   rounded_size = round_up (type_size, align);
 
   /* Reduce rounded_size so it's sharable with the postqueue.  */
-  gimplify_expr (&rounded_size, pre_p, post_p, is_gimple_val, fb_rvalue);
+  gimplify_expr (&rounded_size, NULL, pre_p, post_p,
+      		 is_gimple_val, fb_rvalue);
 
   /* Get AP.  */
   addr = valist_tmp;
@@ -4768,7 +4769,7 @@ dummy_object (tree type)
    builtin function, but a very special sort of operator.  */
 
 enum gimplify_status
-gimplify_va_arg_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_va_arg_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p)
 {
   tree promoted_type, want_va_type, have_va_type;
   tree valist = TREE_OPERAND (*expr_p, 0);
@@ -4825,7 +4826,7 @@ gimplify_va_arg_expr (tree *expr_p, tree
 	 Call abort to encourage the user to fix the program.  */
       inform ("if this code is reached, the program will abort");
       t = build_call_expr (implicit_built_in_decls[BUILT_IN_TRAP], 0);
-      append_to_statement_list (t, pre_p);
+      gimplify_and_add (t, pre_p);
 
       /* This is dead code, but go ahead and finish so that the
 	 mode of the result comes out right.  */
@@ -4847,10 +4848,12 @@ gimplify_va_arg_expr (tree *expr_p, tree
 	      tree p1 = build_pointer_type (TREE_TYPE (va_list_type_node));
 	      valist = build_fold_addr_expr_with_type (valist, p1);
 	    }
-	  gimplify_expr (&valist, pre_p, post_p, is_gimple_val, fb_rvalue);
+	  gimplify_expr (&valist, NULL, pre_p, post_p, 
+	      		 is_gimple_val, fb_rvalue);
 	}
       else
-	gimplify_expr (&valist, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
+	gimplify_expr (&valist, NULL, pre_p, post_p, 
+	    	       is_gimple_min_lval, fb_lvalue);
 
       if (!targetm.gimplify_va_arg_expr)
 	/* FIXME:Once most targets are converted we should merely
Index: diagnostic.h
===================================================================
--- diagnostic.h	(revision 124007)
+++ diagnostic.h	(working copy)
@@ -209,13 +209,17 @@ extern char *file_name_as_prefix (const 
 
 /* In tree-pretty-print.c  */
 extern int dump_generic_node (pretty_printer *, tree, int, int, bool);
+extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);
 extern void print_generic_stmt (FILE *, tree, int);
 extern void print_generic_stmt_indented (FILE *, tree, int, int);
+extern void print_gimple_stmt (FILE *, gimple, int);
 extern void print_generic_expr (FILE *, tree, int);
 extern void print_generic_decl (FILE *, tree, int);
 
 extern void debug_generic_expr (tree);
 extern void debug_generic_stmt (tree);
 extern void debug_tree_chain (tree);
+extern void debug_gimple_stmt (gimple);
+extern void debug_gimple_seq (gs_seq);
 extern void debug_c_tree (tree);
 #endif /* ! GCC_DIAGNOSTIC_H */
Index: omp-low.c
===================================================================
--- omp-low.c	(revision 124007)
+++ omp-low.c	(working copy)
@@ -1426,7 +1426,7 @@ scan_omp (tree *stmt_p, omp_context *ctx
 /* Build a call to GOMP_barrier.  */
 
 static void
-build_omp_barrier (tree *stmt_list)
+build_omp_barrier (gs_seq stmt_list)
 {
   tree t = build_call_expr (built_in_decls[BUILT_IN_GOMP_BARRIER], 0);
   gimplify_and_add (t, stmt_list);
@@ -1763,7 +1763,9 @@ lower_rec_input_clauses (tree clauses, t
 	      if (x)
 		{
 		  dtor = x;
+#if 0
 		  gimplify_stmt (&dtor);
+#endif
 		  tsi_link_before (&diter, dtor, TSI_SAME_STMT);
 		}
 	      break;
@@ -4177,11 +4179,12 @@ lower_regimplify (tree *tp, struct walk_
   tree pre = NULL;
 
   if (wi->is_lhs)
-    gs = gimplify_expr (tp, &pre, NULL, is_gimple_lvalue, fb_lvalue);
+    gs = gimplify_expr (tp, NULL, &pre, NULL, is_gimple_lvalue, fb_lvalue);
   else if (wi->val_only)
-    gs = gimplify_expr (tp, &pre, NULL, is_gimple_val, fb_rvalue);
+    gs = gimplify_expr (tp, NULL, &pre, NULL, is_gimple_val, fb_rvalue);
   else
-    gs = gimplify_expr (tp, &pre, NULL, is_gimple_formal_tmp_var, fb_rvalue);
+    gs = gimplify_expr (tp, NULL, &pre, NULL,
+			is_gimple_formal_tmp_var, fb_rvalue);
   gcc_assert (gs == GS_ALL_DONE);
 
   if (pre)
Index: tree-gimple.h
===================================================================
--- tree-gimple.h	(revision 124186)
+++ tree-gimple.h	(working copy)
@@ -29,8 +29,8 @@ Boston, MA 02110-1301, USA.  */
 extern tree create_tmp_var_raw (tree, const char *);
 extern tree create_tmp_var_name (const char *);
 extern tree create_tmp_var (tree, const char *);
-extern tree get_initialized_tmp_var (tree, tree *, tree *);
-extern tree get_formal_tmp_var (tree, tree *);
+extern tree get_initialized_tmp_var (tree, gs_seq, gs_seq);
+extern tree get_formal_tmp_var (tree, gs_seq);
 
 extern void declare_vars (tree, tree, bool);
 
@@ -111,16 +111,16 @@ enum gimplify_status {
   GS_ALL_DONE	= 1	/* The expression is fully gimplified.  */
 };
 
-extern enum gimplify_status gimplify_expr (tree *, gs_seq, tree *, tree *,
+extern enum gimplify_status gimplify_expr (tree *, gs_seq, gs_seq, gs_seq,
 					   bool (*) (tree), fallback_t);
-extern void gimplify_type_sizes (tree, tree *);
-extern void gimplify_one_sizepos (tree *, tree *);
-extern void gimplify_stmt (tree *);
+extern void gimplify_type_sizes (tree, gs_seq);
+extern void gimplify_one_sizepos (tree *, gs_seq);
+extern void gimplify_stmt (tree *, gs_seq);
 extern void gimplify_to_stmt_list (tree *);
 extern void gimplify_body (tree *, gs_seq, tree, bool);
 extern void push_gimplify_context (void);
 extern void pop_gimplify_context (tree);
-extern void gimplify_and_add (tree, tree *);
+extern void gimplify_and_add (tree, gs_seq);
 
 /* Miscellaneous helpers.  */
 extern void gimple_add_tmp_var (tree);
@@ -131,7 +131,7 @@ extern tree build_and_jump (tree *);
 extern tree alloc_stmt_list (void);
 extern void free_stmt_list (tree);
 extern tree force_labels_r (tree *, int *, void *);
-extern enum gimplify_status gimplify_va_arg_expr (tree *, tree *, tree *);
+extern enum gimplify_status gimplify_va_arg_expr (tree *, gs_seq, gs_seq);
 struct gimplify_omp_ctx;
 extern void omp_firstprivatize_variable (struct gimplify_omp_ctx *, tree);
 extern tree gimple_boolify (tree);
Index: gimple-iterator.h
===================================================================
--- gimple-iterator.h	(revision 124155)
+++ gimple-iterator.h	(working copy)
@@ -88,6 +88,8 @@ gsi_prev (gimple_stmt_iterator *i)
 }
 
 /* Return a pointer to the current stmt.  */
+/* FIXME tuples: Probably uneeded.  Let's leave this in for now, until we're
+   sure we don't need it.  */
 
 static inline gimple *
 gsi_stmt_ptr (gimple_stmt_iterator i)
Index: c-decl.c
===================================================================
--- c-decl.c	(revision 124007)
+++ c-decl.c	(working copy)
@@ -6687,8 +6687,10 @@ c_gimple_diagnostics_recursively (tree f
   c_warn_unused_result (&DECL_SAVED_TREE (fndecl));
 
   /* Notice when OpenMP structured block constraints are violated.  */
+#if 0
   if (flag_openmp)
     diagnose_omp_structured_block_errors (fndecl);
+#endif
 
   /* Finalize all nested functions now.  */
   cgn = cgraph_node (fndecl);
Index: function.c
===================================================================
--- function.c	(revision 124007)
+++ function.c	(working copy)
@@ -3135,7 +3135,7 @@ gimplify_parm_type (tree *tp, int *walk_
       else if (TYPE_SIZE (t) && !TREE_CONSTANT (TYPE_SIZE (t))
 	       && !TYPE_SIZES_GIMPLIFIED (t))
 	{
-	  gimplify_type_sizes (t, (tree *) data);
+	  gimplify_type_sizes (t, (gs_seq) data);
 	  *walk_subtrees = 1;
 	}
     }
@@ -3145,15 +3145,15 @@ gimplify_parm_type (tree *tp, int *walk_
 
 /* Gimplify the parameter list for current_function_decl.  This involves
    evaluating SAVE_EXPRs of variable sized parameters and generating code
-   to implement callee-copies reference parameters.  Returns a list of
-   statements to add to the beginning of the function, or NULL if nothing
-   to do.  */
+   to implement callee-copies reference parameters.  Returns a sequence of
+   statements to add to the beginning of the function.  */
 
-tree
+struct gs_sequence
 gimplify_parameters (void)
 {
   struct assign_parm_data_all all;
-  tree fnargs, parm, stmts = NULL;
+  tree fnargs, parm;
+  struct gs_sequence stmts = GS_SEQ_INIT;
 
   assign_parms_initialize_all (&all);
   fnargs = assign_parms_augmented_arg_list (&all);
Index: langhooks.h
===================================================================
--- langhooks.h	(revision 124007)
+++ langhooks.h	(working copy)
@@ -421,7 +421,7 @@ struct lang_hooks
 
   /* Perform language-specific gimplification on the argument.  Returns an
      enum gimplify_status, though we can't see that type here.  */
-  int (*gimplify_expr) (tree *, tree *, tree *);
+  int (*gimplify_expr) (tree *, gs_seq, gs_seq, gs_seq);
 
   /* Fold an OBJ_TYPE_REF expression to the address of a function.
      KNOWN_TYPE carries the true type of the OBJ_TYPE_REF_OBJECT.  */
Index: gimple-ir.c
===================================================================
--- gimple-ir.c	(revision 124091)
+++ gimple-ir.c	(working copy)
@@ -30,7 +30,7 @@ Software Foundation, 51 Franklin Street,
 #include "gimple-ir.h"
 
 #define DEFGSCODE(SYM, NAME)	NAME,
-static const char *gs_code_name[] = {
+const char *const gs_code_name[] = {
 #include "gs.def"
 };
 #undef DEFGSCODE
@@ -49,7 +49,79 @@ gs_build_return (bool result_decl_p, tre
   GS_RETURN_OPERAND_RETVAL (p) = retval;
   return p;
 }
+
+/* Construct a GS_ASSIGN statement.  */
+
+gimple
+gs_build_assign (tree lhs, tree rhs)
+{
+  gimple p;
+  enum gimple_statement_structure_enum gss;
+
+  gss = gss_for_assign (TREE_CODE (rhs));
+  switch (gss)
+    {
+    case GSS_ASSIGN_BINARY:
+      p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_binary));
+      GS_CODE (p) = GS_ASSIGN;
+      GS_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
+      GS_ASSIGN_BINARY_LHS (p) = lhs;
+      GS_ASSIGN_BINARY_RHS1 (p) = TREE_OPERAND (rhs, 0);
+      GS_ASSIGN_BINARY_RHS2 (p) = TREE_OPERAND (rhs, 1);
+      break;
+    case GSS_ASSIGN_UNARY_REG:
+      p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_unary_reg));
+      GS_CODE (p) = GS_ASSIGN;
+      GS_ASSIGN_UNARY_REG_LHS (p) = lhs;
+      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (rhs))))
+	GS_ASSIGN_UNARY_REG_RHS (p) = TREE_OPERAND (rhs, 0);
+      else
+	GS_ASSIGN_UNARY_REG_RHS (p) = rhs;
+      GS_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
+      break;
+    case GSS_ASSIGN_UNARY_MEM:
+      p = ggc_alloc_cleared (sizeof (struct gimple_statement_assign_unary_mem));
+      GS_CODE (p) = GS_ASSIGN;
+      GS_ASSIGN_UNARY_MEM_LHS (p) = lhs;
+      if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (rhs))))
+	GS_ASSIGN_UNARY_MEM_RHS (p) = TREE_OPERAND (rhs, 0);
+      else
+	GS_ASSIGN_UNARY_MEM_RHS (p) = rhs;
+
+      GS_SUBCODE_FLAGS (p) = TREE_CODE (rhs);
+      break;
+    default:
+      gcc_unreachable ();
+    }
+  GS_CODE (p) = GS_ASSIGN;
+  return p;
+}
 
+/* Given a CODE for the RHS of a GS_ASSIGN, return the GSS enum for it.  */
+
+enum gimple_statement_structure_enum
+gss_for_assign (enum tree_code code)
+{
+  enum tree_code_class class = TREE_CODE_CLASS (code);
+
+  if (class == tcc_binary || class == tcc_comparison)
+    return GSS_ASSIGN_BINARY;
+
+  /* There can be 3 types of unary operations:
+
+     SYM = <constant>		<== GSS_ASSIGN_UNARY_REG
+     SYM = SSA_NAME		<== GSS_ASSIGN_UNARY_REG
+     SYM = SYM2			<== GSS_ASSIGN_UNARY_MEM
+     SYM = UNARY_OP SYM2	<== GSS_ASSIGN_UNARY_MEM
+  */
+
+  if (class == tcc_constant || code == SSA_NAME)
+    return GSS_ASSIGN_UNARY_REG;
+
+  /* Must be class == tcc_unary.  */
+  return GSS_ASSIGN_UNARY_MEM;
+}
+
 /* Return which gimple structure is used by T.  The enums here are defined
    in gsstruct.def.  */
 
@@ -61,29 +133,7 @@ gimple_statement_structure (gimple gs)
 
   switch (code)
     {
-    case GS_ASSIGN:
-      {
-	enum tree_code_class class = TREE_CODE_CLASS (subcode);
-
-	if (class == tcc_binary
-	    || class == tcc_comparison)
-	  return GSS_ASSIGN_BINARY;
-	else 
-	  {
-	    /* There can be 3 types of unary operations:
-
-		 SYM = <constant>	<== GSS_ASSIGN_UNARY_REG
-		 SYM = SSA_NAME		<== GSS_ASSIGN_UNARY_REG
-	         SYM = SYM2		<== GSS_ASSIGN_UNARY_MEM
-		 SYM = UNARY_OP SYM2	<== GSS_ASSIGN_UNARY_MEM
-	    */
-	    if (class == tcc_constant || subcode == SSA_NAME)
-	      return GSS_ASSIGN_UNARY_REG;
-
-	    /* Must be class == tcc_unary.  */
-	    return GSS_ASSIGN_UNARY_MEM;
-	  }
-      }
+    case GS_ASSIGN:		return gss_for_assign (subcode);
     case GS_ASM:		return GSS_ASM;
     case GS_BIND:		return GSS_BIND;
     case GS_CALL:		return GSS_CALL;
@@ -109,10 +159,10 @@ gimple_statement_structure (gimple gs)
     case GS_OMP_PARALLEL:	return GSS_OMP_PARALLEL;
     case GS_OMP_SECTIONS:	return GSS_OMP_SECTIONS;
     case GS_OMP_SINGLE:		return GSS_OMP_SINGLE;
-    default: ;
+    default:
+      gcc_unreachable ();
+      return GSS_BASE;
     }
-  gcc_unreachable ();
-  return GSS_BASE;
 }
 
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
@@ -137,18 +187,23 @@ gs_check_failed (const gimple gs, const 
 void
 gs_add (gimple gs, gs_seq seq)
 {
+  gimple last;
+
   /* Make sure this stmt is not part of another chain.  */
   gcc_assert (GS_PREV (gs) == NULL);
 
+  for (last = gs; GS_NEXT (last) != NULL; last = GS_NEXT (last))
+    ;
+
   if (GS_SEQ_FIRST (seq) == NULL)
     {
       GS_SEQ_FIRST (seq) = gs;
-      GS_SEQ_LAST (seq) = gs;
+      GS_SEQ_LAST (seq) = last;
     }
   else
     {
       GS_PREV (gs) = GS_SEQ_LAST (seq);
       GS_NEXT (GS_SEQ_LAST (seq)) = gs;
-      GS_SEQ_LAST (seq) = gs;
+      GS_SEQ_LAST (seq) = last;
     }
 }
Index: gimple-ir.h
===================================================================
--- gimple-ir.h	(revision 124186)
+++ gimple-ir.h	(working copy)
@@ -35,22 +35,23 @@ enum gs_code {
 #define GS_NEXT(G) ((G)->base.next)
 #define GS_PREV(G) ((G)->base.prev)
 #define GS_LOCUS(G) ((G)->base.locus)
+#define GS_LOCUS_EMPTY_P(G)	(GS_LOCUS ((G)).file == NULL \
+				 && GS_LOCUS ((G)).line == 0)
 
 /* A sequences of gimple statements.  */
 #define GS_SEQ_FIRST(S)	(S)->first
 #define GS_SEQ_LAST(S)		(S)->last
-#define GS_SEQ_INIT {0, 0}
+#define GS_SEQ_INIT (struct gs_sequence) {0, 0}
 #define GS_SEQ_EMPTY_P(S) (!GS_SEQ_FIRST ((S)))
 struct gs_sequence
 {
   gimple first;
   gimple last;
 };
-typedef struct gs_sequence *gs_seq;
 
 struct gimple_statement_base GTY(())
 {
-  unsigned int code : 16;
+  ENUM_BITFIELD(gs_code) code : 16;
   unsigned int subcode_flags : 16;
   gimple next;
   gimple prev;
@@ -63,7 +64,6 @@ struct gimple_statement_with_ops GTY(())
 {
   struct gimple_statement_base base;
   unsigned modified : 1;
-  bitmap address_taken;
   struct def_optype_d GTY((skip)) *def_ops;
   struct use_optype_d GTY((skip)) *use_ops;
 };
@@ -319,9 +319,15 @@ union gimple_statement_d GTY ((desc ("gi
   struct gimple_statement_omp_single GTY ((tag ("GSS_OMP_SINGLE"))) gs_omp_single;
 };
 
+/* Prototypes.  */
+
 extern gimple gs_build_return (bool, tree);
+extern gimple gs_build_assign (tree, tree);
 extern enum gimple_statement_structure_enum gimple_statement_structure (gimple);
 extern void gs_add (gimple, gs_seq);
+extern enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
+
+extern const char *const gs_code_name[];
 
 /* Error out if a gimple tuple is addressed incorrectly.  */
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
@@ -382,6 +388,23 @@ gs_assign_operand_rhs (gimple gs)
   return gs_assign_operand (gs, 1);
 }
 
+#define GS_ASSIGN_BINARY_LHS(G)		\
+  GS_CHECK ((G), GS_ASSIGN)->gs_assign_binary.op[0]
+#define GS_ASSIGN_BINARY_RHS1(G)	\
+  GS_CHECK ((G), GS_ASSIGN)->gs_assign_binary.op[1]
+#define GS_ASSIGN_BINARY_RHS2(G)	\
+  GS_CHECK ((G), GS_ASSIGN)->gs_assign_binary.op[2]
+
+#define GS_ASSIGN_UNARY_REG_LHS(G)	\
+    GS_CHECK ((G), GS_ASSIGN)->gs_assign_unary_reg.op[0]
+#define GS_ASSIGN_UNARY_REG_RHS(G)	\
+    GS_CHECK ((G), GS_ASSIGN)->gs_assign_unary_reg.op[1]
+
+#define GS_ASSIGN_UNARY_MEM_LHS(G)	\
+    GS_CHECK ((G), GS_ASSIGN)->gs_assign_unary_mem.op[0]
+#define GS_ASSIGN_UNARY_MEM_RHS(G)	\
+    GS_CHECK ((G), GS_ASSIGN)->gs_assign_unary_mem.op[1]
+
 /* GS_RETURN accessors.  */
 static inline tree *
 gs_return_operand_retval (gimple gs)
@@ -391,6 +414,15 @@ gs_return_operand_retval (gimple gs)
 
 #define GS_RETURN_OPERAND_RETVAL(G) (*gs_return_operand_retval ((G)))
 
+/* Append sequence SRC to the end of sequence DST.  */
+
+static inline void
+gs_seq_append (gs_seq src, gs_seq dst)
+{
+  if (!GS_SEQ_EMPTY_P (src))
+    gs_add (GS_SEQ_FIRST (src), dst);
+}
+
 #include "gimple-iterator.h"
 
 #endif  /* GCC_GIMPLE_IR_H */
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 124186)
+++ gimplify.c	(working copy)
@@ -85,7 +85,7 @@ struct gimplify_ctx
 
   tree current_bind_expr;
   tree temps;
-  tree conditional_cleanups;
+  struct gs_sequence conditional_cleanups;
   tree exit_label;
   tree return_temp;
   
@@ -113,7 +113,9 @@ typedef struct gimple_temp_hash_elt
 } elt_t;
 
 /* Forward declarations.  */
-static enum gimplify_status gimplify_compound_expr (tree *, tree *, bool);
+#if 0
+static enum gimplify_status gimplify_compound_expr (tree *, gs_seq, bool);
+#endif
 #ifdef ENABLE_CHECKING
 static bool cpt_same_type (tree a, tree b);
 #endif
@@ -223,12 +225,13 @@ gimple_conditional_context (void)
 
 /* Note that we've entered a COND_EXPR.  */
 
+#if 0
 static void
 gimple_push_condition (void)
 {
 #ifdef ENABLE_CHECKING
   if (gimplify_ctxp->conditions == 0)
-    gcc_assert (!gimplify_ctxp->conditional_cleanups);
+    gcc_assert (GS_SEQ_EMPTY_P (&gimplify_ctxp->conditional_cleanups));
 #endif
   ++(gimplify_ctxp->conditions);
 }
@@ -237,17 +240,18 @@ gimple_push_condition (void)
    now, add any conditional cleanups we've seen to the prequeue.  */
 
 static void
-gimple_pop_condition (tree *pre_p)
+gimple_pop_condition (gs_seq pre_p)
 {
   int conds = --(gimplify_ctxp->conditions);
 
   gcc_assert (conds >= 0);
   if (conds == 0)
     {
-      append_to_statement_list (gimplify_ctxp->conditional_cleanups, pre_p);
-      gimplify_ctxp->conditional_cleanups = NULL_TREE;
+      gs_seq_append (&gimplify_ctxp->conditional_cleanups, pre_p);
+      gimplify_ctxp->conditional_cleanups = GS_SEQ_INIT;
     }
 }
+#endif
 
 /* A stable comparison routine for use with splay trees and DECLs.  */
 
@@ -333,7 +337,7 @@ append_to_statement_list_force (tree t, 
     append_to_statement_list_1 (t, list_p);
 }
 
-/* Both gimplify the statement T and append it to LIST_P.  */
+/* Both gimplify the statement T and append it to SEQ.  */
 
 void
 gimplify_and_add (tree t, gs_seq seq)
@@ -341,8 +345,7 @@ gimplify_and_add (tree t, gs_seq seq)
   struct gs_sequence tseq = GS_SEQ_INIT;
 
   gimplify_stmt (&t, &tseq);
-  if (TREE_SIDE_EFFECTS (GS_SEQ_FIRST (*tseq)))
-    gs_add (GS_SEQ_FIRST (*tseq), seq);
+  gs_seq_append (&tseq, seq);
 }
 
 /* Strip off a legitimate source ending from the input string NAME of
@@ -589,8 +592,11 @@ static tree
 internal_get_tmp_var (tree val, gs_seq pre_p, gs_seq post_p, bool is_formal)
 {
   tree t, mod;
+  struct gs_sequence tseq = GS_SEQ_INIT;
 
-  gimplify_expr (&val, pre_p, post_p, is_gimple_formal_tmp_rhs, fb_rvalue);
+  gimplify_expr (&val, &tseq, pre_p, post_p, is_gimple_formal_tmp_rhs,
+      		 fb_rvalue);
+  gs_seq_append (&tseq, pre_p);
 
   t = lookup_tmp_var (val, is_formal);
 
@@ -635,11 +641,11 @@ internal_get_tmp_var (tree val, gs_seq p
 }
 
 /* Returns a formal temporary variable initialized with VAL.  PRE_P
-   points to a statement list where side-effects needed to compute VAL
-   should be stored.  */
+   points to a sequence where side-effects needed to compute VAL should be
+   stored.  */
 
 tree
-get_formal_tmp_var (tree val, tree *pre_p)
+get_formal_tmp_var (tree val, gs_seq pre_p)
 {
   return internal_get_tmp_var (val, pre_p, NULL, true);
 }
@@ -648,7 +654,7 @@ get_formal_tmp_var (tree val, tree *pre_
    are as in gimplify_expr.  */
 
 tree
-get_initialized_tmp_var (tree val, tree *pre_p, tree *post_p)
+get_initialized_tmp_var (tree val, gs_seq pre_p, gs_seq post_p)
 {
   return internal_get_tmp_var (val, pre_p, post_p, false);
 }
@@ -774,7 +780,7 @@ annotate_one_with_locus (gimple gs, loca
 {
   /* All gimple statements have location.  */
 
-  if (! GS_LOCUS (gs) && should_carry_locus_p (gs))
+  if (GS_LOCUS_EMPTY_P (gs) && should_carry_locus_p (gs))
     GS_LOCUS (gs) = locus;
 }
 
@@ -909,12 +915,14 @@ unvisit_body (tree *body_p, tree fndecl)
 
 /* Unshare T and all the trees reached from T via TREE_CHAIN.  */
 
+#if 0
 static void
 unshare_all_trees (tree t)
 {
   walk_tree (&t, copy_if_shared_r, NULL, NULL);
   walk_tree (&t, unmark_visited_r, NULL, NULL);
 }
+#endif
 
 /* Unconditionally make an unshared copy of EXPR.  This is used when using
    stored expressions which span multiple functions, such as BINFO_VTABLE,
@@ -1049,7 +1057,7 @@ build_stack_save_restore (tree *save, tr
 /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
 
 static enum gimplify_status
-gimplify_bind_expr (tree *expr_p, tree *pre_p)
+gimplify_bind_expr (tree *expr_p, gs_seq pre_p)
 {
   tree bind_expr = *expr_p;
   bool old_save_stack = gimplify_ctxp->save_stack;
@@ -1088,7 +1096,7 @@ gimplify_bind_expr (tree *expr_p, tree *
   gimple_push_bind_expr (bind_expr);
   gimplify_ctxp->save_stack = false;
 
-  gimplify_to_stmt_list (&BIND_EXPR_BODY (bind_expr));
+  gimplify_stmt (&BIND_EXPR_BODY (bind_expr), pre_p);
 
   if (gimplify_ctxp->save_stack)
     {
@@ -1114,7 +1122,7 @@ gimplify_bind_expr (tree *expr_p, tree *
   if (temp)
     {
       *expr_p = temp;
-      append_to_statement_list (bind_expr, pre_p);
+      gimplify_and_add (bind_expr, pre_p);
       return GS_OK;
     }
   else
@@ -1129,7 +1137,7 @@ gimplify_bind_expr (tree *expr_p, tree *
    STMT should be stored.  */
 
 static enum gimplify_status
-gimplify_return_expr (tree stmt, gs_seq seq_p, gs_seq pre_p)
+gimplify_return_expr (tree stmt, gs_seq pre_p)
 {
   tree ret_expr = TREE_OPERAND (stmt, 0);
   tree result_decl, result;
@@ -1138,7 +1146,7 @@ gimplify_return_expr (tree stmt, gs_seq 
       || ret_expr == error_mark_node)
     {
       gs_add (gs_build_return (TREE_CODE (ret_expr) == RESULT_DECL, ret_expr),
-	      seq_p);
+	      pre_p);
       return GS_ALL_DONE;
     }
 
@@ -1199,7 +1207,7 @@ gimplify_return_expr (tree stmt, gs_seq 
     ret_expr = result;
   else
     ret_expr = build_gimple_modify_stmt (result_decl, result);
-  gs_add (gs_build_return (result == result_decl, ret_expr), seq_p);
+  gs_add (gs_build_return (result == result_decl, ret_expr), pre_p);
 
   return GS_ALL_DONE;
 }
@@ -1208,7 +1216,7 @@ gimplify_return_expr (tree stmt, gs_seq 
    and initialization explicit.  */
 
 static enum gimplify_status
-gimplify_decl_expr (tree *stmt_p)
+gimplify_decl_expr (tree *stmt_p, gs_seq seq_p)
 {
   tree stmt = *stmt_p;
   tree decl = DECL_EXPR_DECL (stmt);
@@ -1221,7 +1229,7 @@ gimplify_decl_expr (tree *stmt_p)
   if ((TREE_CODE (decl) == TYPE_DECL
        || TREE_CODE (decl) == VAR_DECL)
       && !TYPE_SIZES_GIMPLIFIED (TREE_TYPE (decl)))
-    gimplify_type_sizes (TREE_TYPE (decl), stmt_p);
+    gimplify_type_sizes (TREE_TYPE (decl), seq_p);
 
   if (TREE_CODE (decl) == VAR_DECL && !DECL_EXTERNAL (decl))
     {
@@ -1234,8 +1242,8 @@ gimplify_decl_expr (tree *stmt_p)
 	     of the emitted code: see mx_register_decls().  */
 	  tree t, addr, ptr_type;
 
-	  gimplify_one_sizepos (&DECL_SIZE (decl), stmt_p);
-	  gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), stmt_p);
+	  gimplify_one_sizepos (&DECL_SIZE (decl), seq_p);
+	  gimplify_one_sizepos (&DECL_SIZE_UNIT (decl), seq_p);
 
 	  /* All occurrences of this decl in final gimplified code will be
 	     replaced by indirection.  Setting DECL_VALUE_EXPR does two
@@ -1254,7 +1262,7 @@ gimplify_decl_expr (tree *stmt_p)
 	  t = fold_convert (ptr_type, t);
 	  t = build_gimple_modify_stmt (addr, t);
 
-	  gimplify_and_add (t, stmt_p);
+	  gimplify_and_add (t, seq_p);
 
 	  /* Indicate that we need to restore the stack level when the
 	     enclosing BIND_EXPR is exited.  */
@@ -1267,7 +1275,7 @@ gimplify_decl_expr (tree *stmt_p)
 	    {
 	      DECL_INITIAL (decl) = NULL_TREE;
 	      init = build2 (INIT_EXPR, void_type_node, decl, init);
-	      gimplify_and_add (init, stmt_p);
+	      gimplify_and_add (init, seq_p);
 	    }
 	  else
 	    /* We must still examine initializers for static variables
@@ -1292,13 +1300,13 @@ gimplify_decl_expr (tree *stmt_p)
    EXIT_EXPR, we need to append a label for it to jump to.  */
 
 static enum gimplify_status
-gimplify_loop_expr (tree *expr_p, tree *pre_p)
+gimplify_loop_expr (tree *expr_p, gs_seq pre_p)
 {
   tree saved_label = gimplify_ctxp->exit_label;
   tree start_label = build1 (LABEL_EXPR, void_type_node, NULL_TREE);
   tree jump_stmt = build_and_jump (&LABEL_EXPR_LABEL (start_label));
 
-  append_to_statement_list (start_label, pre_p);
+  gimplify_and_add (start_label, pre_p);
 
   gimplify_ctxp->exit_label = NULL_TREE;
 
@@ -1306,7 +1314,7 @@ gimplify_loop_expr (tree *expr_p, tree *
 
   if (gimplify_ctxp->exit_label)
     {
-      append_to_statement_list (jump_stmt, pre_p);
+      gimplify_and_add (jump_stmt, pre_p);
       *expr_p = build1 (LABEL_EXPR, void_type_node, gimplify_ctxp->exit_label);
     }
   else
@@ -1365,12 +1373,12 @@ sort_case_labels (tree label_vec)
    branch to.  */
 
 static enum gimplify_status
-gimplify_switch_expr (tree *expr_p, tree *pre_p)
+gimplify_switch_expr (tree *expr_p, gs_seq pre_p)
 {
   tree switch_expr = *expr_p;
   enum gimplify_status ret;
 
-  ret = gimplify_expr (&SWITCH_COND (switch_expr), pre_p, NULL,
+  ret = gimplify_expr (&SWITCH_COND (switch_expr), NULL, pre_p, NULL,
 		       is_gimple_val, fb_rvalue);
 
   if (SWITCH_BODY (switch_expr))
@@ -1422,7 +1430,7 @@ gimplify_switch_expr (tree *expr_p, tree
 
       label_vec = make_tree_vec (len + 1);
       SWITCH_LABELS (*expr_p) = label_vec;
-      append_to_statement_list (switch_expr, pre_p);
+      gimplify_and_add (switch_expr, pre_p);
 
       if (! default_case)
 	{
@@ -1430,7 +1438,7 @@ gimplify_switch_expr (tree *expr_p, tree
 	     around the switch body.  */
 	  default_case = build3 (CASE_LABEL_EXPR, void_type_node, NULL_TREE,
 				 NULL_TREE, create_artificial_label ());
-	  append_to_statement_list (SWITCH_BODY (switch_expr), pre_p);
+	  gimplify_and_add (SWITCH_BODY (switch_expr), pre_p);
 	  *expr_p = build1 (LABEL_EXPR, void_type_node,
 			    CASE_LABEL (default_case));
 	}
@@ -1702,15 +1710,15 @@ gimplify_var_or_parm_decl (tree *expr_p)
    union reference must be explicit, which was not always the case when we
    were splitting up array and member refs.
 
-   PRE_P points to the list where side effects that must happen before
+   PRE_P points to the sequence where side effects that must happen before
      *EXPR_P should be stored.
 
-   POST_P points to the list where side effects that must happen after
+   POST_P points to the sequence where side effects that must happen after
      *EXPR_P should be stored.  */
 
 static enum gimplify_status
-gimplify_compound_lval (tree *expr_p, tree *pre_p,
-			tree *post_p, fallback_t fallback)
+gimplify_compound_lval (tree *expr_p, gs_seq pre_p,
+			gs_seq post_p, fallback_t fallback)
 {
   tree *p;
   VEC(tree,heap) *stack;
@@ -1771,7 +1779,8 @@ gimplify_compound_lval (tree *expr_p, tr
 	      if (!is_gimple_min_invariant (low))
 		{
 	          TREE_OPERAND (t, 2) = low;
-		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+		  tret = gimplify_expr (&TREE_OPERAND (t, 2),
+		      			NULL, pre_p, post_p,
 					is_gimple_formal_tmp_reg, fb_rvalue);
 		  ret = MIN (ret, tret);
 		}
@@ -1790,7 +1799,8 @@ gimplify_compound_lval (tree *expr_p, tr
 	      if (!is_gimple_min_invariant (elmt_size))
 		{
 	          TREE_OPERAND (t, 3) = elmt_size;
-		  tret = gimplify_expr (&TREE_OPERAND (t, 3), pre_p, post_p,
+		  tret = gimplify_expr (&TREE_OPERAND (t, 3), 
+		      			NULL, pre_p, post_p,
 					is_gimple_formal_tmp_reg, fb_rvalue);
 		  ret = MIN (ret, tret);
 		}
@@ -1812,7 +1822,8 @@ gimplify_compound_lval (tree *expr_p, tr
 	      if (!is_gimple_min_invariant (offset))
 		{
 	          TREE_OPERAND (t, 2) = offset;
-		  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+		  tret = gimplify_expr (&TREE_OPERAND (t, 2), 
+		      			NULL, pre_p, post_p,
 					is_gimple_formal_tmp_reg, fb_rvalue);
 		  ret = MIN (ret, tret);
 		}
@@ -1823,7 +1834,7 @@ gimplify_compound_lval (tree *expr_p, tr
   /* Step 2 is to gimplify the base expression.  Make sure lvalue is set
      so as to match the min_lval predicate.  Failure to do so may result
      in the creation of large aggregate temporaries.  */
-  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval,
+  tret = gimplify_expr (p, NULL, pre_p, post_p, is_gimple_min_lval,
 			fallback | fb_lvalue);
   ret = MIN (ret, tret);
 
@@ -1846,17 +1857,20 @@ gimplify_compound_lval (tree *expr_p, tr
 	     branch is merged into mainline (dnovillo 2004-05-03).  */
 	  if (!is_gimple_min_invariant (TREE_OPERAND (t, 1)))
 	    {
-	      tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+	      tret = gimplify_expr (&TREE_OPERAND (t, 1), 
+		  		    NULL, pre_p, post_p,
 				    is_gimple_formal_tmp_reg, fb_rvalue);
 	      ret = MIN (ret, tret);
 	    }
 	}
       else if (TREE_CODE (t) == BIT_FIELD_REF)
 	{
-	  tret = gimplify_expr (&TREE_OPERAND (t, 1), pre_p, post_p,
+	  tret = gimplify_expr (&TREE_OPERAND (t, 1), 
+	      			NULL, pre_p, post_p,
 				is_gimple_val, fb_rvalue);
 	  ret = MIN (ret, tret);
-	  tret = gimplify_expr (&TREE_OPERAND (t, 2), pre_p, post_p,
+	  tret = gimplify_expr (&TREE_OPERAND (t, 2), 
+	      			NULL, pre_p, post_p,
 				is_gimple_val, fb_rvalue);
 	  ret = MIN (ret, tret);
 	}
@@ -1869,7 +1883,7 @@ gimplify_compound_lval (tree *expr_p, tr
       recalculate_side_effects (t);
     }
 
-  tret = gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fallback);
+  tret = gimplify_expr (p, NULL, pre_p, post_p, is_gimple_min_lval, fallback);
   ret = MIN (ret, tret);
 
   /* If the outermost expression is a COMPONENT_REF, canonicalize its type.  */
@@ -1897,11 +1911,13 @@ gimplify_compound_lval (tree *expr_p, tr
 	in another expression.  */
 
 static enum gimplify_status
-gimplify_self_mod_expr (tree *expr_p, tree *pre_p, tree *post_p,
+gimplify_self_mod_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p,
 			bool want_value)
 {
   enum tree_code code;
-  tree lhs, lvalue, rhs, t1, post = NULL, *orig_post_p = post_p;
+  tree lhs, lvalue, rhs, t1;
+  struct gs_sequence post = GS_SEQ_INIT;
+  gs_seq orig_post_p = post_p;
   bool postfix;
   enum tree_code arith_code;
   enum gimplify_status ret;
@@ -1931,7 +1947,8 @@ gimplify_self_mod_expr (tree *expr_p, tr
 
   /* Gimplify the LHS into a GIMPLE lvalue.  */
   lvalue = TREE_OPERAND (*expr_p, 0);
-  ret = gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+  ret = gimplify_expr (&lvalue, NULL, pre_p, post_p,
+      		       is_gimple_lvalue, fb_lvalue);
   if (ret == GS_ERROR)
     return ret;
 
@@ -1943,7 +1960,8 @@ gimplify_self_mod_expr (tree *expr_p, tr
      that as the result value and in the postqueue operation.  */
   if (postfix)
     {
-      ret = gimplify_expr (&lhs, pre_p, post_p, is_gimple_val, fb_rvalue);
+      ret = gimplify_expr (&lhs, NULL, pre_p, post_p,
+	  		   is_gimple_val, fb_rvalue);
       if (ret == GS_ERROR)
 	return ret;
     }
@@ -1954,7 +1972,14 @@ gimplify_self_mod_expr (tree *expr_p, tr
   if (postfix)
     {
       gimplify_and_add (t1, orig_post_p);
-      append_to_statement_list (post, orig_post_p);
+
+      /* FIXME tuples: Why were we gimplifying here?  Shouldn't this be
+	 gimple already?  We should've append_to_statement_list_force() ??
+
+	 Hmmm... I hope ``post'' didn't contain ungimplified stuff.  */
+      /* gimplify_and_add (post, orig_post_p); */
+      gs_seq_append (&post, orig_post_p);
+
       *expr_p = lhs;
       return GS_ALL_DONE;
     }
@@ -1994,7 +2019,7 @@ maybe_with_size_expr (tree *expr_p)
 /* Subroutine of gimplify_call_expr:  Gimplify a single argument.  */
 
 static enum gimplify_status
-gimplify_arg (tree *expr_p, tree *pre_p)
+gimplify_arg (tree *expr_p, gs_seq pre_p)
 {
   bool (*test) (tree);
   fallback_t fb;
@@ -2016,7 +2041,7 @@ gimplify_arg (tree *expr_p, tree *pre_p)
      the argument list must occur before the actual call. So, when
      gimplifying arguments, force gimplify_expr to use an internal
      post queue which is then appended to the end of PRE_P.  */
-  return gimplify_expr (expr_p, pre_p, NULL, test, fb);
+  return gimplify_expr (expr_p, NULL, pre_p, NULL, test, fb);
 }
 
 /* Gimplify the CALL_EXPR node pointed to by EXPR_P.  PRE_P points to the
@@ -2024,7 +2049,7 @@ gimplify_arg (tree *expr_p, tree *pre_p)
    WANT_VALUE is true if the result of the call is desired.  */
 
 static enum gimplify_status
-gimplify_call_expr (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_call_expr (tree *expr_p, gs_seq pre_p, bool want_value)
 {
   tree decl;
   enum gimplify_status ret;
@@ -2087,7 +2112,7 @@ gimplify_call_expr (tree *expr_p, tree *
   /* There is a sequence point before the call, so any side effects in
      the calling expression must occur before the actual call.  Force
      gimplify_expr to use an internal post queue.  */
-  ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
+  ret = gimplify_expr (&CALL_EXPR_FN (*expr_p), NULL, pre_p, NULL,
 		       is_gimple_call_addr, fb_rvalue);
 
   nargs = call_expr_nargs (*expr_p);
@@ -2420,8 +2445,9 @@ gimple_boolify (tree expr)
     PRE_P points to the list where side effects that must happen before
       *EXPR_P should be stored.  */
 
+#if 0
 static enum gimplify_status
-gimplify_cond_expr (tree *expr_p, tree *pre_p, fallback_t fallback)
+gimplify_cond_expr (tree *expr_p, gs_seq pre_p, fallback_t fallback)
 {
   tree expr = *expr_p;
   tree tmp, tmp2, type;
@@ -2541,10 +2567,12 @@ gimplify_cond_expr (tree *expr_p, tree *
   *expr_p = expr;
   return ret;
 }
+#endif
 
 /* A subroutine of gimplify_modify_expr.  Replace a MODIFY_EXPR with
    a call to __builtin_memcpy.  */
 
+#if 0
 static enum gimplify_status
 gimplify_modify_expr_to_memcpy (tree *expr_p, tree size, bool want_value)
 {
@@ -2593,6 +2621,7 @@ gimplify_modify_expr_to_memset (tree *ex
   *expr_p = t;
   return GS_OK;
 }
+#endif
 
 /* A subroutine of gimplify_init_ctor_preeval.  Called via walk_tree,
    determine, cautiously, if a CONSTRUCTOR overlaps the lhs of an
@@ -2652,7 +2681,7 @@ gimplify_init_ctor_preeval_1 (tree *tp, 
    into temporaries.  */
 
 static void
-gimplify_init_ctor_preeval (tree *expr_p, tree *pre_p, tree *post_p,
+gimplify_init_ctor_preeval (tree *expr_p, gs_seq pre_p, gs_seq post_p,
 			    struct gimplify_init_ctor_preeval_data *data)
 {
   enum gimplify_status one;
@@ -2689,7 +2718,8 @@ gimplify_init_ctor_preeval (tree *expr_p
      gimplification now means that we won't have to deal with complicated
      language-specific trees, nor trees like SAVE_EXPR that can induce
      exponential search behavior.  */
-  one = gimplify_expr (expr_p, pre_p, post_p, is_gimple_mem_rhs, fb_rvalue);
+  one = gimplify_expr (expr_p, NULL, pre_p, post_p,
+      		       is_gimple_mem_rhs, fb_rvalue);
   if (one == GS_ERROR)
     {
       *expr_p = NULL;
@@ -2735,12 +2765,12 @@ gimplify_init_ctor_preeval (tree *expr_p
    already been taken care of for us, in gimplify_init_ctor_preeval().  */
 
 static void gimplify_init_ctor_eval (tree, VEC(constructor_elt,gc) *,
-				     tree *, bool);
+				     gs_seq, bool);
 
 static void
 gimplify_init_ctor_eval_range (tree object, tree lower, tree upper,
 			       tree value, tree array_elt_type,
-			       tree *pre_p, bool cleared)
+			       gs_seq pre_p, bool cleared)
 {
   tree loop_entry_label, loop_exit_label;
   tree var, var_type, cref, tmp;
@@ -2751,12 +2781,10 @@ gimplify_init_ctor_eval_range (tree obje
   /* Create and initialize the index variable.  */
   var_type = TREE_TYPE (upper);
   var = create_tmp_var (var_type, NULL);
-  append_to_statement_list (build_gimple_modify_stmt (var, lower), pre_p);
+  gimplify_and_add (build_gimple_modify_stmt (var, lower), pre_p);
 
   /* Add the loop entry label.  */
-  append_to_statement_list (build1 (LABEL_EXPR,
-				    void_type_node,
-				    loop_entry_label),
+  gimplify_and_add (build1 (LABEL_EXPR, void_type_node, loop_entry_label),
 			    pre_p);
 
   /* Build the reference.  */
@@ -2772,7 +2800,7 @@ gimplify_init_ctor_eval_range (tree obje
     gimplify_init_ctor_eval (cref, CONSTRUCTOR_ELTS (value),
 			     pre_p, cleared);
   else
-    append_to_statement_list (build_gimple_modify_stmt (cref, value), pre_p);
+    gimplify_and_add (build_gimple_modify_stmt (cref, value), pre_p);
 
   /* We exit the loop when the index var is equal to the upper bound.  */
   gimplify_and_add (build3 (COND_EXPR, void_type_node,
@@ -2787,18 +2815,14 @@ gimplify_init_ctor_eval_range (tree obje
   /* Otherwise, increment the index var...  */
   tmp = build2 (PLUS_EXPR, var_type, var,
 		fold_convert (var_type, integer_one_node));
-  append_to_statement_list (build_gimple_modify_stmt (var, tmp), pre_p);
+  gimplify_and_add (build_gimple_modify_stmt (var, tmp), pre_p);
 
   /* ...and jump back to the loop entry.  */
-  append_to_statement_list (build1 (GOTO_EXPR,
-				    void_type_node,
-				    loop_entry_label),
+  gimplify_and_add (build1 (GOTO_EXPR, void_type_node, loop_entry_label),
 			    pre_p);
 
   /* Add the loop exit label.  */
-  append_to_statement_list (build1 (LABEL_EXPR,
-				    void_type_node,
-				    loop_exit_label),
+  gimplify_and_add (build1 (LABEL_EXPR, void_type_node, loop_exit_label),
 			    pre_p);
 }
 
@@ -2832,7 +2856,7 @@ zero_sized_type (tree type)
 
 static void
 gimplify_init_ctor_eval (tree object, VEC(constructor_elt,gc) *elts,
-			 tree *pre_p, bool cleared)
+			 gs_seq pre_p, bool cleared)
 {
   tree array_elt_type = NULL;
   unsigned HOST_WIDE_INT ix;
@@ -2914,9 +2938,10 @@ gimplify_init_ctor_eval (tree object, VE
    initializers, so if not all elements are initialized we keep the
    original MODIFY_EXPR, we just remove all of the constructor elements.  */
 
+#if 0
 static enum gimplify_status
-gimplify_init_constructor (tree *expr_p, tree *pre_p,
-			   tree *post_p, bool want_value)
+gimplify_init_constructor (tree *expr_p, gs_seq pre_p,
+			   gs_seq post_p, bool want_value)
 {
   tree object;
   tree ctor = GENERIC_TREE_OPERAND (*expr_p, 1);
@@ -2927,7 +2952,7 @@ gimplify_init_constructor (tree *expr_p,
   if (TREE_CODE (ctor) != CONSTRUCTOR)
     return GS_UNHANDLED;
 
-  ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+  ret = gimplify_expr (&GENERIC_TREE_OPERAND (*expr_p, 0), NULL, pre_p, post_p,
 		       is_gimple_lvalue, fb_lvalue);
   if (ret == GS_ERROR)
     return ret;
@@ -3087,8 +3112,7 @@ gimplify_init_constructor (tree *expr_p,
 	       case of variable sized types.  Avoid shared tree structures.  */
 	    CONSTRUCTOR_ELTS (ctor) = NULL;
 	    object = unshare_expr (object);
-	    gimplify_stmt (expr_p);
-	    append_to_statement_list (*expr_p, pre_p);
+	    gimplify_stmt (expr_p, pre_p);
 	  }
 
 	/* If we have not block cleared the object, or if there are nonzero
@@ -3129,7 +3153,8 @@ gimplify_init_constructor (tree *expr_p,
 	  {
 	    ctor = build2 (COMPLEX_EXPR, type, r, i);
 	    TREE_OPERAND (*expr_p, 1) = ctor;
-	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
+	    ret = gimplify_expr (&TREE_OPERAND (*expr_p, 1),
+				 NULL, pre_p, post_p,
 				 rhs_predicate_for (TREE_OPERAND (*expr_p, 0)),
 				 fb_rvalue);
 	  }
@@ -3174,7 +3199,7 @@ gimplify_init_constructor (tree *expr_p,
 	for (ix = 0; VEC_iterate (constructor_elt, elts, ix, ce); ix++)
 	  {
 	    enum gimplify_status tret;
-	    tret = gimplify_expr (&ce->value, pre_p, post_p,
+	    tret = gimplify_expr (&ce->value, NULL, pre_p, post_p,
 				  is_gimple_val, fb_rvalue);
 	    if (tret == GS_ERROR)
 	      ret = GS_ERROR;
@@ -3200,6 +3225,7 @@ gimplify_init_constructor (tree *expr_p,
   else
     return GS_ALL_DONE;
 }
+#endif
 
 /* Given a pointer value OP0, return a simplified version of an
    indirection through OP0, or NULL_TREE if no simplification is
@@ -3261,9 +3287,10 @@ fold_indirect_ref_rhs (tree t)
 /* Subroutine of gimplify_modify_expr to do simplifications of MODIFY_EXPRs
    based on the code of the RHS.  We loop for as long as something changes.  */
 
+#if 0
 static enum gimplify_status
-gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p, tree *pre_p,
-			  tree *post_p, bool want_value)
+gimplify_modify_expr_rhs (tree *expr_p, tree *from_p, tree *to_p,
+			  gs_seq pre_p, gs_seq post_p, bool want_value)
 {
   enum gimplify_status ret = GS_OK;
 
@@ -3319,14 +3346,20 @@ gimplify_modify_expr_rhs (tree *expr_p, 
       case COMPOUND_EXPR:
 	/* Remove any COMPOUND_EXPR in the RHS so the following cases will be
 	   caught.  */
+#if 0
 	gimplify_compound_expr (from_p, pre_p, true);
+#endif
+	gcc_unreachable();
 	ret = GS_OK;
 	break;
 
       case CONSTRUCTOR:
 	/* If we're initializing from a CONSTRUCTOR, break this into
 	   individual MODIFY_EXPRs.  */
+#if 0
 	return gimplify_init_constructor (expr_p, pre_p, post_p, want_value);
+#endif
+	gcc_unreachable(); return GS_ALL_DONE;
 
       case COND_EXPR:
 	/* If we're assigning to a non-register type, push the assignment
@@ -3340,7 +3373,7 @@ gimplify_modify_expr_rhs (tree *expr_p, 
 	    tree cond = *from_p;
 	    tree result = *to_p;
 
-	    ret = gimplify_expr (&result, pre_p, post_p,
+	    ret = gimplify_expr (&result, NULL, pre_p, post_p,
 				 is_gimple_min_lval, fb_lvalue);
 	    if (ret != GS_ERROR)
 	      ret = GS_OK;
@@ -3429,7 +3462,7 @@ gimplify_modify_expr_rhs (tree *expr_p, 
 	  tree wrap = *from_p;
 	  tree t;
 
-	  ret = gimplify_expr (to_p, pre_p, post_p,
+	  ret = gimplify_expr (to_p, NULL, pre_p, post_p,
 			       is_gimple_min_lval, fb_lvalue);
 	  if (ret != GS_ERROR)
 	    ret = GS_OK;
@@ -3454,6 +3487,7 @@ gimplify_modify_expr_rhs (tree *expr_p, 
 
   return ret;
 }
+#endif
 
 /* Destructively convert the TREE pointer in TP into a gimple tuple if
    appropriate.  */
@@ -3506,7 +3540,7 @@ tree_to_gimple_tuple (tree *tp)
    DECL_GIMPLE_REG_P set.  */
 
 static enum gimplify_status
-gimplify_modify_expr_complex_part (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_modify_expr_complex_part (tree *expr_p, gs_seq pre_p, bool want_value)
 {
   enum tree_code code, ocode;
   tree lhs, rhs, new_rhs, other, realpart, imagpart;
@@ -3528,17 +3562,10 @@ gimplify_modify_expr_complex_part (tree 
   else
     new_rhs = build2 (COMPLEX_EXPR, TREE_TYPE (lhs), realpart, imagpart);
 
-  GENERIC_TREE_OPERAND (*expr_p, 0) = lhs;
-  GENERIC_TREE_OPERAND (*expr_p, 1) = new_rhs;
-
   if (want_value)
-    {
-      tree_to_gimple_tuple (expr_p);
-
-      append_to_statement_list (*expr_p, pre_p);
-      *expr_p = rhs;
-    }
+    *expr_p = rhs;
 
+  gs_add (gs_build_assign (lhs, new_rhs), pre_p);
   return GS_ALL_DONE;
 }
 
@@ -3558,7 +3585,8 @@ gimplify_modify_expr_complex_part (tree 
 	in another expression.  */
 
 static enum gimplify_status
-gimplify_modify_expr (tree *expr_p, tree *pre_p, tree *post_p, bool want_value)
+gimplify_modify_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p,
+		      bool want_value)
 {
   tree *from_p = &GENERIC_TREE_OPERAND (*expr_p, 1);
   tree *to_p = &GENERIC_TREE_OPERAND (*expr_p, 0);
@@ -3572,19 +3600,19 @@ gimplify_modify_expr (tree *expr_p, tree
      as statements and throw away the assignment.  */
   if (zero_sized_type (TREE_TYPE (*from_p)))
     {
-      gimplify_stmt (from_p);
-      gimplify_stmt (to_p);
-      append_to_statement_list (*from_p, pre_p);
-      append_to_statement_list (*to_p, pre_p);
+      gimplify_stmt (from_p, pre_p);
+      gimplify_stmt (to_p, pre_p);
       *expr_p = NULL_TREE;
       return GS_ALL_DONE;
     }
 
+#if 0
   /* See if any simplifications can be done based on what the RHS is.  */
   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
 				  want_value);
   if (ret != GS_UNHANDLED)
     return ret;
+#endif
 
   /* If the value being copied is of variable width, compute the length
      of the copy into a WITH_SIZE_EXPR.   Note that we need to do this
@@ -3594,15 +3622,16 @@ gimplify_modify_expr (tree *expr_p, tree
      that is what we must here.  */
   maybe_with_size_expr (from_p);
 
-  ret = gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
+  ret = gimplify_expr (to_p, NULL, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
   if (ret == GS_ERROR)
     return ret;
 
-  ret = gimplify_expr (from_p, pre_p, post_p,
+  ret = gimplify_expr (from_p, NULL, pre_p, post_p,
 		       rhs_predicate_for (*to_p), fb_rvalue);
   if (ret == GS_ERROR)
     return ret;
 
+#if 0
   /* Now see if the above changed *from_p to something we handle specially.  */
   ret = gimplify_modify_expr_rhs (expr_p, from_p, to_p, pre_p, post_p,
 				  want_value);
@@ -3625,6 +3654,7 @@ gimplify_modify_expr (tree *expr_p, tree
 	  return gimplify_modify_expr_to_memcpy (expr_p, size, want_value);
 	}
     }
+#endif
 
   /* Transform partial stores to non-addressable complex variables into
      total stores.  This allows us to use real instead of virtual operands
@@ -3655,14 +3685,15 @@ gimplify_modify_expr (tree *expr_p, tree
       SET_DECL_DEBUG_EXPR (*from_p, *to_p);
     }
 
+  gs_add (gs_build_assign (*to_p, *from_p), pre_p);
+
   if (want_value)
     {
-      tree_to_gimple_tuple (expr_p);
-
-      append_to_statement_list (*expr_p, pre_p);
       *expr_p = *to_p;
       return GS_OK;
     }
+  else
+    *expr_p = NULL;
 
   return GS_ALL_DONE;
 }
@@ -3748,8 +3779,9 @@ gimplify_boolean_expr (tree *expr_p)
    invocations of gimplify_expr.  Would probably save on creations
    of statement_list nodes.  */
 
+#if 0
 static enum gimplify_status
-gimplify_compound_expr (tree *expr_p, tree *pre_p, bool want_value)
+gimplify_compound_expr (tree *expr_p, gs_seq pre_p, bool want_value)
 {
   tree t = *expr_p;
 
@@ -3776,10 +3808,12 @@ gimplify_compound_expr (tree *expr_p, tr
       return GS_ALL_DONE;
     }
 }
+#endif
 
 /* Gimplifies a statement list.  These may be created either by an
    enlightened front-end, or by shortcut_cond_expr.  */
 
+#if 0
 static enum gimplify_status
 gimplify_statement_list (tree *expr_p, tree *pre_p)
 {
@@ -3791,7 +3825,10 @@ gimplify_statement_list (tree *expr_p, t
     {
       tree t;
 
+#if 0
       gimplify_stmt (tsi_stmt_ptr (i));
+#endif
+      gcc_unreachable();
 
       t = tsi_stmt (i);
       if (t == NULL)
@@ -3814,6 +3851,7 @@ gimplify_statement_list (tree *expr_p, t
 
   return GS_ALL_DONE;
 }
+#endif
 
 /*  Gimplify a SAVE_EXPR node.  EXPR_P points to the expression to
     gimplify.  After gimplification, EXPR_P will point to a new temporary
@@ -3823,7 +3861,7 @@ gimplify_statement_list (tree *expr_p, t
 	*EXPR_P should be stored.  */
 
 static enum gimplify_status
-gimplify_save_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_save_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p)
 {
   enum gimplify_status ret = GS_ALL_DONE;
   tree val;
@@ -3839,9 +3877,8 @@ gimplify_save_expr (tree *expr_p, tree *
 	 being executed only for its side-effects.  */
       if (TREE_TYPE (val) == void_type_node)
 	{
-	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
+	  ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), NULL, pre_p, post_p,
 			       is_gimple_stmt, fb_none);
-	  append_to_statement_list (TREE_OPERAND (*expr_p, 0), pre_p);
 	  val = NULL;
 	}
       else
@@ -3870,7 +3907,7 @@ gimplify_save_expr (tree *expr_p, tree *
 	*EXPR_P should be stored.  */
 
 static enum gimplify_status
-gimplify_addr_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_addr_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p)
 {
   tree expr = *expr_p;
   tree op0 = TREE_OPERAND (expr, 0);
@@ -3936,7 +3973,7 @@ gimplify_addr_expr (tree *expr_p, tree *
 	 the address of a call that returns a struct; see
 	 gcc.dg/c99-array-lval-1.c.  The gimplifier will correctly make
 	 the implied temporary explicit.  */
-      ret = gimplify_expr (&TREE_OPERAND (expr, 0), pre_p, post_p,
+      ret = gimplify_expr (&TREE_OPERAND (expr, 0), NULL, pre_p, post_p,
 			   is_gimple_addressable, fb_either);
       if (ret != GS_ERROR)
 	{
@@ -3964,7 +4001,7 @@ gimplify_addr_expr (tree *expr_p, tree *
    value; output operands should be a gimple lvalue.  */
 
 static enum gimplify_status
-gimplify_asm_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_asm_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p)
 {
   tree expr = *expr_p;
   int noutputs = list_length (ASM_OUTPUTS (expr));
@@ -3992,7 +4029,7 @@ gimplify_asm_expr (tree *expr_p, tree *p
       if (!allows_reg && allows_mem)
 	lang_hooks.mark_addressable (TREE_VALUE (link));
 
-      tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+      tret = gimplify_expr (&TREE_VALUE (link), NULL, pre_p, post_p,
 			    is_inout ? is_gimple_min_lval : is_gimple_lvalue,
 			    fb_lvalue | fb_mayfail);
       if (tret == GS_ERROR)
@@ -4104,7 +4141,7 @@ gimplify_asm_expr (tree *expr_p, tree *p
       /* If the operand is a memory input, it should be an lvalue.  */
       if (!allows_reg && allows_mem)
 	{
-	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+	  tret = gimplify_expr (&TREE_VALUE (link), NULL, pre_p, post_p,
 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
 	  lang_hooks.mark_addressable (TREE_VALUE (link));
 	  if (tret == GS_ERROR)
@@ -4115,7 +4152,7 @@ gimplify_asm_expr (tree *expr_p, tree *p
 	}
       else
 	{
-	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
+	  tret = gimplify_expr (&TREE_VALUE (link), NULL, pre_p, post_p,
 				is_gimple_asm_val, fb_rvalue);
 	  if (tret == GS_ERROR)
 	    ret = tret;
@@ -4139,6 +4176,7 @@ gimplify_asm_expr (tree *expr_p, tree *p
    having an optimizer to tighten up try/finally regions would be a Good
    Thing.  */
 
+#if 0
 static enum gimplify_status
 gimplify_cleanup_point_expr (tree *expr_p, tree *pre_p)
 {
@@ -4151,9 +4189,9 @@ gimplify_cleanup_point_expr (tree *expr_
      CLEANUP_POINT_EXPR and the cleanup.  So save and reset the count and
      any cleanups collected outside the CLEANUP_POINT_EXPR.  */
   int old_conds = gimplify_ctxp->conditions;
-  tree old_cleanups = gimplify_ctxp->conditional_cleanups;
+  struct gs_sequence old_cleanups = gimplify_ctxp->conditional_cleanups;
   gimplify_ctxp->conditions = 0;
-  gimplify_ctxp->conditional_cleanups = NULL_TREE;
+  gimplify_ctxp->conditional_cleanups = GS_SEQ_INIT;
 
   body = TREE_OPERAND (*expr_p, 0);
   gimplify_to_stmt_list (&body);
@@ -4208,12 +4246,13 @@ gimplify_cleanup_point_expr (tree *expr_
       return GS_ALL_DONE;
     }
 }
+#endif
 
 /* Insert a cleanup marker for gimplify_cleanup_point_expr.  CLEANUP
    is the cleanup action required.  */
 
 static void
-gimple_push_cleanup (tree var, tree cleanup, bool eh_only, tree *pre_p)
+gimple_push_cleanup (tree var, tree cleanup, bool eh_only, gs_seq pre_p)
 {
   tree wce;
 
@@ -4245,14 +4284,16 @@ gimple_push_cleanup (tree var, tree clea
 	   val
       */
 
+#if 0 /* FIXME tuples */
       tree flag = create_tmp_var (boolean_type_node, "cleanup");
-      tree ffalse = build_gimple_modify_stmt (flag, boolean_false_node);
-      tree ftrue = build_gimple_modify_stmt (flag, boolean_true_node);
+      gimple ffalse = gs_build_assign (flag, boolean_false_node);
+      gimple ftrue = gs_build_assign (flag, boolean_true_node);
       cleanup = build3 (COND_EXPR, void_type_node, flag, cleanup, NULL);
       wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
-      append_to_statement_list (ffalse, &gimplify_ctxp->conditional_cleanups);
-      append_to_statement_list (wce, &gimplify_ctxp->conditional_cleanups);
-      append_to_statement_list (ftrue, pre_p);
+      gs_add (ffalse, &gimplify_ctxp->conditional_cleanups);
+      gs_seq_append (wce, &gimplify_ctxp->conditional_cleanups);
+      gs_add (ftrue, pre_p);
+#endif
 
       /* Because of this manipulation, and the EH edges that jump
 	 threading cannot redirect, the temporary (VAR) will appear
@@ -4263,16 +4304,18 @@ gimple_push_cleanup (tree var, tree clea
     {
       wce = build1 (WITH_CLEANUP_EXPR, void_type_node, cleanup);
       CLEANUP_EH_ONLY (wce) = eh_only;
+#if 0
       append_to_statement_list (wce, pre_p);
+#endif
     }
 
-  gimplify_stmt (&TREE_OPERAND (wce, 0));
+  gimplify_stmt (&TREE_OPERAND (wce, 0), pre_p);
 }
 
 /* Gimplify a TARGET_EXPR which doesn't appear on the rhs of an INIT_EXPR.  */
 
 static enum gimplify_status
-gimplify_target_expr (tree *expr_p, tree *pre_p, tree *post_p)
+gimplify_target_expr (tree *expr_p, gs_seq pre_p, gs_seq post_p)
 {
   tree targ = *expr_p;
   tree temp = TARGET_EXPR_SLOT (targ);
@@ -4288,12 +4331,14 @@ gimplify_target_expr (tree *expr_p, tree
       /* If TARGET_EXPR_INITIAL is void, then the mere evaluation of the
 	 expression is supposed to initialize the slot.  */
       if (VOID_TYPE_P (TREE_TYPE (init)))
-	ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt, fb_none);
+	ret = gimplify_expr (&init, NULL, pre_p, post_p,
+	    		     is_gimple_stmt, fb_none);
       else
 	{
 	  init = build2 (INIT_EXPR, void_type_node, temp, init);
-	  ret = gimplify_expr (&init, pre_p, post_p, is_gimple_stmt,
-			       fb_none);
+	  ret = gimplify_expr (&init, NULL, pre_p, post_p, 
+	      		       is_gimple_stmt, fb_none);
+	  init = NULL;
 	}
       if (ret == GS_ERROR)
 	{
@@ -4301,12 +4346,13 @@ gimplify_target_expr (tree *expr_p, tree
 	  TARGET_EXPR_INITIAL (targ) = NULL_TREE;
 	  return GS_ERROR;
 	}
-      append_to_statement_list (init, pre_p);
+      if (init)
+	gimplify_and_add (init, pre_p);
 
       /* If needed, push the cleanup for the temp.  */
       if (TARGET_EXPR_CLEANUP (targ))
 	{
-	  gimplify_stmt (&TARGET_EXPR_CLEANUP (targ));
+	  gimplify_stmt (&TARGET_EXPR_CLEANUP (targ), pre_p);
 	  gimple_push_cleanup (temp, TARGET_EXPR_CLEANUP (targ),
 			       CLEANUP_EH_ONLY (targ), pre_p);
 	}
@@ -4325,8 +4371,7 @@ gimplify_target_expr (tree *expr_p, tree
 
 /* Gimplification of expression trees.  */
 
-/* Gimplify an expression which appears at statement context; usually, this
-   means replacing it with a suitably gimple STATEMENT_LIST.  */
+/* Gimplify an expression which appears at statement context into SEQ_P.  */
 
 void
 gimplify_stmt (tree *stmt_p, gs_seq seq_p)
@@ -4339,7 +4384,11 @@ gimplify_stmt (tree *stmt_p, gs_seq seq_
 void
 gimplify_to_stmt_list (tree *stmt_p)
 {
+  /* FIXME tuples: This should be obsoleted in favor of putting everything
+     in a sequence.  */
+#if 0
   gimplify_stmt (stmt_p);
+#endif
   if (!*stmt_p)
     *stmt_p = alloc_stmt_list ();
   else if (TREE_CODE (*stmt_p) != STATEMENT_LIST)
@@ -4696,7 +4745,7 @@ omp_check_private (struct gimplify_omp_c
    and previous omp contexts.  */
 
 static void
-gimplify_scan_omp_clauses (tree *list_p, tree *pre_p, bool in_parallel,
+gimplify_scan_omp_clauses (tree *list_p, gs_seq pre_p, bool in_parallel,
 			   bool in_combined_parallel)
 {
   struct gimplify_omp_ctx *ctx, *outer_ctx;
@@ -4751,10 +4800,10 @@ gimplify_scan_omp_clauses (tree *list_p,
 				GOVD_LOCAL | GOVD_SEEN);
 	      gimplify_omp_ctxp = ctx;
 	      push_gimplify_context ();
-	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c));
+	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_INIT (c), pre_p);
 	      pop_gimplify_context (OMP_CLAUSE_REDUCTION_INIT (c));
 	      push_gimplify_context ();
-	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c));
+	      gimplify_stmt (&OMP_CLAUSE_REDUCTION_MERGE (c), pre_p);
 	      pop_gimplify_context (OMP_CLAUSE_REDUCTION_MERGE (c));
 	      gimplify_omp_ctxp = outer_ctx;
 	    }
@@ -4790,7 +4839,7 @@ gimplify_scan_omp_clauses (tree *list_p,
 
 	case OMP_CLAUSE_SCHEDULE:
 	case OMP_CLAUSE_NUM_THREADS:
-	  gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), pre_p, NULL,
+	  gs = gimplify_expr (&OMP_CLAUSE_OPERAND (c, 0), NULL, pre_p, NULL,
 			      is_gimple_val, fb_rvalue);
 	  if (gs == GS_ERROR)
 	    remove = true;
@@ -4945,7 +4994,7 @@ gimplify_adjust_omp_clauses (tree *list_
    decls will be decomposed during gimplification.  */
 
 static enum gimplify_status
-gimplify_omp_parallel (tree *expr_p, tree *pre_p)
+gimplify_omp_parallel (tree *expr_p, gs_seq pre_p)
 {
   tree expr = *expr_p;
 
@@ -4954,7 +5003,7 @@ gimplify_omp_parallel (tree *expr_p, tre
 
   push_gimplify_context ();
 
-  gimplify_stmt (&OMP_PARALLEL_BODY (expr));
+  gimplify_stmt (&OMP_PARALLEL_BODY (expr), pre_p);
 
   if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
     pop_gimplify_context (OMP_PARALLEL_BODY (expr));
@@ -4969,7 +5018,7 @@ gimplify_omp_parallel (tree *expr_p, tre
 /* Gimplify the gross structure of an OMP_FOR statement.  */
 
 static enum gimplify_status
-gimplify_omp_for (tree *expr_p, tree *pre_p)
+gimplify_omp_for (tree *expr_p, gs_seq pre_p)
 {
   tree for_stmt, decl, t;
   enum gimplify_status ret = GS_OK;
@@ -4991,9 +5040,12 @@ gimplify_omp_for (tree *expr_p, tree *pr
   else
     omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
 
-  ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+#if 0
+  ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1), NULL,
 			&OMP_FOR_PRE_BODY (for_stmt),
 			NULL, is_gimple_val, fb_rvalue);
+#endif
+  
 
   tree_to_gimple_tuple (&OMP_FOR_INIT (for_stmt));
 
@@ -5001,9 +5053,11 @@ gimplify_omp_for (tree *expr_p, tree *pr
   gcc_assert (COMPARISON_CLASS_P (t));
   gcc_assert (GENERIC_TREE_OPERAND (t, 0) == decl);
 
-  ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1),
+#if 0
+  ret |= gimplify_expr (&GENERIC_TREE_OPERAND (t, 1), NULL,
 			&OMP_FOR_PRE_BODY (for_stmt),
 			NULL, is_gimple_val, fb_rvalue);
+#endif
 
   tree_to_gimple_tuple (&OMP_FOR_INCR (for_stmt));
   t = OMP_FOR_INCR (for_stmt);
@@ -5044,8 +5098,11 @@ gimplify_omp_for (tree *expr_p, tree *pr
 	  gcc_unreachable ();
 	}
 
-      ret |= gimplify_expr (&TREE_OPERAND (t, 1), &OMP_FOR_PRE_BODY (for_stmt),
+#if 0
+      ret |= gimplify_expr (&TREE_OPERAND (t, 1),
+			    NULL, &OMP_FOR_PRE_BODY (for_stmt),
 			    NULL, is_gimple_val, fb_rvalue);
+#endif
       break;
 
     default:
@@ -5062,7 +5119,7 @@ gimplify_omp_for (tree *expr_p, tree *pr
    In particular, OMP_SECTIONS and OMP_SINGLE.  */
 
 static enum gimplify_status
-gimplify_omp_workshare (tree *expr_p, tree *pre_p)
+gimplify_omp_workshare (tree *expr_p, gs_seq pre_p)
 {
   tree stmt = *expr_p;
 
@@ -5162,7 +5219,7 @@ gimplify_omp_atomic_fetch_op (tree *expr
    a subexpression, 0 if it did not, or -1 if an error was encountered.  */
 
 static int
-goa_stabilize_expr (tree *expr_p, tree *pre_p, tree lhs_addr, tree lhs_var)
+goa_stabilize_expr (tree *expr_p, gs_seq pre_p, tree lhs_addr, tree lhs_var)
 {
   tree expr = *expr_p;
   int saw_lhs;
@@ -5192,7 +5249,7 @@ goa_stabilize_expr (tree *expr_p, tree *
   if (saw_lhs == 0)
     {
       enum gimplify_status gs;
-      gs = gimplify_expr (expr_p, pre_p, NULL, is_gimple_val, fb_rvalue);
+      gs = gimplify_expr (expr_p, NULL, pre_p, NULL, is_gimple_val, fb_rvalue);
       if (gs != GS_ALL_DONE)
 	saw_lhs = -1;
     }
@@ -5213,7 +5270,7 @@ goa_stabilize_expr (tree *expr_p, tree *
    index of the builtin decl.  */
 
 static enum gimplify_status
-gimplify_omp_atomic_pipeline (tree *expr_p, tree *pre_p, tree addr,
+gimplify_omp_atomic_pipeline (tree *expr_p, gs_seq pre_p, tree addr,
 			      tree rhs, int index)
 {
   tree oldval, oldival, oldival2, newval, newival, label;
@@ -5317,7 +5374,7 @@ gimplify_omp_atomic_pipeline (tree *expr
    this situation as well.  */
 
 static enum gimplify_status
-gimplify_omp_atomic_mutex (tree *expr_p, tree *pre_p, tree addr, tree rhs)
+gimplify_omp_atomic_mutex (tree *expr_p, gs_seq pre_p, tree addr, tree rhs)
 {
   tree t;
 
@@ -5340,7 +5397,7 @@ gimplify_omp_atomic_mutex (tree *expr_p,
 /* Gimplify an OMP_ATOMIC statement.  */
 
 static enum gimplify_status
-gimplify_omp_atomic (tree *expr_p, tree *pre_p)
+gimplify_omp_atomic (tree *expr_p, gs_seq pre_p)
 {
   tree addr = TREE_OPERAND (*expr_p, 0);
   tree rhs = TREE_OPERAND (*expr_p, 1);
@@ -5391,7 +5448,7 @@ gimplify_omp_atomic (tree *expr_p, tree 
     Return 0 if gimplification failed.
 
     SEQ_P is the sequence where the gimplified expression tree will be
-    	expanded to.
+    	expanded to.  If SEQ_P is NULL, PRE_P is used instead.
 
     PRE_P is the sequence where side effects that must happen before EXPR
 	should be stored.
@@ -5424,6 +5481,7 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	       bool (* gimple_test_f) (tree), fallback_t fallback)
 {
   tree tmp;
+  struct gs_sequence internal_seq = GS_SEQ_INIT;
   struct gs_sequence internal_pre = GS_SEQ_INIT;
   struct gs_sequence internal_post = GS_SEQ_INIT;
   tree save_expr;
@@ -5441,10 +5499,22 @@ gimplify_expr (tree *expr_p, gs_seq seq_
      whether they are fully simplified.  */
 
   /* Set up our internal queues if needed.  */
+  if (seq_p == NULL)
+    {
+      gcc_assert (pre_p != NULL);
+      internal_seq = GS_SEQ_INIT;
+      seq_p = &internal_seq;
+    }
   if (pre_p == NULL)
-    pre_p = &internal_pre;
+    {
+      internal_pre = GS_SEQ_INIT;
+      pre_p = &internal_pre;
+    }
   if (post_p == NULL)
-    post_p = &internal_post;
+    {
+      internal_post = GS_SEQ_INIT;
+      post_p = &internal_post;
+    }
 
   saved_location = input_location;
   if (save_expr != error_mark_node
@@ -5493,7 +5563,7 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	case POSTDECREMENT_EXPR:
 	case PREINCREMENT_EXPR:
 	case PREDECREMENT_EXPR:
-	  ret = gimplify_self_mod_expr (expr_p, seq_p, pre_p, post_p,
+	  ret = gimplify_self_mod_expr (expr_p, pre_p, post_p,
 					fallback != fb_none);
 	  break;
 
@@ -5503,11 +5573,12 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	case IMAGPART_EXPR:
 	case COMPONENT_REF:
 	case VIEW_CONVERT_EXPR:
-	  ret = gimplify_compound_lval (expr_p, seq_p, pre_p, post_p,
+	  ret = gimplify_compound_lval (expr_p, pre_p, post_p,
 					fallback ? fallback : fb_rvalue);
 	  break;
 
 	case COND_EXPR:
+#if 0
 	  ret = gimplify_cond_expr (expr_p, seq_p, pre_p, fallback);
 	  /* C99 code may assign to an array in a structure value of a
 	     conditional expression, and this has undefined behavior
@@ -5518,10 +5589,12 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	      *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
 	      lang_hooks.mark_addressable (*expr_p);
 	    }
+#endif
+	  gcc_unreachable();
 	  break;
 
 	case CALL_EXPR:
-	  ret = gimplify_call_expr (expr_p, seq_p, pre_p, fallback != fb_none);
+	  ret = gimplify_call_expr (expr_p, pre_p, fallback != fb_none);
 	  /* C99 code may assign to an array in a structure returned
 	     from a function, and this has undefined behavior only on
 	     execution, so create a temporary if an lvalue is
@@ -5537,7 +5610,10 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	  gcc_unreachable ();
 
 	case COMPOUND_EXPR:
+#if 0
 	  ret = gimplify_compound_expr (expr_p, pre_p, fallback != fb_none);
+#endif
+	  gcc_unreachable();
 	  break;
 
 	case MODIFY_EXPR:
@@ -5545,19 +5621,6 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	case INIT_EXPR:
 	  ret = gimplify_modify_expr (expr_p, pre_p, post_p,
 				      fallback != fb_none);
-
-	  if (*expr_p)
-	    {
-	      /* The distinction between MODIFY_EXPR and INIT_EXPR is no longer
-		 useful.  */
-	      if (TREE_CODE (*expr_p) == INIT_EXPR)
-		TREE_SET_CODE (*expr_p, MODIFY_EXPR);
-
-	      /* Convert MODIFY_EXPR to GIMPLE_MODIFY_STMT.  */
-	      if (TREE_CODE (*expr_p) == MODIFY_EXPR)
-		tree_to_gimple_tuple (expr_p);
-	    }
-
 	  break;
 
 	case TRUTH_ANDIF_EXPR:
@@ -5645,7 +5708,7 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	  break;
 
 	case DECL_EXPR:
-	  ret = gimplify_decl_expr (expr_p);
+	  ret = gimplify_decl_expr (expr_p, seq_p);
 	  break;
 
 	case EXC_PTR_EXPR:
@@ -5688,7 +5751,7 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	  break;
 
 	case RETURN_EXPR:
-	  ret = gimplify_return_expr (*expr_p, seq_p, pre_p);
+	  ret = gimplify_return_expr (*expr_p, pre_p);
 	  break;
 
 	case CONSTRUCTOR:
@@ -5764,7 +5827,10 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	  break;
 
 	case CLEANUP_POINT_EXPR:
+	  gcc_unreachable();
+#if 0
 	  ret = gimplify_cleanup_point_expr (expr_p, pre_p);
+#endif
 	  break;
 
 	case TARGET_EXPR:
@@ -5801,7 +5867,10 @@ gimplify_expr (tree *expr_p, gs_seq seq_
 	  break;
 
 	case STATEMENT_LIST:
+#if 0
 	  ret = gimplify_statement_list (expr_p, pre_p);
+#endif
+	  gcc_unreachable();
 	  break;
 
 	case WITH_SIZE_EXPR:
@@ -6009,26 +6078,51 @@ gimplify_expr (tree *expr_p, gs_seq seq_
     }
 
   /* If we are gimplifying at the statement level, we're done.  Tack
-     everything together and replace the original statement with the
-     gimplified form.  */
+     everything together and be done.  */
   if (fallback == fb_none || is_statement)
     {
       if (!GS_SEQ_EMPTY_P (&internal_pre) || !GS_SEQ_EMPTY_P (&internal_post))
-	{
-	  append_to_statement_list (*expr_p, &internal_pre);
-	  append_to_statement_list (internal_post, &internal_pre);
-	  annotate_all_with_locus (&internal_pre, input_location);
-	  *expr_p = internal_pre;
-	}
-      else if (!*expr_p)
-	;
-      else if (TREE_CODE (*expr_p) == STATEMENT_LIST)
-	annotate_all_with_locus (expr_p, input_location);
-      else
-	annotate_one_with_locus (*expr_p, input_location);
+	gs_seq_append (&internal_post, &internal_pre);
+
+      /* EXPR_P should be a gimple statement, so the tree is meaningless;
+	 do nothing with it.  */
+
+      annotate_all_with_locus (&internal_pre, input_location);
       goto out;
     }
 
+#ifdef ENABLE_CHECKING
+  if (*expr_p)
+    {
+      enum tree_code code = TREE_CODE (*expr_p);
+      /* These expressions should already be in gimple IR form.  */
+      gcc_assert (code != MODIFY_EXPR
+	  	  && code != GIMPLE_MODIFY_STMT
+		  && code != ASM_EXPR
+		  && code != CALL_EXPR
+		  && code != BIND_EXPR
+		  && code != CATCH_EXPR
+		  && code != COND_EXPR
+		  && code != EH_FILTER_EXPR
+		  && code != GOTO_EXPR
+		  && code != LABEL_EXPR
+		  && code != PHI_NODE
+		  && code != RESX_EXPR
+		  && code != SWITCH_EXPR
+		  && code != TRY_FINALLY_EXPR
+		  && code != OMP_CONTINUE
+		  && code != OMP_CRITICAL
+		  && code != OMP_FOR
+		  && code != OMP_MASTER
+		  && code != OMP_ORDERED
+		  && code != OMP_PARALLEL
+		  && code != OMP_RETURN
+		  && code != OMP_SECTIONS
+		  && code != OMP_SECTION
+		  && code != OMP_SINGLE);
+    }
+#endif
+
   /* Otherwise we're gimplifying a subexpression, so the resulting value is
      interesting.  */
 
@@ -6098,10 +6192,24 @@ gimplify_expr (tree *expr_p, gs_seq seq_
   if (!GS_SEQ_EMPTY_P (&internal_post))
     {
       annotate_all_with_locus (&internal_post, input_location);
-      append_to_statement_list (internal_post, pre_p);
+      gs_seq_append (&internal_post, pre_p);
     }
 
  out:
+  /* FIXME tuples:
+
+     If we weren't given a pre_p, everything must go in seq_p.
+     If we weren't given a seq_p, everything must go in pre_p.
+
+     This is really stupid.  What we need is to always/only use pre_p,
+     but pre_p == NULL means is_statement.  We need to add another
+     flag passed to gimplify_expr ``bool is_statement'' to avoid this
+     ambiguity.  */
+  if (!GS_SEQ_EMPTY_P (&internal_seq))
+    gs_seq_append (&internal_seq, pre_p);
+  else if (!GS_SEQ_EMPTY_P (&internal_pre))
+    gs_seq_append (&internal_pre, seq_p);
+
   input_location = saved_location;
   return ret;
 }
@@ -6110,7 +6218,7 @@ gimplify_expr (tree *expr_p, gs_seq seq_
    size that we find.  Add to LIST_P any statements generated.  */
 
 void
-gimplify_type_sizes (tree type, tree *list_p)
+gimplify_type_sizes (tree type, gs_seq list_p)
 {
   tree field, t;
 
@@ -6195,7 +6303,7 @@ gimplify_type_sizes (tree type, tree *li
    We add any required statements to STMT_P.  */
 
 void
-gimplify_one_sizepos (tree *expr_p, tree *stmt_p)
+gimplify_one_sizepos (tree *expr_p, gs_seq stmt_p)
 {
   tree type, expr = *expr_p;
 
@@ -6212,7 +6320,7 @@ gimplify_one_sizepos (tree *expr_p, tree
   type = TREE_TYPE (expr);
   *expr_p = unshare_expr (expr);
 
-  gimplify_expr (expr_p, seq_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
+  gimplify_expr (expr_p, NULL, stmt_p, NULL, is_gimple_val, fb_rvalue);
   expr = *expr_p;
 
   /* Verify that we've an exact type match with the original expression.
@@ -6231,9 +6339,9 @@ gimplify_one_sizepos (tree *expr_p, tree
       tmp = build1 (NOP_EXPR, type, expr);
       tmp = build_gimple_modify_stmt (*expr_p, tmp);
       if (EXPR_HAS_LOCATION (expr))
-	SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
+        SET_EXPR_LOCUS (tmp, EXPR_LOCUS (expr));
       else
-	SET_EXPR_LOCATION (tmp, input_location);
+        SET_EXPR_LOCATION (tmp, input_location);
 
       gimplify_and_add (tmp, stmt_p);
     }
@@ -6275,6 +6383,7 @@ cpt_same_type (tree a, tree b)
    The type of a dereference should correspond to the pointer type;
    similarly the type of an address should match its object.  */
 
+#if 0
 static tree
 check_pointer_types_r (tree *tp, int *walk_subtrees ATTRIBUTE_UNUSED,
 		       void *data ATTRIBUTE_UNUSED)
@@ -6316,6 +6425,7 @@ check_pointer_types_r (tree *tp, int *wa
 
   return NULL_TREE;
 }
+#endif /* if 0 */
 #endif
 
 /* Gimplify the body of statements pointed to by BODY_P.  FNDECL is the
@@ -6325,7 +6435,8 @@ void
 gimplify_body (tree *body_p, gs_seq seq_p, tree fndecl, bool do_parms)
 {
   location_t saved_location = input_location;
-  tree body, parm_stmts;
+  //  tree body;
+  struct gs_sequence parm_stmts;
 
   timevar_push (TV_TREE_GIMPLIFY);
 
@@ -6344,10 +6455,11 @@ gimplify_body (tree *body_p, gs_seq seq_
 
   /* Resolve callee-copies.  This has to be done before processing
      the body so that DECL_VALUE_EXPR gets processed correctly.  */
-  parm_stmts = do_parms ? gimplify_parameters () : NULL;
+  parm_stmts = do_parms ? gimplify_parameters () : GS_SEQ_INIT;
 
   /* Gimplify the function's body.  */
-  gimplify_stmt (body_p);
+  gimplify_stmt (body_p, seq_p);
+#if 0
   body = *body_p;
 
   if (!body)
@@ -6388,6 +6500,7 @@ gimplify_body (tree *body_p, gs_seq seq_
 #ifdef ENABLE_CHECKING
   walk_tree (body_p, check_pointer_types_r, NULL, NULL);
 #endif
+#endif /* if 0 */
 
   timevar_pop (TV_TREE_GIMPLIFY);
   input_location = saved_location;
@@ -6427,6 +6540,8 @@ gimplify_function_tree (tree fndecl)
     DECL_GIMPLE_REG_P (ret) = 1;
 
   gimplify_body (&DECL_SAVED_TREE (fndecl), &seq, fndecl, true);
+  debug_gimple_seq (&seq);
+  exit (0);
 
   /* If we're instrumenting function entry/exit, then prepend the call to
      the entry hook and wrap the whole function in a TRY_FINALLY_EXPR to
@@ -6466,13 +6581,13 @@ gimplify_function_tree (tree fndecl)
    base variable of the final destination be VAR if suitable.  */
 
 tree
-force_gimple_operand (tree expr, tree *stmts, bool simple, tree var)
+force_gimple_operand (tree expr, gs_seq stmts, bool simple, tree var)
 {
   tree t;
   enum gimplify_status ret;
   gimple_predicate gimple_test_f;
 
-  *stmts = NULL_TREE;
+  *stmts = GS_SEQ_INIT;
 
   if (is_gimple_val (expr))
     return expr;
@@ -6485,8 +6600,7 @@ force_gimple_operand (tree expr, tree *s
   if (var)
     expr = build_gimple_modify_stmt (var, expr);
 
-  ret = gimplify_expr (&expr, stmts, NULL,
-		       gimple_test_f, fb_rvalue);
+  ret = gimplify_expr (&expr, NULL, stmts, NULL, gimple_test_f, fb_rvalue);
   gcc_assert (ret != GS_ERROR);
 
   if (gimple_referenced_vars (cfun))
@@ -6504,14 +6618,16 @@ force_gimple_operand (tree expr, tree *s
    some statements are produced, emits them before BSI.  */
 
 tree
-force_gimple_operand_bsi (block_stmt_iterator *bsi, tree expr,
+force_gimple_operand_bsi (block_stmt_iterator *bsi ATTRIBUTE_UNUSED, tree expr,
 			  bool simple_p, tree var)
 {
-  tree stmts;
+  struct gs_sequence stmts;
 
   expr = force_gimple_operand (expr, &stmts, simple_p, var);
+#if 0
   if (stmts)
     bsi_insert_before (bsi, stmts, BSI_SAME_STMT);
+#endif
 
   return expr;
 }
Index: coretypes.h
===================================================================
--- coretypes.h	(revision 124091)
+++ coretypes.h	(working copy)
@@ -49,6 +49,8 @@ union gimple_statement_d;
 typedef union gimple_statement_d *gimple;
 union section;
 typedef union section section;
+struct gs_sequence;
+typedef struct gs_sequence *gs_seq;
 
 /* The major intermediate representations of GCC.  */
 enum ir_type {
Index: tree-mudflap.c
===================================================================
--- tree-mudflap.c	(revision 124007)
+++ tree-mudflap.c	(working copy)
@@ -1025,8 +1025,10 @@ mx_register_decls (tree decl, tree *stmt
 
           /* Accumulate the two calls.  */
           /* ??? Set EXPR_LOCATION.  */
+#if 0
           gimplify_stmt (&register_fncall);
           gimplify_stmt (&unregister_fncall);
+#endif
 
           /* Add the __mf_register call at the current appending point.  */
           if (tsi_end_p (initially_stmts))
Index: tree-inline.c
===================================================================
--- tree-inline.c	(revision 124007)
+++ tree-inline.c	(working copy)
@@ -801,12 +801,14 @@ copy_bb (copy_body_data *id, basic_block
 
 	  gimple_duplicate_stmt_histograms (cfun, stmt, id->src_cfun, orig_stmt);
 
+#if 0
 	  /* With return slot optimization we can end up with
 	     non-gimple (foo *)&this->m, fix that here.  */
 	  if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
 	      && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == NOP_EXPR
 	      && !is_gimple_val (TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0)))
 	    gimplify_stmt (&stmt);
+#endif
 
           bsi_insert_after (&copy_bsi, stmt, BSI_NEW_STMT);
 
@@ -1419,7 +1421,9 @@ setup_one_parameter (copy_body_data *id,
           tree_stmt_iterator i;
 
 	  push_gimplify_context ();
+#if 0
 	  gimplify_stmt (&init_stmt);
+#endif
 	  if (gimple_in_ssa_p (cfun)
               && init_stmt && TREE_CODE (init_stmt) == STATEMENT_LIST)
 	    {
Index: c-gimplify.c
===================================================================
--- c-gimplify.c	(revision 124007)
+++ c-gimplify.c	(working copy)
@@ -179,7 +179,7 @@ c_build_bind_expr (tree block, tree body
    decl instead.  */
 
 static enum gimplify_status
-gimplify_compound_literal_expr (tree *expr_p, tree *pre_p)
+gimplify_compound_literal_expr (tree *expr_p, gs_seq pre_p)
 {
   tree decl_s = COMPOUND_LITERAL_EXPR_DECL_STMT (*expr_p);
   tree decl = DECL_EXPR_DECL (decl_s);
@@ -198,7 +198,8 @@ gimplify_compound_literal_expr (tree *ex
 /* Do C-specific gimplification.  Args are as for gimplify_expr.  */
 
 int
-c_gimplify_expr (tree *expr_p, tree *pre_p, tree *post_p ATTRIBUTE_UNUSED)
+c_gimplify_expr (tree *expr_p, gs_seq seq_p ATTRIBUTE_UNUSED, gs_seq pre_p,
+    		 gs_seq post_p ATTRIBUTE_UNUSED)
 {
   enum tree_code code = TREE_CODE (*expr_p);
 
Index: tree-flow.h
===================================================================
--- tree-flow.h	(revision 124007)
+++ tree-flow.h	(working copy)
@@ -1114,7 +1114,7 @@ extern bool thread_through_all_blocks (v
 extern void register_jump_thread (edge, edge);
 
 /* In gimplify.c  */
-tree force_gimple_operand (tree, tree *, bool, tree);
+tree force_gimple_operand (tree, gs_seq, bool, tree);
 tree force_gimple_operand_bsi (block_stmt_iterator *, tree, bool, tree);
 
 /* In tree-ssa-structalias.c */
Index: c-common.h
===================================================================
--- c-common.h	(revision 124007)
+++ c-common.h	(working copy)
@@ -888,7 +888,7 @@ extern void warn_for_div_by_zero (tree d
 
 /* In c-gimplify.c  */
 extern void c_genericize (tree);
-extern int c_gimplify_expr (tree *, tree *, tree *);
+extern int c_gimplify_expr (tree *, gs_seq, gs_seq, gs_seq);
 extern tree c_build_bind_expr (tree, tree);
 
 /* In c-pch.c  */
Index: tree-cfg.c
===================================================================
--- tree-cfg.c	(revision 124007)
+++ tree-cfg.c	(working copy)
@@ -501,6 +501,7 @@ make_edges (void)
 	      fallthru = true;
 	      break;
 
+#if 0
 	    case OMP_PARALLEL:
 	    case OMP_FOR:
 	    case OMP_SINGLE:
@@ -516,6 +517,7 @@ make_edges (void)
 	      cur_region = new_omp_region (bb, code, cur_region);
 	      fallthru = false;
 	      break;
+#endif
 
 	    case OMP_RETURN:
 	      /* In the case of an OMP_SECTION, the edge will go somewhere
@@ -569,8 +571,10 @@ make_edges (void)
 	make_edge (bb, bb->next_bb, EDGE_FALLTHRU);
     }
 
+#if 0
   if (root_omp_region)
     free_omp_regions ();
+#endif
 
   /* Fold COND_EXPR_COND of each COND_EXPR.  */
   fold_cond_expr_cond ();
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 124007)
+++ config/i386/i386.c	(working copy)
@@ -4674,7 +4674,7 @@ ix86_va_start (tree valist, rtx nextarg)
 /* Implement va_arg.  */
 
 static tree
-ix86_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
+ix86_gimplify_va_arg (tree valist, tree type, gs_seq pre_p, gs_seq post_p)
 {
   static const int intreg[6] = { 0, 1, 2, 3, 4, 5 };
   tree f_gpr, f_fpr, f_ovf, f_sav;
@@ -4878,7 +4878,7 @@ ix86_gimplify_va_arg (tree valist, tree 
       gimplify_and_add (t, pre_p);
 
       t = build1 (LABEL_EXPR, void_type_node, lab_false);
-      append_to_statement_list (t, pre_p);
+      gimplify_and_add (t, pre_p);
     }
 
   /* ... otherwise out of the overflow area.  */
@@ -4895,7 +4895,7 @@ ix86_gimplify_va_arg (tree valist, tree 
       t = build2 (BIT_AND_EXPR, TREE_TYPE (t), t,
 		  build_int_cst (TREE_TYPE (t), -align));
     }
-  gimplify_expr (&t, pre_p, NULL, is_gimple_val, fb_rvalue);
+  gimplify_expr (&t, NULL, pre_p, NULL, is_gimple_val, fb_rvalue);
 
   t2 = build2 (GIMPLE_MODIFY_STMT, void_type_node, addr, t);
   gimplify_and_add (t2, pre_p);



More information about the Gcc-patches mailing list