From: Sylvain Noiry <snoiry@kalrayinc.com>
To: gcc-patches@gcc.gnu.org
Cc: Sylvain Noiry <snoiry@kalrayinc.com>
Subject: [PATCH v2 03/11] Native complex ops: Add gen_rtx_complex hook
Date: Tue, 12 Sep 2023 12:07:05 +0200 [thread overview]
Message-ID: <20230912100713.1074-4-snoiry@kalrayinc.com> (raw)
In-Reply-To: <20230912100713.1074-1-snoiry@kalrayinc.com>
Summary:
Add a new target hook for complex element creation during
the expand pass, called gen_rtx_complex. The default implementation
calls gen_rtx_CONCAT like before. Then calls to gen_rtx_CONCAT for
complex handling are replaced by calls to targetm.gen_rtx_complex.
gcc/ChangeLog:
* target.def: Add gen_rtx_complex target hook
* targhooks.cc (default_gen_rtx_complex): New: Default
implementation for gen_rtx_complex
* targhooks.h: Add default_gen_rtx_complex
* doc/tm.texi: Document TARGET_GEN_RTX_COMPLEX
* doc/tm.texi.in: Add TARGET_GEN_RTX_COMPLEX
* emit-rtl.cc (gen_reg_rtx): Replace call to
gen_rtx_CONCAT by call to gen_rtx_complex
(init_emit_once): Likewise
* expmed.cc (flip_storage_order): Likewise
* optabs.cc (expand_doubleword_mod): Likewise
---
gcc/doc/tm.texi | 6 ++++++
gcc/doc/tm.texi.in | 2 ++
gcc/emit-rtl.cc | 26 +++++++++-----------------
gcc/expmed.cc | 2 +-
gcc/optabs.cc | 11 ++++++-----
gcc/target.def | 10 ++++++++++
gcc/targhooks.cc | 27 +++++++++++++++++++++++++++
gcc/targhooks.h | 2 ++
8 files changed, 63 insertions(+), 23 deletions(-)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index c4f935b5746..470497a3ade 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -4620,6 +4620,12 @@ to return a nonzero value when it is required, the compiler will run out
of spill registers and print a fatal error message.
@end deftypefn
+@deftypefn {Target Hook} rtx TARGET_GEN_RTX_COMPLEX (machine_mode @var{mode}, rtx @var{real_part}, rtx @var{imag_part})
+This hook should return an rtx representing a complex of mode @var{machine_mode} built from @var{real_part} and @var{imag_part}.
+ If both arguments are @code{NULL}, create them as registers.
+ The default is @code{gen_rtx_CONCAT}.
+@end deftypefn
+
@deftypefn {Target Hook} rtx TARGET_READ_COMPLEX_PART (rtx @var{cplx}, complex_part_t @var{part})
This hook should return the rtx representing the specified @var{part} of the complex given by @var{cplx}.
@var{part} can be the real part, the imaginary part, or both of them.
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index b8970761c8d..27a0b321fe0 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -3392,6 +3392,8 @@ stack.
@hook TARGET_SMALL_REGISTER_CLASSES_FOR_MODE_P
+@hook TARGET_GEN_RTX_COMPLEX
+
@hook TARGET_READ_COMPLEX_PART
@hook TARGET_WRITE_COMPLEX_PART
diff --git a/gcc/emit-rtl.cc b/gcc/emit-rtl.cc
index f6276a2d0b6..22012bfea13 100644
--- a/gcc/emit-rtl.cc
+++ b/gcc/emit-rtl.cc
@@ -1190,19 +1190,7 @@ gen_reg_rtx (machine_mode mode)
if (generating_concat_p
&& (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
|| GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
- {
- /* For complex modes, don't make a single pseudo.
- Instead, make a CONCAT of two pseudos.
- This allows noncontiguous allocation of the real and imaginary parts,
- which makes much better code. Besides, allocating DCmode
- pseudos overstrains reload on some machines like the 386. */
- rtx realpart, imagpart;
- machine_mode partmode = GET_MODE_INNER (mode);
-
- realpart = gen_reg_rtx (partmode);
- imagpart = gen_reg_rtx (partmode);
- return gen_rtx_CONCAT (mode, realpart, imagpart);
- }
+ return targetm.gen_rtx_complex (mode, NULL, NULL);
/* Do not call gen_reg_rtx with uninitialized crtl. */
gcc_assert (crtl->emit.regno_pointer_align_length);
@@ -6274,14 +6262,18 @@ init_emit_once (void)
FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_INT)
{
- rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
- const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
+ machine_mode imode = GET_MODE_INNER (mode);
+ rtx inner = const_tiny_rtx[0][(int) imode];
+ const_tiny_rtx[0][(int) mode] =
+ targetm.gen_rtx_complex (mode, inner, inner);
}
FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_FLOAT)
{
- rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
- const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
+ machine_mode imode = GET_MODE_INNER (mode);
+ rtx inner = const_tiny_rtx[0][(int) imode];
+ const_tiny_rtx[0][(int) mode] =
+ targetm.gen_rtx_complex (mode, inner, inner);
}
FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL)
diff --git a/gcc/expmed.cc b/gcc/expmed.cc
index 973c16a14d3..ce935951781 100644
--- a/gcc/expmed.cc
+++ b/gcc/expmed.cc
@@ -400,7 +400,7 @@ flip_storage_order (machine_mode mode, rtx x)
real = flip_storage_order (GET_MODE_INNER (mode), real);
imag = flip_storage_order (GET_MODE_INNER (mode), imag);
- return gen_rtx_CONCAT (mode, real, imag);
+ return targetm.gen_rtx_complex (mode, real, imag);
}
if (UNLIKELY (reverse_storage_order_supported < 0))
diff --git a/gcc/optabs.cc b/gcc/optabs.cc
index 32ff379ffc3..429a20f9cd7 100644
--- a/gcc/optabs.cc
+++ b/gcc/optabs.cc
@@ -1001,16 +1001,17 @@ expand_doubleword_mod (machine_mode mode, rtx op0, rtx op1, bool unsignedp)
machine_mode cmode = TYPE_MODE (ctype);
rtx op00 = operand_subword_force (op0, 0, mode);
rtx op01 = operand_subword_force (op0, 1, mode);
- rtx cres = gen_rtx_CONCAT (cmode, gen_reg_rtx (word_mode),
- gen_reg_rtx (word_mode));
+ rtx cres = targetm.gen_rtx_complex (cmode, gen_reg_rtx (word_mode),
+ gen_reg_rtx (word_mode));
tree lhs = make_tree (ctype, cres);
tree arg0 = make_tree (wtype, op00);
tree arg1 = make_tree (wtype, op01);
expand_addsub_overflow (UNKNOWN_LOCATION, PLUS_EXPR, lhs, arg0,
arg1, true, true, true, false, NULL);
- sum = expand_simple_binop (word_mode, PLUS, XEXP (cres, 0),
- XEXP (cres, 1), NULL_RTX, 1,
- OPTAB_DIRECT);
+ sum = expand_simple_binop (word_mode, PLUS,
+ read_complex_part (cres, REAL_P),
+ read_complex_part (cres, IMAG_P),
+ NULL_RTX, 1, OPTAB_DIRECT);
if (sum == NULL_RTX)
return NULL_RTX;
}
diff --git a/gcc/target.def b/gcc/target.def
index f99df939776..d63dacbbb8f 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -3313,6 +3313,16 @@ a pointer to int.",
bool, (ao_ref *ref),
default_ref_may_alias_errno)
+/* Return the rtx representation of a complex with a specified mode. */
+DEFHOOK
+(gen_rtx_complex,
+ "This hook should return an rtx representing a complex of mode @var{machine_mode} built from @var{real_part} and @var{imag_part}.\n\
+ If both arguments are @code{NULL}, create them as registers.\n\
+ The default is @code{gen_rtx_CONCAT}.",
+ rtx,
+ (machine_mode mode, rtx real_part, rtx imag_part),
+ default_gen_rtx_complex)
+
/* Returns the value corresponding to the specified part of a complex. */
DEFHOOK
(read_complex_part,
diff --git a/gcc/targhooks.cc b/gcc/targhooks.cc
index df852eb18e3..f6e7bc6c141 100644
--- a/gcc/targhooks.cc
+++ b/gcc/targhooks.cc
@@ -1533,6 +1533,33 @@ default_preferred_simd_mode (scalar_mode)
return word_mode;
}
+/* By default, call gen_rtx_CONCAT. */
+
+rtx
+default_gen_rtx_complex (machine_mode mode, rtx real_part, rtx imag_part)
+{
+ /* For complex modes, don't make a single pseudo.
+ Instead, make a CONCAT of two pseudos.
+ This allows noncontiguous allocation of the real and imaginary parts,
+ which makes much better code. Besides, allocating DCmode
+ pseudos overstrains reload on some machines like the 386. */
+ machine_mode imode = GET_MODE_INNER (mode);
+
+ if (real_part == NULL)
+ real_part = gen_reg_rtx (imode);
+ else
+ gcc_assert ((GET_MODE (real_part) == imode)
+ || (GET_MODE (real_part) == E_VOIDmode));
+
+ if (imag_part == NULL)
+ imag_part = gen_reg_rtx (imode);
+ else
+ gcc_assert ((GET_MODE (imag_part) == imode)
+ || (GET_MODE (imag_part) == E_VOIDmode));
+
+ return gen_rtx_CONCAT (mode, real_part, imag_part);
+}
+
/* By default, extract one of the components of the complex value CPLX. Extract the
real part if part is REAL_P, and the imaginary part if it is IMAG_P. If part is
BOTH_P, return cplx directly. */
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index dcacc725e27..cf37eea24b5 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -124,6 +124,8 @@ extern opt_machine_mode default_get_mask_mode (machine_mode);
extern bool default_empty_mask_is_expensive (unsigned);
extern vector_costs *default_vectorize_create_costs (vec_info *, bool);
+extern rtx default_gen_rtx_complex (machine_mode mode, rtx real_part,
+ rtx imag_part);
extern rtx default_read_complex_part (rtx cplx, complex_part_t part);
extern void default_write_complex_part (rtx cplx, rtx val,
complex_part_t part);
--
2.17.1
next prev parent reply other threads:[~2023-09-12 10:07 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-17 9:02 [PATCH 0/9] Native complex operations Sylvain Noiry
2023-07-17 9:02 ` [PATCH 1/9] Native complex operations: Conditional lowering Sylvain Noiry
2023-07-17 9:02 ` [PATCH 2/9] Native complex operations: Move functions to hooks Sylvain Noiry
2023-07-17 9:02 ` [PATCH 3/9] Native complex operations: Add gen_rtx_complex hook Sylvain Noiry
2023-07-17 9:02 ` [PATCH 4/9] Native complex operations: Allow native complex regs and ops in rtl Sylvain Noiry
2023-07-17 9:02 ` [PATCH 5/9] Native complex operations: Add the conjugate op in optabs Sylvain Noiry
2023-07-17 9:02 ` [PATCH 6/9] Native complex operations: Update how complex rotations are handled Sylvain Noiry
2023-07-17 9:02 ` [PATCH 7/9] Native complex operations: Vectorization of native complex operations Sylvain Noiry
2023-07-17 9:02 ` [PATCH 8/9] Native complex operations: Add explicit vector of complex Sylvain Noiry
2023-07-17 9:02 ` [PATCH 9/9] Native complex operation: Experimental support in x86 backend Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 0/11] Native complex operations Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 01/11] Native complex ops : Conditional lowering Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 02/11] Native complex ops: Move functions to hooks Sylvain Noiry
2023-09-12 10:07 ` Sylvain Noiry [this message]
2023-09-12 10:07 ` [PATCH v2 04/11] Native complex ops: Allow native complex regs and ops in rtl Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 05/11] Native complex ops: Add the conjugate op in optabs Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 06/11] Native complex ops: Update how complex rotations are handled Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 07/11] Native complex ops: Vectorization of native complex operations Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 08/11] Native complex ops: Add explicit vector of complex Sylvain Noiry
2023-09-12 17:25 ` Joseph Myers
2023-09-13 6:48 ` Richard Biener
2023-09-12 10:07 ` [PATCH v2 09/11] Native complex ops: remove useless special cases Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 10/11] Native complex ops: Add a fast complex multiplication pattern Sylvain Noiry
2023-09-12 10:07 ` [PATCH v2 11/11] Native complex ops: Experimental support in x86 backend Sylvain Noiry
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230912100713.1074-4-snoiry@kalrayinc.com \
--to=snoiry@kalrayinc.com \
--cc=gcc-patches@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).