GCC Middle and Back End API Reference
ipa-split.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 "alloc-pool.h"
#include "tree-pass.h"
#include "ssa.h"
#include "cgraph.h"
#include "diagnostic.h"
#include "fold-const.h"
#include "cfganal.h"
#include "calls.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "gimple-walk.h"
#include "symbol-summary.h"
#include "sreal.h"
#include "ipa-cp.h"
#include "ipa-prop.h"
#include "tree-cfg.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "tree-inline.h"
#include "gimple-pretty-print.h"
#include "ipa-fnsummary.h"
#include "cfgloop.h"
#include "attribs.h"
#include "ipa-strub.h"
Include dependency graph for ipa-split.cc:

Data Structures

class  split_bb_info
class  split_point
class  stack_entry


static tree find_retval (basic_block return_bb)
static bool test_nonssa_use (gimple *, tree t, tree, void *data)
static void dump_split_point (FILE *file, class split_point *current)
static bool verify_non_ssa_vars (class split_point *current, bitmap non_ssa_vars, basic_block return_bb)
static void check_forbidden_calls (gimple *stmt)
static bool dominated_by_forbidden (basic_block bb)
static bool split_part_set_ssa_name_p (tree val, class split_point *current, basic_block return_bb)
static void consider_split (class split_point *current, bitmap non_ssa_vars, basic_block return_bb)
static basic_block find_return_bb (void)
static bool mark_nonssa_use (gimple *, tree t, tree, void *data)
static bool visit_bb (basic_block bb, basic_block return_bb, bitmap set_ssa_names, bitmap used_ssa_names, bitmap non_ssa_vars)
static void find_split_points (basic_block return_bb, sreal overall_time, int overall_size)
static void split_function (basic_block return_bb, class split_point *split_point, bool add_tsan_func_exit)
static unsigned int execute_split_functions (void)
gimple_opt_passmake_pass_split_functions (gcc::context *ctxt)
static unsigned int execute_feedback_split_functions (void)
gimple_opt_passmake_pass_feedback_split_functions (gcc::context *ctxt)


static vec< split_bb_infobb_info_vec
class split_point best_split_point
static bitmap forbidden_dominators

Function Documentation

◆ check_forbidden_calls()

static void check_forbidden_calls ( gimple * stmt)
If STMT is a call, check the callee against a list of forbidden
predicate functions.  If a match is found, look for uses of the
call result in condition statements that compare against zero.
For each such use, find the block targeted by the condition
statement for the nonzero result, and set the bit for this block
in the forbidden dominators bitmap.  The purpose of this is to avoid
selecting a split point where we are likely to lose the chance
to optimize away an unused function call.   

References bitmap_set_bit, dyn_cast(), extract_true_false_edges_from_block(), FOR_EACH_IMM_USE_FAST, forbidden_dominators, gimple_bb(), gimple_call_builtin_p(), gimple_call_lhs(), gimple_cond_code(), gimple_cond_rhs(), basic_block_def::index, integer_zerop(), TREE_CODE, and USE_STMT.

Referenced by execute_split_functions().

◆ consider_split()

static void consider_split ( class split_point * current,
bitmap non_ssa_vars,
basic_block return_bb )

◆ dominated_by_forbidden()

static bool dominated_by_forbidden ( basic_block bb)
If BB is dominated by any block in the forbidden dominators set,
return TRUE; else FALSE.   

References BASIC_BLOCK_FOR_FN, CDI_DOMINATORS, cfun, dominated_by_p(), EXECUTE_IF_SET_IN_BITMAP, and forbidden_dominators.

Referenced by consider_split().

◆ dump_split_point()

◆ execute_feedback_split_functions()

static unsigned int execute_feedback_split_functions ( void )
Execute function splitting pass.   

References execute_split_functions(), and TODO_rebuild_cgraph_edges.

◆ execute_split_functions()

static unsigned int execute_split_functions ( void )

◆ find_return_bb()

static basic_block find_return_bb ( void )
Return basic block containing RETURN statement.  We allow basic blocks
of the form:
<retval> = tmp_var;
return <retval>
but return_bb cannot be more complex than this (except for
-fsanitize=thread we allow TSAN_FUNC_EXIT () internal call in there).
If nothing is found, return the exit block.

When there are multiple RETURN statement, chose one with return value,
since that one is more likely shared by multiple code paths.

Return BB is special, because for function splitting it is the only
basic block that is duplicated in between header and split part of the

TODO: We might support multiple return blocks.   

References auto_var_in_fn_p(), cfun, current_function_decl, dyn_cast(), EXIT_BLOCK_PTR_FOR_FN, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_call_internal_p(), gimple_clobber_p(), gimple_return_retval(), gsi_end_p(), gsi_last_bb(), gsi_prev(), gsi_stmt(), is_gimple_debug(), is_gimple_min_invariant(), NULL_TREE, SANITIZE_THREAD, single_pred_edge(), and single_pred_p().

Referenced by execute_split_functions().

◆ find_retval()

static tree find_retval ( basic_block return_bb)
Given return basic block RETURN_BB, see where return value is really

References dyn_cast(), gimple_assign_rhs1(), gimple_clobber_p(), gimple_return_retval(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), and NULL.

Referenced by consider_split(), and split_function().

◆ find_split_points()

static void find_split_points ( basic_block return_bb,
sreal overall_time,
int overall_size )
Find all articulations and call consider_split on them.
OVERALL_TIME and OVERALL_SIZE is time and size of the function.

We perform basic algorithm for finding an articulation in a graph
created from CFG by considering it to be an unoriented graph.

The articulation is discovered via DFS walk. We collect earliest
basic block on stack that is reachable via backward edge.  Articulation
is any basic block such that there is no backward edge bypassing it.
To reduce stack usage we maintain heap allocated stack in STACK vector.
AUX pointer of BB is set to index it appears in the stack or -1 once
it is visited and popped off the stack.

The algorithm finds articulation after visiting the whole component
reachable by it.  This makes it convenient to collect information about
the component used by consider_split.   

References basic_block_def::aux, stack_entry::bb, bb_info_vec, stack_entry::bbs_visited, BITMAP_ALLOC, bitmap_and_compl(), BITMAP_FREE, bitmap_ior_into(), bitmap_set_bit, stack_entry::can_split, cfun, consider_split(), dump_file, dump_flags, stack_entry::earliest, EDGE_COUNT, stack_entry::edge_num, EDGE_PRED, EDGE_SUCC, split_point::entry_bb, ENTRY_BLOCK_PTR_FOR_FN, EXIT_BLOCK_PTR_FOR_FN, FOR_EACH_BB_FN, split_point::header_size, split_point::header_time, basic_block_def::index, INT_MAX, stack_entry::non_ssa_vars, NULL, overall_size, stack_entry::overall_size, stack_entry::overall_time, basic_block_def::preds, stack_entry::set_ssa_names, split_point::split_bbs, split_point::split_size, split_point::split_time, split_point::ssa_names_to_pass, basic_block_def::succs, TDF_DETAILS, stack_entry::used_ssa_names, visit_bb(), and vNULL.

Referenced by execute_split_functions().

◆ make_pass_feedback_split_functions()

gimple_opt_pass * make_pass_feedback_split_functions ( gcc::context * ctxt)

◆ make_pass_split_functions()

gimple_opt_pass * make_pass_split_functions ( gcc::context * ctxt)

◆ mark_nonssa_use()

static bool mark_nonssa_use ( gimple * ,
tree t,
tree ,
void * data )
Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
variable, mark it as used in bitmap passed via DATA.
Return true when access to T prevents splitting the function.   

References auto_var_in_fn_p(), bitmap_bit_p, bitmap_set_bit, current_function_decl, DECL_BY_REFERENCE, DECL_RESULT, DECL_UID, dump_file, dump_flags, FORCED_LABEL, get_base_address(), INDIRECT_REF_P, is_gimple_reg(), SSA_NAME_VAR, TDF_DETAILS, TREE_CODE, TREE_OPERAND, and VAR_P.

Referenced by visit_bb().

◆ split_function()

static void split_function ( basic_block return_bb,
class split_point * split_point,
bool add_tsan_func_exit )
Split function at SPLIT_POINT.   

References add_bb_to_loop(), add_phi_arg(), symtab_node::add_to_same_comdat_group(), aggregate_value_p(), ipa_adjusted_param::base_index, BITMAP_ALLOC, bitmap_bit_p, bitmap_empty_p(), BITMAP_FREE, bitmap_set_bit, build_simple_mem_ref, cgraph_node::calls_comdat_local, cgraph_node::can_change_signature, CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, compute_fn_summary(), copy_ssa_name(), basic_block_def::count, split_point::count, create_basic_block(), create_tmp_reg(), cgraph_node::create_version_clone_with_body(), current_function_decl, current_loops, symtab_node::decl, DECL_ARG_TYPE, DECL_ARGUMENTS, DECL_BY_REFERENCE, DECL_CHAIN, decl_debug_args_lookup(), DECL_INITIAL, DECL_NO_INLINE_WARNING_P, DECL_ORIGIN, DECL_RESULT, dump_file, dump_flags, dump_function_to_file(), dump_split_point(), dyn_cast(), split_point::entry_bb, EXIT_BLOCK_PTR_FOR_FN, find_retval(), fndecl_built_in_p(), fold_convert, FOR_EACH_EDGE, FOR_EACH_SSA_TREE_OPERAND, FOR_EACH_SSA_USE_OPERAND, FOR_EACH_VEC_ELT, force_gimple_operand_gsi(), free_dominance_info(), g, cgraph_node::get(), get_or_create_ssa_default_def(), gimple_assign_lhs(), gimple_assign_set_rhs1(), gimple_bb(), gimple_build_assign(), gimple_build_call_internal(), gimple_build_call_vec(), gimple_build_debug_bind(), gimple_build_return(), gimple_call_set_lhs(), gimple_call_set_return_slot_opt(), gimple_clobber_p(), gimple_debug_bind_reset_value(), gimple_phi_result(), gimple_return_set_retval(), gimple_set_block(), gimple_set_vuse(), gimple_vdef(), gimple_vuse(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_insert_after(), gsi_last_bb(), GSI_NEW_STMT, gsi_next(), gsi_remove(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), i, basic_block_def::index, IPA_PARAM_OP_COPY, is_gimple_debug(), is_gimple_reg(), is_gimple_reg_type(), is_gimple_val(), make_single_succ_edge(), make_ssa_name(), mark_virtual_phi_result_for_renaming(), MAY_HAVE_DEBUG_BIND_STMTS, NOT_BUILT_IN, NULL, NULL_TREE, ipa_adjusted_param::op, gphi_iterator::phi(), basic_block_def::preds, ipa_adjusted_param::prev_clone_index, cgraph_edge::rebuild_edges(), redirect_edge_and_branch(), symtab_node::remove_all_references(), cgraph_node::remove_callees(), remove_edge(), remove_phi_node(), symtab_node::same_comdat_group, set_decl_built_in_function(), SET_USE, split_point::split_bbs, split_block(), cgraph_node::split_part, split_point::split_part_set_retval, ssa_default_def(), SSA_NAME_DEF_STMT, SSA_NAME_VERSION, split_point::ssa_names_to_pass, SSA_OP_USE, cgraph_node::tp_first_run, TREE_CODE, TREE_THIS_VOLATILE, TREE_TYPE, UNKNOWN_LOCATION, unshare_expr(), update_stmt(), USE_FROM_PTR, useless_type_conversion_p(), vec_safe_length(), vec_safe_push(), virtual_operand_p(), vNULL, VOID_TYPE_P, and profile_count::zero().

Referenced by execute_split_functions().

◆ split_part_set_ssa_name_p()

static bool split_part_set_ssa_name_p ( tree val,
class split_point * current,
basic_block return_bb )
For give split point CURRENT and return block RETURN_BB return 1
if ssa name VAL is set by split part and 0 otherwise.   

References bitmap_bit_p, gimple_bb(), split_point::split_bbs, SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, and TREE_CODE.

Referenced by consider_split().

◆ test_nonssa_use()

static bool test_nonssa_use ( gimple * ,
tree t,
tree ,
void * data )
Callback for walk_stmt_load_store_addr_ops.  If T is non-SSA automatic
variable, check it if it is present in bitmap passed via DATA.   

References auto_var_in_fn_p(), bitmap_bit_p, current_function_decl, DECL_BY_REFERENCE, DECL_RESULT, DECL_UID, FORCED_LABEL, get_base_address(), INDIRECT_REF_P, is_gimple_reg(), SSA_NAME_VAR, TREE_CODE, TREE_OPERAND, and VAR_P.

Referenced by verify_non_ssa_vars().

◆ verify_non_ssa_vars()

static bool verify_non_ssa_vars ( class split_point * current,
bitmap non_ssa_vars,
basic_block return_bb )

◆ visit_bb()

static bool visit_bb ( basic_block bb,
basic_block return_bb,
bitmap set_ssa_names,
bitmap used_ssa_names,
bitmap non_ssa_vars )
Compute local properties of basic block BB we collect when looking for
split points.  We look for ssa defs and store them in SET_SSA_NAMES,
for ssa uses and store them in USED_SSA_NAMES and for any non-SSA automatic
vars stored in NON_SSA_VARS.

When BB has edge to RETURN_BB, collect uses in RETURN_BB too.  

Return false when BB contains something that prevents it from being put into
split function.   

References bitmap_set_bit, BUILT_IN_NORMAL, DECL_ATTRIBUTES, DECL_FUNCTION_CODE(), dump_file, dump_flags, fndecl_built_in_p(), FOR_EACH_EDGE, FOR_EACH_SSA_TREE_OPERAND, gimple_call_fndecl(), gimple_clobber_p(), gimple_phi_arg_def(), gimple_phi_num_args(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_start_phis(), gsi_stmt(), i, is_gimple_debug(), lookup_attribute(), mark_nonssa_use(), SSA_NAME_VERSION, SSA_OP_DEF, SSA_OP_USE, basic_block_def::succs, TDF_DETAILS, TREE_CODE, virtual_operand_p(), and walk_stmt_load_store_addr_ops().

Referenced by find_split_points().

Variable Documentation

◆ bb_info_vec

vec<split_bb_info> bb_info_vec

◆ best_split_point

class split_point best_split_point
Best split point found.   

Referenced by consider_split(), and execute_split_functions().

◆ forbidden_dominators

bitmap forbidden_dominators
Set of basic blocks that are not allowed to dominate a split point.   

Referenced by check_forbidden_calls(), consider_split(), dominated_by_forbidden(), and execute_split_functions().