aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-05-12 11:28:01 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-05-12 11:28:01 +0000
commit75df257b38bd4cdcb750fc893c5023363230cfe8 (patch)
treec3e45e445fd98056a3ab6ec685befd4449426000
parent4c0164573e213045052ca6bc3113d7d63cf62816 (diff)
downloadgcc-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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/config/aarch64/aarch64-simd.md6
-rw-r--r--gcc/config/aarch64/aarch64-sve.md12
-rw-r--r--gcc/config/aarch64/predicates.md6
-rw-r--r--gcc/doc/md.texi21
-rw-r--r--gcc/read-md.h1
-rw-r--r--gcc/read-rtl.c126
7 files changed, 145 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2628c24..1a9c8c1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2019-05-12 Richard Sandiford <richard.sandiford@arm.com>
+
+ * 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.
+
2019-05-12 Iain Sandoe <iain@sandoe.co.uk>
* config/rs6000/rs6000.c (debug_stack_info): When -mdebug=stack
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index e3852c5..2b7a002 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -716,9 +716,9 @@
(USMAX:VDQ_BHSI
(match_operand:VDQ_BHSI 1 "register_operand" "w")
(match_operand:VDQ_BHSI 2 "register_operand" "w"))
- (match_operator 3 "aarch64_<max_opp>"
- [(match_dup 1)
- (match_dup 2)])))]
+ (<max_opp>:VDQ_BHSI
+ (match_dup 1)
+ (match_dup 2))))]
"TARGET_SIMD"
"<su>abd\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
[(set_attr "type" "neon_abd<q>")]
diff --git a/gcc/config/aarch64/aarch64-sve.md b/gcc/config/aarch64/aarch64-sve.md
index e94801d..b9cb1fa 100644
--- a/gcc/config/aarch64/aarch64-sve.md
+++ b/gcc/config/aarch64/aarch64-sve.md
@@ -3149,8 +3149,7 @@
[(set_attr "movprfx" "*,yes")]
)
-;; Helper expander for aarch64_<su>abd<mode>_3 to save the callers
-;; the hassle of constructing the other arm of the MINUS.
+;; Unpredicated integer absolute difference.
(define_expand "<su>abd<mode>_3"
[(use (match_operand:SVE_I 0 "register_operand"))
(USMAX:SVE_I (match_operand:SVE_I 1 "register_operand")
@@ -3158,9 +3157,8 @@
"TARGET_SVE"
{
rtx pred = force_reg (<VPRED>mode, CONSTM1_RTX (<VPRED>mode));
- rtx other_arm = gen_rtx_<MAX_OPP> (<MODE>mode, operands[1], operands[2]);
emit_insn (gen_aarch64_<su>abd<mode>_3 (operands[0], pred, operands[1],
- operands[2], other_arm));
+ operands[2]));
DONE;
}
)
@@ -3174,9 +3172,9 @@
(USMAX:SVE_I
(match_operand:SVE_I 2 "register_operand" "0, w")
(match_operand:SVE_I 3 "register_operand" "w, w"))
- (match_operator 4 "aarch64_<max_opp>"
- [(match_dup 2)
- (match_dup 3)]))]
+ (<max_opp>:SVE_I
+ (match_dup 2)
+ (match_dup 3)))]
UNSPEC_MERGE_PTRUE))]
"TARGET_SVE"
"@
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 8e1b784..10100ca 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -323,12 +323,6 @@
(ior (match_operand 0 "register_operand")
(match_operand 0 "const_scalar_int_operand")))
-(define_predicate "aarch64_smin"
- (match_code "smin"))
-
-(define_predicate "aarch64_umin"
- (match_code "umin"))
-
;; True for integer comparisons and for FP comparisons other than LTGT or UNEQ.
(define_special_predicate "aarch64_comparison_operator"
(match_code "eq,ne,le,lt,ge,gt,geu,gtu,leu,ltu,unordered,
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 30612a6..b35bcaa 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -10979,6 +10979,27 @@ Other attributes are defined using:
(define_code_attr @var{name} [(@var{code1} "@var{value1}") @dots{} (@var{coden} "@var{valuen}")])
@end smallexample
+Instruction patterns can use code attributes as rtx codes, which can be
+useful if two sets of codes act in tandem. For example, the following
+@code{define_insn} defines two patterns, one calculating a signed absolute
+difference and another calculating an unsigned absolute difference:
+
+@smallexample
+(define_code_iterator any_max [smax umax])
+(define_code_attr paired_min [(smax "smin") (umax "umin")])
+(define_insn @dots{}
+ [(set (match_operand:SI 0 @dots{})
+ (minus:SI (any_max:SI (match_operand:SI 1 @dots{})
+ (match_operand:SI 2 @dots{}))
+ (<paired_min>:SI (match_dup 1) (match_dup 2))))]
+ @dots{})
+@end smallexample
+
+The signed version of the instruction uses @code{smax} and @code{smin}
+while the unsigned version uses @code{umax} and @code{umin}. There
+are no versions that pair @code{smax} with @code{umin} or @code{umax}
+with @code{smin}.
+
Here's an example of code iterators in action, taken from the MIPS port:
@smallexample
diff --git a/gcc/read-md.h b/gcc/read-md.h
index 18426f7..327f378 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -337,6 +337,7 @@ class rtx_reader : public md_reader
~rtx_reader ();
bool read_rtx (const char *rtx_name, vec<rtx> *rtxen);
+ rtx rtx_alloc_for_name (const char *);
rtx read_rtx_code (const char *code_name);
virtual rtx read_rtx_operand (rtx return_rtx, int idx);
rtx read_nested_rtx ();
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);