#include <tree-ssa-threadedge.h>
Public Member Functions | |
jump_threader (jt_simplifier *, class jt_state *) | |
~jump_threader () | |
void | thread_outgoing_edges (basic_block) |
void | remove_jump_threads_including (edge_def *) |
bool | thread_through_all_blocks (bool may_peel_loop_headers) |
Private Member Functions | |
tree | simplify_control_stmt_condition (edge, gimple *) |
tree | simplify_control_stmt_condition_1 (edge, gimple *, tree op0, tree_code cond_code, tree op1, unsigned limit) |
bool | thread_around_empty_blocks (vec< class jump_thread_edge * > *path, edge, bitmap visited, unsigned &limit) |
int | thread_through_normal_block (vec< jump_thread_edge * > *path, edge, bitmap visited, unsigned &limit) |
void | thread_across_edge (edge) |
bool | record_temporary_equivalences_from_phis (edge) |
gimple * | record_temporary_equivalences_from_stmts_at_dest (edge) |
Private Attributes | |
gcond * | dummy_cond |
class fwd_jt_path_registry * | m_registry |
jt_simplifier * | m_simplifier |
jt_state * | m_state |
jump_threader::jump_threader | ( | jt_simplifier * | simplifier, |
class jt_state * | state ) |
References dummy_cond, gcc_assert, gimple_build_cond(), integer_zero_node, m_registry, m_simplifier, m_state, NULL, num_ssa_names, and ssa_name_values.
jump_threader::~jump_threader | ( | void | ) |
References dummy_cond, ggc_free(), m_registry, and ssa_name_values.
Record temporary equivalences created by PHIs at the target of the edge E. If a PHI which prevents threading is encountered, then return FALSE indicating we should not thread this edge, else return TRUE.
References gimple_bb(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start_phis(), m_state, gphi_iterator::phi(), PHI_ARG_DEF_FROM_EDGE, jt_state::register_equiv(), SSA_NAME_DEF_STMT, stmt_count, TREE_CODE, and virtual_operand_p().
Referenced by thread_through_normal_block().
Try to simplify each statement in E->dest, ultimately leading to a simplification of the COND_EXPR at the end of E->dest. Record unwind information for temporary equivalences onto STACK. Uses M_SIMPLIFIER to further simplify statements using pass specific information. We might consider marking just those statements which ultimately feed the COND_EXPR. It's not clear if the overhead of bookkeeping would be recovered by trying to simplify fewer statements. If we are able to simplify a statement into the form SSA_NAME = (SSA_NAME | gimple invariant), then we can record a context sensitive equivalence which may help us simplify later statements in E->dest.
References as_a(), BUILT_IN_NORMAL, DECL_FUNCTION_CODE(), dump_file, estimate_threading_killed_stmts(), fndecl_built_in_p(), gimple_asm_volatile_p(), gimple_assign_lhs(), gimple_call_builtin_p(), gimple_call_fndecl(), gimple_call_internal_p(), gimple_call_internal_unique_p(), gimple_call_lhs(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), is_gimple_call(), is_gimple_debug(), m_simplifier, m_state, NULL, NULL_TREE, jt_state::record_ranges_from_stmt(), jt_state::register_equivs_stmt(), stmt_count, and TREE_CODE.
Referenced by thread_through_normal_block().
void jump_threader::remove_jump_threads_including | ( | edge_def * | e | ) |
References m_registry, and fwd_jt_path_registry::remove_jump_threads_including().
Simplify the control statement at the end of the block E->dest. Use SIMPLIFY (a pointer to a callback function) to further simplify a condition using pass specific information. Return the simplified condition or NULL if simplification could not be performed. When simplifying a GIMPLE_SWITCH, we may return the CASE_LABEL_EXPR that will be taken.
References as_a(), gcc_unreachable, ggc_free(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_copy(), gimple_goto_dest(), gimple_switch_index(), gimple_switch_set_index(), i, INTEGRAL_TYPE_P, is_gimple_min_invariant(), m_simplifier, m_state, NULL, POINTER_TYPE_P, jt_simplifier::simplify(), simplify_control_stmt_condition_1(), SSA_NAME_VALUE, TREE_CODE, and TREE_TYPE.
Referenced by thread_around_empty_blocks(), and thread_through_normal_block().
|
private |
Recursive helper for simplify_control_stmt_condition.
References boolean_type_node, CONVERT_EXPR_P, dummy_cond, fold_binary, fold_defer_overflow_warnings(), fold_undefer_overflow_warnings(), gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), is_gimple_min_invariant(), m_simplifier, m_state, NULL_TREE, jt_simplifier::simplify(), swap_tree_comparison(), TREE_OPERAND, tree_swap_operands_p(), and WARN_STRICT_OVERFLOW_CONDITIONAL.
Referenced by simplify_control_stmt_condition().
|
private |
We are exiting E->src, see if E->dest ends with a conditional jump which has a known value when reached via E. If so, thread the edge.
References jt_path_registry::allocate_thread_path(), bitmap_clear(), bitmap_set_bit, EDGE_COMPLEX, EDGE_COPY_SRC_JOINER_BLOCK, edge_forwards_cmp_to_conditional_jump_through_empty_bb_p(), EDGE_START_JUMP_THREAD, FOR_EACH_EDGE, gcc_checking_assert, m_registry, m_state, jt_state::pop(), propagate_threaded_block_debug_into(), jt_state::push(), jt_path_registry::push_edge(), jt_path_registry::register_jump_thread(), stmt_count, thread_around_empty_blocks(), thread_through_normal_block(), and visited.
Referenced by thread_outgoing_edges().
|
private |
See if TAKEN_EDGE->dest is a threadable block with no side effecs (ie, it need not be duplicated as part of the CFG/SSA updating process). If it is threadable, add it to PATH and VISITED and recurse, ultimately returning TRUE from the toplevel call. Otherwise do nothing and return false.
References jt_state::append_path(), bitmap_bit_p, bitmap_set_bit, CASE_LABEL, cfun, EDGE_NO_COPY_SRC_BLOCK, find_edge(), find_taken_edge(), gsi_end_p(), gsi_start_nondebug_bb(), gsi_stmt(), has_phis_p(), is_gimple_min_invariant(), label_to_block(), m_registry, m_state, NULL_TREE, jt_path_registry::push_edge(), simplify_control_stmt_condition(), single_succ_edge(), single_succ_p(), thread_around_empty_blocks(), TREE_CODE, and visited.
Referenced by thread_across_edge(), thread_around_empty_blocks(), and thread_through_normal_block().
void jump_threader::thread_outgoing_edges | ( | basic_block | bb | ) |
Examine the outgoing edges from BB and conditionally try to thread them.
References EDGE_COMPLEX, EDGE_COUNT, EDGE_SUCC, extract_true_false_edges_from_block(), gsi_last_bb(), potentially_threadable_block(), safe_is_a(), single_succ_edge(), single_succ_to_potentially_threadable_block(), basic_block_def::succs, and thread_across_edge().
References m_registry, and jt_path_registry::thread_through_all_blocks().
|
private |
We are exiting E->src, see if E->dest ends with a conditional jump which has a known value when reached via E. E->dest can have arbitrary side effects which, if threading is successful, will be maintained. Special care is necessary if E is a back edge in the CFG as we may have already recorded equivalences for E->dest into our various tables, including the result of the conditional at the end of E->dest. Threading opportunities are severely limited in that case to avoid short-circuiting the loop incorrectly. Positive return value is success. Zero return value is failure, but the block can still be duplicated as a joiner in a jump thread path, negative indicates the block should not be duplicated and thus is not suitable for a joiner in a jump threading path.
References jt_state::append_path(), bitmap_bit_p, bitmap_set_bit, CASE_LABEL, cfun, EDGE_COPY_SRC_BLOCK, EDGE_START_JUMP_THREAD, empty_block_with_phis_p(), find_edge(), find_taken_edge(), basic_block_def::index, is_gimple_min_invariant(), label_to_block(), m_registry, m_state, NULL, jt_path_registry::push_edge(), record_temporary_equivalences_from_phis(), record_temporary_equivalences_from_stmts_at_dest(), jt_state::register_equivs_edge(), simplify_control_stmt_condition(), thread_around_empty_blocks(), TREE_CODE, and visited.
Referenced by thread_across_edge().
|
private |
Referenced by jump_threader(), simplify_control_stmt_condition_1(), and ~jump_threader().
|
private |
|
private |
|
private |