[tuples] constructors and assorted infrastructure

Aldy Hernandez aldyh@redhat.com
Fri May 4 13:46:00 GMT 2007


Here are some infrastructure changes, mostly dealing with constructors
for building gimple statements.  For now, we have GS_ASSIGN and
GS_RETURN being built correctly.  We also have macros to access operands, etc.

Committed to branch.

	* gimple-ir.c (gs_code_name): Constify.
	(gs_build_assign): New.
	(gimple_statement_structure): Abstract code out to...
	(gss_for_assign): ...here.
	(gs_add): Set the last item correctly.
	* gimple-ir.h (GS_LOCUS_EMPTY_P): New.
	(GS_SEQ_INIT): Add a cast.
	(gimple_statement_base): Make code a gs_code enum.
	(gimple_statement_with_ops): Remove address_taken.
	(GS_ASSIGN_BINARY_LHS): New.
	(GS_ASSIGN_BINARY_RHS1): New.
	(GS_ASSIGN_BINARY_RHS2): New.
	(GS_ASSIGN_UNARY_REG_LHS): New.
	(GS_ASSIGN_UNARY_REG_RHS): New.
	(GS_ASSIGN_UNARY_MEM_LHS): New.
	(GS_ASSIGN_UNARY_MEM_RHS): New.
	(gs_seq_append): New.
	Move gs_seq typedef to...
	* coretypes.h: ...here.
	* gimple-iterator.h (gsi_stmt_ptr): Add FIXME note.

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: 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: 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)



More information about the Gcc-patches mailing list