Commit 75c70254 by Steven Bosscher Committed by Mostafa Hagog

> 2005-06-02 Steven Bosscher <stevenb@suse.de> > Mostafa Hagog...

> 2005-06-02 Steven Bosscher  <stevenb@suse.de>
>            Mostafa Hagog <mustafa@il.ibm.com>
>
>       * cfgloop.h (doloop_condition_get): Make external.
>       * loop-doloop.c (doloop_condition_get): Generalize to make it
>       usable in modulo-sched.c.
>       * modulo-sched.c (doloop_register_get): Use
>       doloop_condition_get instead of duplicating it.

Co-Authored-By: Mostafa Hagog <mustafa@il.ibm.com>

From-SVN: r100490
parent 9267ee62
2005-06-02 Steven Bosscher <stevenb@suse.de>
Mostafa Hagog <mustafa@il.ibm.com>
* cfgloop.h (doloop_condition_get): Make external.
* loop-doloop.c (doloop_condition_get): Generalize to make it
usable in modulo-sched.c.
* modulo-sched.c (doloop_register_get): Use
doloop_condition_get instead of duplicating it.
2005-06-02 Bernd Schmidt <bernd.schmidt@analog.com> 2005-06-02 Bernd Schmidt <bernd.schmidt@analog.com>
* reload1.c (reload): Undo 2005-04-20 change. Make sure we detect * reload1.c (reload): Undo 2005-04-20 change. Make sure we detect
......
...@@ -289,6 +289,7 @@ extern void verify_loop_structure (struct loops *); ...@@ -289,6 +289,7 @@ extern void verify_loop_structure (struct loops *);
/* Loop analysis. */ /* Loop analysis. */
extern bool just_once_each_iteration_p (const struct loop *, basic_block); extern bool just_once_each_iteration_p (const struct loop *, basic_block);
extern unsigned expected_loop_iterations (const struct loop *); extern unsigned expected_loop_iterations (const struct loop *);
extern rtx doloop_condition_get (rtx);
/* Loop manipulation. */ /* Loop manipulation. */
extern bool can_duplicate_loop_p (struct loop *loop); extern bool can_duplicate_loop_p (struct loop *loop);
......
...@@ -69,12 +69,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -69,12 +69,13 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
/* Return the loop termination condition for PATTERN or zero /* Return the loop termination condition for PATTERN or zero
if it is not a decrement and branch jump insn. */ if it is not a decrement and branch jump insn. */
static rtx rtx
doloop_condition_get (rtx pattern) doloop_condition_get (rtx pattern)
{ {
rtx cmp; rtx cmp;
rtx inc; rtx inc;
rtx reg; rtx reg;
rtx inc_src;
rtx condition; rtx condition;
/* The canonical doloop pattern we expect is: /* The canonical doloop pattern we expect is:
...@@ -85,12 +86,13 @@ doloop_condition_get (rtx pattern) ...@@ -85,12 +86,13 @@ doloop_condition_get (rtx pattern)
(set (reg) (plus (reg) (const_int -1))) (set (reg) (plus (reg) (const_int -1)))
(additional clobbers and uses)]) (additional clobbers and uses)])
Some machines (IA-64) make the decrement conditional on Some targets (IA-64) wrap the set of the loop counter in
the condition as well, so we don't bother verifying the an if_then_else too.
actual decrement. In summary, the branch must be the
first entry of the parallel (also required by jump.c), In summary, the branch must be the first entry of the
and the second entry of the parallel must be a set of parallel (also required by jump.c), and the second
the loop counter register. */ entry of the parallel must be a set of the loop counter
register. */
if (GET_CODE (pattern) != PARALLEL) if (GET_CODE (pattern) != PARALLEL)
return 0; return 0;
...@@ -99,11 +101,21 @@ doloop_condition_get (rtx pattern) ...@@ -99,11 +101,21 @@ doloop_condition_get (rtx pattern)
inc = XVECEXP (pattern, 0, 1); inc = XVECEXP (pattern, 0, 1);
/* Check for (set (reg) (something)). */ /* Check for (set (reg) (something)). */
if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc))) if (GET_CODE (inc) != SET)
return 0; return 0;
/* Extract loop counter register. */
reg = SET_DEST (inc); reg = SET_DEST (inc);
if (! REG_P (reg))
return 0;
/* Check if something = (plus (reg) (const_int -1)).
On IA-64, this decrement is wrapped in an if_then_else. */
inc_src = SET_SRC (inc);
if (GET_CODE (inc_src) == IF_THEN_ELSE)
inc_src = XEXP (inc_src, 1);
if (GET_CODE (inc_src) != PLUS
|| XEXP (inc_src, 0) != reg
|| XEXP (inc_src, 1) != constm1_rtx)
return 0;
/* Check for (set (pc) (if_then_else (condition) /* Check for (set (pc) (if_then_else (condition)
(label_ref (label)) (label_ref (label))
...@@ -118,15 +130,16 @@ doloop_condition_get (rtx pattern) ...@@ -118,15 +130,16 @@ doloop_condition_get (rtx pattern)
/* Extract loop termination condition. */ /* Extract loop termination condition. */
condition = XEXP (SET_SRC (cmp), 0); condition = XEXP (SET_SRC (cmp), 0);
if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE) /* We expect a GE or NE comparison with 0 or 1. */
|| GET_CODE (XEXP (condition, 1)) != CONST_INT) if ((GET_CODE (condition) != GE
&& GET_CODE (condition) != NE)
|| (XEXP (condition, 1) != const0_rtx
&& XEXP (condition, 1) != const1_rtx))
return 0; return 0;
if (XEXP (condition, 0) == reg) if ((XEXP (condition, 0) == reg)
return condition; || (GET_CODE (XEXP (condition, 0)) == PLUS
&& XEXP (XEXP (condition, 0), 0) == reg))
if (GET_CODE (XEXP (condition, 0)) == PLUS
&& XEXP (XEXP (condition, 0), 0) == reg)
return condition; return condition;
/* ??? If a machine uses a funny comparison, we could return a /* ??? If a machine uses a funny comparison, we could return a
......
...@@ -269,74 +269,31 @@ static struct sched_info sms_sched_info = ...@@ -269,74 +269,31 @@ static struct sched_info sms_sched_info =
}; };
/* Return the register decremented and tested or zero if it is not a decrement /* Return the register decremented and tested in INSN,
and branch jump insn (similar to doloop_condition_get). */ or zero if it is not a decrement-and-branch insn. */
static rtx static rtx
doloop_register_get (rtx insn, rtx *comp) doloop_register_get (rtx insn)
{ {
rtx pattern, cmp, inc, reg, condition; rtx pattern, reg, condition;
if (!JUMP_P (insn))
return NULL_RTX;
pattern = PATTERN (insn);
/* The canonical doloop pattern we expect is:
(parallel [(set (pc) (if_then_else (condition)
(label_ref (label))
(pc)))
(set (reg) (plus (reg) (const_int -1)))
(additional clobbers and uses)])
where condition is further restricted to be
(ne (reg) (const_int 1)). */
if (GET_CODE (pattern) != PARALLEL)
return NULL_RTX;
cmp = XVECEXP (pattern, 0, 0);
inc = XVECEXP (pattern, 0, 1);
/* Return the compare rtx. */
*comp = cmp;
/* Check for (set (reg) (something)). */ if (! JUMP_P (insn))
if (GET_CODE (inc) != SET || ! REG_P (SET_DEST (inc)))
return NULL_RTX; return NULL_RTX;
/* Extract loop counter register. */ pattern = PATTERN (insn);
reg = SET_DEST (inc); condition = doloop_condition_get (pattern);
if (! condition)
/* Check if something = (plus (reg) (const_int -1)). */
if (GET_CODE (SET_SRC (inc)) != PLUS
|| XEXP (SET_SRC (inc), 0) != reg
|| XEXP (SET_SRC (inc), 1) != constm1_rtx)
return NULL_RTX;
/* Check for (set (pc) (if_then_else (condition)
(label_ref (label))
(pc))). */
if (GET_CODE (cmp) != SET
|| SET_DEST (cmp) != pc_rtx
|| GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE
|| GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF
|| XEXP (SET_SRC (cmp), 2) != pc_rtx)
return NULL_RTX;
/* Extract loop termination condition. */
condition = XEXP (SET_SRC (cmp), 0);
/* Check if condition = (ne (reg) (const_int 1)), which is more
restrictive than the check in doloop_condition_get:
if ((GET_CODE (condition) != GE && GET_CODE (condition) != NE)
|| GET_CODE (XEXP (condition, 1)) != CONST_INT). */
if (GET_CODE (condition) != NE
|| XEXP (condition, 1) != const1_rtx)
return NULL_RTX; return NULL_RTX;
if (XEXP (condition, 0) == reg) if (REG_P (XEXP (condition, 0)))
return reg; reg = XEXP (condition, 0);
else if (GET_CODE (XEXP (condition, 0)) == PLUS
&& REG_P (XEXP (XEXP (condition, 0), 0)))
reg = XEXP (XEXP (condition, 0), 0);
else
gcc_unreachable ();
return NULL_RTX; return reg;
} }
/* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so /* Check if COUNT_REG is set to a constant in the PRE_HEADER block, so
...@@ -1025,7 +982,7 @@ sms_schedule (FILE *dump_file) ...@@ -1025,7 +982,7 @@ sms_schedule (FILE *dump_file)
for (i = 0; i < loops->num; i++) for (i = 0; i < loops->num; i++)
{ {
rtx head, tail; rtx head, tail;
rtx count_reg, comp; rtx count_reg;
struct loop *loop = loops->parray[i]; struct loop *loop = loops->parray[i];
/* For debugging. */ /* For debugging. */
...@@ -1088,7 +1045,7 @@ sms_schedule (FILE *dump_file) ...@@ -1088,7 +1045,7 @@ sms_schedule (FILE *dump_file)
} }
/* Make sure this is a doloop. */ /* Make sure this is a doloop. */
if ( !(count_reg = doloop_register_get (tail, &comp))) if ( !(count_reg = doloop_register_get (tail)))
continue; continue;
/* Don't handle BBs with calls or barriers, or !single_set insns. */ /* Don't handle BBs with calls or barriers, or !single_set insns. */
...@@ -1134,7 +1091,7 @@ sms_schedule (FILE *dump_file) ...@@ -1134,7 +1091,7 @@ sms_schedule (FILE *dump_file)
for (i = 0; i < num_loops; i++) for (i = 0; i < num_loops; i++)
{ {
rtx head, tail; rtx head, tail;
rtx count_reg, count_init, comp; rtx count_reg, count_init;
int mii, rec_mii; int mii, rec_mii;
unsigned stage_count = 0; unsigned stage_count = 0;
HOST_WIDEST_INT loop_count = 0; HOST_WIDEST_INT loop_count = 0;
...@@ -1186,7 +1143,7 @@ sms_schedule (FILE *dump_file) ...@@ -1186,7 +1143,7 @@ sms_schedule (FILE *dump_file)
/* In case of th loop have doloop register it gets special /* In case of th loop have doloop register it gets special
handling. */ handling. */
count_init = NULL_RTX; count_init = NULL_RTX;
if ((count_reg = doloop_register_get (tail, &comp))) if ((count_reg = doloop_register_get (tail)))
{ {
basic_block pre_header; basic_block pre_header;
......
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