aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2017-11-01 10:37:03 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2017-11-01 10:37:03 +0000
commit06ec586d2c384ba016c784de3279f3770d9f399d (patch)
treefa771154bb36a0e333d0f1ec22f6a13d31021200 /gcc
parent9b1de7e2e8e99eabf2b8d1ef74eb57fbd41bc730 (diff)
downloadgcc-06ec586d2c384ba016c784de3279f3770d9f399d.zip
gcc-06ec586d2c384ba016c784de3279f3770d9f399d.tar.gz
gcc-06ec586d2c384ba016c784de3279f3770d9f399d.tar.bz2
Allow vector CONSTs
This patch allows (const ...) wrappers to be used for rtx vector constants, as an alternative to const_vector. This is useful for SVE, where the number of elements isn't known until runtime. It could also be useful in future for fixed-length vectors, to reduce the amount of memory needed to represent simple constants with high element counts. However, one nice thing about keeping it restricted to variable-length vectors is that there is never any need to handle combinations of (const ...) and CONST_VECTOR. 2017-11-01 Richard Sandiford <richard.sandiford@linaro.org> Alan Hayward <alan.hayward@arm.com> David Sherwood <david.sherwood@arm.com> gcc/ * doc/rtl.texi (const): Update description of address constants. Say that vector constants are allowed too. * common.md (E, F): Use CONSTANT_P instead of checking for CONST_VECTOR. * emit-rtl.c (gen_lowpart_common): Use const_vec_p instead of checking for CONST_VECTOR. * expmed.c (make_tree): Use build_vector_from_val for a CONST VEC_DUPLICATE. * expr.c (expand_expr_real_2): Check for vector modes instead of checking for CONST_VECTOR. * rtl.h (const_vec_p): New function. (const_vec_duplicate_p): Check for a CONST VEC_DUPLICATE. (unwrap_const_vec_duplicate): Handle them here too. Co-Authored-By: Alan Hayward <alan.hayward@arm.com> Co-Authored-By: David Sherwood <david.sherwood@arm.com> From-SVN: r254296
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/common.md4
-rw-r--r--gcc/doc/rtl.texi19
-rw-r--r--gcc/emit-rtl.c2
-rw-r--r--gcc/expmed.c10
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/rtl.h25
7 files changed, 63 insertions, 17 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0dde53b..0a30e38 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,4 +1,22 @@
2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
+ Alan Hayward <alan.hayward@arm.com>
+ David Sherwood <david.sherwood@arm.com>
+
+ * doc/rtl.texi (const): Update description of address constants.
+ Say that vector constants are allowed too.
+ * common.md (E, F): Use CONSTANT_P instead of checking for
+ CONST_VECTOR.
+ * emit-rtl.c (gen_lowpart_common): Use const_vec_p instead of
+ checking for CONST_VECTOR.
+ * expmed.c (make_tree): Use build_vector_from_val for a CONST
+ VEC_DUPLICATE.
+ * expr.c (expand_expr_real_2): Check for vector modes instead
+ of checking for CONST_VECTOR.
+ * rtl.h (const_vec_p): New function.
+ (const_vec_duplicate_p): Check for a CONST VEC_DUPLICATE.
+ (unwrap_const_vec_duplicate): Handle them here too.
+
+2017-11-01 Richard Sandiford <richard.sandiford@linaro.org>
David Malcolm <dmalcolm@redhat.com>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
diff --git a/gcc/common.md b/gcc/common.md
index dd28a7b..22c010f 100644
--- a/gcc/common.md
+++ b/gcc/common.md
@@ -80,14 +80,14 @@
(define_constraint "E"
"Matches a floating-point constant."
(ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
- (match_test "GET_CODE (op) == CONST_VECTOR
+ (match_test "CONSTANT_P (op)
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
;; There is no longer a distinction between "E" and "F".
(define_constraint "F"
"Matches a floating-point constant."
(ior (match_test "CONST_DOUBLE_AS_FLOAT_P (op)")
- (match_test "GET_CODE (op) == CONST_VECTOR
+ (match_test "CONSTANT_P (op)
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_VECTOR_FLOAT")))
(define_constraint "X"
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index 7f67685..0a5623e 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1667,14 +1667,17 @@ Usually that is the only mode for which a label is directly valid.
@findex const
@item (const:@var{m} @var{exp})
-Represents a constant that is the result of an assembly-time
-arithmetic computation. The operand, @var{exp}, is an expression that
-contains only constants (@code{const_int}, @code{symbol_ref} and
-@code{label_ref} expressions) combined with @code{plus} and
-@code{minus}. However, not all combinations are valid, since the
-assembler cannot do arbitrary arithmetic on relocatable symbols.
-
-@var{m} should be @code{Pmode}.
+Wraps an rtx computation @var{exp} whose inputs and result do not
+change during the execution of a thread. There are two valid uses.
+The first is to represent a global or thread-local address calculation.
+In this case @var{exp} should contain @code{const_int},
+@code{symbol_ref}, @code{label_ref} or @code{unspec} expressions,
+combined with @code{plus} and @code{minus}. Any such @code{unspec}s
+are target-specific and typically represent some form of relocation
+operator. @var{m} should be a valid address mode.
+
+The second use of @code{const} is to wrap a vector operation.
+In this case @var{exp} must be a @code{vec_duplicate} expression.
@findex high
@item (high:@var{m} @var{exp})
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 4df550f..10554ac 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -1470,7 +1470,7 @@ gen_lowpart_common (machine_mode mode, rtx x)
return gen_rtx_fmt_e (GET_CODE (x), int_mode, XEXP (x, 0));
}
else if (GET_CODE (x) == SUBREG || REG_P (x)
- || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
+ || GET_CODE (x) == CONCAT || const_vec_p (x)
|| CONST_DOUBLE_AS_FLOAT_P (x) || CONST_SCALAR_INT_P (x))
return lowpart_subreg (mode, x, innermode);
diff --git a/gcc/expmed.c b/gcc/expmed.c
index eeb25d3..da9a0a2 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -5244,7 +5244,15 @@ make_tree (tree type, rtx x)
return fold_convert (type, make_tree (t, XEXP (x, 0)));
case CONST:
- return make_tree (type, XEXP (x, 0));
+ {
+ rtx op = XEXP (x, 0);
+ if (GET_CODE (op) == VEC_DUPLICATE)
+ {
+ tree elt_tree = make_tree (TREE_TYPE (type), XEXP (op, 0));
+ return build_vector_from_val (type, elt_tree);
+ }
+ return make_tree (type, op);
+ }
case SYMBOL_REF:
t = SYMBOL_REF_DECL (x);
diff --git a/gcc/expr.c b/gcc/expr.c
index 496d492..cb294bb 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -9429,7 +9429,7 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
/* Careful here: if the target doesn't support integral vector modes,
a constant selection vector could wind up smooshed into a normal
integral constant. */
- if (CONSTANT_P (op2) && GET_CODE (op2) != CONST_VECTOR)
+ if (CONSTANT_P (op2) && !VECTOR_MODE_P (GET_MODE (op2)))
{
tree sel_type = TREE_TYPE (treeop2);
machine_mode vmode
diff --git a/gcc/rtl.h b/gcc/rtl.h
index b01e306..373f8a2 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2749,12 +2749,22 @@ extern rtx shallow_copy_rtx (const_rtx CXX_MEM_STAT_INFO);
extern int rtx_equal_p (const_rtx, const_rtx);
extern bool rtvec_all_equal_p (const_rtvec);
+/* Return true if X is some form of vector constant. */
+
+inline bool
+const_vec_p (const_rtx x)
+{
+ return VECTOR_MODE_P (GET_MODE (x)) && CONSTANT_P (x);
+}
+
/* Return true if X is a vector constant with a duplicated element value. */
inline bool
const_vec_duplicate_p (const_rtx x)
{
- return GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0));
+ return ((GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0)))
+ || (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE));
}
/* Return true if X is a vector constant with a duplicated element value.
@@ -2764,11 +2774,16 @@ template <typename T>
inline bool
const_vec_duplicate_p (T x, T *elt)
{
- if (const_vec_duplicate_p (x))
+ if (GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0)))
{
*elt = CONST_VECTOR_ELT (x, 0);
return true;
}
+ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
+ {
+ *elt = XEXP (XEXP (x, 0), 0);
+ return true;
+ }
return false;
}
@@ -2794,8 +2809,10 @@ template <typename T>
inline T
unwrap_const_vec_duplicate (T x)
{
- if (const_vec_duplicate_p (x))
- x = CONST_VECTOR_ELT (x, 0);
+ if (GET_CODE (x) == CONST_VECTOR && rtvec_all_equal_p (XVEC (x, 0)))
+ return CONST_VECTOR_ELT (x, 0);
+ if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
+ return XEXP (XEXP (x, 0), 0);
return x;
}