diff options
author | Richard Henderson <rth@cygnus.com> | 2000-10-20 10:54:49 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2000-10-20 10:54:49 -0700 |
commit | 4ca0f257ffa8d24fb2aa68c7b4fb69dfb63b9e2c (patch) | |
tree | 17e20885b9b6a6b336ca83bd8420b0e17c168955 /gcc | |
parent | 444751385724c1ed44e29047bfd96bcdba91f522 (diff) | |
download | gcc-4ca0f257ffa8d24fb2aa68c7b4fb69dfb63b9e2c.zip gcc-4ca0f257ffa8d24fb2aa68c7b4fb69dfb63b9e2c.tar.gz gcc-4ca0f257ffa8d24fb2aa68c7b4fb69dfb63b9e2c.tar.bz2 |
regrename.c (rr_replace_reg): Rewrite to use recog_data to perform substitutions...
* regrename.c (rr_replace_reg): Rewrite to use recog_data to
perform substitutions, and apply_change_group to see if it worked.
From-SVN: r36971
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/regrename.c | 170 |
2 files changed, 61 insertions, 112 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index eab6238..6414aec6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -7,6 +7,9 @@ Fri Oct 20 13:33:16 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> * function.c (locate_and_pad_parm): Zero alignment_pad. + * regrename.c (rr_replace_reg): Rewrite to use recog_data to + perform substitutions, and apply_change_group to see if it worked. + Fri Oct 20 13:33:16 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> * dwarf2out.c (add_bound_info): Also ignore COND_EXPR. diff --git a/gcc/regrename.c b/gcc/regrename.c index fb0a3be..968b8b9 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -83,8 +83,7 @@ static int replace_reg_in_block PARAMS ((def_uses *, varray_type *, static int consider_def PARAMS ((rtx, int, def_uses *, int)); static int consider_available PARAMS ((rtx, int, HARD_REG_SET *, int, def_uses *, int)); -static rtx rr_replace_reg PARAMS ((rtx, rtx, rtx, int, rtx, - int *)); +static void rr_replace_reg PARAMS ((rtx, rtx, int, rtx, int *)); static int consider_use PARAMS ((rtx, int, int, int)); static int condmove_p PARAMS ((rtx)); static void dump_def_use_chain PARAMS ((HARD_REG_SET *, def_uses *, @@ -527,8 +526,8 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) rtx reg_use = 0; rtx new_reg = gen_rtx_REG (GET_MODE (reg_def), avail_reg); - rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, def)), reg_def, new_reg, - DESTINATION, VARRAY_RTX (*uid_ruid, def), &status); + rr_replace_reg (reg_def, new_reg, DESTINATION, + VARRAY_RTX (*uid_ruid, def), &status); if (!status) return status; @@ -568,9 +567,8 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) { new_reg = gen_rtx_REG (GET_MODE (reg_use), avail_reg); - rr_replace_reg (PATTERN (VARRAY_RTX (*uid_ruid, du_idx)), reg_use, - new_reg, SOURCE, VARRAY_RTX (*uid_ruid, du_idx), - &status); + rr_replace_reg (reg_use, new_reg, SOURCE, + VARRAY_RTX (*uid_ruid, du_idx), &status); death_note = find_reg_note (VARRAY_RTX (*uid_ruid, du_idx), REG_DEAD, reg_use); if (death_note) @@ -628,134 +626,82 @@ replace_reg_in_block (du, uid_ruid, def, reg_def, avail_reg) /* Try to replace REG_USE in X with REG_SUB if INSN has a REPLACE_TYPE. STATUS is zero if the resulting pattern is not valid. */ -static rtx -rr_replace_reg (x, reg_use, reg_sub, replace_type, insn, status) - rtx x; +static void +rr_replace_reg (reg_use, reg_sub, replace_type, insn, status) rtx reg_use; rtx reg_sub; int replace_type; rtx insn; int *status; { - enum rtx_code code; int i; - const char *fmt; - int n; + int changed = 0; - if (x == 0) - return x; + /* We only perform replacements on operands, since everything else + is by definition hard-coded. Begin by extracting insn information + so that we know where the operands and dups exist. */ + extract_insn (insn); - code = GET_CODE (x); - switch (code) + for (i = recog_data.n_operands - 1; i >= 0; --i) { - case REG: - if (REGNO (x) == REGNO (reg_use)) - { - if (GET_MODE (x) == GET_MODE (reg_use)) - return reg_sub; - else - return gen_rtx_REG (GET_MODE (x), REGNO (reg_sub)); - } + rtx op; - return x; + /* Match replace_type with operand_type and skip those we aren't + supposed to touch. Note that OP_INOUT does _not_ match either + replace_type. */ + if (replace_type == DESTINATION && recog_data.operand_type[i] != OP_OUT) + continue; + if (replace_type == SOURCE && recog_data.operand_type[i] != OP_IN) + continue; - case SET: - if (replace_type == DESTINATION) - SET_DEST (x) = rr_replace_reg (SET_DEST (x), reg_use, reg_sub, - replace_type, insn, status); - else if (replace_type == SOURCE) - { - unsigned int dest_subregno = 0; - int had_subreg = GET_CODE (SET_DEST (x)) == SUBREG; - - if (had_subreg) - dest_subregno = REGNO (XEXP (SET_DEST (x), 0)); - - SET_SRC (x) = rr_replace_reg (SET_SRC (x), reg_use, reg_sub, - replace_type, insn, status); - - /* If the replacement register is not part of the source - then it may be part of a source mem operand. */ - if (GET_CODE (SET_DEST (x)) == MEM - || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT - || GET_CODE (SET_DEST (x)) == SIGN_EXTRACT - || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART) - SET_DEST (x) = rr_replace_reg (SET_DEST (x), reg_use, reg_sub, - replace_type, insn, status); - /* Shared rtl sanity check. */ - if (had_subreg && dest_subregno != REGNO (XEXP (SET_DEST (x), 0))) - { - *status = 0; - return x; - } - } + op = recog_data.operand[i]; + if (GET_CODE (op) != REG) + continue; - n = recog_memoized (insn); - if (n >= 0) + if (REGNO (op) == REGNO (reg_use)) { - int id; - - extract_insn (insn); - - /* Any MATCH_DUP's which are REGs must still match */ - for (id = insn_data[n].n_dups - 1; id >= 0; id--) - { - int opno = recog_data.dup_num[id]; + rtx new = reg_sub; + if (GET_MODE (op) != GET_MODE (reg_use)) + new = gen_rtx_REG (GET_MODE (op), REGNO (reg_sub)); - if (GET_CODE (*recog_data.dup_loc[id]) == REG - && GET_CODE (*recog_data.operand_loc[opno]) == REG - && (REGNO (*recog_data.dup_loc[id]) - != REGNO (*recog_data.operand_loc[opno]))) - *status = 0; - } + validate_change (insn, recog_data.operand_loc[i], new, 1); + recog_data.operand[i] = new; - if (!constrain_operands (1)) - { - *status = 0; - validate_replace_rtx (reg_sub, reg_use, insn); - } + changed |= 1 << i; } - else - *status = 0; - - return x; - - default: - break; } - fmt = GET_RTX_FORMAT (code); - for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) + /* Any MATCH_DUP's for changed operands must also be changed. */ + /* ??? This more or less assumes that operand_type is correct, in + that the dup will be of the appropriate replace_type. */ + for (i = recog_data.n_dups - 1; i >= 0; i--) { - if (fmt[i] == 'e') - XEXP (x, i) = rr_replace_reg (XEXP (x, i), reg_use, reg_sub, - replace_type, insn, status); - if (fmt[i] == 'E') - { - register int xv; + int opno = recog_data.dup_num[i]; + if ((changed >> opno) & 1) + validate_change (insn, recog_data.dup_loc[i], + recog_data.operand[i], 1); + } - for (xv = 0; xv < XVECLEN (x, i); xv++) - { - XVECEXP (x, i, xv) = rr_replace_reg (XVECEXP (x, i, xv), reg_use, - reg_sub, replace_type, insn, - status); - n = recog_memoized (insn); - if (n >= 0) - { - extract_insn (insn); - if (!constrain_operands (1)) - { - *status = 0; - validate_replace_rtx (reg_sub, reg_use, insn); - } - } - else - *status = 0; - } - } + /* Verify that the changes applied so far result in a recognizable insn. */ + if (! apply_change_group ()) + { + *status = 0; + return; } - return x; + /* Verify that there are no other references of the given type to the + register in question. That is, there are no hard-coded references + to this hard register left in the insn. */ + if (replace_type == DESTINATION) + { + if (reg_set_p (reg_use, insn)) + *status = 0; + } + else + { + if (reg_referenced_p (reg_use, PATTERN (insn))) + *status = 0; + } } /* Can REGNO in INSN be considered for renaming, given def INUM in d/u |