]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cfgloopanal.c
re PR objc++/60398 (FAIL: obj-c++.dg/invalid-method-2.mm -fgnu-runtime (test for...
[gcc.git] / gcc / cfgloopanal.c
index 853e6f22dd43b9c58d9427fa39fba317301c336c..e01b9ccbec4c396ff018fe9ba5a90490ea27afea 100644 (file)
@@ -1,6 +1,5 @@
 /* Natural loop analysis code for GNU compiler.
-   Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
-   Free Software Foundation, Inc.
+   Copyright (C) 2002-2014 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -28,10 +27,14 @@ along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "cfgloop.h"
 #include "expr.h"
-#include "output.h"
 #include "graphds.h"
 #include "params.h"
 
+struct target_cfgloop default_target_cfgloop;
+#if SWITCHABLE_TARGET
+struct target_cfgloop *this_target_cfgloop = &default_target_cfgloop;
+#endif
+
 /* Checks whether BB is executed exactly once in each LOOP iteration.  */
 
 bool
@@ -61,7 +64,7 @@ just_once_each_iteration_p (const struct loop *loop, const_basic_block bb)
 
    LOOPS is the loop tree.  */
 
-#define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block)
+#define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block_for_fn (cfun))
 #define BB_REPR(BB) ((BB)->index + 1)
 
 bool
@@ -74,7 +77,7 @@ mark_irreducible_loops (void)
   int src, dest;
   unsigned depth;
   struct graph *g;
-  int num = number_of_loops ();
+  int num = number_of_loops (cfun);
   struct loop *cloop;
   bool irred_loop_found = false;
   int i;
@@ -82,7 +85,8 @@ mark_irreducible_loops (void)
   gcc_assert (current_loops != NULL);
 
   /* Reset the flags.  */
-  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR_FOR_FN (cfun),
+                 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
     {
       act->flags &= ~BB_IRREDUCIBLE_LOOP;
       FOR_EACH_EDGE (e, ei, act->succs)
@@ -90,13 +94,14 @@ mark_irreducible_loops (void)
     }
 
   /* Create the edge lists.  */
-  g = new_graph (last_basic_block + num);
+  g = new_graph (last_basic_block_for_fn (cfun) + num);
 
-  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
+  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR_FOR_FN (cfun),
+                 EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb)
     FOR_EACH_EDGE (e, ei, act->succs)
       {
        /* Ignore edges to exit.  */
-       if (e->dest == EXIT_BLOCK_PTR)
+       if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
          continue;
 
        src = BB_REPR (act);
@@ -125,7 +130,7 @@ mark_irreducible_loops (void)
            if (depth == loop_depth (act->loop_father))
              cloop = act->loop_father;
            else
-             cloop = VEC_index (loop_p, act->loop_father->superloops, depth);
+             cloop = (*act->loop_father->superloops)[depth];
 
            src = LOOP_REPR (cloop);
          }
@@ -309,7 +314,7 @@ seq_cost (const_rtx seq, bool speed)
     {
       set = single_set (seq);
       if (set)
-       cost += rtx_cost (set, SET, speed);
+       cost += set_rtx_cost (set, speed);
       else
        cost++;
     }
@@ -317,19 +322,6 @@ seq_cost (const_rtx seq, bool speed)
   return cost;
 }
 
-/* The properties of the target.  */
-
-unsigned target_avail_regs;    /* Number of available registers.  */
-unsigned target_clobbered_regs; /* Number of available registers that are
-                                  call-clobbered.  */
-unsigned target_res_regs;      /* Number of registers reserved for temporary
-                                  expressions.  */
-unsigned target_reg_cost[2];   /* The cost for register when there still
-                                  is some reserve, but we are approaching
-                                  the number of available registers.  */
-unsigned target_spill_cost[2]; /* The cost for register when we need
-                                  to spill.  */
-
 /* Initialize the constants for computing set costs.  */
 
 void
@@ -419,7 +411,7 @@ estimate_reg_pressure_cost (unsigned n_new, unsigned n_old, bool speed,
 
   if (optimize && (flag_ira_region == IRA_REGION_ALL
                   || flag_ira_region == IRA_REGION_MIXED)
-      && number_of_loops () <= (unsigned) IRA_MAX_LOOPS_NUM)
+      && number_of_loops (cfun) <= (unsigned) IRA_MAX_LOOPS_NUM)
     /* IRA regional allocation deals with high register pressure
        better.  So decrease the cost (to do more accurate the cost
        calculation for IRA, we need to know how many registers lives
@@ -437,10 +429,10 @@ mark_loop_exit_edges (void)
   basic_block bb;
   edge e;
 
-  if (number_of_loops () <= 1)
+  if (number_of_loops (cfun) <= 1)
     return;
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     {
       edge_iterator ei;
 
@@ -455,3 +447,73 @@ mark_loop_exit_edges (void)
     }
 }
 
+/* Return exit edge if loop has only one exit that is likely
+   to be executed on runtime (i.e. it is not EH or leading
+   to noreturn call.  */
+
+edge
+single_likely_exit (struct loop *loop)
+{
+  edge found = single_exit (loop);
+  vec<edge> exits;
+  unsigned i;
+  edge ex;
+
+  if (found)
+    return found;
+  exits = get_loop_exit_edges (loop);
+  FOR_EACH_VEC_ELT (exits, i, ex)
+    {
+      if (ex->flags & (EDGE_EH | EDGE_ABNORMAL_CALL))
+       continue;
+      /* The constant of 5 is set in a way so noreturn calls are
+        ruled out by this test.  The static branch prediction algorithm
+         will not assign such a low probability to conditionals for usual
+         reasons.  */
+      if (profile_status_for_fn (cfun) != PROFILE_ABSENT
+         && ex->probability < 5 && !ex->count)
+       continue;
+      if (!found)
+       found = ex;
+      else
+       {
+         exits.release ();
+         return NULL;
+       }
+    }
+  exits.release ();
+  return found;
+}
+
+
+/* Gets basic blocks of a LOOP.  Header is the 0-th block, rest is in dfs
+   order against direction of edges from latch.  Specially, if
+   header != latch, latch is the 1-st block.  */
+
+vec<basic_block>
+get_loop_hot_path (const struct loop *loop)
+{
+  basic_block bb = loop->header;
+  vec<basic_block> path = vNULL;
+  bitmap visited = BITMAP_ALLOC (NULL);
+
+  while (true)
+    {
+      edge_iterator ei;
+      edge e;
+      edge best = NULL;
+
+      path.safe_push (bb);
+      bitmap_set_bit (visited, bb->index);
+      FOR_EACH_EDGE (e, ei, bb->succs)
+        if ((!best || e->probability > best->probability)
+           && !loop_exit_edge_p (loop, e)
+           && !bitmap_bit_p (visited, e->dest->index))
+         best = e;
+      if (!best || best->dest == loop->header)
+       break;
+      bb = best->dest;
+    }
+  BITMAP_FREE (visited);
+  return path;
+}
This page took 0.038123 seconds and 5 git commands to generate.