|
GCC Middle and Back End API 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"
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_seq * | vec_perm_simplify_seq |
Variables | |
| static bool | cfg_changed |
| static bitmap | to_purge |
| static vec< tree > | lattice |
| 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 [] |
| #define CASE_ATOMIC | ( | NAME, | |
| OTHER, | |||
| OP ) |
| #define CPD_ITERATIONS 5 |
Referenced by constant_pointer_difference().
| typedef struct _vec_perm_simplify_seq* vec_perm_simplify_seq |
|
static |
References append_vec_perm_simplify_seq_list(), and process_vec_perm_simplify_seq_list().
Referenced by append_vec_perm_simplify_seq_list().
|
static |
Blend the two given simplifiable vec permute sequences using the given permutations.
References blend_vec_perm_simplify_seqs(), dump_file, dump_flags, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs3(), print_gimple_stmt(), _vec_perm_simplify_seq::stmt, TDF_DETAILS, TREE_TYPE, update_stmt(), _vec_perm_simplify_seq::v_1_stmt, _vec_perm_simplify_seq::v_2_stmt, and vect_gen_perm_mask_checked().
Referenced by blend_vec_perm_simplify_seqs(), and process_vec_perm_simplify_seq_list().
|
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().
|
static |
Calculate the permutations for blending the two given vec permute sequences. This may fail if the resulting permutation is not supported.
References calc_perm_vec_perm_simplify_seqs(), can_vec_perm_const_p(), gimple_assign_lhs(), gimple_assign_rhs3(), i, _vec_perm_simplify_seq::nelts, _vec_perm_simplify_seq::new_sel, vec_perm_indices::new_vector(), _vec_perm_simplify_seq::stmt, TREE_INT_CST_LOW, TREE_TYPE, TYPE_MODE, _vec_perm_simplify_seq::v_1_stmt, _vec_perm_simplify_seq::v_2_stmt, and VECTOR_CST_ELT.
Referenced by calc_perm_vec_perm_simplify_seqs(), and process_vec_perm_simplify_seq_list().
|
static |
Test if we can blend two simplifiable vec permute sequences. NEED_SWAP will be set, if sequences must be swapped for blending.
References can_blend_vec_perm_simplify_seqs_p(), dump_file, dump_flags, dyn_cast(), gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_bb(), gimple_uid(), _vec_perm_simplify_seq::nelts, SSA_NAME_DEF_STMT, _vec_perm_simplify_seq::stmt, TDF_DETAILS, TREE_CODE, TREE_TYPE, _vec_perm_simplify_seq::v_1_stmt, _vec_perm_simplify_seq::v_x_stmt, and _vec_perm_simplify_seq::v_y_stmt.
Referenced by can_blend_vec_perm_simplify_seqs_p(), and process_vec_perm_simplify_seq_list().
Checks if the destination ssa name in DEF_STMT can be used as propagation source. Returns true if so, otherwise false.
References can_propagate_from(), CONVERT_EXPR_CODE_P, FUNCTION_POINTER_TYPE_P, gcc_assert, gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_assign_single_p(), gimple_has_volatile_ops(), is_gimple_assign(), is_gimple_min_invariant(), stmt_references_abnormal_ssa_name(), tcc_declaration, tcc_reference, TREE_CODE_CLASS, and TREE_TYPE.
Referenced by can_propagate_from(), defcodefor_name(), forward_propagate_into_comparison_1(), and simplify_permutation().
|
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().
|
static |
Check whether an array contains a valid table according to VALIDATE_FN.
References check_table_array(), CONSTRUCTOR_ELTS, FOR_EACH_CONSTRUCTOR_ELT, i, RAW_DATA_LENGTH, RAW_DATA_SCHAR_ELT, RAW_DATA_UCHAR_ELT, TREE_CODE, tree_fits_shwi_p(), tree_to_shwi(), TREE_TYPE, and TYPE_UNSIGNED.
Referenced by check_table(), and check_table_array().
|
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().
|
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().
For pointers p2 and p1 return p2 - p1 if the difference is known and constant, otherwise return NULL.
References constant_pointer_difference(), CONVERT_EXPR_CODE_P, CPD_ITERATIONS, get_addr_base_and_unit_offset(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), i, is_gimple_assign(), mem_ref_offset(), NULL_TREE, POINTER_TYPE_P, size_binop, size_int, size_zero_node, sizetype, SSA_NAME_DEF_STMT, _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_OPERAND, TREE_TYPE, and wide_int_to_tree().
Referenced by constant_pointer_difference(), and simplify_builtin_memcpy_memset().
|
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().
|
static |
Replace STMT with a low-part multiply of OP1 and OP2, combining any EXTRAS back on top under OUTER.
References create_mul_low_seq(), gimple_assign_lhs(), gimple_build_assign(), gimple_location(), gimple_seq_add_stmt(), gimple_set_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_low_seq(), and match_long_mul().
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().
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().
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().
|
static |
NAME is a SSA_NAME representing DEF_RHS which is of the form ADDR_EXPR <whatever>. Try to forward propagate the ADDR_EXPR into the use USE_STMT. Often this will allow for removal of an ADDR_EXPR and INDIRECT_REF node or for recovery of array indexing from pointer arithmetic. Return true if the propagation was successful (the propagation can be not totally successful, yet things may have been changed).
References build1(), build1_loc(), build2(), build_aligned_type(), build_fold_addr_expr, CONVERT_EXPR_CODE_P, fold_build2, fold_convert, fold_stmt_inplace(), forward_propagate_addr_expr(), forward_propagate_addr_expr_1(), gcc_assert, get_addr_base_and_unit_offset(), gimple_assign_lhs(), gimple_assign_lhs_ptr(), gimple_assign_rhs1(), gimple_assign_rhs1_ptr(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_assign_set_rhs_with_ops(), gimple_clobber_p(), gimple_location(), gsi_stmt(), handled_component_p(), integer_zerop(), INTEGRAL_TYPE_P, is_gimple_mem_ref_addr(), is_gimple_min_invariant(), mem_ref_offset(), POINTER_TYPE_P, ptr_type_node, tidy_after_forward_propagate_addr(), TREE_CODE, TREE_OPERAND, TREE_SIDE_EFFECTS, TREE_THIS_NOTRAP, TREE_THIS_VOLATILE, TREE_TYPE, TYPE_ALIGN, TYPE_PRECISION, types_compatible_p(), unshare_expr(), update_stmt(), useless_type_conversion_p(), and wide_int_to_tree().
Referenced by forward_propagate_addr_expr(), and forward_propagate_addr_expr_1().
|
static |
Propagate from the ssa name definition statements of the assignment from a comparison at *GSI into the conditional if that simplifies it. Returns true if the stmt was modified.
References dump_file, fold_stmt(), forward_propagate_into_comparison(), forward_propagate_into_comparison_1(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gsi_stmt(), print_generic_expr(), print_gimple_expr(), remove_prop_source_from_use(), _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_TYPE, update_stmt(), and useless_type_conversion_p().
Referenced by forward_propagate_into_comparison().
|
static |
Combine the comparison OP0 CODE OP1 at LOC with the defining statements of its operand. Return a new comparison tree or NULL_TREE if there were no simplifying combines.
References can_propagate_from(), combine_cond_expr_cond(), CONVERT_EXPR_CODE_P, forward_propagate_into_comparison_1(), get_prop_source_stmt(), gimple_assign_rhs_code(), NULL_TREE, rhs_to_tree(), _vec_perm_simplify_seq::stmt, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_OPERAND, and TREE_TYPE.
Referenced by forward_propagate_into_comparison(), forward_propagate_into_comparison_1(), and forward_propagate_into_gimple_cond().
|
static |
Propagate from the ssa name definition statements of COND_EXPR in GIMPLE_COND statement STMT into the conditional if that simplifies it. Returns zero if no statement was changed, one if there were changes and two if cfg_cleanup needs to run.
References boolean_type_node, canonicalize_bool_cond(), dump_file, forward_propagate_into_comparison_1(), forward_propagate_into_gimple_cond(), gcc_assert, gimple_bb(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_condition_from_tree(), is_gimple_condexpr_for_cond(), is_gimple_min_invariant(), print_generic_expr(), print_gimple_expr(), remove_prop_source_from_use(), _vec_perm_simplify_seq::stmt, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, unshare_expr(), and update_stmt().
Referenced by forward_propagate_into_gimple_cond().
|
static |
Invalidate the lattice entry for NAME, done when releasing SSA names.
References fwprop_invalidate_lattice(), lattice, NULL_TREE, SSA_NAME_VERSION, and TREE_CODE.
Referenced by forward_propagate_addr_expr(), fwprop_invalidate_lattice(), remove_prop_source_from_use(), and simplify_builtin_memcpy_memset().
Set the lattice entry for NAME to VAL.
References fwprop_set_lattice_val(), lattice, maybe_duplicate_ssa_info_at_copy(), num_ssa_names, SSA_NAME_VERSION, and TREE_CODE.
Referenced by fwprop_set_lattice_val().
Primitive "lattice" function for gimple_simplify.
References fwprop_ssa_val(), lattice, SSA_NAME_VERSION, and TREE_CODE.
Referenced by fwprop_ssa_val().
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 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().
References gimple_clz_msb_iso_table_index().
Referenced by gimple_clz_msb_iso_table_index(), and simplify_count_zeroes().
References gimple_clz_table_index().
Referenced by gimple_clz_table_index(), and simplify_count_zeroes().
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().
Match.pd function to match the ctz expression.
References gimple_ctz_table_index().
Referenced by gimple_ctz_table_index(), and simplify_count_zeroes().
References gimple_mul_carry_cross_sum().
Referenced by gimple_mul_carry_cross_sum().
References gimple_mul_carry_low().
Referenced by gimple_mul_carry_low().
References gimple_mul_carry_low_sum().
Referenced by gimple_mul_carry_low_sum().
References gimple_mul_cross_sum().
Referenced by gimple_mul_cross_sum(), long_mul_check_two_carries(), and match_long_mul_phi().
Match.pd functions to match long multiplication.
References gimple_mul_hi().
Referenced by gimple_mul_hi().
References gimple_mul_hihi().
Referenced by gimple_mul_hihi().
References gimple_mul_hilo().
Referenced by gimple_mul_hilo(), long_mul_hilo_orientation(), and long_mul_is_cross_half().
References gimple_mul_ladder_part_sum().
Referenced by gimple_mul_ladder_part_sum().
References gimple_mul_ladder_sum1().
Referenced by gimple_mul_ladder_sum1().
References gimple_mul_ladder_sum2().
Referenced by gimple_mul_ladder_sum2().
References gimple_mul_ladder_sum3().
Referenced by gimple_mul_ladder_sum3().
References gimple_mul_lo().
Referenced by gimple_mul_lo().
References gimple_mul_lolo().
Referenced by gimple_mul_lolo(), and long_mul_check_two_carries().
References gimple_mul_low_accum().
Referenced by gimple_mul_low_accum().
References gimple_mul_low_sum().
Referenced by gimple_mul_low_sum(), and match_long_mul_phi().
Determine whether applying the 2 permutations (mask1 then mask2) gives back one of the input.
References fold_ternary, gcc_assert, gcc_checking_assert, i, is_combined_permutation_identity(), NULL_TREE, operand_equal_p(), vec_perm_indices::series_p(), TREE_CODE, TREE_INT_CST_LOW, tree_to_vec_perm_builder(), TREE_TYPE, TYPE_VECTOR_SUBPARTS(), VECTOR_CST_ELT, and VECTOR_CST_NELTS.
Referenced by is_combined_permutation_identity(), and simplify_permutation().
|
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().
|
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().
|
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().
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().
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().
|
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().
|
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().
|
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().
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().
|
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().
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().
|
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().
|
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().
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().
|
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().
|
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().
| gimple_opt_pass * make_pass_forwprop | ( | gcc::context * | ctxt | ) |
References make_pass_forwprop().
Referenced by make_pass_empty_loop(), and make_pass_forwprop().
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().
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().
|
static |
Reduce the lane consumption of a simplifiable vec perm sequence.
References dump_file, dump_flags, gimple_assign_set_rhs3(), narrow_vec_perm_simplify_seq(), _vec_perm_simplify_seq::new_sel, print_gimple_stmt(), _vec_perm_simplify_seq::stmt, TDF_DETAILS, and update_stmt().
Referenced by narrow_vec_perm_simplify_seq(), and process_vec_perm_simplify_seq_list().
Returns a new src based on the copy `DEST = SRC` and for the old SRC2. Returns null if SRC2 is not related to DEST.
References cst_and_fits_in_hwi(), DECL_P, fold_build1, fold_build2, fold_convert, int_cst_value(), known_eq, new_src_based_on_copy(), NULL_TREE, operand_equal_p(), split_core_and_offset_size(), TREE_CODE, and TREE_TYPE.
Referenced by new_src_based_on_copy(), optimize_agr_copyprop_1(), optimize_agr_copyprop_arg(), and optimize_agr_copyprop_return().
Optimize
a = {}; // DEST = value ;; LEN(nullptr)
b = a;
into
a = {};
b = {};
Similarly for memset (&a, ..., sizeof (a)); instead of a = {};
and/or memcpy (&b, &a, sizeof (a)); instead of b = a;
References ao_ref_init(), ao_ref_init_from_ptr_and_size(), DECL_SIZE_UNIT, FOR_EACH_IMM_USE_STMT, get_addr_base_and_unit_offset(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_call_arg(), gimple_call_builtin_p(), gimple_clobber_p(), gimple_has_volatile_ops(), gimple_store_p(), gimple_vdef(), i, integer_zero_node, integer_zerop(), INTEGRAL_TYPE_P, is_a(), NULL_TREE, optimize_aggr_zeroprop(), optimize_aggr_zeroprop_1(), poly_int_tree_p(), _vec_perm_simplify_seq::stmt, stmt_may_clobber_ref_p_1(), wi::to_poly_offset(), TREE_CODE, TREE_OPERAND, TREE_STRING_LENGTH, TREE_STRING_POINTER, TREE_TYPE, TYPE_PRECISION, and TYPE_SIZE_UNIT.
Referenced by optimize_aggr_zeroprop(), and simplify_builtin_call().
|
static |
Helper function for optimize_aggr_zeroprop. Props the zeroing (memset, VAL) that was done in DEST+OFFSET:LEN (DEFSTMT) into the STMT. Returns true if the STMT was updated.
References as_a(), bitmap_set_bit, build_constructor(), builtin_decl_implicit(), cfun, DECL_SIZE_UNIT, dump_file, dump_flags, get_addr_base_and_unit_offset(), gimple_assign_lhs(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_assign_set_rhs_from_tree(), gimple_bb(), gimple_call_arg(), gimple_call_builtin_p(), gimple_call_set_arg(), gimple_call_set_fndecl(), gimple_call_set_fntype(), gimple_store_p(), gsi_for_stmt(), integer_zerop(), is_gimple_assign(), maybe_clean_or_replace_eh_stmt(), maybe_gt, NULL, NULL_TREE, operand_equal_p(), optimize_aggr_zeroprop_1(), poly_int_tree_p(), print_gimple_stmt(), statistics_counter_event(), _vec_perm_simplify_seq::stmt, TDF_DETAILS, wi::to_poly_offset(), to_purge, TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_SIZE_UNIT, and update_stmt().
Referenced by optimize_aggr_zeroprop(), and optimize_aggr_zeroprop_1().
|
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().
Helper function for optimize_agr_copyprop. For aggregate copies in USE_STMT, see if DEST is on the lhs of USE_STMT and replace it with SRC.
References bitmap_set_bit, cfun, DECL_P, dump_file, dump_flags, gcc_assert, get_addr_base_and_unit_offset(), get_object_alignment(), gimple_assign_lhs(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_assign_set_rhs_from_tree(), gimple_bb(), gimple_has_volatile_ops(), gimple_store_p(), gsi_for_stmt(), known_eq, maybe_clean_or_replace_eh_stmt(), new_src_based_on_copy(), NULL_TREE, operand_equal_p(), optimize_agr_copyprop_1(), print_gimple_stmt(), same_for_assignment(), statistics_counter_event(), _vec_perm_simplify_seq::stmt, TDF_DETAILS, to_purge, tree_fits_poly_int64_p(), tree_to_poly_int64(), TREE_TYPE, TYPE_SIZE_UNIT, unshare_expr(), and update_stmt().
Referenced by optimize_agr_copyprop(), and optimize_agr_copyprop_1().
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().
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().
|
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().
|
static |
Optimizes strlen (s) ==/!= 0 to *s ==/!= 0.
References build_zero_cst(), char_type_node, fold_before_rtl_expansion_p(), fold_build2, fold_convert_loc(), gimple_call_arg(), gimple_call_lhs(), gimple_location(), gimplify_and_update_call_from_tree(), NULL, NULL_TREE, optimize_strlen_comp(), ptr_type_node, TREE_TYPE, and use_in_zero_equality().
Referenced by optimize_strlen_comp(), and simplify_builtin_call().
|
static |
Rewrite the vector load at *GSI to component-wise loads if the load is only used in BIT_FIELD_REF extractions with eventual intermediate widening.
References bit_field_offset(), bit_field_size(), bitsize_int, can_implement_p(), fold_build3, FOR_EACH_IMM_USE_FAST, FOR_EACH_IMM_USE_STMT, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_assign(), gimple_debug_bind_p(), gimple_debug_bind_reset_value(), gimple_location(), gimple_set_location(), gimple_set_vuse(), gimple_vuse(), gsi_for_stmt(), gsi_insert_before(), gsi_next(), gsi_remove(), GSI_SAME_STMT, gsi_stmt(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), known_eq, make_ssa_name(), optimize_vector_load(), prepare_target_mem_ref_lvalue(), release_defs(), size_binop, SSA_NAME_DEF_STMT, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, TREE_INT_CST_LOW, TREE_OPERAND, TREE_TYPE, TYPE_MODE, TYPE_SIZE, unlink_stmt_vdef(), unshare_expr(), update_stmt(), USE_STMT, and VECTOR_TYPE_P.
Referenced by optimize_vector_load().
|
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().
|
static |
Try to blend narrowed vec_perm_simplify_seqs pairwise. The provided list will be empty after this call.
References blend_vec_perm_simplify_seqs(), calc_perm_vec_perm_simplify_seqs(), can_blend_vec_perm_simplify_seqs_p(), dump_file, dump_flags, FOR_EACH_VEC_ELT, FOR_EACH_VEC_ELT_FROM, i, narrow_vec_perm_simplify_seq(), process_vec_perm_simplify_seq_list(), and TDF_DETAILS.
Referenced by append_vec_perm_simplify_seq_list(), and process_vec_perm_simplify_seq_list().
|
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().
|
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().
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().
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().
|
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().
|
static |
Optimizes builtin memchrs for small constant sizes with a const string. GSI_P is the GSI for the call. STMT is the call itself.
References boolean_type_node, build_int_cst(), CHAR_BIT, char_type_node, fold_build2_loc(), fold_convert_loc(), gimple_bb(), gimple_call_arg(), gimple_call_lhs(), gimple_call_num_args(), gimple_location(), gimplify_and_update_call_from_tree(), i, optimize_bb_for_speed_p(), simplify_builtin_memchr(), _vec_perm_simplify_seq::stmt, TREE_CODE, tree_fits_uhwi_p(), TREE_OPERAND, TREE_STRING_LENGTH, TREE_STRING_POINTER, tree_to_uhwi(), TREE_TYPE, use_in_zero_equality(), and useless_type_conversion_p().
Referenced by simplify_builtin_call(), and simplify_builtin_memchr().
|
static |
Optimizes builtin memcmps for small constant sizes. GSI_P is the GSI for the call. STMT is the call itself.
References boolean_type_node, build2_loc(), build_aligned_type(), build_int_cst(), build_nonstandard_integer_type(), build_pointer_type_for_mode(), builtin_decl_explicit(), char_type_node, CHAR_TYPE_SIZE, DECL_FUNCTION_CODE(), fold_before_rtl_expansion_p(), fold_build2_loc(), fold_const_aggregate_ref(), fold_convert_loc(), gcc_assert, GET_MODE_BITSIZE(), GET_MODE_SIZE(), get_pointer_alignment(), gimple_call_arg(), gimple_call_fndecl(), gimple_call_lhs(), gimple_call_num_args(), gimple_call_set_fndecl(), gimple_location(), gimplify_and_update_call_from_tree(), int_mode_for_size(), INTEGRAL_TYPE_P, known_eq, MIN, POINTER_TYPE_P, pow2p_hwi(), ptr_mode, simplify_builtin_memcmp(), _vec_perm_simplify_seq::stmt, targetm, tree_fits_uhwi_p(), tree_to_uhwi(), TREE_TYPE, TYPE_ALIGN, TYPE_MODE, update_stmt(), use_in_zero_equality(), and word_mode.
Referenced by simplify_builtin_call(), and simplify_builtin_memcmp().
|
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().
|
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().
|
static |
STMT is a SWITCH_EXPR for which we attempt to find equivalent forms of the condition which we may be able to optimize better.
References bitmap_set_bit, CASE_HIGH, CASE_LOW, gimple_assign_cast_p(), gimple_assign_rhs1(), gimple_switch_index(), gimple_switch_label(), gimple_switch_num_labels(), gimple_switch_set_index(), int_fits_type_p(), INTEGRAL_TYPE_P, NULL_TREE, simplify_gimple_switch(), simplify_gimple_switch_label_vec(), SSA_NAME_DEF_STMT, SSA_NAME_VERSION, _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_TYPE, TYPE_PRECISION, and update_stmt().
Referenced by simplify_gimple_switch().
|
static |
Helper function for simplify_gimple_switch. Remove case labels that have values outside the range of the new type.
References BITMAP_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, build_case_label(), build_int_cst(), CASE_LABEL, cfun, ei_next(), ei_safe_edge(), ei_start, gimple_bb(), gimple_switch_default_label(), gimple_switch_label(), gimple_switch_num_labels(), gimple_switch_set_label(), gimple_switch_set_num_labels(), i, basic_block_def::index, label_to_block(), NULL, NULL_TREE, preprocess_case_label_vec_for_gimple(), simplify_gimple_switch_label_vec(), and _vec_perm_simplify_seq::stmt.
Referenced by simplify_gimple_switch(), and simplify_gimple_switch_label_vec().
|
static |
Combine a shuffle with its arguments. Returns true if there were any changes made.
References build1(), build_nonstandard_integer_type(), build_vector_type(), can_propagate_from(), fold_build1, fold_ternary, gcc_assert, gcc_checking_assert, get_prop_source_stmt(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_build_assign(), gimple_set_num_ops(), gsi_insert_before(), GSI_SAME_STMT, gsi_stmt(), has_single_use(), is_combined_permutation_identity(), is_gimple_assign(), make_ssa_name(), maybe_gt, vec_perm_indices::new_shrunk_vector(), NULL, NULL_TREE, num_imm_uses(), remove_prop_source_from_use(), simplify_permutation(), SSA_NAME_DEF_STMT, TREE_CODE, TREE_INT_CST_LOW, TREE_OPERAND, tree_to_vec_perm_builder(), TREE_TYPE, TYPE_SIZE, TYPE_VECTOR_SUBPARTS(), unshare_expr(), update_stmt(), vec_perm_indices_to_tree(), VECTOR_INTEGER_TYPE_P, and VECTOR_TYPE_P.
Referenced by simplify_permutation().
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().
|
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().
|
static |
Recognize a VEC_PERM_EXPR. Returns true if there were any changes.
References as_a(), bit_field_offset(), bit_field_size(), bitsize_zero_node, build1(), build3(), build_vector_type(), build_zero_cst(), can_vec_perm_const_p(), cfun, CONSTANT_CLASS_P, CONSTRUCTOR_ELTS, CONVERT_EXPR_CODE_P, DECIMAL_FLOAT_TYPE_P, error_mark_node, FLOAT_TYPE_P, fold_convert, FOR_EACH_VEC_SAFE_ELT, gcc_assert, gcc_checking_assert, get_bit_field_ref_def(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_set_rhs_from_tree(), gimple_assign_set_rhs_with_ops(), gimple_build(), gimple_build_assign(), gimple_build_vector_from_val(), gsi_insert_before(), gsi_insert_seq_before(), GSI_SAME_STMT, gsi_stmt(), i, insn_data, poly_int< N, C >::is_constant(), known_eq, make_ssa_name(), mode_for_vector(), NULL, NULL_TREE, operand_equal_p(), optab_default, optab_for_tree_code(), optab_handler(), PROP_gimple_lvec, signed_or_unsigned_type_for(), simplify_vector_constructor(), ssa_uniform_vector_p(), ssizetype, supportable_convert_operation(), poly_int< N, C >::to_constant(), TREE_CODE, tree_nop_conversion_p(), TREE_OPERAND, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, TYPE_SIGN, TYPE_SIZE, TYPE_UNSIGNED, TYPE_VECTOR_SUBPARTS(), UNKNOWN_LOCATION, update_stmt(), useless_type_conversion_p(), constructor_elt::value, vec_perm_indices_to_tree(), VECTOR_BOOLEAN_TYPE_P, VECTOR_CST_ELT, VECTOR_MODE_P, and VECTOR_TYPE_P.
Referenced by simplify_vector_constructor().
|
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().
|
static |
We've just substituted an ADDR_EXPR into stmt. Update all the relevant data structures to match.
References bitmap_set_bit, gimple_assign_rhs1(), gimple_bb(), maybe_clean_or_replace_eh_stmt(), recompute_tree_invariant_for_addr_expr(), _vec_perm_simplify_seq::stmt, tidy_after_forward_propagate_addr(), to_purge, and TREE_CODE.
Referenced by forward_propagate_addr_expr_1(), and tidy_after_forward_propagate_addr().
|
static |
Set to true if we delete dead edges during the optimization.
Const-and-copy lattice.
Referenced by fwprop_invalidate_lattice(), fwprop_set_lattice_val(), and fwprop_ssa_val().
|
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().
|
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().
|
staticconstexpr |
Longest variant in long_mul_table has 4 summands.
Referenced by long_mul_classify_chain(), and long_mul_linearize_chain().
|
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().
|
static |