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().