GCC Middle and Back End API Reference
tree-ssa-forwprop.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "expmed.h"
#include "optabs-query.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "expr.h"
#include "tree-dfa.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-dom.h"
#include "tree-ssa-strlen.h"
#include "builtins.h"
#include "tree-cfgcleanup.h"
#include "cfganal.h"
#include "optabs-tree.h"
#include "insn-config.h"
#include "recog.h"
#include "cfgloop.h"
#include "tree-vectorizer.h"
#include "tree-vector-builder.h"
#include "vec-perm-indices.h"
#include "internal-fn.h"
#include "cgraph.h"
#include "tree-ssa.h"
#include "gimple-range.h"
#include "tree-ssa-dce.h"
#include "tree-ssa-math-opts.h"
Include dependency graph for tree-ssa-forwprop.cc:

Data Structures

struct  _vec_perm_simplify_seq
struct  long_mul_row

Macros

#define CPD_ITERATIONS   5
#define CASE_ATOMIC(NAME, OTHER, OP)

Typedefs

typedef struct _vec_perm_simplify_seqvec_perm_simplify_seq

Functions

static bool forward_propagate_addr_expr (tree, tree, bool)
static tree rhs_to_tree (tree type, gimple *stmt)
static void fwprop_set_lattice_val (tree name, tree val)
static void fwprop_invalidate_lattice (tree name)
static gimpleget_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
static bool can_propagate_from (gimple *def_stmt)
static void remove_prop_source_from_use (tree name)
static tree combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type, tree op0, tree op1, bool invariant_only)
static tree forward_propagate_into_comparison_1 (gimple *stmt, enum tree_code code, tree type, tree op0, tree op1)
static bool forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
static int forward_propagate_into_gimple_cond (gcond *stmt)
static void tidy_after_forward_propagate_addr (gimple *stmt)
static bool forward_propagate_addr_expr_1 (tree name, tree def_rhs, gimple_stmt_iterator *use_stmt_gsi, bool single_use_p)
static void simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type, vec< std::pair< int, int > > &edges_to_remove)
static bool simplify_gimple_switch (gswitch *stmt, vec< std::pair< int, int > > &edges_to_remove, bitmap simple_dce_worklist)
static tree constant_pointer_difference (tree p1, tree p2)
static void optimize_aggr_zeroprop_1 (gimple *defstmt, gimple *stmt, tree dest, poly_int64 offset, tree val, poly_offset_int len)
static void optimize_aggr_zeroprop (gimple *stmt, bool full_walk)
static tree split_core_and_offset_size (tree expr, poly_int64 *pbytesize, poly_int64 *pbytepos, tree *poffset, int *preversep)
static tree new_src_based_on_copy (tree src2, tree dest, tree src)
static bool same_for_assignment (tree src, tree dest)
static void optimize_agr_copyprop_1 (gimple *stmt, gimple *use_stmt, tree dest, tree src)
static void optimize_agr_copyprop_arg (gimple *defstmt, gcall *call, tree dest, tree src)
static void optimize_agr_copyprop_return (gimple *defstmt, greturn *use, tree dest, tree src)
static void optimize_agr_copyprop (gimple *stmt)
static void do_simple_agr_dse (gassign *stmt, bool full_walk)
static bool simplify_builtin_memcmp (gimple_stmt_iterator *gsi_p, gcall *stmt)
static bool simplify_builtin_memchr (gimple_stmt_iterator *gsi_p, gcall *stmt)
static bool simplify_builtin_memcpy_memset (gimple_stmt_iterator *gsi_p, gcall *stmt2)
static bool optimize_stack_restore (gimple_stmt_iterator *gsi, gimple *call)
static bool optimize_strlen_comp (gimple_stmt_iterator *gsi, gimple *call)
static bool simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2, bool full_walk)
static void defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
static bool simplify_rotate (gimple_stmt_iterator *gsi)
template<typename ValidateFn>
static bool check_table_array (tree ctor, HOST_WIDE_INT &zero_val, unsigned bits, ValidateFn validate_fn)
template<typename ValidateFn>
static bool check_table_string (tree string, HOST_WIDE_INT &zero_val, unsigned bits, ValidateFn validate_fn)
template<typename ValidateFn>
static bool check_table (tree ctor, tree type, HOST_WIDE_INT &zero_val, unsigned bits, ValidateFn validate_fn)
bool gimple_ctz_table_index (tree, tree *, tree(*)(tree))
bool gimple_clz_table_index (tree, tree *, tree(*)(tree))
bool gimple_clz_msb_iso_table_index (tree, tree *, tree(*)(tree))
static bool simplify_count_zeroes (gimple_stmt_iterator *gsi)
bool gimple_cond_carry_add (tree, tree *, tree(*)(tree))
bool gimple_mul_hi (tree, tree *, tree(*)(tree))
bool gimple_mul_lo (tree, tree *, tree(*)(tree))
bool gimple_mul_hilo (tree, tree *, tree(*)(tree))
bool gimple_mul_lolo (tree, tree *, tree(*)(tree))
bool gimple_mul_hihi (tree, tree *, tree(*)(tree))
bool gimple_mul_cross_sum (tree, tree *, tree(*)(tree))
bool gimple_mul_low_sum (tree, tree *, tree(*)(tree))
bool gimple_mul_low_accum (tree, tree *, tree(*)(tree))
bool gimple_mul_carry_cross_sum (tree, tree *, tree(*)(tree))
bool gimple_mul_carry_low_sum (tree, tree *, tree(*)(tree))
bool gimple_mul_carry_low (tree, tree *, tree(*)(tree))
bool gimple_mul_ladder_sum1 (tree, tree *, tree(*)(tree))
bool gimple_mul_ladder_sum2 (tree, tree *, tree(*)(tree))
bool gimple_mul_ladder_sum3 (tree, tree *, tree(*)(tree))
bool gimple_mul_ladder_part_sum (tree, tree *, tree(*)(tree))
static void build_mul_high_seq (tree op1, tree op2, tree dest, location_t loc, gimple_seq *seq)
static void long_mul_apply_extras (tree acc, const vec< tree > &extras, tree_code outer, gassign *stmt, gimple_seq *seq)
static void create_mul_high_seq (tree op1, tree op2, gassign *stmt, const vec< tree > &extras, tree_code outer)
static void create_mul_low_seq (tree op1, tree op2, gassign *stmt, const vec< tree > &extras, tree_code outer)
static bool long_mul_linearize_chain (gimple *stmt, tree_code outer, vec< tree > &leaves, gimple **shared_def_out=NULL)
static bool long_mul_is_lshift_def (tree expr, tree *inner_out, unsigned HOST_WIDE_INT *shift_out)
static int long_mul_summand_compare (const void *a, const void *b)
static bool long_mul_same_ops (tree a, tree b, tree op0, tree op1)
static bool long_mul_is_cross_half (tree h, tree op0, tree op1)
static int long_mul_hilo_orientation (tree h, tree op0, tree op1)
static bool long_mul_canonical_ops (const vec< long_mul_summand > &summands, tree *op0_out, tree *op1_out)
static const long_mul_summand * long_mul_find_summand (const vec< long_mul_summand > &summands, long_mul_kind kind)
static bool long_mul_check_consistency (const vec< long_mul_summand > &summands, tree *op0_out, tree *op1_out)
static bool long_mul_signature_matches (const vec< long_mul_summand > &summands, const long_mul_row &row)
static bool long_mul_check_two_carries (const vec< long_mul_summand > &summands, gimple *)
static bool long_mul_check_low_plus_defer (const vec< long_mul_summand > &, gimple *stmt)
static void long_mul_hint_shared_intermediate (gimple *shared_def)
static const long_mul_rowlong_mul_classify_match (const vec< long_mul_summand > &summands, tree lhs_type, tree_code outer, gimple *candidate_stmt, tree *out_op0, tree *out_op1)
static const long_mul_rowlong_mul_classify_chain (gimple *stmt, tree_code outer, tree lhs_type, gimple *candidate, const long_mul_summand *extra, vec< tree > *extras_out, tree *out_op0, tree *out_op1)
static bool match_long_mul (gassign *stmt)
static bool match_long_mul_phi (gphi *phi)
static bool simplify_phi_result_movdiv (gimple *stmt, tree_code code)
static int is_combined_permutation_identity (tree mask1, tree mask2)
static bool simplify_permutation (gimple_stmt_iterator *gsi)
static tree get_bit_field_ref_def (tree val, enum tree_code &conv_code)
static bool simplify_vector_constructor (gimple_stmt_iterator *gsi)
static tree prepare_target_mem_ref_lvalue (tree ref, gimple_stmt_iterator *gsi)
static void optimize_vector_load (gimple_stmt_iterator *gsi)
static tree fwprop_ssa_val (tree name)
static bool recognise_vec_perm_simplify_seq (gassign *stmt, vec_perm_simplify_seq *seq)
static void narrow_vec_perm_simplify_seq (const vec_perm_simplify_seq &seq)
static bool can_blend_vec_perm_simplify_seqs_p (vec_perm_simplify_seq seq1, vec_perm_simplify_seq seq2, bool *need_swap)
static bool calc_perm_vec_perm_simplify_seqs (vec_perm_simplify_seq seq1, vec_perm_simplify_seq seq2, vec_perm_indices *seq2_stmt_indices, vec_perm_indices *seq1_v_1_stmt_indices, vec_perm_indices *seq1_v_2_stmt_indices)
static void blend_vec_perm_simplify_seqs (vec_perm_simplify_seq seq1, vec_perm_simplify_seq seq2, const vec_perm_indices &seq2_stmt_indices, const vec_perm_indices &seq1_v_1_stmt_indices, const vec_perm_indices &seq1_v_2_stmt_indices)
static void process_vec_perm_simplify_seq_list (vec< vec_perm_simplify_seq > *l)
static void append_vec_perm_simplify_seq_list (vec< vec_perm_simplify_seq > *l, const vec_perm_simplify_seq &seq)
gimple_opt_passmake_pass_forwprop (gcc::context *ctxt)

Variables

static bool cfg_changed
static bitmap to_purge
static vec< treelattice
static constexpr unsigned LONG_MUL_MAX_CAPTURES = 8
static constexpr unsigned LONG_MUL_MAX_SUMMANDS = 4
static constexpr unsigned LONG_MUL_MAX_EXTRAS = 4
static const long_mul_row long_mul_table []

Macro Definition Documentation

◆ CASE_ATOMIC

#define CASE_ATOMIC ( NAME,
OTHER,
OP )
Value:
case BUILT_IN_##NAME##_1: \
case BUILT_IN_##NAME##_2: \
case BUILT_IN_##NAME##_4: \
case BUILT_IN_##NAME##_8: \
case BUILT_IN_##NAME##_16: \
atomic_op = OP; \
other_atomic \
= (enum built_in_function) (BUILT_IN_##OTHER##_1 \
+ (DECL_FUNCTION_CODE (callee2) \
- BUILT_IN_##NAME##_1)); \
goto handle_atomic_fetch_op;
built_in_function
Definition genmatch.cc:1018
@ NAME
Definition tree-ssa-pre.cc:241
built_in_function DECL_FUNCTION_CODE(const_tree decl)
Definition tree.h:4525

◆ CPD_ITERATIONS

#define CPD_ITERATIONS   5

Typedef Documentation

◆ vec_perm_simplify_seq

Function Documentation

◆ append_vec_perm_simplify_seq_list()

void append_vec_perm_simplify_seq_list ( vec< vec_perm_simplify_seq > * l,
const vec_perm_simplify_seq & seq )
static

◆ blend_vec_perm_simplify_seqs()

◆ build_mul_high_seq()

void build_mul_high_seq ( tree op1,
tree op2,
tree dest,
location_t loc,
gimple_seq * seq )
static
Append to SEQ statements assigning DEST the high-part multiply of
OP1 and OP2, emitted as
  (N)(((2N) op1 * (2N) op2) >> N).
pass_optimize_widening_mul's convert_mult_to_widen and
convert_mult_to_highpart later rewrite this to a single
WIDEN_MULT_EXPR or MULT_HIGHPART_EXPR when the target supports it,
otherwise the 2N multiply expands directly.  Emitting the canonical
widening shape keeps target-capability decisions in the layer that
already owns them.   

References build_int_cst(), build_mul_high_seq(), build_nonstandard_integer_type(), gimple_build(), gimple_build_assign(), gimple_convert(), gimple_seq_add_stmt(), gimple_set_location(), integer_type_node, TREE_TYPE, and TYPE_PRECISION.

Referenced by build_mul_high_seq(), create_mul_high_seq(), and match_long_mul_phi().

◆ calc_perm_vec_perm_simplify_seqs()

bool calc_perm_vec_perm_simplify_seqs ( vec_perm_simplify_seq seq1,
vec_perm_simplify_seq seq2,
vec_perm_indices * seq2_stmt_indices,
vec_perm_indices * seq1_v_1_stmt_indices,
vec_perm_indices * seq1_v_2_stmt_indices )
static

◆ can_blend_vec_perm_simplify_seqs_p()

◆ can_propagate_from()

◆ check_table()

template<typename ValidateFn>
bool check_table ( tree ctor,
tree type,
HOST_WIDE_INT & zero_val,
unsigned bits,
ValidateFn validate_fn )
static
Check whether CTOR contains a valid table according to VALIDATE_FN.   

References CHAR_TYPE_SIZE, check_table(), check_table_array(), check_table_string(), TREE_CODE, and TYPE_PRECISION.

Referenced by check_table(), and simplify_count_zeroes().

◆ check_table_array()

template<typename ValidateFn>
bool check_table_array ( tree ctor,
HOST_WIDE_INT & zero_val,
unsigned bits,
ValidateFn validate_fn )
static

◆ check_table_string()

template<typename ValidateFn>
bool check_table_string ( tree string,
HOST_WIDE_INT & zero_val,
unsigned bits,
ValidateFn validate_fn )
static
Check whether a string contains a valid table according to VALIDATE_FN.   

References check_table_string(), i, TREE_STRING_LENGTH, and TREE_STRING_POINTER.

Referenced by check_table(), and check_table_string().

◆ combine_cond_expr_cond()

tree combine_cond_expr_cond ( gimple * stmt,
enum tree_code code,
tree type,
tree op0,
tree op1,
bool invariant_only )
static
Combine OP0 CODE OP1 in the context of a COND_EXPR.  Returns
the folded result in a form suitable for COND_EXPR_COND or
NULL_TREE, if there is no suitable simplified form.  If
INVARIANT_ONLY is true only gimple_min_invariant results are
considered simplified.   

References canonicalize_cond_expr_cond(), combine_cond_expr_cond(), fold_binary_loc(), gcc_assert, gimple_location(), is_gimple_min_invariant(), NULL_TREE, _vec_perm_simplify_seq::stmt, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, and TREE_TYPE.

Referenced by combine_cond_expr_cond(), and forward_propagate_into_comparison_1().

◆ constant_pointer_difference()

◆ create_mul_high_seq()

void create_mul_high_seq ( tree op1,
tree op2,
gassign * stmt,
const vec< tree > & extras,
tree_code outer )
static
Replace STMT with a high-part multiply of OP1 and OP2, combining any
EXTRAS back on top under OUTER.   

References build_mul_high_seq(), create_mul_high_seq(), gimple_assign_lhs(), gimple_location(), gsi_for_stmt(), gsi_replace_with_seq(), long_mul_apply_extras(), make_ssa_name(), NULL, _vec_perm_simplify_seq::stmt, and TREE_TYPE.

Referenced by create_mul_high_seq(), and match_long_mul().

◆ create_mul_low_seq()

void create_mul_low_seq ( tree op1,
tree op2,
gassign * stmt,
const vec< tree > & extras,
tree_code outer )
static

◆ defcodefor_name()

void defcodefor_name ( tree name,
enum tree_code * code,
tree * arg1,
tree * arg2 )
inlinestatic
Given a ssa_name in NAME see if it was defined by an assignment and
set CODE to be the code and ARG1 to the first operand on the rhs and ARG2
to the second operand on the rhs.  

References can_propagate_from(), defcodefor_name(), get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), GIMPLE_SINGLE_RHS, is_gimple_assign(), NULL_TREE, SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by defcodefor_name(), and simplify_rotate().

◆ do_simple_agr_dse()

void do_simple_agr_dse ( gassign * stmt,
bool full_walk )
static
Simple DSE of the lhs from a clobber STMT.
This is used mostly to clean up from optimize_agr_copyprop and
to remove (exactly one) extra copy that might later on confuse SRA.
An example is:
;; write to a and such.
b = a; // This statement is to be removed
b = {CLOBBER};
SRA will totally scalarize b (which means also a) here for the extra copy
which is not something welcomed. So removing the copy will
allow SRA to move the scalarization of a further down or not at all.

References ao_ref_init(), as_a(), bitmap_set_bit, CDI_DOMINATORS, cfun, DECL_P, do_simple_agr_dse(), dominated_by_p(), dump_file, dump_flags, dyn_cast(), ECF_CONST, ECF_LOOPING_CONST_OR_PURE, ECF_NOVOPS, ECF_PURE, FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_bb(), gimple_call_flags(), gimple_call_fntype(), gimple_call_lhs(), gimple_call_return_slot_opt_p(), gimple_call_set_lhs(), gimple_clobber_p(), gimple_nop_p(), gimple_phi_result(), gimple_store_p(), gimple_vdef(), gimple_vuse(), gsi_for_stmt(), gsi_remove(), basic_block_def::index, is_a(), NULL_TREE, poly_int_tree_p(), print_gimple_stmt(), ref_maybe_used_by_stmt_p(), release_defs(), single_imm_use(), SSA_NAME_DEF_STMT, statistics_counter_event(), _vec_perm_simplify_seq::stmt, stmt_could_throw_p(), stmt_may_clobber_ref_p_1(), stmt_unremovable_because_of_non_call_eh_p(), TDF_DETAILS, to_purge, TREE_ADDRESSABLE, TREE_TYPE, TYPE_SIZE, unlink_stmt_vdef(), and update_stmt().

Referenced by do_simple_agr_dse().

◆ forward_propagate_addr_expr()

bool forward_propagate_addr_expr ( tree name,
tree rhs,
bool parent_single_use_p )
static
STMT is a statement of the form SSA_NAME = ADDR_EXPR <whatever>.

Try to forward propagate the ADDR_EXPR into all uses of the SSA_NAME.
Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF
node or for recovery of array indexing from pointer arithmetic.

PARENT_SINGLE_USE_P tells if, when in a recursive invocation, NAME was
the single use in the previous invocation.  Pass true when calling
this as toplevel.

Returns true, if all uses have been propagated into.   

References forward_propagate_addr_expr(), forward_propagate_addr_expr_1(), fwprop_invalidate_lattice(), gather_imm_use_stmts(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_get_lhs(), gsi_for_stmt(), gsi_remove(), gsi_stmt(), has_single_use(), has_zero_uses(), is_gimple_assign(), is_gimple_debug(), release_defs(), TREE_CODE, and update_stmt().

Referenced by forward_propagate_addr_expr(), and forward_propagate_addr_expr_1().

◆ forward_propagate_addr_expr_1()

bool forward_propagate_addr_expr_1 ( tree name,
tree def_rhs,
gimple_stmt_iterator * use_stmt_gsi,
bool single_use_p )
static

◆ forward_propagate_into_comparison()

bool forward_propagate_into_comparison ( gimple_stmt_iterator * gsi)
static

◆ forward_propagate_into_comparison_1()

tree forward_propagate_into_comparison_1 ( gimple * stmt,
enum tree_code code,
tree type,
tree op0,
tree op1 )
static

◆ forward_propagate_into_gimple_cond()

int forward_propagate_into_gimple_cond ( gcond * stmt)
static

◆ fwprop_invalidate_lattice()

void fwprop_invalidate_lattice ( tree name)
static

◆ fwprop_set_lattice_val()

void fwprop_set_lattice_val ( tree name,
tree val )
static

◆ fwprop_ssa_val()

tree fwprop_ssa_val ( tree name)
static
Primitive "lattice" function for gimple_simplify.   

References fwprop_ssa_val(), lattice, SSA_NAME_VERSION, and TREE_CODE.

Referenced by fwprop_ssa_val().

◆ get_bit_field_ref_def()

tree get_bit_field_ref_def ( tree val,
enum tree_code & conv_code )
static
Get the BIT_FIELD_REF definition of VAL, if any, looking through
conversions with code CONV_CODE or update it if still ERROR_MARK.
Return NULL_TREE if no such matching def was found.   

References CONVERT_EXPR_CODE_P, get_bit_field_ref_def(), get_prop_source_stmt(), gimple_assign_rhs1(), gimple_assign_rhs_code(), is_gimple_assign(), NULL, NULL_TREE, SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by get_bit_field_ref_def(), and simplify_vector_constructor().

◆ get_prop_source_stmt()

gimple * get_prop_source_stmt ( tree name,
bool single_use_only,
bool * single_use_p )
static
Get the statement we can propagate from into NAME skipping
trivial copies.  Returns the statement which defines the
propagation source or NULL_TREE if there is no such one.
If SINGLE_USE_ONLY is set considers only sources which have
a single use chain up to NAME.  If SINGLE_USE_P is non-null,
it is set to whether the chain to NAME is a single use chain
or not.  SINGLE_USE_P is not written to if SINGLE_USE_ONLY is set.   

References get_prop_source_stmt(), gimple_assign_rhs1(), gimple_assign_rhs_code(), has_single_use(), is_gimple_assign(), NULL, and SSA_NAME_DEF_STMT.

Referenced by forward_propagate_into_comparison_1(), get_bit_field_ref_def(), get_prop_source_stmt(), and simplify_permutation().

◆ gimple_clz_msb_iso_table_index()

bool gimple_clz_msb_iso_table_index ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_clz_table_index()

bool gimple_clz_table_index ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_cond_carry_add()

bool gimple_cond_carry_add ( tree ,
tree * ,
tree(*  )(tree) )
extern
Long-multiply fold framework.

Walks the outer addition or bit_ior chain on a candidate statement,
classifies each summand against the atom match patterns from
match.pd, and looks the resulting multiset of (kind, extract) tuples
up in a table.  On a hit, three cross-summand consistency checks
decide whether the wide multiply is emitted.   
Match.pd recognizers for the conditional carry-add pattern.  

References gimple_cond_carry_add().

Referenced by gimple_cond_carry_add(), and match_long_mul_phi().

◆ gimple_ctz_table_index()

bool gimple_ctz_table_index ( tree ,
tree * ,
tree(*  )(tree) )
extern
Match.pd function to match the ctz expression.   

References gimple_ctz_table_index().

Referenced by gimple_ctz_table_index(), and simplify_count_zeroes().

◆ gimple_mul_carry_cross_sum()

bool gimple_mul_carry_cross_sum ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_carry_low()

bool gimple_mul_carry_low ( tree ,
tree * ,
tree(*  )(tree) )
extern

References gimple_mul_carry_low().

Referenced by gimple_mul_carry_low().

◆ gimple_mul_carry_low_sum()

bool gimple_mul_carry_low_sum ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_cross_sum()

bool gimple_mul_cross_sum ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_hi()

bool gimple_mul_hi ( tree ,
tree * ,
tree(*  )(tree) )
extern
Match.pd functions to match long multiplication.   

References gimple_mul_hi().

Referenced by gimple_mul_hi().

◆ gimple_mul_hihi()

bool gimple_mul_hihi ( tree ,
tree * ,
tree(*  )(tree) )
extern

References gimple_mul_hihi().

Referenced by gimple_mul_hihi().

◆ gimple_mul_hilo()

bool gimple_mul_hilo ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_ladder_part_sum()

bool gimple_mul_ladder_part_sum ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_ladder_sum1()

bool gimple_mul_ladder_sum1 ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_ladder_sum2()

bool gimple_mul_ladder_sum2 ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_ladder_sum3()

bool gimple_mul_ladder_sum3 ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_lo()

bool gimple_mul_lo ( tree ,
tree * ,
tree(*  )(tree) )
extern

References gimple_mul_lo().

Referenced by gimple_mul_lo().

◆ gimple_mul_lolo()

bool gimple_mul_lolo ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ gimple_mul_low_accum()

bool gimple_mul_low_accum ( tree ,
tree * ,
tree(*  )(tree) )
extern

References gimple_mul_low_accum().

Referenced by gimple_mul_low_accum().

◆ gimple_mul_low_sum()

bool gimple_mul_low_sum ( tree ,
tree * ,
tree(*  )(tree) )
extern

◆ is_combined_permutation_identity()

int is_combined_permutation_identity ( tree mask1,
tree mask2 )
static

◆ long_mul_apply_extras()

void long_mul_apply_extras ( tree acc,
const vec< tree > & extras,
tree_code outer,
gassign * stmt,
gimple_seq * seq )
static
Append to SEQ statements combining ACC with each of EXTRAS under
OUTER, the last one assigning to STMT's lhs.  EXTRAS are leaves of
STMT's own chain, so any combining order is valid.   

References gimple_assign_lhs(), gimple_build(), gimple_build_assign(), gimple_location(), gimple_seq_add_stmt(), gimple_set_location(), i, long_mul_apply_extras(), _vec_perm_simplify_seq::stmt, and TREE_TYPE.

Referenced by create_mul_high_seq(), create_mul_low_seq(), and long_mul_apply_extras().

◆ long_mul_canonical_ops()

bool long_mul_canonical_ops ( const vec< long_mul_summand > & summands,
tree * op0_out,
tree * op1_out )
static
Find the first summand that carries operand captures, and return its
(op0, op1) pair in *OP0_OUT / *OP1_OUT.  Returns false if no summand
provides them.   

References long_mul_canonical_ops().

Referenced by long_mul_canonical_ops(), long_mul_check_consistency(), and long_mul_check_two_carries().

◆ long_mul_check_consistency()

bool long_mul_check_consistency ( const vec< long_mul_summand > & summands,
tree * op0_out,
tree * op1_out )
static
Run the cross-summand validation invariants and return the canonical
(op0, op1).  Returns false unless all summands that carry operands use
the same (op0, op1) pair (in either order), every LMX_HI/LMX_SHL_N shift
equals halfwidth, every captured hilo is a true cross-half product of
(op0, op1), and every cross-half pair (both those inside a single
mul_cross_sum-bearing summand and those spread across separate
LMK_MUL_HILO summands) contains one of each orientation.   

References a, b, INTEGRAL_TYPE_P, long_mul_canonical_ops(), long_mul_check_consistency(), long_mul_hilo_orientation(), long_mul_is_cross_half(), long_mul_same_ops(), NULL_TREE, TREE_TYPE, and TYPE_PRECISION.

Referenced by long_mul_check_consistency(), and long_mul_classify_match().

◆ long_mul_check_low_plus_defer()

bool long_mul_check_low_plus_defer ( const vec< long_mul_summand > & ,
gimple * stmt )
static
The lolo + cross_shifted shape is also the low half of a two-carry
long-multiply, where an unsigned overflow compare against one of
the PLUS operands is the low-carry term consumed by the matching
high-part fold.  Folding to mul_lo here destroys cross_shifted,
which both the compare and the high-part match still need; defer
so the high-part fold runs first.  After it does, the compare is
dead and the surviving lolo + cross_shifted is picked up by this
row in the next forwprop instance.  Returns false to defer.   

References dyn_cast(), FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), is_gimple_assign(), long_mul_check_low_plus_defer(), and NULL_TREE.

Referenced by long_mul_check_low_plus_defer().

◆ long_mul_check_two_carries()

bool long_mul_check_two_carries ( const vec< long_mul_summand > & summands,
gimple *  )
static
Extra check for the two-carries high-part row: the LMK_CARRY_LOW summand's
two operands (carry_a, carry_b) must be a (cross_shifted, mul_lolo) pair
consistent with the multiset's canonical (op0, op1).   

References gimple_mul_cross_sum(), gimple_mul_lolo(), i, long_mul_canonical_ops(), long_mul_check_two_carries(), long_mul_find_summand(), long_mul_is_cross_half(), long_mul_is_lshift_def(), LONG_MUL_MAX_CAPTURES, long_mul_same_ops(), NULL, TREE_TYPE, and TYPE_PRECISION.

Referenced by long_mul_check_two_carries().

◆ long_mul_classify_chain()

const long_mul_row * long_mul_classify_chain ( gimple * stmt,
tree_code outer,
tree lhs_type,
gimple * candidate,
const long_mul_summand * extra,
vec< tree > * extras_out,
tree * out_op0,
tree * out_op1 )
static
Walk STMT's outer chain (kind OUTER), classify each leaf as a
long-multiply summand, optionally add the already-classified EXTRA,
and look the multiset up in long_mul_table for a result of type
LHS_TYPE.  CANDIDATE is passed to per-row extra_check predicates.

If EXTRAS_OUT is non-NULL, leaves matching no summand are set aside
there instead of failing the match, and the caller must re-apply
them on top of the folded multiply.  A leaf that does match is
always consumed: if that makes the signature miss every row the
match fails, rather than retrying with the leaf demoted to an extra
(subset search would be exponential).

Returns the matched row and the half-width operands via
OUT_OP0/OUT_OP1, or NULL on a miss.  No IR mutation.   

References gcc_checking_assert, long_mul_classify_chain(), long_mul_classify_match(), long_mul_hint_shared_intermediate(), long_mul_linearize_chain(), LONG_MUL_MAX_EXTRAS, LONG_MUL_MAX_SUMMANDS, long_mul_summand_compare(), and NULL.

Referenced by long_mul_classify_chain(), match_long_mul(), and match_long_mul_phi().

◆ long_mul_classify_match()

const long_mul_row * long_mul_classify_match ( const vec< long_mul_summand > & summands,
tree lhs_type,
tree_code outer,
gimple * candidate_stmt,
tree * out_op0,
tree * out_op1 )
static
Search long_mul_table for a row whose multiset matches SUMMANDS for
outer kind OUTER on a result of type LHS_TYPE.  CANDIDATE_STMT is
passed to per-row extra_check predicates.  On a hit, returns the
matching row and writes the half-width operands via OUT_OP0/OUT_OP1.
No IR mutation.   

References GET_MODE_2XWIDER_MODE(), long_mul_row::HIGH_PART, is_a(), long_mul_check_consistency(), long_mul_classify_match(), long_mul_signature_matches(), long_mul_table, NULL, optimize_widening_mul_active_p(), SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, and TYPE_MODE.

Referenced by long_mul_classify_chain(), and long_mul_classify_match().

◆ long_mul_find_summand()

const long_mul_summand * long_mul_find_summand ( const vec< long_mul_summand > & summands,
long_mul_kind kind )
static
Return the first summand in SUMMANDS whose kind matches KIND, or NULL.   

References gcc_checking_assert, long_mul_find_summand(), and NULL.

Referenced by long_mul_check_two_carries(), and long_mul_find_summand().

◆ long_mul_hilo_orientation()

int long_mul_hilo_orientation ( tree h,
tree op0,
tree op1 )
static
Orientation of the mul_hilo capture H relative to (OP0, OP1):
returns 0 for high(OP0)*low(OP1), 1 for high(OP1)*low(OP0), or -1
if H does not decompose that way.  A cross-sum of two mul_hilos must
see one of each orientation -- otherwise a doubled factor would fold
to the wrong value.  (In a self-multiply the two orientations
coincide; see the OP0 == OP1 bypass in long_mul_check_consistency.)   

References gimple_mul_hilo(), long_mul_hilo_orientation(), LONG_MUL_MAX_CAPTURES, and NULL.

Referenced by long_mul_check_consistency(), and long_mul_hilo_orientation().

◆ long_mul_hint_shared_intermediate()

void long_mul_hint_shared_intermediate ( gimple * shared_def)
static
If a multi-used inner addition (sharing the chain's outer code) blocked
linearization of a long-mul candidate, emit a dump-file hint pointing
at it.   

References dump_file, dump_flags, long_mul_hint_shared_intermediate(), print_gimple_stmt(), TDF_DETAILS, and TDF_SLIM.

Referenced by long_mul_classify_chain(), and long_mul_hint_shared_intermediate().

◆ long_mul_is_cross_half()

bool long_mul_is_cross_half ( tree h,
tree op0,
tree op1 )
static
True if H is a cross-half product of (OP0, OP1) -- gimple_mul_hilo
recognizes it and its captured operands match the pair.   

References gimple_mul_hilo(), long_mul_is_cross_half(), LONG_MUL_MAX_CAPTURES, long_mul_same_ops(), and NULL.

Referenced by long_mul_check_consistency(), long_mul_check_two_carries(), and long_mul_is_cross_half().

◆ long_mul_is_lshift_def()

bool long_mul_is_lshift_def ( tree expr,
tree * inner_out,
unsigned HOST_WIDE_INT * shift_out )
static
If EXPR is defined by LSHIFT_EXPR with a uhwi-valued amount, return
the shifted input via *INNER_OUT and the amount via *SHIFT_OUT.   

References gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), is_gimple_assign(), long_mul_is_lshift_def(), SSA_NAME_DEF_STMT, TREE_CODE, tree_fits_uhwi_p(), and tree_to_uhwi().

Referenced by long_mul_check_two_carries(), and long_mul_is_lshift_def().

◆ long_mul_linearize_chain()

bool long_mul_linearize_chain ( gimple * stmt,
tree_code outer,
vec< tree > & leaves,
gimple ** shared_def_out = NULL )
static
Walk the OUTER addition or BIT_IOR chain rooted at STMT and collect
the leaf operands into LEAVES.  Descends through single-use
intermediate stmts of the same code.  Returns false once the leaf
count exceeds LONG_MUL_MAX_SUMMANDS + LONG_MUL_MAX_EXTRAS, so an
overlong chain bails mid-walk instead of after a full traversal.

If SHARED_DEF_OUT is non-NULL, record there the first inner stmt that
shares the outer code but has more than one use -- descending into it
would change semantics, so it stays as a leaf.  Such a leaf often
classifies as something no row matches, silently disabling the fold;
the caller surfaces this as a dump-file hint.   

References gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), has_single_use(), is_gimple_assign(), long_mul_linearize_chain(), LONG_MUL_MAX_EXTRAS, LONG_MUL_MAX_SUMMANDS, NULL, SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by long_mul_classify_chain(), and long_mul_linearize_chain().

◆ long_mul_same_ops()

bool long_mul_same_ops ( tree a,
tree b,
tree op0,
tree op1 )
inlinestatic
True if (A, B) is the same pair as (OP0, OP1) in either order.   

References a, b, and long_mul_same_ops().

Referenced by long_mul_check_consistency(), long_mul_check_two_carries(), long_mul_is_cross_half(), and long_mul_same_ops().

◆ long_mul_signature_matches()

bool long_mul_signature_matches ( const vec< long_mul_summand > & summands,
const long_mul_row & row )
static
Compare the (already-sorted) SUMMANDS multiset against ROW.sig.   

References long_mul_row::count, i, long_mul_signature_matches(), and long_mul_row::sig.

Referenced by long_mul_classify_match(), and long_mul_signature_matches().

◆ long_mul_summand_compare()

int long_mul_summand_compare ( const void * a,
const void * b )
static
qsort comparator: sort summands by (kind, extract) to put a multiset
into canonical order for table lookup.  Unstable sort within a tie is
harmless: no row in long_mul_table pairs distinct subterms under the
same (kind, extract), and long_mul_check_consistency cross-validates
that matching summands share one canonical (op0, op1).   

References a, b, gcc_checking_assert, and long_mul_summand_compare().

Referenced by long_mul_classify_chain(), and long_mul_summand_compare().

◆ make_pass_forwprop()

gimple_opt_pass * make_pass_forwprop ( gcc::context * ctxt)

◆ match_long_mul()

bool match_long_mul ( gassign * stmt)
static
Top-level entry for long-multiply folding.  Walks STMT's outer
addition or BIT_IOR chain, classifies the summands, and dispatches
to create_mul_high_seq / create_mul_low_seq if the multiset matches
a known long-multiply form.  Returns true on success.   

References create_mul_high_seq(), create_mul_low_seq(), dump_file, dump_flags, gimple_assign_lhs(), gimple_assign_rhs_code(), gimple_bb(), long_mul_row::HIGH_PART, INTEGRAL_TYPE_P, is_gimple_assign(), long_mul_classify_chain(), match_long_mul(), NULL, long_mul_row::part, single_imm_use(), TDF_DETAILS, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by match_long_mul().

◆ match_long_mul_phi()

bool match_long_mul_phi ( gphi * phi)
static
PHI-driven entry for long-multiply folding.  When PHI's value
flattens to base + (carry << N), probe sum to classify the carry
kind, linearize base for the remaining high-part summands, and run
the long-multiply table.  On a hit, emit a 2N-bit multiply at the
top of the join block with PHI_RES as its LHS and remove the PHI.
Otherwise leave the IR untouched.  Only HIGH_PART rows are
reachable.  LOW_PART rows are BIT_IOR-shaped and never produce a
carry PHI.   

References build_mul_high_seq(), dump_file, dump_flags, wi::exact_log2(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_cond_carry_add(), gimple_location(), gimple_mul_cross_sum(), gimple_mul_low_sum(), gimple_phi_result(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_seq_before(), GSI_SAME_STMT, long_mul_row::HIGH_PART, INTEGRAL_TYPE_P, is_gimple_assign(), long_mul_classify_chain(), LONG_MUL_MAX_CAPTURES, match_long_mul_phi(), NULL, long_mul_row::part, remove_phi_node(), SSA_NAME_DEF_STMT, TDF_DETAILS, wi::to_wide(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by match_long_mul_phi().

◆ narrow_vec_perm_simplify_seq()

void narrow_vec_perm_simplify_seq ( const vec_perm_simplify_seq & seq)
static

◆ new_src_based_on_copy()

tree new_src_based_on_copy ( tree src2,
tree dest,
tree src )
static

◆ optimize_aggr_zeroprop()

◆ optimize_aggr_zeroprop_1()

◆ optimize_agr_copyprop()

void optimize_agr_copyprop ( gimple * stmt)
static
Optimizes
  DEST = SRC;
  DEST2 = DEST; # DEST2 = SRC2;
  into
  DEST = SRC;
  DEST2 = SRC;
  STMT is the first statement and SRC is the common
  between the statements.

  Also optimizes:
  DEST = SRC;
  call_func(..., DEST, ...);
  into:
  DEST = SRC;
  call_func(..., SRC, ...);

References as_a(), cfun, FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_has_volatile_ops(), gimple_store_p(), gimple_vdef(), is_a(), is_gimple_call(), optimize_agr_copyprop(), optimize_agr_copyprop_1(), optimize_agr_copyprop_arg(), optimize_agr_copyprop_return(), same_for_assignment(), _vec_perm_simplify_seq::stmt, and stmt_could_throw_p().

Referenced by optimize_agr_copyprop().

◆ optimize_agr_copyprop_1()

◆ optimize_agr_copyprop_arg()

void optimize_agr_copyprop_arg ( gimple * defstmt,
gcall * call,
tree dest,
tree src )
static
Helper function for optimize_agr_copyprop_1, propagate aggregates
into the arguments of USE_STMT if the argument matches with DEST;
replacing it with SRC.   

References dump_file, dump_flags, gimple_call_arg_ptr(), gimple_call_num_args(), is_gimple_min_invariant(), new_src_based_on_copy(), optimize_agr_copyprop_arg(), print_gimple_stmt(), TDF_DETAILS, TREE_CODE, TREE_TYPE, TYPE_VOLATILE, unshare_expr(), and update_stmt().

Referenced by optimize_agr_copyprop(), and optimize_agr_copyprop_arg().

◆ optimize_agr_copyprop_return()

void optimize_agr_copyprop_return ( gimple * defstmt,
greturn * use,
tree dest,
tree src )
static
Helper function for optimize_agr_copyprop, propagate aggregates
into the return stmt USE if the operand of the return matches DEST;
replacing it with SRC.   

References dump_file, dump_flags, gimple_return_retval(), gimple_return_set_retval(), is_gimple_min_invariant(), is_global_var(), new_src_based_on_copy(), optimize_agr_copyprop_return(), print_gimple_stmt(), SSA_NAME_VAR, TDF_DETAILS, TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_VOLATILE, update_stmt(), and VAR_P.

Referenced by optimize_agr_copyprop(), and optimize_agr_copyprop_return().

◆ optimize_stack_restore()

bool optimize_stack_restore ( gimple_stmt_iterator * gsi,
gimple * call )
static
Try to optimize out __builtin_stack_restore.  Optimize it out
if there is another __builtin_stack_restore in the same basic
block and no calls or ASM_EXPRs are in between, or if this block's
only outgoing edge is to EXIT_BLOCK and there are no calls or
ASM_EXPRs after this __builtin_stack_restore.
Note restore right before a noreturn function is not needed.
And skip some cheap calls that will most likely become an instruction.
Restoring the stack before a call is important to be able to keep
stack usage down so that call does not run out of stack.   

References build_int_cst(), cfun, dyn_cast(), EDGE_COUNT, EXIT_BLOCK_PTR_FOR_FN, fndecl_built_in_p(), fndecl_builtin_alloc_p(), fold_before_rtl_expansion_p(), gimple_call_arg(), gimple_call_fndecl(), gimple_call_internal_p(), gimple_call_noreturn_p(), gimple_call_num_args(), gsi_bb(), gsi_end_p(), gsi_for_stmt(), gsi_next(), gsi_stmt(), has_single_use(), i, is_a(), is_gimple_call(), is_inexpensive_builtin(), is_simple_builtin(), NULL_TREE, optimize_stack_restore(), POINTER_TYPE_P, replace_call_with_value(), single_succ_edge(), SSA_NAME_DEF_STMT, _vec_perm_simplify_seq::stmt, basic_block_def::succs, TREE_CODE, and TREE_TYPE.

Referenced by optimize_stack_restore(), and simplify_builtin_call().

◆ optimize_strlen_comp()

◆ optimize_vector_load()

◆ prepare_target_mem_ref_lvalue()

tree prepare_target_mem_ref_lvalue ( tree ref,
gimple_stmt_iterator * gsi )
static
Prepare a TARGET_MEM_REF ref so that it can be subsetted as
lvalue.  This splits out an address computation stmt before *GSI
and returns a MEM_REF wrapping the address.   

References build1(), build2_loc(), build_int_cst(), build_pointer_type(), EXPR_LOCATION, gimple_build_assign(), gsi_insert_before(), GSI_SAME_STMT, make_ssa_name(), mark_addressable(), prepare_target_mem_ref_lvalue(), TREE_CODE, TREE_OPERAND, TREE_TYPE, and unshare_expr().

Referenced by optimize_vector_load(), and prepare_target_mem_ref_lvalue().

◆ process_vec_perm_simplify_seq_list()

void process_vec_perm_simplify_seq_list ( vec< vec_perm_simplify_seq > * l)
static

◆ recognise_vec_perm_simplify_seq()

bool recognise_vec_perm_simplify_seq ( gassign * stmt,
vec_perm_simplify_seq * seq )
static
Search for opportunities to free half of the lanes in the following pattern:

  v_in = {e0, e1, e2, e3}
  v_1 = VEC_PERM <v_in, v_in, {0, 2, 0, 2}>
  // v_1 = {e0, e2, e0, e2}
  v_2 = VEC_PERM <v_in, v_in, {1, 3, 1, 3}>
  // v_2 = {e1, e3, e1, e3}

  v_x = v_1 + v_2
  // v_x = {e0+e1, e2+e3, e0+e1, e2+e3}
  v_y = v_1 - v_2
  // v_y = {e0-e1, e2-e3, e0-e1, e2-e3}

  v_out = VEC_PERM <v_x, v_y, {0, 1, 6, 7}>
  // v_out = {e0+e1, e2+e3, e0-e1, e2-e3}

The last statement could be simplified to:
  v_out' = VEC_PERM <v_x, v_y, {0, 1, 4, 5}>
  // v_out' = {e0+e1, e2+e3, e0-e1, e2-e3}

Characteristic properties:
- v_1 and v_2 are created from the same input vector v_in and introduce the
  lane duplication (in the selection operand) that we can eliminate.
- v_x and v_y are results from lane-preserving operations that use v_1 and
  v_2 as inputs.
- v_out is created by selecting from duplicated lanes.   

References can_vec_perm_const_p(), commutative_tree_code(), dump_file, dump_flags, dyn_cast(), gcc_checking_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_bb(), has_single_use(), i, num_imm_uses(), print_generic_expr(), print_gimple_stmt(), recognise_vec_perm_simplify_seq(), SSA_NAME_DEF_STMT, tcc_binary, TDF_DETAILS, TREE_CODE, TREE_CODE_CLASS, TREE_INT_CST_LOW, TREE_TYPE, TYPE_MODE, vect_gen_perm_mask_checked(), VECTOR_CST_ELT, and VECTOR_CST_NELTS.

Referenced by recognise_vec_perm_simplify_seq().

◆ remove_prop_source_from_use()

void remove_prop_source_from_use ( tree name)
static
Remove a chain of dead statements starting at the definition of
NAME.  The chain is linked via the first operand of the defining statements.
If NAME was replaced in its only use then this function can be used
to clean up dead stmts.  The function handles already released SSA
names gracefully.   

References bitmap_set_bit, fwprop_invalidate_lattice(), gimple_assign_rhs1(), gimple_bb(), gimple_get_lhs(), gimple_has_side_effects(), gsi_for_stmt(), gsi_remove(), has_zero_uses(), basic_block_def::index, is_gimple_assign(), NULL_TREE, release_defs(), remove_prop_source_from_use(), SSA_NAME_DEF_STMT, SSA_NAME_IN_FREE_LIST, SSA_NAME_IS_DEFAULT_DEF, _vec_perm_simplify_seq::stmt, to_purge, TREE_CODE, and unlink_stmt_vdef().

Referenced by forward_propagate_into_comparison(), forward_propagate_into_gimple_cond(), remove_prop_source_from_use(), and simplify_permutation().

◆ rhs_to_tree()

tree rhs_to_tree ( tree type,
gimple * stmt )
static
Return the rhs of a gassign *STMT in a form of a single tree,
converted to type TYPE.

This should disappear, but is needed so we can combine expressions and use
the fold() interfaces. Long term, we need to develop folding and combine
routines that deal with gimple exclusively .  

References build1(), fold_build2_loc(), fold_build3_loc(), gcc_unreachable, get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_location(), GIMPLE_SINGLE_RHS, GIMPLE_TERNARY_RHS, GIMPLE_UNARY_RHS, rhs_to_tree(), and _vec_perm_simplify_seq::stmt.

Referenced by forward_propagate_into_comparison_1(), and rhs_to_tree().

◆ same_for_assignment()

bool same_for_assignment ( tree src,
tree dest )
static
Returns true if SRC and DEST are the same address such that
`SRC == DEST;` is considered a nop. This is more than an
operand_equal_p check as it needs to be similar to
new_src_based_on_copy.   

References cst_and_fits_in_hwi(), DECL_P, fold_build2, fold_convert, int_cst_value(), known_eq, operand_equal_p(), same_for_assignment(), split_core_and_offset_size(), and TREE_TYPE.

Referenced by optimize_agr_copyprop(), optimize_agr_copyprop_1(), and same_for_assignment().

◆ simplify_builtin_call()

bool simplify_builtin_call ( gimple_stmt_iterator * gsi_p,
tree callee2,
bool full_walk )
static
*GSI_P is a GIMPLE_CALL to a builtin function.
Optimize
memcpy (p, "abcd", 4);
memset (p + 4, ' ', 3);
into
memcpy (p, "abcd   ", 7);
call if the latter can be stored by pieces during expansion.

Optimize
memchr ("abcd", a, 4) == 0;
or
memchr ("abcd", a, 4) != 0;
to
(a == 'a' || a == 'b' || a == 'c' || a == 'd') == 0
or
(a == 'a' || a == 'b' || a == 'c' || a == 'd') != 0

Also canonicalize __atomic_fetch_op (p, x, y) op x
to __atomic_op_fetch (p, x, y) or
__atomic_op_fetch (p, x, y) iop x
to __atomic_fetch_op (p, x, y) when possible (also __sync).   

References a, as_a(), build_zero_cst(), builtin_decl_explicit(), CASE_ATOMIC, DECL_FUNCTION_CODE(), END_BUILTINS, fold_convert, FOR_EACH_IMM_USE_STMT, g, gcc_assert, gcc_unreachable, 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_with_ops(), GIMPLE_BINARY_RHS, gimple_build_assign(), gimple_call_arg(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_set_fndecl(), gimple_call_set_lhs(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gimple_debug_bind_reset_value(), gsi_for_stmt(), gsi_insert_after(), GSI_NEW_STMT, gsi_remove(), gsi_stmt(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), make_ssa_name(), wi::neg(), NULL, NULL_TREE, operand_equal_p(), optimize_aggr_zeroprop(), optimize_stack_restore(), optimize_strlen_comp(), release_ssa_name(), simplify_builtin_call(), simplify_builtin_memchr(), simplify_builtin_memcmp(), simplify_builtin_memcpy_memset(), single_imm_use(), SSA_NAME_DEF_STMT, stmt_ends_bb_p(), wi::to_wide(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, update_stmt(), and useless_type_conversion_p().

Referenced by simplify_builtin_call().

◆ simplify_builtin_memchr()

◆ simplify_builtin_memcmp()

◆ simplify_builtin_memcpy_memset()

bool simplify_builtin_memcpy_memset ( gimple_stmt_iterator * gsi_p,
gcall * stmt2 )
static
*GSI_P is a GIMPLE_CALL to a builtin function.
  Optimize
  memcpy (p, "abcd", 4); // STMT1
  memset (p + 4, ' ', 3); // STMT2
  into
  memcpy (p, "abcd   ", 7);
  call if the latter can be stored by pieces during expansion.

References build_fold_addr_expr, build_int_cst(), build_string_literal(), BUILT_IN_NORMAL, builtin_decl_explicit(), builtin_strncpy_read_str(), can_store_by_pieces(), CHAR_BIT, char_type_node, compare_tree_int(), constant_pointer_difference(), DECL_FUNCTION_CODE(), fndecl_built_in_p(), fold_convert, force_gimple_operand_gsi(), fwprop_invalidate_lattice(), get_pointer_alignment(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_bb(), gimple_build_nop(), gimple_call_arg(), gimple_call_fndecl(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_set_arg(), gimple_call_set_fndecl(), gimple_call_set_fntype(), gimple_call_set_lhs(), gimple_get_lhs(), gimple_vdef(), gimple_vuse(), gsi_for_stmt(), gsi_remove(), gsi_replace(), GSI_SAME_STMT, is_gimple_call(), is_gimple_val(), NULL, NULL_TREE, release_defs(), release_ssa_name(), rtl_profile_for_bb(), simplify_builtin_memcpy_memset(), single_imm_use(), size_binop, size_one_node, size_zero_node, sizetype, SSA_NAME_DEF_STMT, string_constant(), STRIP_USELESS_TYPE_CONVERSION, TREE_CODE, tree_fits_shwi_p(), tree_fits_uhwi_p(), tree_int_cst_lt(), TREE_STRING_LENGTH, TREE_STRING_POINTER, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TYPE_MODE, unlink_stmt_vdef(), and update_stmt().

Referenced by simplify_builtin_call(), and simplify_builtin_memcpy_memset().

◆ simplify_count_zeroes()

bool simplify_count_zeroes ( gimple_stmt_iterator * gsi)
static
Recognize count leading and trailing zeroes idioms.
The canonical form is array[((x & -x) * C) >> SHIFT] where C is a magic
constant which when multiplied by a power of 2 creates a unique value
in the top 5 or 6 bits.  This is then indexed into a table which maps it
to the number of trailing zeroes.  Array[0] is returned so the caller can
emit an appropriate sequence depending on whether ctz (0) is defined on
the target.   

References array_ref_low_bound(), boolean_type_node, build_int_cst(), build_zero_cst(), cfun, check_table(), CLZ_DEFINED_VALUE_AT_ZERO, ctor_for_folding(), CTZ_DEFINED_VALUE_AT_ZERO, direct_internal_fn_supported_p(), enable_ranger(), g, gcc_checking_assert, get_global_range_query(), get_range_query(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_build_assign(), gimple_build_call_internal(), gimple_call_lhs(), gimple_clz_msb_iso_table_index(), gimple_clz_table_index(), gimple_ctz_table_index(), gimple_location(), gimple_seq_add_stmt(), gimple_set_lhs(), gimple_set_location(), gsi_replace_with_seq(), gsi_stmt(), HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1U, i, integer_type_node, integer_zerop(), INTEGRAL_TYPE_P, make_ssa_name(), NULL, NULL_TREE, OPTIMIZE_FOR_BOTH, range_includes_zero_p(), range_query::range_of_expr(), SCALAR_INT_TYPE_MODE, simplify_count_zeroes(), _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_OPERAND, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, TYPE_SIZE, and TYPE_UNSIGNED.

Referenced by simplify_count_zeroes().

◆ simplify_gimple_switch()

bool simplify_gimple_switch ( gswitch * stmt,
vec< std::pair< int, int > > & edges_to_remove,
bitmap simple_dce_worklist )
static

◆ simplify_gimple_switch_label_vec()

◆ simplify_permutation()

◆ simplify_phi_result_movdiv()

bool simplify_phi_result_movdiv ( gimple * stmt,
tree_code code )
static
Verify if we have the following structure:

iftmp1 = PHI <pow2a, pow2b, pow2c, ...>
_ssa1 = _ssa2 MOD|DIV iftmp1;
_ssa3 = _ssa1 EQ|NE 0;

And, if the right conditions are met, change the PHI args
and "_ssa1" stmt to a cheaper alternative.

- for MOD, if either "_ssa2" is known to be positive or
"_ssa1" is used just in zero comparisons:

iftmp1 = PHI <(pow2a - 1), (pow2b - 1), (pow2c - 1), ...>
_ssa1 = _ssa2 & iftmp1;

- for DIV, if "_ssa2" is known to be positive:

iftmp1 = PHI <log2 (pow2a), log2 (pow2b), log2 (pow2c), ...>
_ssa1 = _ssa2 >> iftmp1;   

References add_phi_arg(), as_a(), gimple::bb, create_phi_node(), wi::exact_log2(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), gimple_convert(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_edge(), gimple_phi_arg_location(), gimple_phi_num_args(), gimple_phi_result(), gsi_for_phi(), gsi_for_stmt(), GSI_SAME_STMT, i, integer_pow2p(), integer_type_node, INTEGRAL_TYPE_P, make_ssa_name(), remove_phi_node(), simplify_phi_result_movdiv(), SSA_NAME_DEF_STMT, wi::to_wide(), tree_expr_nonnegative_p, tree_int_cst_sgn(), TREE_TYPE, update_stmt(), use_in_zero_equality(), and wide_int_to_tree().

Referenced by simplify_phi_result_movdiv().

◆ simplify_rotate()

bool simplify_rotate ( gimple_stmt_iterator * gsi)
static
Recognize rotation patterns.  Return true if a transformation
applied, otherwise return false.

We are looking for X with unsigned type T with bitsize B, OP being
+, | or ^, some type T2 wider than T.  For:
(X << CNT1) OP (X >> CNT2)                              iff CNT1 + CNT2 == B
((T) ((T2) X << CNT1)) OP ((T) ((T2) X >> CNT2))        iff CNT1 + CNT2 == B

transform these into:
X r<< CNT1

Or for:
(X << Y) OP (X >> (B - Y))
(X << (int) Y) OP (X >> (int) (B - Y))
((T) ((T2) X << Y)) OP ((T) ((T2) X >> (B - Y)))
((T) ((T2) X << (int) Y)) OP ((T) ((T2) X >> (int) (B - Y)))
(X << Y) | (X >> ((-Y) & (B - 1)))
(X << (int) Y) | (X >> (int) ((-Y) & (B - 1)))
((T) ((T2) X << Y)) | ((T) ((T2) X >> ((-Y) & (B - 1))))
((T) ((T2) X << (int) Y)) | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))

transform these into (last 2 only if ranger can prove Y < B
or Y = N * B):
X r<< Y
or
X r<< (& & (B - 1))
The latter for the forms with T2 wider than T if ranger can't prove Y < B.

Or for:
(X << (Y & (B - 1))) | (X >> ((-Y) & (B - 1)))
(X << (int) (Y & (B - 1))) | (X >> (int) ((-Y) & (B - 1)))
((T) ((T2) X << (Y & (B - 1)))) | ((T) ((T2) X >> ((-Y) & (B - 1))))
((T) ((T2) X << (int) (Y & (B - 1)))) \
  | ((T) ((T2) X >> (int) ((-Y) & (B - 1))))

transform these into:
X r<< (Y & (B - 1))

Note, in the patterns with T2 type, the type of OP operands
might be even a signed type, but should have precision B.
Expressions with & (B - 1) should be recognized only if B is
a power of 2.   

References build_int_cst(), cfun, CONVERT_EXPR_CODE_P, defcodefor_name(), enable_ranger(), floor_log2(), wide_int_storage::from(), g, get_global_range_query(), get_range_query(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build_assign(), gsi_insert_before(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), has_single_use(), i, INTEGRAL_TYPE_P, make_ssa_name(), MIN, NULL, NULL_TREE, operand_equal_for_phi_arg_p(), pow2p_hwi(), r, range_query::range_of_expr(), simplify_rotate(), SSA_NAME_DEF_STMT, _vec_perm_simplify_seq::stmt, TREE_CODE, tree_fits_shwi_p(), tree_fits_uhwi_p(), tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, type_has_mode_precision_p(), TYPE_PRECISION, TYPE_SIGN, TYPE_UNSIGNED, types_compatible_p(), irange::union_(), and useless_type_conversion_p().

Referenced by simplify_rotate().

◆ simplify_vector_constructor()

bool simplify_vector_constructor ( gimple_stmt_iterator * gsi)
static

◆ split_core_and_offset_size()

tree split_core_and_offset_size ( tree expr,
poly_int64 * pbytesize,
poly_int64 * pbytepos,
tree * poffset,
int * preversep )
static
Returns the pointer to the base of the object of the
reference EXPR and extracts the information about
the offset of the access, storing it to PBYTESIZE,
PBYTEPOS and PREVERSEP.
If the access is not a byte sized or position is not
on the byte, return NULL.   

References build_fold_addr_expr_loc(), EXPR_LOCATION, get_inner_reference(), NULL_TREE, split_core_and_offset_size(), STRIP_NOPS, wi::to_poly_offset(), poly_int< N, C >::to_shwi(), TREE_CODE, and TREE_OPERAND.

Referenced by new_src_based_on_copy(), same_for_assignment(), and split_core_and_offset_size().

◆ tidy_after_forward_propagate_addr()

void tidy_after_forward_propagate_addr ( gimple * stmt)
static

Variable Documentation

◆ cfg_changed

bool cfg_changed
static
Set to true if we delete dead edges during the optimization.   

◆ lattice

vec<tree> lattice
static
Const-and-copy lattice.   

Referenced by fwprop_invalidate_lattice(), fwprop_set_lattice_val(), and fwprop_ssa_val().

◆ LONG_MUL_MAX_CAPTURES

unsigned LONG_MUL_MAX_CAPTURES = 8
staticconstexpr
Widest match.pd atom (mul_carry_low_sum) takes 7 captures; round up
to 8 for the scratch buffers below.   

Referenced by long_mul_check_two_carries(), long_mul_hilo_orientation(), long_mul_is_cross_half(), and match_long_mul_phi().

◆ LONG_MUL_MAX_EXTRAS

unsigned LONG_MUL_MAX_EXTRAS = 4
staticconstexpr
Cap on the leaves set aside as not part of the idiom, so an
arbitrarily long unrelated chain still bails early.   

Referenced by long_mul_classify_chain(), and long_mul_linearize_chain().

◆ LONG_MUL_MAX_SUMMANDS

unsigned LONG_MUL_MAX_SUMMANDS = 4
staticconstexpr
Longest variant in long_mul_table has 4 summands.   

Referenced by long_mul_classify_chain(), and long_mul_linearize_chain().

◆ long_mul_table

const long_mul_row long_mul_table[]
static
Long-multiply variant table.  Each row enumerates the multiset of
(kind, extract) summands that compose one long-multiply form.  Rows
are sorted by long_mul_summand_compare, matching the input summands'
sort order, so a plain element-wise compare suffices.  Rows describe
unsigned schoolbook expansions on an even-width 2N-bit type split at
half-width N; EXTRA_CHECK carries invariants the (kind, extract)
signature cannot express.

The formula on each row uses xh, xl, yh, yl for the half-width pieces
of x and y, cross_sum for xh*yl + xl*yh, and hilo for either cross-half
product (consumers validate the operand shape).   

Referenced by long_mul_classify_match().

◆ to_purge