|
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_summand |
| 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 |
Enumerations | |
| enum | long_mul_kind { LMK_MUL_HIHI , LMK_MUL_LOLO , LMK_MUL_HILO , LMK_CROSS_SUM , LMK_LOW_ACCUM , LMK_LOW_SUM , LMK_LADDER_SUM1 , LMK_LADDER_SUM2 , LMK_LADDER_SUM3 , LMK_LADDER_PART_SUM , LMK_CARRY_LOW , LMK_CARRY_CROSS_SUM , LMK_CARRY_LOW_SUM } |
| enum | long_mul_extract { LMX_NONE , LMX_HI , LMX_LO , LMX_SHL_N } |
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 ) |
Referenced by simplify_builtin_call().
| #define CPD_ITERATIONS 5 |
Referenced by constant_pointer_difference().
| typedef struct _vec_perm_simplify_seq* vec_perm_simplify_seq |
| enum long_mul_extract |
| enum long_mul_kind |
|
static |
References process_vec_perm_simplify_seq_list().
|
static |
Blend the two given simplifiable vec permute sequences using the given permutations.
References 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 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_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 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 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 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 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 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 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 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_array(), check_table_string(), TREE_CODE, and TYPE_PRECISION.
Referenced by simplify_count_zeroes().
|
static |
Check whether an array contains a valid table according to VALIDATE_FN.
References 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().
|
static |
Check whether a string contains a valid table according to VALIDATE_FN.
References i, TREE_STRING_LENGTH, and TREE_STRING_POINTER.
Referenced by check_table().
|
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(), 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 forward_propagate_into_comparison_1().
For pointers p2 and p1 return p2 - p1 if the difference is known and constant, otherwise return NULL.
References 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 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(), 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 match_long_mul().
|
static |
Replace STMT with a low-part multiply of OP1 and OP2, combining any EXTRAS back on top under OUTER.
References 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 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(), 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 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, 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().
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_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_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(), 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().
|
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_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().
|
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, 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(), 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(), 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().
|
static |
Invalidate the lattice entry for NAME, done when releasing SSA names.
References lattice, NULL_TREE, SSA_NAME_VERSION, and TREE_CODE.
Referenced by forward_propagate_addr_expr(), remove_prop_source_from_use(), and simplify_builtin_memcpy_memset().
Set the lattice entry for NAME to VAL.
References lattice, maybe_duplicate_ssa_info_at_copy(), num_ssa_names, SSA_NAME_VERSION, and TREE_CODE.
Primitive "lattice" function for gimple_simplify.
References lattice, SSA_NAME_VERSION, and TREE_CODE.
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_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 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 gimple_assign_rhs1(), gimple_assign_rhs_code(), has_single_use(), is_gimple_assign(), NULL, single_use(), and SSA_NAME_DEF_STMT.
Referenced by forward_propagate_into_comparison_1(), get_bit_field_ref_def(), and simplify_permutation().
Referenced by simplify_count_zeroes().
Referenced by 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. The two names split the gcond polarity: cond_carry_add matches when the true edge selects (base + pow2), cond_carry_add_neg when the true edge selects base.
Referenced by match_long_mul_phi().
Referenced by match_long_mul_phi().
Match.pd function to match the ctz expression.
Referenced by simplify_count_zeroes().
Referenced by long_mul_classify_carry().
Referenced by long_mul_classify_carry().
Referenced by long_mul_classify_carry().
Match.pd functions to match long multiplication.
Referenced by long_mul_classify_summand().
Referenced by long_mul_classify_bare().
Referenced by long_mul_classify_hi_extract(), long_mul_hilo_orientation(), and long_mul_is_cross_half().
Referenced by long_mul_classify_hi_extract().
Referenced by long_mul_classify_plus_kinds().
Referenced by long_mul_classify_plus_kinds().
Referenced by long_mul_classify_plus_kinds().
Referenced by long_mul_classify_summand().
Referenced by long_mul_check_two_carries(), long_mul_classify_bare(), and long_mul_classify_lo_extract().
Referenced by long_mul_classify_plus_kinds().
Referenced by long_mul_classify_plus_kinds(), 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, 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 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, last, _vec_perm_simplify_seq::stmt, and TREE_TYPE.
Referenced by create_mul_high_seq(), and create_mul_low_seq().
|
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.
Referenced by 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, LMK_MUL_HILO, LMX_HI, LMX_SHL_N, long_mul_canonical_ops(), long_mul_hilo_orientation(), long_mul_is_cross_half(), long_mul_same_ops(), NULL_TREE, TREE_TYPE, and TYPE_PRECISION.
Referenced by long_mul_classify_match().
|
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(), and NULL_TREE.
|
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 long_mul_summand::carry_a, long_mul_summand::carry_b, gimple_mul_cross_sum(), gimple_mul_lolo(), i, LMK_CARRY_LOW, long_mul_canonical_ops(), long_mul_find_summand(), long_mul_is_cross_half(), long_mul_is_lshift_def(), LONG_MUL_MAX_CAPTURES, long_mul_same_ops(), NULL, scratch, shift, TREE_TYPE, and TYPE_PRECISION.
|
static |
Classify LEAF as one of the bare-kind summands (no extraction wrapper): mul_hihi or mul_lolo standing on their own.
References gimple_mul_hihi(), gimple_mul_lolo(), LMK_MUL_HIHI, LMK_MUL_LOLO, LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), and NULL.
Referenced by long_mul_classify_summand().
|
static |
Classify LEAF as a carry-kind summand. The lshift amount is baked into mul_carry_cross_sum / mul_carry_low_sum, so they're tried before any branch that looks for a generic (X >> N) or (X << N) wrapper.
References gimple_mul_carry_cross_sum(), gimple_mul_carry_low(), gimple_mul_carry_low_sum(), LMK_CARRY_CROSS_SUM, LMK_CARRY_LOW, LMK_CARRY_LOW_SUM, LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), and NULL.
Referenced by long_mul_classify_summand().
|
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 candidate(), long_mul_classify_match(), long_mul_classify_summand(), 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 match_long_mul(), and match_long_mul_phi().
|
static |
Classify INNER -- already unwrapped from an outer (X >> SHIFT) -- as a high-half-extracted summand. mul_hilo (mult-shape) is orthogonal to the plus-based kinds and is tried first; ladder_part_sum (one arm unconstrained) and mul_cross_sum (any plus) are the fallbacks after the shared plus-based ladder.
References long_mul_summand::extract, gimple_mul_cross_sum(), gimple_mul_hilo(), gimple_mul_ladder_part_sum(), LMK_CROSS_SUM, LMK_LADDER_PART_SUM, LMK_MUL_HILO, LMX_HI, long_mul_classify_plus_kinds(), LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), NULL, long_mul_summand::shift, and shift.
Referenced by long_mul_classify_summand().
|
static |
Classify INNER -- already unwrapped from an outer (X & MASK) -- as a low-half-masked summand.
References long_mul_summand::extract, gimple_mul_lolo(), LMK_MUL_LOLO, LMX_LO, LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), and NULL.
Referenced by long_mul_classify_summand().
|
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_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().
|
static |
Plus-based summand kinds shared by the (X >> SHIFT) and (X << SHIFT) classifiers. Order is by specificity: mul_low_sum's first arm is any plus, so mul_ladder_sum1/3 (which constrain that arm to a plus containing a mul_lo) and mul_low_accum (which constrains both arms) shadow it and must come first.
References gimple_mul_ladder_sum1(), gimple_mul_ladder_sum2(), gimple_mul_ladder_sum3(), gimple_mul_low_accum(), gimple_mul_low_sum(), LMK_LADDER_SUM1, LMK_LADDER_SUM2, LMK_LADDER_SUM3, LMK_LOW_ACCUM, LMK_LOW_SUM, LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), and NULL.
Referenced by long_mul_classify_hi_extract(), and long_mul_classify_shl_extract().
|
static |
Classify INNER -- already unwrapped from an outer (X << SHIFT) -- as a left-shifted summand. No mul_hilo / ladder_part_sum here -- those shapes appear only under (X >> SHIFT).
References long_mul_summand::extract, gimple_mul_cross_sum(), LMK_CROSS_SUM, LMX_SHL_N, long_mul_classify_plus_kinds(), LONG_MUL_MAX_CAPTURES, long_mul_set_summand(), NULL, long_mul_summand::shift, and shift.
Referenced by long_mul_classify_summand().
|
static |
Classify LEAF as one of the long-multiply summand shapes. On success, fill *INFO with the kind, extract, captured operands and shift. Dispatches to per-extract helpers; the order matters because the carry kinds bake an lshift into the pattern and would otherwise be misread by the (X << N) branch.
References gimple_mul_hi(), gimple_mul_lo(), long_mul_classify_bare(), long_mul_classify_carry(), long_mul_classify_hi_extract(), long_mul_classify_lo_extract(), long_mul_classify_shl_extract(), long_mul_is_lshift_def(), LONG_MUL_MAX_CAPTURES, NULL, shift, and tree_to_uhwi().
Referenced by long_mul_classify_chain().
|
static |
Return the first summand in SUMMANDS whose kind matches KIND, or NULL.
References NULL.
Referenced by long_mul_check_two_carries().
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_MAX_CAPTURES, NULL, and scratch.
Referenced by long_mul_check_consistency().
|
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, print_gimple_stmt(), TDF_DETAILS, and TDF_SLIM.
Referenced by long_mul_classify_chain().
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_MAX_CAPTURES, long_mul_same_ops(), NULL, and scratch.
Referenced by long_mul_check_consistency(), and long_mul_check_two_carries().
|
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(), SSA_NAME_DEF_STMT, TREE_CODE, tree_fits_uhwi_p(), and tree_to_uhwi().
Referenced by long_mul_check_two_carries(), and long_mul_classify_summand().
|
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_MAX_EXTRAS, LONG_MUL_MAX_SUMMANDS, NULL, SSA_NAME_DEF_STMT, and TREE_CODE.
Referenced by long_mul_classify_chain().
True if (A, B) is the same pair as (OP0, OP1) in either order.
Referenced by long_mul_check_consistency(), long_mul_check_two_carries(), and long_mul_is_cross_half().
|
static |
Fill INFO's kind plus the captures from RES_OPS that the kind requires. The kind itself determines how many (op0, op1) and hilo captures to pick up from RES_OPS, and whether a baked-in shift is present.
References long_mul_summand::carry_a, long_mul_summand::carry_b, long_mul_summand::hilo0, long_mul_summand::hilo1, long_mul_summand::hilo2, long_mul_summand::kind, LMK_CARRY_CROSS_SUM, LMK_CARRY_LOW, LMK_CARRY_LOW_SUM, LMK_CROSS_SUM, LMK_LADDER_PART_SUM, LMK_LADDER_SUM1, LMK_LADDER_SUM2, LMK_LADDER_SUM3, LMK_LOW_ACCUM, LMK_LOW_SUM, LMK_MUL_HIHI, LMK_MUL_HILO, LMK_MUL_LOLO, long_mul_summand::op0, long_mul_summand::op1, long_mul_summand::shift, and tree_to_uhwi().
Referenced by long_mul_classify_bare(), long_mul_classify_carry(), long_mul_classify_hi_extract(), long_mul_classify_lo_extract(), long_mul_classify_plus_kinds(), and long_mul_classify_shl_extract().
|
static |
Compare the (already-sorted) SUMMANDS multiset against ROW.sig.
References long_mul_row::count, long_mul_row::extract, i, long_mul_row::kind, and long_mul_row::sig.
Referenced by long_mul_classify_match().
|
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, long_mul_summand::extract, and long_mul_summand::kind.
Referenced by long_mul_classify_chain().
| gimple_opt_pass * make_pass_forwprop | ( | gcc::context * | ctxt | ) |
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(), NULL, long_mul_row::part, single_imm_use(), TDF_DETAILS, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.
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(), long_mul_summand::carry_a, long_mul_summand::carry_b, dump_file, dump_flags, wi::exact_log2(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_bb(), gimple_cond_carry_add(), gimple_cond_carry_add_neg(), 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, long_mul_summand::hilo0, long_mul_summand::hilo1, long_mul_summand::hilo2, INTEGRAL_TYPE_P, is_gimple_assign(), long_mul_summand::kind, LMK_CARRY_CROSS_SUM, LMK_CARRY_LOW, LMK_CARRY_LOW_SUM, long_mul_classify_chain(), LONG_MUL_MAX_CAPTURES, NULL, long_mul_summand::op0, long_mul_summand::op1, long_mul_row::part, remove_phi_node(), long_mul_summand::shift, SSA_NAME_DEF_STMT, TDF_DETAILS, wi::to_wide(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, and TYPE_UNSIGNED.
|
static |
Reduce the lane consumption of a simplifiable vec perm sequence.
References dump_file, dump_flags, gimple_assign_set_rhs3(), _vec_perm_simplify_seq::new_sel, print_gimple_stmt(), _vec_perm_simplify_seq::stmt, TDF_DETAILS, and update_stmt().
Referenced by 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, NULL_TREE, operand_equal_p(), split_core_and_offset_size(), TREE_CODE, and TREE_TYPE.
Referenced by 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_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, TYPE_SIZE_UNIT, and worklist.
Referenced by 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(), 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().
|
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_1(), optimize_agr_copyprop_arg(), optimize_agr_copyprop_return(), same_for_assignment(), _vec_perm_simplify_seq::stmt, and stmt_could_throw_p().
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(), 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().
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 changed, dump_file, dump_flags, gimple_call_arg_ptr(), gimple_call_num_args(), is_gimple_min_invariant(), new_src_based_on_copy(), print_gimple_stmt(), TDF_DETAILS, TREE_CODE, TREE_TYPE, TYPE_VOLATILE, unshare_expr(), and update_stmt().
Referenced by optimize_agr_copyprop().
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(), 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().
|
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, 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 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, ptr_type_node, TREE_TYPE, and use_in_zero_equality().
Referenced by 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(), 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, VECTOR_TYPE_P, and worklist.
|
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(), TREE_CODE, TREE_OPERAND, TREE_TYPE, and unshare_expr().
Referenced by optimize_vector_load().
|
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(), and TDF_DETAILS.
Referenced by append_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(), 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.
|
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(), 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(), 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, and _vec_perm_simplify_seq::stmt.
Referenced by forward_propagate_into_comparison_1().
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(), split_core_and_offset_size(), and TREE_TYPE.
Referenced by optimize_agr_copyprop(), and optimize_agr_copyprop_1().
|
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_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().
|
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(), _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().
|
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, _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().
|
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(), 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().
|
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, _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_OPERAND, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, TYPE_SIZE, and TYPE_UNSIGNED.
|
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, edges_to_remove, 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_label_vec(), SSA_NAME_DEF_STMT, SSA_NAME_VERSION, _vec_perm_simplify_seq::stmt, TREE_CODE, TREE_TYPE, TYPE_PRECISION, and update_stmt().
|
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, edges_to_remove, 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(), and _vec_perm_simplify_seq::stmt.
Referenced by simplify_gimple_switch().
|
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(), 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.
|
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(), 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().
|
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, 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(), 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.
|
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, STRIP_NOPS, wi::to_poly_offset(), poly_int< N, C >::to_shwi(), TREE_CODE, and TREE_OPERAND.
Referenced by new_src_based_on_copy(), and same_for_assignment().
|
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, to_purge, and TREE_CODE.
Referenced by forward_propagate_addr_expr_1().
|
static |
Set to true if we delete dead edges during the optimization.
Referenced by execute_cse_conv_1(), execute_cse_sincos_1(), expand_vector_operations(), gimple_expand_vec_set_extract_expr(), instrument_memory_accesses(), ipcp_transform_function(), match_arith_overflow(), maybe_optimize_guarding_check(), ipa_param_body_adjustments::modify_cfun_body(), ipa_param_body_adjustments::perform_cfun_body_modifications(), reload_cse_regs_1(), sra_modify_function_body(), tail_merge_optimize(), and tsan_pass().
Const-and-copy lattice.
Referenced by fwprop_invalidate_lattice(), fwprop_set_lattice_val(), fwprop_ssa_val(), get_component_ssa_name(), reorder_operands(), and set_component_ssa_name().
|
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_classify_bare(), long_mul_classify_carry(), long_mul_classify_hi_extract(), long_mul_classify_lo_extract(), long_mul_classify_plus_kinds(), long_mul_classify_shl_extract(), long_mul_classify_summand(), 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().