150826Smdodd/* Perform doloop optimizations
250826Smdodd   Copyright (C) 2004, 2005 Free Software Foundation, Inc.
350826Smdodd   Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
450826Smdodd
550826SmdoddThis file is part of GCC.
650826Smdodd
750826SmdoddGCC is free software; you can redistribute it and/or modify it under
850826Smdoddthe terms of the GNU General Public License as published by the Free
950826SmdoddSoftware Foundation; either version 2, or (at your option) any later
1050826Smdoddversion.
1150826Smdodd
1250826SmdoddGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1350826SmdoddWARRANTY; without even the implied warranty of MERCHANTABILITY or
1450826SmdoddFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1550826Smdoddfor more details.
1650826Smdodd
1750826SmdoddYou should have received a copy of the GNU General Public License
1850826Smdoddalong with GCC; see the file COPYING.  If not, write to the Free
1950826SmdoddSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2050826Smdodd02110-1301, USA.  */
2150826Smdodd
2250826Smdodd#include "config.h"
2350826Smdodd#include "system.h"
2450826Smdodd#include "coretypes.h"
2550826Smdodd#include "tm.h"
2650826Smdodd#include "rtl.h"
2750826Smdodd#include "flags.h"
2850826Smdodd#include "expr.h"
2950826Smdodd#include "hard-reg-set.h"
3050826Smdodd#include "basic-block.h"
3150826Smdodd#include "toplev.h"
3250826Smdodd#include "tm_p.h"
3350826Smdodd#include "cfgloop.h"
3450826Smdodd#include "output.h"
3550826Smdodd#include "params.h"
3650826Smdodd#include "target.h"
3750826Smdodd
3850826Smdodd/* This module is used to modify loops with a determinable number of
3950826Smdodd   iterations to use special low-overhead looping instructions.
4050826Smdodd
4150826Smdodd   It first validates whether the loop is well behaved and has a
4250826Smdodd   determinable number of iterations (either at compile or run-time).
4350826Smdodd   It then modifies the loop to use a low-overhead looping pattern as
4450826Smdodd   follows:
4550826Smdodd
4650826Smdodd   1. A pseudo register is allocated as the loop iteration counter.
4750826Smdodd
4850826Smdodd   2. The number of loop iterations is calculated and is stored
4950826Smdodd      in the loop counter.
5050826Smdodd
5150826Smdodd   3. At the end of the loop, the jump insn is replaced by the
5250826Smdodd      doloop_end pattern.  The compare must remain because it might be
5350826Smdodd      used elsewhere.  If the loop-variable or condition register are
5450826Smdodd      used elsewhere, they will be eliminated by flow.
5550826Smdodd
5650826Smdodd   4. An optional doloop_begin pattern is inserted at the top of the
5750826Smdodd      loop.
5850826Smdodd
5950826Smdodd   TODO The optimization should only performed when either the biv used for exit
6050826Smdodd   condition is unused at all except for the exit test, or if we do not have to
6150826Smdodd   change its value, since otherwise we have to add a new induction variable,
6250826Smdodd   which usually will not pay up (unless the cost of the doloop pattern is
6350826Smdodd   somehow extremely lower than the cost of compare & jump, or unless the bct
6450826Smdodd   register cannot be used for anything else but doloop -- ??? detect these
6550826Smdodd   cases).  */
6650826Smdodd
6750826Smdodd#ifdef HAVE_doloop_end
6850826Smdodd
6950826Smdodd/* Return the loop termination condition for PATTERN or zero
7050826Smdodd   if it is not a decrement and branch jump insn.  */
7150826Smdodd
7250826Smdoddrtx
7350826Smdodddoloop_condition_get (rtx pattern)
7450826Smdodd{
7550826Smdodd  rtx cmp;
7650826Smdodd  rtx inc;
7750826Smdodd  rtx reg;
7850826Smdodd  rtx inc_src;
7950826Smdodd  rtx condition;
8050826Smdodd
8150826Smdodd  /* The canonical doloop pattern we expect is:
8250826Smdodd
8350826Smdodd     (parallel [(set (pc) (if_then_else (condition)
8450826Smdodd                                        (label_ref (label))
8550826Smdodd                                        (pc)))
8650826Smdodd                (set (reg) (plus (reg) (const_int -1)))
8750826Smdodd                (additional clobbers and uses)])
8850826Smdodd
8950826Smdodd     Some targets (IA-64) wrap the set of the loop counter in
9050826Smdodd     an if_then_else too.
9150826Smdodd
9250826Smdodd     In summary, the branch must be the first entry of the
9350826Smdodd     parallel (also required by jump.c), and the second
9450826Smdodd     entry of the parallel must be a set of the loop counter
9550826Smdodd     register.  */
9650826Smdodd
9750826Smdodd  if (GET_CODE (pattern) != PARALLEL)
9850826Smdodd    return 0;
9950826Smdodd
10050826Smdodd  cmp = XVECEXP (pattern, 0, 0);
10150826Smdodd  inc = XVECEXP (pattern, 0, 1);
10250826Smdodd
10350826Smdodd  /* Check for (set (reg) (something)).  */
10450826Smdodd  if (GET_CODE (inc) != SET)
10550826Smdodd    return 0;
10650826Smdodd  reg = SET_DEST (inc);
10750826Smdodd  if (! REG_P (reg))
10850826Smdodd    return 0;
10952050Smdodd
11052050Smdodd  /* Check if something = (plus (reg) (const_int -1)).
11152050Smdodd     On IA-64, this decrement is wrapped in an if_then_else.  */
11250826Smdodd  inc_src = SET_SRC (inc);
11352050Smdodd  if (GET_CODE (inc_src) == IF_THEN_ELSE)
11450826Smdodd    inc_src = XEXP (inc_src, 1);
11550826Smdodd  if (GET_CODE (inc_src) != PLUS
11650826Smdodd      || XEXP (inc_src, 0) != reg
11750826Smdodd      || XEXP (inc_src, 1) != constm1_rtx)
11850826Smdodd    return 0;
11950826Smdodd
12050826Smdodd  /* Check for (set (pc) (if_then_else (condition)
12150826Smdodd                                       (label_ref (label))
12250826Smdodd                                       (pc))).  */
12352050Smdodd  if (GET_CODE (cmp) != SET
12452050Smdodd      || SET_DEST (cmp) != pc_rtx
12550826Smdodd      || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
12652050Smdodd      || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
12750826Smdodd      || XEXP (SET_SRC (cmp), 2) != pc_rtx)
12852050Smdodd    return 0;
12950826Smdodd
13052050Smdodd  /* Extract loop termination condition.  */
13152050Smdodd  condition = XEXP (SET_SRC (cmp), 0);
13250826Smdodd
13352050Smdodd  /* We expect a GE or NE comparison with 0 or 1.  */
13452050Smdodd  if ((GET_CODE (condition) != GE
13552050Smdodd       && GET_CODE (condition) != NE)
13652050Smdodd      || (XEXP (condition, 1) != const0_rtx
13752050Smdodd          && XEXP (condition, 1) != const1_rtx))
13852050Smdodd    return 0;
13952050Smdodd
14052050Smdodd  if ((XEXP (condition, 0) == reg)
14152050Smdodd      || (GET_CODE (XEXP (condition, 0)) == PLUS
14252050Smdodd		   && XEXP (XEXP (condition, 0), 0) == reg))
14352050Smdodd    return condition;
14452050Smdodd
14552050Smdodd  /* ??? If a machine uses a funny comparison, we could return a
14652050Smdodd     canonicalized form here.  */
14750826Smdodd
14850826Smdodd  return 0;
14950826Smdodd}
15050826Smdodd
15150826Smdodd/* Return nonzero if the loop specified by LOOP is suitable for
15250826Smdodd   the use of special low-overhead looping instructions.  DESC
15350826Smdodd   describes the number of iterations of the loop.  */
15450826Smdodd
15550826Smdoddstatic bool
15650826Smdodddoloop_valid_p (struct loop *loop, struct niter_desc *desc)
15750826Smdodd{
15850826Smdodd  basic_block *body = get_loop_body (loop), bb;
15950826Smdodd  rtx insn;
16050826Smdodd  unsigned i;
16150826Smdodd  bool result = true;
16250826Smdodd
16350826Smdodd  /* Check for loops that may not terminate under special conditions.  */
16450826Smdodd  if (!desc->simple_p
16550826Smdodd      || desc->assumptions
16650826Smdodd      || desc->infinite)
16750826Smdodd    {
16850826Smdodd      /* There are some cases that would require a special attention.
16950826Smdodd	 For example if the comparison is LEU and the comparison value
17050826Smdodd	 is UINT_MAX then the loop will not terminate.  Similarly, if the
17150826Smdodd	 comparison code is GEU and the comparison value is 0, the
17250826Smdodd	 loop will not terminate.
17350826Smdodd
17450826Smdodd	 If the absolute increment is not 1, the loop can be infinite
17550826Smdodd	 even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
17650826Smdodd
17750826Smdodd	 ??? We could compute these conditions at run-time and have a
17850826Smdodd	 additional jump around the loop to ensure an infinite loop.
17950826Smdodd	 However, it is very unlikely that this is the intended
18050826Smdodd	 behavior of the loop and checking for these rare boundary
18150826Smdodd	 conditions would pessimize all other code.
18250826Smdodd
18350826Smdodd	 If the loop is executed only a few times an extra check to
18450826Smdodd	 restart the loop could use up most of the benefits of using a
18550826Smdodd	 count register loop.  Note however, that normally, this
18651675Smdodd	 restart branch would never execute, so it could be predicted
18750826Smdodd	 well by the CPU.  We should generate the pessimistic code by
18850826Smdodd	 default, and have an option, e.g. -funsafe-loops that would
18952050Smdodd	 enable count-register loops in this case.  */
19050826Smdodd      if (dump_file)
19150826Smdodd	fprintf (dump_file, "Doloop: Possible infinite iteration case.\n");
19250826Smdodd      result = false;
19350826Smdodd      goto cleanup;
19450826Smdodd    }
19550826Smdodd
19650826Smdodd  for (i = 0; i < loop->num_nodes; i++)
19750826Smdodd    {
19850826Smdodd      bb = body[i];
19950826Smdodd
20050826Smdodd      for (insn = BB_HEAD (bb);
20150826Smdodd	   insn != NEXT_INSN (BB_END (bb));
20250826Smdodd	   insn = NEXT_INSN (insn))
20350826Smdodd	{
20450826Smdodd	  /* Different targets have different necessities for low-overhead
20550826Smdodd	     looping.  Call the back end for each instruction within the loop
20650826Smdodd	     to let it decide whether the insn prohibits a low-overhead loop.
20750826Smdodd	     It will then return the cause for it to emit to the dump file.  */
20850826Smdodd	  const char * invalid = targetm.invalid_within_doloop (insn);
20950826Smdodd	  if (invalid)
21050826Smdodd	    {
21150826Smdodd	      if (dump_file)
21252050Smdodd		fprintf (dump_file, "Doloop: %s\n", invalid);
21350826Smdodd	      result = false;
21450826Smdodd	      goto cleanup;
21550826Smdodd	    }
21650826Smdodd	}
21750826Smdodd    }
21850826Smdodd  result = true;
21950826Smdodd
22050826Smdoddcleanup:
22150826Smdodd  free (body);
22250826Smdodd
22350826Smdodd  return result;
22450826Smdodd}
22550826Smdodd
22650826Smdodd/* Adds test of COND jumping to DEST on edge *E and set *E to the new fallthru
22750826Smdodd   edge.  If the condition is always false, do not do anything.  If it is always
22850826Smdodd   true, redirect E to DEST and return false.  In all other cases, true is
22950826Smdodd   returned.  */
23050826Smdodd
23150826Smdoddstatic bool
23250826Smdoddadd_test (rtx cond, edge *e, basic_block dest)
23350826Smdodd{
23450826Smdodd  rtx seq, jump, label;
23550826Smdodd  enum machine_mode mode;
23650826Smdodd  rtx op0 = XEXP (cond, 0), op1 = XEXP (cond, 1);
23750826Smdodd  enum rtx_code code = GET_CODE (cond);
23850826Smdodd  basic_block bb;
23950826Smdodd
24050826Smdodd  mode = GET_MODE (XEXP (cond, 0));
24150826Smdodd  if (mode == VOIDmode)
24250826Smdodd    mode = GET_MODE (XEXP (cond, 1));
24350826Smdodd
24450826Smdodd  start_sequence ();
24550826Smdodd  op0 = force_operand (op0, NULL_RTX);
24650826Smdodd  op1 = force_operand (op1, NULL_RTX);
24750826Smdodd  label = block_label (dest);
24850826Smdodd  do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label);
24950826Smdodd
25050826Smdodd  jump = get_last_insn ();
25150826Smdodd  if (!JUMP_P (jump))
25250826Smdodd    {
25350826Smdodd      /* The condition is always false and the jump was optimized out.  */
25450826Smdodd      end_sequence ();
25550826Smdodd      return true;
25650826Smdodd    }
25750826Smdodd
25850826Smdodd  seq = get_insns ();
25950826Smdodd  end_sequence ();
26050826Smdodd  bb = loop_split_edge_with (*e, seq);
26150826Smdodd  *e = single_succ_edge (bb);
26250826Smdodd
26350826Smdodd  if (any_uncondjump_p (jump))
26450826Smdodd    {
26550826Smdodd      /* The condition is always true.  */
26650826Smdodd      delete_insn (jump);
26750826Smdodd      redirect_edge_and_branch_force (*e, dest);
26850826Smdodd      return false;
26950826Smdodd    }
27050826Smdodd
27150826Smdodd  JUMP_LABEL (jump) = label;
27250826Smdodd
27350826Smdodd  /* The jump is supposed to handle an unlikely special case.  */
27450826Smdodd  REG_NOTES (jump)
27550826Smdodd	  = gen_rtx_EXPR_LIST (REG_BR_PROB,
27650826Smdodd			       const0_rtx, REG_NOTES (jump));
27750826Smdodd  LABEL_NUSES (label)++;
27850826Smdodd
27950826Smdodd  make_edge (bb, dest, (*e)->flags & ~EDGE_FALLTHRU);
28050826Smdodd  return true;
28150826Smdodd}
28250826Smdodd
28350826Smdodd/* Modify the loop to use the low-overhead looping insn where LOOP
28450826Smdodd   describes the loop, DESC describes the number of iterations of the
28550826Smdodd   loop, and DOLOOP_INSN is the low-overhead looping insn to emit at the
28650826Smdodd   end of the loop.  CONDITION is the condition separated from the
28750826Smdodd   DOLOOP_SEQ.  COUNT is the number of iterations of the LOOP.  */
28850826Smdodd
28950826Smdoddstatic void
29050826Smdodddoloop_modify (struct loop *loop, struct niter_desc *desc,
29150826Smdodd	       rtx doloop_seq, rtx condition, rtx count)
29250826Smdodd{
29350826Smdodd  rtx counter_reg;
29450826Smdodd  rtx tmp, noloop = NULL_RTX;
29550826Smdodd  rtx sequence;
29650826Smdodd  rtx jump_insn;
29750826Smdodd  rtx jump_label;
29850826Smdodd  int nonneg = 0;
29950826Smdodd  bool increment_count;
30050826Smdodd  basic_block loop_end = desc->out_edge->src;
30150826Smdodd  enum machine_mode mode;
30250826Smdodd
30350826Smdodd  jump_insn = BB_END (loop_end);
30450826Smdodd
30550826Smdodd  if (dump_file)
30650826Smdodd    {
30750826Smdodd      fprintf (dump_file, "Doloop: Inserting doloop pattern (");
30850826Smdodd      if (desc->const_iter)
30950826Smdodd	fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter);
31050826Smdodd      else
31150826Smdodd	fputs ("runtime", dump_file);
31250826Smdodd      fputs (" iterations).\n", dump_file);
31350826Smdodd    }
31450826Smdodd
31550826Smdodd  /* Discard original jump to continue loop.  The original compare
31650826Smdodd     result may still be live, so it cannot be discarded explicitly.  */
31750826Smdodd  delete_insn (jump_insn);
31850826Smdodd
31950826Smdodd  counter_reg = XEXP (condition, 0);
32050826Smdodd  if (GET_CODE (counter_reg) == PLUS)
32150826Smdodd    counter_reg = XEXP (counter_reg, 0);
32250826Smdodd  mode = GET_MODE (counter_reg);
32350826Smdodd
32450826Smdodd  increment_count = false;
32550826Smdodd  switch (GET_CODE (condition))
32650826Smdodd    {
32750826Smdodd    case NE:
32850826Smdodd      /* Currently only NE tests against zero and one are supported.  */
329      noloop = XEXP (condition, 1);
330      if (noloop != const0_rtx)
331	{
332	  gcc_assert (noloop == const1_rtx);
333	  increment_count = true;
334	}
335      break;
336
337    case GE:
338      /* Currently only GE tests against zero are supported.  */
339      gcc_assert (XEXP (condition, 1) == const0_rtx);
340
341      noloop = constm1_rtx;
342
343      /* The iteration count does not need incrementing for a GE test.  */
344      increment_count = false;
345
346      /* Determine if the iteration counter will be non-negative.
347	 Note that the maximum value loaded is iterations_max - 1.  */
348      if (desc->niter_max
349	  <= ((unsigned HOST_WIDEST_INT) 1
350	      << (GET_MODE_BITSIZE (mode) - 1)))
351	nonneg = 1;
352      break;
353
354      /* Abort if an invalid doloop pattern has been generated.  */
355    default:
356      gcc_unreachable ();
357    }
358
359  if (increment_count)
360    count = simplify_gen_binary (PLUS, mode, count, const1_rtx);
361
362  /* Insert initialization of the count register into the loop header.  */
363  start_sequence ();
364  tmp = force_operand (count, counter_reg);
365  convert_move (counter_reg, tmp, 1);
366  sequence = get_insns ();
367  end_sequence ();
368  emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
369
370  if (desc->noloop_assumptions)
371    {
372      rtx ass = copy_rtx (desc->noloop_assumptions);
373      basic_block preheader = loop_preheader_edge (loop)->src;
374      basic_block set_zero
375	      = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
376      basic_block new_preheader
377	      = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
378      edge te;
379
380      /* Expand the condition testing the assumptions and if it does not pass,
381	 reset the count register to 0.  */
382      redirect_edge_and_branch_force (single_succ_edge (preheader), new_preheader);
383      set_immediate_dominator (CDI_DOMINATORS, new_preheader, preheader);
384
385      set_zero->count = 0;
386      set_zero->frequency = 0;
387
388      te = single_succ_edge (preheader);
389      for (; ass; ass = XEXP (ass, 1))
390	if (!add_test (XEXP (ass, 0), &te, set_zero))
391	  break;
392
393      if (ass)
394	{
395	  /* We reached a condition that is always true.  This is very hard to
396	     reproduce (such a loop does not roll, and thus it would most
397	     likely get optimized out by some of the preceding optimizations).
398	     In fact, I do not have any testcase for it.  However, it would
399	     also be very hard to show that it is impossible, so we must
400	     handle this case.  */
401	  set_zero->count = preheader->count;
402	  set_zero->frequency = preheader->frequency;
403	}
404
405      if (EDGE_COUNT (set_zero->preds) == 0)
406	{
407	  /* All the conditions were simplified to false, remove the
408	     unreachable set_zero block.  */
409	  remove_bb_from_loops (set_zero);
410	  delete_basic_block (set_zero);
411	}
412      else
413	{
414	  /* Reset the counter to zero in the set_zero block.  */
415	  start_sequence ();
416	  convert_move (counter_reg, noloop, 0);
417	  sequence = get_insns ();
418	  end_sequence ();
419	  emit_insn_after (sequence, BB_END (set_zero));
420
421	  set_immediate_dominator (CDI_DOMINATORS, set_zero,
422				   recount_dominator (CDI_DOMINATORS,
423						      set_zero));
424	}
425
426      set_immediate_dominator (CDI_DOMINATORS, new_preheader,
427			       recount_dominator (CDI_DOMINATORS,
428						  new_preheader));
429    }
430
431  /* Some targets (eg, C4x) need to initialize special looping
432     registers.  */
433#ifdef HAVE_doloop_begin
434  {
435    rtx init;
436    unsigned level = get_loop_level (loop) + 1;
437    init = gen_doloop_begin (counter_reg,
438			     desc->const_iter ? desc->niter_expr : const0_rtx,
439			     GEN_INT (desc->niter_max),
440			     GEN_INT (level));
441    if (init)
442      {
443	start_sequence ();
444	emit_insn (init);
445	sequence = get_insns ();
446	end_sequence ();
447	emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
448      }
449  }
450#endif
451
452  /* Insert the new low-overhead looping insn.  */
453  emit_jump_insn_after (doloop_seq, BB_END (loop_end));
454  jump_insn = BB_END (loop_end);
455  jump_label = block_label (desc->in_edge->dest);
456  JUMP_LABEL (jump_insn) = jump_label;
457  LABEL_NUSES (jump_label)++;
458
459  /* Ensure the right fallthru edge is marked, for case we have reversed
460     the condition.  */
461  desc->in_edge->flags &= ~EDGE_FALLTHRU;
462  desc->out_edge->flags |= EDGE_FALLTHRU;
463
464  /* Add a REG_NONNEG note if the actual or estimated maximum number
465     of iterations is non-negative.  */
466  if (nonneg)
467    {
468      REG_NOTES (jump_insn)
469	= gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn));
470    }
471}
472
473/* Process loop described by LOOP validating that the loop is suitable for
474   conversion to use a low overhead looping instruction, replacing the jump
475   insn where suitable.  Returns true if the loop was successfully
476   modified.  */
477
478static bool
479doloop_optimize (struct loop *loop)
480{
481  enum machine_mode mode;
482  rtx doloop_seq, doloop_pat, doloop_reg;
483  rtx iterations, count;
484  rtx iterations_max;
485  rtx start_label;
486  rtx condition;
487  unsigned level, est_niter;
488  struct niter_desc *desc;
489  unsigned word_mode_size;
490  unsigned HOST_WIDE_INT word_mode_max;
491
492  if (dump_file)
493    fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
494
495  iv_analysis_loop_init (loop);
496
497  /* Find the simple exit of a LOOP.  */
498  desc = get_simple_loop_desc (loop);
499
500  /* Check that loop is a candidate for a low-overhead looping insn.  */
501  if (!doloop_valid_p (loop, desc))
502    {
503      if (dump_file)
504	fprintf (dump_file,
505		 "Doloop: The loop is not suitable.\n");
506      return false;
507    }
508  mode = desc->mode;
509
510  est_niter = 3;
511  if (desc->const_iter)
512    est_niter = desc->niter;
513  /* If the estimate on number of iterations is reliable (comes from profile
514     feedback), use it.  Do not use it normally, since the expected number
515     of iterations of an unrolled loop is 2.  */
516  if (loop->header->count)
517    est_niter = expected_loop_iterations (loop);
518
519  if (est_niter < 3)
520    {
521      if (dump_file)
522	fprintf (dump_file,
523		 "Doloop: Too few iterations (%u) to be profitable.\n",
524		 est_niter);
525      return false;
526    }
527
528  count = copy_rtx (desc->niter_expr);
529  iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
530  iterations_max = GEN_INT (desc->niter_max);
531  level = get_loop_level (loop) + 1;
532
533  /* Generate looping insn.  If the pattern FAILs then give up trying
534     to modify the loop since there is some aspect the back-end does
535     not like.  */
536  start_label = block_label (desc->in_edge->dest);
537  doloop_reg = gen_reg_rtx (mode);
538  doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
539			       GEN_INT (level), start_label);
540
541  word_mode_size = GET_MODE_BITSIZE (word_mode);
542  word_mode_max
543	  = ((unsigned HOST_WIDE_INT) 1 << (word_mode_size - 1) << 1) - 1;
544  if (! doloop_seq
545      && mode != word_mode
546      /* Before trying mode different from the one in that # of iterations is
547	 computed, we must be sure that the number of iterations fits into
548	 the new mode.  */
549      && (word_mode_size >= GET_MODE_BITSIZE (mode)
550	  || desc->niter_max <= word_mode_max))
551    {
552      if (word_mode_size > GET_MODE_BITSIZE (mode))
553	{
554	  count = simplify_gen_unary (ZERO_EXTEND, word_mode,
555				      count, mode);
556	  iterations = simplify_gen_unary (ZERO_EXTEND, word_mode,
557					   iterations, mode);
558	  iterations_max = simplify_gen_unary (ZERO_EXTEND, word_mode,
559					       iterations_max, mode);
560	}
561      else
562	{
563	  count = lowpart_subreg (word_mode, count, mode);
564	  iterations = lowpart_subreg (word_mode, iterations, mode);
565	  iterations_max = lowpart_subreg (word_mode, iterations_max, mode);
566	}
567      PUT_MODE (doloop_reg, word_mode);
568      doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
569				   GEN_INT (level), start_label);
570    }
571  if (! doloop_seq)
572    {
573      if (dump_file)
574	fprintf (dump_file,
575		 "Doloop: Target unwilling to use doloop pattern!\n");
576      return false;
577    }
578
579  /* If multiple instructions were created, the last must be the
580     jump instruction.  Also, a raw define_insn may yield a plain
581     pattern.  */
582  doloop_pat = doloop_seq;
583  if (INSN_P (doloop_pat))
584    {
585      while (NEXT_INSN (doloop_pat) != NULL_RTX)
586	doloop_pat = NEXT_INSN (doloop_pat);
587      if (JUMP_P (doloop_pat))
588	doloop_pat = PATTERN (doloop_pat);
589      else
590	doloop_pat = NULL_RTX;
591    }
592
593  if (! doloop_pat
594      || ! (condition = doloop_condition_get (doloop_pat)))
595    {
596      if (dump_file)
597	fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n");
598      return false;
599    }
600
601  doloop_modify (loop, desc, doloop_seq, condition, count);
602  return true;
603}
604
605/* This is the main entry point.  Process all LOOPS using doloop_optimize.  */
606
607void
608doloop_optimize_loops (struct loops *loops)
609{
610  unsigned i;
611  struct loop *loop;
612
613  for (i = 1; i < loops->num; i++)
614    {
615      loop = loops->parray[i];
616      if (!loop)
617	continue;
618
619      doloop_optimize (loop);
620    }
621
622  iv_analysis_done ();
623
624#ifdef ENABLE_CHECKING
625  verify_dominators (CDI_DOMINATORS);
626  verify_loop_structure (loops);
627#endif
628}
629#endif /* HAVE_doloop_end */
630
631