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:
Bernd Schmidt 1998-11-04 21:25:00 +00:00 committed by Jeff Law
parent 56744d1a2a
commit 0eadeb15bc
11 changed files with 273 additions and 302 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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]);

View File

@ -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

View File

@ -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;
}

View File

@ -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[];

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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;