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]

[tuples] GS_BIND, GS_TRY, and minor API changes


Well, now that Diego's off watching soccer, I mean football, I'll take
this opportunity to cause merge conflicts on his tree for a change.

The major goal here is to generate GS_BIND correctly.  This in turn,
brought about GS_TRY changes, and an assortment of other changes.

I have added two new sequence manipulators, gs_push and gs_pop.  We use
these to keep a stack of GS_BIND's for our gimplifier contexts.  We
should be safe using GS_NEXT/GS_PREV to chain them together, since we
only use gimple_push_bind_expr() from within gimplify_bind_expr, and
I am making sure that we don't add the bind expr to the output sequence
until after we've popped the current binding.

[Not sure whether I'm abusing sequences as a stack, but it seemed
intuitive.  Should I use something else?]

Also new is gs_seq_copy(), a function to copy one sequence onto another.
I've adjusted everywhere in the builders where we were trying to do this
by setting the first/last items in a sequence.  Much cleaner this way.

This patch also makes the sequences in gs_omp_build* pointers, to maintain
consistency.

All gimple.exp tests pass.

Now let's see if I can come up with another set of intrusive changes
while the Argentinian/Brazil game is going on on Sunday. :-)

Aldy

	* testsuite/gcc.dg/gimple/with_size_expr.c: Check for GS_TRY.
	* Makefile.in (gimple-ir.o): Add diagnostic.h dependency.
	* gimple-pretty-print.c (dump_gs_call): Dump LHS if available.
	(dump_gs_try): New.
	(dump_gimple_stmt): Add case for GS_TRY.
	* gimple-ir.c.  Include diagnostic.h.
	(gs_build_try): Cleanup and eval are sequences.
	Remove catch_p and finally_p arguments.  Add catch_finally argument.
	(gs_omp_build_critical): Body is a gs_seq.
	(gs_omp_build_parallel): Same.
	(gs_omp_build_section): Same.
	(gs_omp_build_master): Same.
	(gs_omp_build_continue): Same.
	(gs_omp_build_ordered): Same.
	(gs_omp_build_sections): Same.
	(gs_omp_build_single): Same.
	(gs_omp_build_for): Body and pre_body is a gs_seq.
	(gs_push): New.
	(gs_pop): New.
	(walk_tuple_ops): Walk GS_TRY tuples eval and cleanups correctly.
	Dump tuple before we ICE.
	* gimple-ir.h (gs_seq_copy): New.
	(struct gimple_statement_try): Eval and cleanups are gs_seq's.
	(gs_bind_set_body): Use gs_seq_copy.
	(gs_try_eval): Return address of eval.
	(gs_try_cleanup): Return address of cleanup.
	(gs_try_set_eval): Use gs_seq_copy.
	(gs_try_set_cleanup): Same.
	(gs_omp_set_body): Same.
	(gs_omp_for_set_pre_body): Same.
	* gimplify.c (struct gimplify_ctx): Rename current_bind_expr to
	current_bind_expr_seq, and make it a sequence.
	(pop_gimplify_context): Adjust for current_bind_expr_seq.
	(gimple_push_bind_expr): Same.
	(gimple_pop_bind_expr): Same.
	(gimple_current_bind_expr): Same.
	(build_stack_save_restore): Generate tuples.
	(gimplify_bind_expr): Same.

Index: testsuite/gcc.dg/gimple/with_size_expr.c
===================================================================
--- testsuite/gcc.dg/gimple/with_size_expr.c	(revision 126641)
+++ testsuite/gcc.dg/gimple/with_size_expr.c	(working copy)
@@ -12,4 +12,6 @@ void f(int a) 
   d = c;
 }
 
+/* { dg-final { scan-tree-dump-times "gimpleir: GS_TRY tuple" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_stack_save" 1 "gimple" } } */
 /* { dg-final { cleanup-tree-dump "gimple" } } */
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c	(revision 126641)
+++ gimple-pretty-print.c	(working copy)
@@ -206,6 +206,13 @@ static void
 dump_gs_call (pretty_printer *buffer, gimple gs, int spc, int flags)
 {
   size_t i;
+  tree lhs = gs_call_lhs (gs);
+
+  if (lhs)
+    {
+      dump_generic_node (buffer, lhs, spc, flags, false);
+      pp_string (buffer, " = ");
+    }
 
   dump_generic_node (buffer, gs_call_fn (gs), spc, flags, false);
   pp_string (buffer, " (");
@@ -312,7 +319,7 @@ dump_gs_label (pretty_printer *buffer, g
 
 /* Dump a GS_BIND tuple on the pretty_printer BUFFER, SPC
    spaces of indent.  FLAGS specifies details to show in the dump (see
-   TDF_* in tree.h)  */
+   TDF_* in tree.h).  */
 
 static void
 dump_gs_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -342,6 +349,32 @@ dump_gs_bind (pretty_printer *buffer, gi
 }
 
 
+/* Dump a GS_TRY tuple on the pretty_printer BUFFER, SPC spaces of
+   indent.  FLAGS specifies details to show in the dump (see TDF_* in
+   tree.h).  */
+
+static void
+dump_gs_try (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  if (flags & TDF_DETAILS)
+    pp_string (buffer, "GS_TRY tuple");
+
+  newline_and_indent (buffer, spc);
+  pp_string (buffer, "try {");
+  newline_and_indent (buffer, spc + 2);
+  dump_gimple_seq (buffer, gs_try_eval (gs), spc + 2, flags);
+  newline_and_indent (buffer, spc);
+  if (GS_SUBCODE_FLAGS (gs) == GS_TRY_CATCH)
+    pp_string (buffer, "} catch {");
+  else
+    pp_string (buffer, "} finally {");
+  newline_and_indent (buffer, spc + 2);
+  dump_gimple_seq (buffer, gs_try_cleanup (gs), spc + 2, flags);
+  newline_and_indent (buffer, spc);
+  pp_character (buffer, '}');
+}
+
+
 /* 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).  */
@@ -391,6 +424,10 @@ dump_gimple_stmt (pretty_printer *buffer
       dump_gs_switch (buffer, gs, spc, flags);
       break;
 
+    case GS_TRY:
+      dump_gs_try (buffer, gs, spc, flags);
+      break;
+
     default:
       GS_NIY;
     }
Index: gimple-ir.c
===================================================================
--- gimple-ir.c	(revision 126641)
+++ gimple-ir.c	(working copy)
@@ -28,6 +28,7 @@ Software Foundation, 51 Franklin Street,
 #include "errors.h"
 #include "tree-gimple.h"
 #include "gimple-ir.h"
+#include "diagnostic.h"
 
 #define DEFGSCODE(SYM, NAME)	NAME,
 const char *const gs_code_name[] = {
@@ -363,22 +364,21 @@ gs_build_eh_filter (tree types, gimple f
 
    EVAL is the expression to evaluate.
    CLEANUP is the cleanup expression.
-   CATCH_P is true if this is a try/catch
-   FINALLY_P is true if this is a try/finally.  */
+   CATCH_FINALLY is either GS_TRY_CATCH or GS_TRY_FINALLY depending on whether
+   this is a try/catch or a try/finally respectively.  */
 
 gimple
-gs_build_try (gimple eval, gimple cleanup, bool catch_p, bool finally_p)
+gs_build_try (gs_seq eval, gs_seq cleanup, unsigned int catch_finally)
 {
   gimple p;
 
+  gcc_assert (catch_finally == GS_TRY_CATCH
+	      || catch_finally == GS_TRY_FINALLY);
   p = ggc_alloc_cleared (sizeof (struct gimple_statement_try));
   GS_CODE (p) = GS_TRY;
   gs_try_set_eval (p, eval);
   gs_try_set_cleanup (p, cleanup);
-  if (catch_p)
-    GS_SUBCODE_FLAGS (p) |= GS_TRY_CATCH;
-  if (finally_p)
-    GS_SUBCODE_FLAGS (p) |= GS_TRY_FINALLY;
+  GS_SUBCODE_FLAGS (p) = catch_finally;
 
   return p;
 }
@@ -504,7 +504,7 @@ gs_build_switch_vec (tree index, tree de
    NAME is optional identifier for this critical block.  */
 
 gimple 
-gs_omp_build_critical (struct gs_sequence body, tree name)
+gs_omp_build_critical (gs_seq body, tree name)
 {
   gimple p;
 
@@ -528,11 +528,10 @@ gs_omp_build_critical (struct gs_sequenc
    OMP_FOR_COND  the predicate used to compare INDEX and FINAL.
    INCR is the increment expression.  */
 
-gimple 
-gs_omp_build_for (struct gs_sequence body, tree clauses, tree index, 
+gimple
+gs_omp_build_for (gs_seq body, tree clauses, tree index, 
                   tree initial, tree final, tree incr, 
-                  struct gs_sequence pre_body, 
-                  enum gs_cond omp_for_cond)
+                  gs_seq pre_body, enum gs_cond omp_for_cond)
 {
   gimple p;
 
@@ -558,7 +557,7 @@ gs_omp_build_for (struct gs_sequence bod
    DATA_ARG are the shared data argument(s).  */
 
 gimple 
-gs_omp_build_parallel (struct gs_sequence body, tree clauses, tree child_fn, 
+gs_omp_build_parallel (gs_seq body, tree clauses, tree child_fn, 
                        tree data_arg)
 {
   gimple p;
@@ -577,8 +576,8 @@ gs_omp_build_parallel (struct gs_sequenc
 
    BODY is the sequence of statements in the section.  */
 
-gimple 
-gs_omp_build_section (struct gs_sequence body)
+gimple
+gs_omp_build_section (gs_seq body)
 {
   gimple p;
 
@@ -593,7 +592,7 @@ gs_omp_build_section (struct gs_sequence
    BODY is the sequence of statements to be executed by just the master.  */
 
 gimple 
-gs_omp_build_master (struct gs_sequence body)
+gs_omp_build_master (gs_seq body)
 {
   gimple p;
 
@@ -607,7 +606,7 @@ gs_omp_build_master (struct gs_sequence 
    FIXME tuples: BODY.  */
 
 gimple 
-gs_omp_build_continue (struct gs_sequence body)
+gs_omp_build_continue (gs_seq body)
 {
   gimple p;
 
@@ -624,7 +623,7 @@ gs_omp_build_continue (struct gs_sequenc
    sequence.  */
 
 gimple 
-gs_omp_build_ordered (struct gs_sequence body)
+gs_omp_build_ordered (gs_seq body)
 {
   gimple p;
 
@@ -658,7 +657,7 @@ gs_omp_build_return (bool wait_p)
    firstprivate, lastprivate, reduction, and nowait.  */
 
 gimple 
-gs_omp_build_sections (struct gs_sequence body, tree clauses)
+gs_omp_build_sections (gs_seq body, tree clauses)
 {
   gimple p;
 
@@ -677,7 +676,7 @@ gs_omp_build_sections (struct gs_sequenc
    copyprivate, nowait.  */
 
 gimple 
-gs_omp_build_single (struct gs_sequence body, tree clauses)
+gs_omp_build_single (gs_seq body, tree clauses)
 {
   gimple p;
 
@@ -749,6 +748,39 @@ gs_check_failed (const gimple gs, const 
 }
 #endif /* ENABLE_TREE_CHECKING */
 
+
+/* Push gimple statement GS into the front of sequence SEQ.  */
+
+void
+gs_push (gimple gs, gs_seq seq)
+{
+  gimple oldfirst = gs_seq_first (seq);
+
+  GS_NEXT (gs) = oldfirst;
+  if (oldfirst)
+    GS_PREV (oldfirst) = gs;
+  gs_seq_set_first (seq, gs);
+}
+
+
+/* Remove the first gimple statement from sequence SEQ and return it.  */
+
+gimple
+gs_pop (gs_seq seq)
+{
+  gimple first = gs_seq_first (seq);
+  gimple new_first;
+
+  gs_seq_set_first (seq, GS_NEXT (first));
+  new_first = gs_seq_first (seq);
+  if (new_first)
+    GS_PREV (new_first) = NULL;
+  if (first)
+    GS_NEXT (first) = NULL;
+  return first;
+}
+
+
 /* Link a gimple statement(s) to the end of the sequence SEQ.  */
 
 void
@@ -881,8 +913,8 @@ walk_tuple_ops (gimple gs, walk_tree_fn 
       break;
 
     case GS_TRY:
-      walk_tuple_ops (gs_try_eval (gs), func, data, pset);
-      walk_tuple_ops (gs_try_cleanup (gs), func, data, pset);
+      walk_seq_ops (gs_try_eval (gs), func, data, pset);
+      walk_seq_ops (gs_try_cleanup (gs), func, data, pset);
       break;
 
     case GS_OMP_CRITICAL:
@@ -932,6 +964,7 @@ walk_tuple_ops (gimple gs, walk_tree_fn 
       break;
 
     default:
+      debug_gimple_stmt (gs);
       gcc_unreachable ();
       break;
     }
Index: gimple-ir.h
===================================================================
--- gimple-ir.h	(revision 126641)
+++ gimple-ir.h	(working copy)
@@ -78,6 +78,15 @@ gs_seq_init (gs_seq s)
   s->last = NULL;
 }
 
+/* Copy the sequence SRC into the sequence DEST.  */
+
+static inline void
+gs_seq_copy (gs_seq dest, gs_seq src)
+{
+  gs_seq_set_first (dest, gs_seq_first (src));
+  gs_seq_set_last (dest, gs_seq_last (src));
+}
+
 static inline bool
 gs_seq_empty_p (gs_seq s)
 {
@@ -177,9 +186,9 @@ struct gimple_statement_try GTY(())
 {
   struct gimple_statement_base base;
   /* Expression to evaluate.  */
-  gimple eval;
+  struct gs_sequence eval;
   /* Cleanup expression.  */
-  gimple cleanup;
+  struct gs_sequence cleanup;
 };
 
 /* Flags stored in GS_TRY's subcode flags.  */
@@ -382,24 +391,26 @@ extern gimple gs_build_bind (tree, gs_se
 extern gimple gs_build_asm (const char *, unsigned, unsigned, unsigned, ...);
 extern gimple gs_build_catch (tree, gimple);
 extern gimple gs_build_eh_filter (tree, gimple);
-extern gimple gs_build_try (gimple, gimple, bool, bool);
+extern gimple gs_build_try (gs_seq, gs_seq, unsigned int);
 extern gimple gs_build_phi (unsigned, unsigned, tree, ...);
 extern gimple gs_build_resx (int);
 extern gimple gs_build_switch (unsigned int, tree, tree, ...);
 extern gimple gs_build_switch_vec (tree, tree, VEC(tree,heap) *);
-extern gimple gs_omp_build_parallel (struct gs_sequence, tree, tree, tree);
-extern gimple gs_omp_build_for (struct gs_sequence, tree, tree, tree, tree,
-    				tree, struct gs_sequence, enum gs_cond);
-extern gimple gs_omp_build_critical (struct gs_sequence, tree);
-extern gimple gs_omp_build_section (struct gs_sequence);
-extern gimple gs_omp_build_continue (struct gs_sequence);
-extern gimple gs_omp_build_master (struct gs_sequence);
+extern gimple gs_omp_build_parallel (gs_seq, tree, tree, tree);
+extern gimple gs_omp_build_for (gs_seq, tree, tree, tree, tree, tree, gs_seq,
+				enum gs_cond);
+extern gimple gs_omp_build_critical (gs_seq, tree);
+extern gimple gs_omp_build_section (gs_seq);
+extern gimple gs_omp_build_continue (gs_seq);
+extern gimple gs_omp_build_master (gs_seq);
 extern gimple gs_omp_build_return (bool);
-extern gimple gs_omp_build_ordered (struct gs_sequence);
-extern gimple gs_omp_build_sections (struct gs_sequence, tree);
-extern gimple gs_omp_build_single (struct gs_sequence, tree);
+extern gimple gs_omp_build_ordered (gs_seq);
+extern gimple gs_omp_build_sections (gs_seq, tree);
+extern gimple gs_omp_build_single (gs_seq, tree);
 extern enum gimple_statement_structure_enum gimple_statement_structure (gimple);
 extern void gs_add (gs_seq, gimple);
+extern void gs_push (gimple, gs_seq);
+extern gimple gs_pop (gs_seq);
 extern enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
 extern void sort_case_labels (VEC(tree,heap) *);
 extern void walk_tuple_ops (gimple, walk_tree_fn, void *,
@@ -747,11 +758,10 @@ gs_bind_body (gimple gs) {
 }
 
 static inline void
-gs_bind_set_body (gimple gs, gs_seq gss)
+gs_bind_set_body (gimple gs, gs_seq seq)
 {
   GS_CHECK (gs, GS_BIND);
-  gs_seq_set_first (&(gs->gs_bind.body), gs_seq_first (gss)); 
-  gs_seq_set_last (&(gs->gs_bind.body), gs_seq_last (gss)); 
+  gs_seq_copy (&(gs->gs_bind.body), seq);
 }
 
 /* GS_ASM accessors. */
@@ -922,32 +932,32 @@ gs_eh_filter_set_failure (gimple gs, gim
 
 /* GS_TRY accessors. */
 
-static inline gimple
+static inline gs_seq
 gs_try_eval (gimple gs)
 {
   GS_CHECK (gs, GS_TRY);
-  return gs->gs_try.eval;
+  return &gs->gs_try.eval;
 }
 
-static inline gimple
+static inline gs_seq
 gs_try_cleanup (gimple gs)
 {
   GS_CHECK (gs, GS_TRY);
-  return gs->gs_try.cleanup;
+  return &gs->gs_try.cleanup;
 }
 
 static inline void
-gs_try_set_eval (gimple gs, gimple eval)
+gs_try_set_eval (gimple gs, gs_seq eval)
 {
   GS_CHECK (gs, GS_TRY);
-  gs->gs_try.eval = eval;
+  gs_seq_copy (gs_try_eval (gs), eval);
 }
 
 static inline void
-gs_try_set_cleanup (gimple gs, gimple cleanup)
+gs_try_set_cleanup (gimple gs, gs_seq cleanup)
 {
-    GS_CHECK (gs, GS_TRY);
-    gs->gs_try.cleanup = cleanup;
+  GS_CHECK (gs, GS_TRY);
+  gs_seq_copy (gs_try_cleanup (gs), cleanup);
 }
 
 /* GS_PHI accessors. */
@@ -1100,10 +1110,9 @@ gs_omp_body (gimple gs)
 }
 
 static inline void
-gs_omp_set_body (gimple gs, struct gs_sequence body)
+gs_omp_set_body (gimple gs, gs_seq body)
 {
-  gs_seq_set_first (&(gs->omp.body), gs_seq_first (&body));
-  gs_seq_set_last (&(gs->omp.body), gs_seq_last (&body));
+  gs_seq_copy (&(gs->omp.body), body);
 }
 
 /* GS_OMP_CRITICAL accessors. */
@@ -1202,11 +1211,10 @@ gs_omp_for_pre_body (gimple gs)
 }
 
 static inline void
-gs_omp_for_set_pre_body (gimple gs, struct gs_sequence pre_body)
+gs_omp_for_set_pre_body (gimple gs, gs_seq pre_body)
 {
   GS_CHECK (gs, GS_OMP_FOR);
-  gs_seq_set_first (&(gs->gs_omp_for.pre_body),  gs_seq_first (&pre_body));
-  gs_seq_set_last (&(gs->gs_omp_for.pre_body),  gs_seq_last (&pre_body));
+  gs_seq_copy (&(gs->gs_omp_for.pre_body),  pre_body);
 }
 
 /* GS_OMP_PARALLEL accessors. */
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 126641)
+++ gimplify.c	(working copy)
@@ -85,7 +85,7 @@ struct gimplify_ctx
 {
   struct gimplify_ctx *prev_context;
 
-  gimple current_bind_expr;
+  struct gs_sequence current_bind_expr_seq;
   tree temps;
   struct gs_sequence conditional_cleanups;
   tree exit_label;
@@ -177,7 +177,7 @@ pop_gimplify_context (gimple body)
   struct gimplify_ctx *c = gimplify_ctxp;
   tree t;
 
-  gcc_assert (c && !c->current_bind_expr);
+  gcc_assert (c && gs_seq_empty_p (&c->current_bind_expr_seq));
   gimplify_ctxp = c->prev_context;
 
   for (t = c->temps; t ; t = TREE_CHAIN (t))
@@ -198,23 +198,21 @@ pop_gimplify_context (gimple body)
 }
 
 static void
-gimple_push_bind_expr (tree bind)
+gimple_push_bind_expr (gimple gs_bind)
 {
-  TREE_CHAIN (bind) = gimplify_ctxp->current_bind_expr;
-  gimplify_ctxp->current_bind_expr = bind;
+  gs_push (gs_bind, &gimplify_ctxp->current_bind_expr_seq);
 }
 
 static void
 gimple_pop_bind_expr (void)
 {
-  gimplify_ctxp->current_bind_expr
-    = TREE_CHAIN (gimplify_ctxp->current_bind_expr);
+  gs_pop (&gimplify_ctxp->current_bind_expr_seq);
 }
 
 gimple
 gimple_current_bind_expr (void)
 {
-  return gimplify_ctxp->current_bind_expr;
+  return gs_seq_first (&gimplify_ctxp->current_bind_expr_seq);
 }
 
 /* Returns true iff there is a COND_EXPR between us and the innermost
@@ -990,18 +988,16 @@ voidify_wrapper_expr (tree wrapper, tree
    a temporary through which they communicate.  */
 
 static void
-build_stack_save_restore (tree *save, tree *restore)
+build_stack_save_restore (gimple *save, gimple *restore)
 {
-  tree save_call, tmp_var;
+  tree tmp_var;
 
-  save_call =
-    build_call_expr (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
+  *save = gs_build_call (implicit_built_in_decls[BUILT_IN_STACK_SAVE], 0);
   tmp_var = create_tmp_var (ptr_type_node, "saved_stack");
+  gs_call_set_lhs (*save, tmp_var);
 
-  *save = build_gimple_modify_stmt (tmp_var, save_call);
-  *restore =
-    build_call_expr (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
-		     1, tmp_var);
+  *restore = gs_build_call (implicit_built_in_decls[BUILT_IN_STACK_RESTORE],
+			    1, tmp_var);
 }
 
 /* Gimplify a BIND_EXPR.  Just voidify and recurse.  */
@@ -1012,6 +1008,10 @@ gimplify_bind_expr (tree *expr_p, gs_seq
   tree bind_expr = *expr_p;
   bool old_save_stack = gimplify_ctxp->save_stack;
   tree t;
+  gimple gs_bind;
+  struct gs_sequence empty_seq;
+
+  gs_seq_init (&empty_seq);
 
   tree temp = voidify_wrapper_expr (bind_expr, NULL);
 
@@ -1043,36 +1043,48 @@ gimplify_bind_expr (tree *expr_p, gs_seq
 	DECL_GIMPLE_REG_P (t) = 1;
     }
 
-  gimple_push_bind_expr (bind_expr);
+  gs_bind = gs_build_bind (BIND_EXPR_VARS (bind_expr), &empty_seq);
+  gimple_push_bind_expr (gs_bind);
+
   gimplify_ctxp->save_stack = false;
 
-  gimplify_stmt (&BIND_EXPR_BODY (bind_expr), pre_p);
+  /* Gimplify the body into the GS_BIND tuple's body.  */
+  gimplify_stmt (&BIND_EXPR_BODY (bind_expr), gs_bind_body (gs_bind));
 
   if (gimplify_ctxp->save_stack)
     {
-      tree stack_save, stack_restore;
+      gimple stack_save, stack_restore, gs;
+      struct gs_sequence restore_seq;
 
       /* Save stack on entry and restore it on exit.  Add a try_finally
 	 block to achieve this.  Note that mudflap depends on the
 	 format of the emitted code: see mx_register_decls().  */
       build_stack_save_restore (&stack_save, &stack_restore);
 
-      t = build2 (TRY_FINALLY_EXPR, void_type_node,
-		  BIND_EXPR_BODY (bind_expr), NULL_TREE);
-      append_to_statement_list (stack_restore, &TREE_OPERAND (t, 1));
-
-      BIND_EXPR_BODY (bind_expr) = NULL_TREE;
-      append_to_statement_list (stack_save, &BIND_EXPR_BODY (bind_expr));
-      append_to_statement_list (t, &BIND_EXPR_BODY (bind_expr));
+      /* FIXME tuples: Creating a one item sequence is really
+	 retarded.  If this happens more often in the gimplifier we
+	 should create a helper function for this.  */
+      gs_seq_init (&restore_seq);
+      gs_add (&restore_seq, stack_restore);
+
+      gs = gs_build_try (gs_bind_body (gs_bind), &restore_seq, GS_TRY_FINALLY);
+
+      gs_bind_set_body (gs_bind, &empty_seq);
+      gs_add (gs_bind_body (gs_bind), stack_save);
+      gs_add (gs_bind_body (gs_bind), gs);
     }
 
   gimplify_ctxp->save_stack = old_save_stack;
+
+  /* Make sure we add the gs_bind into the queue after we pop the
+     current bind_expr, else we risk corrupting the current_bind_expr_seq
+     stack.  */
   gimple_pop_bind_expr ();
+  gs_add (pre_p, gs_bind);
 
   if (temp)
     {
       *expr_p = temp;
-      gimplify_and_add (bind_expr, pre_p);
       return GS_OK;
     }
   else
@@ -5009,7 +5021,7 @@ gimplify_omp_parallel (tree *expr_p, gs_
   if (TREE_CODE (OMP_PARALLEL_BODY (expr)) == BIND_EXPR)
     pop_gimplify_context (OMP_PARALLEL_BODY (expr));
   else
-    pop_gimplify_context (NULL_TREE);
+    pop_gimplify_context (NULL);
 
   gimplify_adjust_omp_clauses (&OMP_PARALLEL_CLAUSES (expr));
 
@@ -6564,8 +6576,7 @@ gimplify_body (tree *body_p, gs_seq seq_
   if (GS_CODE (outer_bind) != GS_BIND)
     {
       outer_bind = gs_build_bind (NULL_TREE, seq_p);
-      gs_seq_set_first (seq_p, outer_bind);
-      gs_seq_set_last (seq_p, outer_bind);
+      gs_add (seq_p, outer_bind);
     }
 
   *body_p = NULL_TREE;
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 126641)
+++ Makefile.in	(working copy)
@@ -2208,7 +2208,7 @@ tree-gimple.o : tree-gimple.c $(CONFIG_H
    $(RTL_H) $(TREE_GIMPLE_H) $(TM_H) coretypes.h bitmap.h $(GGC_H) \
    output.h $(TREE_FLOW_H)
 gimple-ir.o : gimple-ir.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
-   $(GGC_H) $(TREE_GIMPLE_H) $(GIMPLE_IR_H)
+   $(GGC_H) $(TREE_GIMPLE_H) $(GIMPLE_IR_H) $(DIAGNOSTIC_H)
 gimple-pretty-print.o : gimple-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(DIAGNOSTIC_H) $(REAL_H) $(HASHTAB_H) $(TREE_FLOW_H) \
    $(TM_H) coretypes.h gimple-iterator.h tree-pass.h gimple-ir.h


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]