https://gcc.gnu.org/g:94f896c7c6c0329077271487219e345bcdcec6ab
commit r16-2502-g94f896c7c6c0329077271487219e345bcdcec6ab Author: Stefan Schulze Frielinghaus <stefa...@gcc.gnu.org> Date: Fri Jul 25 11:04:38 2025 +0200 Determine CONSTRAINT_LEN at run-time [PR121214] Tests gcc.dg/asm-hard-reg-error-{4,5}.c ICE on sparc*-sun-solaris2.11 since in tm-preds.h we end up with #define CONSTRAINT_LEN(c_,s_) 1 and, therefore, do not parse hard register constraints correctly. Hard register constraints are non-single character constraints and require insn_constraint_len() in order to determine the length. In write_tm_preds_h() from genpreds.cc, previously variable constraint_max_namelen was used in order to decide whether we have single or non-single character constraints. The distinction shouldn't be done anymore and we always must call into insn_constraint_len(). While being on it, remove guard constraint_max_namelen>0 since we always have some constraints coming from common.md. This leaves constraint_max_namelen without users so remove it. gcc/ChangeLog: PR middle-end/121214 * genpreds.cc (constraint_max_namelen): Delete. (write_tm_preds_h): Always write insn_constraint_len() and define CONSTRAINT_LEN to it, i.e., remove guard constraint_max_namelen>1. Remove outer guard constraint_max_namelen>0 and re-indent. (write_insn_preds_c): Remove guard constraint_max_namelen>0 and re-indent. Diff: --- gcc/genpreds.cc | 260 +++++++++++++++++++++++++++----------------------------- 1 file changed, 123 insertions(+), 137 deletions(-) diff --git a/gcc/genpreds.cc b/gcc/genpreds.cc index 4f8beeb05140..7ee68c99e559 100644 --- a/gcc/genpreds.cc +++ b/gcc/genpreds.cc @@ -719,7 +719,6 @@ static const char const_dbl_constraints[] = "GH"; /* Summary data used to decide whether to output various functions and macro definitions. */ -static unsigned int constraint_max_namelen; static bool have_register_constraints; static bool have_memory_constraints; static bool have_special_memory_constraints; @@ -942,7 +941,6 @@ add_constraint (const char *name, const char *regclass, *last_constraint_ptr = c; last_constraint_ptr = &c->next_textual; - constraint_max_namelen = MAX (constraint_max_namelen, strlen (name)); have_register_constraints |= c->is_register; have_const_int_constraints |= c->is_const_int; have_extra_constraints |= c->is_extra; @@ -1563,133 +1561,124 @@ write_tm_preds_h (void) "#endif\n" "\n"); - if (constraint_max_namelen > 0) - { - write_enum_constraint_num (); - puts ("extern enum constraint_num lookup_constraint_1 (const char *);\n" - "extern const unsigned char lookup_constraint_array[];\n" + write_enum_constraint_num (); + puts ("extern enum constraint_num lookup_constraint_1 (const char *);\n" + "extern const unsigned char lookup_constraint_array[];\n" + "\n" + "/* Return the constraint at the beginning of P, or" + " CONSTRAINT__UNKNOWN if it\n" + " isn't recognized. */\n" + "\n" + "static inline enum constraint_num\n" + "lookup_constraint (const char *p)\n" + "{\n" + " unsigned int index = lookup_constraint_array" + "[(unsigned char) *p];\n" + " return (index == UCHAR_MAX\n" + " ? lookup_constraint_1 (p)\n" + " : (enum constraint_num) index);\n" + "}\n"); + if (satisfied_start == num_constraints) + puts ("/* Return true if X satisfies constraint C. */\n" + "\n" + "static inline bool\n" + "constraint_satisfied_p (rtx, enum constraint_num)\n" + "{\n" + " return false;\n" + "}\n"); + else + printf ("extern bool (*constraint_satisfied_p_array[]) (rtx);\n" "\n" - "/* Return the constraint at the beginning of P, or" - " CONSTRAINT__UNKNOWN if it\n" - " isn't recognized. */\n" + "/* Return true if X satisfies constraint C. */\n" "\n" - "static inline enum constraint_num\n" - "lookup_constraint (const char *p)\n" - "{\n" - " unsigned int index = lookup_constraint_array" - "[(unsigned char) *p];\n" - " return (index == UCHAR_MAX\n" - " ? lookup_constraint_1 (p)\n" - " : (enum constraint_num) index);\n" - "}\n"); - if (satisfied_start == num_constraints) - puts ("/* Return true if X satisfies constraint C. */\n" - "\n" - "static inline bool\n" - "constraint_satisfied_p (rtx, enum constraint_num)\n" - "{\n" - " return false;\n" - "}\n"); - else - printf ("extern bool (*constraint_satisfied_p_array[]) (rtx);\n" - "\n" - "/* Return true if X satisfies constraint C. */\n" - "\n" - "static inline bool\n" - "constraint_satisfied_p (rtx x, enum constraint_num c)\n" - "{\n" - " int i = (int) c - (int) CONSTRAINT_%s;\n" - " return i >= 0 && constraint_satisfied_p_array[i] (x);\n" - "}\n" - "\n", - enum_order[satisfied_start]->name); - - write_range_function ("insn_extra_register_constraint", - register_start, register_end); - write_range_function ("insn_extra_memory_constraint", - memory_start, memory_end); - write_range_function ("insn_extra_special_memory_constraint", - special_memory_start, special_memory_end); - write_range_function ("insn_extra_relaxed_memory_constraint", - relaxed_memory_start, relaxed_memory_end); - write_range_function ("insn_extra_address_constraint", - address_start, address_end); - write_allows_reg_mem_function (); - - if (constraint_max_namelen > 1) - { - write_insn_constraint_len (); - puts ("#define CONSTRAINT_LEN(c_,s_) " - "insn_constraint_len (c_,s_)\n"); - } - else - puts ("#define CONSTRAINT_LEN(c_,s_) 1\n"); - if (have_register_constraints) - puts ("extern enum reg_class reg_class_for_constraint_1 " - "(enum constraint_num);\n" - "\n" - "static inline enum reg_class\n" - "reg_class_for_constraint (enum constraint_num c)\n" - "{\n" - " if (insn_extra_register_constraint (c))\n" - " return reg_class_for_constraint_1 (c);\n" - " return NO_REGS;\n" - "}\n"); - else - puts ("static inline enum reg_class\n" - "reg_class_for_constraint (enum constraint_num)\n" - "{\n" - " return 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" - "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n" - " insn_const_int_ok_for_constraint (v_, " - "lookup_constraint (s_))\n"); - else - puts ("static inline bool\n" - "insn_const_int_ok_for_constraint (HOST_WIDE_INT," - " enum constraint_num)\n" - "{\n" - " return false;\n" - "}\n"); - - puts ("enum constraint_type\n" + "static inline bool\n" + "constraint_satisfied_p (rtx x, enum constraint_num c)\n" "{\n" - " CT_REGISTER,\n" - " CT_CONST_INT,\n" - " CT_MEMORY,\n" - " CT_SPECIAL_MEMORY,\n" - " CT_RELAXED_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 *>, 4> values; - if (const_int_start != const_int_end) - values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT")); - if (memory_start != memory_end) - values.safe_push (std::make_pair (memory_start, "CT_MEMORY")); - if (special_memory_start != special_memory_end) - values.safe_push (std::make_pair (special_memory_start, - "CT_SPECIAL_MEMORY")); - if (relaxed_memory_start != relaxed_memory_end) - values.safe_push (std::make_pair (relaxed_memory_start, - "CT_RELAXED_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 ("}"); - - write_get_register_filter (); - write_get_register_filter_id (); - } + " int i = (int) c - (int) CONSTRAINT_%s;\n" + " return i >= 0 && constraint_satisfied_p_array[i] (x);\n" + "}\n" + "\n", + enum_order[satisfied_start]->name); + + write_range_function ("insn_extra_register_constraint", + register_start, register_end); + write_range_function ("insn_extra_memory_constraint", + memory_start, memory_end); + write_range_function ("insn_extra_special_memory_constraint", + special_memory_start, special_memory_end); + write_range_function ("insn_extra_relaxed_memory_constraint", + relaxed_memory_start, relaxed_memory_end); + write_range_function ("insn_extra_address_constraint", + address_start, address_end); + write_allows_reg_mem_function (); + + write_insn_constraint_len (); + puts ("#define CONSTRAINT_LEN(c_,s_) insn_constraint_len (c_,s_)\n"); + if (have_register_constraints) + puts ("extern enum reg_class reg_class_for_constraint_1 " + "(enum constraint_num);\n" + "\n" + "static inline enum reg_class\n" + "reg_class_for_constraint (enum constraint_num c)\n" + "{\n" + " if (insn_extra_register_constraint (c))\n" + " return reg_class_for_constraint_1 (c);\n" + " return NO_REGS;\n" + "}\n"); + else + puts ("static inline enum reg_class\n" + "reg_class_for_constraint (enum constraint_num)\n" + "{\n" + " return 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" + "#define CONST_OK_FOR_CONSTRAINT_P(v_,c_,s_) \\\n" + " insn_const_int_ok_for_constraint (v_, " + "lookup_constraint (s_))\n"); + else + puts ("static inline bool\n" + "insn_const_int_ok_for_constraint (HOST_WIDE_INT," + " enum constraint_num)\n" + "{\n" + " return false;\n" + "}\n"); + + puts ("enum constraint_type\n" + "{\n" + " CT_REGISTER,\n" + " CT_CONST_INT,\n" + " CT_MEMORY,\n" + " CT_SPECIAL_MEMORY,\n" + " CT_RELAXED_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 *>, 4> values; + if (const_int_start != const_int_end) + values.safe_push (std::make_pair (const_int_start, "CT_CONST_INT")); + if (memory_start != memory_end) + values.safe_push (std::make_pair (memory_start, "CT_MEMORY")); + if (special_memory_start != special_memory_end) + values.safe_push (std::make_pair (special_memory_start, + "CT_SPECIAL_MEMORY")); + if (relaxed_memory_start != relaxed_memory_end) + values.safe_push (std::make_pair (relaxed_memory_start, + "CT_RELAXED_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 ("}"); + + write_get_register_filter (); + write_get_register_filter_id (); puts ("#endif /* tm-preds.h */"); } @@ -1750,17 +1739,14 @@ write_insn_preds_c (void) FOR_ALL_PREDICATES (p) write_one_predicate_function (p); - if (constraint_max_namelen > 0) - { - write_lookup_constraint_1 (); - write_lookup_constraint_array (); - if (have_register_constraints) - write_reg_class_for_constraint_1 (); - write_constraint_satisfied_p_array (); - - if (have_const_int_constraints) - write_insn_const_int_ok_for_constraint (); - } + write_lookup_constraint_1 (); + write_lookup_constraint_array (); + if (have_register_constraints) + write_reg_class_for_constraint_1 (); + write_constraint_satisfied_p_array (); + + if (have_const_int_constraints) + write_insn_const_int_ok_for_constraint (); write_init_reg_class_start_regs (); }