diff options
author | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-11-27 22:09:10 +0000 |
---|---|---|
committer | rth <rth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2001-11-27 22:09:10 +0000 |
commit | 691b0a39ab31115e163f824d42657a831aacc500 (patch) | |
tree | dff365973b7e8ce8692d894aee674e1c1466698c /gcc/doloop.c | |
parent | ffaa56d8468e7779e93217dfae0521a508f9afc6 (diff) | |
download | gcc-691b0a39ab31115e163f824d42657a831aacc500.tar.gz |
* unroll.c (loop_iterations): Move last change ...
* doloop.c (doloop_modify_runtime): ... here.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@47387 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/doloop.c')
-rw-r--r-- | gcc/doloop.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/gcc/doloop.c b/gcc/doloop.c index 2b1317f900a..be232d63e6c 100644 --- a/gcc/doloop.c +++ b/gcc/doloop.c @@ -596,6 +596,46 @@ doloop_modify_runtime (loop, iterations_max, copy_rtx (neg_inc ? final_value : initial_value), NULL_RTX, unsigned_p, OPTAB_LIB_WIDEN); + /* Some code transformations can result in code akin to + + tmp = i + 1; + ... + goto scan_start; + top: + tmp = tmp + 1; + scan_start: + i = tmp; + if (i < n) goto top; + + We'll have already detected this form of loop in scan_loop, + and set loop->top and loop->scan_start appropriately. + + In this situation, we skip the increment the first time through + the loop, which results in an incorrect estimate of the number + of iterations. Adjust the difference to compensate. */ + /* ??? Logically, it would seem this belongs in loop_iterations. + However, this causes regressions e.g. on x86 execute/20011008-3.c, + so I do not believe we've properly characterized the exact nature + of the problem. In the meantime, this fixes execute/20011126-2.c + on ia64 and some Ada front end miscompilation on ppc. */ + + if (loop->scan_start) + { + struct loop_ivs *ivs = LOOP_IVS (loop); + struct iv_class *bl + = REG_IV_CLASS (ivs, REGNO (loop_info->iteration_var)); + + if (INSN_LUID (bl->biv->insn) < INSN_LUID (loop->scan_start)) + { + if (loop_dump_stream) + fprintf (loop_dump_stream, + "Doloop: Basic induction var skips initial incr.\n"); + + diff = expand_simple_binop (mode, PLUS, diff, increment, diff, + unsigned_p, OPTAB_LIB_WIDEN); + } + } + if (abs_inc * loop_info->unroll_number != 1) { int shift_count; |