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:
parent
d919140b83
commit
2407343c3d
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
29
gcc/cfgrtl.c
29
gcc/cfgrtl.c
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user