This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [tuples] gimplifying MODIFY_EXPR and RETURN_EXPR


On Thu, May 03, 2007 at 06:40:51PM -0400, Aldy Hernandez wrote:
> 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.

Hi folks.

I've separated things out, and committed the easier parts of the patch,
so y'all can look at the design things that really need reviewing.

Here is patch with the things you need to look at.  Everything else is on
the branch.

No where was my pi~na colada?
Aldy
 
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 Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]