GCC Middle and Back End API Reference
jump_threader Class Reference

#include <tree-ssa-threadedge.h>

Collaboration diagram for jump_threader:

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)
 
int thread_through_normal_block (vec< jump_thread_edge * > *path, edge, bitmap visited)
 
void thread_across_edge (edge)
 
bool record_temporary_equivalences_from_phis (edge)
 
gimplerecord_temporary_equivalences_from_stmts_at_dest (edge)
 

Private Attributes

gconddummy_cond
 
class fwd_jt_path_registrym_registry
 
jt_simplifierm_simplifier
 
jt_statem_state
 

Constructor & Destructor Documentation

◆ jump_threader()

jump_threader::jump_threader ( jt_simplifier * simplifier,
class jt_state * state )

◆ ~jump_threader()

jump_threader::~jump_threader ( void )

Member Function Documentation

◆ record_temporary_equivalences_from_phis()

bool jump_threader::record_temporary_equivalences_from_phis ( edge e)
private
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().

◆ record_temporary_equivalences_from_stmts_at_dest()

gimple * jump_threader::record_temporary_equivalences_from_stmts_at_dest ( edge e)
private
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().

◆ remove_jump_threads_including()

void jump_threader::remove_jump_threads_including ( edge_def * e)

◆ simplify_control_stmt_condition()

tree jump_threader::simplify_control_stmt_condition ( edge e,
gimple * stmt )
private
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().

◆ simplify_control_stmt_condition_1()

◆ thread_across_edge()

◆ thread_around_empty_blocks()

bool jump_threader::thread_around_empty_blocks ( vec< class jump_thread_edge * > * path,
edge taken_edge,
bitmap visited )
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().

◆ thread_outgoing_edges()

void jump_threader::thread_outgoing_edges ( basic_block bb)

◆ thread_through_all_blocks()

bool jump_threader::thread_through_all_blocks ( bool may_peel_loop_headers)

◆ thread_through_normal_block()

int jump_threader::thread_through_normal_block ( vec< jump_thread_edge * > * path,
edge e,
bitmap visited )
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().

Field Documentation

◆ dummy_cond

gcond* jump_threader::dummy_cond
private

◆ m_registry

◆ m_simplifier

◆ m_state


The documentation for this class was generated from the following files: