aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-05-27 06:27:03 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-05-27 06:27:03 -0400
commit3061cc5422b176d0b0f7a283582098f777f73ec7 (patch)
tree79f01100754fd17da000c7e09f3c752aef5eb51e /gcc
parenta6ba1470c243802732938fb4afd46828b0647308 (diff)
downloadgcc-3061cc5422b176d0b0f7a283582098f777f73ec7.zip
gcc-3061cc5422b176d0b0f7a283582098f777f73ec7.tar.gz
gcc-3061cc5422b176d0b0f7a283582098f777f73ec7.tar.bz2
(requires_inout): Renamed from requires_inout_p and returns number of alternatives that require a match.
(requires_inout): Renamed from requires_inout_p and returns number of alternatives that require a match. (block_alloc): Use new function and handle case where all alternatives have some operand that must match operand 0. From-SVN: r7358
Diffstat (limited to 'gcc')
-rw-r--r--gcc/local-alloc.c63
1 files changed, 47 insertions, 16 deletions
diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c
index aa32ebf4..107ab9c 100644
--- a/gcc/local-alloc.c
+++ b/gcc/local-alloc.c
@@ -263,7 +263,7 @@ static int find_free_reg PROTO((enum reg_class, enum machine_mode,
static void mark_life PROTO((int, enum machine_mode, int));
static void post_mark_life PROTO((int, enum machine_mode, int, int, int));
static int no_conflict_p PROTO((rtx, rtx, rtx));
-static int requires_inout_p PROTO((char *));
+static int requires_inout PROTO((char *));
/* Allocate a new quantity (new within current basic block)
for register number REGNO which is born at index BIRTH
@@ -1207,13 +1207,21 @@ block_alloc (b)
)
{
#ifdef REGISTER_CONSTRAINTS
+ /* If non-negative, is an operand that must match operand 0. */
int must_match_0 = -1;
-
+ /* Counts number of alternatives that require a match with
+ operand 0. */
+ int n_matching_alts = 0;
for (i = 1; i < insn_n_operands[insn_code_number]; i++)
- if (requires_inout_p
- (insn_operand_constraint[insn_code_number][i]))
- must_match_0 = i;
+ {
+ char *p = insn_operand_constraint[insn_code_number][i];
+ int this_match = (requires_inout (p));
+
+ n_matching_alts += this_match;
+ if (this_match == insn_n_alternatives[insn_code_number])
+ must_match_0 = i;
+ }
#endif
r0 = recog_operand[0];
@@ -1230,6 +1238,16 @@ block_alloc (b)
&& ! (i == must_match_0 - 1
&& insn_operand_constraint[insn_code_number][i][0] == '%'))
continue;
+
+ /* Likewise if each alternative has some operand that
+ must match operand zero. In that case, skip any
+ operand that doesn't list operand 0 since we know that
+ the operand always conflicts with operand 0. We
+ ignore commutatity in this case to keep things simple. */
+ if (n_matching_alts == insn_n_alternatives[insn_code_number]
+ && (0 == requires_inout
+ (insn_operand_constraint[insn_code_number][i])))
+ continue;
#endif
r1 = recog_operand[i];
@@ -2265,26 +2283,25 @@ no_conflict_p (insn, r0, r1)
#ifdef REGISTER_CONSTRAINTS
-/* Return 1 if the constraint string P indicates that the a the operand
- must be equal to operand 0 and that no register is acceptable. */
+/* Return the number of alternatives for which the constraint string P
+ indicates that the operand must be equal to operand 0 and that no register
+ is acceptable. */
static int
-requires_inout_p (p)
+requires_inout (p)
char *p;
{
char c;
int found_zero = 0;
+ int reg_allowed = 0;
+ int num_matching_alts = 0;
while (c = *p++)
switch (c)
{
- case '0':
- found_zero = 1;
- break;
-
case '=': case '+': case '?':
case '#': case '&': case '!':
- case '*': case '%': case ',':
+ case '*': case '%':
case '1': case '2': case '3': case '4':
case 'm': case '<': case '>': case 'V': case 'o':
case 'E': case 'F': case 'G': case 'H':
@@ -2298,14 +2315,28 @@ requires_inout_p (p)
/* These don't say anything we care about. */
break;
+ case ',':
+ if (found_zero && ! reg_allowed)
+ num_matching_alts++;
+
+ found_zero = reg_allowed = 0;
+ break;
+
+ case '0':
+ found_zero = 1;
+ break;
+
case 'p':
case 'g': case 'r':
default:
- /* These mean a register is allowed. Fail if so. */
- return 0;
+ reg_allowed = 1;
+ break;
}
- return found_zero;
+ if (found_zero && ! reg_allowed)
+ num_matching_alts++;
+
+ return num_matching_alts;
}
#endif /* REGISTER_CONSTRAINTS */