GCC Middle and Back End API Reference
tree-ssa-forwprop.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "tree-pass.h"
#include "ssa.h"
#include "expmed.h"
#include "optabs-query.h"
#include "gimple-pretty-print.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "tree-eh.h"
#include "gimplify.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "expr.h"
#include "tree-dfa.h"
#include "tree-ssa-propagate.h"
#include "tree-ssa-dom.h"
#include "tree-ssa-strlen.h"
#include "builtins.h"
#include "tree-cfgcleanup.h"
#include "cfganal.h"
#include "optabs-tree.h"
#include "insn-config.h"
#include "recog.h"
#include "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 dependency graph for tree-ssa-forwprop.cc:


#define CPD_ITERATIONS   5


static bool forward_propagate_addr_expr (tree, tree, bool)
static tree rhs_to_tree (tree type, gimple *stmt)
static void fwprop_set_lattice_val (tree name, tree val)
static void fwprop_invalidate_lattice (tree name)
static gimpleget_prop_source_stmt (tree name, bool single_use_only, bool *single_use_p)
static bool can_propagate_from (gimple *def_stmt)
static bool remove_prop_source_from_use (tree name)
static tree combine_cond_expr_cond (gimple *stmt, enum tree_code code, tree type, tree op0, tree op1, bool invariant_only)
static tree forward_propagate_into_comparison_1 (gimple *stmt, enum tree_code code, tree type, tree op0, tree op1)
static int forward_propagate_into_comparison (gimple_stmt_iterator *gsi)
static int forward_propagate_into_gimple_cond (gcond *stmt)
static void tidy_after_forward_propagate_addr (gimple *stmt)
static bool forward_propagate_addr_expr_1 (tree name, tree def_rhs, gimple_stmt_iterator *use_stmt_gsi, bool single_use_p)
static void simplify_gimple_switch_label_vec (gswitch *stmt, tree index_type)
static bool simplify_gimple_switch (gswitch *stmt)
static tree constant_pointer_difference (tree p1, tree p2)
static bool simplify_builtin_call (gimple_stmt_iterator *gsi_p, tree callee2)
static void defcodefor_name (tree name, enum tree_code *code, tree *arg1, tree *arg2)
static bool simplify_rotate (gimple_stmt_iterator *gsi)
static bool check_ctz_array (tree ctor, unsigned HOST_WIDE_INT mulc, HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits)
static bool check_ctz_string (tree string, unsigned HOST_WIDE_INT mulc, HOST_WIDE_INT &zero_val, unsigned shift, unsigned bits)
static bool optimize_count_trailing_zeroes (tree array_ref, tree x, tree mulc, tree tshift, HOST_WIDE_INT &zero_val)
bool gimple_ctz_table_index (tree, tree *, tree(*)(tree))
static bool simplify_count_trailing_zeroes (gimple_stmt_iterator *gsi)
static bool simplify_bitfield_ref (gimple_stmt_iterator *gsi)
static int is_combined_permutation_identity (tree mask1, tree mask2)
static int simplify_permutation (gimple_stmt_iterator *gsi)
static tree get_bit_field_ref_def (tree val, enum tree_code &conv_code)
static bool simplify_vector_constructor (gimple_stmt_iterator *gsi)
static tree prepare_target_mem_ref_lvalue (tree ref, gimple_stmt_iterator *gsi)
static void optimize_vector_load (gimple_stmt_iterator *gsi)
static tree fwprop_ssa_val (tree name)
gimple_opt_passmake_pass_forwprop (gcc::context *ctxt)


static bool cfg_changed
static bitmap to_purge
static vec< treelattice

Macro Definition Documentation


OP )
case BUILT_IN_##NAME##_1: \
case BUILT_IN_##NAME##_2: \
case BUILT_IN_##NAME##_4: \
case BUILT_IN_##NAME##_8: \
case BUILT_IN_##NAME##_16: \
- BUILT_IN_##NAME##_1)); \
Definition genmatch.cc:354
Definition ggc.h:184
Definition tree-ssa-pre.cc:242
built_in_function DECL_FUNCTION_CODE(const_tree decl)
Definition tree.h:4318


#define CPD_ITERATIONS   5

Function Documentation

◆ can_propagate_from()

◆ check_ctz_array()

static bool check_ctz_array ( tree ctor,
unsigned HOST_WIDE_INT mulc,
HOST_WIDE_INT & zero_val,
unsigned shift,
unsigned bits )
Check whether an array contains a valid ctz table.   

References CONSTRUCTOR_ELTS, FOR_EACH_CONSTRUCTOR_ELT, ggc_alloc(), HOST_WIDE_INT_1U, i, shift, TREE_CODE, and tree_to_shwi().

Referenced by optimize_count_trailing_zeroes().

◆ check_ctz_string()

static bool check_ctz_string ( tree string,
unsigned HOST_WIDE_INT mulc,
HOST_WIDE_INT & zero_val,
unsigned shift,
unsigned bits )
Check whether a string contains a valid ctz table.   

References ggc_alloc(), HOST_WIDE_INT_1U, i, shift, TREE_STRING_LENGTH, and TREE_STRING_POINTER.

Referenced by optimize_count_trailing_zeroes().

◆ combine_cond_expr_cond()

static tree combine_cond_expr_cond ( gimple * stmt,
enum tree_code code,
tree type,
tree op0,
tree op1,
bool invariant_only )
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(), fold_defer_overflow_warnings(), fold_undefer_overflow_warnings(), gcc_assert, ggc_alloc(), gimple_location(), is_gimple_min_invariant(), NULL, NULL_TREE, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_TYPE, and warning_suppressed_p().

Referenced by forward_propagate_into_comparison_1().

◆ constant_pointer_difference()

◆ defcodefor_name()

static void defcodefor_name ( tree name,
enum tree_code * code,
tree * arg1,
tree * arg2 )
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(), ggc_alloc(), 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().

◆ forward_propagate_addr_expr()

static bool forward_propagate_addr_expr ( tree name,
tree rhs,
bool parent_single_use_p )
Forward propagation of expressions for single use variables.
   Copyright (C) 2004-2024 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
This pass propagates the RHS of assignment statements into use
 sites of the LHS of the assignment.  It's basically a specialized
 form of tree combination.   It is hoped all of this can disappear
 when we have a generalized tree combiner.

 One class of common cases we handle is forward propagating a single use
 variable into a COND_EXPR.

     x = a COND b;
     if (x) goto ... else goto ...

 Will be transformed into:

     if (a COND b) goto ... else goto ...

 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).

 Or (assuming c1 and c2 are constants):

     x = a + c1;
     if (x EQ/NEQ c2) goto ... else goto ...

 Will be transformed into:

      if (a EQ/NEQ (c2 - c1)) goto ... else goto ...

 Similarly for x = a - c1.


     x = !a
     if (x) goto ... else goto ...

 Will be transformed into:

      if (a == 0) goto ... else goto ...

 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
 For these cases, we propagate A into all, possibly more than one,
 COND_EXPRs that use X.


     x = (typecast) a
     if (x) goto ... else goto ...

 Will be transformed into:

      if (a != 0) goto ... else goto ...

 (Assuming a is an integral type and x is a boolean or x is an
  integral and a is a boolean.)

 Similarly for the tests (x == 0), (x != 0), (x == 1) and (x != 1).
 For these cases, we propagate A into all, possibly more than one,
 COND_EXPRs that use X.

 In addition to eliminating the variable and the statement which assigns
 a value to the variable, we may be able to later thread the jump without
 adding insane complexity in the dominator optimizer.

 Also note these transformations can cascade.  We handle this by having
 a worklist of COND_EXPR statements to examine.  As we make a change to
 a statement, we put it back on the worklist to examine on the next
 iteration of the main loop.

 A second class of propagation opportunities arises for ADDR_EXPR

   ptr = &x->y->z;
   res = *ptr;

 Will get turned into

   res = x->y->z;

   ptr = (type1*)&type2var;
   res = *ptr

 Will get turned into (if type1 and type2 are the same size
 and neither have volatile on them):
   res = VIEW_CONVERT_EXPR<type1>(type2var)


   ptr = &x[0];
   ptr2 = ptr + <constant>;

 Will get turned into

   ptr2 = &x[constant/elementsize];


   ptr = &x[0];
   offset = index * element_size;
   offset_p = (pointer) offset;
   ptr2 = ptr + offset_p

Will get turned into:

   ptr2 = &x[index];

  ssa = (int) decl
  res = ssa & 1

Provided that decl has known alignment >= 2, will get turned into

  res = 0

We also propagate casts into SWITCH_EXPR and COND_EXPR conditions to
allow us to remove the cast and {NOT_EXPR,NEG_EXPR} into a subsequent

 This will (of course) be extended as other needs arise.   
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 FOR_EACH_IMM_USE_STMT, forward_propagate_addr_expr_1(), fwprop_invalidate_lattice(), ggc_alloc(), 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().

◆ forward_propagate_addr_expr_1()

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

◆ forward_propagate_into_comparison()

static int forward_propagate_into_comparison ( gimple_stmt_iterator * gsi)
Propagate from the ssa name definition statements of the assignment
from a comparison at *GSI into the conditional if that simplifies it.
Returns 1 if the stmt was modified and 2 if the CFG needs cleanup,
otherwise returns 0.   

References cfg_changed, fold_stmt(), forward_propagate_into_comparison_1(), ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gsi_stmt(), remove_prop_source_from_use(), TREE_CODE, TREE_TYPE, update_stmt(), and useless_type_conversion_p().

◆ forward_propagate_into_comparison_1()

static tree forward_propagate_into_comparison_1 ( gimple * stmt,
enum tree_code code,
tree type,
tree op0,
tree op1 )
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(), ggc_alloc(), gimple_assign_rhs_code(), NULL_TREE, rhs_to_tree(), tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_OPERAND, and TREE_TYPE.

Referenced by forward_propagate_into_comparison(), and forward_propagate_into_gimple_cond().

◆ forward_propagate_into_gimple_cond()

static int forward_propagate_into_gimple_cond ( gcond * stmt)

◆ fwprop_invalidate_lattice()

static void fwprop_invalidate_lattice ( tree name)
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_call().

◆ fwprop_set_lattice_val()

static void fwprop_set_lattice_val ( tree name,
tree val )
Set the lattice entry for NAME to VAL.   

References lattice, num_ssa_names, SSA_NAME_VERSION, and TREE_CODE.

◆ fwprop_ssa_val()

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

References lattice, SSA_NAME_VERSION, and TREE_CODE.

◆ get_bit_field_ref_def()

static tree get_bit_field_ref_def ( tree val,
enum tree_code & conv_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(), ggc_alloc(), 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_prop_source_stmt()

static gimple * get_prop_source_stmt ( tree name,
bool single_use_only,
bool * single_use_p )
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 ggc_alloc(), 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(), simplify_bitfield_ref(), and simplify_permutation().

◆ gimple_ctz_table_index()

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

Referenced by simplify_count_trailing_zeroes().

◆ is_combined_permutation_identity()

static int is_combined_permutation_identity ( tree mask1,
tree mask2 )
Determine whether applying the 2 permutations (mask1 then mask2)
gives back one of the input.   

References fold_ternary, gcc_assert, gcc_checking_assert, ggc_alloc(), i, NULL_TREE, operand_equal_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().

◆ make_pass_forwprop()

gimple_opt_pass * make_pass_forwprop ( gcc::context * ctxt)

References ggc_alloc().

◆ optimize_count_trailing_zeroes()

static bool optimize_count_trailing_zeroes ( tree array_ref,
tree x,
tree mulc,
tree tshift,
HOST_WIDE_INT & zero_val )
Recognize count trailing zeroes idiom.
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(), CHAR_TYPE_SIZE, check_ctz_array(), check_ctz_string(), ctor_for_folding(), direct_internal_fn_supported_p(), gcc_assert, ggc_alloc(), integer_zerop(), OPTIMIZE_FOR_BOTH, TREE_CODE, TREE_OPERAND, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TYPE_PRECISION, TYPE_SIZE, and TYPE_UNSIGNED.

Referenced by simplify_count_trailing_zeroes().

◆ optimize_vector_load()

◆ prepare_target_mem_ref_lvalue()

static tree prepare_target_mem_ref_lvalue ( tree ref,
gimple_stmt_iterator * gsi )
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, ggc_alloc(), 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().

◆ remove_prop_source_from_use()

static bool remove_prop_source_from_use ( tree name)
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.
Returns true if cleanup-cfg has to run.   

References bitmap_set_bit, cfg_changed, fwprop_invalidate_lattice(), ggc_alloc(), 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, to_purge, TREE_CODE, and unlink_stmt_vdef().

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

◆ rhs_to_tree()

static tree rhs_to_tree ( tree type,
gimple * stmt )
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(), ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs3(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_location(), GIMPLE_SINGLE_RHS, GIMPLE_TERNARY_RHS, and GIMPLE_UNARY_RHS.

Referenced by forward_propagate_into_comparison_1().

◆ simplify_bitfield_ref()

◆ simplify_builtin_call()

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

memchr ("abcd", a, 4) == 0;
memchr ("abcd", a, 4) != 0;
(a == 'a' || a == 'b' || a == 'c' || a == 'd') == 0
(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, boolean_type_node, build2(), build_fold_addr_expr, build_int_cst(), build_string_literal(), build_zero_cst(), BUILT_IN_NORMAL, builtin_decl_explicit(), builtin_strncpy_read_str(), can_store_by_pieces(), CASE_ATOMIC, CHAR_BIT, char_type_node, compare_tree_int(), COMPARISON_CLASS_P, constant_pointer_difference(), DECL_FUNCTION_CODE(), END_BUILTINS, fndecl_built_in_p(), fold_build2_loc(), fold_convert, fold_convert_loc(), FOR_EACH_IMM_USE_STMT, force_gimple_operand_gsi(), fwprop_invalidate_lattice(), g, gcc_assert, gcc_checking_assert, gcc_unreachable, get_pointer_alignment(), ggc_alloc(), 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_assign_single_p(), gimple_bb(), GIMPLE_BINARY_RHS, gimple_build_assign(), 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_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gimple_debug_bind_reset_value(), gimple_get_lhs(), gimple_location(), gimple_vdef(), gimple_vuse(), gimplify_and_update_call_from_tree(), gsi_for_stmt(), gsi_insert_after(), GSI_NEW_STMT, gsi_remove(), gsi_replace(), GSI_SAME_STMT, gsi_stmt(), i, INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_call(), is_gimple_debug(), is_gimple_val(), make_ssa_name(), wi::neg(), NULL, NULL_TREE, operand_equal_p(), optimize_bb_for_speed_p(), 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, stmt_ends_bb_p(), string_constant(), STRIP_USELESS_TYPE_CONVERSION, wi::to_wide(), TREE_CODE, tree_fits_shwi_p(), tree_fits_uhwi_p(), tree_int_cst_lt(), TREE_OPERAND, TREE_STRING_LENGTH, TREE_STRING_POINTER, tree_to_shwi(), tree_to_uhwi(), TREE_TYPE, TYPE_MODE, TYPE_PRECISION, unlink_stmt_vdef(), update_stmt(), use_in_zero_equality(), and useless_type_conversion_p().

◆ simplify_count_trailing_zeroes()

◆ simplify_gimple_switch()

static bool simplify_gimple_switch ( gswitch * stmt)

◆ simplify_gimple_switch_label_vec()

◆ simplify_permutation()

◆ simplify_rotate()

static bool simplify_rotate ( gimple_stmt_iterator * gsi)
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
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(), ggc_alloc(), 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, 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(), and useless_type_conversion_p().

◆ simplify_vector_constructor()

◆ tidy_after_forward_propagate_addr()

static void tidy_after_forward_propagate_addr ( gimple * stmt)
We've just substituted an ADDR_EXPR into stmt.  Update all the
relevant data structures to match.   

References bitmap_set_bit, ggc_alloc(), gimple_assign_rhs1(), gimple_bb(), maybe_clean_or_replace_eh_stmt(), recompute_tree_invariant_for_addr_expr(), to_purge, and TREE_CODE.

Referenced by forward_propagate_addr_expr_1().

Variable Documentation

◆ cfg_changed

◆ lattice

◆ to_purge