Skip to content

Commit 2f0b6a9

Browse files
committed
Reorder relation calculating code in the path solver.
Enabling the fully resolving threader triggers various relation ordering issues that have previously been dormant because the VRP hybrid threader (forward threader based) never gives us long enough paths for this to matter. The new threader spares no punches in finding non-obvious paths, so getting the relations right is paramount. This patch fixes a couple oversights that have gone undetected. First, some background. There are 3 types of relations along a path: a) Relations inherent in a PHI. b) Relations as a side-effect of evaluating a statement. c) Outgoing relations between blocks in a path. We must calculate these in their proper order, otherwise we can run into ordering issues. The current ordering is wrong, as we precalculate PHIs for _all_ blocks before anything else, and then proceed to register the relations throughout the path. Also, we fail to realize that a PHI whose argument is also defined in the PHIs block cannot be registered as an equivalence without causing more ordering issues. This patch fixes all the problems described above. With it we get a handful more net threads, but most importantly, we disallow some threads that were wrong. Tested on x86-64 and ppc64le Linux on the usual regstrap, plus by comparing the different thread counts before and after this patch. gcc/ChangeLog: * gimple-range-fold.cc (fold_using_range::range_of_range_op): Dump operands as well as relation. * gimple-range-path.cc (path_range_query::compute_ranges_in_block): Compute PHI relations first. Compute outgoing relations at the end. (path_range_query::compute_ranges): Remove call to compute_relations. (path_range_query::compute_relations): Remove. (path_range_query::maybe_register_phi_relation): New. (path_range_query::compute_phi_relations): Abstract out registering one PHI relation to... (path_range_query::compute_outgoing_relations): ...here. * gimple-range-path.h (class path_range_query): Remove compute_relations. Add maybe_register_phi_relation.
1 parent 9f4edfc commit 2f0b6a9

File tree

3 files changed

+58
-54
lines changed

3 files changed

+58
-54
lines changed

gcc/gimple-range-fold.cc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,9 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src)
620620
if (dump_file && (dump_flags & TDF_DETAILS) && rel != VREL_NONE)
621621
{
622622
fprintf (dump_file, " folding with relation ");
623+
print_generic_expr (dump_file, op1, TDF_SLIM);
623624
print_relation (dump_file, rel);
625+
print_generic_expr (dump_file, op2, TDF_SLIM);
624626
fputc ('\n', dump_file);
625627
}
626628
// Fold range, and register any dependency if available.

gcc/gimple-range-path.cc

Lines changed: 54 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,9 @@ path_range_query::compute_ranges_in_block (basic_block bb)
316316
int_range_max r, cached_range;
317317
unsigned i;
318318

319+
if (m_resolve && !at_entry ())
320+
compute_phi_relations (bb, prev_bb ());
321+
319322
// Force recalculation of any names in the cache that are defined in
320323
// this block. This can happen on interdependent SSA/phis in loops.
321324
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
@@ -341,7 +344,8 @@ path_range_query::compute_ranges_in_block (basic_block bb)
341344
return;
342345

343346
// Solve imports that are exported to the next block.
344-
edge e = find_edge (bb, next_bb ());
347+
basic_block next = next_bb ();
348+
edge e = find_edge (bb, next);
345349
EXECUTE_IF_SET_IN_BITMAP (m_imports, 0, i, bi)
346350
{
347351
tree name = ssa_name (i);
@@ -369,6 +373,9 @@ path_range_query::compute_ranges_in_block (basic_block bb)
369373
}
370374
}
371375
}
376+
377+
if (m_resolve)
378+
compute_outgoing_relations (bb, next);
372379
}
373380

374381
// Adjust all pointer imports in BB with non-null information.
@@ -485,7 +492,6 @@ path_range_query::compute_ranges (const vec<basic_block> &path,
485492
{
486493
add_copies_to_imports ();
487494
get_path_oracle ()->reset_path ();
488-
compute_relations (path);
489495
}
490496

491497
if (DEBUG_SOLVER)
@@ -527,7 +533,12 @@ path_range_query::compute_ranges (const vec<basic_block> &path,
527533
}
528534

529535
if (DEBUG_SOLVER)
530-
dump (dump_file);
536+
{
537+
fprintf (dump_file, "\npath_oracle:\n");
538+
get_path_oracle ()->dump (dump_file);
539+
fprintf (dump_file, "\n");
540+
dump (dump_file);
541+
}
531542
}
532543

533544
// 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)
624635
return true;
625636
}
626637

627-
// Compute relations on a path. This involves two parts: relations
628-
// along the conditionals joining a path, and relations determined by
629-
// examining PHIs.
630-
631638
void
632-
path_range_query::compute_relations (const vec<basic_block> &path)
639+
path_range_query::maybe_register_phi_relation (gphi *phi, tree arg)
633640
{
634-
if (!dom_info_available_p (CDI_DOMINATORS))
635-
return;
641+
basic_block bb = gimple_bb (phi);
642+
tree result = gimple_phi_result (phi);
643+
gimple *def = SSA_NAME_DEF_STMT (arg);
636644

637-
jt_fur_source src (NULL, this, &m_ranger.gori (), path);
638-
basic_block prev = NULL;
639-
for (unsigned i = path.length (); i > 0; --i)
640-
{
641-
basic_block bb = path[i - 1];
642-
gimple *stmt = last_stmt (bb);
645+
// Avoid recording the equivalence if the arg is defined in this
646+
// block, as that would create an ordering problem.
647+
if (def && gimple_bb (def) == bb)
648+
return;
643649

644-
compute_phi_relations (bb, prev);
650+
if (dump_file && (dump_flags & TDF_DETAILS))
651+
fprintf (dump_file, " from bb%d:", bb->index);
645652

646-
// Compute relations in outgoing edges along the path. Skip the
647-
// final conditional which we don't know yet.
648-
if (i > 1
649-
&& stmt
650-
&& gimple_code (stmt) == GIMPLE_COND
651-
&& irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt))))
652-
{
653-
basic_block next = path[i - 2];
654-
int_range<2> r;
655-
gcond *cond = as_a<gcond *> (stmt);
656-
edge e0 = EDGE_SUCC (bb, 0);
657-
edge e1 = EDGE_SUCC (bb, 1);
658-
659-
if (e0->dest == next)
660-
gcond_edge_range (r, e0);
661-
else if (e1->dest == next)
662-
gcond_edge_range (r, e1);
663-
else
664-
gcc_unreachable ();
665-
666-
src.register_outgoing_edges (cond, r, e0, e1);
667-
}
668-
prev = bb;
669-
}
653+
get_path_oracle ()->killing_def (result);
654+
m_oracle->register_relation (entry_bb (), EQ_EXPR, arg, result);
670655
}
671656

672657
// 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)
681666
if (prev == NULL)
682667
return;
683668

684-
basic_block entry = entry_bb ();
685669
edge e_in = find_edge (prev, bb);
686-
gcc_checking_assert (e_in);
687670

688671
for (gphi_iterator iter = gsi_start_phis (bb); !gsi_end_p (iter);
689672
gsi_next (&iter))
690673
{
691674
gphi *phi = iter.phi ();
692-
tree result = gimple_phi_result (phi);
693675
unsigned nargs = gimple_phi_num_args (phi);
694676

695677
for (size_t i = 0; i < nargs; ++i)
@@ -698,17 +680,36 @@ path_range_query::compute_phi_relations (basic_block bb, basic_block prev)
698680
tree arg = gimple_phi_arg_def (phi, i);
699681

700682
if (gimple_range_ssa_p (arg))
701-
{
702-
if (dump_file && (dump_flags & TDF_DETAILS))
703-
fprintf (dump_file, " from bb%d:", bb->index);
683+
maybe_register_phi_relation (phi, arg);
684+
break;
685+
}
686+
}
687+
}
704688

705-
// Throw away any previous relation.
706-
get_path_oracle ()->killing_def (result);
689+
// Compute outgoing relations from BB to NEXT.
707690

708-
m_oracle->register_relation (entry, EQ_EXPR, arg, result);
709-
}
691+
void
692+
path_range_query::compute_outgoing_relations (basic_block bb, basic_block next)
693+
{
694+
gimple *stmt = last_stmt (bb);
710695

711-
break;
712-
}
696+
if (stmt
697+
&& gimple_code (stmt) == GIMPLE_COND
698+
&& irange::supports_type_p (TREE_TYPE (gimple_cond_lhs (stmt))))
699+
{
700+
int_range<2> r;
701+
gcond *cond = as_a<gcond *> (stmt);
702+
edge e0 = EDGE_SUCC (bb, 0);
703+
edge e1 = EDGE_SUCC (bb, 1);
704+
705+
if (e0->dest == next)
706+
gcond_edge_range (r, e0);
707+
else if (e1->dest == next)
708+
gcond_edge_range (r, e1);
709+
else
710+
gcc_unreachable ();
711+
712+
jt_fur_source src (NULL, this, &m_ranger.gori (), *m_path);
713+
src.register_outgoing_edges (cond, r, e0, e1);
713714
}
714715
}

gcc/gimple-range-path.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class path_range_query : public range_query
5757
void compute_ranges_in_block (basic_block bb);
5858
void adjust_for_non_null_uses (basic_block bb);
5959
void ssa_range_in_phi (irange &r, gphi *phi);
60-
void compute_relations (const vec<basic_block> &);
60+
void compute_outgoing_relations (basic_block bb, basic_block next);
6161
void compute_phi_relations (basic_block bb, basic_block prev);
62+
void maybe_register_phi_relation (gphi *, tree arg);
6263
void add_copies_to_imports ();
6364
bool add_to_imports (tree name, bitmap imports);
6465

0 commit comments

Comments
 (0)