Makefile.in (insn-extract.o): Fix dependencies.

* Makefile.in (insn-extract.o): Fix dependencies.
	* genextract.c (main): Generate includes for insn-config.h and
	recog.h.
	Delete generation of declarations which are now in recog.h.
	* genrecog.c (main): Delete generation of definitions which are
	now in recog.c.
	* local-alloc.c (block_alloc): Use extract_insn and the variables
	it sets up instead of looking up values by insn_code.
	* recog.c (recog_operand, recog_operand_loc, recog_dup_loc,
	recog_dup_num): Define here instead of generating the definition in
	genrecog.c.
	(recog_n_operands, recog_n_dups, recog_n_alternatives,
	recog_operand_mode, recog_constraints, recog_operand_address_p):
	New variables.
	(extract_insn): New function.
	* recog.h (extract_insn): Declare function.
	(which_alternative, recog_n_operands, recog_n_dups,
	recog_n_alternatives, recog_operand_mode, recog_constraints,
	recog_operand_address_p): Declare variables.
	* regclass.c (n_occurrences): New static function.
	* reload.c (n_occurrences): Delete function.
	(find_reloads): Use extract_insn.
	* reload.h (n_occurrences): Delete declaration.

From-SVN: r23147
This commit is contained in:
Bernd Schmidt 1998-10-17 01:28:57 +00:00 committed by Jeff Law
parent e02bdac131
commit 0a578fee77
10 changed files with 240 additions and 165 deletions

View File

@ -1,3 +1,29 @@
Sat Oct 17 02:26:03 1998 Bernd Schmidt <crux@pool.informatik.rwth-aachen.de>
* Makefile.in (insn-extract.o): Fix dependencies.
* genextract.c (main): Generate includes for insn-config.h and
recog.h.
Delete generation of declarations which are now in recog.h.
* genrecog.c (main): Delete generation of definitions which are
now in recog.c.
* local-alloc.c (block_alloc): Use extract_insn and the variables
it sets up instead of looking up values by insn_code.
* recog.c (recog_operand, recog_operand_loc, recog_dup_loc,
recog_dup_num): Define here instead of generating the definition in
genrecog.c.
(recog_n_operands, recog_n_dups, recog_n_alternatives,
recog_operand_mode, recog_constraints, recog_operand_address_p):
New variables.
(extract_insn): New function.
* recog.h (extract_insn): Declare function.
(which_alternative, recog_n_operands, recog_n_dups,
recog_n_alternatives, recog_operand_mode, recog_constraints,
recog_operand_address_p): Declare variables.
* regclass.c (n_occurrences): New static function.
* reload.c (n_occurrences): Delete function.
(find_reloads): Use extract_insn.
* reload.h (n_occurrences): Delete declaration.
Sat Oct 17 01:17:51 1998 Jeffrey A Law (law@cygnus.com)
* reload1.c (reload_as_needed): Fix test for when to call

View File

@ -1627,7 +1627,8 @@ s-opinit : $(md_file) genopinit $(srcdir)/move-if-change
$(srcdir)/move-if-change tmp-opinit.c insn-opinit.c
touch s-opinit
insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h toplev.h
insn-extract.o : insn-extract.c $(CONFIG_H) $(RTL_H) system.h toplev.h \
insn-config.h recog.h
$(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -c insn-extract.c
insn-extract.c: s-extract ; @true

View File

@ -460,17 +460,14 @@ from the machine description file `md'. */\n\n");
printf ("#include \"config.h\"\n");
printf ("#include \"system.h\"\n");
printf ("#include \"rtl.h\"\n");
printf ("#include \"insn-config.h\"\n");
printf ("#include \"recog.h\"\n");
printf ("#include \"toplev.h\"\n\n");
/* This variable exists only so it can be the "location"
of any missing operand whose numbers are skipped by a given pattern. */
printf ("static rtx junk ATTRIBUTE_UNUSED;\n");
printf ("extern rtx recog_operand[];\n");
printf ("extern rtx *recog_operand_loc[];\n");
printf ("extern rtx *recog_dup_loc[];\n");
printf ("extern char recog_dup_num[];\n");
printf ("void\ninsn_extract (insn)\n");
printf (" rtx insn;\n");
printf ("{\n");

View File

@ -1802,10 +1802,6 @@ from the machine description file `md'. */\n\n");
printf ("*/\n\n");
printf ("rtx recog_operand[MAX_RECOG_OPERANDS];\n\n");
printf ("rtx *recog_operand_loc[MAX_RECOG_OPERANDS];\n\n");
printf ("rtx *recog_dup_loc[MAX_DUP_OPERANDS];\n\n");
printf ("char recog_dup_num[MAX_DUP_OPERANDS];\n\n");
printf ("#define operands recog_operand\n\n");
next_subroutine_number = 0;

View File

@ -955,13 +955,11 @@ block_alloc (b)
register rtx r0, r1;
int combined_regno = -1;
int i;
int insn_code_number = recog_memoized (insn);
this_insn_number = insn_number;
this_insn = insn;
if (insn_code_number >= 0)
insn_extract (insn);
extract_insn (insn);
which_alternative = -1;
/* Is this insn suitable for tying two registers?
@ -982,11 +980,11 @@ block_alloc (b)
If tying is done, WIN is set nonzero. */
if (insn_code_number >= 0
if (1
#ifdef REGISTER_CONSTRAINTS
&& insn_n_operands[insn_code_number] > 1
&& insn_operand_constraint[insn_code_number][0][0] == '='
&& insn_operand_constraint[insn_code_number][0][1] != '&'
&& recog_n_operands > 1
&& recog_constraints[0][0] == '='
&& recog_constraints[0][1] != '&'
#else
&& GET_CODE (PATTERN (insn)) == SET
&& rtx_equal_p (SET_DEST (PATTERN (insn)), recog_operand[0])
@ -1000,19 +998,19 @@ block_alloc (b)
operand 0. */
int n_matching_alts = 0;
for (i = 1; i < insn_n_operands[insn_code_number]; i++)
for (i = 1; i < recog_n_operands; i++)
{
char *p = insn_operand_constraint[insn_code_number][i];
char *p = recog_constraints[i];
int this_match = (requires_inout (p));
n_matching_alts += this_match;
if (this_match == insn_n_alternatives[insn_code_number])
if (this_match == recog_n_alternatives)
must_match_0 = i;
}
#endif
r0 = recog_operand[0];
for (i = 1; i < insn_n_operands[insn_code_number]; i++)
for (i = 1; i < recog_n_operands; i++)
{
#ifdef REGISTER_CONSTRAINTS
/* Skip this operand if we found an operand that
@ -1021,9 +1019,9 @@ block_alloc (b)
if (must_match_0 >= 0 && i != must_match_0
&& ! (i == must_match_0 + 1
&& insn_operand_constraint[insn_code_number][i-1][0] == '%')
&& recog_constraints[i-1][0] == '%')
&& ! (i == must_match_0 - 1
&& insn_operand_constraint[insn_code_number][i][0] == '%'))
&& recog_constraints[i][0] == '%'))
continue;
/* Likewise if each alternative has some operand that
@ -1031,9 +1029,8 @@ block_alloc (b)
operand that doesn't list operand 0 since we know that
the operand always conflicts with operand 0. We
ignore commutatity in this case to keep things simple. */
if (n_matching_alts == insn_n_alternatives[insn_code_number]
&& (0 == requires_inout
(insn_operand_constraint[insn_code_number][i])))
if (n_matching_alts == recog_n_alternatives
&& 0 == requires_inout (recog_constraints[i]))
continue;
#endif
@ -1044,9 +1041,9 @@ block_alloc (b)
of them. */
if (
#ifdef REGISTER_CONSTRAINTS
insn_operand_constraint[insn_code_number][i][0] == 'p'
recog_constraints[i][0] == 'p'
#else
insn_operand_address_p[insn_code_number][i]
recog_operand_address_p[i]
#endif
)
while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)

View File

@ -54,6 +54,45 @@ static rtx *find_constant_term_loc PROTO((rtx *));
int volatile_ok;
/* The following vectors hold the results from insn_extract. */
/* Indexed by N, gives value of operand N. */
rtx recog_operand[MAX_RECOG_OPERANDS];
/* Indexed by N, gives location where operand N was found. */
rtx *recog_operand_loc[MAX_RECOG_OPERANDS];
/* Indexed by N, gives location where the Nth duplicate-appearance of
an operand was found. This is something that matched MATCH_DUP. */
rtx *recog_dup_loc[MAX_RECOG_OPERANDS];
/* Indexed by N, gives the operand number that was duplicated in the
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;
/* The number of MATCH_DUPs in the insn. */
int recog_n_dups;
/* The number of alternatives in the constraints for the insn. */
int recog_n_alternatives;
/* Indexed by N, gives the mode of operand N. */
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];
#ifndef REGISTER_CONSTRAINTS
/* Indexed by N, nonzero if operand N should be an address. */
char recog_operand_address_p[MAX_RECOG_OPERANDS];
#endif
/* On return from `constrain_operands', indicate which alternative
was satisfied. */
@ -1656,6 +1695,90 @@ adj_offsettable_operand (op, offset)
abort ();
}
/* Analyze INSN and compute the variables recog_n_operands, recog_n_dups,
recog_n_alternatives, recog_operand, recog_operand_loc, recog_constraints,
recog_operand_mode, recog_dup_loc and recog_dup_num.
If REGISTER_CONSTRAINTS is not defined, also compute
recog_operand_address_p. */
void
extract_insn (insn)
rtx insn;
{
int i;
int icode;
int noperands;
rtx body = PATTERN (insn);
recog_n_operands = 0;
recog_n_alternatives = 0;
recog_n_dups = 0;
switch (GET_CODE (body))
{
case USE:
case CLOBBER:
case ASM_INPUT:
case ADDR_VEC:
case ADDR_DIFF_VEC:
return;
case SET:
case PARALLEL:
case ASM_OPERANDS:
recog_n_operands = noperands = asm_noperands (body);
if (noperands >= 0)
{
char *p;
/* This insn is an `asm' with operands. */
/* expand_asm_operands makes sure there aren't too many operands. */
if (noperands > MAX_RECOG_OPERANDS)
abort ();
/* Now get the operand values and constraints out of the insn. */
decode_asm_operands (body, recog_operand, recog_operand_loc,
recog_constraints, recog_operand_mode);
if (noperands > 0)
{
char *p = recog_constraints[0];
recog_n_alternatives = 1;
while (*p)
recog_n_alternatives += (*p++ == ',');
}
#ifndef REGISTER_CONSTRAINTS
bzero (recog_operand_address_p, sizeof recog_operand_address_p);
#endif
break;
}
/* FALLTHROUGH */
default:
/* Ordinary insn: recognize it, get the operands via insn_extract
and get the constraints. */
icode = recog_memoized (insn);
if (icode < 0)
fatal_insn_not_found (insn);
recog_n_operands = noperands = insn_n_operands[icode];
recog_n_alternatives = insn_n_alternatives[icode];
recog_n_dups = insn_n_dups[icode];
insn_extract (insn);
for (i = 0; i < noperands; i++)
{
#ifdef REGISTER_CONSTRAINTS
recog_constraints[i] = insn_operand_constraint[icode][i];
#else
recog_operand_address_p[i] = insn_operand_address_p[icode][i];
#endif
recog_operand_mode[i] = insn_operand_mode[icode][i];
}
}
}
#ifdef REGISTER_CONSTRAINTS
/* Check the operands of an insn (found in recog_operands)

View File

@ -61,10 +61,15 @@ extern int mode_dependent_address_p PROTO((rtx));
extern int recog PROTO((rtx, rtx, int *));
extern void add_clobbers PROTO((rtx, int));
extern void insn_extract PROTO((rtx));
extern void extract_insn PROTO((rtx));
/* Nonzero means volatile operands are recognized. */
extern int volatile_ok;
/* Set by constrain_operands to the number of the alternative that
matched. */
extern int which_alternative;
/* The following vectors hold the results from insn_extract. */
/* Indexed by N, gives value of operand N. */
@ -81,6 +86,28 @@ extern rtx *recog_dup_loc[];
Nth duplicate-appearance of an operand. */
extern char recog_dup_num[];
/* The next variables are set up by extract_insn. */
/* The number of operands of the insn. */
extern int recog_n_operands;
/* The number of MATCH_DUPs in the insn. */
extern int recog_n_dups;
/* The number of alternatives in the constraints for the insn. */
extern int recog_n_alternatives;
/* Indexed by N, gives the mode of operand N. */
extern enum machine_mode recog_operand_mode[];
/* Indexed by N, gives the constraint string for operand N. */
extern char *recog_constraints[];
#ifndef REGISTER_CONSTRAINTS
/* Indexed by N, nonzero if operand N should be an address. */
extern char recog_operand_address_p[];
#endif
/* Access the output function for CODE. */
#define OUT_FCN(CODE) (*insn_outfun[(int) (CODE)])

View File

@ -665,6 +665,7 @@ static int loop_depth;
static int loop_cost;
static int n_occurrences PROTO((int, char *));
static void record_reg_classes PROTO((int, int, rtx *, enum machine_mode *,
char **, rtx));
static int copy_cost PROTO((rtx, enum machine_mode,
@ -707,6 +708,18 @@ regclass_init ()
prefclass = 0;
}
/* Return the number of times character C occurs in string S. */
static int
n_occurrences (c, s)
int c;
char *s;
{
int n = 0;
while (*s)
n += (*s++ == c);
return n;
}
/* This is a pass of the compiler that scans all instructions
and calculates the preferred class for each pseudo-register.
This information can be accessed later by calling `reg_preferred_class'.

View File

@ -2156,19 +2156,6 @@ operands_match_p (x, y)
return 1 + success_2;
}
/* Return the number of times character C occurs in string S. */
int
n_occurrences (c, s)
int c;
char *s;
{
int n = 0;
while (*s)
n += (*s++ == c);
return n;
}
/* Describe the range of registers or memory referenced by X.
If X is a register, set REG_FLAG and put the first register
number into START and the last plus one into END.
@ -2442,7 +2429,6 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
static int last_output_reload_regno = -1;
this_insn = insn;
this_insn_is_asm = 0; /* Tentative. */
n_reloads = 0;
n_replacements = 0;
n_earlyclobbers = 0;
@ -2470,86 +2456,37 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
bzero ((char *) secondary_memlocs_elim, sizeof secondary_memlocs_elim);
#endif
/* Find what kind of insn this is. NOPERANDS gets number of operands.
Make OPERANDS point to a vector of operand values.
Make OPERAND_LOCS point to a vector of pointers to
where the operands were found.
Fill CONSTRAINTS and CONSTRAINTS1 with pointers to the
constraint-strings for this insn.
Return if the insn needs no reload processing. */
switch (GET_CODE (body))
{
case USE:
case CLOBBER:
case ASM_INPUT:
case ADDR_VEC:
case ADDR_DIFF_VEC:
return 0;
case SET:
/* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
is cheap to move between them. If it is not, there may not be an insn
to do the copy, so we may need a reload. */
if (GET_CODE (SET_DEST (body)) == REG
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
&& GET_CODE (SET_SRC (body)) == REG
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
&& REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
return 0;
case PARALLEL:
case ASM_OPERANDS:
reload_n_operands = noperands = asm_noperands (body);
if (noperands >= 0)
{
/* This insn is an `asm' with operands. */
insn_code_number = -1;
this_insn_is_asm = 1;
/* expand_asm_operands makes sure there aren't too many operands. */
if (noperands > MAX_RECOG_OPERANDS)
abort ();
/* Now get the operand values and constraints out of the insn. */
decode_asm_operands (body, recog_operand, recog_operand_loc,
constraints, operand_mode);
if (noperands > 0)
{
bcopy ((char *) constraints, (char *) constraints1,
noperands * sizeof (char *));
n_alternatives = n_occurrences (',', constraints[0]) + 1;
}
break;
}
default:
/* Ordinary insn: recognize it, get the operands via insn_extract
and get the constraints. */
insn_code_number = recog_memoized (insn);
if (insn_code_number < 0)
fatal_insn_not_found (insn);
reload_n_operands = noperands = insn_n_operands[insn_code_number];
n_alternatives = insn_n_alternatives[insn_code_number];
/* Just return "no reloads" if insn has no operands with constraints. */
if (n_alternatives == 0)
return 0;
insn_extract (insn);
for (i = 0; i < noperands; i++)
{
constraints[i] = constraints1[i]
= insn_operand_constraint[insn_code_number][i];
operand_mode[i] = insn_operand_mode[insn_code_number][i];
}
}
if (noperands == 0)
/* Dispose quickly of (set (reg..) (reg..)) if both have hard regs and it
is cheap to move between them. If it is not, there may not be an insn
to do the copy, so we may need a reload. */
if (GET_CODE (body) == SET
&& GET_CODE (SET_DEST (body)) == REG
&& REGNO (SET_DEST (body)) < FIRST_PSEUDO_REGISTER
&& GET_CODE (SET_SRC (body)) == REG
&& REGNO (SET_SRC (body)) < FIRST_PSEUDO_REGISTER
&& REGISTER_MOVE_COST (REGNO_REG_CLASS (REGNO (SET_SRC (body))),
REGNO_REG_CLASS (REGNO (SET_DEST (body)))) == 2)
return 0;
extract_insn (insn);
noperands = reload_n_operands = recog_n_operands;
n_alternatives = recog_n_alternatives;
/* Just return "no reloads" if insn has no operands with constraints. */
if (noperands == 0 || n_alternatives == 0)
return 0;
insn_code_number = INSN_CODE (insn);
this_insn_is_asm = insn_code_number < 0;
bcopy ((char *) recog_operand_mode, (char *) operand_mode,
noperands * sizeof (enum machine_mode));
bcopy ((char *) recog_constraints, (char *) constraints,
noperands * sizeof (char *));
bcopy ((char *) constraints, (char *) constraints1,
noperands * sizeof (char *));
commutative = -1;
/* If we will need to know, later, whether some pair of operands
@ -4272,50 +4209,11 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
replace_reloads = replace;
this_insn = insn;
/* Find what kind of insn this is. NOPERANDS gets number of operands.
Store the operand values in RECOG_OPERAND and the locations
of the words in the insn that point to them in RECOG_OPERAND_LOC.
Return if the insn needs no reload processing. */
extract_insn (insn);
switch (GET_CODE (body))
{
case USE:
case CLOBBER:
case ASM_INPUT:
case ADDR_VEC:
case ADDR_DIFF_VEC:
return;
case PARALLEL:
case SET:
noperands = asm_noperands (body);
if (noperands >= 0)
{
/* This insn is an `asm' with operands.
First, find out how many operands, and allocate space. */
insn_code_number = -1;
/* ??? This is a bug! ???
Give up and delete this insn if it has too many operands. */
if (noperands > MAX_RECOG_OPERANDS)
abort ();
/* Now get the operand values out of the insn. */
decode_asm_operands (body, recog_operand, recog_operand_loc,
NULL_PTR, NULL_PTR);
break;
}
default:
/* Ordinary insn: recognize it, allocate space for operands and
constraints, and get them out via insn_extract. */
insn_code_number = recog_memoized (insn);
noperands = insn_n_operands[insn_code_number];
insn_extract (insn);
}
noperands = reload_n_operands = recog_n_operands;
/* Return if the insn needs no reload processing. */
if (noperands == 0)
return;

View File

@ -247,9 +247,6 @@ extern int remove_address_replacements PROTO((rtx in_rtx));
autoincrement and autodecrement. */
extern int operands_match_p PROTO((rtx, rtx));
/* Return the number of times character C occurs in string S. */
extern int n_occurrences PROTO((int, char *));
/* Return 1 if altering OP will not modify the value of CLOBBER. */
extern int safe_from_earlyclobber PROTO((rtx, rtx));