recog.h (enum op_type): Define.
* recog.h (enum op_type): Define. (constrain_operands): Adjust prototype. (recog_op_type): Declare new variable. * recog.c (recog_op_type): New variable. (insn_invalid_p): Allow modifying an asm statement after reload. (extract_insn): Set up recog_op_type. (constrain_operands): Lose INSN_CODE_NUM arg. All callers changed. Don't compute operand types, use recog_op_type. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * caller-save.c (init_caller_save): Use extract_insn, not insn_extract. * reorg.c (fill_slots_from_thread): Likewise. * reload1.c (reload_as_needed): Likewise. (gen_reload): Likewise. (inc_for_reload): Likewise. (reload_cse_simplify_operands): Likewise. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * genattrtab.c (write_attr_case): Generate call to extract_insn, not insn_extract. * final.c (final_scan_insn): Use extract_insn, not insn_extract. (cleanup_operand_subregs): Use extract_insn, not insn_extract. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * regmove.c (find_matches): Likewise. Change meaning of the return value to be nonzero if the optimization can be performed, zero if not. All callers changed. Shorten some variable names to fix formatting problems. (regmove_optimize): Shorten some variable names to fix formatting problems. Use the information computed by extract_insn instead of the previous method of finding it by insn code number. * regclass.c (scan_one_insn): Likewise. (record_reg_classes): Don't compute operand types, use recog_op_type. * reload.c (find_reloads): Lose CONSTRAINTS1 variable; use recog_constraints instead. From-SVN: r23529
This commit is contained in:
parent
56744d1a2a
commit
0eadeb15bc
@ -1,3 +1,42 @@
|
||||
Wed Nov 4 22:16:36 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
|
||||
|
||||
* recog.h (enum op_type): Define.
|
||||
(constrain_operands): Adjust prototype.
|
||||
(recog_op_type): Declare new variable.
|
||||
* recog.c (recog_op_type): New variable.
|
||||
(insn_invalid_p): Allow modifying an asm statement after reload.
|
||||
(extract_insn): Set up recog_op_type.
|
||||
(constrain_operands): Lose INSN_CODE_NUM arg. All callers changed.
|
||||
Don't compute operand types, use recog_op_type.
|
||||
Use the information computed by extract_insn instead of the previous
|
||||
method of finding it by insn code number.
|
||||
* caller-save.c (init_caller_save): Use extract_insn, not insn_extract.
|
||||
* reorg.c (fill_slots_from_thread): Likewise.
|
||||
* reload1.c (reload_as_needed): Likewise.
|
||||
(gen_reload): Likewise.
|
||||
(inc_for_reload): Likewise.
|
||||
(reload_cse_simplify_operands): Likewise.
|
||||
Use the information computed by extract_insn instead of the previous
|
||||
method of finding it by insn code number.
|
||||
* genattrtab.c (write_attr_case): Generate call to extract_insn, not
|
||||
insn_extract.
|
||||
* final.c (final_scan_insn): Use extract_insn, not insn_extract.
|
||||
(cleanup_operand_subregs): Use extract_insn, not insn_extract.
|
||||
Use the information computed by extract_insn instead of the previous
|
||||
method of finding it by insn code number.
|
||||
* regmove.c (find_matches): Likewise. Change meaning of the return
|
||||
value to be nonzero if the optimization can be performed, zero if
|
||||
not. All callers changed.
|
||||
Shorten some variable names to fix formatting problems.
|
||||
(regmove_optimize): Shorten some variable names to fix formatting
|
||||
problems.
|
||||
Use the information computed by extract_insn instead of the previous
|
||||
method of finding it by insn code number.
|
||||
* regclass.c (scan_one_insn): Likewise.
|
||||
(record_reg_classes): Don't compute operand types, use recog_op_type.
|
||||
* reload.c (find_reloads): Lose CONSTRAINTS1 variable; use
|
||||
recog_constraints instead.
|
||||
|
||||
Wed Nov 4 21:37:46 1998 Jeffrey A Law (law@cygnus.com)
|
||||
|
||||
* rtl.h (flow2_completed): Declare.
|
||||
|
@ -196,10 +196,10 @@ init_caller_save ()
|
||||
&& reg_restore_code[i][j] != (enum insn_code)-1);
|
||||
if (ok)
|
||||
{
|
||||
insn_extract (saveinsn);
|
||||
ok = constrain_operands (reg_save_code[i][j], 1);
|
||||
insn_extract (restinsn);
|
||||
ok &= constrain_operands (reg_restore_code[i][j], 1);
|
||||
extract_insn (saveinsn);
|
||||
ok = constrain_operands (1);
|
||||
extract_insn (restinsn);
|
||||
ok &= constrain_operands (1);
|
||||
}
|
||||
|
||||
if (! ok)
|
||||
|
13
gcc/final.c
13
gcc/final.c
@ -2843,11 +2843,11 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
since `reload' should have changed them so that they do. */
|
||||
|
||||
insn_code_number = recog_memoized (insn);
|
||||
insn_extract (insn);
|
||||
extract_insn (insn);
|
||||
cleanup_subreg_operands (insn);
|
||||
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
if (! constrain_operands (insn_code_number, 1))
|
||||
if (! constrain_operands (1))
|
||||
fatal_insn_not_found (insn);
|
||||
#endif
|
||||
|
||||
@ -2855,8 +2855,7 @@ final_scan_insn (insn, file, optimize, prescan, nopeepholes)
|
||||
it is output. */
|
||||
|
||||
#ifdef FINAL_PRESCAN_INSN
|
||||
FINAL_PRESCAN_INSN (insn, recog_operand,
|
||||
insn_n_operands[insn_code_number]);
|
||||
FINAL_PRESCAN_INSN (insn, recog_operand, recog_n_operands);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_cc0
|
||||
@ -3047,8 +3046,8 @@ cleanup_subreg_operands (insn)
|
||||
since `reload' should have changed them so that they do. */
|
||||
|
||||
insn_code_number = recog_memoized (insn);
|
||||
insn_extract (insn);
|
||||
for (i = 0; i < insn_n_operands[insn_code_number]; i++)
|
||||
extract_insn (insn);
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
{
|
||||
if (GET_CODE (recog_operand[i]) == SUBREG)
|
||||
recog_operand[i] = alter_subreg (recog_operand[i]);
|
||||
@ -3057,7 +3056,7 @@ cleanup_subreg_operands (insn)
|
||||
recog_operand[i] = walk_alter_subreg (recog_operand[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < insn_n_dups[insn_code_number]; i++)
|
||||
for (i = 0; i < recog_n_dups; i++)
|
||||
{
|
||||
if (GET_CODE (*recog_dup_loc[i]) == SUBREG)
|
||||
*recog_dup_loc[i] = alter_subreg (*recog_dup_loc[i]);
|
||||
|
@ -34,7 +34,7 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
If the attribute `alternative', or a random C expression is present,
|
||||
`constrain_operands' is called. If either of these cases of a reference to
|
||||
an operand is found, `insn_extract' is called.
|
||||
an operand is found, `extract_insn' is called.
|
||||
|
||||
The special attribute `length' is also recognized. For this operand,
|
||||
expressions involving the address of an operand or the current insn,
|
||||
@ -5063,14 +5063,14 @@ write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
|
||||
if (must_extract)
|
||||
{
|
||||
write_indent (indent + 2);
|
||||
printf ("insn_extract (insn);\n");
|
||||
printf ("extract_insn (insn);\n");
|
||||
}
|
||||
|
||||
if (must_constrain)
|
||||
{
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
write_indent (indent + 2);
|
||||
printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
|
||||
printf ("if (! constrain_operands (reload_completed))\n");
|
||||
write_indent (indent + 2);
|
||||
printf (" fatal_insn_not_found (insn);\n");
|
||||
#endif
|
||||
|
80
gcc/recog.c
80
gcc/recog.c
@ -56,7 +56,8 @@ static int insn_invalid_p PROTO((rtx));
|
||||
|
||||
int volatile_ok;
|
||||
|
||||
/* The following vectors hold the results from insn_extract. */
|
||||
/* The next variables are set up by extract_insn. The first four of them
|
||||
are also set up during insn_extract. */
|
||||
|
||||
/* Indexed by N, gives value of operand N. */
|
||||
rtx recog_operand[MAX_RECOG_OPERANDS];
|
||||
@ -72,9 +73,6 @@ rtx *recog_dup_loc[MAX_RECOG_OPERANDS];
|
||||
Nth duplicate-appearance of an operand. */
|
||||
char recog_dup_num[MAX_RECOG_OPERANDS];
|
||||
|
||||
|
||||
/* The next variables are set up by extract_insn. */
|
||||
|
||||
/* The number of operands of the insn. */
|
||||
int recog_n_operands;
|
||||
|
||||
@ -90,6 +88,9 @@ enum machine_mode recog_operand_mode[MAX_RECOG_OPERANDS];
|
||||
/* Indexed by N, gives the constraint string for operand N. */
|
||||
char *recog_constraints[MAX_RECOG_OPERANDS];
|
||||
|
||||
/* Indexed by N, gives the type (in, out, inout) for operand N. */
|
||||
enum op_type recog_op_type[MAX_RECOG_OPERANDS];
|
||||
|
||||
#ifndef REGISTER_CONSTRAINTS
|
||||
/* Indexed by N, nonzero if operand N should be an address. */
|
||||
char recog_operand_address_p[MAX_RECOG_OPERANDS];
|
||||
@ -264,25 +265,17 @@ insn_invalid_p (insn)
|
||||
int icode = recog_memoized (insn);
|
||||
int is_asm = icode < 0 && asm_noperands (PATTERN (insn)) >= 0;
|
||||
|
||||
if (is_asm)
|
||||
{
|
||||
if (! check_asm_operands (PATTERN (insn)))
|
||||
return 1;
|
||||
|
||||
/* Disallow modification of ASM_OPERANDS after reload; verifying the
|
||||
constraints is too difficult. */
|
||||
if (reload_completed)
|
||||
return 1;
|
||||
}
|
||||
else if (icode < 0)
|
||||
if (is_asm && ! check_asm_operands (PATTERN (insn)))
|
||||
return 1;
|
||||
if (! is_asm && icode < 0)
|
||||
return 1;
|
||||
|
||||
/* After reload, verify that all constraints are satisfied. */
|
||||
if (reload_completed)
|
||||
{
|
||||
insn_extract (insn);
|
||||
extract_insn (insn);
|
||||
|
||||
if (! constrain_operands (INSN_CODE (insn), 1))
|
||||
if (! constrain_operands (1))
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -304,8 +297,7 @@ apply_change_group ()
|
||||
given a MEM and it still is a valid address, or if this is in insn
|
||||
and it is recognized. In the latter case, if reload has completed,
|
||||
we also require that the operands meet the constraints for
|
||||
the insn. We do not allow modifying an ASM_OPERANDS after reload
|
||||
has completed because verifying the constraints is too difficult. */
|
||||
the insn. */
|
||||
|
||||
for (i = 0; i < num_changes; i++)
|
||||
{
|
||||
@ -1807,13 +1799,18 @@ extract_insn (insn)
|
||||
recog_operand_mode[i] = insn_operand_mode[icode][i];
|
||||
}
|
||||
}
|
||||
for (i = 0; i < noperands; i++)
|
||||
recog_op_type[i] = (recog_constraints[i][0] == '=' ? OP_OUT
|
||||
: recog_constraints[i][0] == '+' ? OP_INOUT
|
||||
: OP_IN);
|
||||
}
|
||||
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
|
||||
/* Check the operands of an insn (found in recog_operands)
|
||||
against the insn's operand constraints (found via INSN_CODE_NUM)
|
||||
/* Check the operands of an insn against the insn's operand constraints
|
||||
and return 1 if they are valid.
|
||||
The information about the insn's operands, constraints, operand modes
|
||||
etc. is obtained from the global variables set up by extract_insn.
|
||||
|
||||
WHICH_ALTERNATIVE is set to a number which indicates which
|
||||
alternative of constraints was matched: 0 for the first alternative,
|
||||
@ -1843,40 +1840,35 @@ struct funny_match
|
||||
};
|
||||
|
||||
int
|
||||
constrain_operands (insn_code_num, strict)
|
||||
int insn_code_num;
|
||||
constrain_operands (strict)
|
||||
int strict;
|
||||
{
|
||||
char *constraints[MAX_RECOG_OPERANDS];
|
||||
int matching_operands[MAX_RECOG_OPERANDS];
|
||||
enum op_type {OP_IN, OP_OUT, OP_INOUT} op_types[MAX_RECOG_OPERANDS];
|
||||
int earlyclobber[MAX_RECOG_OPERANDS];
|
||||
register int c;
|
||||
int noperands = insn_n_operands[insn_code_num];
|
||||
|
||||
struct funny_match funny_match[MAX_RECOG_OPERANDS];
|
||||
int funny_match_index;
|
||||
int nalternatives = insn_n_alternatives[insn_code_num];
|
||||
|
||||
if (noperands == 0 || nalternatives == 0)
|
||||
if (recog_n_operands == 0 || recog_n_alternatives == 0)
|
||||
return 1;
|
||||
|
||||
for (c = 0; c < noperands; c++)
|
||||
for (c = 0; c < recog_n_operands; c++)
|
||||
{
|
||||
constraints[c] = insn_operand_constraint[insn_code_num][c];
|
||||
constraints[c] = recog_constraints[c];
|
||||
matching_operands[c] = -1;
|
||||
op_types[c] = OP_IN;
|
||||
}
|
||||
|
||||
which_alternative = 0;
|
||||
|
||||
while (which_alternative < nalternatives)
|
||||
while (which_alternative < recog_n_alternatives)
|
||||
{
|
||||
register int opno;
|
||||
int lose = 0;
|
||||
funny_match_index = 0;
|
||||
|
||||
for (opno = 0; opno < noperands; opno++)
|
||||
for (opno = 0; opno < recog_n_operands; opno++)
|
||||
{
|
||||
register rtx op = recog_operand[opno];
|
||||
enum machine_mode mode = GET_MODE (op);
|
||||
@ -1912,6 +1904,8 @@ constrain_operands (insn_code_num, strict)
|
||||
case '!':
|
||||
case '*':
|
||||
case '%':
|
||||
case '=':
|
||||
case '+':
|
||||
break;
|
||||
|
||||
case '#':
|
||||
@ -1921,14 +1915,6 @@ constrain_operands (insn_code_num, strict)
|
||||
p++;
|
||||
break;
|
||||
|
||||
case '=':
|
||||
op_types[opno] = OP_OUT;
|
||||
break;
|
||||
|
||||
case '+':
|
||||
op_types[opno] = OP_INOUT;
|
||||
break;
|
||||
|
||||
case '&':
|
||||
earlyclobber[opno] = 1;
|
||||
break;
|
||||
@ -1973,8 +1959,8 @@ constrain_operands (insn_code_num, strict)
|
||||
strictly valid, i.e., that all pseudos requiring hard regs
|
||||
have gotten them. */
|
||||
if (strict <= 0
|
||||
|| (strict_memory_address_p
|
||||
(insn_operand_mode[insn_code_num][opno], op)))
|
||||
|| (strict_memory_address_p (recog_operand_mode[opno],
|
||||
op)))
|
||||
win = 1;
|
||||
break;
|
||||
|
||||
@ -2154,18 +2140,18 @@ constrain_operands (insn_code_num, strict)
|
||||
operand. */
|
||||
|
||||
if (strict > 0)
|
||||
for (eopno = 0; eopno < noperands; eopno++)
|
||||
for (eopno = 0; eopno < recog_n_operands; eopno++)
|
||||
/* Ignore earlyclobber operands now in memory,
|
||||
because we would often report failure when we have
|
||||
two memory operands, one of which was formerly a REG. */
|
||||
if (earlyclobber[eopno]
|
||||
&& GET_CODE (recog_operand[eopno]) == REG)
|
||||
for (opno = 0; opno < noperands; opno++)
|
||||
for (opno = 0; opno < recog_n_operands; opno++)
|
||||
if ((GET_CODE (recog_operand[opno]) == MEM
|
||||
|| op_types[opno] != OP_OUT)
|
||||
|| recog_op_type[opno] != OP_OUT)
|
||||
&& opno != eopno
|
||||
/* Ignore things like match_operator operands. */
|
||||
&& *insn_operand_constraint[insn_code_num][opno] != 0
|
||||
&& *recog_constraints[opno] != 0
|
||||
&& ! (matching_operands[opno] == eopno
|
||||
&& operands_match_p (recog_operand[opno],
|
||||
recog_operand[eopno]))
|
||||
@ -2191,7 +2177,7 @@ constrain_operands (insn_code_num, strict)
|
||||
/* If we are about to reject this, but we are not to test strictly,
|
||||
try a very loose test. Only return failure if it fails also. */
|
||||
if (strict == 0)
|
||||
return constrain_operands (insn_code_num, -1);
|
||||
return constrain_operands (-1);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
12
gcc/recog.h
12
gcc/recog.h
@ -20,6 +20,13 @@ Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include "gansidecl.h"
|
||||
|
||||
/* Types of operands. */
|
||||
enum op_type {
|
||||
OP_IN,
|
||||
OP_OUT,
|
||||
OP_INOUT
|
||||
};
|
||||
|
||||
extern void init_recog PROTO((void));
|
||||
extern void init_recog_no_volatile PROTO((void));
|
||||
extern int recog_memoized PROTO((rtx));
|
||||
@ -28,7 +35,7 @@ extern int validate_change PROTO((rtx, rtx *, rtx, int));
|
||||
extern int apply_change_group PROTO((void));
|
||||
extern int num_validated_changes PROTO((void));
|
||||
extern void cancel_changes PROTO((int));
|
||||
extern int constrain_operands PROTO((int, int));
|
||||
extern int constrain_operands PROTO((int));
|
||||
extern int memory_address_p PROTO((enum machine_mode, rtx));
|
||||
extern int strict_memory_address_p PROTO((enum machine_mode, rtx));
|
||||
extern int validate_replace_rtx PROTO((rtx, rtx, rtx));
|
||||
@ -103,6 +110,9 @@ extern enum machine_mode recog_operand_mode[];
|
||||
/* Indexed by N, gives the constraint string for operand N. */
|
||||
extern char *recog_constraints[];
|
||||
|
||||
/* Indexed by N, gives the type (in, out, inout) for operand N. */
|
||||
extern enum op_type recog_op_type[];
|
||||
|
||||
#ifndef REGISTER_CONSTRAINTS
|
||||
/* Indexed by N, nonzero if operand N should be an address. */
|
||||
extern char recog_operand_address_p[];
|
||||
|
196
gcc/regclass.c
196
gcc/regclass.c
@ -765,12 +765,9 @@ scan_one_insn (insn, pass)
|
||||
{
|
||||
enum rtx_code code = GET_CODE (insn);
|
||||
enum rtx_code pat_code;
|
||||
|
||||
char *constraints[MAX_RECOG_OPERANDS];
|
||||
enum machine_mode modes[MAX_RECOG_OPERANDS];
|
||||
int nalternatives;
|
||||
int noperands;
|
||||
rtx set;
|
||||
rtx set, note;
|
||||
int i, j;
|
||||
|
||||
/* Show that an insn inside a loop is likely to be executed three
|
||||
@ -799,106 +796,88 @@ scan_one_insn (insn, pass)
|
||||
|| pat_code == ADDR_DIFF_VEC)
|
||||
return insn;
|
||||
|
||||
if (code == INSN
|
||||
&& (noperands = asm_noperands (PATTERN (insn))) >= 0)
|
||||
set = single_set (insn);
|
||||
extract_insn (insn);
|
||||
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
{
|
||||
decode_asm_operands (PATTERN (insn), recog_operand, NULL_PTR,
|
||||
constraints, modes);
|
||||
nalternatives = (noperands == 0 ? 0
|
||||
: n_occurrences (',', constraints[0]) + 1);
|
||||
constraints[i] = recog_constraints[i];
|
||||
modes[i] = recog_operand_mode[i];
|
||||
}
|
||||
else
|
||||
|
||||
/* If this insn loads a parameter from its stack slot, then
|
||||
it represents a savings, rather than a cost, if the
|
||||
parameter is stored in memory. Record this fact. */
|
||||
|
||||
if (set != 0 && GET_CODE (SET_DEST (set)) == REG
|
||||
&& GET_CODE (SET_SRC (set)) == MEM
|
||||
&& (note = find_reg_note (insn, REG_EQUIV,
|
||||
NULL_RTX)) != 0
|
||||
&& GET_CODE (XEXP (note, 0)) == MEM)
|
||||
{
|
||||
int insn_code_number = recog_memoized (insn);
|
||||
rtx note;
|
||||
costs[REGNO (SET_DEST (set))].mem_cost
|
||||
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
|
||||
GENERAL_REGS, 1)
|
||||
* loop_cost);
|
||||
record_address_regs (XEXP (SET_SRC (set), 0),
|
||||
BASE_REG_CLASS, loop_cost * 2);
|
||||
return insn;
|
||||
}
|
||||
|
||||
set = single_set (insn);
|
||||
insn_extract (insn);
|
||||
/* Improve handling of two-address insns such as
|
||||
(set X (ashift CONST Y)) where CONST must be made to
|
||||
match X. Change it into two insns: (set X CONST)
|
||||
(set X (ashift X Y)). If we left this for reloading, it
|
||||
would probably get three insns because X and Y might go
|
||||
in the same place. This prevents X and Y from receiving
|
||||
the same hard reg.
|
||||
|
||||
nalternatives = insn_n_alternatives[insn_code_number];
|
||||
noperands = insn_n_operands[insn_code_number];
|
||||
We can only do this if the modes of operands 0 and 1
|
||||
(which might not be the same) are tieable and we only need
|
||||
do this during our first pass. */
|
||||
|
||||
/* If this insn loads a parameter from its stack slot, then
|
||||
it represents a savings, rather than a cost, if the
|
||||
parameter is stored in memory. Record this fact. */
|
||||
if (pass == 0 && optimize
|
||||
&& recog_n_operands >= 3
|
||||
&& recog_constraints[1][0] == '0'
|
||||
&& recog_constraints[1][1] == 0
|
||||
&& CONSTANT_P (recog_operand[1])
|
||||
&& ! rtx_equal_p (recog_operand[0], recog_operand[1])
|
||||
&& ! rtx_equal_p (recog_operand[0], recog_operand[2])
|
||||
&& GET_CODE (recog_operand[0]) == REG
|
||||
&& MODES_TIEABLE_P (GET_MODE (recog_operand[0]),
|
||||
recog_operand_mode[1]))
|
||||
{
|
||||
rtx previnsn = prev_real_insn (insn);
|
||||
rtx dest
|
||||
= gen_lowpart (recog_operand_mode[1],
|
||||
recog_operand[0]);
|
||||
rtx newinsn
|
||||
= emit_insn_before (gen_move_insn (dest,
|
||||
recog_operand[1]),
|
||||
insn);
|
||||
|
||||
if (set != 0 && GET_CODE (SET_DEST (set)) == REG
|
||||
&& GET_CODE (SET_SRC (set)) == MEM
|
||||
&& (note = find_reg_note (insn, REG_EQUIV,
|
||||
NULL_RTX)) != 0
|
||||
&& GET_CODE (XEXP (note, 0)) == MEM)
|
||||
/* If this insn was the start of a basic block,
|
||||
include the new insn in that block.
|
||||
We need not check for code_label here;
|
||||
while a basic block can start with a code_label,
|
||||
INSN could not be at the beginning of that block. */
|
||||
if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN)
|
||||
{
|
||||
costs[REGNO (SET_DEST (set))].mem_cost
|
||||
-= (MEMORY_MOVE_COST (GET_MODE (SET_DEST (set)),
|
||||
GENERAL_REGS, 1)
|
||||
* loop_cost);
|
||||
record_address_regs (XEXP (SET_SRC (set), 0),
|
||||
BASE_REG_CLASS, loop_cost * 2);
|
||||
return insn;
|
||||
int b;
|
||||
for (b = 0; b < n_basic_blocks; b++)
|
||||
if (insn == basic_block_head[b])
|
||||
basic_block_head[b] = newinsn;
|
||||
}
|
||||
|
||||
/* Improve handling of two-address insns such as
|
||||
(set X (ashift CONST Y)) where CONST must be made to
|
||||
match X. Change it into two insns: (set X CONST)
|
||||
(set X (ashift X Y)). If we left this for reloading, it
|
||||
would probably get three insns because X and Y might go
|
||||
in the same place. This prevents X and Y from receiving
|
||||
the same hard reg.
|
||||
/* This makes one more setting of new insns's dest. */
|
||||
REG_N_SETS (REGNO (recog_operand[0]))++;
|
||||
|
||||
We can only do this if the modes of operands 0 and 1
|
||||
(which might not be the same) are tieable and we only need
|
||||
do this during our first pass. */
|
||||
*recog_operand_loc[1] = recog_operand[0];
|
||||
for (i = recog_n_dups - 1; i >= 0; i--)
|
||||
if (recog_dup_num[i] == 1)
|
||||
*recog_dup_loc[i] = recog_operand[0];
|
||||
|
||||
if (pass == 0 && optimize
|
||||
&& noperands >= 3
|
||||
&& insn_operand_constraint[insn_code_number][1][0] == '0'
|
||||
&& insn_operand_constraint[insn_code_number][1][1] == 0
|
||||
&& CONSTANT_P (recog_operand[1])
|
||||
&& ! rtx_equal_p (recog_operand[0], recog_operand[1])
|
||||
&& ! rtx_equal_p (recog_operand[0], recog_operand[2])
|
||||
&& GET_CODE (recog_operand[0]) == REG
|
||||
&& MODES_TIEABLE_P (GET_MODE (recog_operand[0]),
|
||||
insn_operand_mode[insn_code_number][1]))
|
||||
{
|
||||
rtx previnsn = prev_real_insn (insn);
|
||||
rtx dest
|
||||
= gen_lowpart (insn_operand_mode[insn_code_number][1],
|
||||
recog_operand[0]);
|
||||
rtx newinsn
|
||||
= emit_insn_before (gen_move_insn (dest,
|
||||
recog_operand[1]),
|
||||
insn);
|
||||
|
||||
/* If this insn was the start of a basic block,
|
||||
include the new insn in that block.
|
||||
We need not check for code_label here;
|
||||
while a basic block can start with a code_label,
|
||||
INSN could not be at the beginning of that block. */
|
||||
if (previnsn == 0 || GET_CODE (previnsn) == JUMP_INSN)
|
||||
{
|
||||
int b;
|
||||
for (b = 0; b < n_basic_blocks; b++)
|
||||
if (insn == basic_block_head[b])
|
||||
basic_block_head[b] = newinsn;
|
||||
}
|
||||
|
||||
/* This makes one more setting of new insns's dest. */
|
||||
REG_N_SETS (REGNO (recog_operand[0]))++;
|
||||
|
||||
*recog_operand_loc[1] = recog_operand[0];
|
||||
for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
|
||||
if (recog_dup_num[i] == 1)
|
||||
*recog_dup_loc[i] = recog_operand[0];
|
||||
|
||||
return PREV_INSN (newinsn);
|
||||
}
|
||||
|
||||
for (i = 0; i < noperands; i++)
|
||||
{
|
||||
constraints[i]
|
||||
= insn_operand_constraint[insn_code_number][i];
|
||||
modes[i] = insn_operand_mode[insn_code_number][i];
|
||||
}
|
||||
return PREV_INSN (newinsn);
|
||||
}
|
||||
|
||||
/* If we get here, we are set up to record the costs of all the
|
||||
@ -907,7 +886,7 @@ scan_one_insn (insn, pass)
|
||||
classes for any pseudos, doing it twice if some pair of
|
||||
operands are commutative. */
|
||||
|
||||
for (i = 0; i < noperands; i++)
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
{
|
||||
op_costs[i] = init_cost;
|
||||
|
||||
@ -926,7 +905,7 @@ scan_one_insn (insn, pass)
|
||||
have been initialized. We must do this even if one operand
|
||||
is a constant--see addsi3 in m68k.md. */
|
||||
|
||||
for (i = 0; i < noperands - 1; i++)
|
||||
for (i = 0; i < recog_n_operands - 1; i++)
|
||||
if (constraints[i][0] == '%')
|
||||
{
|
||||
char *xconstraints[MAX_RECOG_OPERANDS];
|
||||
@ -935,23 +914,23 @@ scan_one_insn (insn, pass)
|
||||
/* Handle commutative operands by swapping the constraints.
|
||||
We assume the modes are the same. */
|
||||
|
||||
for (j = 0; j < noperands; j++)
|
||||
for (j = 0; j < recog_n_operands; j++)
|
||||
xconstraints[j] = constraints[j];
|
||||
|
||||
xconstraints[i] = constraints[i+1];
|
||||
xconstraints[i+1] = constraints[i];
|
||||
record_reg_classes (nalternatives, noperands,
|
||||
record_reg_classes (recog_n_alternatives, recog_n_operands,
|
||||
recog_operand, modes, xconstraints,
|
||||
insn);
|
||||
}
|
||||
|
||||
record_reg_classes (nalternatives, noperands, recog_operand,
|
||||
record_reg_classes (recog_n_alternatives, recog_n_operands, recog_operand,
|
||||
modes, constraints, insn);
|
||||
|
||||
/* Now add the cost for each operand to the total costs for
|
||||
its register. */
|
||||
|
||||
for (i = 0; i < noperands; i++)
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
if (GET_CODE (recog_operand[i]) == REG
|
||||
&& REGNO (recog_operand[i]) >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
@ -1171,15 +1150,9 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
|
||||
rtx insn;
|
||||
{
|
||||
int alt;
|
||||
enum op_type {OP_READ, OP_WRITE, OP_READ_WRITE} op_types[MAX_RECOG_OPERANDS];
|
||||
int i, j;
|
||||
rtx set;
|
||||
|
||||
/* By default, each operand is an input operand. */
|
||||
|
||||
for (i = 0; i < n_ops; i++)
|
||||
op_types[i] = OP_READ;
|
||||
|
||||
/* Process each alternative, each time minimizing an operand's cost with
|
||||
the cost for each operand in that alternative. */
|
||||
|
||||
@ -1220,14 +1193,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
|
||||
any modifiers for the operand before we can make this test. */
|
||||
|
||||
while (*p == '%' || *p == '=' || *p == '+' || *p == '&')
|
||||
{
|
||||
if (*p == '=')
|
||||
op_types[i] = OP_WRITE;
|
||||
else if (*p == '+')
|
||||
op_types[i] = OP_READ_WRITE;
|
||||
|
||||
p++;
|
||||
}
|
||||
p++;
|
||||
|
||||
if (p[0] >= '0' && p[0] <= '0' + i && (p[1] == ',' || p[1] == 0))
|
||||
{
|
||||
@ -1477,10 +1443,10 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
|
||||
|
||||
else if (classes[i] != NO_REGS)
|
||||
{
|
||||
if (op_types[i] != OP_WRITE)
|
||||
if (recog_op_type[i] != OP_OUT)
|
||||
alt_cost += copy_cost (op, mode, classes[i], 1);
|
||||
|
||||
if (op_types[i] != OP_READ)
|
||||
if (recog_op_type[i] != OP_IN)
|
||||
alt_cost += copy_cost (op, mode, classes[i], 0);
|
||||
}
|
||||
|
||||
@ -1504,7 +1470,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn)
|
||||
&& REGNO (ops[i]) >= FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
struct costs *pp = &op_costs[i], *qq = &this_op_costs[i];
|
||||
int scale = 1 + (op_types[i] == OP_READ_WRITE);
|
||||
int scale = 1 + (recog_op_type[i] == OP_INOUT);
|
||||
|
||||
pp->mem_cost = MIN (pp->mem_cost,
|
||||
(qq->mem_cost + alt_cost) * scale);
|
||||
|
140
gcc/regmove.c
140
gcc/regmove.c
@ -962,8 +962,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
insn = pass ? PREV_INSN (insn) : NEXT_INSN (insn))
|
||||
{
|
||||
rtx set;
|
||||
int insn_code_number;
|
||||
int operand_number, match_number;
|
||||
int op_no, match_no;
|
||||
|
||||
if (GET_CODE (insn) == NOTE)
|
||||
{
|
||||
@ -1008,11 +1007,9 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
insn_code_number
|
||||
= find_matches (insn, &match);
|
||||
|
||||
if (insn_code_number < 0)
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
if (find_matches (insn, &match) < 0)
|
||||
continue;
|
||||
|
||||
/* Now scan through the operands looking for a source operand
|
||||
@ -1022,21 +1019,19 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
If it dies there, then replace the dest in both operands with
|
||||
the source operand. */
|
||||
|
||||
for (operand_number = 0;
|
||||
operand_number < insn_n_operands[insn_code_number];
|
||||
operand_number++)
|
||||
for (op_no = 0; op_no < recog_n_operands; op_no++)
|
||||
{
|
||||
rtx src, dst, src_subreg;
|
||||
enum reg_class src_class, dst_class;
|
||||
|
||||
match_number = match.with[operand_number];
|
||||
match_no = match.with[op_no];
|
||||
|
||||
/* Nothing to do if the two operands aren't supposed to match. */
|
||||
if (match_number < 0)
|
||||
if (match_no < 0)
|
||||
continue;
|
||||
|
||||
src = recog_operand[operand_number];
|
||||
dst = recog_operand[match_number];
|
||||
src = recog_operand[op_no];
|
||||
dst = recog_operand[match_no];
|
||||
|
||||
if (GET_CODE (src) != REG)
|
||||
continue;
|
||||
@ -1057,7 +1052,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
|
||||
if (REGNO (src) < FIRST_PSEUDO_REGISTER)
|
||||
{
|
||||
if (match.commutative[operand_number] < operand_number)
|
||||
if (match.commutative[op_no] < op_no)
|
||||
regno_src_regno[REGNO (dst)] = REGNO (src);
|
||||
continue;
|
||||
}
|
||||
@ -1065,28 +1060,28 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
if (REG_LIVE_LENGTH (REGNO (src)) < 0)
|
||||
continue;
|
||||
|
||||
/* operand_number/src must be a read-only operand, and
|
||||
/* op_no/src must be a read-only operand, and
|
||||
match_operand/dst must be a write-only operand. */
|
||||
if (match.use[operand_number] != READ
|
||||
|| match.use[match_number] != WRITE)
|
||||
if (match.use[op_no] != READ
|
||||
|| match.use[match_no] != WRITE)
|
||||
continue;
|
||||
|
||||
if (match.early_clobber[match_number]
|
||||
if (match.early_clobber[match_no]
|
||||
&& count_occurrences (PATTERN (insn), src) > 1)
|
||||
continue;
|
||||
|
||||
/* Make sure match_operand is the destination. */
|
||||
if (recog_operand[match_number] != SET_DEST (set))
|
||||
if (recog_operand[match_no] != SET_DEST (set))
|
||||
continue;
|
||||
|
||||
/* If the operands already match, then there is nothing to do. */
|
||||
/* But in the commutative case, we might find a better match. */
|
||||
if (operands_match_p (src, dst)
|
||||
|| (match.commutative[operand_number] >= 0
|
||||
|| (match.commutative[op_no] >= 0
|
||||
&& operands_match_p (recog_operand[match.commutative
|
||||
[operand_number]], dst)
|
||||
[op_no]], dst)
|
||||
&& (replacement_quality (recog_operand[match.commutative
|
||||
[operand_number]])
|
||||
[op_no]])
|
||||
>= replacement_quality (src))))
|
||||
continue;
|
||||
|
||||
@ -1096,7 +1091,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
continue;
|
||||
|
||||
if (fixup_match_1 (insn, set, src, src_subreg, dst, pass,
|
||||
operand_number, match_number,
|
||||
op_no, match_no,
|
||||
regmove_dump_file))
|
||||
break;
|
||||
}
|
||||
@ -1121,11 +1116,10 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
}
|
||||
if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
|
||||
{
|
||||
int insn_code_number = find_matches (insn, &match);
|
||||
int operand_number, match_number;
|
||||
int op_no, match_no;
|
||||
int success = 0;
|
||||
|
||||
if (insn_code_number < 0)
|
||||
|
||||
if (find_matches (insn, &match) < 0)
|
||||
continue;
|
||||
|
||||
/* Now scan through the operands looking for a destination operand
|
||||
@ -1136,9 +1130,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
|
||||
copy_src = NULL_RTX;
|
||||
copy_dst = NULL_RTX;
|
||||
for (operand_number = 0;
|
||||
operand_number < insn_n_operands[insn_code_number];
|
||||
operand_number++)
|
||||
for (op_no = 0; op_no < recog_n_operands; op_no++)
|
||||
{
|
||||
rtx set, p, src, dst;
|
||||
rtx src_note, dst_note;
|
||||
@ -1146,14 +1138,14 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
enum reg_class src_class, dst_class;
|
||||
int length;
|
||||
|
||||
match_number = match.with[operand_number];
|
||||
match_no = match.with[op_no];
|
||||
|
||||
/* Nothing to do if the two operands aren't supposed to match. */
|
||||
if (match_number < 0)
|
||||
if (match_no < 0)
|
||||
continue;
|
||||
|
||||
dst = recog_operand[match_number];
|
||||
src = recog_operand[operand_number];
|
||||
dst = recog_operand[match_no];
|
||||
src = recog_operand[op_no];
|
||||
|
||||
if (GET_CODE (src) != REG)
|
||||
continue;
|
||||
@ -1165,26 +1157,26 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
|
||||
/* If the operands already match, then there is nothing to do. */
|
||||
if (operands_match_p (src, dst)
|
||||
|| (match.commutative[operand_number] >= 0
|
||||
&& operands_match_p (recog_operand[match.commutative[operand_number]], dst)))
|
||||
|| (match.commutative[op_no] >= 0
|
||||
&& operands_match_p (recog_operand[match.commutative[op_no]], dst)))
|
||||
continue;
|
||||
|
||||
set = single_set (insn);
|
||||
if (! set)
|
||||
continue;
|
||||
|
||||
/* match_number/dst must be a write-only operand, and
|
||||
/* match_no/dst must be a write-only operand, and
|
||||
operand_operand/src must be a read-only operand. */
|
||||
if (match.use[operand_number] != READ
|
||||
|| match.use[match_number] != WRITE)
|
||||
if (match.use[op_no] != READ
|
||||
|| match.use[match_no] != WRITE)
|
||||
continue;
|
||||
|
||||
if (match.early_clobber[match_number]
|
||||
if (match.early_clobber[match_no]
|
||||
&& count_occurrences (PATTERN (insn), src) > 1)
|
||||
continue;
|
||||
|
||||
/* Make sure match_number is the destination. */
|
||||
if (recog_operand[match_number] != SET_DEST (set))
|
||||
/* Make sure match_no is the destination. */
|
||||
if (recog_operand[match_no] != SET_DEST (set))
|
||||
continue;
|
||||
|
||||
if (REGNO (src) < FIRST_PSEUDO_REGISTER)
|
||||
@ -1252,11 +1244,11 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
if (regmove_dump_file)
|
||||
fprintf (regmove_dump_file,
|
||||
"Could fix operand %d of insn %d matching operand %d.\n",
|
||||
operand_number, INSN_UID (insn), match_number);
|
||||
op_no, INSN_UID (insn), match_no);
|
||||
|
||||
/* Scan backward to find the first instruction that uses
|
||||
the input operand. If the operand is set here, then
|
||||
replace it in both instructions with match_number. */
|
||||
replace it in both instructions with match_no. */
|
||||
|
||||
for (length = 0, p = PREV_INSN (insn); p; p = PREV_INSN (p))
|
||||
{
|
||||
@ -1304,7 +1296,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
validate_replace_rtx (dst, src, insn);
|
||||
/* Now make sure the dst is right. */
|
||||
validate_change (insn,
|
||||
recog_operand_loc[match_number],
|
||||
recog_operand_loc[match_no],
|
||||
dst, 0);
|
||||
}
|
||||
}
|
||||
@ -1384,7 +1376,7 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
if (regmove_dump_file)
|
||||
fprintf (regmove_dump_file,
|
||||
"Fixed operand %d of insn %d matching operand %d.\n",
|
||||
operand_number, INSN_UID (insn), match_number);
|
||||
op_no, INSN_UID (insn), match_no);
|
||||
|
||||
break;
|
||||
}
|
||||
@ -1413,9 +1405,9 @@ regmove_optimize (f, nregs, regmove_dump_file)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns the INSN_CODE for INSN if its pattern has matching constraints for
|
||||
any operand. Returns -1 if INSN can't be recognized, or if the alternative
|
||||
can't be determined.
|
||||
/* Returns nonzero if INSN's pattern has matching constraints for any operand.
|
||||
Returns 0 if INSN can't be recognized, or if the alternative can't be
|
||||
determined.
|
||||
|
||||
Initialize the info in MATCHP based on the constraints. */
|
||||
|
||||
@ -1425,39 +1417,33 @@ find_matches (insn, matchp)
|
||||
struct match *matchp;
|
||||
{
|
||||
int likely_spilled[MAX_RECOG_OPERANDS];
|
||||
int operand_number;
|
||||
int insn_code_number = recog_memoized (insn);
|
||||
int op_no;
|
||||
int any_matches = 0;
|
||||
|
||||
if (insn_code_number < 0)
|
||||
return -1;
|
||||
|
||||
insn_extract (insn);
|
||||
if (! constrain_operands (insn_code_number, 0))
|
||||
return -1;
|
||||
extract_insn (insn);
|
||||
if (! constrain_operands (0))
|
||||
return 0;
|
||||
|
||||
/* Must initialize this before main loop, because the code for
|
||||
the commutative case may set matches for operands other than
|
||||
the current one. */
|
||||
for (operand_number = insn_n_operands[insn_code_number];
|
||||
--operand_number >= 0; )
|
||||
matchp->with[operand_number] = matchp->commutative[operand_number] = -1;
|
||||
for (op_no = recog_n_operands; --op_no >= 0; )
|
||||
matchp->with[op_no] = matchp->commutative[op_no] = -1;
|
||||
|
||||
for (operand_number = 0; operand_number < insn_n_operands[insn_code_number];
|
||||
operand_number++)
|
||||
for (op_no = 0; op_no < recog_n_operands; op_no++)
|
||||
{
|
||||
char *p, c;
|
||||
int i = 0;
|
||||
|
||||
p = insn_operand_constraint[insn_code_number][operand_number];
|
||||
p = recog_constraints[op_no];
|
||||
|
||||
likely_spilled[operand_number] = 0;
|
||||
matchp->use[operand_number] = READ;
|
||||
matchp->early_clobber[operand_number] = 0;
|
||||
likely_spilled[op_no] = 0;
|
||||
matchp->use[op_no] = READ;
|
||||
matchp->early_clobber[op_no] = 0;
|
||||
if (*p == '=')
|
||||
matchp->use[operand_number] = WRITE;
|
||||
matchp->use[op_no] = WRITE;
|
||||
else if (*p == '+')
|
||||
matchp->use[operand_number] = READWRITE;
|
||||
matchp->use[op_no] = READWRITE;
|
||||
|
||||
for (;*p && i < which_alternative; p++)
|
||||
if (*p == ',')
|
||||
@ -1471,32 +1457,32 @@ find_matches (insn, matchp)
|
||||
case '+':
|
||||
break;
|
||||
case '&':
|
||||
matchp->early_clobber[operand_number] = 1;
|
||||
matchp->early_clobber[op_no] = 1;
|
||||
break;
|
||||
case '%':
|
||||
matchp->commutative[operand_number] = operand_number + 1;
|
||||
matchp->commutative[operand_number + 1] = operand_number;
|
||||
matchp->commutative[op_no] = op_no + 1;
|
||||
matchp->commutative[op_no + 1] = op_no;
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
c -= '0';
|
||||
if (c < operand_number && likely_spilled[(unsigned char) c])
|
||||
if (c < op_no && likely_spilled[(unsigned char) c])
|
||||
break;
|
||||
matchp->with[operand_number] = c;
|
||||
matchp->with[op_no] = c;
|
||||
any_matches = 1;
|
||||
if (matchp->commutative[operand_number] >= 0)
|
||||
matchp->with[matchp->commutative[operand_number]] = c;
|
||||
if (matchp->commutative[op_no] >= 0)
|
||||
matchp->with[matchp->commutative[op_no]] = c;
|
||||
break;
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h':
|
||||
case 'j': case 'k': case 'l': case 'p': case 'q': case 't': case 'u':
|
||||
case 'v': case 'w': case 'x': case 'y': case 'z': case 'A': case 'B':
|
||||
case 'C': case 'D': case 'W': case 'Y': case 'Z':
|
||||
if (CLASS_LIKELY_SPILLED_P (REG_CLASS_FROM_LETTER (c)))
|
||||
likely_spilled[operand_number] = 1;
|
||||
likely_spilled[op_no] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return any_matches ? insn_code_number : -1;
|
||||
return any_matches;
|
||||
}
|
||||
|
||||
/* Try to replace output operand DST in SET, with input operand SRC. SET is
|
||||
|
10
gcc/reload.c
10
gcc/reload.c
@ -2383,8 +2383,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
register int insn_code_number;
|
||||
register int i, j;
|
||||
int noperands;
|
||||
/* These are the constraints for the insn. We don't change them. */
|
||||
char *constraints1[MAX_RECOG_OPERANDS];
|
||||
/* These start out as the constraints for the insn
|
||||
and they are chewed up as we consider alternatives. */
|
||||
char *constraints[MAX_RECOG_OPERANDS];
|
||||
@ -2488,8 +2486,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
noperands * sizeof (enum machine_mode));
|
||||
bcopy ((char *) recog_constraints, (char *) constraints,
|
||||
noperands * sizeof (char *));
|
||||
bcopy ((char *) constraints, (char *) constraints1,
|
||||
noperands * sizeof (char *));
|
||||
|
||||
commutative = -1;
|
||||
|
||||
@ -3360,7 +3356,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
|| modified[j] != RELOAD_WRITE)
|
||||
&& j != i
|
||||
/* Ignore things like match_operator operands. */
|
||||
&& *constraints1[j] != 0
|
||||
&& *recog_constraints[j] != 0
|
||||
/* Don't count an input operand that is constrained to match
|
||||
the early clobber operand. */
|
||||
&& ! (this_alternative_matches[j] == i
|
||||
@ -3477,7 +3473,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
pref_or_nothing[commutative] = pref_or_nothing[commutative + 1];
|
||||
pref_or_nothing[commutative + 1] = t;
|
||||
|
||||
bcopy ((char *) constraints1, (char *) constraints,
|
||||
bcopy ((char *) recog_constraints, (char *) constraints,
|
||||
noperands * sizeof (char *));
|
||||
goto try_swapped;
|
||||
}
|
||||
@ -3594,7 +3590,7 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
|
||||
= find_reloads_toplev (force_const_mem (operand_mode[i],
|
||||
recog_operand[i]),
|
||||
i, address_type[i], ind_levels, 0, insn);
|
||||
if (alternative_allows_memconst (constraints1[i],
|
||||
if (alternative_allows_memconst (recog_constraints[i],
|
||||
goal_alternative_number))
|
||||
goal_alternative_win[i] = 1;
|
||||
}
|
||||
|
@ -4207,8 +4207,7 @@ reload_as_needed (live_known)
|
||||
for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p))
|
||||
if (p != insn && GET_RTX_CLASS (GET_CODE (p)) == 'i'
|
||||
&& (recog_memoized (p) < 0
|
||||
|| (insn_extract (p),
|
||||
! constrain_operands (INSN_CODE (p), 1))))
|
||||
|| (extract_insn (p), ! constrain_operands (1))))
|
||||
{
|
||||
error_for_asm (insn,
|
||||
"`asm' operand requires impossible reload");
|
||||
@ -7670,7 +7669,7 @@ gen_reload (out, in, opnum, type)
|
||||
|
||||
It might be better not to actually emit the insn unless it is valid,
|
||||
but we need to pass the insn as an operand to `recog' and
|
||||
`insn_extract' and it is simpler to emit and then delete the insn if
|
||||
`extract_insn' and it is simpler to emit and then delete the insn if
|
||||
not valid than to dummy things up. */
|
||||
|
||||
rtx op0, op1, tem, insn;
|
||||
@ -7698,11 +7697,11 @@ gen_reload (out, in, opnum, type)
|
||||
|
||||
if (code >= 0)
|
||||
{
|
||||
insn_extract (insn);
|
||||
extract_insn (insn);
|
||||
/* We want constrain operands to treat this insn strictly in
|
||||
its validity determination, i.e., the way it would after reload
|
||||
has completed. */
|
||||
if (constrain_operands (code, 1))
|
||||
if (constrain_operands (1))
|
||||
return insn;
|
||||
}
|
||||
|
||||
@ -7740,11 +7739,11 @@ gen_reload (out, in, opnum, type)
|
||||
|
||||
if (code >= 0)
|
||||
{
|
||||
insn_extract (insn);
|
||||
extract_insn (insn);
|
||||
/* We want constrain operands to treat this insn strictly in
|
||||
its validity determination, i.e., the way it would after reload
|
||||
has completed. */
|
||||
if (constrain_operands (code, 1))
|
||||
if (constrain_operands (1))
|
||||
{
|
||||
/* Add a REG_EQUIV note so that find_equiv_reg can find it. */
|
||||
REG_NOTES (insn)
|
||||
@ -8181,8 +8180,8 @@ inc_for_reload (reloadreg, in, value, inc_amount)
|
||||
code = recog_memoized (add_insn);
|
||||
if (code >= 0)
|
||||
{
|
||||
insn_extract (add_insn);
|
||||
if (constrain_operands (code, 1))
|
||||
extract_insn (add_insn);
|
||||
if (constrain_operands (1))
|
||||
{
|
||||
/* If this is a pre-increment and we have incremented the value
|
||||
where it lives, copy the incremented value to RELOADREG to
|
||||
@ -9005,7 +9004,6 @@ reload_cse_simplify_operands (insn)
|
||||
rtx insn;
|
||||
{
|
||||
#ifdef REGISTER_CONSTRAINTS
|
||||
int insn_code_number, n_operands, n_alternatives;
|
||||
int i,j;
|
||||
|
||||
char *constraints[MAX_RECOG_OPERANDS];
|
||||
@ -9023,41 +9021,33 @@ reload_cse_simplify_operands (insn)
|
||||
int *alternative_order;
|
||||
rtx reg = gen_rtx_REG (VOIDmode, -1);
|
||||
|
||||
/* Find out some information about this insn. */
|
||||
insn_code_number = recog_memoized (insn);
|
||||
/* We don't modify asm instructions. */
|
||||
if (insn_code_number < 0)
|
||||
return 0;
|
||||
extract_insn (insn);
|
||||
|
||||
n_operands = insn_n_operands[insn_code_number];
|
||||
n_alternatives = insn_n_alternatives[insn_code_number];
|
||||
|
||||
if (n_alternatives == 0 || n_operands == 0)
|
||||
if (recog_n_alternatives == 0 || recog_n_operands == 0)
|
||||
return 0;
|
||||
insn_extract (insn);
|
||||
|
||||
/* Figure out which alternative currently matches. */
|
||||
if (! constrain_operands (insn_code_number, 1))
|
||||
if (! constrain_operands (1))
|
||||
fatal_insn_not_found (insn);
|
||||
|
||||
alternative_reject = (int *) alloca (n_alternatives * sizeof (int));
|
||||
alternative_nregs = (int *) alloca (n_alternatives * sizeof (int));
|
||||
alternative_order = (int *) alloca (n_alternatives * sizeof (int));
|
||||
bzero ((char *)alternative_reject, n_alternatives * sizeof (int));
|
||||
bzero ((char *)alternative_nregs, n_alternatives * sizeof (int));
|
||||
alternative_reject = (int *) alloca (recog_n_alternatives * sizeof (int));
|
||||
alternative_nregs = (int *) alloca (recog_n_alternatives * sizeof (int));
|
||||
alternative_order = (int *) alloca (recog_n_alternatives * sizeof (int));
|
||||
bzero ((char *)alternative_reject, recog_n_alternatives * sizeof (int));
|
||||
bzero ((char *)alternative_nregs, recog_n_alternatives * sizeof (int));
|
||||
|
||||
for (i = 0; i < n_operands; i++)
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
int regno;
|
||||
char *p;
|
||||
|
||||
op_alt_regno[i] = (int *) alloca (n_alternatives * sizeof (int));
|
||||
for (j = 0; j < n_alternatives; j++)
|
||||
op_alt_regno[i] = (int *) alloca (recog_n_alternatives * sizeof (int));
|
||||
for (j = 0; j < recog_n_alternatives; j++)
|
||||
op_alt_regno[i][j] = -1;
|
||||
|
||||
p = constraints[i] = insn_operand_constraint[insn_code_number][i];
|
||||
mode = insn_operand_mode[insn_code_number][i];
|
||||
p = constraints[i] = recog_constraints[i];
|
||||
mode = recog_operand_mode[i];
|
||||
|
||||
/* Add the reject values for each alternative given by the constraints
|
||||
for this operand. */
|
||||
@ -9152,21 +9142,21 @@ reload_cse_simplify_operands (insn)
|
||||
|
||||
/* Record all alternatives which are better or equal to the currently
|
||||
matching one in the alternative_order array. */
|
||||
for (i = j = 0; i < n_alternatives; i++)
|
||||
for (i = j = 0; i < recog_n_alternatives; i++)
|
||||
if (alternative_reject[i] <= alternative_reject[which_alternative])
|
||||
alternative_order[j++] = i;
|
||||
n_alternatives = j;
|
||||
recog_n_alternatives = j;
|
||||
|
||||
/* Sort it. Given a small number of alternatives, a dumb algorithm
|
||||
won't hurt too much. */
|
||||
for (i = 0; i < n_alternatives - 1; i++)
|
||||
for (i = 0; i < recog_n_alternatives - 1; i++)
|
||||
{
|
||||
int best = i;
|
||||
int best_reject = alternative_reject[alternative_order[i]];
|
||||
int best_nregs = alternative_nregs[alternative_order[i]];
|
||||
int tmp;
|
||||
|
||||
for (j = i + 1; j < n_alternatives; j++)
|
||||
for (j = i + 1; j < recog_n_alternatives; j++)
|
||||
{
|
||||
int this_reject = alternative_reject[alternative_order[j]];
|
||||
int this_nregs = alternative_nregs[alternative_order[j]];
|
||||
@ -9192,9 +9182,9 @@ reload_cse_simplify_operands (insn)
|
||||
/* Pop back to the real obstacks while changing the insn. */
|
||||
pop_obstacks ();
|
||||
|
||||
for (i = 0; i < n_operands; i++)
|
||||
for (i = 0; i < recog_n_operands; i++)
|
||||
{
|
||||
enum machine_mode mode = insn_operand_mode[insn_code_number][i];
|
||||
enum machine_mode mode = recog_operand_mode[i];
|
||||
if (op_alt_regno[i][j] == -1)
|
||||
continue;
|
||||
|
||||
@ -9202,10 +9192,10 @@ reload_cse_simplify_operands (insn)
|
||||
gen_rtx_REG (mode, op_alt_regno[i][j]), 1);
|
||||
}
|
||||
|
||||
for (i = insn_n_dups[insn_code_number] - 1; i >= 0; i--)
|
||||
for (i = recog_n_dups - 1; i >= 0; i--)
|
||||
{
|
||||
int op = recog_dup_num[i];
|
||||
enum machine_mode mode = insn_operand_mode[insn_code_number][op];
|
||||
enum machine_mode mode = recog_operand_mode[op];
|
||||
|
||||
if (op_alt_regno[op][j] == -1)
|
||||
continue;
|
||||
|
@ -3875,8 +3875,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
|
||||
insn);
|
||||
|
||||
if (recog_memoized (ninsn) < 0
|
||||
|| (insn_extract (ninsn),
|
||||
! constrain_operands (INSN_CODE (ninsn), 1)))
|
||||
|| (extract_insn (ninsn), ! constrain_operands (1)))
|
||||
{
|
||||
delete_insn (ninsn);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user