aboutsummaryrefslogtreecommitdiff
path: root/gcc/regclass.c
diff options
context:
space:
mode:
authorRichard Kenner <kenner@vlsi1.ultra.nyu.edu>1999-11-01 12:57:38 +0000
committerRichard Kenner <kenner@gcc.gnu.org>1999-11-01 07:57:38 -0500
commitda2c02192bfb2849b893b0c71e1b007db6426b7c (patch)
tree72c8057bcf13f26641ce774f9aaf5b65d87f2810 /gcc/regclass.c
parentffa669ea3c0d3d4a01bda872b40064151970f5aa (diff)
downloadgcc-da2c02192bfb2849b893b0c71e1b007db6426b7c.zip
gcc-da2c02192bfb2849b893b0c71e1b007db6426b7c.tar.gz
gcc-da2c02192bfb2849b893b0c71e1b007db6426b7c.tar.bz2
regclass.c (record_reg_classes): In matching case, recompute costs since the direction of movement is different.
* regclass.c (record_reg_classes): In matching case, recompute costs since the direction of movement is different. From-SVN: r30319
Diffstat (limited to 'gcc/regclass.c')
-rw-r--r--gcc/regclass.c55
1 files changed, 43 insertions, 12 deletions
diff --git a/gcc/regclass.c b/gcc/regclass.c
index 7cfa62e..46e61d2 100644
--- a/gcc/regclass.c
+++ b/gcc/regclass.c
@@ -1160,6 +1160,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
int alt_fail = 0;
int alt_cost = 0;
enum reg_class classes[MAX_RECOG_OPERANDS];
+ int allows_mem[MAX_RECOG_OPERANDS];
int class;
for (i = 0; i < n_ops; i++)
@@ -1168,12 +1169,12 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
rtx op = ops[i];
enum machine_mode mode = modes[i];
int allows_addr = 0;
- int allows_mem = 0;
int win = 0;
unsigned char c;
/* Initially show we know nothing about the register class. */
classes[i] = NO_REGS;
+ allows_mem[i] = 0;
/* If this operand has no constraints at all, we can conclude
nothing about it since anything is valid. */
@@ -1196,8 +1197,12 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
if (p[0] >= '0' && p[0] <= '0' + i && (p[1] == ',' || p[1] == 0))
{
+ /* Copy class and whether memory is allowed from the matching
+ alternative. Then perform any needed cost computations
+ and/or adjustments. */
j = p[0] - '0';
classes[i] = classes[j];
+ allows_mem[i] = allows_mem[j];
if (GET_CODE (op) != REG || REGNO (op) < FIRST_PSEUDO_REGISTER)
{
@@ -1233,12 +1238,38 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
}
else
{
- /* The costs of this operand are the same as that of the
- other operand. However, if we cannot tie them, this
- alternative needs to do a copy, which is one
- instruction. */
+ /* The costs of this operand are not the same as the other
+ operand since move costs are not symmetric. Moreover,
+ if we cannot tie them, this alternative needs to do a
+ copy, which is one instruction. */
+
+ struct costs *pp = &this_op_costs[i];
+
+ for (class = 0; class < N_REG_CLASSES; class++)
+ pp->cost[class]
+ = (recog_data.operand_type[i] == OP_IN
+ ? may_move_cost[class][(int) classes[i]]
+ : move_cost[(int) classes[i]][class]);
+
+ /* If the alternative actually allows memory, make things
+ a bit cheaper since we won't need an extra insn to
+ load it. */
+
+ pp->mem_cost
+ = (MEMORY_MOVE_COST (mode, classes[i],
+ recog_data.operand_type[i] == OP_IN)
+ - allows_mem[i]);
+
+ /* If we have assigned a class to this register in our
+ first pass, add a cost to this alternative corresponding
+ to what we would add if this register were not in the
+ appropriate class. */
+
+ if (prefclass)
+ alt_cost
+ += (may_move_cost[(unsigned char) prefclass[REGNO (op)]]
+ [(int) classes[i]]);
- this_op_costs[i] = this_op_costs[j];
if (REGNO (ops[i]) != REGNO (ops[j])
&& ! find_reg_note (insn, REG_DEAD, op))
alt_cost += 2;
@@ -1287,7 +1318,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
case 'm': case 'o': case 'V':
/* It doesn't seem worth distinguishing between offsettable
and non-offsettable addresses here. */
- allows_mem = 1;
+ allows_mem[i] = 1;
if (GET_CODE (op) == MEM)
win = 1;
break;
@@ -1388,7 +1419,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
#endif
))
win = 1;
- allows_mem = 1;
+ allows_mem[i] = 1;
case 'r':
classes[i]
= reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
@@ -1448,7 +1479,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
pp->mem_cost
= (MEMORY_MOVE_COST (mode, classes[i],
recog_data.operand_type[i] == OP_IN)
- - allows_mem);
+ - allows_mem[i]);
/* If we have assigned a class to this register in our
first pass, add a cost to this alternative corresponding
@@ -1486,7 +1517,7 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
/* The only other way this alternative can be used is if this is a
constant that could be placed into memory. */
- else if (CONSTANT_P (op) && (allows_addr || allows_mem))
+ else if (CONSTANT_P (op) && (allows_addr || allows_mem[i]))
alt_cost += MEMORY_MOVE_COST (mode, classes[i], 1);
else
alt_fail = 1;
@@ -1530,9 +1561,9 @@ record_reg_classes (n_alts, n_ops, ops, modes, subreg_changes_size,
int nr;
if (regno >= FIRST_PSEUDO_REGISTER && prefclass != 0
- && (reg_class_size[(unsigned char)prefclass[regno]]
+ && (reg_class_size[(unsigned char) prefclass[regno]]
== CLASS_MAX_NREGS (prefclass[regno], mode)))
- op_costs[i].cost[(unsigned char)prefclass[regno]] = -1;
+ op_costs[i].cost[(unsigned char) prefclass[regno]] = -1;
else if (regno < FIRST_PSEUDO_REGISTER)
for (class = 0; class < N_REG_CLASSES; class++)
if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)