GCC Middle and Back End API Reference
tree-ssa-ifcombine.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 "memmodel.h"
#include "tm_p.h"
#include "ssa.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
#include "cfganal.h"
#include "gimple-iterator.h"
#include "gimple-fold.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "tree-ssa.h"
#include "attribs.h"
#include "asan.h"
Include dependency graph for tree-ssa-ifcombine.cc:

Macros

#define LOGICAL_OP_NON_SHORT_CIRCUIT
 

Functions

static bool recognize_if_then_else (basic_block cond_bb, basic_block *then_bb, basic_block *else_bb)
 
static bool bb_no_side_effects_p (basic_block bb)
 
static bool forwarder_block_to (basic_block bb, basic_block to_bb)
 
static bool same_phi_args_p (basic_block bb1, basic_block bb2, basic_block dest)
 
static tree get_name_for_bit_test (tree candidate)
 
static bool recognize_single_bit_test (gcond *cond, tree *name, tree *bit, bool inv)
 
static bool recognize_bits_test (gcond *cond, tree *name, tree *bits, bool inv)
 
static void update_profile_after_ifcombine (basic_block inner_cond_bb, basic_block outer_cond_bb)
 
static bool ifcombine_ifandif (basic_block inner_cond_bb, bool inner_inv, basic_block outer_cond_bb, bool outer_inv, bool result_inv)
 
static bool tree_ssa_ifcombine_bb_1 (basic_block inner_cond_bb, basic_block outer_cond_bb, basic_block then_bb, basic_block else_bb, basic_block phi_pred_bb)
 
static bool tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
 
gimple_opt_passmake_pass_tree_ifcombine (gcc::context *ctxt)
 

Macro Definition Documentation

◆ LOGICAL_OP_NON_SHORT_CIRCUIT

#define LOGICAL_OP_NON_SHORT_CIRCUIT
Value:
false) >= 2)
#define cfun
Definition function.h:475
T * ggc_alloc(ALONE_CXX_MEM_STAT_INFO)
Definition ggc.h:184
bool optimize_function_for_speed_p(struct function *fun)
Definition predict.cc:278
Combining of if-expressions on trees.
   Copyright (C) 2007-2024 Free Software Foundation, Inc.
   Contributed by Richard Guenther <rguenther@suse.de>

This file is part of GCC.

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

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
rtl is needed only because arm back-end requires it for
BRANCH_COST.   

Referenced by ifcombine_ifandif().

Function Documentation

◆ bb_no_side_effects_p()

◆ forwarder_block_to()

static bool forwarder_block_to ( basic_block bb,
basic_block to_bb )
static
Return true if BB is an empty forwarder block to TO_BB.   

References empty_block_p(), ggc_alloc(), single_succ(), and single_succ_p().

Referenced by tree_ssa_ifcombine_bb().

◆ get_name_for_bit_test()

static tree get_name_for_bit_test ( tree candidate)
static

◆ ifcombine_ifandif()

◆ make_pass_tree_ifcombine()

gimple_opt_pass * make_pass_tree_ifcombine ( gcc::context * ctxt)

References ggc_alloc().

◆ recognize_bits_test()

static bool recognize_bits_test ( gcond * cond,
tree * name,
tree * bits,
bool inv )
static
Recognize a bit test pattern in a GIMPLE_COND and its defining
statements.  Store the name being tested in *NAME and the bits
in *BITS.  The COND_EXPR computes *NAME & *BITS.
Returns true if the pattern matched, false otherwise.   

References get_name_for_bit_test(), ggc_alloc(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), integer_zerop(), is_gimple_assign(), SSA_NAME_DEF_STMT, and TREE_CODE.

Referenced by ifcombine_ifandif().

◆ recognize_if_then_else()

static bool recognize_if_then_else ( basic_block cond_bb,
basic_block * then_bb,
basic_block * else_bb )
static
This pass combines COND_EXPRs to simplify control flow.  It
currently recognizes bit tests and comparisons in chains that
represent logical and or logical or of two COND_EXPRs.

It does so by walking basic blocks in a approximate reverse
post-dominator order and trying to match CFG patterns that
represent logical and or logical or of two COND_EXPRs.
Transformations are done if the COND_EXPR conditions match
either

  1. two single bit tests X & (1 << Yn) (for logical and)

  2. two bit tests X & Yn (for logical or)

  3. two comparisons X OPn Y (for logical or)

To simplify this pass, removing basic blocks and dead code
is left to CFG cleanup and DCE.   
Recognize a if-then-else CFG pattern starting to match with the
COND_BB basic-block containing the COND_EXPR.  The recognized
then end else blocks are stored to *THEN_BB and *ELSE_BB.  If
*THEN_BB and/or *ELSE_BB are already set, they are required to
match the then and else basic-blocks to make the pattern match.
Returns true if the pattern matched, false otherwise.   

References EDGE_COUNT, EDGE_SUCC, and ggc_alloc().

Referenced by tree_ssa_ifcombine_bb(), and tree_ssa_ifcombine_bb_1().

◆ recognize_single_bit_test()

static bool recognize_single_bit_test ( gcond * cond,
tree * name,
tree * bit,
bool inv )
static
Recognize a single bit test pattern in GIMPLE_COND and its defining
statements.  Store the name being tested in *NAME and the bit
in *BIT.  The GIMPLE_COND computes *NAME & (1 << *BIT).
Returns true if the pattern matched, false otherwise.   

References build_int_cst(), CONVERT_EXPR_CODE_P, get_name_for_bit_test(), ggc_alloc(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_ssa_name_copy_p(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), integer_onep(), integer_pow2p(), integer_type_node, integer_zero_node, integer_zerop(), is_gimple_assign(), SSA_NAME_DEF_STMT, TREE_CODE, tree_log2(), TREE_TYPE, and TYPE_PRECISION.

Referenced by ifcombine_ifandif().

◆ same_phi_args_p()

static bool same_phi_args_p ( basic_block bb1,
basic_block bb2,
basic_block dest )
static
Verify if all PHI node arguments in DEST for edges from BB1 or
BB2 to DEST are the same.  This makes the CFG merge point
free from side-effects.  Return true in this case, else false.   

References find_edge(), ggc_alloc(), gsi_end_p(), gsi_next(), gsi_start_phis(), operand_equal_p(), gphi_iterator::phi(), and PHI_ARG_DEF_FROM_EDGE.

Referenced by tree_ssa_ifcombine_bb_1().

◆ tree_ssa_ifcombine_bb()

static bool tree_ssa_ifcombine_bb ( basic_block inner_cond_bb)
static
Recognize a CFG pattern and dispatch to the appropriate
if-conversion helper.  We start with BB as the innermost
worker basic-block.  Returns true if a transformation was done.   

References bb_no_side_effects_p(), forwarder_block_to(), ggc_alloc(), NULL, recognize_if_then_else(), single_pred(), single_pred_p(), and tree_ssa_ifcombine_bb_1().

◆ tree_ssa_ifcombine_bb_1()

static bool tree_ssa_ifcombine_bb_1 ( basic_block inner_cond_bb,
basic_block outer_cond_bb,
basic_block then_bb,
basic_block else_bb,
basic_block phi_pred_bb )
static
Helper function for tree_ssa_ifcombine_bb.  Recognize a CFG pattern and
dispatch to the appropriate if-conversion helper for a particular
set of INNER_COND_BB, OUTER_COND_BB, THEN_BB and ELSE_BB.
PHI_PRED_BB should be one of INNER_COND_BB, THEN_BB or ELSE_BB.   

References ggc_alloc(), ifcombine_ifandif(), recognize_if_then_else(), and same_phi_args_p().

Referenced by tree_ssa_ifcombine_bb().

◆ update_profile_after_ifcombine()

static void update_profile_after_ifcombine ( basic_block inner_cond_bb,
basic_block outer_cond_bb )
static
Update profile after code in outer_cond_bb was adjusted so
outer_cond_bb has no condition.   

References profile_probability::always(), EDGE_SUCC, find_edge(), gcc_assert, ggc_alloc(), profile_probability::never(), and single_pred_p().

Referenced by ifcombine_ifandif().