GCC Middle and Back End API Reference
tree-vect-generic.c File Reference

Typedefs

typedef tree(* elem_op_func )(gimple_stmt_iterator *, tree, tree, tree, tree, tree, enum tree_code)

Functions

static void expand_vector_operations_1 (gimple_stmt_iterator *)
static tree build_replicated_const ()
static tree build_word_mode_vector_type ()
static tree tree_vec_extract (gimple_stmt_iterator *gsi, tree type, tree t, tree bitsize, tree bitpos)
static tree do_unop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b, tree bitpos, tree bitsize, enum tree_code code)
static tree do_binop (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b, tree bitpos, tree bitsize, enum tree_code code)
static tree do_compare (gimple_stmt_iterator *gsi, tree inner_type, tree a, tree b, tree bitpos, tree bitsize, enum tree_code code)
static tree do_plus_minus (gimple_stmt_iterator *gsi, tree word_type, tree a, tree b, tree bitpos, tree bitsize, enum tree_code code)
static tree do_negate (gimple_stmt_iterator *gsi, tree word_type, tree b, tree unused, tree bitpos, tree bitsize, enum tree_code code)
static tree expand_vector_piecewise (gimple_stmt_iterator *gsi, elem_op_func f, tree type, tree inner_type, tree a, tree b, enum tree_code code)
static tree expand_vector_parallel (gimple_stmt_iterator *gsi, elem_op_func f, tree type, tree a, tree b, enum tree_code code)
static tree expand_vector_addition (gimple_stmt_iterator *gsi, elem_op_func f, elem_op_func f_parallel, tree type, tree a, tree b, enum tree_code code)
static tree expand_vector_comparison (gimple_stmt_iterator *gsi, tree type, tree op0, tree op1, enum tree_code code)
static tree add_rshift ()
static tree expand_vector_divmod (gimple_stmt_iterator *gsi, tree type, tree op0, tree op1, enum tree_code code)
static void expand_vector_condition ()
static tree expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type, gimple assign, enum tree_code code)
static tree type_for_widest_vector_mode ()
static tree vector_element ()
static void lower_vec_perm ()
static void expand_vector_operations_1 ()
static bool gate_expand_vector_operations_ssa ()
static unsigned int expand_vector_operations ()
gimple_opt_passmake_pass_lower_vector ()
gimple_opt_passmake_pass_lower_vector_ssa ()

Variables

static tree vector_inner_type
static tree vector_last_type
static int vector_last_nunits

Typedef Documentation

typedef tree(* elem_op_func)(gimple_stmt_iterator *, tree, tree, tree, tree, tree, enum tree_code)

Function Documentation

static tree add_rshift ( )
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 tree build_replicated_const ( )
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 tree build_word_mode_vector_type ( )
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 tree do_binop ( gimple_stmt_iterator gsi,
tree  inner_type,
tree  a,
tree  b,
tree  bitpos,
tree  bitsize,
enum tree_code  code 
)
static
static tree do_compare ( gimple_stmt_iterator gsi,
tree  inner_type,
tree  a,
tree  b,
tree  bitpos,
tree  bitsize,
enum tree_code  code 
)
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 tree do_negate ( gimple_stmt_iterator gsi,
tree  word_type,
tree  b,
tree  unused,
tree  bitpos,
tree  bitsize,
enum tree_code  code 
)
static
static tree do_plus_minus ( gimple_stmt_iterator gsi,
tree  word_type,
tree  a,
tree  b,
tree  bitpos,
tree  bitsize,
enum tree_code  code 
)
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 tree do_unop ( gimple_stmt_iterator gsi,
tree  inner_type,
tree  a,
tree  b,
tree  bitpos,
tree  bitsize,
enum tree_code  code 
)
static
static tree expand_vector_addition ( gimple_stmt_iterator gsi,
elem_op_func  f,
elem_op_func  f_parallel,
tree  type,
tree  a,
tree  b,
enum tree_code  code 
)
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 tree expand_vector_comparison ( gimple_stmt_iterator gsi,
tree  type,
tree  op0,
tree  op1,
enum tree_code  code 
)
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 void expand_vector_condition ( )
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 tree expand_vector_divmod ( gimple_stmt_iterator gsi,
tree  type,
tree  op0,
tree  op1,
enum tree_code  code 
)
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 tree expand_vector_operation ( gimple_stmt_iterator gsi,
tree  type,
tree  compute_type,
gimple  assign,
enum tree_code  code 
)
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 unsigned int expand_vector_operations ( )
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 void expand_vector_operations_1 ( gimple_stmt_iterator )
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 void expand_vector_operations_1 ( )
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 tree expand_vector_parallel ( gimple_stmt_iterator gsi,
elem_op_func  f,
tree  type,
tree  a,
tree  b,
enum tree_code  code 
)
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 tree expand_vector_piecewise ( gimple_stmt_iterator gsi,
elem_op_func  f,
tree  type,
tree  inner_type,
tree  a,
tree  b,
enum tree_code  code 
)
static
   Expand a vector operation to scalars, by using many operations
   whose type is the vector type's inner type.  
static bool gate_expand_vector_operations_ssa ( )
static
   Use this to lower vector operations introduced by the vectorizer,
   if it may need the bit-twiddling tricks implemented in this file.  
static void lower_vec_perm ( )
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 ( )
static tree tree_vec_extract ( gimple_stmt_iterator gsi,
tree  type,
tree  t,
tree  bitsize,
tree  bitpos 
)
inlinestatic
static tree type_for_widest_vector_mode ( )
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 tree vector_element ( )
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.  

Variable Documentation

tree vector_inner_type
static
int vector_last_nunits
static
tree vector_last_type
static