diff options
| -rw-r--r-- | gcc/gimple-range-path.cc | 21 | ||||
| -rw-r--r-- | gcc/gimple-range-path.h | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-18.c | 20 | ||||
| -rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-19.c | 33 | ||||
| -rw-r--r-- | gcc/tree-ssa-threadbackward.cc | 4 |
5 files changed, 65 insertions, 15 deletions
diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 43e7526..389faec 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -549,7 +549,7 @@ path_range_query::add_to_imports (tree name, bitmap imports) return false; } -// Compute the imports to the path ending in EXIT. These are +// Compute the imports to PATH. These are // essentially the SSA names used to calculate the final conditional // along the path. // @@ -559,9 +559,10 @@ path_range_query::add_to_imports (tree name, bitmap imports) // we can solve. void -path_range_query::compute_imports (bitmap imports, basic_block exit) +path_range_query::compute_imports (bitmap imports, const vec<basic_block> &path) { // Start with the imports from the exit block... + basic_block exit = path[0]; gori_compute &gori = m_ranger->gori (); bitmap r_imports = gori.imports (exit); bitmap_copy (imports, r_imports); @@ -599,7 +600,7 @@ path_range_query::compute_imports (bitmap imports, basic_block exit) tree arg = gimple_phi_arg (phi, i)->def; if (TREE_CODE (arg) == SSA_NAME - && m_path.contains (e->src) + && path.contains (e->src) && bitmap_set_bit (imports, SSA_NAME_VERSION (arg))) worklist.safe_push (arg); } @@ -607,9 +608,9 @@ path_range_query::compute_imports (bitmap imports, basic_block exit) } // Exported booleans along the path, may help conditionals. if (m_resolve) - for (i = 0; i < m_path.length (); ++i) + for (i = 0; i < path.length (); ++i) { - basic_block bb = m_path[i]; + basic_block bb = path[i]; tree name; FOR_EACH_GORI_EXPORT_NAME (gori, bb, name) if (TREE_CODE (TREE_TYPE (name)) == BOOLEAN_TYPE) @@ -636,7 +637,7 @@ path_range_query::compute_ranges (const vec<basic_block> &path, if (imports) bitmap_copy (m_imports, imports); else - compute_imports (m_imports, exit_bb ()); + compute_imports (m_imports, m_path); if (m_resolve) get_path_oracle ()->reset_path (); @@ -845,15 +846,9 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev) void path_range_query::compute_outgoing_relations (basic_block bb, basic_block next) { - gimple *stmt = last_stmt (bb); - - if (stmt - && gimple_code (stmt) == GIMPLE_COND - && (import_p (gimple_cond_lhs (stmt)) - || import_p (gimple_cond_rhs (stmt)))) + if (gcond *cond = safe_dyn_cast <gcond *> (last_stmt (bb))) { int_range<2> r; - gcond *cond = as_a<gcond *> (stmt); edge e0 = EDGE_SUCC (bb, 0); edge e1 = EDGE_SUCC (bb, 1); diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h index 2c4624e..e783e00 100644 --- a/gcc/gimple-range-path.h +++ b/gcc/gimple-range-path.h @@ -37,7 +37,7 @@ public: void compute_ranges (const vec<basic_block> &, const bitmap_head *imports = NULL); void compute_ranges (edge e); - void compute_imports (bitmap imports, basic_block exit); + void compute_imports (bitmap imports, const vec<basic_block> &); bool range_of_expr (vrange &r, tree name, gimple * = NULL) override; bool range_of_stmt (vrange &r, gimple *, tree name = NULL) override; bool unreachable_path_p (); diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-18.c new file mode 100644 index 0000000..a899f4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-18.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-threadfull1-stats" } */ + +void foo (int nest, int print_nest) +{ + _Bool t0 = nest != 0; + _Bool t1 = nest == print_nest; + _Bool t2 = t0 & t1; + if (t2) + __builtin_puts ("x"); + nest++; + if (nest > 2) + __builtin_abort (); + if (print_nest == nest) + __builtin_puts ("y"); +} + +/* We should be able to thread (t2) to !(print_nest == nest) using the + nest == print_nest relation implied by the entry block. */ +/* { dg-final { scan-tree-dump "Jumps threaded: 1" "threadfull1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-19.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-19.c new file mode 100644 index 0000000..58a872b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-19.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-threadfull1-stats" } */ + +struct S; +struct S { struct S *next; }; +int foo (struct S *chain, _Bool is_ctor, _Bool is_dtor) +{ + int num_args = 0; + if (chain) /* A */ + { + do { + num_args++; + chain = chain->next; + if (!chain) + break; + } while (1); + } + if (is_ctor) + num_args++; /* B */ + if (is_dtor) + num_args++; + else + { + if (num_args > 2) /* C */ + __builtin_puts ("x"); + } + return num_args; +} + +/* We want to thread both paths from A with NULL chain to C, the one through + B and one around it. + ??? Ideally we'd thread one "path" containing the half-diamond with B. */ +/* { dg-final { scan-tree-dump "Jumps threaded: 2" "threadfull1" { xfail *-*-* } } } */ diff --git a/gcc/tree-ssa-threadbackward.cc b/gcc/tree-ssa-threadbackward.cc index 30047c6..6585a30 100644 --- a/gcc/tree-ssa-threadbackward.cc +++ b/gcc/tree-ssa-threadbackward.cc @@ -451,7 +451,9 @@ back_threader::find_paths (basic_block bb, tree name) m_visited_bbs.empty (); m_path.truncate (0); m_name = name; - m_solver->compute_imports (m_imports, bb); + m_path.safe_push (bb); + m_solver->compute_imports (m_imports, m_path); + m_path.pop (); auto_bitmap interesting; bitmap_copy (interesting, m_imports); |
