GCC Middle and Back End API Reference
tree-ssa-math-opts.c File Reference

Data Structures

struct  occurrence
struct  symbolic_number

Functions

static struct occurrenceocc_new ()
static void insert_bb (struct occurrence *new_occ, basic_block idom, struct occurrence **p_head)
static void register_division_in ()
static void compute_merit ()
static bool is_division_by ()
static void insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ, tree def, tree recip_def, int threshold)
static void replace_reciprocal ()
static struct occurrencefree_bb ()
static void execute_cse_reciprocals_1 ()
static bool gate_cse_reciprocals ()
static unsigned int execute_cse_reciprocals ()
gimple_opt_passmake_pass_cse_reciprocals ()
static bool maybe_record_sincos (vec< gimple > *stmts, basic_block *top_bb, gimple use_stmt)
static bool execute_cse_sincos_1 ()
static int powi_lookup_cost ()
static int powi_cost ()
static tree powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type, HOST_WIDE_INT n, tree *cache)
static tree powi_as_mults (gimple_stmt_iterator *gsi, location_t loc, tree arg0, HOST_WIDE_INT n)
static tree gimple_expand_builtin_powi (gimple_stmt_iterator *gsi, location_t loc, tree arg0, HOST_WIDE_INT n)
static tree build_and_insert_call (gimple_stmt_iterator *gsi, location_t loc, tree fn, tree arg)
static tree build_and_insert_binop (gimple_stmt_iterator *gsi, location_t loc, const char *name, enum tree_code code, tree arg0, tree arg1)
static tree build_and_insert_ref (gimple_stmt_iterator *gsi, location_t loc, tree type, const char *name, enum tree_code code, tree arg0)
static tree build_and_insert_cast (gimple_stmt_iterator *gsi, location_t loc, tree type, tree val)
static tree gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, tree arg0, tree arg1)
static tree gimple_expand_builtin_cabs ()
static unsigned int execute_cse_sincos ()
static bool gate_cse_sincos ()
gimple_opt_passmake_pass_cse_sincos ()
static bool do_shift_rotate (enum tree_code code, struct symbolic_number *n, int count)
static bool verify_symbolic_number_p ()
static tree find_bswap_1 ()
static tree find_bswap ()
static unsigned int execute_optimize_bswap ()
static bool gate_optimize_bswap ()
gimple_opt_passmake_pass_optimize_bswap ()
static bool widening_mult_conversion_strippable_p ()
static bool is_widening_mult_rhs_p (tree type, tree rhs, tree *type_out, tree *new_rhs_out)
static bool is_widening_mult_p (gimple stmt, tree *type1_out, tree *rhs1_out, tree *type2_out, tree *rhs2_out)
static bool convert_mult_to_widen ()
static bool convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple stmt, enum tree_code code)
static bool convert_mult_to_fma ()
static unsigned int execute_optimize_widening_mul ()
static bool gate_optimize_widening_mul ()
gimple_opt_passmake_pass_optimize_widening_mul ()

Variables

struct {
   int   rdivs_inserted
   int   rfuncs_inserted
reciprocal_stats
struct {
   int   inserted
sincos_stats
struct {
   int   found_16bit
   int   found_32bit
   int   found_64bit
bswap_stats
struct {
   int   widen_mults_inserted
   int   maccs_inserted
   int   fmas_inserted
widen_mul_stats
static struct occurrenceocc_head
static alloc_pool occ_pool
static const unsigned char powi_table [POWI_TABLE_SIZE]

Function Documentation

static tree build_and_insert_binop ( gimple_stmt_iterator gsi,
location_t  loc,
const char *  name,
enum tree_code  code,
tree  arg0,
tree  arg1 
)
static
Build a gimple binary operation with the given CODE and arguments
   ARG0, ARG1, assigning the result to a new SSA name for variable
   TARGET.  Insert the statement prior to GSI's current position, and
   return the fresh SSA name. 

References gimple_build_assign_with_ops(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, and make_temp_ssa_name().

Referenced by gimple_expand_builtin_cabs(), and gimple_expand_builtin_pow().

static tree build_and_insert_call ( gimple_stmt_iterator gsi,
location_t  loc,
tree  fn,
tree  arg 
)
static
Build a gimple call statement that calls FN with argument ARG.
   Set the lhs of the call statement to a fresh SSA name.  Insert the
   statement prior to GSI's current position, and return the fresh
   SSA name.   

References gimple_build_call(), gimple_set_lhs(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, and make_temp_ssa_name().

Referenced by gimple_expand_builtin_cabs(), and gimple_expand_builtin_pow().

static tree build_and_insert_cast ( gimple_stmt_iterator gsi,
location_t  loc,
tree  type,
tree  val 
)
static
Build a gimple assignment to cast VAL to TYPE.  Insert the statement
   prior to GSI's current position, and return the fresh SSA name.   

References gimple_build_assign_with_ops(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, and make_ssa_name().

Referenced by convert_mult_to_widen(), and convert_plusminus_to_widen().

static tree build_and_insert_ref ( gimple_stmt_iterator gsi,
location_t  loc,
tree  type,
const char *  name,
enum tree_code  code,
tree  arg0 
)
inlinestatic
Build a gimple reference operation with the given CODE and argument
   ARG, assigning the result to a new SSA name of TYPE with NAME.
   Insert the statement prior to GSI's current position, and return
   the fresh SSA name.   

References gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, and make_temp_ssa_name().

Referenced by gimple_expand_builtin_cabs().

static void compute_merit ( )
static
Compute the number of divisions that postdominate each block in OCC and
   its children.   

References occurrence::bb, CDI_POST_DOMINATORS, occurrence::children, dom, dominated_by_p(), occurrence::next, occurrence::num_divisions, and single_noncomplex_succ().

Referenced by execute_cse_reciprocals_1().

static bool convert_mult_to_fma ( )
static
Combine the multiplication at MUL_STMT with operands MULOP1 and MULOP2
   with uses in additions and subtractions to form fused multiply-add
   operations.  Returns true if successful and MUL_STMT should be removed.   

References force_gimple_operand_gsi(), FP_CONTRACT_OFF, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign_with_ops(), gimple_get_lhs(), gsi_for_stmt(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, has_single_use(), has_zero_uses(), is_gimple_assign(), is_gimple_debug(), optab_handler(), release_defs(), single_imm_use(), and widen_mul_stats.

Referenced by execute_optimize_widening_mul().

static bool convert_mult_to_widen ( )
static
Process a single gimple statement STMT, which has a MULT_EXPR as
   its rhs, and try to convert it into a WIDEN_MULT_EXPR.  The return
   value is true iff we converted the statement.   

References build_and_insert_cast(), build_nonstandard_integer_type(), find_widening_optab_handler_and_mode(), gimple_assign_lhs(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), gimple_location(), handler(), is_widening_mult_p(), type(), update_stmt(), and widen_mul_stats.

Referenced by execute_optimize_widening_mul().

static bool convert_plusminus_to_widen ( gimple_stmt_iterator gsi,
gimple  stmt,
enum tree_code  code 
)
static
Process a single gimple statement STMT, which is found at the
   iterator GSI and has a either a PLUS_EXPR or a MINUS_EXPR as its
   rhs (given by CODE), and try to convert it into a
   WIDEN_MULT_PLUS_EXPR or a WIDEN_MULT_MINUS_EXPR.  The return value
   is true iff we converted the statement.   

References build_and_insert_cast(), build_nonstandard_integer_type(), find_widening_optab_handler_and_mode(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_with_ops_1(), gimple_location(), gsi_stmt(), handler(), is_gimple_assign(), is_widening_mult_p(), optab_default, optab_for_tree_code(), type(), update_stmt(), useless_type_conversion_p(), and widen_mul_stats.

Referenced by execute_optimize_widening_mul().

static bool do_shift_rotate ( enum tree_code  code,
struct symbolic_number n,
int  count 
)
inlinestatic
Perform a SHIFT or ROTATE operation by COUNT bits on symbolic
   number N.  Return false if the requested operation is not permitted
   on a symbolic number.   

References count, HOST_WIDEST_INT, symbolic_number::n, and symbolic_number::size.

Referenced by find_bswap_1().

static void execute_cse_reciprocals_1 ( )
static
Look for floating-point divisions among DEF's uses, and try to
   replace them by multiplications with the reciprocal.  Add
   as many statements computing the reciprocal as needed.

   DEF must be a GIMPLE register of a floating-point type.   

References compute_merit(), count, free_bb(), insert_reciprocals(), is_division_by(), is_gimple_reg(), occurrence::next, register_division_in(), replace_reciprocal(), and targetm.

Referenced by execute_cse_reciprocals().

static bool execute_cse_sincos_1 ( )
static
Look for sin, cos and cexpi calls with the same argument NAME and
   create a single call to cexpi CSEing the result in this case.
   We first walk over all immediate uses of the argument collecting
   statements that we can CSE in a vector and in a second pass replace
   the statement rhs with a REALPART or IMAGPART expression on the
   result of the cexpi call we insert before the use statement that
   dominates all other candidates.   

References BUILT_IN_NORMAL, cfg_changed, gimple_build_call(), gimple_call_fndecl(), gimple_call_lhs(), gimple_call_set_lhs(), gimple_purge_dead_eh_edges(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), gsi_replace(), GSI_SAME_STMT, make_temp_ssa_name(), mathfn_built_in(), maybe_record_sincos(), sincos_stats, type(), and vNULL.

Referenced by execute_cse_sincos().

static tree find_bswap ( )
static
Check if STMT completes a bswap implementation consisting of ORs,
   SHIFTs and ANDs.  Return the source tree expression on which the
   byte swap is performed and NULL if no bswap was found.   
The number which the find_bswap result should match in order to
   have a full byte swap.  The number is shifted to the left according
   to the size of the symbolic number before using it.   

References ceil_log2(), find_bswap_1(), gimple_expr_type(), HOST_WIDE_INT, HOST_WIDEST_INT, limit, symbolic_number::n, and symbolic_number::size.

Referenced by execute_optimize_bswap().

static tree find_bswap_1 ( )
static
find_bswap_1 invokes itself recursively with N and tries to perform
   the operation given by the rhs of STMT on the result.  If the
   operation could successfully be executed the function returns the
   tree expression of the source operand and NULL otherwise.   

References do_shift_rotate(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_expr_type(), GIMPLE_UNARY_RHS, HOST_WIDEST_INT, is_gimple_assign(), symbolic_number::n, symbolic_number::size, verify_symbolic_number_p(), and widest_int_cst_value().

Referenced by find_bswap().

static struct occurrence* free_bb ( )
staticread
Free OCC and return one more "struct occurrence" to be freed.   

References basic_block_def::aux, occurrence::bb, occurrence::children, occurrence::next, and pool_free().

Referenced by execute_cse_reciprocals_1().

static bool gate_cse_reciprocals ( )
static
static bool gate_cse_sincos ( )
static
static bool gate_optimize_bswap ( )
static
static bool gate_optimize_widening_mul ( )
static
static tree gimple_expand_builtin_cabs ( )
static
ARG is the argument to a cabs builtin call in GSI with location info
   LOC.  Create a sequence of statements prior to GSI that calculates
   sqrt(R*R + I*I), where R and I are the real and imaginary components
   of ARG, respectively.  Return an expression holding the result.   

References build_and_insert_binop(), build_and_insert_call(), build_and_insert_ref(), gsi_stmt(), mathfn_built_in(), optab_handler(), and optimize_bb_for_speed_p().

Referenced by execute_cse_sincos().

static tree gimple_expand_builtin_pow ( gimple_stmt_iterator gsi,
location_t  loc,
tree  arg0,
tree  arg1 
)
static
ARG0 and ARG1 are the two arguments to a pow builtin call in GSI
   with location info LOC.  If possible, create an equivalent and
   less expensive sequence of statements prior to GSI, and return an
   expession holding the result.   

References abs_hwi(), absu_hwi(), build_and_insert_binop(), build_and_insert_call(), build_real(), cfun, dconst1, dconst2, dconsthalf, gimple_expand_builtin_powi(), gimple_val_nonnegative_real_p(), HOST_WIDE_INT, mathfn_built_in(), optab_handler(), optimize_function_for_speed_p(), optimize_insn_for_speed_p(), powi_cost(), real_arithmetic(), real_convert(), real_from_integer(), real_identical(), real_round(), real_to_integer(), real_value_truncate(), and type().

Referenced by execute_cse_sincos().

static tree gimple_expand_builtin_powi ( gimple_stmt_iterator gsi,
location_t  loc,
tree  arg0,
HOST_WIDE_INT  n 
)
static
ARG0 and N are the two arguments to a powi builtin in GSI with
   location info LOC.  If the arguments are appropriate, create an
   equivalent sequence of statements prior to GSI using an optimal
   number of multiplications, and return an expession holding the
   result.   

References cfun, optimize_function_for_speed_p(), powi_as_mults(), and powi_cost().

Referenced by execute_cse_sincos(), and gimple_expand_builtin_pow().

static void insert_bb ( struct occurrence new_occ,
basic_block  idom,
struct occurrence **  p_head 
)
static
Insert NEW_OCC into our subset of the dominator tree.  P_HEAD points to a
   list of "struct occurrence"s, one per basic block, having IDOM as
   their common dominator.

   We try to insert NEW_OCC as deep as possible in the tree, and we also
   insert any other block that is a common dominator for BB and one
   block already in the tree.   

References basic_block_def::aux, occurrence::bb, CDI_DOMINATORS, occurrence::children, dom, nearest_common_dominator(), occurrence::next, and occ_new().

Referenced by create_add_on_incoming_edge(), insert_stmt_after(), and register_division_in().

static void insert_reciprocals ( gimple_stmt_iterator def_gsi,
struct occurrence occ,
tree  def,
tree  recip_def,
int  threshold 
)
static
Walk the subset of the dominator tree rooted at OCC, setting the
   RECIP_DEF field to a definition of 1.0 / DEF that can be used in
   the given basic block.  The field may be left NULL, of course,
   if it is not possible or profitable to do the optimization.

   DEF_BSI is an iterator pointing at the statement defining DEF.
   If RECIP_DEF is set, a dominator already has a computation that can
   be used.   

References occurrence::bb, gimple_stmt_iterator_d::bb, occurrence::bb_has_division, build_one_cst(), occurrence::children, create_tmp_reg(), gimple_build_assign_with_ops(), gsi_after_labels(), gsi_end_p(), gsi_insert_after(), gsi_insert_before(), GSI_NEW_STMT, gsi_next(), GSI_SAME_STMT, gsi_stmt(), is_division_by(), occurrence::next, occurrence::num_divisions, occurrence::recip_def, occurrence::recip_def_stmt, reciprocal_stats, and type().

Referenced by execute_cse_reciprocals_1().

static bool is_division_by ( )
inlinestatic
Return whether USE_STMT is a floating-point division by DEF.   

References gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), and is_gimple_assign().

Referenced by execute_cse_reciprocals_1(), and insert_reciprocals().

static bool is_widening_mult_p ( gimple  stmt,
tree type1_out,
tree rhs1_out,
tree type2_out,
tree rhs2_out 
)
static
Return true if STMT performs a widening multiplication, assuming the
   output type is TYPE.  If so, store the unwidened types of the operands
   in *TYPE1_OUT and *TYPE2_OUT respectively.  Also fill *RHS1_OUT and
   *RHS2_OUT such that converting those operands to types *TYPE1_OUT
   and *TYPE2_OUT would give the operands of the multiplication.   

References gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), int_fits_type_p(), and is_widening_mult_rhs_p().

Referenced by convert_mult_to_widen(), and convert_plusminus_to_widen().

static bool is_widening_mult_rhs_p ( tree  type,
tree  rhs,
tree type_out,
tree new_rhs_out 
)
static
Return true if RHS is a suitable operand for a widening multiplication,
   assuming a target type of TYPE.
   There are two cases:

     - RHS makes some value at least twice as wide.  Store that value
       in *NEW_RHS_OUT if so, and store its type in *TYPE_OUT.

     - RHS is an integer constant.  Store that value in *NEW_RHS_OUT if so,
       but leave *TYPE_OUT untouched.   

References gimple_assign_rhs1(), is_gimple_assign(), and widening_mult_conversion_strippable_p().

Referenced by is_widening_mult_p().

gimple_opt_pass* make_pass_cse_reciprocals ( )
gimple_opt_pass* make_pass_cse_sincos ( )
gimple_opt_pass* make_pass_optimize_bswap ( )
gimple_opt_pass* make_pass_optimize_widening_mul ( )
static bool maybe_record_sincos ( vec< gimple > *  stmts,
basic_block top_bb,
gimple  use_stmt 
)
static
Records an occurrence at statement USE_STMT in the vector of trees
   STMTS if it is dominated by *TOP_BB or dominates it or this basic block
   is not yet initialized.  Returns true if the occurrence was pushed on
   the vector.  Adjusts *TOP_BB to be the basic block dominating all
   statements in the vector.   

References CDI_DOMINATORS, dominated_by_p(), and gimple_bb().

Referenced by execute_cse_sincos_1().

static struct occurrence* occ_new ( )
staticread
Allocate and return a new struct occurrence for basic block BB, and
   whose children list is headed by CHILDREN.   

References basic_block_def::aux, occurrence::bb, occurrence::children, memset(), and pool_alloc().

Referenced by insert_bb(), and register_division_in().

static tree powi_as_mults ( gimple_stmt_iterator gsi,
location_t  loc,
tree  arg0,
HOST_WIDE_INT  n 
)
static
Convert ARG0**N to a tree of multiplications of ARG0 with itself.
   This function needs to be kept in sync with powi_cost above.   

References build_real(), cache, dconst1, gimple_build_assign_with_ops(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, make_temp_ssa_name(), memset(), and powi_as_mults_1().

Referenced by gimple_expand_builtin_powi().

static tree powi_as_mults_1 ( gimple_stmt_iterator gsi,
location_t  loc,
tree  type,
HOST_WIDE_INT  n,
tree cache 
)
static
Recursive subroutine of powi_as_mults.  This function takes the
   array, CACHE, of already calculated exponents and an exponent N and
   returns a tree that corresponds to CACHE[1]**N, with type TYPE.   

References gimple_build_assign_with_ops(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, HOST_WIDE_INT, make_temp_ssa_name(), and powi_table.

Referenced by powi_as_mults().

static int powi_cost ( )
static
Return the number of multiplications required to calculate
   powi(x,n) for an arbitrary x, given the exponent N.  This
   function needs to be kept in sync with powi_as_mults below.   

References cache, HOST_WIDE_INT, memset(), and powi_lookup_cost().

Referenced by gimple_expand_builtin_pow(), and gimple_expand_builtin_powi().

static int powi_lookup_cost ( )
static
Return the number of multiplications required to calculate
   powi(x,n) where n is less than POWI_TABLE_SIZE.  This is a
   subroutine of powi_cost.  CACHE is an array indicating
   which exponents have already been calculated.   

References powi_table.

Referenced by powi_cost().

static void register_division_in ( )
inlinestatic
Register that we found a division in BB.   

References basic_block_def::aux, occurrence::bb_has_division, insert_bb(), occurrence::num_divisions, and occ_new().

Referenced by execute_cse_reciprocals_1().

static void replace_reciprocal ( )
inlinestatic
static bool verify_symbolic_number_p ( )
inlinestatic
Perform sanity checking for the symbolic number N and the gimple
   statement STMT.   

References gimple_expr_type(), and symbolic_number::size.

Referenced by find_bswap_1().

static bool widening_mult_conversion_strippable_p ( )
static
Return true if stmt is a type conversion operation that can be stripped
   when used in a widening multiply operation.   

References gimple_assign_lhs(), gimple_assign_rhs1(), and gimple_assign_rhs_code().

Referenced by is_widening_mult_rhs_p().


Variable Documentation

struct { ... } bswap_stats

Referenced by execute_optimize_bswap().

int fmas_inserted
int found_16bit
int found_32bit
int found_64bit
int maccs_inserted
struct occurrence* occ_head
static
The instance of "struct occurrence" representing the highest
   interesting block in the dominator tree.   
alloc_pool occ_pool
static
Allocation pool for getting instances of "struct occurrence".   
const unsigned char powi_table[POWI_TABLE_SIZE]
static
The following table is an efficient representation of an
   "optimal power tree".  For each value, i, the corresponding
   value, j, in the table states than an optimal evaluation
   sequence for calculating pow(x,i) can be found by evaluating
   pow(x,j)*pow(x,i-j).  An optimal power tree for the first
   100 integers is given in Knuth's "Seminumerical algorithms".   

Referenced by powi_as_mults_1(), and powi_lookup_cost().

int rdivs_inserted
struct { ... } reciprocal_stats
int rfuncs_inserted
struct { ... } sincos_stats
int widen_mults_inserted