GCC Middle and Back End API Reference
tree-ssa-loop-unswitch.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple.h"
#include "tree-pass.h"
#include "ssa.h"
#include "fold-const.h"
#include "tree-cfg.h"
#include "tree-ssa.h"
#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop.h"
#include "tree-into-ssa.h"
#include "cfgloop.h"
#include "tree-inline.h"
#include "gimple-iterator.h"
#include "cfghooks.h"
#include "tree-ssa-loop-manip.h"
#include "tree-vectorizer.h"
#include "gimple-range.h"
#include "dbgcnt.h"
#include "cfganal.h"
#include "tree-cfgcleanup.h"
Include dependency graph for tree-ssa-loop-unswitch.cc:

Data Structures

struct  unswitch_predicate

Typedefs

typedef vec< std::pair< unswitch_predicate *, bool > > predicate_vector

Functions

static class loop * tree_unswitch_loop (class loop *, edge, tree)
static bool tree_unswitch_single_loop (class loop *, dump_user_location_t, predicate_vector &predicate_path, unsigned loop_size, unsigned &budget, int ignored_edge_flag, bitmap, unswitch_predicate *=NULL, basic_block=NULL)
static void find_unswitching_predicates_for_bb (basic_block bb, class loop *loop, class loop *&outer_loop, vec< unswitch_predicate * > &candidates, unswitch_predicate *&hottest, basic_block &hottest_bb)
static bool tree_unswitch_outer_loop (class loop *)
static edge find_loop_guard (class loop *, vec< gimple * > &)
static bool empty_bb_without_guard_p (class loop *, basic_block, vec< gimple * > &)
static bool used_outside_loop_p (class loop *, tree, vec< gimple * > &)
static void hoist_guard (class loop *, edge)
static bool check_exit_phi (class loop *)
static tree get_vop_from_header (class loop *)
static void clean_up_after_unswitching (int)
static vec< unswitch_predicate * > & get_predicates_for_bb (basic_block bb)
static void set_predicates_for_bb (basic_block bb, vec< unswitch_predicate * > predicates)
static unsigned estimate_loop_insns (class loop *loop)
static unsigned init_loop_unswitch_info (class loop *&loop, unswitch_predicate *&hottest, basic_block &hottest_bb)
unsigned int tree_ssa_unswitch_loops (function *fun)
static bool is_maybe_undefined (const tree name, gimple *stmt, class loop *loop)
static void merge_last (predicate_vector &predicate_path)
static void add_predicate_to_path (predicate_vector &predicate_path, unswitch_predicate *predicate, bool true_edge)
static bool find_range_for_lhs (predicate_vector &predicate_path, tree lhs, int_range_max &range)
static tree evaluate_control_stmt_using_entry_checks (gimple *stmt, predicate_vector &predicate_path, int ignored_edge_flag, hash_set< edge > *ignored_edges)
static bool simplify_loop_version (class loop *loop, predicate_vector &predicate_path, int ignored_edge_flag, bitmap handled)
template<typename VisitOp>
static void evaluate_bbs (class loop *loop, predicate_vector *predicate_path, int ignored_edge_flag, VisitOp visit)
static void evaluate_loop_insns_for_predicate (class loop *loop, predicate_vector &predicate_path, unswitch_predicate *predicate, int ignored_edge_flag, unsigned *true_size, unsigned *false_size)
gimple_opt_pass * make_pass_tree_unswitch (gcc::context *ctxt)

Variables

static gimple_ranger * ranger = NULL
static vec< vec< unswitch_predicate * > > * bb_predicates

Typedef Documentation

◆ predicate_vector

typedef vec<std::pair<unswitch_predicate *, bool> > predicate_vector
The type represents a predicate path leading to a basic block.   

Function Documentation

◆ add_predicate_to_path()

void add_predicate_to_path ( predicate_vector & predicate_path,
unswitch_predicate * predicate,
bool true_edge )
static
Add PREDICATE to PREDICATE_PATH on TRUE_EDGE.   

References add_predicate_to_path(), and merge_last().

Referenced by add_predicate_to_path(), evaluate_loop_insns_for_predicate(), and tree_unswitch_single_loop().

◆ check_exit_phi()

◆ clean_up_after_unswitching()

◆ empty_bb_without_guard_p()

bool empty_bb_without_guard_p ( class loop * loop,
basic_block bb,
vec< gimple * > & dbg_to_reset )
static
Returns true if
1) no statement in BB has side effects
2) assuming that edge GUARD is always taken, all definitions in BB
   are noy used outside of the loop.
KNOWN_INVARIANTS is a set of ssa names we know to be invariant, and
PROCESSED is a set of ssa names for that we already tested whether they
are invariant or not.  Uses in debug stmts outside of the loop are
pushed to DBG_TO_RESET.   

References CDI_DOMINATORS, dominated_by_p(), empty_bb_without_guard_p(), FOR_EACH_SSA_TREE_OPERAND, gimple_has_side_effects(), gimple_vdef(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), is_gimple_debug(), PHI_RESULT, single_exit(), SSA_OP_DEF, used_outside_loop_p(), and virtual_operand_p().

Referenced by empty_bb_without_guard_p(), and find_loop_guard().

◆ estimate_loop_insns()

unsigned estimate_loop_insns ( class loop * loop)
static
Estimate number of instructions in LOOP using eni_size_weights.   

References eni_size_weights, estimate_loop_insns(), estimate_num_insns(), free(), get_loop_body(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), i, and loop::num_nodes.

Referenced by estimate_loop_insns(), and init_loop_unswitch_info().

◆ evaluate_bbs()

template<typename VisitOp>
void evaluate_bbs ( class loop * loop,
predicate_vector * predicate_path,
int ignored_edge_flag,
VisitOp visit )
static
Evaluate reachable blocks in LOOP and call VISIT on them, aborting the
DFS walk if VISIT returns true.  When PREDICATE_PATH is specified then
take into account that when computing reachability, otherwise just
look at the simplified state and IGNORED_EDGE_FLAG.   

References cfun, hash_set< KeyId, Lazy, Traits >::contains(), evaluate_bbs(), evaluate_control_stmt_using_entry_checks(), basic_block_def::flags, flow_bb_inside_loop_p(), FOR_EACH_EDGE, get_predicates_for_bb(), gimple_cond_false_p(), gimple_cond_true_p(), gsi_last_bb(), loop::header, integer_nonzerop(), loop::num_nodes, safe_dyn_cast(), basic_block_def::succs, and visit.

Referenced by evaluate_bbs(), evaluate_loop_insns_for_predicate(), and tree_unswitch_single_loop().

◆ evaluate_control_stmt_using_entry_checks()

◆ evaluate_loop_insns_for_predicate()

void evaluate_loop_insns_for_predicate ( class loop * loop,
predicate_vector & predicate_path,
unswitch_predicate * predicate,
int ignored_edge_flag,
unsigned * true_size,
unsigned * false_size )
static
Evaluate how many instruction will we have if we unswitch LOOP (with BBS)
based on PREDICATE predicate (using PREDICATE_PATH).  Store the
result in TRUE_SIZE and FALSE_SIZE.   

References add_predicate_to_path(), evaluate_bbs(), and evaluate_loop_insns_for_predicate().

Referenced by evaluate_loop_insns_for_predicate(), and tree_unswitch_single_loop().

◆ find_loop_guard()

◆ find_range_for_lhs()

bool find_range_for_lhs ( predicate_vector & predicate_path,
tree lhs,
int_range_max & range )
static

◆ find_unswitching_predicates_for_bb()

void find_unswitching_predicates_for_bb ( basic_block bb,
class loop * loop,
class loop *& outer_loop,
vec< unswitch_predicate * > & candidates,
unswitch_predicate *& hottest,
basic_block & hottest_bb )
static

◆ get_predicates_for_bb()

vec< unswitch_predicate * > & get_predicates_for_bb ( basic_block bb)
static
Return vector of predicates that belong to a basic block.   

References bb_predicates, get_predicates_for_bb(), gimple_uid(), last_nondebug_stmt(), and NULL.

Referenced by evaluate_bbs(), get_predicates_for_bb(), simplify_loop_version(), and tree_unswitch_single_loop().

◆ get_vop_from_header()

tree get_vop_from_header ( class loop * loop)
static

◆ hoist_guard()

◆ init_loop_unswitch_info()

unsigned init_loop_unswitch_info ( class loop *& loop,
unswitch_predicate *& hottest,
basic_block & hottest_bb )
static

◆ is_maybe_undefined()

bool is_maybe_undefined ( const tree name,
gimple * stmt,
class loop * loop )
static
Return TRUE if an SSA_NAME maybe undefined and is therefore
unsuitable for unswitching.  STMT is the statement we are
considering for unswitching and LOOP is the loop it appears in.   

References gimple_bb(), loop::header, is_maybe_undefined(), and ssa_name_maybe_undef_p().

Referenced by find_unswitching_predicates_for_bb(), and is_maybe_undefined().

◆ make_pass_tree_unswitch()

gimple_opt_pass * make_pass_tree_unswitch ( gcc::context * ctxt)

◆ merge_last()

void merge_last ( predicate_vector & predicate_path)
static
Merge ranges for the last item of PREDICATE_PATH with a predicate
that shared the same LHS.   

References i, irange::intersect(), unswitch_predicate::lhs, merge_last(), unswitch_predicate::merged_false_range, unswitch_predicate::merged_true_range, and operand_equal_p().

Referenced by add_predicate_to_path(), and merge_last().

◆ set_predicates_for_bb()

void set_predicates_for_bb ( basic_block bb,
vec< unswitch_predicate * > predicates )
static
Save predicates that belong to a basic block.   

References bb_predicates, gimple_set_uid(), last_nondebug_stmt(), and set_predicates_for_bb().

Referenced by init_loop_unswitch_info(), and set_predicates_for_bb().

◆ simplify_loop_version()

◆ tree_ssa_unswitch_loops()

◆ tree_unswitch_loop()

class loop * tree_unswitch_loop ( class loop * loop,
edge edge_true,
tree cond )
static
Unswitch a LOOP w.r. to given EDGE_TRUE.  We only support unswitching of
innermost loops.  COND is the condition determining which loop is entered;
the new loop is entered if COND is true.  Returns NULL if impossible, new
loop otherwise.   

References EDGE_COUNT, flow_bb_inside_loop_p(), gcc_assert, profile_probability::invert(), loop_version(), NULL, tree_unswitch_loop(), and unshare_expr().

Referenced by tree_unswitch_loop(), and tree_unswitch_single_loop().

◆ tree_unswitch_outer_loop()

◆ tree_unswitch_single_loop()

bool tree_unswitch_single_loop ( class loop * loop,
dump_user_location_t loc,
predicate_vector & predicate_path,
unsigned loop_size,
unsigned & budget,
int ignored_edge_flag,
bitmap handled,
unswitch_predicate * hottest,
basic_block hottest_bb )
static

◆ used_outside_loop_p()

bool used_outside_loop_p ( class loop * loop,
tree name,
vec< gimple * > & dbg_to_reset )
static
Return true if NAME is used outside of LOOP.  Pushes debug stmts that
have such uses to DBG_TO_RESET but do not consider such uses.   

References flow_bb_inside_loop_p(), FOR_EACH_IMM_USE_FAST, gimple_bb(), is_gimple_debug(), USE_STMT, and used_outside_loop_p().

Referenced by empty_bb_without_guard_p(), and used_outside_loop_p().

Variable Documentation

◆ bb_predicates

vec<vec<unswitch_predicate *> >* bb_predicates
static
Cache storage for unswitch_predicate belonging to a basic block.   

Referenced by get_predicates_for_bb(), set_predicates_for_bb(), and tree_ssa_unswitch_loops().

◆ ranger

gimple_ranger* ranger = NULL
static
Ranger instance used in the pass.   

Referenced by evaluate_control_stmt_using_entry_checks(), and tree_ssa_unswitch_loops().