GCC Middle and Back End API Reference
tree-ssa-math-opts.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "optabs-tree.h"
#include "gimple-pretty-print.h"
#include "alias.h"
#include "fold-const.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "stor-layout.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "builtins.h"
#include "internal-fn.h"
#include "case-cfn-macros.h"
#include "optabs-libfuncs.h"
#include "tree-eh.h"
#include "targhooks.h"
#include "domwalk.h"
#include "tree-ssa-math-opts.h"
#include "dbgcnt.h"
#include "langhooks.h"
#include "cfghooks.h"
Include dependency graph for tree-ssa-math-opts.cc:

Data Structures

struct  occurrence
struct  pow_synth_sqrt_info
struct  fma_transformation_info
class  fma_deferring_state
struct  long_mul_halves
struct  long_mul_arg_split

Macros

#define POWI_MAX_MULTS   (2*HOST_BITS_PER_WIDE_INT-2)
#define POWI_TABLE_SIZE   256
#define POWI_WINDOW_SIZE   3

Functions

static void insert_bb (struct occurrence *new_occ, basic_block idom, struct occurrence **p_head)
static void register_division_in (basic_block bb, int importance)
static void compute_merit (struct occurrence *occ)
static bool is_division_by (gimple *use_stmt, tree def)
static bool is_mult_by (gimple *use_stmt, tree def, tree a)
static bool is_square_of (gimple *use_stmt, tree def)
static bool is_division_by_square (gimple *use_stmt, tree def)
static void insert_reciprocals (gimple_stmt_iterator *def_gsi, struct occurrence *occ, tree def, tree recip_def, tree square_recip_def, int should_insert_square_recip, int threshold)
static void replace_reciprocal_squares (use_operand_p use_p)
static void replace_reciprocal (use_operand_p use_p)
static struct occurrencefree_bb (struct occurrence *occ)
static void optimize_recip_sqrt (gimple_stmt_iterator *def_gsi, tree def)
static void execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def)
internal_fn internal_fn_reciprocal (gcall *call)
gimple_opt_passmake_pass_cse_reciprocals (gcc::context *ctxt)
static tree execute_cse_conv_1 (tree name, bool *cfg_changed)
static bool maybe_record_sincos (vec< gimple * > *stmts, basic_block *top_bb, gimple *use_stmt)
static bool execute_cse_sincos_1 (tree name)
static int powi_lookup_cost (unsigned HOST_WIDE_INT n, bool *cache)
static int powi_cost (HOST_WIDE_INT n)
static tree powi_as_mults_1 (gimple_stmt_iterator *gsi, location_t loc, tree type, unsigned HOST_WIDE_INT n, tree *cache)
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_cast (gimple_stmt_iterator *gsi, location_t loc, tree type, tree val)
bool representable_as_half_series_p (REAL_VALUE_TYPE c, unsigned n, struct pow_synth_sqrt_info *info)
static tree get_fn_chain (tree arg, unsigned int n, gimple_stmt_iterator *gsi, tree fn, location_t loc, tree *cache)
static void print_nested_fn (FILE *stream, const char *fname, const char *arg, unsigned int n)
static void dump_fractional_sqrt_sequence (FILE *stream, const char *arg, struct pow_synth_sqrt_info *info)
static void dump_integer_part (FILE *stream, const char *arg, HOST_WIDE_INT n)
static tree expand_pow_as_sqrts (gimple_stmt_iterator *gsi, location_t loc, tree arg0, tree arg1, HOST_WIDE_INT max_depth)
static tree gimple_expand_builtin_pow (gimple_stmt_iterator *gsi, location_t loc, tree arg0, tree arg1)
gimple_opt_passmake_pass_cse_sincos (gcc::context *ctxt)
gimple_opt_passmake_pass_expand_pow (gcc::context *ctxt)
static bool widening_mult_conversion_strippable_p (tree result_type, gimple *stmt)
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 is_copysign_call_with_1 (gimple *call)
static bool convert_expand_mult_copysign (gimple *stmt, gimple_stmt_iterator *gsi)
static bool convert_mult_to_widen (gimple *stmt, gimple_stmt_iterator *gsi)
static bool convert_plusminus_to_widen (gimple_stmt_iterator *gsi, gimple *stmt, enum tree_code code)
static void convert_mult_to_fma_1 (tree mul_result, tree op1, tree op2)
static void cancel_fma_deferring (fma_deferring_state *state)
static gphiresult_of_phi (tree op)
static bool last_fma_candidate_feeds_initial_phi (fma_deferring_state *state, hash_set< tree > *last_result_set)
static bool convert_mult_to_fma (gimple *mul_stmt, tree op1, tree op2, fma_deferring_state *state, tree mul_cond=NULL_TREE, tree mul_len=NULL_TREE, tree mul_bias=NULL_TREE)
static void maybe_optimize_guarding_check (vec< gimple * > &mul_stmts, gimple *cond_stmt, gimple *div_stmt, bool *cfg_changed)
static bool arith_cast_equal_p (tree val1, tree val2)
static int arith_overflow_check_p (gimple *stmt, gimple *cast_stmt, gimple *&use_stmt, tree maxval, tree *other)
bool gimple_unsigned_integer_sat_add (tree, tree *, tree(*)(tree))
bool gimple_unsigned_integer_sat_sub (tree, tree *, tree(*)(tree))
bool gimple_unsigned_integer_sat_trunc (tree, tree *, tree(*)(tree))
bool gimple_unsigned_integer_sat_mul (tree, tree *, tree(*)(tree))
bool gimple_spaceship (tree, tree *, tree(*)(tree))
bool gimple_signed_integer_sat_add (tree, tree *, tree(*)(tree))
bool gimple_signed_integer_sat_sub (tree, tree *, tree(*)(tree))
bool gimple_signed_integer_sat_trunc (tree, tree *, tree(*)(tree))
static void build_saturation_binary_arith_call_and_replace (gimple_stmt_iterator *gsi, internal_fn fn, tree lhs, tree op_0, tree op_1)
static bool build_saturation_binary_arith_call_and_insert (gimple_stmt_iterator *gsi, internal_fn fn, tree lhs, tree op_0, tree op_1)
static void match_saturation_add_with_assign (gimple_stmt_iterator *gsi, gassign *stmt)
static bool match_saturation_add (gimple_stmt_iterator *gsi, gphi *phi)
static void match_unsigned_saturation_sub (gimple_stmt_iterator *gsi, gassign *stmt)
static void match_unsigned_saturation_mul (gimple_stmt_iterator *gsi, gassign *stmt)
static bool match_saturation_mul (gimple_stmt_iterator *gsi, gphi *phi)
static bool match_spaceship (gimple_stmt_iterator *gsi, gphi *phi)
static bool match_saturation_sub (gimple_stmt_iterator *gsi, gphi *phi)
static void match_unsigned_saturation_trunc (gimple_stmt_iterator *gsi, gassign *stmt)
static bool match_saturation_trunc (gimple_stmt_iterator *gsi, gphi *phi)
static bool match_arith_overflow (gimple_stmt_iterator *gsi, gimple *stmt, enum tree_code code, bool *cfg_changed)
static gimpleuaddc_cast (gimple *g)
static gimpleuaddc_ne0 (gimple *g)
static bool uaddc_is_cplxpart (gimple *g, tree_code part)
static bool match_uaddc_usubc (gimple_stmt_iterator *gsi, gimple *stmt, tree_code code)
static void match_single_bit_test (gimple_stmt_iterator *gsi, gimple *stmt)
static bool target_supports_divmod_p (optab divmod_optab, optab div_optab, machine_mode mode)
static bool divmod_candidate_p (gassign *stmt)
static bool convert_to_divmod (gassign *stmt)
static bool convert_mult_to_highpart (gassign *stmt, gimple_stmt_iterator *gsi)
static void optimize_spaceship (gcond *stmt)
static bool can_widen_to_narrow_p (scalar_int_mode narrow_mode, unsigned int half_width, scalar_int_mode *half_mode)
static void build_long_mul_partials (gimple_seq *seq, location_t loc, tree op1, tree op2, tree half_type, tree half_amt, tree *lolo, tree *hilo, tree *lohi, tree *hihi, bool use_widen)
static tree emit_long_mul_highpart (gimple_seq *seq, location_t loc, tree a, tree b, tree narrow_type)
static tree combine_long_mul_halves (gimple_seq *seq, location_t loc, tree l1, tree h1, tree l2, tree h2, tree narrow_type)
static bool long_mul_op_fits_p (tree op, unsigned narrow_prec, bitmap phi_seen)
static bool long_mul_split_operand (gimple_seq *, location_t, tree, tree, tree *, tree *)
static bool long_mul_split_phi (gphi *phi, tree narrow_type, tree *lo, tree *hi)
static bool long_mul_high_half_uses (tree prod, unsigned int narrow_prec, vec< gimple * > *high_uses)
static bool long_mul_only_low_half_used_p (tree prod, unsigned int narrow_prec)
static bool unexpandable_long_mul_p (gimple *stmt, tree *narrow_type)
static bool narrow_long_mul_low_half (gimple_stmt_iterator *)
static void narrow_long_mul_operands (tree op1, tree op2)
static void finish_long_mul_low_half (gimple_stmt_iterator *gsi)
static bool narrow_long_mul_halves (gimple *stmt)
bool gimple_long_mul_high_chain (tree, tree *, tree(*)(tree))
static bool lower_long_mul_high_chain (gimple_stmt_iterator *gsi)
bool optimize_widening_mul_active_p (void)
gimple_opt_passmake_pass_optimize_widening_mul (gcc::context *ctxt)

Variables

static struct { ... }  reciprocal_stats
struct { 
   int   inserted 
   int   conv_removed 
sincos_stats
struct { 
   int   widen_mults_inserted 
   int   maccs_inserted 
   int   fmas_inserted 
   int   divmod_calls_inserted 
   int   highpart_mults_inserted 
widen_mul_stats
static struct occurrenceocc_head
static object_allocator< occurrence > * occ_pool
static const unsigned char powi_table [POWI_TABLE_SIZE]
static hash_map< tree, long_mul_halves > * long_mul_phi_halves

Macro Definition Documentation

◆ POWI_MAX_MULTS

#define POWI_MAX_MULTS   (2*HOST_BITS_PER_WIDE_INT-2)
To evaluate powi(x,n), the floating point value x raised to the
constant integer exponent n, we use a hybrid algorithm that
combines the "window method" with look-up tables.  For an
introduction to exponentiation algorithms and "addition chains",
see section 4.6.3, "Evaluation of Powers" of Donald E. Knuth,
"Seminumerical Algorithms", Vol. 2, "The Art of Computer Programming",
3rd Edition, 1998, and Daniel M. Gordon, "A Survey of Fast Exponentiation
Methods", Journal of Algorithms, Vol. 27, pp. 129-146, 1998.   
Provide a default value for POWI_MAX_MULTS, the maximum number of
multiplications to inline before calling the system library's pow
function.  powi(x,n) requires at worst 2*bits(n)-2 multiplications,
so this default never requires calling pow, powf or powl.   

Referenced by expand_pow_as_sqrts(), gimple_expand_builtin_pow(), and gimple_expand_builtin_powi().

◆ POWI_TABLE_SIZE

#define POWI_TABLE_SIZE   256
The size of the "optimal power tree" lookup table.  All
exponents less than this value are simply looked up in the
powi_table below.  This threshold is also used to size the
cache of pseudo registers that hold intermediate results.   

Referenced by powi_as_mults(), powi_as_mults_1(), and powi_cost().

◆ POWI_WINDOW_SIZE

#define POWI_WINDOW_SIZE   3
The size, in bits of the window, used in the "window method"
exponentiation algorithm.  This is equivalent to a radix of
(1<<POWI_WINDOW_SIZE) in the corresponding "m-ary method".   

Referenced by powi_as_mults_1(), and powi_cost().

Function Documentation

◆ arith_cast_equal_p()

bool arith_cast_equal_p ( tree val1,
tree val2 )
static
Helper function for arith_overflow_check_p.  Return true
if VAL1 is equal to VAL2 cast to corresponding integral type
with other signedness or vice versa.   

References wi::eq_p(), gimple_assign_cast_p(), gimple_assign_rhs1(), SSA_NAME_DEF_STMT, wi::to_wide(), and TREE_CODE.

Referenced by arith_overflow_check_p().

◆ arith_overflow_check_p()

int arith_overflow_check_p ( gimple * stmt,
gimple * cast_stmt,
gimple *& use_stmt,
tree maxval,
tree * other )
static

◆ build_and_insert_binop()

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(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, make_temp_ssa_name(), NULL, and TREE_TYPE.

Referenced by convert_mult_to_highpart(), expand_pow_as_sqrts(), and gimple_expand_builtin_pow().

◆ build_and_insert_call()

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, make_temp_ssa_name(), NULL, and TREE_TYPE.

Referenced by get_fn_chain(), and gimple_expand_builtin_pow().

◆ build_and_insert_cast()

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_convert(), and GSI_SAME_STMT.

Referenced by convert_mult_to_highpart(), convert_mult_to_widen(), and convert_plusminus_to_widen().

◆ build_long_mul_partials()

void build_long_mul_partials ( gimple_seq * seq,
location_t loc,
tree op1,
tree op2,
tree half_type,
tree half_amt,
tree * lolo,
tree * hilo,
tree * lohi,
tree * hihi,
bool use_widen )
static
Append to *SEQ the operand split and partial products for an unsigned
long multiply of OP1 by OP2 at the precision of TREE_TYPE (OP1).
HALF_TYPE is the (N/2)-bit unsigned type; HALF_AMT is the integer-typed
shift constant equal to N/2.

Outputs the four partial products via *LOLO, *HILO, *LOHI, *HIHI.

USE_WIDEN selects the partial-product form:
  true  - cast halves to HALF_TYPE and use WIDEN_MULT_EXPR (needs
          an (N/2)-by-(N/2)->N widening multiply optab).
  false - mask/shift halves within the N-bit accumulator and use
          plain MULT_EXPR; the halves fit in N/2 bits so the N-bit
          low product is exact.   

References gimple_build(), wi::mask(), TREE_TYPE, TYPE_PRECISION, and wide_int_to_tree().

Referenced by emit_long_mul_highpart().

◆ build_saturation_binary_arith_call_and_insert()

◆ build_saturation_binary_arith_call_and_replace()

◆ can_widen_to_narrow_p()

bool can_widen_to_narrow_p ( scalar_int_mode narrow_mode,
unsigned int half_width,
scalar_int_mode * half_mode )
static
Long-multiply inverse-lowering helper.

The forwprop long-multiply recognizer canonicalizes a hand-written
longhand high-part multiply into a cast+mult+shift+cast chain
`(N) ((2N) a * (2N) b) >> N'.  When the target lacks an expansion
path for the wide form, `lower_long_mul_high_chain' resynthesizes
the longhand at narrow precision via `build_long_mul_partials'.   
Test whether the target supports an (HALF)-by-(HALF)->NARROW unsigned
widening multiply.  Returns true on success, with the half-width
scalar int mode placed in *HALF_MODE.   

References convert_optab_handler(), and int_mode_for_size().

Referenced by emit_long_mul_highpart().

◆ cancel_fma_deferring()

void cancel_fma_deferring ( fma_deferring_state * state)
static

◆ combine_long_mul_halves()

tree combine_long_mul_halves ( gimple_seq * seq,
location_t loc,
tree l1,
tree h1,
tree l2,
tree h2,
tree narrow_type )
static
Emit into *SEQ the high N bits (NARROW_TYPE) of the unsigned product of two
2N-bit values given as N-bit halves, x = L1 + H1*2^N and y = L2 + H2*2^N:
the high half of x*y is the high N bits of L1*L2, plus H1*L2 and L1*H2, all
mod 2^N.   

References emit_long_mul_highpart(), and gimple_build().

Referenced by long_mul_split_operand(), lower_long_mul_high_chain(), and narrow_long_mul_halves().

◆ compute_merit()

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

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

Referenced by compute_merit(), and execute_cse_reciprocals_1().

◆ convert_expand_mult_copysign()

bool convert_expand_mult_copysign ( gimple * stmt,
gimple_stmt_iterator * gsi )
static
Try to expand the pattern x * copysign (1, y) into xorsign (x, y).
This only happens when the xorsign optab is defined, if the
pattern is not a xorsign pattern or if expansion fails FALSE is
returned, otherwise TRUE is returned.   

References as_a(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_build_call_internal(), gimple_call_arg(), gimple_location(), gimple_set_lhs(), gimple_set_location(), gsi_replace(), has_single_use(), HONOR_SNANS(), is_copysign_call_with_1(), optab_handler(), SSA_NAME_DEF_STMT, TREE_CODE, TREE_TYPE, and TYPE_MODE.

◆ convert_mult_to_fma()

bool convert_mult_to_fma ( gimple * mul_stmt,
tree op1,
tree op2,
fma_deferring_state * state,
tree mul_cond = NULL_TREE,
tree mul_len = NULL_TREE,
tree mul_bias = NULL_TREE )
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.
 If MUL_COND is nonnull, the multiplication in MUL_STMT is conditional
 on MUL_COND, otherwise it is unconditional.

 If STATE indicates that we are deferring FMA transformation, that means
 that we do not produce FMAs for basic blocks which look like:

  <bb 6>
  # accumulator_111 = PHI <0.0(5), accumulator_66(6)>
  _65 = _14 * _16;
  accumulator_66 = _65 + accumulator_111;

or its unrolled version, i.e. with several FMA candidates that feed result
of one into the addend of another.  Instead, we add them to a list in STATE
and if we later discover an FMA candidate that is not part of such a chain,
we go back and perform all deferred past candidates.   

References ANY_INTEGRAL_TYPE_P, bb_optimization_type(), can_interpret_as_conditional_op_p(), cancel_fma_deferring(), convert_mult_to_fma_1(), dbg_cnt(), direct_internal_fn_supported_p(), dump_file, dump_flags, FLOAT_TYPE_P, FOR_EACH_IMM_USE_FAST, FOR_EACH_PHI_OR_STMT_USE, FP_CONTRACT_FAST, gcc_assert, gcc_checking_assert, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs_code(), gimple_bb(), gimple_get_lhs(), has_single_use(), has_zero_uses(), integer_truep(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), fma_transformation_info::mul_result, fma_transformation_info::mul_stmt, NULL_TREE, fma_transformation_info::op1, fma_transformation_info::op2, poly_int_tree_p(), print_gimple_stmt(), result_of_phi(), single_imm_use(), SSA_NAME_DEF_STMT, SSA_OP_USE, TDF_DETAILS, TDF_NONE, wi::to_widest(), TREE_CODE, tree_nop_conversion_p(), tree_to_poly_int64(), TREE_TYPE, type_has_mode_precision_p(), TYPE_OVERFLOW_TRAPS, TYPE_SIZE, USE_FROM_PTR, and USE_STMT.

◆ convert_mult_to_fma_1()

◆ convert_mult_to_highpart()

bool convert_mult_to_highpart ( gassign * stmt,
gimple_stmt_iterator * gsi )
static

◆ convert_mult_to_widen()

◆ convert_plusminus_to_widen()

◆ convert_to_divmod()

bool convert_to_divmod ( gassign * stmt)
static
This function looks for:
t1 = a TRUNC_DIV_EXPR b;
t2 = a TRUNC_MOD_EXPR b;
and transforms it to the following sequence:
complex_tmp = DIVMOD (a, b);
t1 = REALPART_EXPR(a);
t2 = IMAGPART_EXPR(b);
For conditions enabling the transform see divmod_candidate_p().

The pass has three parts:
1) Find top_stmt which is trunc_div or trunc_mod stmt and dominates all
   other trunc_div_expr and trunc_mod_expr stmts.
2) Add top_stmt and all trunc_div and trunc_mod stmts dominated by top_stmt
   to stmts vector.
3) Insert DIVMOD call just before top_stmt and update entries in
   stmts vector to use return value of DIMOVD (REALEXPR_PART for div,
   IMAGPART_EXPR for mod).   

References build_complex_type(), CDI_DOMINATORS, cfun, divmod_candidate_p(), dominated_by_p(), fold_build1, FOR_EACH_IMM_USE_STMT, gcc_unreachable, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_bb(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_call_set_nothrow(), gimple_uid(), gsi_for_stmt(), gsi_insert_before(), GSI_SAME_STMT, i, is_gimple_assign(), make_temp_ssa_name(), operand_equal_p(), stmt_can_throw_internal(), TREE_TYPE, update_stmt(), and widen_mul_stats.

◆ divmod_candidate_p()

◆ dump_fractional_sqrt_sequence()

void dump_fractional_sqrt_sequence ( FILE * stream,
const char * arg,
struct pow_synth_sqrt_info * info )
static
Print to STREAM the fractional sequence of sqrt chains
applied to ARG, described by INFO.  Used for the dump file.   

References pow_synth_sqrt_info::deepest, pow_synth_sqrt_info::factors, i, and print_nested_fn().

Referenced by expand_pow_as_sqrts().

◆ dump_integer_part()

void dump_integer_part ( FILE * stream,
const char * arg,
HOST_WIDE_INT n )
static
Print to STREAM a representation of raising ARG to an integer
power N.  Used for the dump file.   

References HOST_WIDE_INT_PRINT_DEC.

Referenced by expand_pow_as_sqrts().

◆ emit_long_mul_highpart()

tree emit_long_mul_highpart ( gimple_seq * seq,
location_t loc,
tree a,
tree b,
tree narrow_type )
static
Emit into *SEQ the high N bits of the unsigned product A * B, where A and B
are NARROW_TYPE (N-bit) values, as a longhand over (N/2)-bit partials.
Returns the high-part SSA.   

References a, as_a(), b, boolean_type_node, build_int_cst(), build_long_mul_partials(), build_nonstandard_integer_type(), can_widen_to_narrow_p(), GET_MODE_PRECISION(), gimple_build(), integer_type_node, wi::mask(), TYPE_MODE, TYPE_PRECISION, and wide_int_to_tree().

Referenced by combine_long_mul_halves().

◆ execute_cse_conv_1()

tree execute_cse_conv_1 ( tree name,
bool * cfg_changed )
static
If NAME is the result of a type conversion, look for other
equivalent dominating or dominated conversions, and replace all
uses with the earliest dominating name, removing the redundant
conversions.  Return the prevailing name.   

References CDI_DOMINATORS, cfg_changed, dominated_by_p(), FOR_EACH_IMM_USE_STMT, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_bb(), gimple_purge_dead_eh_edges(), gsi_end_p(), gsi_for_stmt(), gsi_next(), gsi_remove(), gsi_stmt(), release_defs(), replace_uses_by(), sincos_stats, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, TREE_TYPE, and types_compatible_p().

Referenced by execute_cse_sincos_1().

◆ execute_cse_reciprocals_1()

void execute_cse_reciprocals_1 ( gimple_stmt_iterator * def_gsi,
tree def )
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, FLOAT_TYPE_P, FOR_EACH_IMM_USE_FAST, FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, free_bb(), gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), insert_reciprocals(), is_division_by(), is_gimple_assign(), is_square_of(), occurrence::next, NULL, occ_head, register_division_in(), replace_reciprocal(), replace_reciprocal_squares(), SSA_NAME_DEF_STMT, targetm, TREE_CODE, TREE_TYPE, TYPE_MODE, and USE_STMT.

◆ execute_cse_sincos_1()

bool execute_cse_sincos_1 ( tree name)
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 cfg_changed, execute_cse_conv_1(), fold_build1, FOR_EACH_IMM_USE_STMT, gcc_checking_assert, gcc_unreachable, gimple_bb(), gimple_build_assign(), gimple_build_call(), gimple_call_combined_fn(), 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, i, internal_fn_p(), make_temp_ssa_name(), mathfn_built_in(), mathfn_built_in_type(), maybe_record_sincos(), NULL, NULL_TREE, sincos_stats, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, TREE_TYPE, and types_compatible_p().

◆ expand_pow_as_sqrts()

tree expand_pow_as_sqrts ( gimple_stmt_iterator * gsi,
location_t loc,
tree arg0,
tree arg1,
HOST_WIDE_INT max_depth )
static
Attempt to synthesize a POW[F] (ARG0, ARG1) call using chains of
square roots.  Place at GSI and LOC.  Limit the maximum depth
of the sqrt chains to MAX_DEPTH.  Return the tree holding the
result of the expanded sequence or NULL_TREE if the expansion failed.

This routine assumes that ARG1 is a real number with a fractional part
(the integer exponent case will have been handled earlier in
gimple_expand_builtin_pow).

For ARG1 > 0.0:
* For ARG1 composed of a whole part WHOLE_PART and a fractional part
  FRAC_PART i.e. WHOLE_PART == floor (ARG1) and
                 FRAC_PART == ARG1 - WHOLE_PART:
  Produce POWI (ARG0, WHOLE_PART) * POW (ARG0, FRAC_PART) where
  POW (ARG0, FRAC_PART) is expanded as a product of square root chains
  if it can be expressed as such, that is if FRAC_PART satisfies:
  FRAC_PART == <SUM from i = 1 until MAX_DEPTH> (a[i] * (0.5**i))
  where integer a[i] is either 0 or 1.

  Example:
  POW (x, 3.625) == POWI (x, 3) * POW (x, 0.625)
    --> POWI (x, 3) * SQRT (x) * SQRT (SQRT (SQRT (x)))

For ARG1 < 0.0 there are two approaches:
* (A) Expand to 1.0 / POW (ARG0, -ARG1) where POW (ARG0, -ARG1)
      is calculated as above.

  Example:
  POW (x, -5.625) == 1.0 / POW (x, 5.625)
    -->  1.0 / (POWI (x, 5) * SQRT (x) * SQRT (SQRT (SQRT (x))))

* (B) : WHOLE_PART := - ceil (abs (ARG1))
        FRAC_PART  := ARG1 - WHOLE_PART
  and expand to POW (x, FRAC_PART) / POWI (x, WHOLE_PART).
  Example:
  POW (x, -5.875) == POW (x, 0.125) / POWI (X, 6)
    --> SQRT (SQRT (SQRT (x))) / (POWI (x, 6))

For ARG1 < 0.0 we choose between (A) and (B) depending on
how many multiplications we'd have to do.
So, for the example in (B): POW (x, -5.875), if we were to
follow algorithm (A) we would produce:
1.0 / POWI (X, 5) * SQRT (X) * SQRT (SQRT (X)) * SQRT (SQRT (SQRT (X)))
which contains more multiplications than approach (B).

Hopefully, this approach will eliminate potentially expensive POW library
calls when unsafe floating point math is enabled and allow the compiler to
further optimise the multiplies, square roots and divides produced by this
function.   

References build_and_insert_binop(), build_real(), cache, dconst0, dconst1, pow_synth_sqrt_info::deepest, dump_file, dump_fractional_sqrt_sequence(), dump_integer_part(), exp(), pow_synth_sqrt_info::factors, gcc_assert, get_fn_chain(), gimple_expand_builtin_powi(), i, mathfn_built_in(), NULL_TREE, pow_synth_sqrt_info::num_mults, powi_cost(), POWI_MAX_MULTS, real_arithmetic(), real_ceil(), real_floor(), real_from_integer(), real_identical(), real_to_decimal(), real_to_integer(), real_value_abs(), REAL_VALUE_NEGATIVE, REAL_VALUE_TYPE, representable_as_half_series_p(), SIGNED, TREE_CODE, TREE_REAL_CST, TREE_TYPE, and TYPE_MODE.

Referenced by gimple_expand_builtin_pow().

◆ finish_long_mul_low_half()

void finish_long_mul_low_half ( gimple_stmt_iterator * gsi)
static
The 2N multiply at *GSI has had its high half synthesized elsewhere, so any
use left reads only its low half: narrow it in place, or remove it when it
has no use at all.  Removing it drops a use of each operand, so a 2N
multiply defining one may become low-half-only.  Narrow those operands.   

References gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gsi_remove(), gsi_stmt(), has_zero_uses(), narrow_long_mul_low_half(), narrow_long_mul_operands(), and release_defs().

Referenced by lower_long_mul_high_chain(), and narrow_long_mul_halves().

◆ free_bb()

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

References occurrence::children, free_bb(), and occurrence::next.

Referenced by execute_cse_reciprocals_1(), and free_bb().

◆ get_fn_chain()

tree get_fn_chain ( tree arg,
unsigned int n,
gimple_stmt_iterator * gsi,
tree fn,
location_t loc,
tree * cache )
static
Return the tree corresponding to FN being applied
to ARG N times at GSI and LOC.
Look up previous results from CACHE if need be.
cache[0] should contain just plain ARG i.e. FN applied to ARG 0 times.   

References build_and_insert_call(), cache, and get_fn_chain().

Referenced by expand_pow_as_sqrts(), and get_fn_chain().

◆ gimple_expand_builtin_pow()

◆ gimple_expand_builtin_powi()

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 expression holding the
result.   

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

Referenced by expand_pow_as_sqrts(), and gimple_expand_builtin_pow().

◆ gimple_long_mul_high_chain()

bool gimple_long_mul_high_chain ( tree ,
tree * ,
tree(*  )(tree) )
extern
Match.pd recognizer for the long-multiply recognizer's high-part
emit chain.   

Referenced by lower_long_mul_high_chain().

◆ gimple_signed_integer_sat_add()

bool gimple_signed_integer_sat_add ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_signed_integer_sat_sub()

bool gimple_signed_integer_sat_sub ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_signed_integer_sat_trunc()

bool gimple_signed_integer_sat_trunc ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_spaceship()

bool gimple_spaceship ( tree ,
tree * ,
tree(*  )(tree) )
extern

Referenced by match_spaceship().

◆ gimple_unsigned_integer_sat_add()

bool gimple_unsigned_integer_sat_add ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_mul()

bool gimple_unsigned_integer_sat_mul ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_sub()

bool gimple_unsigned_integer_sat_sub ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_unsigned_integer_sat_trunc()

bool gimple_unsigned_integer_sat_trunc ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ insert_bb()

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, gcc_assert, insert_bb(), nearest_common_dominator(), occurrence::next, NULL, and occurrence::occurrence().

Referenced by insert_bb(), and register_division_in().

◆ insert_reciprocals()

void insert_reciprocals ( gimple_stmt_iterator * def_gsi,
struct occurrence * occ,
tree def,
tree recip_def,
tree square_recip_def,
int should_insert_square_recip,
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.

If should_insert_square_recip is set, then this also inserts
the square of the reciprocal immediately after the definition
of the reciprocal.   

References occurrence::bb, occurrence::bb_has_division, build_one_cst(), occurrence::children, create_tmp_reg(), gimple_build_assign(), gsi_after_labels(), gsi_bb(), gsi_end_p(), gsi_insert_after(), gsi_insert_before(), GSI_NEW_STMT, gsi_next(), GSI_SAME_STMT, gsi_stmt(), insert_reciprocals(), is_division_by(), is_division_by_square(), occurrence::next, occurrence::num_divisions, occurrence::recip_def, occurrence::recip_def_stmt, reciprocal_stats, occurrence::square_recip_def, and TREE_TYPE.

Referenced by execute_cse_reciprocals_1(), and insert_reciprocals().

◆ internal_fn_reciprocal()

internal_fn internal_fn_reciprocal ( gcall * call)
Return an internal function that implements the reciprocal of CALL,
or IFN_LAST if there is no such function that the target supports.   

References direct_internal_fn_supported_p(), direct_internal_fn_types(), gimple_call_combined_fn(), and OPTIMIZE_FOR_SPEED.

◆ is_copysign_call_with_1()

bool is_copysign_call_with_1 ( gimple * call)
static
Check to see if the CALL statement is an invocation of copysign
with 1. being the first argument.   

References as_builtin_fn(), as_internal_fn(), builtin_fn_p(), CASE_FLT_FN, CASE_FLT_FN_FLOATN_NX, dyn_cast(), gimple_call_arg(), gimple_call_combined_fn(), internal_fn_p(), and real_onep().

Referenced by convert_expand_mult_copysign().

◆ is_division_by()

bool is_division_by ( gimple * use_stmt,
tree def )
inlinestatic
Return whether USE_STMT is a floating-point division by DEF.   

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

Referenced by execute_cse_reciprocals_1(), and insert_reciprocals().

◆ is_division_by_square()

bool is_division_by_square ( gimple * use_stmt,
tree def )
inlinestatic
Return whether USE_STMT is a floating-point division by
DEF * DEF.   

References cfun, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), is_square_of(), SSA_NAME_DEF_STMT, stmt_can_throw_internal(), and TREE_CODE.

Referenced by insert_reciprocals().

◆ is_mult_by()

bool is_mult_by ( gimple * use_stmt,
tree def,
tree a )
inlinestatic
Return TRUE if USE_STMT is a multiplication of DEF by A.   

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

Referenced by is_square_of(), and optimize_recip_sqrt().

◆ is_square_of()

bool is_square_of ( gimple * use_stmt,
tree def )
inlinestatic
Return whether USE_STMT is DEF * DEF.   

References is_mult_by().

Referenced by execute_cse_reciprocals_1(), is_division_by_square(), and optimize_recip_sqrt().

◆ is_widening_mult_p()

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(), is_widening_mult_rhs_p(), NULL, TREE_CODE, TREE_TYPE, TYPE_OVERFLOW_TRAPS, and TYPE_PRECISION.

Referenced by convert_mult_to_widen(), and convert_plusminus_to_widen().

◆ is_widening_mult_rhs_p()

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 wi::bit_and(), build_nonstandard_integer_type(), wide_int_storage::from(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), int_mode_for_size(), is_gimple_assign(), wi::mask(), NULL, SSA_NAME_DEF_STMT, wi::to_wide(), TREE_CODE, tree_nonzero_bits(), TREE_TYPE, TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, and widening_mult_conversion_strippable_p().

Referenced by is_widening_mult_p().

◆ last_fma_candidate_feeds_initial_phi()

bool last_fma_candidate_feeds_initial_phi ( fma_deferring_state * state,
hash_set< tree > * last_result_set )
static
After processing statements of a BB and recording STATE, return true if the
initial phi is fed by the last FMA candidate result ore one such result from
previously processed BBs marked in LAST_RESULT_SET.   

References hash_set< KeyId, Lazy, Traits >::contains(), FOR_EACH_PHI_ARG, SSA_OP_USE, and USE_FROM_PTR.

◆ long_mul_high_half_uses()

bool long_mul_high_half_uses ( tree prod,
unsigned int narrow_prec,
vec< gimple * > * high_uses )
static
Collect into HIGH_USES the uses of PROD forming its high half,
`PROD >> NARROW_PREC'.  A use reading only the low NARROW_PREC bits is
accepted but not collected.  Returns false on any other use.   

References CONVERT_EXPR_CODE_P, FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), wi::min_precision(), wi::to_wide(), TREE_CODE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, and UNSIGNED.

Referenced by long_mul_only_low_half_used_p(), and narrow_long_mul_halves().

◆ long_mul_only_low_half_used_p()

bool long_mul_only_low_half_used_p ( tree prod,
unsigned int narrow_prec )
static
True when every use of PROD reads only its low NARROW_PREC bits.   

References long_mul_high_half_uses().

Referenced by narrow_long_mul_low_half().

◆ long_mul_op_fits_p()

bool long_mul_op_fits_p ( tree op,
unsigned narrow_prec,
bitmap phi_seen )
static
True when OP fits NARROW_PREC bits as an unsigned value.  Looks
through widening casts and PHIs, falling back to `tree_nonzero_bits'
otherwise.  PHI_SEEN guards against cycles.   

References bitmap_set_bit, CONVERT_EXPR_CODE_P, dyn_cast(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_phi_arg_def(), gimple_phi_num_args(), i, is_gimple_assign(), long_mul_op_fits_p(), wi::min_precision(), SSA_NAME_DEF_STMT, SSA_NAME_VERSION, TREE_CODE, tree_nonzero_bits(), TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, and UNSIGNED.

Referenced by long_mul_op_fits_p(), and long_mul_split_operand().

◆ long_mul_split_operand()

bool long_mul_split_operand ( gimple_seq * seq,
location_t loc,
tree op,
tree narrow_type,
tree * lo,
tree * hi )
static
Split the 2N-bit unsigned value OP into its low and high N bits (*LO and
*HI, both NARROW_TYPE) using only N-bit operations, as the target has no 2N
multiply or shift.  A 2N product recurses on its operands, its high half
coming from combine_long_mul_halves.  A value shifted down by N recurses on
the shifted value and takes its high half, rather than reading the 2N shift.
A widening cast's low half is the truncated source and its high half is what
the cast extended with, zero or the source's replicated sign bit.  A value
that provably fits N bits has a zero high half.  A PHI is split through its
arguments as a last resort.  Returns false otherwise.   

References build_int_cst(), build_zero_cst(), combine_long_mul_halves(), CONVERT_EXPR_CODE_P, dyn_cast(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build(), gimple_convert(), integer_type_node, INTEGRAL_TYPE_P, is_gimple_assign(), long_mul_op_fits_p(), long_mul_split_operand(), long_mul_split_phi(), signed_type_for(), SSA_NAME_DEF_STMT, TREE_CODE, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by long_mul_split_operand(), long_mul_split_phi(), lower_long_mul_high_chain(), and narrow_long_mul_halves().

◆ long_mul_split_phi()

bool long_mul_split_phi ( gphi * phi,
tree narrow_type,
tree * lo,
tree * hi )
static
Split the 2N-bit result of PHI into N-bit halves *LO and *HI, by splitting
each argument and merging the halves with two new PHIs.  A split goes at
the end of its argument's incoming block, where the argument is available,
rather than on the edge, which could split a critical edge while the
dominator walk is still running.  Returns false, having changed nothing,
when an argument cannot be split.  A split that succeeds stands even if
the caller then gives up.   

References add_phi_arg(), CDI_DOMINATORS, cfun, create_phi_node(), dominated_by_p(), dump_file, dump_flags, ENTRY_BLOCK_PTR_FOR_FN, gcc_checking_assert, gimple_bb(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_edge(), gimple_phi_num_args(), gimple_phi_result(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_insert_seq_after(), gsi_insert_seq_before(), gsi_last_bb(), GSI_SAME_STMT, gsi_stmt(), long_mul_arg_split::hi, i, long_mul_arg_split::lo, long_mul_phi_halves, long_mul_split_operand(), make_ssa_name(), long_mul_arg_split::seq, stmt_ends_bb_p(), TDF_DETAILS, TREE_TYPE, types_compatible_p(), and UNKNOWN_LOCATION.

Referenced by long_mul_split_operand().

◆ lower_long_mul_high_chain()

bool lower_long_mul_high_chain ( gimple_stmt_iterator * gsi)
static
Rewrite the `long_mul_high_chain' whose tail is the statement at GSI

  wide_a    = (T_2N) op1
  wide_b    = (T_2N) op2
  wide_prod = wide_a * wide_b
  hi        = wide_prod >> N
  lhs       = (convert) hi

to a longhand high-part synthesis at T_N precision.  Never materializes
T_2N in gimple, so it covers cases where the 2N mode has no expansion path
(e.g. the high 128 bits of a 128x128 product where 2N=OImode).  An operand
wider than T_N -- a shared wide product or a sign-extended cast -- is split
into T_N halves rather than truncated, so no high input bits are dropped.
Returns true on a rewrite.   

References build_nonstandard_integer_type(), can_mult_highpart_p(), combine_long_mul_halves(), dump_file, dump_flags, finish_long_mul_low_half(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_build_assign(), gimple_location(), gimple_long_mul_high_chain(), gimple_seq_add_stmt(), gimple_set_location(), gsi_for_stmt(), gsi_remove(), gsi_replace_with_seq(), gsi_stmt(), has_zero_uses(), is_a(), is_gimple_assign(), long_mul_split_operand(), NULL, release_defs(), SSA_NAME_DEF_STMT, TDF_DETAILS, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, and useless_type_conversion_p().

◆ make_pass_cse_reciprocals()

gimple_opt_pass * make_pass_cse_reciprocals ( gcc::context * ctxt)

◆ make_pass_cse_sincos()

gimple_opt_pass * make_pass_cse_sincos ( gcc::context * ctxt)

◆ make_pass_expand_pow()

gimple_opt_pass * make_pass_expand_pow ( gcc::context * ctxt)

◆ make_pass_optimize_widening_mul()

gimple_opt_pass * make_pass_optimize_widening_mul ( gcc::context * ctxt)

◆ match_arith_overflow()

bool match_arith_overflow ( gimple_stmt_iterator * gsi,
gimple * stmt,
enum tree_code code,
bool * cfg_changed )
static
Recognize for unsigned x
x = y - z;
if (x > y)
where there are other uses of x and replace it with
_7 = .SUB_OVERFLOW (y, z);
x = REALPART_EXPR <_7>;
_8 = IMAGPART_EXPR <_7>;
if (_8)
and similarly for addition.

Also recognize:
yc = (type) y;
zc = (type) z;
x = yc + zc;
if (x > max)
where y and z have unsigned types with maximum max
and there are other uses of x and all of those cast x
back to that unsigned type and again replace it with
_7 = .ADD_OVERFLOW (y, z);
_9 = REALPART_EXPR <_7>;
_8 = IMAGPART_EXPR <_7>;
if (_8)
and replace (utype) x with _9.
Or with x >> popcount (max) instead of x > max.

Also recognize:
x = ~z;
if (y > x)
and replace it with
_7 = .ADD_OVERFLOW (y, z);
_8 = IMAGPART_EXPR <_7>;
if (_8)

And also recognize:
z = x * y;
if (x != 0)
  goto <bb 3>; [50.00%]
else
  goto <bb 4>; [50.00%]

<bb 3> [local count: 536870913]:
_2 = z / x;
_9 = _2 != y;
_10 = (int) _9;

<bb 4> [local count: 1073741824]:
# iftmp.0_3 = PHI <_10(3), 0(2)>
and replace it with
_7 = .MUL_OVERFLOW (x, y);
z = IMAGPART_EXPR <_7>;
_8 = IMAGPART_EXPR <_7>;
_9 = _8 != 0;
iftmp.0_3 = (int) _9;   

References arith_overflow_check_p(), as_a(), boolean_type_node, build1(), build2(), build_complex_type(), build_int_cst(), can_mult_highpart_p(), cfg_changed, fold_convert, FOR_EACH_IMM_USE_FAST, FOR_EACH_IMM_USE_STMT, g, gcc_assert, gcc_checking_assert, GET_MODE_BITSIZE(), gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), gimple_assign_set_rhs_with_ops(), gimple_bb(), GIMPLE_BINARY_RHS, gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gsi_end_p(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), GSI_NEW_STMT, gsi_next_nondebug(), gsi_prev_nondebug(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), has_zero_uses(), i, INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), make_ssa_name(), wi::max_value(), maybe_optimize_guarding_check(), wi::ne_p(), NULL, NULL_TREE, operand_equal_p(), optab_handler(), release_ssa_name(), wi::rshift(), sc, SCALAR_INT_TYPE_MODE, single_imm_use(), SSA_NAME_DEF_STMT, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, wi::to_wide(), TREE_CODE, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, TYPE_UNSIGNED, UNSIGNED, update_stmt(), USE_STMT, useless_type_conversion_p(), and wide_int_to_tree().

◆ match_saturation_add()

◆ match_saturation_add_with_assign()

◆ match_saturation_mul()

bool match_saturation_mul ( gimple_stmt_iterator * gsi,
gphi * phi )
static
Try to match saturation unsigned mul, aka:
 _6 = .MUL_OVERFLOW (a_4(D), b_5(D));
 _2 = IMAGPART_EXPR <_6>;
 if (_2 != 0)
   goto <bb 4>; [35.00%]
 else
   goto <bb 3>; [65.00%]

 <bb 3> [local count: 697932184]:
 _1 = REALPART_EXPR <_6>;

 <bb 4> [local count: 1073741824]:
 # _3 = PHI <18446744073709551615(2), _1(3)>
 =>
 _3 = .SAT_MUL (a_4(D), b_5(D));   

References build_saturation_binary_arith_call_and_insert(), gimple_phi_num_args(), gimple_phi_result(), gimple_unsigned_integer_sat_mul(), and NULL.

◆ match_saturation_sub()

◆ match_saturation_trunc()

◆ match_single_bit_test()

◆ match_spaceship()

bool match_spaceship ( gimple_stmt_iterator * gsi,
gphi * phi )
static
Try to match variants of spaceship operation:
<bb 2>
if (a_3(D) >= b_4(D)) -- CMP_1
  goto <bb 3>;
else
  goto <bb 4>;

<bb 3>
_1 = a_3(D) > b_4(D); -- CMP_2
_5 = (int) _1;

<bb 4>
# _2 = PHI <-1(2), _5(3)>
=>
_2 = .SPACESHIP (a_3(D), b_4(D), -1);

All possible canonical variants of the comparison operator in CMP_1 and
CMP_2 has been included in gimple_spaceship function.   

References build_minus_one_cst(), build_one_cst(), FOR_EACH_WIDER_MODE_FROM, gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_convert(), gimple_phi_num_args(), gimple_phi_result(), gimple_spaceship(), gsi_insert_before(), GSI_SAME_STMT, integer_type_node, INTEGRAL_TYPE_P, make_ssa_name(), NULL, NULL_TREE, optab_handler(), TREE_TYPE, lang_hooks_for_types::type_for_mode, TYPE_MODE, TYPE_UNSIGNED, lang_hooks::types, types_compatible_p(), and UNKNOWN_LOCATION.

◆ match_uaddc_usubc()

bool match_uaddc_usubc ( gimple_stmt_iterator * gsi,
gimple * stmt,
tree_code code )
static
Try to match e.g.
_29 = .ADD_OVERFLOW (_3, _4);
_30 = REALPART_EXPR <_29>;
_31 = IMAGPART_EXPR <_29>;
_32 = .ADD_OVERFLOW (_30, _38);
_33 = REALPART_EXPR <_32>;
_34 = IMAGPART_EXPR <_32>;
_35 = _31 + _34;
as
_36 = .UADDC (_3, _4, _38);
_33 = REALPART_EXPR <_36>;
_35 = IMAGPART_EXPR <_36>;
or
_22 = .SUB_OVERFLOW (_6, _5);
_23 = REALPART_EXPR <_22>;
_24 = IMAGPART_EXPR <_22>;
_25 = .SUB_OVERFLOW (_23, _37);
_26 = REALPART_EXPR <_25>;
_27 = IMAGPART_EXPR <_25>;
_28 = _24 | _27;
as
_29 = .USUBC (_6, _5, _37);
_26 = REALPART_EXPR <_29>;
_288 = IMAGPART_EXPR <_29>;
provided _38 or _37 above have [0, 1] range
and _3, _4 and _30 or _6, _5 and _23 are unsigned
integral types with the same precision.  Whether + or | or ^ is
used on the IMAGPART_EXPR results doesn't matter, with one of
added or subtracted operands in [0, 1] range at most one
.ADD_OVERFLOW or .SUB_OVERFLOW will indicate overflow.   

References build1(), build_complex_type(), build_zero_cst(), const_unop(), fold_convert, FOR_EACH_IMM_USE_FAST, g, gcc_checking_assert, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_internal_fn(), gimple_call_internal_p(), gimple_call_lhs(), gimple_call_set_lhs(), gsi_for_stmt(), gsi_insert_before(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, has_single_use(), i, INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_call(), is_gimple_debug(), make_ssa_name(), NULL, NULL_TREE, num_imm_uses(), optab_handler(), r, release_defs(), SSA_NAME_DEF_STMT, TREE_CODE, TREE_OPERAND, TREE_TYPE, tree_zero_one_valued_p(), TYPE_MODE, TYPE_PRECISION, TYPE_UNSIGNED, types_compatible_p(), uaddc_cast(), uaddc_is_cplxpart(), uaddc_ne0(), and USE_STMT.

◆ match_unsigned_saturation_mul()

◆ match_unsigned_saturation_sub()

◆ match_unsigned_saturation_trunc()

◆ maybe_optimize_guarding_check()

void maybe_optimize_guarding_check ( vec< gimple * > & mul_stmts,
gimple * cond_stmt,
gimple * div_stmt,
bool * cfg_changed )
static
Helper function of match_arith_overflow.  For MUL_OVERFLOW, if we have
a check for non-zero like:
_1 = x_4(D) * y_5(D);
*res_7(D) = _1;
if (x_4(D) != 0)
  goto <bb 3>; [50.00%]
else
  goto <bb 4>; [50.00%]

<bb 3> [local count: 536870913]:
_2 = _1 / x_4(D);
_9 = _2 != y_5(D);
_10 = (int) _9;

<bb 4> [local count: 1073741824]:
# iftmp.0_3 = PHI <_10(3), 0(2)>
then in addition to using .MUL_OVERFLOW (x_4(D), y_5(D)) we can also
optimize the x_4(D) != 0 condition to 1.   

References as_a(), cfg_changed, EDGE_COUNT, EDGE_SUCC, FOR_EACH_VEC_ELT, g, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_bb(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_cond_rhs(), gimple_phi_arg_def(), gsi_after_labels(), gsi_end_p(), gsi_last_bb(), gsi_next(), gsi_next_nondebug(), gsi_start_phis(), gsi_stmt(), i, integer_onep(), integer_zerop(), INTEGRAL_TYPE_P, is_gimple_debug(), NULL, operand_equal_p(), reset_flow_sensitive_info_in_bb(), safe_dyn_cast(), single_pred_edge(), single_pred_p(), single_succ(), single_succ_edge(), single_succ_p(), SSA_NAME_DEF_STMT, basic_block_def::succs, TREE_CODE, TREE_TYPE, TYPE_PRECISION, and update_stmt().

Referenced by match_arith_overflow().

◆ maybe_record_sincos()

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

◆ narrow_long_mul_halves()

bool narrow_long_mul_halves ( gimple * stmt)
static
Rewrite the multiply STMT into the N-bit halves its uses read, when the
target can neither multiply at 2N bits nor form an N-bit high part.
Returns true on a rewrite, which may remove STMT.

Runs once lower_long_mul_high_chain has been applied to every statement:
both rewrite products with a high half, and this one, keyed on the
definition rather than on a consumer, would otherwise pre-empt it.  What
reaches it is a product that lowering could not retire, its high half also
read as an operand of another product, or read alongside the low half.  A
product read only for its low half is left to narrow_long_mul_low_half.   

References can_mult_highpart_p(), combine_long_mul_halves(), dump_file, dump_flags, finish_long_mul_low_half(), FOR_EACH_VEC_ELT, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_build_assign(), gimple_convert(), gimple_location(), gimple_set_location(), gsi_for_stmt(), gsi_insert_seq_before(), gsi_replace(), GSI_SAME_STMT, i, is_a(), long_mul_high_half_uses(), long_mul_split_operand(), NULL, TDF_DETAILS, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, and unexpandable_long_mul_p().

◆ narrow_long_mul_low_half()

bool narrow_long_mul_low_half ( gimple_stmt_iterator * gsi)
static
If the statement at *GSI is res = a * b with a 2N-bit unsigned result the
target cannot multiply and every use reads only the low N bits, narrow it
to res = (2N) ((N) a * (N) b) and return true.  The low N bits of a product
depend only on the low N bits of the operands, so this preserves every use;
the unused high half becomes zero.  match.pd's shorten rule omits this for
MULT_EXPR.   

References a, b, dump_file, dump_flags, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_build(), gimple_build_assign(), gimple_convert(), gimple_location(), gimple_set_location(), gsi_insert_seq_before(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), long_mul_only_low_half_used_p(), narrow_long_mul_operands(), NULL, TDF_DETAILS, TYPE_PRECISION, and unexpandable_long_mul_p().

Referenced by finish_long_mul_low_half(), and narrow_long_mul_operands().

◆ narrow_long_mul_operands()

void narrow_long_mul_operands ( tree op1,
tree op2 )
static
OP1 and OP2 are the operands of a 2N multiply just narrowed or lowered;
that rewrite now reads each through an N-bit low-half cast.  An operand
defined by another 2N multiply can thereby become low-half-only -- narrow
it too, recursing through chained wide products such as (a*b)*c.   

References gimple_assign_rhs_code(), gsi_for_stmt(), is_gimple_assign(), narrow_long_mul_low_half(), SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by finish_long_mul_low_half(), and narrow_long_mul_low_half().

◆ optimize_recip_sqrt()

void optimize_recip_sqrt ( gimple_stmt_iterator * def_gsi,
tree def )
static
Transform sequences like
t = sqrt (a)
x = 1.0 / t;
r1 = x * x;
r2 = a * x;
into:
t = sqrt (a)
r1 = 1.0 / a;
r2 = t;
x = r1 * r2;
depending on the uses of x, r1, r2.  This removes one multiplication and
allows the sqrt and division operations to execute in parallel.
DEF_GSI is the gsi of the initial division by sqrt that defines
DEF (x in the example above).   

References a, dconst1, dump_file, dyn_cast(), fold_stmt_inplace(), FOR_EACH_IMM_USE_STMT, FOR_EACH_VEC_ELT, gcc_assert, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_bb(), gimple_build_assign(), gimple_call_arg(), gimple_call_combined_fn(), gimple_call_lhs(), gsi_for_stmt(), gsi_insert_after(), gsi_insert_before(), GSI_NEW_STMT, gsi_remove(), GSI_SAME_STMT, gsi_stmt(), i, is_gimple_debug(), is_mult_by(), is_square_of(), make_temp_ssa_name(), NULL, NULL_TREE, print_gimple_stmt(), real_equal(), release_defs(), release_ssa_name(), SSA_NAME_DEF_STMT, TDF_NONE, TREE_CODE, TREE_REAL_CST, TREE_TYPE, and update_stmt().

◆ optimize_spaceship()

void optimize_spaceship ( gcond * stmt)
static
If target has spaceship<MODE>3 expander, pattern recognize
<bb 2> [local count: 1073741824]:
if (a_2(D) == b_3(D))
  goto <bb 6>; [34.00%]
else
  goto <bb 3>; [66.00%]

<bb 3> [local count: 708669601]:
if (a_2(D) < b_3(D))
  goto <bb 6>; [1.04%]
else
  goto <bb 4>; [98.96%]

<bb 4> [local count: 701299439]:
if (a_2(D) > b_3(D))
  goto <bb 5>; [48.89%]
else
  goto <bb 6>; [51.11%]

<bb 5> [local count: 342865295]:

<bb 6> [local count: 1073741824]:
and turn it into:
<bb 2> [local count: 1073741824]:
_1 = .SPACESHIP (a_2(D), b_3(D), 0);
if (_1 == 0)
  goto <bb 6>; [34.00%]
else
  goto <bb 3>; [66.00%]

<bb 3> [local count: 708669601]:
if (_1 == -1)
  goto <bb 6>; [1.04%]
else
  goto <bb 4>; [98.96%]

<bb 4> [local count: 701299439]:
if (_1 == 1)
  goto <bb 5>; [48.89%]
else
  goto <bb 6>; [51.11%]

<bb 5> [local count: 342865295]:

<bb 6> [local count: 1073741824]:
so that the backend can emit optimal comparison and
conditional jump sequence.  If the
<bb 6> [local count: 1073741824]:
above has a single PHI like:
# _27 = PHI<0(2), -1(3), -128(4), 1(5)>
then replace it with effectively
_1 = .SPACESHIP (a_2(D), b_3(D), -128);
_27 = _1;   

References a, as_a(), boolean_false_node, build_int_cst(), cond_only_block_p(), EDGE_COUNT, EDGE_SUCC, empty_block_p(), g, gcc_assert, gimple_bb(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_set_lhs(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gimple_phi_arg_def_from_edge(), gimple_phi_result(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_last_bb(), gsi_next(), GSI_SAME_STMT, gsi_start_phis(), HONOR_NANS(), i, integer_all_onesp(), integer_minus_one_node, integer_one_node, integer_onep(), integer_type_node, integer_zero_node, integer_zerop(), INTEGRAL_TYPE_P, make_ssa_name(), wi::minus_one(), NULL, wi::one(), operand_equal_p(), optab_handler(), basic_block_def::preds, safe_dyn_cast(), SCALAR_FLOAT_TYPE_P, SET_PHI_ARG_DEF_ON_EDGE, set_range_info(), wi::shwi(), SIGNED, signed_char_type_node, single_pred_p(), single_succ(), single_succ_edge(), single_succ_p(), wi::to_wide(), wi::to_widest(), TREE_CODE, tree_int_cst_sgn(), TREE_TYPE, TYPE_MAX_VALUE, TYPE_MIN_VALUE, TYPE_MODE, TYPE_PRECISION, TYPE_UNSIGNED, update_stmt(), useless_type_conversion_p(), and virtual_operand_p().

◆ optimize_widening_mul_active_p()

bool optimize_widening_mul_active_p ( void )
True when pass_optimize_widening_mul will run.  Shared with the
forwprop long-multiply recognizer so its wide-chain emit stays
paired with the lowering that rescues an unsupported 2N shape.
The -Og pipeline (pass_all_optimizations_g) does not contain
pass_optimize_widening_mul at all, so -Og -fexpensive-optimizations
must not enable the emit: the unlowered 2N multiply would reach
expand as an unexpandable mode (e.g. OImode) and ICE.
-fdisable-tree-widening_mul is not observed.   

Referenced by long_mul_classify_match().

◆ powi_as_mults()

tree powi_as_mults ( gimple_stmt_iterator * gsi,
location_t loc,
tree arg0,
HOST_WIDE_INT n )
Convert ARG0**N to a tree of multiplications of ARG0 with itself.
This function needs to be kept in sync with powi_cost above.   
Global, SSA-based optimizations using mathematical identities.
   Copyright (C) 2021-2026 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/>.   

References absu_hwi(), build_one_cst(), build_real(), cache, dconst1, gimple_build_assign(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, make_temp_ssa_name(), NULL, powi_as_mults_1(), POWI_TABLE_SIZE, and TREE_TYPE.

Referenced by attempt_builtin_powi(), and gimple_expand_builtin_powi().

◆ powi_as_mults_1()

tree powi_as_mults_1 ( gimple_stmt_iterator * gsi,
location_t loc,
tree type,
unsigned 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 cache, gimple_build_assign(), gimple_set_location(), gsi_insert_before(), GSI_SAME_STMT, make_temp_ssa_name(), NULL, powi_as_mults_1(), powi_table, POWI_TABLE_SIZE, and POWI_WINDOW_SIZE.

Referenced by powi_as_mults(), and powi_as_mults_1().

◆ powi_cost()

int powi_cost ( HOST_WIDE_INT n)
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 absu_hwi(), cache, powi_lookup_cost(), POWI_TABLE_SIZE, and POWI_WINDOW_SIZE.

Referenced by expand_pow_as_sqrts(), gimple_expand_builtin_pow(), and gimple_expand_builtin_powi().

◆ powi_lookup_cost()

int powi_lookup_cost ( unsigned HOST_WIDE_INT n,
bool * cache )
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 cache, powi_lookup_cost(), and powi_table.

Referenced by powi_cost(), and powi_lookup_cost().

◆ print_nested_fn()

void print_nested_fn ( FILE * stream,
const char * fname,
const char * arg,
unsigned int n )
static
Print to STREAM the repeated application of function FNAME to ARG
N times.  So, for FNAME = "foo", ARG = "x", N = 2 it would print:
"foo (foo (x))".   

References print_nested_fn().

Referenced by dump_fractional_sqrt_sequence(), and print_nested_fn().

◆ register_division_in()

void register_division_in ( basic_block bb,
int importance )
inlinestatic
Register that we found a division in BB.
IMPORTANCE is a measure of how much weighting to give
that division.  Use IMPORTANCE = 2 to register a single
division.  If the division is going to be found multiple
times use 1 (as it is with squares).   

References basic_block_def::aux, occurrence::bb, occurrence::bb_has_division, cfun, ENTRY_BLOCK_PTR_FOR_FN, insert_bb(), NULL, occurrence::num_divisions, occ_head, and occurrence::occurrence().

Referenced by execute_cse_reciprocals_1().

◆ replace_reciprocal()

void replace_reciprocal ( use_operand_p use_p)
inlinestatic

◆ replace_reciprocal_squares()

void replace_reciprocal_squares ( use_operand_p use_p)
inlinestatic

◆ representable_as_half_series_p()

bool representable_as_half_series_p ( REAL_VALUE_TYPE c,
unsigned n,
struct pow_synth_sqrt_info * info )
Return true iff the real value C can be represented as a
sum of powers of 0.5 up to N.  That is:
C == SUM<i from 1..N> (a[i]*(0.5**i)) where a[i] is either 0 or 1.
Record in INFO the various parameters of the synthesis algorithm such
as the factors a[i], the maximum 0.5 power and the number of
multiplications that will be required.   

References dconst0, dconsthalf, pow_synth_sqrt_info::deepest, pow_synth_sqrt_info::factors, i, pow_synth_sqrt_info::num_mults, real_arithmetic(), real_equal(), REAL_VALUE_NEGATIVE, and REAL_VALUE_TYPE.

Referenced by expand_pow_as_sqrts().

◆ result_of_phi()

gphi * result_of_phi ( tree op)
static
If OP is an SSA name defined by a PHI node, return the PHI statement.
Otherwise return NULL.   

References dyn_cast(), NULL, SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by convert_mult_to_fma().

◆ target_supports_divmod_p()

bool target_supports_divmod_p ( optab divmod_optab,
optab div_optab,
machine_mode mode )
static
Return true if target has support for divmod.   

References FOR_EACH_MODE_FROM, NULL, NULL_RTX, optab_handler(), optab_libfunc(), and targetm.

Referenced by divmod_candidate_p().

◆ uaddc_cast()

gimple * uaddc_cast ( gimple * g)
static
Helper of match_uaddc_usubc.  Look through an integral cast
which should preserve [0, 1] range value (unless source has
1-bit signed type) and the cast has single use.   

References g, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), has_single_use(), INTEGRAL_TYPE_P, SSA_NAME_DEF_STMT, TREE_CODE, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by match_uaddc_usubc().

◆ uaddc_is_cplxpart()

bool uaddc_is_cplxpart ( gimple * g,
tree_code part )
static
Return true if G is {REAL,IMAG}PART_EXPR PART with SSA_NAME
operand.   

References g, gimple_assign_rhs1(), gimple_assign_rhs_code(), is_gimple_assign(), TREE_CODE, and TREE_OPERAND.

Referenced by match_uaddc_usubc().

◆ uaddc_ne0()

gimple * uaddc_ne0 ( gimple * g)
static
Helper of match_uaddc_usubc.  Look through a NE_EXPR
comparison with 0 which also preserves [0, 1] value range.   

References g, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), has_single_use(), integer_zerop(), is_gimple_assign(), SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by match_uaddc_usubc().

◆ unexpandable_long_mul_p()

bool unexpandable_long_mul_p ( gimple * stmt,
tree * narrow_type )
static
True when STMT is res = a * b whose unsigned 2N-bit result is in a mode the
target cannot multiply, having neither insn nor libcall, so that expand_mult
would abort; set *NARROW_TYPE to the N-bit unsigned type its halves are
built at.  A mode the target does support is left to convert_mult_to_widen
and convert_mult_to_highpart.   

References build_nonstandard_integer_type(), gimple_assign_lhs(), gimple_assign_rhs_code(), INTEGRAL_TYPE_P, is_a(), is_gimple_assign(), targetm, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by narrow_long_mul_halves(), and narrow_long_mul_low_half().

◆ widening_mult_conversion_strippable_p()

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

References CONVERT_EXPR_CODE_P, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by is_widening_mult_rhs_p().

Variable Documentation

◆ conv_removed

int conv_removed

◆ divmod_calls_inserted

int divmod_calls_inserted

◆ fmas_inserted

int fmas_inserted

◆ highpart_mults_inserted

int highpart_mults_inserted

◆ inserted

◆ long_mul_phi_halves

hash_map<tree, long_mul_halves>* long_mul_phi_halves
static
Halves recorded for one run of the pass, keyed on the PHI they came from.
Several chains can reach one operand PHI, and each that splits it again
leaves another redundant pair of half PHIs behind.   

Referenced by long_mul_split_phi().

◆ maccs_inserted

int maccs_inserted

◆ occ_head

struct occurrence* occ_head
static
The instance of "struct occurrence" representing the highest
interesting block in the dominator tree.   

Referenced by execute_cse_reciprocals_1(), and register_division_in().

◆ occ_pool

object_allocator<occurrence>* occ_pool
static
Allocation pool for getting instances of "struct occurrence".   

Referenced by occurrence::operator delete(), and occurrence::operator new().

◆ powi_table

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

◆ []

struct { ... } reciprocal_stats

Referenced by insert_reciprocals().

◆ [struct]

struct { ... } sincos_stats

◆ [struct]

◆ widen_mults_inserted

int widen_mults_inserted