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] gimplify CALL_EXPR


This patch adds the basics for getting GS_CALL generated.  It converts
the various CALL_EXPRs found during libgcc builds, but we fail early
enough that it's still not possible to tell what's missing.

Will add a few more tests as I find bugs.

I removed the call to debug_gimple_seq in the gimplifier so that 'make
check-gcc RUNTESTFLAGS=gimple.exp'.  Perhaps we should do this with
-fdump-tree-gimple-details.  I'll add a check for TDF_DETAILS at the end
of gimplification.

We are currently failing gcc.dg/gimple/constructors.c.  Aldy says it
works for him, so it must've been something I broke.  I'll check it out.
2007-06-26  Diego Novillo  <dnovillo@google.com>

	* gimple-pretty-print.c (dump_gs_assign, dump_gs_return,
	dump_gs_call): New functions.
	(dump_gimple_stmt): Call them.
	* gimple-ir.c (gs_build_call_1): Factor out of gs_build_call.
	(gs_build_call): Call it.
	(gs_build_call_vec): New function.
	* gimple-ir.h (struct gimple_statement_call): Change type of
	field 'nargs' to size_t.  Update all users.
	(gs_build_call_vec): Declare.
	(gs_call_set_fn): Remove.
	(gs_call_set_nargs): Remove.
	* gimplify.c: Include "vec.h"
	(gimplify_return_expr): Fix formatting
	(gimplify_call_expr): Call gs_build_call_vec.
	(gimplify_expr): Do not try to test if NULL expressions
	are in GIMPLE form.
	(gimplify_function_tree): Do not call debug_gimple_seq.
	* Makefile.in (gimplify.o): Include vec.h


testsuite/ChangeLog:

	* testsuite/gcc.dg/gimple/gimple.exp: Use -O2.

Index: testsuite/gcc.dg/gimple/gimple.exp
===================================================================
--- testsuite/gcc.dg/gimple/gimple.exp	(revision 126029)
+++ testsuite/gcc.dg/gimple/gimple.exp	(working copy)
@@ -21,7 +21,7 @@ load_lib gcc-dg.exp
 # If a testcase doesn't have special options, use these.
 global DEFAULT_CFLAGS
 if ![info exists DEFAULT_CFLAGS] then {
-    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+    set DEFAULT_CFLAGS "-O2"
 }
 
 # Initialize `dg'.
Index: gimple-pretty-print.c
===================================================================
--- gimple-pretty-print.c	(revision 126029)
+++ gimple-pretty-print.c	(working copy)
@@ -92,6 +92,88 @@ print_gimple_stmt (FILE *file, gimple g,
   pp_flush (&buffer);
 }
 
+
+/* Dump the gimple assignment GS.  BUFFER, SPC and FLAGS are as in
+   dump_gimple_stmt.  */
+
+static void
+dump_gs_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  enum gimple_statement_structure_enum gss;
+
+  dump_generic_node (buffer, gs_assign_lhs (gs), spc, flags, false);
+  pp_space (buffer);
+  pp_character (buffer, '=');
+  pp_space (buffer);
+
+  gss = gss_for_assign (GS_SUBCODE_FLAGS (gs));
+  switch (gss)
+    {
+      case GSS_ASSIGN_BINARY:
+	dump_generic_node (buffer, gs_assign_binary_rhs1 (gs), spc,
+			   flags, false);
+	pp_space (buffer);
+	pp_string (buffer, op_symbol_code (GS_SUBCODE_FLAGS (gs)));
+	pp_space (buffer);
+	dump_generic_node (buffer, gs_assign_binary_rhs2 (gs), spc,
+			   flags, false);
+	break;
+
+      case GSS_ASSIGN_UNARY_REG:
+      case GSS_ASSIGN_UNARY_MEM:
+	dump_generic_node (buffer, gs_assign_unary_rhs (gs), spc, flags, false);
+	break;
+
+      default:
+	gcc_unreachable ();
+    }
+}
+
+
+/* Dump the return statement GS.  BUFFER, SPC and FLAGS are as in
+   dump_gimple_stmt.  */
+
+static void
+dump_gs_return (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  tree t;
+
+  pp_string (buffer, "return");
+  t = gs_return_retval (gs);
+  if (t)
+    {
+      pp_space (buffer);
+      if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
+	dump_generic_node (buffer, GIMPLE_STMT_OPERAND (t, 1),
+	    spc, flags, false);
+      else
+	dump_generic_node (buffer, t, spc, flags, false);
+    }
+}
+
+
+/* Dump the call statement GS.  BUFFER, SPC and FLAGS are as in
+   dump_gimple_stmt.  */
+
+static void
+dump_gs_call (pretty_printer *buffer, gimple gs, int spc, int flags)
+{
+  size_t i;
+
+  dump_generic_node (buffer, gs_call_fn (gs), spc, flags, false);
+  pp_string (buffer, " (");
+
+  for (i = 0; i < gs_call_nargs (gs); i++)
+    {
+      dump_generic_node (buffer, gs_call_arg (gs, i), 0, flags, false);
+      if (i < gs_call_nargs (gs) - 1)
+	pp_string (buffer, ", ");
+    }
+
+  pp_string (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).  */
@@ -99,64 +181,26 @@ print_gimple_stmt (FILE *file, gimple g,
 void
 dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
 {
-  tree t;
-
   if (!gs)
     return;
 
   switch (GS_CODE (gs))
     {
     case GS_ASSIGN:
-      {
-	enum gimple_statement_structure_enum gss;
-
-	dump_generic_node (buffer, gs_assign_lhs (gs), spc, flags,
-			   false);
-	pp_space (buffer);
-	pp_character (buffer, '=');
-	pp_space (buffer);
-
-	gss = gss_for_assign (GS_SUBCODE_FLAGS (gs));
-	switch (gss)
-	  {
-	  case GSS_ASSIGN_BINARY:
-	    dump_generic_node (buffer, gs_assign_binary_rhs1 (gs), spc,
-			       flags, false);
-	    pp_space (buffer);
-	    pp_string (buffer, op_symbol_code (GS_SUBCODE_FLAGS (gs)));
-	    pp_space (buffer);
-	    dump_generic_node (buffer, gs_assign_binary_rhs2 (gs), spc,
-			       flags, false);
-	    break;
-	  case GSS_ASSIGN_UNARY_REG:
-	  case GSS_ASSIGN_UNARY_MEM:
-	    dump_generic_node (buffer, gs_assign_unary_rhs (gs), spc,
-			       flags, false);
-	    break;
-	  default:
-	    gcc_unreachable ();
-	  }
+      dump_gs_assign (buffer, gs, spc, flags);
+      break;
 
-	break;
-      }
     case GS_RETURN:
-      pp_string (buffer, "return");
-      t = gs_return_retval (gs);
-      if (t)
-	{
-	  pp_space (buffer);
-	  if (TREE_CODE (t) == GIMPLE_MODIFY_STMT)
-	    dump_generic_node (buffer, GIMPLE_STMT_OPERAND (t, 1),
-			       spc, flags, false);
-	  else
-	    dump_generic_node (buffer, t, spc, flags, false);
-	}
+      dump_gs_return (buffer, gs, spc, flags);
+      break;
+
+    case GS_CALL:
+      dump_gs_call (buffer, gs, spc, flags);
       break;
 
     default:
       GS_NIY;
     }
 
-  pp_semicolon (buffer);
   pp_write_text_to_stream (buffer);
 }
Index: gimple-ir.c
===================================================================
--- gimple-ir.c	(revision 126029)
+++ gimple-ir.c	(working copy)
@@ -53,33 +53,60 @@ gs_build_return (bool result_decl_p, tre
   return p;
 }
 
-/* Construct a GS_CALL statement.
+/* Helper for gs_build_call and gs_build_call_vec.  Build the basic
+   components of a GS_CALL statement to function FN with NARGS
+   arguments.  */
 
-   FUNC is the function decl.
-   NARGS is the number of arguments.
-   The ... are the arguments.  */
+static inline
+gimple gs_build_call_1 (tree fn, size_t nargs)
+{
+  gimple gs = ggc_alloc_cleared (sizeof (struct gimple_statement_call)
+                                 + sizeof (tree) * (nargs - 1));
+
+  GS_CODE (gs) = GS_CALL;
+  GS_SUBCODE_FLAGS (gs) = 0;
+  gs->gs_call.nargs = nargs;
+  gs->gs_call.fn = fn;
+
+  return gs;
+}
+
+
+/* Build a GS_CALL statement to function FN with the arguments
+   specified in vector ARGS.  */
 
 gimple
-gs_build_call (tree func, int nargs, ...)
+gs_build_call_vec (tree fn, VEC(tree, gc) *args)
 {
-  va_list ap;
-  gimple p;
-  int i;
+  size_t i;
+  size_t nargs = VEC_length (tree, args);
+  gimple call = gs_build_call_1 (fn, nargs);
 
-  p = ggc_alloc_cleared (sizeof (struct gimple_statement_call)
-                         + sizeof (tree) * (nargs - 1));
+  for (i = 0; i < nargs; i++)
+    gs_call_set_arg (call, i, VEC_index (tree, args, i));
 
-  GS_CODE (p) = GS_CALL;
-  GS_SUBCODE_FLAGS (p) = 0;
-  gs_call_set_nargs (p, nargs);
-  gs_call_set_fn (p, func);
+  return call;
+}
+
+
+/* Build a GS_CALL statement to function FN.  NARGS is the number of
+   arguments.  The ... are the arguments.  */
+
+gimple
+gs_build_call (tree fn, size_t nargs, ...)
+{
+  va_list ap;
+  gimple call;
+  size_t i;
+
+  call = gs_build_call_1 (fn, nargs);
 
   va_start (ap, nargs);
-  for (i = 0; i < nargs; ++i)
-    gs_call_set_arg (p, i, va_arg (ap, tree));
+  for (i = 0; i < nargs; i++)
+    gs_call_set_arg (call, i, va_arg (ap, tree));
   va_end (ap);
 
-  return p;
+  return call;
 }
 
 /* Construct a GS_ASSIGN statement.
Index: gimple-ir.h
===================================================================
--- gimple-ir.h	(revision 126029)
+++ gimple-ir.h	(working copy)
@@ -39,7 +39,6 @@ enum gs_code {
 				 && GS_LOCUS ((G)).line == 0)
 
 /* A sequences of gimple statements.  */
-
 struct gs_sequence
 {
   gimple first;
@@ -250,7 +249,7 @@ struct gimple_statement_call GTY(())
   tree lhs;
   tree fn;
   tree chain;
-  unsigned long nargs;
+  size_t nargs;
   tree GTY ((length ("%h.nargs"))) args[1];
 };
 
@@ -369,7 +368,8 @@ union gimple_statement_d GTY ((desc ("gi
 
 extern gimple gs_build_return (bool, tree);
 extern gimple gs_build_assign (tree, tree);
-extern gimple gs_build_call (tree, int, ...);
+extern gimple gs_build_call_vec (tree, VEC(tree, gc) *);
+extern gimple gs_build_call (tree, size_t, ...);
 extern gimple gs_build_cond (enum gs_cond, tree, tree, tree, tree);
 extern gimple gs_build_label (tree label);
 extern gimple gs_build_goto (tree dest);
@@ -575,13 +575,6 @@ gs_call_fn (gimple gs)
   return gs->gs_call.fn;
 }
 
-static inline void
-gs_call_set_fn (gimple gs, tree fn)
-{
-  GS_CHECK (gs, GS_CALL);
-  gs->gs_call.fn = fn;
-}
-
 static inline tree
 gs_call_lhs (gimple gs)
 {
@@ -617,13 +610,6 @@ gs_call_nargs (gimple gs)
   return gs->gs_call.nargs;
 }
 
-static inline void
-gs_call_set_nargs (gimple gs, unsigned long nargs)
-{
-  GS_CHECK (gs, GS_CALL);
-  gs->gs_call.nargs = nargs;
-}
-
 static inline tree
 gs_call_arg (gimple gs, int index)
 {
Index: gimplify.c
===================================================================
--- gimplify.c	(revision 126029)
+++ gimplify.c	(working copy)
@@ -51,6 +51,7 @@ Software Foundation, 51 Franklin Street,
 #include "pointer-set.h"
 #include "splay-tree.h"
 #include "gimple-ir.h"
+#include "vec.h"
 
 
 enum gimplify_omp_var_data
@@ -1141,7 +1142,8 @@ gimplify_return_expr (tree stmt, gs_seq 
   tree ret_expr = TREE_OPERAND (stmt, 0);
   tree result_decl, result;
 
-  if (!ret_expr || TREE_CODE (ret_expr) == RESULT_DECL
+  if (!ret_expr
+      || TREE_CODE (ret_expr) == RESULT_DECL
       || ret_expr == error_mark_node)
     {
       gs_add (gs_build_return (TREE_CODE (ret_expr) == RESULT_DECL, ret_expr),
@@ -1206,6 +1208,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), pre_p);
 
   return GS_ALL_DONE;
@@ -2067,6 +2070,7 @@ gimplify_call_expr (tree *expr_p, gs_seq
   tree decl;
   enum gimplify_status ret;
   int i, nargs;
+  VEC(tree, gc) *args = NULL;
 
   gcc_assert (TREE_CODE (*expr_p) == CALL_EXPR);
 
@@ -2140,6 +2144,8 @@ gimplify_call_expr (tree *expr_p, gs_seq
 
       if (t == GS_ERROR)
 	ret = GS_ERROR;
+
+      VEC_safe_push (tree, gc, args, CALL_EXPR_ARG (*expr_p, i));
     }
 
   /* Try this again in case gimplification exposed something.  */
@@ -2164,6 +2170,9 @@ gimplify_call_expr (tree *expr_p, gs_seq
       && (call_expr_flags (*expr_p) & (ECF_CONST | ECF_PURE)))
     TREE_SIDE_EFFECTS (*expr_p) = 0;
 
+  gs_add (gs_build_call_vec (decl, args), pre_p);
+  *expr_p = NULL_TREE;
+
   return ret;
 }
 
@@ -5575,6 +5584,7 @@ gimplify_expr (tree *expr_p, gs_seq pre_
 
 	case CALL_EXPR:
 	  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
@@ -6093,7 +6103,6 @@ gimplify_expr (tree *expr_p, gs_seq pre_
 
       /* EXPR_P should be a gimple statement, so the tree is meaningless;
 	 do nothing with it.  */
-
       annotate_all_with_locus (pre_p, input_location);
       goto out;
     }
@@ -6136,7 +6145,8 @@ gimplify_expr (tree *expr_p, gs_seq pre_
   /* If it's sufficiently simple already, we're done.  Unless we are
      handling some post-effects internally; if that's the case, we need to
      copy into a temp before adding the post-effects to the tree.  */
-  if (gs_seq_empty_p (&internal_post) && (*gimple_test_f) (*expr_p))
+  if (gs_seq_empty_p (&internal_post)
+      && (*expr_p == NULL_TREE || (*gimple_test_f) (*expr_p)))
     goto out;
 
   /* Otherwise, we need to create a new temporary for the gimplified
@@ -6539,7 +6549,6 @@ gimplify_function_tree (tree fndecl)
 
   gs_seq_init (&seq);
   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
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 126029)
+++ Makefile.in	(working copy)
@@ -2146,7 +2146,7 @@ gimplify.o : gimplify.c $(CONFIG_H) $(SY
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(CGRAPH_H) $(TIMEVAR_H) $(TM_H) \
    coretypes.h except.h $(FLAGS_H) $(RTL_H) $(FUNCTION_H) $(EXPR_H) output.h \
    $(GGC_H) gt-gimplify.h $(HASHTAB_H) $(TARGET_H) toplev.h $(OPTABS_H) \
-   $(REAL_H) $(SPLAY_TREE_H)
+   $(REAL_H) $(SPLAY_TREE_H) vec.h
 gimple-low.o : gimple-low.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \
    $(DIAGNOSTIC_H) $(TREE_GIMPLE_H) $(TREE_INLINE_H) $(VARRAY_H) langhooks.h \
    $(LANGHOOKS_DEF_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TM_H) coretypes.h \

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