aboutsummaryrefslogtreecommitdiff
path: root/gcc/selftest.h
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-12-14 00:06:02 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-12-14 00:06:02 +0000
commite535b963b4a39e041cc81e2879cfb637d60c720d (patch)
treee380648d6b3b82e1442620c6f67e83c5d250ef81 /gcc/selftest.h
parentb9f92c0bb7fc0c319b0a2d54b6a74e8f49c469bd (diff)
downloadgcc-e535b963b4a39e041cc81e2879cfb637d60c720d.zip
gcc-e535b963b4a39e041cc81e2879cfb637d60c720d.tar.gz
gcc-e535b963b4a39e041cc81e2879cfb637d60c720d.tar.bz2
poly_int: add poly-int.h
This patch adds a new "poly_int" class to represent polynomial integers of the form: C0 + C1*X1 + C2*X2 ... + Cn*Xn It also adds poly_int-based typedefs for offsets and sizes of various precisions. In these typedefs, the Ci coefficients are compile-time constants and the Xi indeterminates are run-time invariants. The number of coefficients is controlled by the target and is initially 1 for all ports. Most routines can handle general coefficient counts, but for now a few are specific to one or two coefficients. Support for other coefficient counts can be added when needed. The patch also adds a new macro, IN_TARGET_CODE, that can be set to indicate that a TU contains target-specific rather than target-independent code. When this macro is set and the number of coefficients is 1, the poly-int.h classes define a conversion operator to a constant. This allows most existing target code to work without modification. The main exceptions are: - values passed through ..., which need an explicit conversion to a constant - ?: expression in which one arm ends up being a polynomial and the other remains a constant. In these cases it would be valid to convert the constant to a polynomial and the polynomial to a constant, so a cast is needed to break the ambiguity. The patch also adds a new target hook to return the estimated value of a polynomial for costing purposes. The patch also adds operator<< on wide_ints (it was already defined for offset_int and widest_int). I think this was originally excluded because >> is ambiguous for wide_int, but << is useful for converting bytes to bits, etc., so is worth defining on its own. The patch also adds operator% and operator/ for offset_int and widest_int, since those types are always signed. These changes allow the poly_int interface to be more predictable. I'd originally tried adding the tests as selftests, but that ended up bloating cc1 by at least a third. It also took a while to build them at -O2. The patch therefore uses plugin tests instead, where we can force the tests to be built at -O0. They still run in negligible time when built that way. 2017-12-14 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * poly-int.h: New file. * poly-int-types.h: Likewise. * coretypes.h: Include them. (POLY_INT_CONVERSION): Define. * target.def (estimated_poly_value): New hook. * doc/tm.texi.in (TARGET_ESTIMATED_POLY_VALUE): New hook. * doc/tm.texi: Regenerate. * doc/poly-int.texi: New file. * doc/gccint.texi: Include it. * doc/rtl.texi: Describe restrictions on subreg modes. * Makefile.in (TEXI_GCCINT_FILES): Add poly-int.texi. * genmodes.c (NUM_POLY_INT_COEFFS): Provide a default definition. (emit_insn_modes_h): Emit a definition of NUM_POLY_INT_COEFFS. * targhooks.h (default_estimated_poly_value): Declare. * targhooks.c (default_estimated_poly_value): New function. * target.h (estimated_poly_value): Likewise. * wide-int.h (WI_UNARY_RESULT): Use wi::binary_traits. (wi::unary_traits): Delete. (wi::binary_traits::signed_shift_result_type): Define for offset_int << HOST_WIDE_INT, etc. (generic_wide_int::operator <<=): Define for all types and use wi::lshift instead of <<. (wi::hwi_with_prec): Add a default constructor. (wi::ints_for): New class. (operator <<): Define for all wide-int types. (operator /): New function. (operator %): Likewise. * selftest.h (ASSERT_KNOWN_EQ, ASSERT_KNOWN_EQ_AT, ASSERT_MAYBE_NE) (ASSERT_MAYBE_NE_AT): New macros. gcc/testsuite/ * gcc.dg/plugin/poly-int-tests.h, gcc.dg/plugin/poly-int-test-1.c, gcc.dg/plugin/poly-int-01_plugin.c, gcc.dg/plugin/poly-int-02_plugin.c, gcc.dg/plugin/poly-int-03_plugin.c, gcc.dg/plugin/poly-int-04_plugin.c, gcc.dg/plugin/poly-int-05_plugin.c, gcc.dg/plugin/poly-int-06_plugin.c, gcc.dg/plugin/poly-int-07_plugin.c: New tests. * gcc.dg/plugin/plugin.exp: Run them. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r255617
Diffstat (limited to 'gcc/selftest.h')
-rw-r--r--gcc/selftest.h38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/selftest.h b/gcc/selftest.h
index 68b2e8e..ab8a7c0 100644
--- a/gcc/selftest.h
+++ b/gcc/selftest.h
@@ -281,6 +281,25 @@ extern int num_passes;
::selftest::fail ((LOC), desc_); \
SELFTEST_END_STMT
+/* Evaluate EXPECTED and ACTUAL and compare them with known_eq, calling
+ ::selftest::pass if they are always equal,
+ ::selftest::fail if they might be non-equal. */
+
+#define ASSERT_KNOWN_EQ(EXPECTED, ACTUAL) \
+ ASSERT_KNOWN_EQ_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
+
+/* Like ASSERT_KNOWN_EQ, but treat LOC as the effective location of the
+ selftest. */
+
+#define ASSERT_KNOWN_EQ_AT(LOC, EXPECTED, ACTUAL) \
+ SELFTEST_BEGIN_STMT \
+ const char *desc = "ASSERT_KNOWN_EQ (" #EXPECTED ", " #ACTUAL ")"; \
+ if (known_eq (EXPECTED, ACTUAL)) \
+ ::selftest::pass ((LOC), desc); \
+ else \
+ ::selftest::fail ((LOC), desc); \
+ SELFTEST_END_STMT
+
/* Evaluate EXPECTED and ACTUAL and compare them with !=, calling
::selftest::pass if they are non-equal,
::selftest::fail if they are equal. */
@@ -294,6 +313,25 @@ extern int num_passes;
::selftest::fail (SELFTEST_LOCATION, desc_); \
SELFTEST_END_STMT
+/* Evaluate EXPECTED and ACTUAL and compare them with maybe_ne, calling
+ ::selftest::pass if they might be non-equal,
+ ::selftest::fail if they are known to be equal. */
+
+#define ASSERT_MAYBE_NE(EXPECTED, ACTUAL) \
+ ASSERT_MAYBE_NE_AT ((SELFTEST_LOCATION), (EXPECTED), (ACTUAL))
+
+/* Like ASSERT_MAYBE_NE, but treat LOC as the effective location of the
+ selftest. */
+
+#define ASSERT_MAYBE_NE_AT(LOC, EXPECTED, ACTUAL) \
+ SELFTEST_BEGIN_STMT \
+ const char *desc = "ASSERT_MAYBE_NE (" #EXPECTED ", " #ACTUAL ")"; \
+ if (maybe_ne (EXPECTED, ACTUAL)) \
+ ::selftest::pass ((LOC), desc); \
+ else \
+ ::selftest::fail ((LOC), desc); \
+ SELFTEST_END_STMT
+
/* Evaluate EXPECTED and ACTUAL and compare them with strcmp, calling
::selftest::pass if they are equal,
::selftest::fail if they are non-equal. */