mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 15:00:55 +08:00
re PR rtl-optimization/17791 (doloop can produce wrong code causes Ada bootstrap failure)
PR rtl-optimization/17791 * loop-doloop.c (doloop_modify): Take number of iterations as argument. (doloop_optimize): Extend or shorten the number of iterations when changing mode of counter register. * loop-iv.c (lowpart_subreg): Export. * rtl.h (lowpart_subreg): Declare. From-SVN: r88668
This commit is contained in:
parent
1313b31fbb
commit
a82bbcbbbe
@ -1,3 +1,13 @@
|
||||
2004-10-07 Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
PR rtl-optimization/17791
|
||||
* loop-doloop.c (doloop_modify): Take number of iterations as
|
||||
argument.
|
||||
(doloop_optimize): Extend or shorten the number of iterations
|
||||
when changing mode of counter register.
|
||||
* loop-iv.c (lowpart_subreg): Export.
|
||||
* rtl.h (lowpart_subreg): Declare.
|
||||
|
||||
2004-10-07 Zdenek Dvorak <dvorakz@suse.cz>
|
||||
|
||||
PR tree-optimization/17806
|
||||
|
@ -257,20 +257,21 @@ add_test (rtx cond, basic_block bb, basic_block dest)
|
||||
describes the loop, DESC describes the number of iterations of the
|
||||
loop, and DOLOOP_INSN is the low-overhead looping insn to emit at the
|
||||
end of the loop. CONDITION is the condition separated from the
|
||||
DOLOOP_SEQ. */
|
||||
DOLOOP_SEQ. COUNT is the number of iterations of the LOOP. */
|
||||
|
||||
static void
|
||||
doloop_modify (struct loop *loop, struct niter_desc *desc,
|
||||
rtx doloop_seq, rtx condition)
|
||||
rtx doloop_seq, rtx condition, rtx count)
|
||||
{
|
||||
rtx counter_reg;
|
||||
rtx count, tmp, noloop = NULL_RTX;
|
||||
rtx tmp, noloop = NULL_RTX;
|
||||
rtx sequence;
|
||||
rtx jump_insn;
|
||||
rtx jump_label;
|
||||
int nonneg = 0, irr;
|
||||
bool increment_count;
|
||||
basic_block loop_end = desc->out_edge->src;
|
||||
enum machine_mode mode;
|
||||
|
||||
jump_insn = BB_END (loop_end);
|
||||
|
||||
@ -291,8 +292,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
|
||||
counter_reg = XEXP (condition, 0);
|
||||
if (GET_CODE (counter_reg) == PLUS)
|
||||
counter_reg = XEXP (counter_reg, 0);
|
||||
mode = GET_MODE (counter_reg);
|
||||
|
||||
count = copy_rtx (desc->niter_expr);
|
||||
increment_count = false;
|
||||
switch (GET_CODE (condition))
|
||||
{
|
||||
@ -323,7 +324,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
|
||||
Note that the maximum value loaded is iterations_max - 1. */
|
||||
if (desc->niter_max
|
||||
<= ((unsigned HOST_WIDEST_INT) 1
|
||||
<< (GET_MODE_BITSIZE (GET_MODE (counter_reg)) - 1)))
|
||||
<< (GET_MODE_BITSIZE (mode) - 1)))
|
||||
nonneg = 1;
|
||||
break;
|
||||
|
||||
@ -333,7 +334,7 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
|
||||
}
|
||||
|
||||
if (increment_count)
|
||||
count = simplify_gen_binary (PLUS, desc->mode, count, const1_rtx);
|
||||
count = simplify_gen_binary (PLUS, mode, count, const1_rtx);
|
||||
|
||||
/* Insert initialization of the count register into the loop header. */
|
||||
start_sequence ();
|
||||
@ -438,12 +439,14 @@ doloop_optimize (struct loop *loop)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx doloop_seq, doloop_pat, doloop_reg;
|
||||
rtx iterations;
|
||||
rtx iterations, count;
|
||||
rtx iterations_max;
|
||||
rtx start_label;
|
||||
rtx condition;
|
||||
unsigned level, est_niter;
|
||||
struct niter_desc *desc;
|
||||
unsigned word_mode_size;
|
||||
unsigned HOST_WIDE_INT word_mode_max;
|
||||
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
|
||||
@ -481,6 +484,7 @@ doloop_optimize (struct loop *loop)
|
||||
return false;
|
||||
}
|
||||
|
||||
count = copy_rtx (desc->niter_expr);
|
||||
iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
|
||||
iterations_max = GEN_INT (desc->niter_max);
|
||||
level = get_loop_level (loop) + 1;
|
||||
@ -492,8 +496,33 @@ doloop_optimize (struct loop *loop)
|
||||
doloop_reg = gen_reg_rtx (mode);
|
||||
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
|
||||
GEN_INT (level), start_label);
|
||||
if (! doloop_seq && mode != word_mode)
|
||||
|
||||
word_mode_size = GET_MODE_BITSIZE (word_mode);
|
||||
word_mode_max
|
||||
= ((unsigned HOST_WIDE_INT) 1 << (word_mode_size - 1) << 1) - 1;
|
||||
if (! doloop_seq
|
||||
&& mode != word_mode
|
||||
/* Before trying mode different from the one in that # of iterations is
|
||||
computed, we must be sure that the number of iterations fits into
|
||||
the new mode. */
|
||||
&& (word_mode_size >= GET_MODE_BITSIZE (mode)
|
||||
|| desc->niter_max <= word_mode_max))
|
||||
{
|
||||
if (word_mode_size > GET_MODE_BITSIZE (mode))
|
||||
{
|
||||
count = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
iterations, mode);
|
||||
iterations = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
iterations, mode);
|
||||
iterations_max = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
iterations_max, mode);
|
||||
}
|
||||
else
|
||||
{
|
||||
count = lowpart_subreg (word_mode, count, mode);
|
||||
iterations = lowpart_subreg (word_mode, iterations, mode);
|
||||
iterations_max = lowpart_subreg (word_mode, iterations_max, mode);
|
||||
}
|
||||
PUT_MODE (doloop_reg, word_mode);
|
||||
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
|
||||
GEN_INT (level), start_label);
|
||||
@ -528,7 +557,7 @@ doloop_optimize (struct loop *loop)
|
||||
return false;
|
||||
}
|
||||
|
||||
doloop_modify (loop, desc, doloop_seq, condition);
|
||||
doloop_modify (loop, desc, doloop_seq, condition, count);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -156,7 +156,7 @@ assign_luids (basic_block bb)
|
||||
/* Generates a subreg to get the least significant part of EXPR (in mode
|
||||
INNER_MODE) to OUTER_MODE. */
|
||||
|
||||
static rtx
|
||||
rtx
|
||||
lowpart_subreg (enum machine_mode outer_mode, rtx expr,
|
||||
enum machine_mode inner_mode)
|
||||
{
|
||||
|
@ -1432,6 +1432,10 @@ extern void push_to_full_sequence (rtx, rtx);
|
||||
extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
|
||||
enum machine_mode);
|
||||
|
||||
/* In loop-iv.c */
|
||||
|
||||
extern rtx lowpart_subreg (enum machine_mode, rtx, enum machine_mode);
|
||||
|
||||
/* In varasm.c */
|
||||
extern rtx force_const_mem (enum machine_mode, rtx);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user