recog.c (recog_memoized): Rename to recog_memoized_1.

* recog.c (recog_memoized): Rename to recog_memoized_1.
	* recog.h (recog_memoized): Rename to recog_memoized_1.
	(recog_memoized): New macro.
	* rtl.h (single_set): Rename to single_set_1
	(single_set): New macro.
	* rtlanal.c (single_set): Rename to single_set_1;  expect clobbers
	to be last.

	* i386.md (strmovsi_1, strmovhi_1 strmovqi_1):
	Do not use match_dup of input operands at outputs.
	Use register_operand for memory expression.
	(rep_movsi): Put use last, canonicalize.
	Use register_operand for memory expression.
	(rep_movqi): Put use last.
	Use register_operand for memory expression.
	(strsetsi_1, strset_hi_1, strsetqi_1): Do not use match_dup
	of input operands at outputs.  Use register_operand for memory
	expression.
	(rep_stossi): Put use last; canonicalize; fix match_dup in
	the address expression
	(rep_stosqi): Likewise.
	(memcmp expander): Update calls.
	(cmpstrsi_nz_1, cmpstrsi_1, strlensi_1): Avoid match_dups in
	the clobbers.

	* i386.md (fp_jcc_3, fp_jcc_4, jp_fcc_5): if_then_else operand is
	VOIDmode.
	(fp_jcc_4, fp_jcc_3): Refuse unordered comparisons.

From-SVN: r36664
This commit is contained in:
Jan Hubicka 2000-09-29 11:24:13 +00:00
parent 073427934a
commit b1cdafbb6c
6 changed files with 142 additions and 97 deletions

View File

@ -125,6 +125,7 @@ extern int ix86_adjust_cost PARAMS ((rtx, rtx, rtx, int));
extern void ix86_sched_init PARAMS ((FILE *, int));
extern int ix86_sched_reorder PARAMS ((FILE *, int, rtx *, int, int));
extern int ix86_variable_issue PARAMS ((FILE *, int, rtx, int));
extern enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
#ifdef TREE_CODE
extern void init_cumulative_args PARAMS ((CUMULATIVE_ARGS *, tree, rtx));

View File

@ -388,7 +388,6 @@ static void put_condition_code PARAMS ((enum rtx_code, enum machine_mode,
int, int, FILE *));
static enum rtx_code unsigned_comparison PARAMS ((enum rtx_code code));
static rtx ix86_expand_int_compare PARAMS ((enum rtx_code, rtx, rtx));
static enum machine_mode ix86_fp_compare_mode PARAMS ((enum rtx_code));
static enum rtx_code ix86_prepare_fp_compare_args PARAMS ((enum rtx_code,
rtx *, rtx *));
static rtx gen_push PARAMS ((rtx));
@ -4635,7 +4634,7 @@ ix86_expand_int_compare (code, op0, op1)
/* Figure out whether to use ordered or unordered fp comparisons.
Return the appropriate mode to use. */
static enum machine_mode
enum machine_mode
ix86_fp_compare_mode (code)
enum rtx_code code;
{

View File

@ -8539,7 +8539,7 @@
(define_insn "*fp_jcc_3"
[(set (pc)
(if_then_else (match_operator:CCFP 0 "comparison_operator"
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(label_ref (match_operand 3 "" ""))
@ -8550,12 +8550,14 @@
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))
&& SELECT_CC_MODE (GET_CODE (operands[0]),
operands[1], operands[2]) == CCFPmode"
"#")
(define_insn "*fp_jcc_4"
[(set (pc)
(if_then_else (match_operator:CCFP 0 "comparison_operator"
(if_then_else (match_operator 0 "comparison_operator"
[(match_operand 1 "register_operand" "f")
(match_operand 2 "nonimmediate_operand" "fm")])
(pc)
@ -8566,7 +8568,9 @@
"TARGET_80387
&& (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
&& GET_MODE (operands[1]) == GET_MODE (operands[2])
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))"
&& !ix86_use_fcomi_compare (GET_CODE (operands[0]))
&& SELECT_CC_MODE (GET_CODE (operands[0]),
operands[1], operands[2]) == CCFPmode"
"#")
(define_insn "*fp_jcc_5"
@ -10003,10 +10007,10 @@
[(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
(mem:SI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 2)
(const_int 4)))
(set (match_operand:SI 1 "register_operand" "=S")
(plus:SI (match_dup 1)
(plus:SI (match_dup 3)
(const_int 4)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10019,10 +10023,10 @@
[(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
(mem:HI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 2)
(const_int 2)))
(set (match_operand:SI 1 "register_operand" "=S")
(plus:SI (match_dup 1)
(plus:SI (match_dup 3)
(const_int 2)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10035,10 +10039,10 @@
[(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
(mem:QI (match_operand:SI 3 "register_operand" "1")))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 2)
(const_int 1)))
(set (match_operand:SI 1 "register_operand" "=S")
(plus:SI (match_dup 1)
(plus:SI (match_dup 3)
(const_int 1)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10047,21 +10051,18 @@
(set_attr "memory" "both")
(set_attr "mode" "QI")])
;; It might seem that operands 3 & 4 could use predicate register_operand.
;; But strength reduction might offset the MEM expression. So we let
;; reload put the address into %edi & %esi.
(define_insn "rep_movsi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(use (match_operand:SI 5 "register_operand" "2"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "address_operand" "0")
(ashift:SI (match_dup 5) (const_int 2))))
(plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
(const_int 2))
(match_operand:SI 3 "register_operand" "0")))
(set (match_operand:SI 1 "register_operand" "=S")
(plus:SI (match_operand:SI 4 "address_operand" "1")
(ashift:SI (match_dup 5) (const_int 2))))
(plus:SI (ashift:SI (match_dup 5) (const_int 2))
(match_operand:SI 4 "register_operand" "1")))
(set (mem:BLK (match_dup 3))
(mem:BLK (match_dup 4)))
(use (match_dup 5))
(use (reg:SI 19))]
""
"rep\;movsl|rep movsd"
@ -10072,13 +10073,14 @@
(define_insn "rep_movqi"
[(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
(use (match_operand:SI 5 "register_operand" "2"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 5)))
(plus:SI (match_operand:SI 3 "register_operand" "0")
(match_operand:SI 5 "register_operand" "2")))
(set (match_operand:SI 1 "register_operand" "=S")
(plus:SI (match_operand:SI 4 "address_operand" "1") (match_dup 5)))
(plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
(set (mem:BLK (match_dup 3))
(mem:BLK (match_dup 4)))
(use (match_dup 5))
(use (reg:SI 19))]
""
"rep\;movsb|rep movsb"
@ -10307,7 +10309,7 @@
[(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
(match_operand:SI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 1)
(const_int 4)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10320,7 +10322,7 @@
[(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
(match_operand:HI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 1)
(const_int 2)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10333,7 +10335,7 @@
[(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
(match_operand:QI 2 "register_operand" "a"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_dup 0)
(plus:SI (match_dup 1)
(const_int 1)))
(use (reg:SI 19))]
"TARGET_SINGLE_STRINGOP || optimize_size"
@ -10342,19 +10344,16 @@
(set_attr "memory" "store")
(set_attr "mode" "QI")])
;; It might seem that operand 0 could use predicate register_operand.
;; But strength reduction might offset the MEM expression. So we let
;; reload put the address into %edi.
(define_insn "rep_stossi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(use (match_operand:SI 2 "register_operand" "a"))
(use (match_operand:SI 4 "register_operand" "1"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "address_operand" "0")
(ashift:SI (match_dup 3) (const_int 2))))
(plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
(const_int 2))
(match_operand:SI 3 "register_operand" "0")))
(set (mem:BLK (match_dup 3))
(const_int 0))
(use (match_operand:SI 2 "register_operand" "a"))
(use (match_dup 4))
(use (reg:SI 19))]
""
"rep\;stosl|rep stosd"
@ -10365,12 +10364,13 @@
(define_insn "rep_stosqi"
[(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
(use (match_operand:QI 2 "register_operand" "a"))
(use (match_operand:SI 4 "register_operand" "1"))
(set (match_operand:SI 0 "register_operand" "=D")
(plus:SI (match_operand:SI 3 "address_operand" "0") (match_dup 3)))
(plus:SI (match_operand:SI 3 "register_operand" "0")
(match_operand:SI 4 "register_operand" "1")))
(set (mem:BLK (match_dup 3))
(const_int 0))
(use (match_operand:QI 2 "register_operand" "a"))
(use (match_dup 4))
(use (reg:SI 19))]
""
"rep\;stosb|rep stosb"
@ -10413,12 +10413,14 @@
emit_move_insn (operands[0], const0_rtx);
DONE;
}
emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align));
emit_insn (gen_cmpstrsi_nz_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg));
}
else
{
emit_insn (gen_cmpsi_1 (countreg, countreg));
emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align));
emit_insn (gen_cmpstrsi_1 (addr1, addr2, countreg, align,
addr1, addr2, countreg));
}
outlow = gen_lowpart (QImode, out);
@ -10448,21 +10450,17 @@
;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
;; zero. Emit extra code to make sure that a zero-length compare is EQ.
;;
;; It might seem that operands 0 & 1 could use predicate register_operand.
;; But strength reduction might offset the MEM expression. So we let
;; reload put the address into %edi & %esi.
(define_insn "cmpstrsi_nz_1"
[(set (reg:CC 17)
(compare:CC (mem:BLK (match_operand:SI 0 "address_operand" "S"))
(mem:BLK (match_operand:SI 1 "address_operand" "D"))))
(use (match_operand:SI 2 "register_operand" "c"))
(compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
(mem:BLK (match_operand:SI 5 "register_operand" "1"))))
(use (match_operand:SI 6 "register_operand" "2"))
(use (match_operand:SI 3 "immediate_operand" "i"))
(use (reg:SI 19))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))]
(clobber (match_operand:SI 0 "register_operand" "=S"))
(clobber (match_operand:SI 1 "register_operand" "=D"))
(clobber (match_operand:SI 2 "register_operand" "=c"))]
""
"repz{\;| }cmpsb"
[(set_attr "type" "str")
@ -10473,17 +10471,17 @@
(define_insn "cmpstrsi_1"
[(set (reg:CC 17)
(if_then_else:CC (ne (match_operand:SI 2 "register_operand" "c")
(if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
(const_int 0))
(compare:SI (mem:BLK (match_operand:SI 0 "address_operand" "S"))
(mem:BLK (match_operand:SI 1 "address_operand" "D")))
(compare:SI (mem:BLK (match_operand:SI 4 "register_operand" "0"))
(mem:BLK (match_operand:SI 5 "register_operand" "1")))
(const_int 0)))
(use (match_operand:SI 3 "immediate_operand" "i"))
(use (reg:CC 17))
(use (reg:SI 19))
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))]
(clobber (match_operand:SI 0 "register_operand" "=S"))
(clobber (match_operand:SI 1 "register_operand" "=D"))
(clobber (match_operand:SI 2 "register_operand" "=c"))]
""
"repz{\;| }cmpsb"
[(set_attr "type" "str")
@ -10547,25 +10545,21 @@
emit_insn (gen_cld ());
emit_insn (gen_strlensi_1 (scratch1, scratch3, eoschar,
align, constm1_rtx));
align, constm1_rtx, scratch3));
emit_insn (gen_one_cmplsi2 (scratch2, scratch1));
emit_insn (gen_addsi3 (out, scratch2, constm1_rtx));
}
DONE;
}")
;; It might seem that operands 0 & 1 could use predicate register_operand.
;; But strength reduction might offset the MEM expression. So we let
;; reload put the address into %edi.
(define_insn "strlensi_1"
[(set (match_operand:SI 0 "register_operand" "=&c")
(unspec:SI [(mem:BLK (match_operand:SI 1 "address_operand" "D"))
(unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
(match_operand:QI 2 "general_operand" "a")
(match_operand:SI 3 "immediate_operand" "i")
(match_operand:SI 4 "immediate_operand" "0")] 0))
(use (reg:SI 19))
(clobber (match_dup 1))
(clobber (match_operand:SI 1 "register_operand" "=D"))
(clobber (reg:CC 17))]
""
"repnz{\;| }scasb"

View File

@ -112,7 +112,7 @@ init_recog ()
through this one. (The only exception is in combine.c.) */
int
recog_memoized (insn)
recog_memoized_1 (insn)
rtx insn;
{
if (INSN_CODE (insn) < 0)

View File

@ -1329,6 +1329,12 @@ extern void set_unique_reg_note PARAMS ((rtx, enum reg_note, rtx));
/* Functions in rtlanal.c */
/* Single set is implemented as macro for performance reasons. */
#define single_set(I) (INSN_P (I) \
? (GET_CODE (PATTERN (I)) == SET \
? PATTERN (I) : single_set_1 (I)) \
: NULL_RTX)
extern int rtx_unstable_p PARAMS ((rtx));
extern int rtx_varies_p PARAMS ((rtx));
extern int rtx_addr_varies_p PARAMS ((rtx));
@ -1347,7 +1353,7 @@ extern int no_jumps_between_p PARAMS ((rtx, rtx));
extern int modified_in_p PARAMS ((rtx, rtx));
extern int insn_dependent_p PARAMS ((rtx, rtx));
extern int reg_set_p PARAMS ((rtx, rtx));
extern rtx single_set PARAMS ((rtx));
extern rtx single_set_1 PARAMS ((rtx));
extern int multiple_sets PARAMS ((rtx));
extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int));
extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int,

View File

@ -842,46 +842,91 @@ insn_dependent_p_1 (x, pat, data)
will not be used, which we ignore. */
rtx
single_set (insn)
single_set_1 (insn)
rtx insn;
{
rtx set;
rtx pat = PATTERN (insn);
int i;
if (! INSN_P (insn))
return 0;
if (GET_CODE (PATTERN (insn)) == SET)
return PATTERN (insn);
else if (GET_CODE (PATTERN (insn)) == PARALLEL)
if (GET_CODE (pat) == PARALLEL)
{
for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++)
rtx x, sub;
/* This part is is performance critical for targets that use a lot of
parallels, such as i386. We want to accept as single set
instructions even an instructions with multiple sets where only
one has live result, but we attempt to delay this tests only for
multiple set instructions to reduce amount of calls to
find_reg_note and side_effects_p.
We expect the "common" instruction to be parallel with first SET
followed by the clobbers. So first we get the set, then look
if it is followed by USE or CLOBBER. If so, we just return expect
no SETs after these. When SET is followed by another SET, we
continue by the clomplex loop trought all members of PARALLEL.
*/
#ifdef ENABLE_CHECKING
if (XVECLEN (pat, 0) < 2)
abort ();
#endif
set = XVECEXP (pat, 0, 0);
switch (GET_CODE (set))
{
rtx sub = XVECEXP (PATTERN (insn), 0, i);
switch (GET_CODE (sub))
{
case USE:
case CLOBBER:
break;
case SET:
if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
|| side_effects_p (sub))
{
if (set)
return 0;
else
set = sub;
}
break;
default:
return 0;
}
#ifdef ENABLE_CHECKING
case USE:
case CLOBBER:
/* Instruction should not consist only from USEs and CLOBBERS,
since then gcc is allowed to remove it entirely. In case
something else is present, it should be first in the pattern. */
abort();
#endif
case SET:
break;
default:
return NULL_RTX;
}
x = XVECEXP (pat, 0, 1);
switch (GET_CODE (x))
{
case USE:
case CLOBBER:
#ifdef ENABLE_CHECKING
/* The USEs and CLOBBERs should always come last in the pattern. */
for (i = XVECLEN (pat, 0) - 1; i > 1; i--)
if (GET_CODE (XVECEXP (pat, 0, i)) != USE
&& GET_CODE (XVECEXP (pat, 0, i)) != CLOBBER)
abort();
#endif
return set;
case SET:
/* Multiple set insns - we are off the critical path now. */
for (i = XVECLEN (pat, 0) - 1; i > 0; i--)
{
sub = XVECEXP (pat, 0, i);
switch GET_CODE (sub)
{
case USE:
case CLOBBER:
break;
case SET:
if (!set
|| (find_reg_note (insn, REG_UNUSED, SET_DEST (set))
&& side_effects_p (set)))
set = sub;
else if (! find_reg_note (insn, REG_UNUSED, SET_DEST (sub))
|| side_effects_p (sub))
return NULL_RTX;
break;
default:
return NULL_RTX;
}
}
return set;
default:
return NULL_RTX;
}
return set;
}
return 0;