diff options
author | Richard Sandiford <rdsandiford@googlemail.com> | 2014-06-11 16:58:35 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2014-06-11 16:58:35 +0000 |
commit | 777e635f1a6cab5d2c6837b1ea903ed0bcbe87d3 (patch) | |
tree | 923092a0e7d4f3ea66962e54661707bc328d5327 /gcc | |
parent | 9e6b7874141cf74a8eb0786d7265296f671feac4 (diff) | |
download | gcc-777e635f1a6cab5d2c6837b1ea903ed0bcbe87d3.tar.gz |
system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
gcc/
* system.h (REG_CLASS_FROM_CONSTRAINT): Poison.
(REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise.
(EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise.
* genpreds.c (print_type_tree): New function.
(write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT,
REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT,
EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR.
Write out enum constraint_type and get_constraint_type.
* lra-constraints.c (satisfies_memory_constraint_p): Take a
constraint_num rather than a constraint string.
(satisfies_address_constraint_p): Likewise.
(reg_class_from_constraints): Avoid old constraint macros.
(process_alt_operands, process_address_1): Likewise.
(curr_insn_transform): Likewise.
* ira-costs.c (record_reg_classes): Likewise.
(record_operand_costs): Likewise.
* ira-lives.c (single_reg_class): Likewise.
(ira_implicitly_set_insn_hard_regs): Likewise.
* ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise.
* postreload.c (reload_cse_simplify_operands): Likewise.
* recog.c (asm_operand_ok, preprocess_constraints): Likewise.
(constrain_operands, peep2_find_free_register): Likewise.
* reload.c (push_secondary_reload, scratch_reload_class): Likewise.
(find_reloads, alternative_allows_const_pool_ref): Likewise.
* reload1.c (maybe_fix_stack_asms): Likewise.
* stmt.c (parse_output_constraint, parse_input_constraint): Likewise.
* targhooks.c (default_secondary_reload): Likewise.
* config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference
to EXTRA_CONSTRAINT_STR.
* config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT.
From-SVN: r211471
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 33 | ||||
-rw-r--r-- | gcc/config/m32c/m32c.c | 2 | ||||
-rw-r--r-- | gcc/config/sparc/constraints.md | 2 | ||||
-rw-r--r-- | gcc/genpreds.c | 73 | ||||
-rw-r--r-- | gcc/ira-costs.c | 38 | ||||
-rw-r--r-- | gcc/ira-lives.c | 16 | ||||
-rw-r--r-- | gcc/ira.c | 59 | ||||
-rw-r--r-- | gcc/lra-constraints.c | 148 | ||||
-rw-r--r-- | gcc/postreload.c | 4 | ||||
-rw-r--r-- | gcc/recog.c | 91 | ||||
-rw-r--r-- | gcc/reload.c | 132 | ||||
-rw-r--r-- | gcc/reload1.c | 6 | ||||
-rw-r--r-- | gcc/stmt.c | 21 | ||||
-rw-r--r-- | gcc/system.h | 5 | ||||
-rw-r--r-- | gcc/targhooks.c | 8 |
15 files changed, 350 insertions, 288 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b8c5b38ce73..f79e6ab20cd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,38 @@ 2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + * system.h (REG_CLASS_FROM_CONSTRAINT): Poison. + (REG_CLASS_FOR_CONSTRAINT, EXTRA_CONSTRAINT_STR): Likewise. + (EXTRA_MEMORY_CONSTRAINT, EXTRA_ADDRESS_CONSTRAINT): Likewise. + * genpreds.c (print_type_tree): New function. + (write_tm_preds_h): Remove REG_CLASS_FROM_CONSTRAINT, + REG_CLASS_FOR_CONSTRAINT, EXTRA_MEMORY_CONSTRAINT, + EXTRA_ADDRESS_CONSTRAINT and EXTRA_CONSTRAINT_STR. + Write out enum constraint_type and get_constraint_type. + * lra-constraints.c (satisfies_memory_constraint_p): Take a + constraint_num rather than a constraint string. + (satisfies_address_constraint_p): Likewise. + (reg_class_from_constraints): Avoid old constraint macros. + (process_alt_operands, process_address_1): Likewise. + (curr_insn_transform): Likewise. + * ira-costs.c (record_reg_classes): Likewise. + (record_operand_costs): Likewise. + * ira-lives.c (single_reg_class): Likewise. + (ira_implicitly_set_insn_hard_regs): Likewise. + * ira.c (ira_setup_alts, ira_get_dup_out_num): Likewise. + * postreload.c (reload_cse_simplify_operands): Likewise. + * recog.c (asm_operand_ok, preprocess_constraints): Likewise. + (constrain_operands, peep2_find_free_register): Likewise. + * reload.c (push_secondary_reload, scratch_reload_class): Likewise. + (find_reloads, alternative_allows_const_pool_ref): Likewise. + * reload1.c (maybe_fix_stack_asms): Likewise. + * stmt.c (parse_output_constraint, parse_input_constraint): Likewise. + * targhooks.c (default_secondary_reload): Likewise. + * config/m32c/m32c.c (m32c_matches_constraint_p): Avoid reference + to EXTRA_CONSTRAINT_STR. + * config/sparc/constraints.md (U): Likewise REG_CLASS_FROM_CONSTRAINT. + +2014-06-11 Richard Sandiford <rdsandiford@googlemail.com> + * genpreds.c (write_constraint_satisfied_p_1): Replace with... (write_constraint_satisfied_p_array): ...this new function. (write_tm_preds_h): Replace write_constraint_satisfied_p_1 with diff --git a/gcc/config/m32c/m32c.c b/gcc/config/m32c/m32c.c index 0d7dcee1bc9..69b9c55e534 100644 --- a/gcc/config/m32c/m32c.c +++ b/gcc/config/m32c/m32c.c @@ -854,7 +854,7 @@ m32c_cannot_change_mode_class (enum machine_mode from, #define A0_OR_PSEUDO(x) (IS_REG(x, A0_REGNO) || REGNO (x) >= FIRST_PSEUDO_REGISTER) -/* Implements EXTRA_CONSTRAINT_STR (see next function too). 'S' is +/* Implements matching for constraints (see next function too). 'S' is for memory constraints, plus "Rpa" for PARALLEL rtx's we use for call return values. */ bool diff --git a/gcc/config/sparc/constraints.md b/gcc/config/sparc/constraints.md index 6295be0ef03..587bf371b4f 100644 --- a/gcc/config/sparc/constraints.md +++ b/gcc/config/sparc/constraints.md @@ -171,7 +171,7 @@ ;; define_register_constraint would. This currently means that we cannot ;; use LRA on Sparc, since the constraint processing of LRA really depends ;; upon whether an extra constraint is for registers or not. It uses -;; REG_CLASS_FROM_CONSTRAINT, and checks it against NO_REGS. +;; reg_class_for_constraint, and checks it against NO_REGS. (define_constraint "U" "Pseudo-register or hard even-numbered integer register" (and (match_test "TARGET_ARCH32") diff --git a/gcc/genpreds.c b/gcc/genpreds.c index e5ffb386bde..1613d25f3aa 100644 --- a/gcc/genpreds.c +++ b/gcc/genpreds.c @@ -1232,6 +1232,33 @@ write_range_function (const char *name, unsigned int start, unsigned int end) "}\n\n", name); } +/* VEC is a list of key/value pairs, with the keys being lower bounds + of a range. Output a decision tree that handles the keys covered by + [VEC[START], VEC[END]), returning FALLBACK for keys lower then VEC[START]'s. + INDENT is the number of spaces to indent the code. */ +static void +print_type_tree (const vec <std::pair <unsigned int, const char *> > &vec, + unsigned int start, unsigned int end, const char *fallback, + unsigned int indent) +{ + while (start < end) + { + unsigned int mid = (start + end) / 2; + printf ("%*sif (c >= CONSTRAINT_%s)\n", + indent, "", enum_order[vec[mid].first]->c_name); + if (mid + 1 == end) + print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 2); + else + { + printf ("%*s{\n", indent + 2, ""); + print_type_tree (vec, mid + 1, end, vec[mid].second, indent + 4); + printf ("%*s}\n", indent + 2, ""); + } + end = mid; + } + printf ("%*sreturn %s;\n", indent, "", fallback); +} + /* Write tm-preds.h. Unfortunately, it is impossible to forward-declare an enumeration in portable C, so we have to condition all these prototypes on HAVE_MACHINE_MODES. */ @@ -1321,21 +1348,13 @@ write_tm_preds_h (void) " if (insn_extra_register_constraint (c))\n" " return reg_class_for_constraint_1 (c);\n" " return NO_REGS;\n" - "}\n" - "\n" - "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) \\\n" - " reg_class_for_constraint (lookup_constraint (s_))\n" - "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" - " reg_class_for_constraint (x_)\n"); + "}\n"); else puts ("static inline enum reg_class\n" "reg_class_for_constraint (enum constraint_num)\n" "{\n" " return NO_REGS;\n" - "}\n\n" - "#define REG_CLASS_FROM_CONSTRAINT(c_,s_) NO_REGS\n" - "#define REG_CLASS_FOR_CONSTRAINT(x_) \\\n" - " NO_REGS\n"); + "}\n"); if (have_const_int_constraints) puts ("extern bool insn_const_int_ok_for_constraint " "(HOST_WIDE_INT, enum constraint_num);\n" @@ -1347,19 +1366,27 @@ write_tm_preds_h (void) " constraint_satisfied_p (v_, lookup_constraint (s_))\n"); else puts ("#define CONST_DOUBLE_OK_FOR_CONSTRAINT_P(v_,c_,s_) 0\n"); - if (have_extra_constraints) - puts ("#define EXTRA_CONSTRAINT_STR(v_,c_,s_) \\\n" - " constraint_satisfied_p (v_, lookup_constraint (s_))\n"); - if (have_memory_constraints) - puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) " - "insn_extra_memory_constraint (lookup_constraint (s_))\n"); - else - puts ("#define EXTRA_MEMORY_CONSTRAINT(c_,s_) false\n"); - if (have_address_constraints) - puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) " - "insn_extra_address_constraint (lookup_constraint (s_))\n"); - else - puts ("#define EXTRA_ADDRESS_CONSTRAINT(c_,s_) false\n"); + + puts ("enum constraint_type\n" + "{\n" + " CT_REGISTER,\n" + " CT_MEMORY,\n" + " CT_ADDRESS,\n" + " CT_FIXED_FORM\n" + "};\n" + "\n" + "static inline enum constraint_type\n" + "get_constraint_type (enum constraint_num c)\n" + "{"); + auto_vec <std::pair <unsigned int, const char *>, 3> values; + if (memory_start != memory_end) + values.safe_push (std::make_pair (memory_start, "CT_MEMORY")); + if (address_start != address_end) + values.safe_push (std::make_pair (address_start, "CT_ADDRESS")); + if (address_end != num_constraints) + values.safe_push (std::make_pair (address_end, "CT_FIXED_FORM")); + print_type_tree (values, 0, values.length (), "CT_REGISTER", 2); + puts ("}"); } puts ("#endif /* tm-preds.h */"); diff --git a/gcc/ira-costs.c b/gcc/ira-costs.c index 4ecf75f124d..a93985b1855 100644 --- a/gcc/ira-costs.c +++ b/gcc/ira-costs.c @@ -753,25 +753,28 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, break; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS) - classes[i] = ira_reg_class_subunion[classes[i]] - [REG_CLASS_FROM_CONSTRAINT (c, p)]; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) - win = 1; - - if (EXTRA_MEMORY_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl; + switch (get_constraint_type (cn)) { + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + classes[i] = ira_reg_class_subunion[classes[i]][cl]; + break; + + case CT_MEMORY: /* Every MEM can be reloaded to fit. */ insn_allows_mem[i] = allows_mem[i] = 1; if (MEM_P (op)) win = 1; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { + break; + + case CT_ADDRESS: /* Every address can be reloaded to fit. */ allows_addr = 1; - if (address_operand (op, GET_MODE (op))) + if (address_operand (op, GET_MODE (op)) + || constraint_satisfied_p (op, cn)) win = 1; /* We know this operand is an address, so we want it to be allocated to a hard register @@ -781,8 +784,13 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops, = ira_reg_class_subunion[classes[i]] [base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]; + break; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) + win = 1; + break; } -#endif break; } p += CONSTRAINT_LEN (c, p); @@ -1275,8 +1283,8 @@ record_operand_costs (rtx insn, enum reg_class *pref) XEXP (recog_data.operand[i], 0), 0, MEM, SCRATCH, frequency * 2); else if (constraints[i][0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], - constraints[i])) + || (insn_extra_address_constraint + (lookup_constraint (constraints[i])))) record_address_regs (VOIDmode, ADDR_SPACE_GENERIC, recog_data.operand[i], 0, ADDRESS, SCRATCH, frequency * 2); diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index bb03967225b..e173ae36712 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -759,6 +759,7 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) { int c; enum reg_class cl, next_cl; + enum constraint_num cn; cl = NO_REGS; alternative_mask enabled = recog_data.enabled_alternatives; @@ -849,20 +850,19 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const) case 'A': case 'B': case 'C': case 'D': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'W': case 'Y': case 'Z': -#ifdef EXTRA_CONSTRAINT_STR /* ??? Is this the best way to handle memory constraints? */ - if (EXTRA_MEMORY_CONSTRAINT (c, constraints) - || EXTRA_ADDRESS_CONSTRAINT (c, constraints)) + cn = lookup_constraint (constraints); + if (insn_extra_memory_constraint (cn) + || insn_extra_address_constraint (cn)) return NO_REGS; - if (EXTRA_CONSTRAINT_STR (op, c, constraints) + if (constraint_satisfied_p (op, cn) || (equiv_const != NULL_RTX && CONSTANT_P (equiv_const) - && EXTRA_CONSTRAINT_STR (equiv_const, c, constraints))) + && constraint_satisfied_p (equiv_const, cn))) return NO_REGS; -#endif next_cl = (c == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (c, constraints)); + : reg_class_for_constraint (cn)); if (next_cl == NO_REGS) break; if (cl == NO_REGS @@ -950,7 +950,7 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set) case 'W': case 'Y': case 'Z': cl = (c == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (c, p)); + : reg_class_for_constraint (lookup_constraint (p))); if (cl != NO_REGS) { /* There is no register pressure problem if all of the diff --git a/gcc/ira.c b/gcc/ira.c index 6ee1c140f13..2b63a999d21 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -1922,24 +1922,29 @@ ira_setup_alts (rtx insn, HARD_REG_SET &alts) break; case 'o': + case 'r': goto op_success; break; default: { - enum reg_class cl; - - cl = (c == 'r' ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); - if (cl != NO_REGS) - goto op_success; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) - goto op_success; - else if (EXTRA_MEMORY_CONSTRAINT (c, p)) - goto op_success; - else if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - goto op_success; -#endif + enum constraint_num cn = lookup_constraint (p); + switch (get_constraint_type (cn)) + { + case CT_REGISTER: + if (reg_class_for_constraint (cn) != NO_REGS) + goto op_success; + break; + + case CT_ADDRESS: + case CT_MEMORY: + goto op_success; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) + goto op_success; + break; + } break; } } @@ -1972,9 +1977,6 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) int curr_alt, c, original, dup; bool ignore_p, use_commut_op_p; const char *str; -#ifdef EXTRA_CONSTRAINT_STR - rtx op; -#endif if (op_num < 0 || recog_data.n_alternatives == 0) return -1; @@ -1985,9 +1987,7 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) use_commut_op_p = false; for (;;) { -#ifdef EXTRA_CONSTRAINT_STR - op = recog_data.operand[op_num]; -#endif + rtx op = recog_data.operand[op_num]; for (curr_alt = 0, ignore_p = !TEST_HARD_REG_BIT (alts, curr_alt), original = -1;;) @@ -2010,6 +2010,9 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) case 'g': goto fail; case 'r': + if (!targetm.class_likely_spilled_p (GENERAL_REGS)) + goto fail; + break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'h': case 'j': case 'k': case 'l': case 'q': case 't': case 'u': @@ -2018,19 +2021,13 @@ ira_get_dup_out_num (int op_num, HARD_REG_SET &alts) case 'Q': case 'R': case 'S': case 'T': case 'U': case 'W': case 'Y': case 'Z': { - enum reg_class cl; - - cl = (c == 'r' - ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, str)); - if (cl != NO_REGS) - { - if (! targetm.class_likely_spilled_p (cl)) - goto fail; - } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, str)) + enum constraint_num cn = lookup_constraint (str); + enum reg_class cl = reg_class_for_constraint (cn); + if (cl != NO_REGS + && !targetm.class_likely_spilled_p (cl)) + goto fail; + if (constraint_satisfied_p (op, cn)) goto fail; -#endif break; } diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c index 08716fe698a..8342a0a3e3c 100644 --- a/gcc/lra-constraints.c +++ b/gcc/lra-constraints.c @@ -394,40 +394,38 @@ valid_address_p (struct address_info *ad) return valid_address_p (ad->mode, *ad->outer, ad->as); } -#ifdef EXTRA_CONSTRAINT_STR /* Return true if the eliminated form of memory reference OP satisfies extra memory constraint CONSTRAINT. */ static bool -satisfies_memory_constraint_p (rtx op, const char *constraint) +satisfies_memory_constraint_p (rtx op, enum constraint_num constraint) { struct address_info ad; decompose_mem_address (&ad, op); address_eliminator eliminator (&ad); - return EXTRA_CONSTRAINT_STR (op, *constraint, constraint); + return constraint_satisfied_p (op, constraint); } /* Return true if the eliminated form of address AD satisfies extra address constraint CONSTRAINT. */ static bool satisfies_address_constraint_p (struct address_info *ad, - const char *constraint) + enum constraint_num constraint) { address_eliminator eliminator (ad); - return EXTRA_CONSTRAINT_STR (*ad->outer, *constraint, constraint); + return constraint_satisfied_p (*ad->outer, constraint); } /* Return true if the eliminated form of address OP satisfies extra address constraint CONSTRAINT. */ static bool -satisfies_address_constraint_p (rtx op, const char *constraint) +satisfies_address_constraint_p (rtx op, enum constraint_num constraint) { struct address_info ad; decompose_lea_address (&ad, &op); return satisfies_address_constraint_p (&ad, constraint); } -#endif /* Initiate equivalences for LRA. As we keep original equivalences before any elimination, we need to make copies otherwise any change @@ -982,21 +980,20 @@ reg_class_from_constraints (const char *p) break; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl = reg_class_for_constraint (cn); + if (cl == NO_REGS) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) + if (insn_extra_address_constraint (cn)) op_class = (reg_class_subunion [op_class][base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]); -#endif break; } - op_class - = reg_class_subunion[op_class][REG_CLASS_FROM_CONSTRAINT (c, p)]; - break; + op_class = reg_class_subunion[op_class][cl]; + break; } while ((p += len), c); return op_class; @@ -1712,6 +1709,7 @@ process_alt_operands (int only_alternative) bool this_alternative_offmemok; bool scratch_p; enum machine_mode mode; + enum constraint_num cn; opalt_num = nalt * n_operands + nop; if (curr_static_id->operand_alternative[opalt_num].anything_ok) @@ -2030,76 +2028,55 @@ process_alt_operands (int only_alternative) /* Drop through into 'r' case. */ case 'r': - this_alternative - = reg_class_subunion[this_alternative][GENERAL_REGS]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[GENERAL_REGS]); - if (costly_p) - { - this_costly_alternative - = (reg_class_subunion - [this_costly_alternative][GENERAL_REGS]); - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[GENERAL_REGS]); - } + cl = GENERAL_REGS; goto reg; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + cn = lookup_constraint (p); + switch (get_constraint_type (cn)) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, p)) - { - if (MEM_P (op) - && satisfies_memory_constraint_p (op, p)) - win = true; - else if (spilled_pseudo_p (op)) - win = true; - - /* If we didn't already win, we can reload - constants via force_const_mem or put the - pseudo value into memory, or make other - memory by reloading the address like for - 'o'. */ - if (CONST_POOL_OK_P (mode, op) - || MEM_P (op) || REG_P (op)) - badop = false; - constmemok = true; - offmemok = true; - break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { - if (satisfies_address_constraint_p (op, p)) - win = true; - - /* If we didn't already win, we can reload - the address into a base register. */ - cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH); - this_alternative - = reg_class_subunion[this_alternative][cl]; - IOR_HARD_REG_SET (this_alternative_set, - reg_class_contents[cl]); - if (costly_p) - { - this_costly_alternative - = (reg_class_subunion - [this_costly_alternative][cl]); - IOR_HARD_REG_SET (this_costly_alternative_set, - reg_class_contents[cl]); - } - badop = false; - break; - } + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + goto reg; + break; - if (EXTRA_CONSTRAINT_STR (op, c, p)) + case CT_MEMORY: + if (MEM_P (op) + && satisfies_memory_constraint_p (op, cn)) + win = true; + else if (spilled_pseudo_p (op)) + win = true; + + /* If we didn't already win, we can reload constants + via force_const_mem or put the pseudo value into + memory, or make other memory by reloading the + address like for 'o'. */ + if (CONST_POOL_OK_P (mode, op) + || MEM_P (op) || REG_P (op)) + badop = false; + constmemok = true; + offmemok = true; + break; + + case CT_ADDRESS: + /* If we didn't already win, we can reload the address + into a base register. */ + if (satisfies_address_constraint_p (op, cn)) + win = true; + cl = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); + badop = false; + goto reg; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (op, cn)) win = true; -#endif break; } + break; - cl = REG_CLASS_FROM_CONSTRAINT (c, p); + reg: this_alternative = reg_class_subunion[this_alternative][cl]; IOR_HARD_REG_SET (this_alternative_set, reg_class_contents[cl]); @@ -2110,7 +2087,6 @@ process_alt_operands (int only_alternative) IOR_HARD_REG_SET (this_costly_alternative_set, reg_class_contents[cl]); } - reg: if (mode == BLKmode) break; winreg = true; @@ -2856,10 +2832,11 @@ process_address_1 (int nop, rtx *before, rtx *after) rtx new_reg; rtx op = *curr_id->operand_loc[nop]; const char *constraint = curr_static_id->operand[nop].constraint; + enum constraint_num cn = lookup_constraint (constraint); bool change_p; if (constraint[0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint)) + || insn_extra_address_constraint (cn)) decompose_lea_address (&ad, curr_id->operand_loc[nop]); else if (MEM_P (op)) decompose_mem_address (&ad, op); @@ -2888,14 +2865,12 @@ process_address_1 (int nop, rtx *before, rtx *after) && process_addr_reg (ad.index_term, before, NULL, INDEX_REG_CLASS)) change_p = true; -#ifdef EXTRA_CONSTRAINT_STR - /* Target hooks sometimes reject extra constraint addresses -- use - EXTRA_CONSTRAINT_STR for the validation. */ + /* Target hooks sometimes don't treat extra-constraint addresses as + legitimate address_operands, so handle them specially. */ if (constraint[0] != 'p' - && EXTRA_ADDRESS_CONSTRAINT (constraint[0], constraint) - && satisfies_address_constraint_p (&ad, constraint)) + && insn_extra_address_constraint (cn) + && satisfies_address_constraint_p (&ad, cn)) return change_p; -#endif /* There are three cases where the shape of *AD.INNER may now be invalid: @@ -3617,11 +3592,10 @@ curr_insn_transform (void) { if (c == TARGET_MEM_CONSTRAINT || c == 'o') break; -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, constraint) - && satisfies_memory_constraint_p (tem, constraint)) + enum constraint_num cn = lookup_constraint (constraint); + if (insn_extra_memory_constraint (cn) + && satisfies_memory_constraint_p (tem, cn)) break; -#endif } if (c == '\0' || c == ',' || c == '#') continue; diff --git a/gcc/postreload.c b/gcc/postreload.c index 29ba81b41d5..5b18fc74792 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -574,8 +574,8 @@ reload_cse_simplify_operands (rtx insn, rtx testreg) default: rclass = (reg_class_subunion - [(int) rclass] - [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); + [rclass] + [reg_class_for_constraint (lookup_constraint (p))]); break; case ',': case '\0': diff --git a/gcc/recog.c b/gcc/recog.c index 0a5d82e1a80..94cdeec1fa4 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -1729,6 +1729,7 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) while (*constraint) { + enum constraint_num cn; char c = *constraint; int len; switch (c) @@ -1902,27 +1903,37 @@ asm_operand_ok (rtx op, const char *constraint, const char **constraints) result = 1; break; + case 'r': + reg: + if (!result + && GET_MODE (op) != BLKmode + && register_operand (op, VOIDmode)) + result = 1; + break; + default: - /* For all other letters, we first check for a register class, - otherwise it is an EXTRA_CONSTRAINT. */ - if (REG_CLASS_FROM_CONSTRAINT (c, constraint) != NO_REGS) + cn = lookup_constraint (constraint); + switch (get_constraint_type (cn)) { - case 'r': - if (GET_MODE (op) == BLKmode) - break; - if (register_operand (op, VOIDmode)) - result = 1; + case CT_REGISTER: + if (reg_class_for_constraint (cn) != NO_REGS) + goto reg; + break; + + case CT_MEMORY: + /* Every memory operand can be reloaded to fit. */ + result = result || memory_operand (op, VOIDmode); + break; + + case CT_ADDRESS: + /* Every address operand can be reloaded to fit. */ + result = result || address_operand (op, VOIDmode); + break; + + case CT_FIXED_FORM: + result = result || constraint_satisfied_p (op, cn); + break; } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_MEMORY_CONSTRAINT (c, constraint)) - /* Every memory operand can be reloaded to fit. */ - result = result || memory_operand (op, VOIDmode); - else if (EXTRA_ADDRESS_CONSTRAINT (c, constraint)) - /* Every address operand can be reloaded to fit. */ - result = result || address_operand (op, VOIDmode); - else if (EXTRA_CONSTRAINT_STR (op, c, constraint)) - result = 1; -#endif break; } len = CONSTRAINT_LEN (c, constraint); @@ -2434,13 +2445,21 @@ preprocess_constraints (int n_operands, int n_alternatives, break; default: - if (EXTRA_MEMORY_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + enum reg_class cl; + switch (get_constraint_type (cn)) { + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + op_alt[i].cl = reg_class_subunion[op_alt[i].cl][cl]; + break; + + case CT_MEMORY: op_alt[i].memory_ok = 1; break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { + + case CT_ADDRESS: op_alt[i].is_address = 1; op_alt[i].cl = (reg_class_subunion @@ -2448,12 +2467,10 @@ preprocess_constraints (int n_operands, int n_alternatives, [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]); break; - } - op_alt[i].cl - = (reg_class_subunion - [(int) op_alt[i].cl] - [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]); + case CT_FIXED_FORM: + break; + } break; } p += CONSTRAINT_LEN (c, p); @@ -2846,9 +2863,12 @@ constrain_operands (int strict) default: { enum reg_class cl; + enum constraint_num cn = (c == 'r' + ? CONSTRAINT__UNKNOWN + : lookup_constraint (p)); cl = (c == 'r' - ? GENERAL_REGS : REG_CLASS_FROM_CONSTRAINT (c, p)); + ? GENERAL_REGS : reg_class_for_constraint (cn)); if (cl != NO_REGS) { if (strict < 0 @@ -2860,11 +2880,11 @@ constrain_operands (int strict) && reg_fits_class_p (op, cl, offset, mode))) win = 1; } -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_CONSTRAINT_STR (op, c, p)) + + else if (constraint_satisfied_p (op, cn)) win = 1; - else if (EXTRA_MEMORY_CONSTRAINT (c, p) + else if (insn_extra_memory_constraint (cn) /* Every memory operand can be reloaded to fit. */ && ((strict < 0 && MEM_P (op)) /* Before reload, accept what reload can turn @@ -2874,7 +2894,7 @@ constrain_operands (int strict) || (reload_in_progress && REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER))) win = 1; - else if (EXTRA_ADDRESS_CONSTRAINT (c, p) + else if (insn_extra_address_constraint (cn) /* Every address operand can be reloaded to fit. */ && strict < 0) win = 1; @@ -2885,10 +2905,9 @@ constrain_operands (int strict) && REGNO (op) >= FIRST_PSEUDO_REGISTER && reg_renumber[REGNO (op)] < 0 && reg_equiv_mem (REGNO (op)) != 0 - && EXTRA_CONSTRAINT_STR - (reg_equiv_mem (REGNO (op)), c, p)) + && constraint_satisfied_p + (reg_equiv_mem (REGNO (op)), cn)) win = 1; -#endif break; } } @@ -3283,7 +3302,7 @@ peep2_find_free_register (int from, int to, const char *class_str, } cl = (class_str[0] == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT (class_str[0], class_str)); + : reg_class_for_constraint (lookup_constraint (class_str))); for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { diff --git a/gcc/reload.c b/gcc/reload.c index 87c453c85b8..e4614bb3210 100644 --- a/gcc/reload.c +++ b/gcc/reload.c @@ -401,8 +401,8 @@ push_secondary_reload (int in_p, rtx x, int opnum, int optional, scratch_constraint++; letter = *scratch_constraint; scratch_class = (letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) letter, - scratch_constraint)); + : (reg_class_for_constraint + (lookup_constraint (scratch_constraint)))); rclass = scratch_class; mode = insn_data[(int) icode].operand[2].mode; @@ -560,8 +560,7 @@ scratch_reload_class (enum insn_code icode) scratch_letter = *scratch_constraint; if (scratch_letter == 'r') return GENERAL_REGS; - rclass = REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, - scratch_constraint); + rclass = reg_class_for_constraint (lookup_constraint (scratch_constraint)); gcc_assert (rclass != NO_REGS); return rclass; } @@ -2852,7 +2851,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* Ignore things like match_operator operands. */ ; else if (constraints[i][0] == 'p' - || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])) + || (insn_extra_address_constraint + (lookup_constraint (constraints[i])))) { address_operand_reloaded[i] = find_reloads_address (recog_data.operand_mode[i], (rtx*) 0, @@ -3094,6 +3094,8 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, operand. */ int constmemok = 0; int earlyclobber = 0; + enum constraint_num cn; + enum reg_class cl; /* If the predicate accepts a unary operator, it means that we need to reload the operand, but do not do this for @@ -3489,71 +3491,74 @@ find_reloads (rtx insn, int replace, int ind_levels, int live_known, /* Drop through into 'r' case. */ case 'r': - this_alternative[i] - = reg_class_subunion[this_alternative[i]][(int) GENERAL_REGS]; + cl = GENERAL_REGS; goto reg; default: - if (REG_CLASS_FROM_CONSTRAINT (c, p) == NO_REGS) + cn = lookup_constraint (p); + switch (get_constraint_type (cn)) { -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, p)) - { - if (force_reload) - break; - if (EXTRA_CONSTRAINT_STR (operand, c, p)) - win = 1; - /* If the address was already reloaded, - we win as well. */ - else if (MEM_P (operand) - && address_reloaded[i] == 1) - win = 1; - /* Likewise if the address will be reloaded because - reg_equiv_address is nonzero. For reg_equiv_mem - we have to check. */ - else if (REG_P (operand) - && REGNO (operand) >= FIRST_PSEUDO_REGISTER - && reg_renumber[REGNO (operand)] < 0 - && ((reg_equiv_mem (REGNO (operand)) != 0 - && EXTRA_CONSTRAINT_STR (reg_equiv_mem (REGNO (operand)), c, p)) - || (reg_equiv_address (REGNO (operand)) != 0))) - win = 1; - - /* If we didn't already win, we can reload - constants via force_const_mem, and other - MEMs by reloading the address like for 'o'. */ - if (CONST_POOL_OK_P (operand_mode[i], operand) - || MEM_P (operand)) - badop = 0; - constmemok = 1; - offmemok = 1; - break; - } - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) - { - if (EXTRA_CONSTRAINT_STR (operand, c, p)) - win = 1; - - /* If we didn't already win, we can reload - the address into a base register. */ - this_alternative[i] - = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, - ADDRESS, SCRATCH); - badop = 0; - break; - } + case CT_REGISTER: + cl = reg_class_for_constraint (cn); + if (cl != NO_REGS) + goto reg; + break; - if (EXTRA_CONSTRAINT_STR (operand, c, p)) + case CT_MEMORY: + if (force_reload) + break; + if (constraint_satisfied_p (operand, cn)) + win = 1; + /* If the address was already reloaded, + we win as well. */ + else if (MEM_P (operand) && address_reloaded[i] == 1) + win = 1; + /* Likewise if the address will be reloaded because + reg_equiv_address is nonzero. For reg_equiv_mem + we have to check. */ + else if (REG_P (operand) + && REGNO (operand) >= FIRST_PSEUDO_REGISTER + && reg_renumber[REGNO (operand)] < 0 + && ((reg_equiv_mem (REGNO (operand)) != 0 + && (constraint_satisfied_p + (reg_equiv_mem (REGNO (operand)), + cn))) + || (reg_equiv_address (REGNO (operand)) + != 0))) + win = 1; + + /* If we didn't already win, we can reload + constants via force_const_mem, and other + MEMs by reloading the address like for 'o'. */ + if (CONST_POOL_OK_P (operand_mode[i], operand) + || MEM_P (operand)) + badop = 0; + constmemok = 1; + offmemok = 1; + break; + + case CT_ADDRESS: + if (constraint_satisfied_p (operand, cn)) + win = 1; + + /* If we didn't already win, we can reload + the address into a base register. */ + this_alternative[i] + = base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, + ADDRESS, SCRATCH); + badop = 0; + break; + + case CT_FIXED_FORM: + if (constraint_satisfied_p (operand, cn)) win = 1; -#endif break; } + break; - this_alternative[i] - = (reg_class_subunion - [this_alternative[i]] - [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]); reg: + this_alternative[i] + = reg_class_subunion[this_alternative[i]][cl]; if (GET_MODE (operand) == BLKmode) break; winreg = 1; @@ -4687,11 +4692,10 @@ alternative_allows_const_pool_ref (rtx mem ATTRIBUTE_UNUSED, { if (c == TARGET_MEM_CONSTRAINT || c == 'o') return true; -#ifdef EXTRA_CONSTRAINT_STR - if (EXTRA_MEMORY_CONSTRAINT (c, constraint) - && (mem == NULL || EXTRA_CONSTRAINT_STR (mem, c, constraint))) + enum constraint_num cn = lookup_constraint (constraint); + if (insn_extra_memory_constraint (cn) + && (mem == NULL || constraint_satisfied_p (mem, cn))) return true; -#endif } return false; } diff --git a/gcc/reload1.c b/gcc/reload1.c index 9daafa45097..83e383fe501 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -1437,13 +1437,15 @@ maybe_fix_stack_asms (void) break; default: - if (EXTRA_ADDRESS_CONSTRAINT (c, p)) + enum constraint_num cn = lookup_constraint (p); + if (insn_extra_address_constraint (cn)) cls = (int) reg_class_subunion[cls] [(int) base_reg_class (VOIDmode, ADDR_SPACE_GENERIC, ADDRESS, SCRATCH)]; else cls = (int) reg_class_subunion[cls] - [(int) REG_CLASS_FROM_CONSTRAINT (c, p)]; + [reg_class_for_constraint (cn)]; + break; } p += CONSTRAINT_LEN (c, p); } diff --git a/gcc/stmt.c b/gcc/stmt.c index 7c1ea5d5cb9..1cbf7e9fdf4 100644 --- a/gcc/stmt.c +++ b/gcc/stmt.c @@ -322,12 +322,11 @@ parse_output_constraint (const char **constraint_p, int operand_num, default: if (!ISALPHA (*p)) break; - if (REG_CLASS_FROM_CONSTRAINT (*p, p) != NO_REGS) + enum constraint_num cn = lookup_constraint (p); + if (reg_class_for_constraint (cn) != NO_REGS + || insn_extra_address_constraint (cn)) *allows_reg = true; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_ADDRESS_CONSTRAINT (*p, p)) - *allows_reg = true; - else if (EXTRA_MEMORY_CONSTRAINT (*p, p)) + else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else { @@ -337,7 +336,6 @@ parse_output_constraint (const char **constraint_p, int operand_num, *allows_reg = true; *allows_mem = true; } -#endif break; } @@ -454,13 +452,11 @@ parse_input_constraint (const char **constraint_p, int input_num, error ("invalid punctuation %qc in constraint", constraint[j]); return false; } - if (REG_CLASS_FROM_CONSTRAINT (constraint[j], constraint + j) - != NO_REGS) + enum constraint_num cn = lookup_constraint (constraint + j); + if (reg_class_for_constraint (cn) != NO_REGS + || insn_extra_address_constraint (cn)) *allows_reg = true; -#ifdef EXTRA_CONSTRAINT_STR - else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j], constraint + j)) - *allows_reg = true; - else if (EXTRA_MEMORY_CONSTRAINT (constraint[j], constraint + j)) + else if (insn_extra_memory_constraint (cn)) *allows_mem = true; else { @@ -470,7 +466,6 @@ parse_input_constraint (const char **constraint_p, int input_num, *allows_reg = true; *allows_mem = true; } -#endif break; } diff --git a/gcc/system.h b/gcc/system.h index 51b90676de3..b0be80cac6a 100644 --- a/gcc/system.h +++ b/gcc/system.h @@ -930,7 +930,10 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \ ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS \ REG_CLASS_FROM_LETTER CONST_OK_FOR_LETTER_P \ - CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT + CONST_DOUBLE_OK_FOR_LETTER_P EXTRA_CONSTRAINT \ + REG_CLASS_FROM_CONSTRAINT REG_CLASS_FOR_CONSTRAINT \ + EXTRA_CONSTRAINT_STR EXTRA_MEMORY_CONSTRAINT \ + EXTRA_ADDRESS_CONSTRAINT /* Hooks that are no longer used. */ #pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 61d058a539e..667a8c51d63 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -936,8 +936,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, insn_letter = *insn_constraint; insn_class = (insn_letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) insn_letter, - insn_constraint)); + : (reg_class_for_constraint + (lookup_constraint (insn_constraint)))); gcc_assert (insn_class != NO_REGS); } @@ -954,8 +954,8 @@ default_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x ATTRIBUTE_UNUSED, scratch_letter = *scratch_constraint; scratch_class = (scratch_letter == 'r' ? GENERAL_REGS - : REG_CLASS_FROM_CONSTRAINT ((unsigned char) scratch_letter, - scratch_constraint)); + : (reg_class_for_constraint + (lookup_constraint (scratch_constraint)))); if (reg_class_subset_p (reload_class, insn_class)) { |