gimple.c: Include builtins.h
authorJan Hubicka <hubicka@ucw.cz>
Tue, 7 Jun 2016 11:22:26 +0000 (13:22 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 7 Jun 2016 11:22:26 +0000 (11:22 +0000)
* gimple.c: Include builtins.h
(gimple_inexpensive_call_p): New function.
* gimple.h (gimple_inexpensive_call_p): Declare.
* tree-ssa-loop-ch.c (should_duplicate_loop_header_p): Use it.
* tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Likewise;
fix formatting.

From-SVN: r237172

gcc/ChangeLog
gcc/gimple.c
gcc/gimple.h
gcc/tree-ssa-loop-ch.c
gcc/tree-ssa-loop-ivcanon.c

index 3c2825c99c7f753e833de9ca14ee230df47ca559..16f8b60afaf5c76964ff9b0229164f7595e87c85 100644 (file)
@@ -1,3 +1,12 @@
+2016-06-07  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gimple.c: Include builtins.h
+       (gimple_inexpensive_call_p): New function.
+       * gimple.h (gimple_inexpensive_call_p): Declare.
+       * tree-ssa-loop-ch.c (should_duplicate_loop_header_p): Use it.
+       * tree-ssa-loop-ivcanon.c (tree_estimate_loop_size): Likewise;
+       fix formatting.
+
 2016-06-07  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * diagnostic.c (diagnostic_impl, diagnostic_n_impl): New.
index 178c1d3a517d586358e374b1348468091cb707e5..677c56070904f82d77aa8a6e4de7a2e664ecda76 100644 (file)
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-walk.h"
 #include "gimplify.h"
 #include "target.h"
+#include "builtins.h"
 #include "selftest.h"
 #include "gimple-pretty-print.h"
 
@@ -3025,6 +3026,19 @@ maybe_remove_unused_call_args (struct function *fn, gimple *stmt)
     }
 }
 
+/* Return false if STMT will likely expand to real function call.  */
+
+bool
+gimple_inexpensive_call_p (gcall *stmt)
+{
+  if (gimple_call_internal_p (stmt))
+    return true;
+  tree decl = gimple_call_fndecl (stmt);
+  if (decl && is_inexpensive_builtin (decl))
+    return true;
+  return false;
+}
+
 #if CHECKING_P
 
 namespace selftest {
index 063e29d78978f4dad74db05705be1d10856d8607..1da719c52e074be2daa6ceff1e8e2af93b96e0c7 100644 (file)
@@ -1525,6 +1525,7 @@ extern void preprocess_case_label_vec_for_gimple (vec<tree>, tree, tree *);
 extern void gimple_seq_set_location (gimple_seq, location_t);
 extern void gimple_seq_discard (gimple_seq);
 extern void maybe_remove_unused_call_args (struct function *, gimple *);
+extern bool gimple_inexpensive_call_p (gcall *);
 
 /* Formal (expression) temporary table handling: multiple occurrences of
    the same scalar expression are evaluated into the same temporary.  */
index 3af09ece39eb747e4517a8b5e7bf31969c53a710..0ddbda6da7ea5f4fe8ac8efe93abee4054bf1127 100644 (file)
@@ -118,7 +118,8 @@ should_duplicate_loop_header_p (basic_block header, struct loop *loop,
       if (is_gimple_debug (last))
        continue;
 
-      if (is_gimple_call (last))
+      if (gimple_code (last) == GIMPLE_CALL
+         && !gimple_inexpensive_call_p (as_a <gcall *> (last)))
        {
          if (dump_file && (dump_flags & TDF_DETAILS))
            fprintf (dump_file,
index 5a7c378a9755db49bcd7cc6b9d25ed4ba93027d4..fff28ee8712f41e1d0594ffaef5911260a60c72e 100644 (file)
@@ -207,8 +207,8 @@ constant_after_peeling (tree op, gimple *stmt, struct loop *loop)
    Stop estimating after UPPER_BOUND is met.  Return true in this case.  */
 
 static bool
-tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, struct loop_size *size,
-                        int upper_bound)
+tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel,
+                        struct loop_size *size, int upper_bound)
 {
   basic_block *body = get_loop_body (loop);
   gimple_stmt_iterator gsi;
@@ -236,7 +236,8 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
       else
        after_exit = false;
       if (dump_file && (dump_flags & TDF_DETAILS))
-       fprintf (dump_file, " BB: %i, after_exit: %i\n", body[i]->index, after_exit);
+       fprintf (dump_file, " BB: %i, after_exit: %i\n", body[i]->index,
+                after_exit);
 
       for (gsi = gsi_start_bb (body[i]); !gsi_end_p (gsi); gsi_next (&gsi))
        {
@@ -285,20 +286,24 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
          /* Assignments of IV variables.  */
          else if (gimple_code (stmt) == GIMPLE_ASSIGN
                   && TREE_CODE (gimple_assign_lhs (stmt)) == SSA_NAME
-                  && constant_after_peeling (gimple_assign_rhs1 (stmt), stmt, loop)
+                  && constant_after_peeling (gimple_assign_rhs1 (stmt), stmt,
+                                             loop)
                   && (gimple_assign_rhs_class (stmt) != GIMPLE_BINARY_RHS
                       || constant_after_peeling (gimple_assign_rhs2 (stmt),
                                                  stmt, loop)))
            {
              size->constant_iv = true;
              if (dump_file && (dump_flags & TDF_DETAILS))
-               fprintf (dump_file, "   Constant expression will be folded away.\n");
+               fprintf (dump_file,
+                        "   Constant expression will be folded away.\n");
              likely_eliminated = true;
            }
          /* Conditionals.  */
          else if ((gimple_code (stmt) == GIMPLE_COND
-                   && constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
-                   && constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop)
+                   && constant_after_peeling (gimple_cond_lhs (stmt), stmt,
+                                              loop)
+                   && constant_after_peeling (gimple_cond_rhs (stmt), stmt,
+                                              loop)
                    /* We don't simplify all constant compares so make sure
                       they are not both constant already.  See PR70288.  */
                    && (! is_gimple_min_invariant (gimple_cond_lhs (stmt))
@@ -307,8 +312,8 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
                       && constant_after_peeling (gimple_switch_index (
                                                    as_a <gswitch *> (stmt)),
                                                  stmt, loop)
-                      && ! is_gimple_min_invariant (gimple_switch_index (
-                                                      as_a <gswitch *> (stmt)))))
+                      && ! is_gimple_min_invariant
+                              (gimple_switch_index (as_a <gswitch *> (stmt)))))
            {
              if (dump_file && (dump_flags & TDF_DETAILS))
                fprintf (dump_file, "   Constant conditional.\n");
@@ -339,26 +344,24 @@ tree_estimate_loop_size (struct loop *loop, edge exit, edge edge_to_cancel, stru
       for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
        {
          gimple *stmt = gsi_stmt (gsi);
-         if (gimple_code (stmt) == GIMPLE_CALL)
+         if (gimple_code (stmt) == GIMPLE_CALL
+             && !gimple_inexpensive_call_p (as_a <gcall *>  (stmt)))
            {
              int flags = gimple_call_flags (stmt);
-             tree decl = gimple_call_fndecl (stmt);
-
-             if (decl && DECL_IS_BUILTIN (decl)
-                 && is_inexpensive_builtin (decl))
-               ;
-             else if (flags & (ECF_PURE | ECF_CONST))
+             if (flags & (ECF_PURE | ECF_CONST))
                size->num_pure_calls_on_hot_path++;
              else
                size->num_non_pure_calls_on_hot_path++;
              size->num_branches_on_hot_path ++;
            }
-         else if (gimple_code (stmt) != GIMPLE_CALL
-                  && gimple_code (stmt) != GIMPLE_DEBUG)
+         /* Count inexpensive calls as non-calls, because they will likely
+            expand inline.  */
+         else if (gimple_code (stmt) != GIMPLE_DEBUG)
            size->non_call_stmts_on_hot_path++;
          if (((gimple_code (stmt) == GIMPLE_COND
                && (!constant_after_peeling (gimple_cond_lhs (stmt), stmt, loop)
-                   || constant_after_peeling (gimple_cond_rhs (stmt), stmt, loop)))
+                   || constant_after_peeling (gimple_cond_rhs (stmt), stmt,
+                                              loop)))
               || (gimple_code (stmt) == GIMPLE_SWITCH
                   && !constant_after_peeling (gimple_switch_index (
                                                 as_a <gswitch *> (stmt)),