diff options
author | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-14 01:00:10 +0000 |
---|---|---|
committer | law <law@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-07-14 01:00:10 +0000 |
commit | 93b09ee941d266b4f4cfb38148b10fc7242b2eff (patch) | |
tree | 4f43306e6b6516ba2c7464efaa9390aaad67dc16 /gcc/regclass.c | |
parent | 9a77b7457a722c3210ae85949336853909686d61 (diff) | |
download | gcc-93b09ee941d266b4f4cfb38148b10fc7242b2eff.tar.gz |
�
* regclass.c (scan_one_insn): Notice subregs that change the
size of their operand.
(record_reg_classes): Use that to obey CLASS_CANNOT_CHANGE_SIZE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@28096 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r-- | gcc/regclass.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c index 1b6ec9a4b6a..4e162882bd8 100644 --- a/gcc/regclass.c +++ b/gcc/regclass.c @@ -693,7 +693,7 @@ static int loop_cost; static rtx scan_one_insn PROTO((rtx, int)); static void record_reg_classes PROTO((int, int, rtx *, enum machine_mode *, - const char **, rtx)); + char *, const char **, rtx)); static int copy_cost PROTO((rtx, enum machine_mode, enum reg_class, int)); static void record_address_regs PROTO((rtx, enum reg_class, int)); @@ -757,6 +757,7 @@ scan_one_insn (insn, pass) enum rtx_code pat_code; const char *constraints[MAX_RECOG_OPERANDS]; enum machine_mode modes[MAX_RECOG_OPERANDS]; + char subreg_changes_size[MAX_RECOG_OPERANDS]; rtx set, note; int i, j; @@ -794,6 +795,7 @@ scan_one_insn (insn, pass) constraints[i] = recog_constraints[i]; modes[i] = recog_operand_mode[i]; } + memset (subreg_changes_size, 0, sizeof (subreg_changes_size)); /* If this insn loads a parameter from its stack slot, then it represents a savings, rather than a cost, if the @@ -881,7 +883,12 @@ scan_one_insn (insn, pass) op_costs[i] = init_cost; if (GET_CODE (recog_operand[i]) == SUBREG) - recog_operand[i] = SUBREG_REG (recog_operand[i]); + { + rtx inner = SUBREG_REG (recog_operand[i]); + if (GET_MODE_SIZE (modes[i]) != GET_MODE_SIZE (GET_MODE (inner))) + subreg_changes_size[i] = 1; + recog_operand[i] = inner; + } if (GET_CODE (recog_operand[i]) == MEM) record_address_regs (XEXP (recog_operand[i], 0), @@ -910,12 +917,12 @@ scan_one_insn (insn, pass) xconstraints[i] = constraints[i+1]; xconstraints[i+1] = constraints[i]; record_reg_classes (recog_n_alternatives, recog_n_operands, - recog_operand, modes, xconstraints, - insn); + recog_operand, modes, subreg_changes_size, + xconstraints, insn); } record_reg_classes (recog_n_alternatives, recog_n_operands, recog_operand, - modes, constraints, insn); + modes, subreg_changes_size, constraints, insn); /* Now add the cost for each operand to the total costs for its register. */ @@ -1131,11 +1138,13 @@ regclass (f, nregs) alternatives. */ static void -record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn) +record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size, + constraints, insn) int n_alts; int n_ops; rtx *ops; enum machine_mode *modes; + char *subreg_changes_size; const char **constraints; rtx insn; { @@ -1394,6 +1403,16 @@ record_reg_classes (n_alts, n_ops, ops, modes, constraints, insn) constraints[i] = p; +#ifdef CLASS_CANNOT_CHANGE_SIZE + /* If we noted a subreg earlier, and the selected class is a + subclass of CLASS_CANNOT_CHANGE_SIZE, zap it. */ + if (subreg_changes_size[i] + && (reg_class_subunion[(int) CLASS_CANNOT_CHANGE_SIZE] + [(int) classes[i]] + == CLASS_CANNOT_CHANGE_SIZE)) + classes[i] = NO_REGS; +#endif + /* How we account for this operand now depends on whether it is a pseudo register or not. If it is, we first check if any register classes are valid. If not, we ignore this alternative, |