GCC Middle and Back End API Reference
tree-vect-generic.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tree.h"
#include "tm.h"
#include "langhooks.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-ssanames.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "flags.h"
#include "ggc.h"
#include "diagnostic.h"
#include "target.h"
#include "expr.h"
#include "optabs.h"
#include "gt-tree-vect-generic.h"
Include dependency graph for tree-vect-generic.c:

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(), NULL_TREE, optab_for_tree_code(), optab_handler(), optab_scalar, TYPE_MODE, 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 gcc_assert, TREE_CODE, and 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.

References TYPE_VECTOR_SUBPARTS.

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

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(), is_gimple_assign(), SSA_NAME_DEF_STMT, TREE_CODE, TREE_INT_CST_LOW, TREE_TYPE, and TYPE_VECTOR_SUBPARTS.

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