aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>2000-10-20 10:54:49 -0700
committerRichard Henderson <rth@gcc.gnu.org>2000-10-20 10:54:49 -0700
commit4ca0f257ffa8d24fb2aa68c7b4fb69dfb63b9e2c (patch)
tree17e20885b9b6a6b336ca83bd8420b0e17c168955 /gcc
parent444751385724c1ed44e29047bfd96bcdba91f522 (diff)
downloadgcc-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/ChangeLog3
-rw-r--r--gcc/regrename.c170
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