summaryrefslogtreecommitdiff
path: root/gcc/coretypes.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/coretypes.h
parentb9f92c0bb7fc0c319b0a2d54b6a74e8f49c469bd (diff)
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/coretypes.h')
-rw-r--r--gcc/coretypes.h15
1 files changed, 15 insertions, 0 deletions
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 410583e1ce2..9d94e492299 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -396,6 +396,21 @@ typedef unsigned char uchar;
#include "signop.h"
#include "wide-int.h"
#include "wide-int-print.h"
+
+/* On targets that don't need polynomial offsets, target-specific code
+ should be able to treat poly_int like a normal constant, with a
+ conversion operator going from the former to the latter. We also
+ allow this for gencondmd.c for all targets, so that we can treat
+ machine_modes as enums without causing build failures. */
+#if (defined (IN_TARGET_CODE) \
+ && (defined (USE_ENUM_MODES) || NUM_POLY_INT_COEFFS == 1))
+#define POLY_INT_CONVERSION 1
+#else
+#define POLY_INT_CONVERSION 0
+#endif
+
+#include "poly-int.h"
+#include "poly-int-types.h"
#include "insn-modes-inline.h"
#include "machmode.h"
#include "double-int.h"