|
GCC Middle and Back End API Reference
|
Typedefs | |
| typedef tree(* | elem_op_func )(gimple_stmt_iterator *, tree, tree, tree, tree, tree, enum tree_code) |
Variables | |
| static tree | vector_inner_type |
| static tree | vector_last_type |
| static int | vector_last_nunits |
|
static |
Helper function of expand_vector_divmod. Gimplify a RSHIFT_EXPR in type of OP0 with shift counts in SHIFTCNTS array and return the temporary holding the result if successful, otherwise return NULL_TREE.
References build_int_cst(), gimplify_build2(), optab_for_tree_code(), optab_handler(), optab_scalar, and unknown_optab.
|
static |
Build a constant of type TYPE, made of VALUE's bits replicated every TYPE_SIZE (INNER_TYPE) bits to fit TYPE's precision.
|
static |
Return a suitable vector types made of SUBPARTS units each of mode "word_mode" (the global variable).
We build a new type, but we canonicalize it nevertheless,
because it still saves some memory.
References vector_last_type.
|
static |
Referenced by bswap_loc_descriptor(), and dw_sra_loc_expr().
|
static |
Construct expression (A[BITPOS] code B[BITPOS]) ? -1 : 0 INNER_TYPE is the type of A and B elements returned expression is of signed integer type with the size equal to the size of INNER_TYPE.
|
static |
|
static |
Expand vector addition to scalars. This does bit twiddling
in order to increase parallelism:
a + b = (((int) a & 0x7f7f7f7f) + ((int) b & 0x7f7f7f7f)) ^
(a ^ b) & 0x80808080
a - b = (((int) a | 0x80808080) - ((int) b & 0x7f7f7f7f)) ^
(a ^ ~b) & 0x80808080
-b = (0x80808080 - ((int) b & 0x7f7f7f7f)) ^ (~b & 0x80808080)
This optimization should be done only if 4 vector items or more
fit into a word.
|
static |
|
static |
Expand a vector operation to scalars; for integer types we can use special bit twiddling tricks to do the sums a word at a time, using function F_PARALLEL instead of F. These tricks are done only if they can process at least four items, that is, only if the vector holds at least four items and if a word can hold four items.
|
static |
Try to expand vector comparison expression OP0 CODE OP1 by
querying optab if the following expression:
VEC_COND_EXPR< OP0 CODE OP1, {-1,...}, {0,...}>
can be expanded.
|
static |
Expand a vector condition to scalars, by using many conditions on the vector's elements.
TODO: try and find a smaller vector type.
|
static |
Try to expand integer vector division by constant using widening multiply, shifts and additions.
Analysis phase. Determine if all op1 elements are either power
of two and it is possible to expand it using shifts (or for remainder
using masking). Additionally compute the multiplicative constants
and pre and post shifts if the division is to be expanded using
widening or high part multiplication plus shifts. FIXME: Can transform this into op0 >= op1 ? 1 : 0.
Find a suitable multiplier and right shift count
instead of multiplying with D. If the suggested multiplier is more than SIZE bits, we can
do better for even divisors, using an initial right shift. Restart.
Since d might be INT_MIN, we have to cast to
unsigned HOST_WIDE_INT before negating to avoid
undefined signed overflow. n rem d = n rem -d
This case is not handled correctly below.
Both division and remainder sequences need
op0 < 0 ? mask : 0 computed. It can be either computed as
(type) (((uns_type) (op0 >> (prec - 1))) >> (prec - shifts[i]))
if none of the shifts is 0, or as the conditional. q = op0 >> shift;
t1 = op0 + addend;
q = t1 >> shift; r = op0 & mask;
t1 = op0 + addend;
t2 = t1 & mask;
r = t2 - addend; t1 = oprnd0 >> pre_shift;
t2 = t1 h* ml;
q = t2 >> post_shift; t1 = oprnd0 >> pre_shift;
t2 = t1 h* ml;
q = t2 >> post_shift; t1 = oprnd0 h* ml;
t2 = oprnd0 - t1;
t3 = t2 >> 1;
t4 = t1 + t3;
q = t4 >> (post_shift - 1); t1 = oprnd0 h* ml;
t2 = t1; [ iff (mode & 2) != 0 ]
t2 = t1 + oprnd0; [ iff (mode & 2) == 0 ]
t3 = t2 >> post_shift;
t4 = oprnd0 >> (prec - 1);
q = t3 - t4; [ iff (mode & 1) == 0 ]
q = t4 - t3; [ iff (mode & 1) != 0 ] We divided. Now finish by:
t1 = q * oprnd1;
r = oprnd0 - t1;
|
static |
If the compute mode is not a vector mode (hence we are not decomposing
a BLKmode vector to smaller, hardware-supported vectors), we may want
to expand the operations in parallel.
|
static |
??? If we do not cleanup EH then we will ICE in
verification. But in reality we have created wrong-code
as we did not properly transition EH info and edges to
the piecewise computations.
|
static |
@verbatim
Lower vector operations to scalar operations. Copyright (C) 2004-2013 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see http://www.gnu.org/licenses/.
Need to include rtl.h, expr.h, etc. for optabs.
|
static |
Process one statement. If we identify a vector operation, expand it.
The signedness is determined from input argument.
For widening/narrowing vector operations, the relevant type is of the
arguments, not the widened result. VEC_UNPACK_FLOAT_*_EXPR is
calculated in the same way above. Choose between vector shift/rotate by vector and vector shift/rotate by
scalar Check whether we have vector <op> {x,x,x,x} where x
could be a scalar variable or a constant. Transform
vector <op> {x,x,x,x} ==> vector <op> scalar. The rtl expander will expand vector/scalar as vector/vector
if necessary. Don't bother converting the stmt here. Optabs will try converting a negation into a subtraction, so
look for it as well. TODO: negation of floating-point vectors
might be turned into an exclusive OR toggling the sign bit. For very wide vectors, try using a smaller vector mode.
If we are breaking a BLKmode vector into smaller pieces,
type_for_widest_vector_mode has already looked into the optab,
so skip these checks. There is no operation in hardware, so fall back to scalars.
Leave expression untouched for later expansion.
NOTE: We should avoid using gimple_assign_set_rhs_from_tree. One
way to do it is change expand_vector_operation and its callees to
return a tree_code, RHS1 and RHS2 instead of a tree.
|
static |
Expand a vector operation to scalars with the freedom to use a scalar integer type, or to use a different size for the items in the vector type.
We have three strategies. If the type is already correct, just do
the operation an element at a time. Else, if the vector is wider than
one word, do it a word at a time; finally, if the vector is smaller
than one word, do it as a scalar. Use a single scalar operation with a mode no wider than word_mode.
|
static |
Expand a vector operation to scalars, by using many operations whose type is the vector type's inner type.
|
static |
Use this to lower vector operations introduced by the vectorizer, if it may need the bit-twiddling tricks implemented in this file.
|
static |
Check if VEC_PERM_EXPR within the given setting is supported
by hardware, or lower it piecewise.
When VEC_PERM_EXPR has the same first and second operands:
VEC_PERM_EXPR <v0, v0, mask> the lowered version would be
{v0[mask[0]], v0[mask[1]], ...}
MASK and V0 must have the same number of elements.
Otherwise VEC_PERM_EXPR <v0, v1, mask> is lowered to
{mask[0] < len(v0) ? v0[mask[0]] : v1[mask[0]], ...}
V0 and V1 must have the same type. MASK, V0, V1 must have the
same number of arguments.
| gimple_opt_pass* make_pass_lower_vector | ( | ) |
| gimple_opt_pass* make_pass_lower_vector_ssa | ( | ) |
|
inlinestatic |
|
static |
Return a type for the widest vector mode whose components are of type TYPE, or NULL_TREE if none is found.
References build_int_cst(), gimple_assign_rhs1(), gimple_assign_rhs_code(), host_integerp(), and is_gimple_assign().
|
static |
Build a reference to the element of the vector VECT. Function returns either the element itself, either BIT_FIELD_REF, or an ARRAY_REF expression. GSI is required to insert temporary variables while building a refernece to the element of the vector VECT. PTMPVEC is a pointer to the temporary variable for caching purposes. In case when PTMPVEC is NULL new temporary variable will be created.
Given that we're about to compute a binary modulus,
we don't care about the high bits of the value. When lowering a vector statement sequence do some easy
simplification by looking through intermediate vector results.
|
static |
|
static |
|
static |
Referenced by build_word_mode_vector_type().