1132718Skan/* Natural loop analysis code for GNU compiler.
2169689Skan   Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
3132718Skan
4132718SkanThis file is part of GCC.
5132718Skan
6132718SkanGCC is free software; you can redistribute it and/or modify it under
7132718Skanthe terms of the GNU General Public License as published by the Free
8132718SkanSoftware Foundation; either version 2, or (at your option) any later
9132718Skanversion.
10132718Skan
11132718SkanGCC is distributed in the hope that it will be useful, but WITHOUT ANY
12132718SkanWARRANTY; without even the implied warranty of MERCHANTABILITY or
13132718SkanFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14132718Skanfor more details.
15132718Skan
16132718SkanYou should have received a copy of the GNU General Public License
17132718Skanalong with GCC; see the file COPYING.  If not, write to the Free
18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
19169689Skan02110-1301, USA.  */
20132718Skan
21132718Skan#include "config.h"
22132718Skan#include "system.h"
23132718Skan#include "coretypes.h"
24132718Skan#include "tm.h"
25132718Skan#include "rtl.h"
26132718Skan#include "hard-reg-set.h"
27169689Skan#include "obstack.h"
28132718Skan#include "basic-block.h"
29132718Skan#include "cfgloop.h"
30132718Skan#include "expr.h"
31132718Skan#include "output.h"
32132718Skan
33169689Skan/* Checks whether BB is executed exactly once in each LOOP iteration.  */
34132718Skan
35132718Skanbool
36169689Skanjust_once_each_iteration_p (const struct loop *loop, basic_block bb)
37132718Skan{
38132718Skan  /* It must be executed at least once each iteration.  */
39132718Skan  if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
40132718Skan    return false;
41132718Skan
42132718Skan  /* And just once.  */
43132718Skan  if (bb->loop_father != loop)
44132718Skan    return false;
45132718Skan
46132718Skan  /* But this was not enough.  We might have some irreducible loop here.  */
47132718Skan  if (bb->flags & BB_IRREDUCIBLE_LOOP)
48132718Skan    return false;
49132718Skan
50132718Skan  return true;
51132718Skan}
52132718Skan
53169689Skan/* Structure representing edge of a graph.  */
54132718Skan
55169689Skanstruct edge
56132718Skan{
57169689Skan  int src, dest;	/* Source and destination.  */
58169689Skan  struct edge *pred_next, *succ_next;
59169689Skan			/* Next edge in predecessor and successor lists.  */
60169689Skan  void *data;		/* Data attached to the edge.  */
61169689Skan};
62132718Skan
63169689Skan/* Structure representing vertex of a graph.  */
64169689Skan
65169689Skanstruct vertex
66132718Skan{
67169689Skan  struct edge *pred, *succ;
68169689Skan			/* Lists of predecessors and successors.  */
69169689Skan  int component;	/* Number of dfs restarts before reaching the
70169689Skan			   vertex.  */
71169689Skan  int post;		/* Postorder number.  */
72169689Skan};
73132718Skan
74169689Skan/* Structure representing a graph.  */
75132718Skan
76169689Skanstruct graph
77132718Skan{
78169689Skan  int n_vertices;	/* Number of vertices.  */
79169689Skan  struct vertex *vertices;
80169689Skan			/* The vertices.  */
81132718Skan};
82132718Skan
83169689Skan/* Dumps graph G into F.  */
84132718Skan
85169689Skanextern void dump_graph (FILE *, struct graph *);
86132718Skan
87169689Skanvoid
88169689Skandump_graph (FILE *f, struct graph *g)
89132718Skan{
90132718Skan  int i;
91169689Skan  struct edge *e;
92132718Skan
93169689Skan  for (i = 0; i < g->n_vertices; i++)
94132718Skan    {
95169689Skan      if (!g->vertices[i].pred
96169689Skan	  && !g->vertices[i].succ)
97169689Skan	continue;
98132718Skan
99169689Skan      fprintf (f, "%d (%d)\t<-", i, g->vertices[i].component);
100169689Skan      for (e = g->vertices[i].pred; e; e = e->pred_next)
101169689Skan	fprintf (f, " %d", e->src);
102169689Skan      fprintf (f, "\n");
103132718Skan
104169689Skan      fprintf (f, "\t->");
105169689Skan      for (e = g->vertices[i].succ; e; e = e->succ_next)
106169689Skan	fprintf (f, " %d", e->dest);
107169689Skan      fprintf (f, "\n");
108132718Skan    }
109132718Skan}
110132718Skan
111169689Skan/* Creates a new graph with N_VERTICES vertices.  */
112132718Skan
113169689Skanstatic struct graph *
114169689Skannew_graph (int n_vertices)
115132718Skan{
116169689Skan  struct graph *g = XNEW (struct graph);
117132718Skan
118169689Skan  g->n_vertices = n_vertices;
119169689Skan  g->vertices = XCNEWVEC (struct vertex, n_vertices);
120132718Skan
121169689Skan  return g;
122132718Skan}
123132718Skan
124169689Skan/* Adds an edge from F to T to graph G, with DATA attached.  */
125132718Skan
126169689Skanstatic void
127169689Skanadd_edge (struct graph *g, int f, int t, void *data)
128132718Skan{
129169689Skan  struct edge *e = xmalloc (sizeof (struct edge));
130132718Skan
131169689Skan  e->src = f;
132169689Skan  e->dest = t;
133169689Skan  e->data = data;
134132718Skan
135169689Skan  e->pred_next = g->vertices[t].pred;
136169689Skan  g->vertices[t].pred = e;
137132718Skan
138169689Skan  e->succ_next = g->vertices[f].succ;
139169689Skan  g->vertices[f].succ = e;
140132718Skan}
141132718Skan
142169689Skan/* Runs dfs search over vertices of G, from NQ vertices in queue QS.
143169689Skan   The vertices in postorder are stored into QT.  If FORWARD is false,
144169689Skan   backward dfs is run.  */
145132718Skan
146169689Skanstatic void
147169689Skandfs (struct graph *g, int *qs, int nq, int *qt, bool forward)
148132718Skan{
149169689Skan  int i, tick = 0, v, comp = 0, top;
150169689Skan  struct edge *e;
151169689Skan  struct edge **stack = xmalloc (sizeof (struct edge *) * g->n_vertices);
152132718Skan
153169689Skan  for (i = 0; i < g->n_vertices; i++)
154132718Skan    {
155169689Skan      g->vertices[i].component = -1;
156169689Skan      g->vertices[i].post = -1;
157132718Skan    }
158132718Skan
159169689Skan#define FST_EDGE(V) (forward ? g->vertices[(V)].succ : g->vertices[(V)].pred)
160169689Skan#define NEXT_EDGE(E) (forward ? (E)->succ_next : (E)->pred_next)
161169689Skan#define EDGE_SRC(E) (forward ? (E)->src : (E)->dest)
162169689Skan#define EDGE_DEST(E) (forward ? (E)->dest : (E)->src)
163132718Skan
164169689Skan  for (i = 0; i < nq; i++)
165132718Skan    {
166169689Skan      v = qs[i];
167169689Skan      if (g->vertices[v].post != -1)
168132718Skan	continue;
169132718Skan
170169689Skan      g->vertices[v].component = comp++;
171169689Skan      e = FST_EDGE (v);
172169689Skan      top = 0;
173132718Skan
174169689Skan      while (1)
175169689Skan	{
176169689Skan	  while (e && g->vertices[EDGE_DEST (e)].component != -1)
177169689Skan	    e = NEXT_EDGE (e);
178132718Skan
179169689Skan	  if (!e)
180169689Skan	    {
181169689Skan	      if (qt)
182169689Skan		qt[tick] = v;
183169689Skan	      g->vertices[v].post = tick++;
184132718Skan
185169689Skan	      if (!top)
186169689Skan		break;
187132718Skan
188169689Skan	      e = stack[--top];
189169689Skan	      v = EDGE_SRC (e);
190169689Skan	      e = NEXT_EDGE (e);
191169689Skan	      continue;
192169689Skan	    }
193132718Skan
194169689Skan	  stack[top++] = e;
195169689Skan	  v = EDGE_DEST (e);
196169689Skan	  e = FST_EDGE (v);
197169689Skan	  g->vertices[v].component = comp - 1;
198132718Skan	}
199132718Skan    }
200132718Skan
201169689Skan  free (stack);
202132718Skan}
203132718Skan
204169689Skan/* Marks the edge E in graph G irreducible if it connects two vertices in the
205169689Skan   same scc.  */
206132718Skan
207169689Skanstatic void
208169689Skancheck_irred (struct graph *g, struct edge *e)
209132718Skan{
210169689Skan  edge real = e->data;
211132718Skan
212169689Skan  /* All edges should lead from a component with higher number to the
213169689Skan     one with lower one.  */
214169689Skan  gcc_assert (g->vertices[e->src].component >= g->vertices[e->dest].component);
215132718Skan
216169689Skan  if (g->vertices[e->src].component != g->vertices[e->dest].component)
217169689Skan    return;
218132718Skan
219169689Skan  real->flags |= EDGE_IRREDUCIBLE_LOOP;
220169689Skan  if (flow_bb_inside_loop_p (real->src->loop_father, real->dest))
221169689Skan    real->src->flags |= BB_IRREDUCIBLE_LOOP;
222132718Skan}
223132718Skan
224169689Skan/* Runs CALLBACK for all edges in G.  */
225132718Skan
226169689Skanstatic void
227169689Skanfor_each_edge (struct graph *g,
228169689Skan	       void (callback) (struct graph *, struct edge *))
229132718Skan{
230169689Skan  struct edge *e;
231169689Skan  int i;
232132718Skan
233169689Skan  for (i = 0; i < g->n_vertices; i++)
234169689Skan    for (e = g->vertices[i].succ; e; e = e->succ_next)
235169689Skan      callback (g, e);
236132718Skan}
237132718Skan
238169689Skan/* Releases the memory occupied by G.  */
239132718Skan
240169689Skanstatic void
241169689Skanfree_graph (struct graph *g)
242132718Skan{
243169689Skan  struct edge *e, *n;
244169689Skan  int i;
245132718Skan
246169689Skan  for (i = 0; i < g->n_vertices; i++)
247169689Skan    for (e = g->vertices[i].succ; e; e = n)
248169689Skan      {
249169689Skan	n = e->succ_next;
250169689Skan	free (e);
251169689Skan      }
252169689Skan  free (g->vertices);
253169689Skan  free (g);
254132718Skan}
255132718Skan
256132718Skan/* Marks blocks and edges that are part of non-recognized loops; i.e. we
257132718Skan   throw away all latch edges and mark blocks inside any remaining cycle.
258132718Skan   Everything is a bit complicated due to fact we do not want to do this
259132718Skan   for parts of cycles that only "pass" through some loop -- i.e. for
260132718Skan   each cycle, we want to mark blocks that belong directly to innermost
261169689Skan   loop containing the whole cycle.
262169689Skan
263169689Skan   LOOPS is the loop tree.  */
264169689Skan
265169689Skan#define LOOP_REPR(LOOP) ((LOOP)->num + last_basic_block)
266169689Skan#define BB_REPR(BB) ((BB)->index + 1)
267169689Skan
268132718Skanvoid
269132718Skanmark_irreducible_loops (struct loops *loops)
270132718Skan{
271132718Skan  basic_block act;
272169689Skan  edge e;
273169689Skan  edge_iterator ei;
274169689Skan  int i, src, dest;
275169689Skan  struct graph *g;
276169689Skan  int *queue1 = XNEWVEC (int, last_basic_block + loops->num);
277169689Skan  int *queue2 = XNEWVEC (int, last_basic_block + loops->num);
278169689Skan  int nq, depth;
279132718Skan  struct loop *cloop;
280132718Skan
281132718Skan  /* Reset the flags.  */
282132718Skan  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
283132718Skan    {
284132718Skan      act->flags &= ~BB_IRREDUCIBLE_LOOP;
285169689Skan      FOR_EACH_EDGE (e, ei, act->succs)
286132718Skan	e->flags &= ~EDGE_IRREDUCIBLE_LOOP;
287132718Skan    }
288132718Skan
289169689Skan  /* Create the edge lists.  */
290169689Skan  g = new_graph (last_basic_block + loops->num);
291132718Skan
292132718Skan  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
293169689Skan    FOR_EACH_EDGE (e, ei, act->succs)
294132718Skan      {
295169689Skan	/* Ignore edges to exit.  */
296169689Skan	if (e->dest == EXIT_BLOCK_PTR)
297132718Skan	  continue;
298169689Skan
299132718Skan	/* And latch edges.  */
300132718Skan	if (e->dest->loop_father->header == e->dest
301132718Skan	    && e->dest->loop_father->latch == act)
302132718Skan	  continue;
303169689Skan
304132718Skan	/* Edges inside a single loop should be left where they are.  Edges
305132718Skan	   to subloop headers should lead to representative of the subloop,
306169689Skan	   but from the same place.
307169689Skan
308169689Skan	   Edges exiting loops should lead from representative
309132718Skan	   of the son of nearest common ancestor of the loops in that
310132718Skan	   act lays.  */
311132718Skan
312169689Skan	src = BB_REPR (act);
313169689Skan	dest = BB_REPR (e->dest);
314132718Skan
315169689Skan	if (e->dest->loop_father->header == e->dest)
316169689Skan	  dest = LOOP_REPR (e->dest->loop_father);
317169689Skan
318169689Skan	if (!flow_bb_inside_loop_p (act->loop_father, e->dest))
319132718Skan	  {
320169689Skan	    depth = find_common_loop (act->loop_father,
321169689Skan				      e->dest->loop_father)->depth + 1;
322169689Skan	    if (depth == act->loop_father->depth)
323169689Skan	      cloop = act->loop_father;
324169689Skan	    else
325169689Skan	      cloop = act->loop_father->pred[depth];
326169689Skan
327169689Skan	    src = LOOP_REPR (cloop);
328132718Skan	  }
329169689Skan
330169689Skan	add_edge (g, src, dest, e);
331132718Skan      }
332132718Skan
333169689Skan  /* Find the strongly connected components.  Use the algorithm of Tarjan --
334169689Skan     first determine the postorder dfs numbering in reversed graph, then
335169689Skan     run the dfs on the original graph in the order given by decreasing
336169689Skan     numbers assigned by the previous pass.  */
337169689Skan  nq = 0;
338169689Skan  FOR_BB_BETWEEN (act, ENTRY_BLOCK_PTR, EXIT_BLOCK_PTR, next_bb)
339132718Skan    {
340169689Skan      queue1[nq++] = BB_REPR (act);
341132718Skan    }
342169689Skan  for (i = 1; i < (int) loops->num; i++)
343132718Skan    if (loops->parray[i])
344169689Skan      queue1[nq++] = LOOP_REPR (loops->parray[i]);
345169689Skan  dfs (g, queue1, nq, queue2, false);
346169689Skan  for (i = 0; i < nq; i++)
347169689Skan    queue1[i] = queue2[nq - i - 1];
348169689Skan  dfs (g, queue1, nq, NULL, true);
349132718Skan
350169689Skan  /* Mark the irreducible loops.  */
351169689Skan  for_each_edge (g, check_irred);
352132718Skan
353169689Skan  free_graph (g);
354169689Skan  free (queue1);
355169689Skan  free (queue2);
356132718Skan
357132718Skan  loops->state |= LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS;
358132718Skan}
359132718Skan
360132718Skan/* Counts number of insns inside LOOP.  */
361132718Skanint
362132718Skannum_loop_insns (struct loop *loop)
363132718Skan{
364132718Skan  basic_block *bbs, bb;
365132718Skan  unsigned i, ninsns = 0;
366132718Skan  rtx insn;
367132718Skan
368132718Skan  bbs = get_loop_body (loop);
369132718Skan  for (i = 0; i < loop->num_nodes; i++)
370132718Skan    {
371132718Skan      bb = bbs[i];
372132718Skan      ninsns++;
373132718Skan      for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
374132718Skan	if (INSN_P (insn))
375132718Skan	  ninsns++;
376132718Skan    }
377132718Skan  free(bbs);
378132718Skan
379132718Skan  return ninsns;
380132718Skan}
381132718Skan
382132718Skan/* Counts number of insns executed on average per iteration LOOP.  */
383132718Skanint
384132718Skanaverage_num_loop_insns (struct loop *loop)
385132718Skan{
386132718Skan  basic_block *bbs, bb;
387132718Skan  unsigned i, binsns, ninsns, ratio;
388132718Skan  rtx insn;
389132718Skan
390132718Skan  ninsns = 0;
391132718Skan  bbs = get_loop_body (loop);
392132718Skan  for (i = 0; i < loop->num_nodes; i++)
393132718Skan    {
394132718Skan      bb = bbs[i];
395132718Skan
396132718Skan      binsns = 1;
397132718Skan      for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
398132718Skan	if (INSN_P (insn))
399132718Skan	  binsns++;
400132718Skan
401132718Skan      ratio = loop->header->frequency == 0
402132718Skan	      ? BB_FREQ_MAX
403132718Skan	      : (bb->frequency * BB_FREQ_MAX) / loop->header->frequency;
404132718Skan      ninsns += binsns * ratio;
405132718Skan    }
406132718Skan  free(bbs);
407132718Skan
408132718Skan  ninsns /= BB_FREQ_MAX;
409132718Skan  if (!ninsns)
410132718Skan    ninsns = 1; /* To avoid division by zero.  */
411132718Skan
412132718Skan  return ninsns;
413132718Skan}
414132718Skan
415132718Skan/* Returns expected number of LOOP iterations.
416132718Skan   Compute upper bound on number of iterations in case they do not fit integer
417132718Skan   to help loop peeling heuristics.  Use exact counts if at all possible.  */
418132718Skanunsigned
419132718Skanexpected_loop_iterations (const struct loop *loop)
420132718Skan{
421132718Skan  edge e;
422169689Skan  edge_iterator ei;
423132718Skan
424169689Skan  if (loop->latch->count || loop->header->count)
425132718Skan    {
426132718Skan      gcov_type count_in, count_latch, expected;
427132718Skan
428132718Skan      count_in = 0;
429132718Skan      count_latch = 0;
430132718Skan
431169689Skan      FOR_EACH_EDGE (e, ei, loop->header->preds)
432132718Skan	if (e->src == loop->latch)
433132718Skan	  count_latch = e->count;
434132718Skan	else
435132718Skan	  count_in += e->count;
436132718Skan
437132718Skan      if (count_in == 0)
438169689Skan	expected = count_latch * 2;
439169689Skan      else
440169689Skan	expected = (count_latch + count_in - 1) / count_in;
441132718Skan
442132718Skan      /* Avoid overflows.  */
443132718Skan      return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
444132718Skan    }
445132718Skan  else
446132718Skan    {
447132718Skan      int freq_in, freq_latch;
448132718Skan
449132718Skan      freq_in = 0;
450132718Skan      freq_latch = 0;
451132718Skan
452169689Skan      FOR_EACH_EDGE (e, ei, loop->header->preds)
453132718Skan	if (e->src == loop->latch)
454132718Skan	  freq_latch = EDGE_FREQUENCY (e);
455132718Skan	else
456132718Skan	  freq_in += EDGE_FREQUENCY (e);
457132718Skan
458132718Skan      if (freq_in == 0)
459169689Skan	return freq_latch * 2;
460132718Skan
461132718Skan      return (freq_latch + freq_in - 1) / freq_in;
462132718Skan    }
463132718Skan}
464132718Skan
465169689Skan/* Returns the maximum level of nesting of subloops of LOOP.  */
466169689Skan
467169689Skanunsigned
468169689Skanget_loop_level (const struct loop *loop)
469132718Skan{
470169689Skan  const struct loop *ploop;
471169689Skan  unsigned mx = 0, l;
472132718Skan
473169689Skan  for (ploop = loop->inner; ploop; ploop = ploop->next)
474169689Skan    {
475169689Skan      l = get_loop_level (ploop);
476169689Skan      if (l >= mx)
477169689Skan	mx = l + 1;
478169689Skan    }
479169689Skan  return mx;
480132718Skan}
481132718Skan
482169689Skan/* Returns estimate on cost of computing SEQ.  */
483169689Skan
484169689Skanstatic unsigned
485169689Skanseq_cost (rtx seq)
486132718Skan{
487169689Skan  unsigned cost = 0;
488132718Skan  rtx set;
489132718Skan
490169689Skan  for (; seq; seq = NEXT_INSN (seq))
491169689Skan    {
492169689Skan      set = single_set (seq);
493169689Skan      if (set)
494169689Skan	cost += rtx_cost (set, SET);
495169689Skan      else
496169689Skan	cost++;
497169689Skan    }
498132718Skan
499169689Skan  return cost;
500169689Skan}
501132718Skan
502169689Skan/* The properties of the target.  */
503132718Skan
504169689Skanunsigned target_avail_regs;	/* Number of available registers.  */
505169689Skanunsigned target_res_regs;	/* Number of reserved registers.  */
506169689Skanunsigned target_small_cost;	/* The cost for register when there is a free one.  */
507169689Skanunsigned target_pres_cost;	/* The cost for register when there are not too many
508169689Skan				   free ones.  */
509169689Skanunsigned target_spill_cost;	/* The cost for register when we need to spill.  */
510132718Skan
511169689Skan/* Initialize the constants for computing set costs.  */
512169689Skan
513169689Skanvoid
514169689Skaninit_set_costs (void)
515169689Skan{
516169689Skan  rtx seq;
517169689Skan  rtx reg1 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER);
518169689Skan  rtx reg2 = gen_raw_REG (SImode, FIRST_PSEUDO_REGISTER + 1);
519169689Skan  rtx addr = gen_raw_REG (Pmode, FIRST_PSEUDO_REGISTER + 2);
520169689Skan  rtx mem = validize_mem (gen_rtx_MEM (SImode, addr));
521169689Skan  unsigned i;
522169689Skan
523169689Skan  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
524169689Skan    if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
525169689Skan	&& !fixed_regs[i])
526169689Skan      target_avail_regs++;
527169689Skan
528169689Skan  target_res_regs = 3;
529169689Skan
530169689Skan  /* These are really just heuristic values.  */
531169689Skan
532169689Skan  start_sequence ();
533169689Skan  emit_move_insn (reg1, reg2);
534169689Skan  seq = get_insns ();
535169689Skan  end_sequence ();
536169689Skan  target_small_cost = seq_cost (seq);
537169689Skan  target_pres_cost = 2 * target_small_cost;
538169689Skan
539169689Skan  start_sequence ();
540169689Skan  emit_move_insn (mem, reg1);
541169689Skan  emit_move_insn (reg2, mem);
542169689Skan  seq = get_insns ();
543169689Skan  end_sequence ();
544169689Skan  target_spill_cost = seq_cost (seq);
545132718Skan}
546132718Skan
547169689Skan/* Calculates cost for having SIZE new loop global variables.  REGS_USED is the
548169689Skan   number of global registers used in loop.  N_USES is the number of relevant
549169689Skan   variable uses.  */
550169689Skan
551169689Skanunsigned
552169689Skanglobal_cost_for_size (unsigned size, unsigned regs_used, unsigned n_uses)
553169689Skan{
554169689Skan  unsigned regs_needed = regs_used + size;
555169689Skan  unsigned cost = 0;
556169689Skan
557169689Skan  if (regs_needed + target_res_regs <= target_avail_regs)
558169689Skan    cost += target_small_cost * size;
559169689Skan  else if (regs_needed <= target_avail_regs)
560169689Skan    cost += target_pres_cost * size;
561169689Skan  else
562169689Skan    {
563169689Skan      cost += target_pres_cost * size;
564169689Skan      cost += target_spill_cost * n_uses * (regs_needed - target_avail_regs) / regs_needed;
565169689Skan    }
566169689Skan
567169689Skan  return cost;
568169689Skan}
569169689Skan
570169689Skan/* Sets EDGE_LOOP_EXIT flag for all exits of LOOPS.  */
571169689Skan
572169689Skanvoid
573169689Skanmark_loop_exit_edges (struct loops *loops)
574169689Skan{
575169689Skan  basic_block bb;
576169689Skan  edge e;
577169689Skan
578169689Skan  if (loops->num <= 1)
579169689Skan    return;
580169689Skan
581169689Skan  FOR_EACH_BB (bb)
582169689Skan    {
583169689Skan      edge_iterator ei;
584169689Skan
585169689Skan      FOR_EACH_EDGE (e, ei, bb->succs)
586169689Skan	{
587169689Skan	  if (bb->loop_father->outer
588169689Skan	      && loop_exit_edge_p (bb->loop_father, e))
589169689Skan	    e->flags |= EDGE_LOOP_EXIT;
590169689Skan	  else
591169689Skan	    e->flags &= ~EDGE_LOOP_EXIT;
592169689Skan	}
593169689Skan    }
594169689Skan}
595169689Skan
596