diff options
author | Richard Sandiford <richard.sandiford@arm.com> | 2019-05-12 11:28:01 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2019-05-12 11:28:01 +0000 |
commit | 75df257b38bd4cdcb750fc893c5023363230cfe8 (patch) | |
tree | c3e45e445fd98056a3ab6ec685befd4449426000 /gcc/read-rtl.c | |
parent | 4c0164573e213045052ca6bc3113d7d63cf62816 (diff) | |
download | gcc-75df257b38bd4cdcb750fc893c5023363230cfe8.zip gcc-75df257b38bd4cdcb750fc893c5023363230cfe8.tar.gz gcc-75df257b38bd4cdcb750fc893c5023363230cfe8.tar.bz2 |
Accept code attributes as rtx codes in .md files
The recent AArch64 absolute difference patterns had to go through
some hoops to pair max/min rtx codes with the same signedness.
I also need to pair signed/unsigned codes with sign/zero extension
for some SVE ACLE patterns.
This patch therefore supports <...> as rtx codes, like we already
do for modes.
2019-05-12 Richard Sandiford <richard.sandiford@arm.com>
gcc/
* doc/md.texi: Document use of code attributes in rtx patterns.
* read-md.h (rtx_reader::rtx_alloc_for_name): New member function.
* read-rtl.c (find_code): Split out search loops into...
(maybe_find_code): ...this new function.
(check_code_iterator): Make the error message more informative.
(check_code_attribute): New function.
(rtx_reader::rtx_alloc_for_name): Likewise.
(rtx_reader::read_rtx_code): Use rtx_alloc_for_name.
* config/aarch64/predicates.md (aarch64_smin, aarch64_umin): Delete.
* config/aarch64/aarch64-simd.md (*aarch64_<su>abd<mode>_3): Use
<max_opp> directly as an rtx code instead of via a match_operator.
* config/aarch64/aarch64-sve.md (aarch64_<su>abd<mode>_3): Likewise.
(<su>abd<mode>_3): Update accordingly.
From-SVN: r271107
Diffstat (limited to 'gcc/read-rtl.c')
-rw-r--r-- | gcc/read-rtl.c | 126 |
1 files changed, 99 insertions, 27 deletions
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c index ebd69bd..f72b2c3 100644 --- a/gcc/read-rtl.c +++ b/gcc/read-rtl.c @@ -194,22 +194,31 @@ static const compact_insn_name compact_insn_names[] = { { NOTE, "cnote" } }; -/* Implementations of the iterator_group callbacks for codes. */ +/* Return the rtx code for NAME, or UNKNOWN if NAME isn't a valid rtx code. */ -static int -find_code (const char *name) +static rtx_code +maybe_find_code (const char *name) { - int i; - - for (i = 0; i < NUM_RTX_CODE; i++) + for (int i = 0; i < NUM_RTX_CODE; i++) if (strcmp (GET_RTX_NAME (i), name) == 0) - return i; + return (rtx_code) i; - for (i = 0; i < (signed)ARRAY_SIZE (compact_insn_names); i++) + for (int i = 0; i < (signed)ARRAY_SIZE (compact_insn_names); i++) if (strcmp (compact_insn_names[i].name, name) == 0) return compact_insn_names[i].code; - fatal_with_file_and_line ("unknown rtx code `%s'", name); + return UNKNOWN; +} + +/* Implementations of the iterator_group callbacks for codes. */ + +static int +find_code (const char *name) +{ + rtx_code code = maybe_find_code (name); + if (code == UNKNOWN) + fatal_with_file_and_line ("unknown rtx code `%s'", name); + return code; } static void @@ -1306,7 +1315,37 @@ check_code_iterator (struct mapping *iterator) for (v = iterator->values->next; v != 0; v = v->next) if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0) fatal_with_file_and_line ("code iterator `%s' combines " - "different rtx formats", iterator->name); + "`%s' and `%s', which have different " + "rtx formats", iterator->name, + GET_RTX_NAME (bellwether), + GET_RTX_NAME (v->number)); +} + +/* Check that all values of attribute ATTR are rtx codes that have a + consistent format. Return a representative code. */ + +static rtx_code +check_code_attribute (mapping *attr) +{ + rtx_code bellwether = UNKNOWN; + for (map_value *v = attr->values; v != 0; v = v->next) + { + rtx_code code = maybe_find_code (v->string); + if (code == UNKNOWN) + fatal_with_file_and_line ("code attribute `%s' contains " + "unrecognized rtx code `%s'", + attr->name, v->string); + if (bellwether == UNKNOWN) + bellwether = code; + else if (strcmp (GET_RTX_FORMAT (bellwether), + GET_RTX_FORMAT (code)) != 0) + fatal_with_file_and_line ("code attribute `%s' combines " + "`%s' and `%s', which have different " + "rtx formats", attr->name, + GET_RTX_NAME (bellwether), + GET_RTX_NAME (code)); + } + return bellwether; } /* Read an rtx-related declaration from the MD file, given that it @@ -1467,6 +1506,54 @@ parse_reg_note_name (const char *string) fatal_with_file_and_line ("unrecognized REG_NOTE name: `%s'", string); } +/* Allocate an rtx for code NAME. If NAME is a code iterator or code + attribute, record its use for later and use one of its possible + values as an interim rtx code. */ + +rtx +rtx_reader::rtx_alloc_for_name (const char *name) +{ +#ifdef GENERATOR_FILE + size_t len = strlen (name); + if (name[0] == '<' && name[len - 1] == '>') + { + /* Copy the attribute string into permanent storage, without the + angle brackets around it. */ + obstack *strings = get_string_obstack (); + obstack_grow0 (strings, name + 1, len - 2); + char *deferred_name = XOBFINISH (strings, char *); + + /* Find the name of the attribute. */ + const char *attr = strchr (deferred_name, ':'); + if (!attr) + attr = deferred_name; + + /* Find the attribute itself. */ + mapping *m = (mapping *) htab_find (codes.attrs, &attr); + if (!m) + fatal_with_file_and_line ("unknown code attribute `%s'", attr); + + /* Pick the first possible code for now, and record the attribute + use for later. */ + rtx x = rtx_alloc (check_code_attribute (m)); + record_attribute_use (&codes, x, 0, deferred_name); + return x; + } + + mapping *iterator = (mapping *) htab_find (codes.iterators, &name); + if (iterator != 0) + { + /* Pick the first possible code for now, and record the iterator + use for later. */ + rtx x = rtx_alloc (rtx_code (iterator->values->number)); + record_iterator_use (iterator, x, 0); + return x; + } +#endif + + return rtx_alloc (rtx_code (codes.find_builtin (name))); +} + /* Subroutine of read_rtx and read_nested_rtx. CODE_NAME is the name of either an rtx code or a code iterator. Parse the rest of the rtx and return it. */ @@ -1475,7 +1562,6 @@ rtx rtx_reader::read_rtx_code (const char *code_name) { RTX_CODE code; - struct mapping *iterator = NULL; const char *format_ptr; struct md_name name; rtx return_rtx; @@ -1509,20 +1595,9 @@ rtx_reader::read_rtx_code (const char *code_name) return return_rtx; } - /* If this code is an iterator, build the rtx using the iterator's - first value. */ -#ifdef GENERATOR_FILE - iterator = (struct mapping *) htab_find (codes.iterators, &code_name); - if (iterator != 0) - code = (enum rtx_code) iterator->values->number; - else - code = (enum rtx_code) codes.find_builtin (code_name); -#else - code = (enum rtx_code) codes.find_builtin (code_name); -#endif - /* If we end up with an insn expression then we free this space below. */ - return_rtx = rtx_alloc (code); + return_rtx = rtx_alloc_for_name (code_name); + code = GET_CODE (return_rtx); format_ptr = GET_RTX_FORMAT (code); memset (return_rtx, 0, RTX_CODE_SIZE (code)); PUT_CODE (return_rtx, code); @@ -1534,9 +1609,6 @@ rtx_reader::read_rtx_code (const char *code_name) m_reuse_rtx_by_id[reuse_id] = return_rtx; } - if (iterator) - record_iterator_use (iterator, return_rtx, 0); - /* Check for flags. */ read_flags (return_rtx); |