diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-17 01:28:57 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1998-10-17 01:28:57 +0000 |
commit | 5d07813e199bdc0b11ce8f182fc6fa808f1dd6f6 (patch) | |
tree | 1c32cb74e56fdcc9e94bba84731ea49ea1e5910f | |
parent | a784e9ced179b2b66c6c9e64df595955d3abed0c (diff) | |
download | gcc-5d07813e199bdc0b11ce8f182fc6fa808f1dd6f6.tar.gz |
* 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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@23147 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/Makefile.in | 3 | ||||
-rw-r--r-- | gcc/genextract.c | 7 | ||||
-rw-r--r-- | gcc/genrecog.c | 4 | ||||
-rw-r--r-- | gcc/local-alloc.c | 33 | ||||
-rw-r--r-- | gcc/recog.c | 123 | ||||
-rw-r--r-- | gcc/recog.h | 27 | ||||
-rw-r--r-- | gcc/regclass.c | 13 | ||||
-rw-r--r-- | gcc/reload.c | 158 | ||||
-rw-r--r-- | gcc/reload.h | 3 |
10 files changed, 236 insertions, 161 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42684765878..9907808cdf3 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/Makefile.in b/gcc/Makefile.in index fdf3ab21528..7d01d8b6ead 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -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 diff --git a/gcc/genextract.c b/gcc/genextract.c index 991d1d0a5e5..a1e48ed92ea 100644 --- a/gcc/genextract.c +++ b/gcc/genextract.c @@ -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"); diff --git a/gcc/genrecog.c b/gcc/genrecog.c index 5c1046a6b24..ee33a0c189e 100644 --- a/gcc/genrecog.c +++ b/gcc/genrecog.c @@ -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; diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 1e6955ac6ca..f26167ffd1f 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -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) diff --git a/gcc/recog.c b/gcc/recog.c index 97eccbcf6c1..261bb4d1646 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -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) diff --git a/gcc/recog.h b/gcc/recog.h index 980b76f70d7..195efe39264 100644 --- a/gcc/recog.h +++ b/gcc/recog.h @@ -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)]) diff --git a/gcc/regclass.c b/gcc/regclass.c index 601b2f797a6..bfb5fe65345 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -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'. diff --git a/gcc/reload.c b/gcc/reload.c index 6f3ba43b26a..a60841ff09a 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -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,85 +2456,36 @@ 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; + /* 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; - /* expand_asm_operands makes sure there aren't too many operands. */ - if (noperands > MAX_RECOG_OPERANDS) - abort (); + extract_insn (insn); - /* Now get the operand values and constraints out of the insn. */ + noperands = reload_n_operands = recog_n_operands; + n_alternatives = recog_n_alternatives; - 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; - } + /* Just return "no reloads" if insn has no operands with constraints. */ + if (noperands == 0 || n_alternatives == 0) + return 0; - default: - /* Ordinary insn: recognize it, get the operands via insn_extract - and get the constraints. */ + insn_code_number = INSN_CODE (insn); + this_insn_is_asm = insn_code_number < 0; - 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) - return 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; @@ -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. */ - - switch (GET_CODE (body)) - { - case USE: - case CLOBBER: - case ASM_INPUT: - case ADDR_VEC: - case ADDR_DIFF_VEC: - return; + extract_insn (insn); - 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; diff --git a/gcc/reload.h b/gcc/reload.h index e49da9abc34..24e6aa8ccf9 100644 --- a/gcc/reload.h +++ b/gcc/reload.h @@ -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)); |