Commit 2407343c by Joern Rennecke Committed by Joern Rennecke

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
parent d919140b
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
......@@ -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);
......
......@@ -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. */
......
......@@ -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"
"
{
......
......@@ -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"
......
......@@ -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"
......
......@@ -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. */
......
......@@ -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;
......
......@@ -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
""
"
{
......
......@@ -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)
......
......@@ -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"
......
......@@ -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 "" "")]
""
"
{
......
......@@ -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)
......
......@@ -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)
......
......@@ -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
......
/* 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)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment