diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/gimple-range-fold.cc | 2 | ||||
-rw-r--r-- | gcc/gimple-range-path.cc | 107 | ||||
-rw-r--r-- | gcc/gimple-range-path.h | 3 |
3 files changed, 58 insertions, 54 deletions
diff --git a/gcc/gimple-range-fold.cc b/gcc/gimple-range-fold.cc index ed2fbe1..2fab904 100644 --- a/gcc/gimple-range-fold.cc +++ b/gcc/gimple-range-fold.cc @@ -620,7 +620,9 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_NONE) { fprintf (dump_file, " folding with relation "); + print_generic_expr (dump_file, op1, TDF_SLIM); print_relation (dump_file, rel); + print_generic_expr (dump_file, op2, TDF_SLIM); fputc ('\n', dump_file); } // Fold range, and register any dependency if available. diff --git a/gcc/gimple-range-path.cc b/gcc/gimple-range-path.cc index 5573389..2f570a1 100644 --- a/gcc/gimple-range-path.cc +++ b/gcc/gimple-range-path.cc @@ -316,6 +316,9 @@ path_range_query::compute_ranges_in_block (basic_block bb) int_range_max r, cached_range; unsigned i; + if (m_resolve && !at_entry ()) + compute_phi_relations (bb, prev_bb ()); + // Force recalculation of any names in the cache that are defined in // this block. This can happen on interdependent SSA/phis in loops. EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi) @@ -341,7 +344,8 @@ path_range_query::compute_ranges_in_block (basic_block bb) return; // Solve imports that are exported to the next block. - edge e = find_edge (bb, next_bb ()); + basic_block next = next_bb (); + edge e = find_edge (bb, next); EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi) { tree name = ssa_name (i); @@ -369,6 +373,9 @@ path_range_query::compute_ranges_in_block (basic_block bb) } } } + + if (m_resolve) + compute_outgoing_relations (bb, next); } // Adjust all pointer imports in BB with non-null information. @@ -485,7 +492,6 @@ path_range_query::compute_ranges (const vec<basic_block> &path, { add_copies_to_imports (); get_path_oracle ()->reset_path (); - compute_relations (path); } if (DEBUG_SOLVER) @@ -527,7 +533,12 @@ path_range_query::compute_ranges (const vec<basic_block> &path, } if (DEBUG_SOLVER) - dump (dump_file); + { + fprintf (dump_file, "\npath_oracle:\n"); + get_path_oracle ()->dump (dump_file); + fprintf (dump_file, "\n"); + dump (dump_file); + } } // A folding aid used to register and query relations along a path. @@ -624,49 +635,23 @@ path_range_query::range_of_stmt (irange &r, gimple *stmt, tree) return true; } -// Compute relations on a path. This involves two parts: relations -// along the conditionals joining a path, and relations determined by -// examining PHIs. - void -path_range_query::compute_relations (const vec<basic_block> &path) +path_range_query::maybe_register_phi_relation (gphi *phi, tree arg) { - if (!dom_info_available_p (CDI_DOMINATORS)) - return; + basic_block bb = gimple_bb (phi); + tree result = gimple_phi_result (phi); + gimple *def = SSA_NAME_DEF_STMT (arg); - jt_fur_source src (NULL, this, &m_ranger.gori (), path); - basic_block prev = NULL; - for (unsigned i = path.length (); i > 0; --i) - { - basic_block bb = path[i - 1]; - gimple *stmt = last_stmt (bb); + // Avoid recording the equivalence if the arg is defined in this + // block, as that would create an ordering problem. + if (def && gimple_bb (def) == bb) + return; - compute_phi_relations (bb, prev); + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, " from bb%d:", bb->index); - // Compute relations in outgoing edges along the path. Skip the - // final conditional which we don't know yet. - if (i > 1 - && stmt - && gimple_code (stmt) == GIMPLE_COND - && irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt)))) - { - basic_block next = path[i - 2]; - int_range<2> r; - gcond *cond = as_a<gcond *> (stmt); - edge e0 = EDGE_SUCC (bb, 0); - edge e1 = EDGE_SUCC (bb, 1); - - if (e0->dest == next) - gcond_edge_range (r, e0); - else if (e1->dest == next) - gcond_edge_range (r, e1); - else - gcc_unreachable (); - - src.register_outgoing_edges (cond, r, e0, e1); - } - prev = bb; - } + get_path_oracle ()->killing_def (result); + m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result); } // Compute relations for each PHI in BB. For example: @@ -681,15 +666,12 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev) if (prev == NULL) return; - basic_block entry = entry_bb (); edge e_in = find_edge (prev, bb); - gcc_checking_assert (e_in); for (gphi_iterator iter = gsi_start_phis (bb); !gsi_end_p (iter); gsi_next (&iter)) { gphi *phi = iter.phi (); - tree result = gimple_phi_result (phi); unsigned nargs = gimple_phi_num_args (phi); for (size_t i = 0; i < nargs; ++i) @@ -698,17 +680,36 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev) tree arg = gimple_phi_arg_def (phi, i); if (gimple_range_ssa_p (arg)) - { - if (dump_file && (dump_flags & TDF_DETAILS)) - fprintf (dump_file, " from bb%d:", bb->index); + maybe_register_phi_relation (phi, arg); + break; + } + } +} - // Throw away any previous relation. - get_path_oracle ()->killing_def (result); +// Compute outgoing relations from BB to NEXT. - m_oracle->register_relation (entry, EQ_EXPR, arg, result); - } +void +path_range_query::compute_outgoing_relations (basic_block bb, basic_block next) +{ + gimple *stmt = last_stmt (bb); - break; - } + if (stmt + && gimple_code (stmt) == GIMPLE_COND + && irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt)))) + { + int_range<2> r; + gcond *cond = as_a<gcond *> (stmt); + edge e0 = EDGE_SUCC (bb, 0); + edge e1 = EDGE_SUCC (bb, 1); + + if (e0->dest == next) + gcond_edge_range (r, e0); + else if (e1->dest == next) + gcond_edge_range (r, e1); + else + gcc_unreachable (); + + jt_fur_source src (NULL, this, &m_ranger.gori (), *m_path); + src.register_outgoing_edges (cond, r, e0, e1); } } diff --git a/gcc/gimple-range-path.h b/gcc/gimple-range-path.h index 5f4e73a..5416139 100644 --- a/gcc/gimple-range-path.h +++ b/gcc/gimple-range-path.h @@ -57,8 +57,9 @@ private: void compute_ranges_in_block (basic_block bb); void adjust_for_non_null_uses (basic_block bb); void ssa_range_in_phi (irange &r, gphi *phi); - void compute_relations (const vec<basic_block> &); + void compute_outgoing_relations (basic_block bb, basic_block next); void compute_phi_relations (basic_block bb, basic_block prev); + void maybe_register_phi_relation (gphi *, tree arg); void add_copies_to_imports (); bool add_to_imports (tree name, bitmap imports); |