projects
/
platform
/
upstream
/
gcc48.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Imported Upstream version 4.8.1
[platform/upstream/gcc48.git]
/
gcc
/
loop-doloop.c
diff --git
a/gcc/loop-doloop.c
b/gcc/loop-doloop.c
index
5f64569
..
b47901b
100644
(file)
--- a/
gcc/loop-doloop.c
+++ b/
gcc/loop-doloop.c
@@
-1,6
+1,5
@@
/* Perform doloop optimizations
/* Perform doloop optimizations
- Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
- Free Software Foundation, Inc.
+ Copyright (C) 2004-2013 Free Software Foundation, Inc.
Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
This file is part of GCC.
Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
This file is part of GCC.
@@
-31,9
+30,9
@@
along with GCC; see the file COPYING3. If not see
#include "diagnostic-core.h"
#include "tm_p.h"
#include "cfgloop.h"
#include "diagnostic-core.h"
#include "tm_p.h"
#include "cfgloop.h"
-#include "output.h"
#include "params.h"
#include "target.h"
#include "params.h"
#include "target.h"
+#include "dumpfile.h"
/* This module is used to modify loops with a determinable number of
iterations to use special low-overhead looping instructions.
/* This module is used to modify loops with a determinable number of
iterations to use special low-overhead looping instructions.
@@
-410,6
+409,7
@@
doloop_modify (struct loop *loop, struct niter_desc *desc,
basic_block loop_end = desc->out_edge->src;
enum machine_mode mode;
rtx true_prob_val;
basic_block loop_end = desc->out_edge->src;
enum machine_mode mode;
rtx true_prob_val;
+ double_int iterations;
jump_insn = BB_END (loop_end);
jump_insn = BB_END (loop_end);
@@
-460,9
+460,10
@@
doloop_modify (struct loop *loop, struct niter_desc *desc,
/* Determine if the iteration counter will be non-negative.
Note that the maximum value loaded is iterations_max - 1. */
/* Determine if the iteration counter will be non-negative.
Note that the maximum value loaded is iterations_max - 1. */
- if (desc->niter_max
- <= ((unsigned HOST_WIDEST_INT) 1
- << (GET_MODE_PRECISION (mode) - 1)))
+ if (max_loop_iterations (loop, &iterations)
+ && (iterations.ule (double_int_one.llshift
+ (GET_MODE_PRECISION (mode) - 1,
+ GET_MODE_PRECISION (mode)))))
nonneg = 1;
break;
nonneg = 1;
break;
@@
-548,10
+549,19
@@
doloop_modify (struct loop *loop, struct niter_desc *desc,
{
rtx init;
unsigned level = get_loop_level (loop) + 1;
{
rtx init;
unsigned level = get_loop_level (loop) + 1;
+ double_int iter;
+ rtx iter_rtx;
+
+ if (!max_loop_iterations (loop, &iter)
+ || !iter.fits_shwi ())
+ iter_rtx = const0_rtx;
+ else
+ iter_rtx = GEN_INT (iter.to_shwi());
init = gen_doloop_begin (counter_reg,
desc->const_iter ? desc->niter_expr : const0_rtx,
init = gen_doloop_begin (counter_reg,
desc->const_iter ? desc->niter_expr : const0_rtx,
- GEN_INT (desc->niter_max),
- GEN_INT (level));
+ iter_rtx,
+ GEN_INT (level),
+ doloop_seq);
if (init)
{
start_sequence ();
if (init)
{
start_sequence ();
@@
-608,6
+618,8
@@
doloop_optimize (struct loop *loop)
struct niter_desc *desc;
unsigned word_mode_size;
unsigned HOST_WIDE_INT word_mode_max;
struct niter_desc *desc;
unsigned word_mode_size;
unsigned HOST_WIDE_INT word_mode_max;
+ double_int iter;
+ int entered_at_top;
if (dump_file)
fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
if (dump_file)
fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num);
@@
-658,7
+670,11
@@
doloop_optimize (struct loop *loop)
count = copy_rtx (desc->niter_expr);
iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
count = copy_rtx (desc->niter_expr);
iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
- iterations_max = GEN_INT (desc->niter_max);
+ if (!max_loop_iterations (loop, &iter)
+ || !iter.fits_shwi ())
+ iterations_max = const0_rtx;
+ else
+ iterations_max = GEN_INT (iter.to_shwi());
level = get_loop_level (loop) + 1;
/* Generate looping insn. If the pattern FAILs then give up trying
level = get_loop_level (loop) + 1;
/* Generate looping insn. If the pattern FAILs then give up trying
@@
-666,8
+682,11
@@
doloop_optimize (struct loop *loop)
not like. */
start_label = block_label (desc->in_edge->dest);
doloop_reg = gen_reg_rtx (mode);
not like. */
start_label = block_label (desc->in_edge->dest);
doloop_reg = gen_reg_rtx (mode);
+ entered_at_top = (loop->latch == desc->in_edge->dest
+ && contains_no_active_insn_p (loop->latch));
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
- GEN_INT (level), start_label);
+ GEN_INT (level), start_label,
+ GEN_INT (entered_at_top));
word_mode_size = GET_MODE_PRECISION (word_mode);
word_mode_max
word_mode_size = GET_MODE_PRECISION (word_mode);
word_mode_max
@@
-678,7
+697,7
@@
doloop_optimize (struct loop *loop)
computed, we must be sure that the number of iterations fits into
the new mode. */
&& (word_mode_size >= GET_MODE_PRECISION (mode)
computed, we must be sure that the number of iterations fits into
the new mode. */
&& (word_mode_size >= GET_MODE_PRECISION (mode)
- ||
desc->niter_max <= word_mode_max
))
+ ||
iter.ule (double_int::from_shwi (word_mode_max))
))
{
if (word_mode_size > GET_MODE_PRECISION (mode))
{
{
if (word_mode_size > GET_MODE_PRECISION (mode))
{
@@
-697,7
+716,8
@@
doloop_optimize (struct loop *loop)
}
PUT_MODE (doloop_reg, word_mode);
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
}
PUT_MODE (doloop_reg, word_mode);
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
- GEN_INT (level), start_label);
+ GEN_INT (level), start_label,
+ GEN_INT (entered_at_top));
}
if (! doloop_seq)
{
}
if (! doloop_seq)
{
@@
-747,7
+767,6
@@
doloop_optimize_loops (void)
iv_analysis_done ();
#ifdef ENABLE_CHECKING
iv_analysis_done ();
#ifdef ENABLE_CHECKING
- verify_dominators (CDI_DOMINATORS);
verify_loop_structure ();
#endif
}
verify_loop_structure ();
#endif
}