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] Converting more passes


This patch enables the following passes:

pass_inline_parameters,
pass_ipa_function_and_variable_visibility
pass_ipa_early_inline,
pass_inline_parameters,
pass_rebuild_cgraph_edges

Oleg Ryjkov
2008-02-13  Oleg Ryjkov  <olegr@google.com>

	* tree.h: New funtion declaration.
	* gimple-dummy.c (tree_inlinable_function_p): Removed.
	* ipa-inline.c (compute_inline_parameters): Removed
	gcc_unreachable ().
	* calls.c (gimple_alloca_call_p): New function.
	* tree-inline.c (inline_forbidden_p_1): Split in two and removed.
	(inline_forbidden_p_op, inline_forbidden_p_stmt): New functions.
	(inline_forbidden_p): Tuplified.
	(estimate_operator_cost): Added missing cases, per Bill Maddox's
	suggestion.
	* passes.c (init_optimization_passes): Enabled passes.
	* gimple.def (GIMPLE_TRY): Tidy comment.
	* gimple-pretty-print.c (dump_gimple_stmt): Handle TDF_VOPS and
Index: tree.h
===================================================================
--- tree.h	(revision 132293)
+++ tree.h	(working copy)
@@ -4972,6 +4972,7 @@ extern int flags_from_decl_or_type (cons
 extern int call_expr_flags (const_tree);
 
 extern int setjmp_call_p (const_tree);
+extern bool gimple_alloca_call_p (const_gimple);
 extern bool alloca_call_p (const_tree);
 extern bool must_pass_in_stack_var_size (enum machine_mode, const_tree);
 extern bool must_pass_in_stack_var_size_or_pad (enum machine_mode, const_tree);
Index: gimple-dummy.c
===================================================================
--- gimple-dummy.c	(revision 132293)
+++ gimple-dummy.c	(working copy)
@@ -74,7 +74,6 @@ DUMMY_FN (scev_probably_wraps_p)
 DUMMY_FN (scev_reset)
 DUMMY_FN (gimple_duplicate_loop_to_header_edge)
 DUMMY_FN (tree_function_versioning)
-DUMMY_FN (tree_inlinable_function_p)
 DUMMY_FN (tree_int_cst_sign_bit)
 DUMMY_FN (tree_ssa_iv_optimize)
 DUMMY_FN (tree_ssa_lim)
Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 132297)
+++ ipa-inline.c	(working copy)
@@ -1537,10 +1537,6 @@ compute_inline_parameters (void)
   node->local.inlinable = tree_inlinable_function_p (current_function_decl);
   node->local.self_insns = estimate_num_insns_fn (current_function_decl,
 						  &eni_inlining_weights);
-
-  /* FIXME tuples.  */
-  gimple_unreachable ();
-
   if (node->local.inlinable && !node->local.disregard_inline_limits)
     node->local.disregard_inline_limits
       = DECL_DISREGARD_INLINE_LIMITS (current_function_decl);
Index: calls.c
===================================================================
--- calls.c	(revision 132293)
+++ calls.c	(working copy)
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  
 #include "tm.h"
 #include "rtl.h"
 #include "tree.h"
+#include "gimple.h"
 #include "flags.h"
 #include "expr.h"
 #include "optabs.h"
@@ -553,7 +554,21 @@ setjmp_call_p (const_tree fndecl)
   return special_function_p (fndecl, 0) & ECF_RETURNS_TWICE;
 }
 
+/* Return true when an expression stmt contains alloca call.  */
+bool
+gimple_alloca_call_p (const_gimple stmt)
+{
+  if (gimple_code (stmt) == GIMPLE_CALL
+      && TREE_CODE (gimple_call_fn (stmt)) == ADDR_EXPR
+      && (TREE_CODE (TREE_OPERAND (gimple_call_fn (stmt), 0)) == FUNCTION_DECL)
+      && (special_function_p (TREE_OPERAND (gimple_call_fn (stmt), 0), 0)
+          & ECF_MAY_BE_ALLOCA))
+    return true;
+  return false;
+}
+
 /* Return true when exp contains alloca call.  */
+
 bool
 alloca_call_p (const_tree exp)
 {
Index: tree-inline.c
===================================================================
--- tree-inline.c	(revision 132293)
+++ tree-inline.c	(working copy)
@@ -130,7 +130,10 @@ eni_weights eni_time_weights;
 
 static tree declare_return_variable (copy_body_data *, tree, tree, tree *);
 static tree copy_generic_body (copy_body_data *);
+#endif
 static bool inlinable_function_p (tree);
+/* FIXME tuples.  */
+#if 0
 static void remap_block (tree *, copy_body_data *);
 static tree remap_decls (tree, copy_body_data *);
 static void copy_bind_expr (tree *, int *, copy_body_data *);
@@ -1875,6 +1878,7 @@ declare_return_variable (copy_body_data 
   *use_p = use;
   return var;
 }
+#endif
 
 /* Returns nonzero if a function can be inlined as a tree.  */
 
@@ -1886,31 +1890,71 @@ tree_inlinable_function_p (tree fn)
 
 static const char *inline_forbidden_reason;
 
+/* A callback for walk_gimple_seq to hadle tree operands. Returns NULL_TREE if
+   a function can be inlined, otherwise sets the reason why not and returns
+   a tree representing the offending statement. */
+
 static tree
-inline_forbidden_p_1 (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
-		      void *fnp)
+inline_forbidden_p_op (tree *nodep, int *walk_subtrees ATTRIBUTE_UNUSED,
+                         void *fnp ATTRIBUTE_UNUSED)
 {
   tree node = *nodep;
-  tree fn = (tree) fnp;
   tree t;
 
-  switch (TREE_CODE (node))
+  if (TREE_CODE (node) == RECORD_TYPE || TREE_CODE (node) == UNION_TYPE)
     {
-    case CALL_EXPR:
+      /* We cannot inline a function of the form
+
+	   void F (int i) { struct S { int ar[i]; } s; }
+
+	 Attempting to do so produces a catch-22.
+	 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
+	 UNION_TYPE nodes, then it goes into infinite recursion on a
+	 structure containing a pointer to its own type.  If it doesn't,
+	 then the type node for S doesn't get adjusted properly when
+	 F is inlined. 
+
+	 ??? This is likely no longer true, but it's too late in the 4.0
+	 cycle to try to find out.  This should be checked for 4.1.  */
+      for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
+	if (variably_modified_type_p (TREE_TYPE (t), NULL))
+	  {
+	    inline_forbidden_reason
+	      = G_("function %q+F can never be inlined "
+		   "because it uses variable sized variables");
+	    return node;
+	  }
+    }
+  return NULL_TREE;
+}
+
+/* A callback for walk_gimple_seq to handle statements. Returns true iff a
+   function can not be inlined. Also sets the reason why. */
+
+static bool
+inline_forbidden_p_stmt (gimple stmt, void *wip)
+{
+  struct walk_stmt_info wi = *(struct walk_stmt_info *) wip;
+  tree fn = (tree) wi.info;
+  tree t;
+
+  switch (gimple_code (stmt))
+    {
+    case GIMPLE_CALL:
       /* Refuse to inline alloca call unless user explicitly forced so as
 	 this may change program's memory overhead drastically when the
 	 function using alloca is called in loop.  In GCC present in
 	 SPEC2000 inlining into schedule_block cause it to require 2GB of
 	 RAM instead of 256MB.  */
-      if (alloca_call_p (node)
+      if (gimple_alloca_call_p (stmt)
 	  && !lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)))
 	{
 	  inline_forbidden_reason
 	    = G_("function %q+F can never be inlined because it uses "
 		 "alloca (override using the always_inline attribute)");
-	  return node;
+	  return true;
 	}
-      t = get_callee_fndecl (node);
+      t = gimple_call_fndecl (stmt);
       if (! t)
 	break;
 
@@ -1919,7 +1963,7 @@ inline_forbidden_p_1 (tree *nodep, int *
 	{
 	  inline_forbidden_reason
 	    = G_("function %q+F can never be inlined because it uses setjmp");
-	  return node;
+	  return true;
 	}
 
       if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL)
@@ -1934,7 +1978,7 @@ inline_forbidden_p_1 (tree *nodep, int *
 	    inline_forbidden_reason
 	      = G_("function %q+F can never be inlined because it "
 		   "uses variable argument lists");
-	    return node;
+	    return true;
 
 	  case BUILT_IN_LONGJMP:
 	    /* We can't inline functions that call __builtin_longjmp at
@@ -1945,14 +1989,14 @@ inline_forbidden_p_1 (tree *nodep, int *
 	    inline_forbidden_reason
 	      = G_("function %q+F can never be inlined because "
 		   "it uses setjmp-longjmp exception handling");
-	    return node;
+	    return true;
 
 	  case BUILT_IN_NONLOCAL_GOTO:
 	    /* Similarly.  */
 	    inline_forbidden_reason
 	      = G_("function %q+F can never be inlined because "
 		   "it uses non-local goto");
-	    return node;
+	    return true;
 
 	  case BUILT_IN_RETURN:
 	  case BUILT_IN_APPLY_ARGS:
@@ -1963,15 +2007,15 @@ inline_forbidden_p_1 (tree *nodep, int *
 	    inline_forbidden_reason
 	      = G_("function %q+F can never be inlined because "
 		   "it uses __builtin_return or __builtin_apply_args");
-	    return node;
+	    return true;
 
 	  default:
 	    break;
 	  }
       break;
 
-    case GOTO_EXPR:
-      t = TREE_OPERAND (node, 0);
+    case GIMPLE_GOTO:
+      t = gimple_goto_dest (stmt);
 
       /* We will not inline a function which uses computed goto.  The
 	 addresses of its local labels, which may be tucked into
@@ -1982,12 +2026,12 @@ inline_forbidden_p_1 (tree *nodep, int *
 	  inline_forbidden_reason
 	    = G_("function %q+F can never be inlined "
 		 "because it contains a computed goto");
-	  return node;
+	  return true;
 	}
       break;
 
-    case LABEL_EXPR:
-      t = TREE_OPERAND (node, 0);
+    case GIMPLE_LABEL:
+      t = gimple_label_label (stmt);
       if (DECL_NONLOCAL (t))
 	{
 	  /* We cannot inline a function that receives a non-local goto
@@ -1996,39 +2040,15 @@ inline_forbidden_p_1 (tree *nodep, int *
 	  inline_forbidden_reason
 	    = G_("function %q+F can never be inlined "
 		 "because it receives a non-local goto");
-	  return node;
+	  return true;
 	}
       break;
 
-    case RECORD_TYPE:
-    case UNION_TYPE:
-      /* We cannot inline a function of the form
-
-	   void F (int i) { struct S { int ar[i]; } s; }
-
-	 Attempting to do so produces a catch-22.
-	 If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
-	 UNION_TYPE nodes, then it goes into infinite recursion on a
-	 structure containing a pointer to its own type.  If it doesn't,
-	 then the type node for S doesn't get adjusted properly when
-	 F is inlined. 
-
-	 ??? This is likely no longer true, but it's too late in the 4.0
-	 cycle to try to find out.  This should be checked for 4.1.  */
-      for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
-	if (variably_modified_type_p (TREE_TYPE (t), NULL))
-	  {
-	    inline_forbidden_reason
-	      = G_("function %q+F can never be inlined "
-		   "because it uses variable sized variables");
-	    return node;
-	  }
-
     default:
       break;
     }
 
-  return NULL_TREE;
+  return false;
 }
 
 static tree
@@ -2053,24 +2073,31 @@ inline_forbidden_p_2 (tree *nodep, int *
 }
 
 /* Return subexpression representing possible alloca call, if any.  */
-static tree
+
+static bool
 inline_forbidden_p (tree fndecl)
 {
   location_t saved_loc = input_location;
-  block_stmt_iterator bsi;
-  basic_block bb;
-  tree ret = NULL_TREE;
+  gimple_seq seq = gimple_body (fndecl);
+  bool ret = false;
   struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
   tree step;
 
-  FOR_EACH_BB_FN (bb, fun)
-    for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi))
-      {
-	ret = walk_tree_without_duplicates (bsi_stmt_ptr (bsi),
-					    inline_forbidden_p_1, fndecl);
-	if (ret)
-	  goto egress;
-      }
+  {
+    struct walk_stmt_info wi;
+    struct pointer_set_t *visited_nodes = pointer_set_create ();
+
+    memset (&wi, 0, sizeof (wi));
+    wi.info = (void *) fndecl;
+    wi.pset = visited_nodes;
+    ret = walk_gimple_seq (seq,
+                           inline_forbidden_p_stmt,
+                           inline_forbidden_p_op,
+                           &wi) != NULL_TREE;
+    pointer_set_destroy (visited_nodes);
+    if (ret)
+      goto egress;
+  }
 
   for (step = fun->unexpanded_var_list; step; step = TREE_CHAIN (step))
     {
@@ -2078,11 +2105,13 @@ inline_forbidden_p (tree fndecl)
       if (TREE_CODE (decl) == VAR_DECL
 	  && TREE_STATIC (decl)
 	  && !DECL_EXTERNAL (decl)
-	  && DECL_INITIAL (decl))
-	ret = walk_tree_without_duplicates (&DECL_INITIAL (decl),
-					    inline_forbidden_p_2, fndecl);
-	if (ret)
+	  && DECL_INITIAL (decl)
+          && walk_tree_without_duplicates (&DECL_INITIAL (decl),
+				           inline_forbidden_p_2, fndecl))
+        {
+	  ret = true;
 	  goto egress;
+        }
     }
 
 egress:
@@ -2182,7 +2211,6 @@ inlinable_function_p (tree fn)
 
   return inlinable;
 }
-#endif
 
 /* Estimate the cost of a memory move.  Use machine dependent
    word size and take possible memcpy call into account.  */
@@ -2208,6 +2236,12 @@ estimate_operator_cost (enum tree_code c
 {
   switch (code)
     {
+    case RANGE_EXPR:
+    case CONVERT_EXPR:
+    case COMPLEX_EXPR:
+    case NOP_EXPR:
+    case NON_LVALUE_EXPR:
+      return 0;
     /* Assign cost of 1 to usual operations.
        ??? We may consider mapping RTL costs to this.  */
     case COND_EXPR:
Index: passes.c
===================================================================
--- passes.c	(revision 132293)
+++ passes.c	(working copy)
@@ -495,18 +495,13 @@ init_optimization_passes (void)
   NEXT_PASS (pass_lower_vector);
   NEXT_PASS (pass_warn_function_return);
   NEXT_PASS (pass_build_cgraph_edges);
-  /* FIXME tuples.  */
-#if 0
   NEXT_PASS (pass_inline_parameters);
-#endif
   *p = NULL;
 
   /* Interprocedural optimization passes. 
      All these passes are ignored in -fno-unit-at-a-time
      except for subpasses of early_local_passes.  */
   p = &all_ipa_passes;
-  /* FIXME tuples.  */
-#if 0
   NEXT_PASS (pass_ipa_function_and_variable_visibility);
   NEXT_PASS (pass_ipa_early_inline);
     {
@@ -515,7 +510,6 @@ init_optimization_passes (void)
       NEXT_PASS (pass_inline_parameters);
       NEXT_PASS (pass_rebuild_cgraph_edges);
     }
-#endif
   NEXT_PASS (pass_early_local_passes);
     {
       struct tree_opt_pass **p = &pass_early_local_passes.sub;

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