diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 39 | ||||
-rw-r--r-- | gcc/caller-save.c | 8 | ||||
-rw-r--r-- | gcc/final.c | 13 | ||||
-rw-r--r-- | gcc/genattrtab.c | 6 | ||||
-rw-r--r-- | gcc/recog.c | 80 | ||||
-rw-r--r-- | gcc/recog.h | 12 | ||||
-rw-r--r-- | gcc/regclass.c | 198 | ||||
-rw-r--r-- | gcc/regmove.c | 140 | ||||
-rw-r--r-- | gcc/reload.c | 10 | ||||
-rw-r--r-- | gcc/reload1.c | 68 | ||||
-rw-r--r-- | gcc/reorg.c | 3 |
11 files changed, 274 insertions, 303 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 040e330..ae03458 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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. diff --git a/gcc/caller-save.c b/gcc/caller-save.c index b05e849..371b652 100644 --- a/gcc/caller-save.c +++ b/gcc/caller-save.c @@ -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) diff --git a/gcc/final.c b/gcc/final.c index b750d93..18c4dc5 100644 --- a/gcc/final.c +++ b/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]); diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c index 593fb26..8ac90c6 100644 --- a/gcc/genattrtab.c +++ b/gcc/genattrtab.c @@ -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 diff --git a/gcc/recog.c b/gcc/recog.c index 17ec357..6ae7a31 100644 --- a/gcc/recog.c +++ b/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; } diff --git a/gcc/recog.h b/gcc/recog.h index 1bf77b4..d96da77 100644 --- a/gcc/recog.h +++ b/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[]; diff --git a/gcc/regclass.c b/gcc/regclass.c index d9b6db6..8b5f158 100644 --- a/gcc/regclass.c +++ b/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 - { - int insn_code_number = recog_memoized (insn); - rtx note; - set = single_set (insn); - insn_extract (insn); + /* 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. */ - nalternatives = insn_n_alternatives[insn_code_number]; - noperands = insn_n_operands[insn_code_number]; + 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) + { + 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; + } - /* 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. */ + /* 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. + + 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 (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. - - 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 (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]; + /* This makes one more setting of new insns's dest. */ + REG_N_SETS (REGNO (recog_operand[0]))++; - return PREV_INSN (newinsn); - } + *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]; - 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); diff --git a/gcc/regmove.c b/gcc/regmove.c index 55dd3f3..57227b9 100644 --- a/gcc/regmove.c +++ b/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 diff --git a/gcc/reload.c b/gcc/reload.c index afe4753..dc1f4e4 100644 --- a/gcc/reload.c +++ b/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; } diff --git a/gcc/reload1.c b/gcc/reload1.c index 78c3073..685d783 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -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; diff --git a/gcc/reorg.c b/gcc/reorg.c index a26f9d2..7fac18c 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -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; |