From 21f0717ab16fe725e887536f5f90b7487b6431cd Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 29 Oct 2015 10:20:06 -0600 Subject: [PATCH][PR tree-optimization/67892] Use FSM threader to handle backedges PR tree-optimization/67892 * tree-ssa-threadedge.c (simplify_controL_stmt_condition): Fix typo in comment. (thread_through_normal_block): If we have seen a backedge, then do nothing. No longer call find_jump_threads_backwards here. (thread_across_edge): Use find_jump_threads_backwards to find jump threads if the old style threader was not successful. * tree-ssa-threadbackward.c (get_gimple_control_stmt): Use gsi_last_nondebug_bb. Return NULL if the block does not end with a control statement. (find_jump_threads_backwards): Setup code moved here from tree-ssa-threadedge.c::thread_through_normal_block. Accept single edge argument instead of name & block. * tree-ssa-threadbackward.h (find_jump_threads_backwards): Update prototype. PR tree-optimization/67892 * gcc.dg/tree-ssa/pr21417: Update expected output. * gcc.dg/tree-ssa/ssa-dom-thread-2b.c: Likewise. From-SVN: r229538 --- gcc/tree-ssa-threadbackward.c | 45 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) (limited to 'gcc/tree-ssa-threadbackward.c') diff --git a/gcc/tree-ssa-threadbackward.c b/gcc/tree-ssa-threadbackward.c index cfb4ace..90e01df 100644 --- a/gcc/tree-ssa-threadbackward.c +++ b/gcc/tree-ssa-threadbackward.c @@ -37,19 +37,22 @@ along with GCC; see the file COPYING3. If not see static int max_threaded_paths; /* Simple helper to get the last statement from BB, which is assumed - to be a control statement. */ + to be a control statement. Return NULL if the last statement is + not a control statement. */ + static gimple * get_gimple_control_stmt (basic_block bb) { - gimple_stmt_iterator gsi = gsi_last_bb (bb); + gimple_stmt_iterator gsi = gsi_last_nondebug_bb (bb); if (gsi_end_p (gsi)) return NULL; gimple *stmt = gsi_stmt (gsi); enum gimple_code code = gimple_code (stmt); - gcc_assert (code == GIMPLE_COND || code == GIMPLE_SWITCH || code == GIMPLE_GOTO); - return stmt; + if (code == GIMPLE_COND || code == GIMPLE_SWITCH || code == GIMPLE_GOTO) + return stmt; + return NULL; } /* Return true if the CFG contains at least one path from START_BB to END_BB. @@ -340,11 +343,39 @@ fsm_find_control_statement_thread_paths (tree name, finding a path where NAME is a constant, we can thread the path. */ void -find_jump_threads_backwards (tree name, basic_block bb) +find_jump_threads_backwards (edge e) { + if (!flag_expensive_optimizations + || optimize_function_for_size_p (cfun) + || e->dest->loop_father != e->src->loop_father + || loop_depth (e->dest->loop_father) == 0) + return; + + gimple *stmt = get_gimple_control_stmt (e->dest); + if (!stmt) + return; + + enum gimple_code code = gimple_code (stmt); + tree name = NULL; + if (code == GIMPLE_SWITCH) + name = gimple_switch_index (as_a (stmt)); + else if (code == GIMPLE_GOTO) + name = gimple_goto_dest (stmt); + else if (code == GIMPLE_COND) + { + if (TREE_CODE (gimple_cond_lhs (stmt)) == SSA_NAME + && TREE_CODE (gimple_cond_rhs (stmt)) == INTEGER_CST + && (INTEGRAL_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))) + || POINTER_TYPE_P (TREE_TYPE (gimple_cond_lhs (stmt))))) + name = gimple_cond_lhs (stmt); + } + + if (!name || TREE_CODE (name) != SSA_NAME) + return; + vec *bb_path; vec_alloc (bb_path, n_basic_blocks_for_fn (cfun)); - vec_safe_push (bb_path, bb); + vec_safe_push (bb_path, e->dest); hash_set *visited_bbs = new hash_set; max_threaded_paths = PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATHS); @@ -352,4 +383,4 @@ find_jump_threads_backwards (tree name, basic_block bb) delete visited_bbs; vec_free (bb_path); -} +} -- cgit v1.1