SLP Complex Numbers pattern matching.
As an example, the following simple loop:
double a[restrict N]; double b[restrict N]; double c[restrict N];
for (int i=0; i < N; i+=2)
{
c[i] = a[i] - b[i+1];
c[i+1] = a[i+1] + b[i];
}
which represents a complex addition on with a rotation of 90* around the
argand plane. i.e. if `a` and `b` were complex numbers then this would be the
same as `a + (b * I)`.
Here the expressions for `c[i]` and `c[i+1]` are independent but have to be
both recognized in order for the pattern to work. As an SLP tree this is
represented as
+--------------------------------+
| stmt 0 *_9 = _10; |
| stmt 1 *_15 = _16; |
+--------------------------------+
|
|
v
+--------------------------------+
| stmt 0 _10 = _4 - _8; |
| stmt 1 _16 = _12 + _14; |
| lane permutation { 0[0] 1[1] } |
+--------------------------------+
| |
| |
| |
+-----+ | | +-----+
| | | | | |
+-----| { } |<-----+ +----->| { } --------+
| | | +------------------| | |
| +-----+ | +-----+ |
| | | |
| | | |
| +------|------------------+ |
| | | |
v v v v
+--------------------------+ +--------------------------------+
| stmt 0 _8 = *_7; | | stmt 0 _4 = *_3; |
| stmt 1 _14 = *_13; | | stmt 1 _12 = *_11; |
| load permutation { 1 0 } | | load permutation { 0 1 } |
+--------------------------+ +--------------------------------+
The pattern matcher allows you to replace both statements 0 and 1 or none at
all. Because this operation is a two operands operation the actual nodes
being replaced are those in the { } nodes. The actual scalar statements
themselves are not replaced or used during the matching but instead the
SLP_TREE_REPRESENTATIVE statements are inspected. You are also allowed to
replace and match on any number of nodes.
Because the pattern matcher matches on the representative statement for the
SLP node the case of two_operators it allows you to match the children of the
node. This is done using the method `recognize ()`.
The complex_pattern class contains common code for pattern matchers that work
on complex numbers. These provide functionality to allow de-construction and
validation of sequences depicting/transforming REAL and IMAG pairs.
void complex_pattern::build |
( |
vec_info * | vinfo | ) |
|
|
overridevirtual |
Create a replacement pattern statement for each node in m_node and inserts
the new statement into m_node as the new representative statement. The old
statement is marked as being in a pattern defined by the new statement. The
statement is created as call to internal function IFN with m_num_args
arguments.
Futhermore the new pattern is also added to the vectorization information
structure VINFO and the old statement STMT_INFO is marked as unused while
the new statement is marked as used and the number of SLP uses of the new
statement is incremented.
The newly created SLP nodes are marked as SLP only and will be dissolved
if SLP is aborted.
The newly created gimple call is returned and the BB remains unchanged.
This default method is designed to only match against simple operands where
all the input and output types are the same.
Implements vect_pattern.
References vec_info::add_pattern_stmt(), FOR_EACH_VEC_ELT, gimple_bb(), gimple_build_call_internal_vec(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gimple_get_lhs(), gimple_location(), gimple_set_bb(), gimple_set_location(), i, vect_pattern::m_ifn, vect_pattern::m_num_args, m_workset, make_temp_ssa_name(), NULL, pure_slp, SLP_TREE_CODE, SLP_TREE_LANE_PERMUTATION, SLP_TREE_REPRESENTATIVE, SLP_TREE_VECTYPE, STMT_SLP_TYPE, STMT_VINFO_REDUC_DEF, STMT_VINFO_RELEVANT, STMT_VINFO_SLP_VECT_ONLY_PATTERN, STMT_VINFO_STMT, STMT_VINFO_VECTYPE, TREE_TYPE, vect_orig_stmt(), and vect_used_in_scope.
Referenced by complex_add_pattern::build(), complex_fms_pattern::build(), and complex_mul_pattern::build().