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] C++: WITH_CLEANUP_EXPR infrastructure


Howdy folks!

The first step in dealing with C++ is properly gimplifying
CLEANUP_POINT_EXPRs.  This is turn brings the WITH_CLEANUP_EXPR markers.

The following patch adds a new tuples, GIMPLE_WITH_CLEANUP_EXPR, and
associated machinery.  As the non-tuple counterpart, it's merely a
placeholder while we gimplify CLEANUP_POINT_EXPRs, and should not exist
outside of the gimplifier.  Consequently I see no reason to document it
in the design document, though I have documented it in the code.

I could have hijacked GIMPLE_TRY for this purpose, adding yet more flags
to it, but if I've learned anything from this conversion it's that...
"hijacking bad" ... "clean interfaces good".  I'm not entirely convinced
using these placeholders is the best way of gimplifying
CLEANUP_POINT_EXPRs, but there's just so much rewriting and rehasing one
can do.  Perhaps the current approach should be revised, as the FIXME at
the top of gimplify_cleanup_point_expr hints at.  Right now the goal is
to get a new IR while rewriting the least amount of code :).

Oh yeah, there is also a new iterator function, gsi_delink.  I'll be
using that when I commit the gimplifier portion of this series.

Aldy

	* gimple.def: Add GIMPLE_WITH_CLEANUP_EXPR.
	* gsstruct.def: Add GSS_WCE.
	* gimple-iterator.c (gsi_delink): New.
	(gsi_split_seq_*): Update comment.
	* gimple.c (gss_for_code): Handle GIMPLE_WCE.  Adjust whitespace.
	(build_gimple_wce): New.
	* gimple.h (struct gimple_statement_wce): New.
	(union gimple_statement_d): Add gimple_wce.
	(build_gimple_wce): Protoize.
	(gimple_wce_cleanup): New.
	(gimple_wce_set_cleanup): New.
	(gimple_wce_cleanup_eh_only): New.
	(gimple_wce_set_cleanup_eh_only): New.
	(gsi_delink): Protoize.

Index: gimple.def
===================================================================
--- gimple.def	(revision 129237)
+++ gimple.def	(working copy)
@@ -53,6 +53,14 @@ DEFGSCODE(GIMPLE_EH_FILTER, "gimple_eh_f
 DEFGSCODE(GIMPLE_PHI, "gimple_phi")
 DEFGSCODE(GIMPLE_RESX, "gimple_resx")
 DEFGSCODE(GIMPLE_TRY, "gimple_try")
+
+/*  This node represents a cleanup expression.  It is ONLY USED INTERNALLY
+    by the gimplifier as a placeholder for cleanups, and its uses will be
+    cleaned up by the time gimplification is done.
+    
+    This tuples should not exist outside of the gimplifier proper.  */
+DEFGSCODE(GIMPLE_WITH_CLEANUP_EXPR, "gimple_with_cleanup_expr")
+
 DEFGSCODE(GIMPLE_NOP, "gimple_nop")
 DEFGSCODE(GIMPLE_OMP_CONTINUE, "gimple_omp_continue")
 DEFGSCODE(GIMPLE_OMP_CRITICAL, "gimple_omp_critical")
Index: gsstruct.def
===================================================================
--- gsstruct.def	(revision 129237)
+++ gsstruct.def	(working copy)
@@ -36,6 +36,7 @@ DEFGSSTRUCT(GSS_EH_FILTER, "eh_filter")
 DEFGSSTRUCT(GSS_PHI, "phi")
 DEFGSSTRUCT(GSS_RESX, "resx")
 DEFGSSTRUCT(GSS_TRY, "try")
+DEFGSSTRUCT(GSS_WCE, "with_cleanup_expression")
 DEFGSSTRUCT(GSS_ASM, "asm")
 DEFGSSTRUCT(GSS_OMP_CRITICAL, "omp_critical")
 DEFGSSTRUCT(GSS_OMP_FOR, "omp_for")
Index: gimple-iterator.c
===================================================================
--- gimple-iterator.c	(revision 129237)
+++ gimple-iterator.c	(working copy)
@@ -177,8 +177,32 @@ gsi_link_after (gimple_stmt_iterator *i,
 }
 
 
-/* Move all statements in the sequence after I to a new sequence.  I
-   itself is unchanged.  */
+/* Remove a stmt from the sequence.  The iterator is updated to point to the
+   next stmt.  */
+
+void
+gsi_delink (gimple_stmt_iterator *i)
+{
+  gimple cur, next, prev;
+
+  cur = i->stmt;
+  next = gimple_next (cur);
+  prev = gimple_prev (cur);
+
+  if (prev)
+    set_gimple_next (prev, next);
+  else
+    gimple_seq_set_first (i->seq, next);
+  if (next)
+    set_gimple_prev (next, prev);
+  else
+    gimple_seq_set_last (i->seq, prev);
+
+  i->stmt = next;
+}
+
+/* Move all statements in the sequence after I to a new sequence.  Return this
+   new sequence.  I itself is unchanged.  */
 
 gimple_seq
 gsi_split_seq_after (const gimple_stmt_iterator *i)
@@ -204,8 +228,8 @@ gsi_split_seq_after (const gimple_stmt_i
 }
 
 
-/* Move all statements in the sequence before I to a new sequence.  I
-   is set to the head of the new list.  */
+/* Move all statements in the sequence before I to a new sequence.  Return this
+   new sequence.  I is set to the head of the new list.  */
 
 gimple_seq
 gsi_split_seq_before (gimple_stmt_iterator *i)
Index: gimple.c
===================================================================
--- gimple.c	(revision 129237)
+++ gimple.c	(working copy)
@@ -69,30 +69,31 @@ gss_for_code (enum gimple_code code)
     {
     case GIMPLE_ASSIGN:
     case GIMPLE_CALL:
-    case GIMPLE_RETURN:		return GSS_WITH_MEM_OPS;
+    case GIMPLE_RETURN:			return GSS_WITH_MEM_OPS;
     case GIMPLE_COND:
     case GIMPLE_GOTO:
     case GIMPLE_LABEL:
-    case GIMPLE_SWITCH:		return GSS_WITH_OPS;
-    case GIMPLE_ASM:		return GSS_ASM;
-    case GIMPLE_BIND:		return GSS_BIND;
-    case GIMPLE_CATCH:		return GSS_CATCH;
-    case GIMPLE_EH_FILTER:	return GSS_EH_FILTER;
-    case GIMPLE_NOP:		return GSS_BASE;
-    case GIMPLE_PHI:		return GSS_PHI;
-    case GIMPLE_RESX:		return GSS_RESX;
-    case GIMPLE_TRY:		return GSS_TRY;
-    case GIMPLE_OMP_CRITICAL:	return GSS_OMP_CRITICAL;
-    case GIMPLE_OMP_FOR:	return GSS_OMP_FOR;
+    case GIMPLE_SWITCH:			return GSS_WITH_OPS;
+    case GIMPLE_ASM:			return GSS_ASM;
+    case GIMPLE_BIND:			return GSS_BIND;
+    case GIMPLE_CATCH:			return GSS_CATCH;
+    case GIMPLE_EH_FILTER:		return GSS_EH_FILTER;
+    case GIMPLE_NOP:			return GSS_BASE;
+    case GIMPLE_PHI:			return GSS_PHI;
+    case GIMPLE_RESX:			return GSS_RESX;
+    case GIMPLE_TRY:			return GSS_TRY;
+    case GIMPLE_WITH_CLEANUP_EXPR:	return GSS_WCE;
+    case GIMPLE_OMP_CRITICAL:		return GSS_OMP_CRITICAL;
+    case GIMPLE_OMP_FOR:		return GSS_OMP_FOR;
     case GIMPLE_OMP_CONTINUE:
     case GIMPLE_OMP_MASTER:		
     case GIMPLE_OMP_ORDERED:
     case GIMPLE_OMP_RETURN:
-    case GIMPLE_OMP_SECTION:	return GSS_OMP;
-    case GIMPLE_OMP_PARALLEL:	return GSS_OMP_PARALLEL;
-    case GIMPLE_OMP_SECTIONS:	return GSS_OMP_SECTIONS;
-    case GIMPLE_OMP_SINGLE:	return GSS_OMP_SINGLE;
-    default:			gcc_unreachable ();
+    case GIMPLE_OMP_SECTION:		return GSS_OMP;
+    case GIMPLE_OMP_PARALLEL:		return GSS_OMP_PARALLEL;
+    case GIMPLE_OMP_SECTIONS:		return GSS_OMP_SECTIONS;
+    case GIMPLE_OMP_SINGLE:		return GSS_OMP_SINGLE;
+    default:				gcc_unreachable ();
     }
 }
 
@@ -453,6 +454,23 @@ build_gimple_try (gimple_seq eval, gimpl
   return p;
 }
 
+/* Construct a GIMPLE_WITH_CLEANUP_EXPR statement.
+
+   CLEANUP is the cleanup expression.  */
+
+gimple
+build_gimple_wce (gimple_seq cleanup)
+{
+  gimple p;
+
+  p = ggc_alloc_cleared (sizeof (struct gimple_statement_wce));
+  set_gimple_code (p, GIMPLE_WITH_CLEANUP_EXPR);
+  if (cleanup)
+    gimple_wce_set_cleanup (p, cleanup);
+
+  return p;
+}
+
 /* Construct a GIMPLE_PHI statement.
 
    CAPACITY is the max number of args this node can have (for later reuse).
Index: gimple.h
===================================================================
--- gimple.h	(revision 129273)
+++ gimple.h	(working copy)
@@ -239,6 +239,20 @@ enum gimple_try_kind {
   GIMPLE_TRY_FINALLY = 2
 };
 
+/* GIMPLE_WITH_CLEANUP_EXPR */
+struct gimple_statement_wce GTY(())
+{
+  struct gimple_statement_base gsbase;
+
+  /* Subcode: CLEANUP_EH_ONLY.  True if the cleanup should only be
+	      executed if an exception is thrown, not on normal exit of its
+	      scope.  This flag is analogous to the CLEANUP_EH_ONLY flag
+	      in TARGET_EXPRs.  */
+
+  /* Cleanup expression.  */
+  struct gimple_sequence cleanup;
+};
+
 
 /* GIMPLE_ASM */
 struct gimple_statement_asm GTY(())
@@ -339,6 +353,7 @@ union gimple_statement_d GTY ((desc ("gi
   struct gimple_statement_phi GTY ((tag ("GSS_PHI"))) gimple_phi;
   struct gimple_statement_resx GTY ((tag ("GSS_RESX"))) gimple_resx;
   struct gimple_statement_try GTY ((tag ("GSS_TRY"))) gimple_try;
+  struct gimple_statement_wce GTY ((tag ("GSS_WCE"))) gimple_wce;
   struct gimple_statement_asm GTY ((tag ("GSS_ASM"))) gimple_asm;
   struct gimple_statement_omp_critical GTY ((tag ("GSS_OMP_CRITICAL"))) gimple_omp_critical;
   struct gimple_statement_omp_for GTY ((tag ("GSS_OMP_FOR"))) gimple_omp_for;
@@ -641,6 +656,7 @@ gimple build_gimple_asm_vec (const char 
 gimple build_gimple_catch (tree, gimple_seq);
 gimple build_gimple_eh_filter (tree, gimple_seq);
 gimple build_gimple_try (gimple_seq, gimple_seq, unsigned int);
+gimple build_gimple_wce (gimple_seq);
 gimple build_gimple_phi (size_t, size_t, tree, ...);
 gimple build_gimple_resx (int);
 gimple build_gimple_switch (unsigned int, tree, tree, ...);
@@ -1295,6 +1311,39 @@ gimple_try_set_cleanup (gimple gs, gimpl
 }
 
 
+/* GIMPLE_WITH_CLEANUP_EXPR accessors.  */
+
+static inline gimple_seq
+gimple_wce_cleanup (gimple gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+  return &gs->gimple_wce.cleanup;
+}
+
+static inline void
+gimple_wce_set_cleanup (gimple gs, gimple_seq cleanup)
+{
+  GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+  gimple_seq_copy (gimple_wce_cleanup (gs), cleanup);
+}
+
+/* Return the CLEANUP_EH_ONLY flag for a WCE tuple.  */
+static inline bool
+gimple_wce_cleanup_eh_only (gimple gs)
+{
+  GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+  return (bool) gimple_subcode (gs);
+}
+
+/* Set the CLEANUP_EH_ONLY flag for a WCE tuple.  */
+static inline void
+gimple_wce_set_cleanup_eh_only (gimple gs, bool eh_only_p)
+{
+  GIMPLE_CHECK (gs, GIMPLE_WITH_CLEANUP_EXPR);
+  set_gimple_subcode (gs, (unsigned int) eh_only_p);
+}
+
+
 /* GIMPLE_PHI accessors. */
 
 static inline size_t
@@ -1973,6 +2022,7 @@ void gsi_link_before (gimple_stmt_iterat
 void gsi_link_seq_after (gimple_stmt_iterator *, gimple_seq,
 			 enum gsi_iterator_update);
 void gsi_link_after (gimple_stmt_iterator *, gimple, enum gsi_iterator_update);
+void gsi_delink (gimple_stmt_iterator *);
 gimple_seq gsi_split_seq_after (const gimple_stmt_iterator *);
 gimple_seq gsi_split_seq_before (gimple_stmt_iterator *);
 void gsi_replace (gimple_stmt_iterator *, gimple, bool);


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