loop-doloop.c (doloop_modify): Pass doloop_end pattern to gen_doloop_begin.

* loop-doloop.c (doloop_modify): Pass doloop_end pattern to
        gen_doloop_begin.
        (doloop_optimize): Pass flag to indicate if loop is entered at top
        to gen_doloop_end.
        * config/arm/thumb2.md (doloop_end): Accept extra operand.
        * config/bfin/bfin.md (doloop_end): Likewise.
        * config/c6x/c6x.md (doloop_end): Likewise.
        * config/ia64/ia64.md (doloop_end): Likewise.
        * config/mep/mep.md (doloop_begin, doloop_end): Likewise.
        * config/rs6000/rs6000.md (doloop_end): Likewise.
        * config/s390/s390.md (doloop_end): Likewise.
        * config/sh/sh.md (doloop_end): Likewise.
        * config/spu/spu.md (doloop_end): Likewise.
        * config/tilegx/tilegx.md (doloop_end): Likewise.
        * config/tilepro/tilepro.md (doloop_end): Likewise.
        * doc/md.texi (doloop_end): Document new operand.
        * basic-block.h (contains_no_active_insn_p): Declare.
        * cfgrtl.c (contains_no_active_insn_p): New function, factored
        out of ...
        (forwarder_block_p): ... here.

From-SVN: r192505
This commit is contained in:
Joern Rennecke 2012-10-16 16:11:00 +00:00 committed by Joern Rennecke
parent d919140b83
commit 2407343c3d
16 changed files with 88 additions and 26 deletions

View File

@ -1,3 +1,26 @@
2012-10-16 Joern Rennecke <joern.rennecke@embecosm.com>
* loop-doloop.c (doloop_modify): Pass doloop_end pattern to
gen_doloop_begin.
(doloop_optimize): Pass flag to indicate if loop is entered at top
to gen_doloop_end.
* config/arm/thumb2.md (doloop_end): Accept extra operand.
* config/bfin/bfin.md (doloop_end): Likewise.
* config/c6x/c6x.md (doloop_end): Likewise.
* config/ia64/ia64.md (doloop_end): Likewise.
* config/mep/mep.md (doloop_begin, doloop_end): Likewise.
* config/rs6000/rs6000.md (doloop_end): Likewise.
* config/s390/s390.md (doloop_end): Likewise.
* config/sh/sh.md (doloop_end): Likewise.
* config/spu/spu.md (doloop_end): Likewise.
* config/tilegx/tilegx.md (doloop_end): Likewise.
* config/tilepro/tilepro.md (doloop_end): Likewise.
* doc/md.texi (doloop_end): Document new operand.
* basic-block.h (contains_no_active_insn_p): Declare.
* cfgrtl.c (contains_no_active_insn_p): New function, factored
out of ...
(forwarder_block_p): ... here.
2012-10-16 Manuel López-Ibáñez <manu@gcc.gnu.org>
PR c/53063

View File

@ -802,6 +802,7 @@ extern bool purge_all_dead_edges (void);
extern bool purge_dead_edges (basic_block);
extern bool fixup_abnormal_edges (void);
extern basic_block force_nonfallthru_and_redirect (edge, basic_block, rtx);
extern bool contains_no_active_insn_p (const_basic_block);
extern bool forwarder_block_p (const_basic_block);
extern bool can_fallthru (basic_block, basic_block);

View File

@ -541,10 +541,9 @@ flow_active_insn_p (const_rtx insn)
/* Return true if the block has no effect and only forwards control flow to
its single destination. */
/* FIXME: Make this a cfg hook. */
bool
forwarder_block_p (const_basic_block bb)
contains_no_active_insn_p (const_basic_block bb)
{
rtx insn;
@ -552,6 +551,24 @@ forwarder_block_p (const_basic_block bb)
|| !single_succ_p (bb))
return false;
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
return (!INSN_P (insn)
|| (JUMP_P (insn) && simplejump_p (insn))
|| !flow_active_insn_p (insn));
}
/* Likewise, but protect loop latches, headers and preheaders. */
/* FIXME: Make this a cfg hook. */
bool
forwarder_block_p (const_basic_block bb)
{
if (!contains_no_active_insn_p (bb))
return false;
/* Protect loop latches, headers and preheaders. */
if (current_loops)
{
@ -563,13 +580,7 @@ forwarder_block_p (const_basic_block bb)
return false;
}
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = NEXT_INSN (insn))
if (INSN_P (insn) && flow_active_insn_p (insn))
return false;
return (!INSN_P (insn)
|| (JUMP_P (insn) && simplejump_p (insn))
|| !flow_active_insn_p (insn));
return true;
}
/* Return nonzero if we can reach target from src by falling through. */

View File

@ -996,7 +996,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
(use (match_operand 4 "" "")) ; label
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
"TARGET_32BIT"
"
{

View File

@ -1933,6 +1933,7 @@
; operand 2 is the maximum number of loop iterations
; operand 3 is the number of levels of enclosed loops
; operand 4 is the label to jump to at the top of the loop
; operand 5 indicates if the loop is entered at the top
(define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else
(ne (match_operand:SI 0 "" "")
@ -1943,7 +1944,7 @@
(plus:SI (match_dup 0)
(const_int -1)))
(unspec [(const_int 0)] UNSPEC_LSETUP_END)
(clobber (match_scratch:SI 5 ""))])]
(clobber (match_operand 5 ""))])] ; match_scratch
""
{
/* The loop optimizer doesn't check the predicates... */
@ -1956,6 +1957,7 @@
&& (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
FAIL;
bfin_hardware_loop ();
operands[5] = gen_rtx_SCRATCH (SImode);
})
(define_insn "loop_end"

View File

@ -1425,6 +1425,7 @@
; operand 2 is the maximum number of loop iterations
; operand 3 is the number of levels of enclosed loops
; operand 4 is the label to jump to at the top of the loop
; operand 5 indicates if the loop is entered at the top
(define_expand "doloop_end"
[(parallel [(set (pc) (if_then_else
(ne (match_operand:SI 0 "" "")
@ -1434,12 +1435,13 @@
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))
(clobber (match_scratch:SI 5 ""))])]
(clobber (match_operand 5 ""))])] ; match_scratch
"TARGET_INSNS_64PLUS && optimize"
{
/* The loop optimizer doesn't check the predicates... */
if (GET_MODE (operands[0]) != SImode)
FAIL;
operands[5] = gen_rtx_SCRATCH (SImode);
})
(define_insn "mvilc"

View File

@ -3960,7 +3960,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
(use (match_operand 4 "" "")) ; label
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
{
/* Only use cloop on innermost loops. */

View File

@ -2079,7 +2079,8 @@
[(use (match_operand 0 "register_operand" ""))
(use (match_operand:QI 1 "const_int_operand" ""))
(use (match_operand:QI 2 "const_int_operand" ""))
(use (match_operand:QI 3 "const_int_operand" ""))]
(use (match_operand:QI 3 "const_int_operand" ""))
(use (match_operand 4 "" ""))]
"!profile_arc_flag && TARGET_OPT_REPEAT"
"if (INTVAL (operands[3]) > 1)
FAIL;
@ -2115,7 +2116,8 @@
(use (match_operand:QI 1 "const_int_operand" ""))
(use (match_operand:QI 2 "const_int_operand" ""))
(use (match_operand:QI 3 "const_int_operand" ""))
(use (label_ref (match_operand 4 "" "")))]
(use (label_ref (match_operand 4 "" "")))
(use (match_operand 5 "" ""))]
"!profile_arc_flag && TARGET_OPT_REPEAT"
"if (INTVAL (operands[3]) > 1)
FAIL;

View File

@ -13085,7 +13085,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
(use (match_operand 4 "" "")) ; label
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
"
{

View File

@ -8166,7 +8166,8 @@
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
(use (match_operand 4 "" "")) ; label
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
""
{
if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)

View File

@ -8474,11 +8474,14 @@ label:
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))
(clobber (reg:SI T_REG))])]
(clobber (reg:SI T_REG))])
(match_operand 5 "" "")]
"TARGET_SH2"
{
if (GET_MODE (operands[0]) != SImode)
FAIL;
emit_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
DONE;
})
(define_insn_and_split "doloop_end_split"

View File

@ -4490,7 +4490,8 @@ selb\t%0,%4,%0,%3"
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" "")) ; loop level
(use (match_operand 4 "" ""))] ; label
(use (match_operand 4 "" "")) ; label
(match_operand 5 "" "")]
""
"
{

View File

@ -2316,7 +2316,8 @@
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
(use (match_operand 2 "" "")) ;; max iterations
(use (match_operand 3 "" "")) ;; loop level
(use (match_operand 4 "" ""))] ;; label
(use (match_operand 4 "" "")) ;; label
(use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
""
{
if (optimize > 0 && flag_modulo_sched)

View File

@ -1322,7 +1322,8 @@
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
(use (match_operand 2 "" "")) ;; max iterations
(use (match_operand 3 "" "")) ;; loop level
(use (match_operand 4 "" ""))] ;; label
(use (match_operand 4 "" "")) ;; label
(use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
""
{
if (optimize > 0)

View File

@ -5517,7 +5517,9 @@ iterations as a @code{const_int} or @code{const0_rtx} if this cannot be
determined until run-time; operand 2 is the actual or estimated maximum
number of iterations as a @code{const_int}; operand 3 is the number of
enclosed loops as a @code{const_int} (an innermost loop has a value of
1); operand 4 is the label to jump to if the register is nonzero.
1); operand 4 is the label to jump to if the register is nonzero;
operand 5 is const1_rtx if the loop in entered at its top, const0_rtx
otherwise.
@xref{Looping Patterns}.
This optional instruction pattern should be defined for machines with

View File

@ -1,5 +1,5 @@
/* Perform doloop optimizations
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010
Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010, 2012
Free Software Foundation, Inc.
Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)
@ -561,7 +561,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
init = gen_doloop_begin (counter_reg,
desc->const_iter ? desc->niter_expr : const0_rtx,
iter_rtx,
GEN_INT (level));
GEN_INT (level),
doloop_seq);
if (init)
{
start_sequence ();
@ -619,6 +620,7 @@ doloop_optimize (struct loop *loop)
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);
@ -681,8 +683,14 @@ doloop_optimize (struct loop *loop)
not like. */
start_label = block_label (desc->in_edge->dest);
doloop_reg = gen_reg_rtx (mode);
entered_at_top = loop_preheader_edge (loop)->dest == desc->in_edge->dest;
fprintf (stderr, "entered at top orig: %d\n", entered_at_top);
entered_at_top = (loop->latch == desc->in_edge->dest
&& contains_no_active_insn_p (loop->latch));
fprintf (stderr, "entered at top Zdenek: %d\n", entered_at_top);
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
@ -712,7 +720,8 @@ doloop_optimize (struct loop *loop)
}
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)
{