aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-threadedge.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-threadedge.c')
-rw-r--r--gcc/tree-ssa-threadedge.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 9e10e44..4f83991 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "params.h"
#include "tree-ssa-threadedge.h"
+#include "tree-ssa-loop.h"
#include "builtins.h"
#include "cfg.h"
#include "cfganal.h"
@@ -1006,7 +1007,8 @@ static int max_threaded_paths;
static void
fsm_find_control_statement_thread_paths (tree expr,
hash_set<gimple> *visited_phis,
- vec<basic_block, va_gc> *&path)
+ vec<basic_block, va_gc> *&path,
+ bool seen_loop_phi)
{
tree var = SSA_NAME_VAR (expr);
gimple def_stmt = SSA_NAME_DEF_STMT (expr);
@@ -1030,6 +1032,14 @@ fsm_find_control_statement_thread_paths (tree expr,
int next_path_length = 0;
basic_block last_bb_in_path = path->last ();
+ if (loop_containing_stmt (phi)->header == gimple_bb (phi))
+ {
+ /* Do not walk through more than one loop PHI node. */
+ if (seen_loop_phi)
+ return;
+ seen_loop_phi = true;
+ }
+
/* Following the chain of SSA_NAME definitions, we jumped from a definition in
LAST_BB_IN_PATH to a definition in VAR_BB. When these basic blocks are
different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB. */
@@ -1090,7 +1100,9 @@ fsm_find_control_statement_thread_paths (tree expr,
{
vec_safe_push (path, bbi);
/* Recursively follow SSA_NAMEs looking for a constant definition. */
- fsm_find_control_statement_thread_paths (arg, visited_phis, path);
+ fsm_find_control_statement_thread_paths (arg, visited_phis, path,
+ seen_loop_phi);
+
path->pop ();
continue;
}
@@ -1357,7 +1369,8 @@ thread_through_normal_block (edge e,
hash_set<gimple> *visited_phis = new hash_set<gimple>;
max_threaded_paths = PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATHS);
- fsm_find_control_statement_thread_paths (cond, visited_phis, bb_path);
+ fsm_find_control_statement_thread_paths (cond, visited_phis, bb_path,
+ false);
delete visited_phis;
vec_free (bb_path);