/* 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.
#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
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
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;
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)
}
/* 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);
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);
}
{
set = single_set (seq);
if (set)
- cost += rtx_cost (set, SET, speed);
+ cost += set_rtx_cost (set, speed);
else
cost++;
}
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
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
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;
}
}
+/* 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;
+}