/* Perform doloop optimizations
- Copyright (C) 2004 Free Software Foundation, Inc.
+ Copyright (C) 2004, 2005 Free Software Foundation, Inc.
Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
This file is part of GCC.
#include "cfgloop.h"
#include "output.h"
#include "params.h"
+#include "target.h"
/* This module is used to modify loops with a determinable number of
iterations to use special low-overhead looping instructions.
insn != NEXT_INSN (BB_END (bb));
insn = NEXT_INSN (insn))
{
- /* A called function may clobber any special registers required for
- low-overhead looping. */
- if (CALL_P (insn))
- {
- if (dump_file)
- fprintf (dump_file, "Doloop: Function call in loop.\n");
+ /* Different targets have different necessities for low-overhead
+ looping. Call the back end for each instruction within the loop
+ to let it decide whether the insn is valid. */
+ if (!targetm.insn_valid_within_doloop (insn))
+ {
result = false;
goto cleanup;
- }
-
- /* Some targets (eg, PPC) use the count register for branch on table
- instructions. ??? This should be a target specific check. */
- if (JUMP_P (insn)
- && (GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC
- || GET_CODE (PATTERN (insn)) == ADDR_VEC))
- {
- if (dump_file)
- fprintf (dump_file, "Doloop: Computed branch in the loop.\n");
- result = false;
- goto cleanup;
- }
+ }
}
}
result = true;
{
case NE:
/* Currently only NE tests against zero and one are supported. */
- if (XEXP (condition, 1) == const1_rtx)
+ noloop = XEXP (condition, 1);
+ if (noloop != const0_rtx)
{
+ gcc_assert (noloop == const1_rtx);
increment_count = true;
- noloop = const1_rtx;
}
- else if (XEXP (condition, 1) == const0_rtx)
- noloop = const0_rtx;
- else
- abort ();
break;
case GE:
/* Currently only GE tests against zero are supported. */
- if (XEXP (condition, 1) != const0_rtx)
- abort ();
+ gcc_assert (XEXP (condition, 1) == const0_rtx);
noloop = constm1_rtx;
/* Abort if an invalid doloop pattern has been generated. */
default:
- abort ();
+ gcc_unreachable ();
}
if (increment_count)
/* Expand the condition testing the assumptions and if it does not pass,
reset the count register to 0. */
add_test (XEXP (ass, 0), preheader, set_zero);
- EDGE_SUCC (preheader, 0)->flags &= ~EDGE_FALLTHRU;
- cnt = EDGE_SUCC (preheader, 0)->count;
- EDGE_SUCC (preheader, 0)->probability = 0;
- EDGE_SUCC (preheader, 0)->count = 0;
- irr = EDGE_SUCC (preheader, 0)->flags & EDGE_IRREDUCIBLE_LOOP;
+ single_succ_edge (preheader)->flags &= ~EDGE_FALLTHRU;
+ cnt = single_succ_edge (preheader)->count;
+ single_succ_edge (preheader)->probability = 0;
+ single_succ_edge (preheader)->count = 0;
+ irr = single_succ_edge (preheader)->flags & EDGE_IRREDUCIBLE_LOOP;
te = make_edge (preheader, new_preheader, EDGE_FALLTHRU | irr);
te->probability = REG_BR_PROB_BASE;
te->count = cnt;
for (ass = XEXP (ass, 1); ass; ass = XEXP (ass, 1))
{
bb = loop_split_edge_with (te, NULL_RTX);
- te = EDGE_SUCC (bb, 0);
+ te = single_succ_edge (bb);
add_test (XEXP (ass, 0), bb, set_zero);
make_edge (bb, set_zero, irr);
}