public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/marxin/heads/loop-unswitch-improvement)] Improve costing model - make it selective.
@ 2021-11-19 16:27 Martin Liska
0 siblings, 0 replies; 2+ messages in thread
From: Martin Liska @ 2021-11-19 16:27 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:c7db632e169eac94a68055e7314aa0f6bfdfe1a0
commit c7db632e169eac94a68055e7314aa0f6bfdfe1a0
Author: Martin Liska <mliska@suse.cz>
Date: Fri Nov 19 17:27:31 2021 +0100
Improve costing model - make it selective.
Diff:
---
gcc/tree-ssa-loop-unswitch.c | 334 +++++++++++++++++++++++--------------------
1 file changed, 180 insertions(+), 154 deletions(-)
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index afb4572a62e..aafb6dfb551 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -303,6 +303,137 @@ simplify_using_entry_checks (unswitch_predicate *predicate,
return NULL_TREE;
}
+/* Find all unswitching predicates. */
+
+static bool
+find_all_unswitching_predicates (class loop *loop, basic_block *bbs,
+ bool true_edge,
+ unswitch_predicate *parent_predicate,
+ gimple_ranger *ranger,
+ vec<unswitch_predicate *> &candidates)
+{
+ bool changed = false;
+
+ for (unsigned i = 0; i != loop->num_nodes; i++)
+ {
+ /* Find a bb to unswitch on. */
+ unswitch_predicate *predicate = tree_may_unswitch_on (bbs[i], loop,
+ ranger);
+ if (predicate == NULL)
+ continue;
+
+ tree folded = simplify_using_entry_checks (predicate,
+ parent_predicate, true_edge);
+ gimple *stmt = last_stmt (bbs[i]);
+ if (folded != NULL_TREE)
+ {
+ /* Remove path. */
+ gcond *cond = dyn_cast<gcond *> (stmt);
+ if (integer_nonzerop (folded))
+ gimple_cond_set_condition_from_tree (cond, boolean_true_node);
+ else
+ gimple_cond_set_condition_from_tree (cond, boolean_false_node);
+
+ delete predicate;
+ predicate = NULL;
+ changed = true;
+ }
+ else
+ candidates.safe_push (predicate);
+ }
+
+ return changed;
+}
+
+static unsigned
+evaluate_insns (class loop *loop, basic_block *bbs,
+ unswitch_predicate *candidate, bool true_edge,
+ gimple_ranger *ranger, auto_bb_flag &reachable_flag)
+{
+ auto_vec<basic_block> worklist (loop->num_nodes);
+ worklist.quick_push (bbs[0]);
+
+ while (!worklist.is_empty ())
+ {
+ edge e;
+ edge_iterator ei;
+ int flags = 0;
+ basic_block bb = worklist.pop ();
+
+ if (EDGE_COUNT (bb->succs) == 2)
+ {
+ gcond *cond = dyn_cast<gcond *> (last_stmt (bb));
+ if (cond != NULL)
+ {
+ if (gimple_cond_true_p (cond))
+ flags = EDGE_FALSE_VALUE;
+ else if (gimple_cond_false_p (cond))
+ flags = EDGE_TRUE_VALUE;
+ else
+ {
+ unswitch_predicate *predicate
+ = tree_may_unswitch_on (bb, loop, ranger);
+ if (predicate != NULL)
+ {
+ tree folded
+ = simplify_using_entry_checks (predicate, candidate,
+ true_edge);
+ if (folded == boolean_true_node)
+ flags = EDGE_FALSE_VALUE;
+ else if (folded == boolean_false_node)
+ flags = EDGE_TRUE_VALUE;
+
+ delete predicate;
+ }
+ }
+ }
+ }
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ basic_block dest = e->dest;
+
+ if (dest->loop_father == loop
+ && !(dest->flags & reachable_flag)
+ && !(e->flags & flags))
+ {
+ worklist.safe_push (dest);
+ dest->flags |= reachable_flag;
+ }
+ }
+ }
+
+ /* Evaluate insns. */
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ if (bbs[i]->flags & reachable_flag)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
+
+ /* Clear the flag from basic blocks. */
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ bbs[i]->flags &= ~reachable_flag;
+
+ return size;
+}
+
+static unsigned
+evaluate_loop_insns_for_predicate (class loop *loop, basic_block *bbs,
+ gimple_ranger *ranger,
+ unswitch_predicate *candidate)
+{
+ auto_bb_flag reachable_true (cfun), reachable_false (cfun);
+
+ unsigned true_loop_cost = evaluate_insns (loop, bbs, candidate, true,
+ ranger, reachable_true);
+ unsigned false_loop_cost = evaluate_insns (loop, bbs, candidate, false,
+ ranger, reachable_false);
+
+ return true_loop_cost + false_loop_cost;
+}
+
/* Unswitch single LOOP. NUM is number of unswitchings done; we do not allow
it to grow too much, it is too easy to create example on that the code would
grow exponentially. RANGER is gimple ranger used in this pass. */
@@ -313,9 +444,6 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
{
basic_block *bbs;
class loop *nloop;
- unsigned i, found;
- unswitch_predicate *predicate = NULL;
- gimple *stmt;
bool changed = false;
HOST_WIDE_INT iterations;
@@ -330,15 +458,6 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
return false;
}
- /* The loop should not be too large, to limit code growth. */
- if (tree_num_loop_insns (loop, &eni_size_weights)
- > (unsigned) param_max_unswitch_insns)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, ";; Not unswitching, loop too big\n");
- return false;
- }
-
/* If the loop is not expected to iterate, there is no need
for unswitching. */
iterations = estimated_loop_iterations_int (loop);
@@ -354,169 +473,76 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
}
bbs = get_loop_body (loop);
- found = loop->num_nodes;
+ auto_vec<unswitch_predicate *> candidates;
- for (unsigned i = 0; true; i++)
- {
- /* Find a bb to unswitch on. */
- for (; i < loop->num_nodes; i++)
- if ((predicate = tree_may_unswitch_on (bbs[i], loop, ranger)))
- break;
+ changed = find_all_unswitching_predicates (loop, bbs, true_edge,
+ parent_predicate, ranger,
+ candidates);
- if (i == loop->num_nodes)
- {
- if (dump_file
- && num > param_max_unswitch_level
- && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
+ unswitch_predicate *predicate = NULL;
+ if (num > param_max_unswitch_level)
+ {
+ if (dump_file
+ && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
+ goto exit;
+ }
- if (found == loop->num_nodes)
- goto exit;
- break;
- }
+ for (auto pred: candidates)
+ {
+ unsigned cost
+ = evaluate_loop_insns_for_predicate (loop, bbs, ranger, pred);
- tree folded = simplify_using_entry_checks (predicate,
- parent_predicate, true_edge);
- stmt = last_stmt (bbs[i]);
- if (folded != NULL_TREE && integer_nonzerop (folded))
- {
- /* Remove false path. */
- gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
- boolean_true_node);
- delete predicate;
- predicate = NULL;
- changed = true;
- }
- else if (folded != NULL_TREE && integer_zerop (folded))
- {
- /* Remove true path. */
- gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
- boolean_false_node);
- delete predicate;
- predicate = NULL;
- changed = true;
- }
- /* Do not unswitch too much. */
- else if (num > param_max_unswitch_level)
- continue;
- /* In nested tree_unswitch_single_loop first optimize all conditions
- using entry checks, then discover still reachable blocks in the
- loop and find the condition only among those still reachable bbs. */
- else if (num != 0)
+ if (cost <= (unsigned)param_max_unswitch_insns)
{
- if (found == loop->num_nodes)
- found = i;
- continue;
+ predicate = pred;
+ break;
}
- else
+ else if (dump_file && (dump_flags & TDF_DETAILS))
{
- found = i;
- break;
+ fprintf (dump_file, ";; Not unswitching condition, loop too big "
+ "(%d insns): ", cost);
+ print_generic_expr (dump_file, pred->condition);
+ fprintf (dump_file, "\n");
}
-
- update_stmt (stmt);
}
- if (num != 0)
+ if (predicate != NULL)
{
- basic_block *tos, *worklist;
-
- /* When called recursively, first do a quick discovery
- of reachable bbs after the above changes and only
- consider conditions in still reachable bbs. */
- tos = worklist = XNEWVEC (basic_block, loop->num_nodes);
-
- for (i = 0; i < loop->num_nodes; i++)
- bbs[i]->flags &= ~BB_REACHABLE;
-
- /* Start with marking header. */
- *tos++ = bbs[0];
- bbs[0]->flags |= BB_REACHABLE;
+ if (!dbg_cnt (loop_unswitch))
+ goto exit;
- /* Iterate: find everything reachable from what we've already seen
- within the same innermost loop. Don't look through false edges
- if condition is always true or true edges if condition is
- always false. */
- while (tos != worklist)
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- basic_block b = *--tos;
- edge e;
- edge_iterator ei;
- int flags = 0;
-
- if (EDGE_COUNT (b->succs) == 2)
- {
- gimple *stmt = last_stmt (b);
- if (stmt
- && gimple_code (stmt) == GIMPLE_COND)
- {
- gcond *cond_stmt = as_a <gcond *> (stmt);
- if (gimple_cond_true_p (cond_stmt))
- flags = EDGE_FALSE_VALUE;
- else if (gimple_cond_false_p (cond_stmt))
- flags = EDGE_TRUE_VALUE;
- }
- }
-
- FOR_EACH_EDGE (e, ei, b->succs)
- {
- basic_block dest = e->dest;
-
- if (dest->loop_father == loop
- && !(dest->flags & BB_REACHABLE)
- && !(e->flags & flags))
- {
- *tos++ = dest;
- dest->flags |= BB_REACHABLE;
- }
- }
+ fprintf (dump_file, ";; Unswitching loop with condition: ");
+ print_generic_expr (dump_file, predicate->condition);
+ fprintf (dump_file, "\n");
}
- free (worklist);
-
- /* Find a bb to unswitch on. */
- for (; found < loop->num_nodes; found++)
- if ((bbs[found]->flags & BB_REACHABLE)
- && (predicate = tree_may_unswitch_on (bbs[found], loop, ranger)))
- break;
-
- if (found == loop->num_nodes)
- goto exit;
- }
-
- if (!dbg_cnt (loop_unswitch))
- goto exit;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, ";; Unswitching loop with condition: ");
- print_generic_expr (dump_file, predicate->condition);
- fprintf (dump_file, "\n");
- }
+ initialize_original_copy_tables ();
+ /* Unswitch the loop on this condition. */
+ nloop = tree_unswitch_loop (loop, gimple_bb (predicate->stmt),
+ predicate->condition);
+ if (!nloop)
+ {
+ free_original_copy_tables ();
+ goto exit;
+ }
- initialize_original_copy_tables ();
- /* Unswitch the loop on this condition. */
- nloop = tree_unswitch_loop (loop, bbs[found], predicate->condition);
- if (!nloop)
- {
+ /* Update the SSA form after unswitching. */
+ update_ssa (TODO_update_ssa);
free_original_copy_tables ();
- goto exit;
- }
- /* Update the SSA form after unswitching. */
- update_ssa (TODO_update_ssa);
- free_original_copy_tables ();
-
- /* Invoke itself on modified loops. */
- tree_unswitch_single_loop (nloop, num + 1, ranger, predicate, false);
- tree_unswitch_single_loop (loop, num + 1, ranger, predicate, true);
- delete predicate;
- free (bbs);
- return true;
+ /* Invoke itself on modified loops. */
+ tree_unswitch_single_loop (nloop, num + 1, ranger, predicate, false);
+ tree_unswitch_single_loop (loop, num + 1, ranger, predicate, true);
+ changed = true;
+ }
exit:
+ for (auto predicate: candidates)
+ delete predicate;
free (bbs);
- delete predicate;
return changed;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* [gcc(refs/users/marxin/heads/loop-unswitch-improvement)] Improve costing model - make it selective.
@ 2021-11-22 12:45 Martin Liska
0 siblings, 0 replies; 2+ messages in thread
From: Martin Liska @ 2021-11-22 12:45 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:f6e8549b871b677bcecd9aa3e05ead8bace8fbea
commit f6e8549b871b677bcecd9aa3e05ead8bace8fbea
Author: Martin Liska <mliska@suse.cz>
Date: Fri Nov 19 17:27:31 2021 +0100
Improve costing model - make it selective.
Diff:
---
gcc/tree-ssa-loop-unswitch.c | 334 +++++++++++++++++++++++--------------------
1 file changed, 180 insertions(+), 154 deletions(-)
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index afb4572a62e..aafb6dfb551 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -303,6 +303,137 @@ simplify_using_entry_checks (unswitch_predicate *predicate,
return NULL_TREE;
}
+/* Find all unswitching predicates. */
+
+static bool
+find_all_unswitching_predicates (class loop *loop, basic_block *bbs,
+ bool true_edge,
+ unswitch_predicate *parent_predicate,
+ gimple_ranger *ranger,
+ vec<unswitch_predicate *> &candidates)
+{
+ bool changed = false;
+
+ for (unsigned i = 0; i != loop->num_nodes; i++)
+ {
+ /* Find a bb to unswitch on. */
+ unswitch_predicate *predicate = tree_may_unswitch_on (bbs[i], loop,
+ ranger);
+ if (predicate == NULL)
+ continue;
+
+ tree folded = simplify_using_entry_checks (predicate,
+ parent_predicate, true_edge);
+ gimple *stmt = last_stmt (bbs[i]);
+ if (folded != NULL_TREE)
+ {
+ /* Remove path. */
+ gcond *cond = dyn_cast<gcond *> (stmt);
+ if (integer_nonzerop (folded))
+ gimple_cond_set_condition_from_tree (cond, boolean_true_node);
+ else
+ gimple_cond_set_condition_from_tree (cond, boolean_false_node);
+
+ delete predicate;
+ predicate = NULL;
+ changed = true;
+ }
+ else
+ candidates.safe_push (predicate);
+ }
+
+ return changed;
+}
+
+static unsigned
+evaluate_insns (class loop *loop, basic_block *bbs,
+ unswitch_predicate *candidate, bool true_edge,
+ gimple_ranger *ranger, auto_bb_flag &reachable_flag)
+{
+ auto_vec<basic_block> worklist (loop->num_nodes);
+ worklist.quick_push (bbs[0]);
+
+ while (!worklist.is_empty ())
+ {
+ edge e;
+ edge_iterator ei;
+ int flags = 0;
+ basic_block bb = worklist.pop ();
+
+ if (EDGE_COUNT (bb->succs) == 2)
+ {
+ gcond *cond = dyn_cast<gcond *> (last_stmt (bb));
+ if (cond != NULL)
+ {
+ if (gimple_cond_true_p (cond))
+ flags = EDGE_FALSE_VALUE;
+ else if (gimple_cond_false_p (cond))
+ flags = EDGE_TRUE_VALUE;
+ else
+ {
+ unswitch_predicate *predicate
+ = tree_may_unswitch_on (bb, loop, ranger);
+ if (predicate != NULL)
+ {
+ tree folded
+ = simplify_using_entry_checks (predicate, candidate,
+ true_edge);
+ if (folded == boolean_true_node)
+ flags = EDGE_FALSE_VALUE;
+ else if (folded == boolean_false_node)
+ flags = EDGE_TRUE_VALUE;
+
+ delete predicate;
+ }
+ }
+ }
+ }
+
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ basic_block dest = e->dest;
+
+ if (dest->loop_father == loop
+ && !(dest->flags & reachable_flag)
+ && !(e->flags & flags))
+ {
+ worklist.safe_push (dest);
+ dest->flags |= reachable_flag;
+ }
+ }
+ }
+
+ /* Evaluate insns. */
+ unsigned size = 0;
+
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ if (bbs[i]->flags & reachable_flag)
+ for (gimple_stmt_iterator gsi = gsi_start_bb (bbs[i]); !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
+
+ /* Clear the flag from basic blocks. */
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ bbs[i]->flags &= ~reachable_flag;
+
+ return size;
+}
+
+static unsigned
+evaluate_loop_insns_for_predicate (class loop *loop, basic_block *bbs,
+ gimple_ranger *ranger,
+ unswitch_predicate *candidate)
+{
+ auto_bb_flag reachable_true (cfun), reachable_false (cfun);
+
+ unsigned true_loop_cost = evaluate_insns (loop, bbs, candidate, true,
+ ranger, reachable_true);
+ unsigned false_loop_cost = evaluate_insns (loop, bbs, candidate, false,
+ ranger, reachable_false);
+
+ return true_loop_cost + false_loop_cost;
+}
+
/* Unswitch single LOOP. NUM is number of unswitchings done; we do not allow
it to grow too much, it is too easy to create example on that the code would
grow exponentially. RANGER is gimple ranger used in this pass. */
@@ -313,9 +444,6 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
{
basic_block *bbs;
class loop *nloop;
- unsigned i, found;
- unswitch_predicate *predicate = NULL;
- gimple *stmt;
bool changed = false;
HOST_WIDE_INT iterations;
@@ -330,15 +458,6 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
return false;
}
- /* The loop should not be too large, to limit code growth. */
- if (tree_num_loop_insns (loop, &eni_size_weights)
- > (unsigned) param_max_unswitch_insns)
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, ";; Not unswitching, loop too big\n");
- return false;
- }
-
/* If the loop is not expected to iterate, there is no need
for unswitching. */
iterations = estimated_loop_iterations_int (loop);
@@ -354,169 +473,76 @@ tree_unswitch_single_loop (class loop *loop, int num, gimple_ranger *ranger,
}
bbs = get_loop_body (loop);
- found = loop->num_nodes;
+ auto_vec<unswitch_predicate *> candidates;
- for (unsigned i = 0; true; i++)
- {
- /* Find a bb to unswitch on. */
- for (; i < loop->num_nodes; i++)
- if ((predicate = tree_may_unswitch_on (bbs[i], loop, ranger)))
- break;
+ changed = find_all_unswitching_predicates (loop, bbs, true_edge,
+ parent_predicate, ranger,
+ candidates);
- if (i == loop->num_nodes)
- {
- if (dump_file
- && num > param_max_unswitch_level
- && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
+ unswitch_predicate *predicate = NULL;
+ if (num > param_max_unswitch_level)
+ {
+ if (dump_file
+ && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, ";; Not unswitching anymore, hit max level\n");
+ goto exit;
+ }
- if (found == loop->num_nodes)
- goto exit;
- break;
- }
+ for (auto pred: candidates)
+ {
+ unsigned cost
+ = evaluate_loop_insns_for_predicate (loop, bbs, ranger, pred);
- tree folded = simplify_using_entry_checks (predicate,
- parent_predicate, true_edge);
- stmt = last_stmt (bbs[i]);
- if (folded != NULL_TREE && integer_nonzerop (folded))
- {
- /* Remove false path. */
- gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
- boolean_true_node);
- delete predicate;
- predicate = NULL;
- changed = true;
- }
- else if (folded != NULL_TREE && integer_zerop (folded))
- {
- /* Remove true path. */
- gimple_cond_set_condition_from_tree (as_a <gcond *> (stmt),
- boolean_false_node);
- delete predicate;
- predicate = NULL;
- changed = true;
- }
- /* Do not unswitch too much. */
- else if (num > param_max_unswitch_level)
- continue;
- /* In nested tree_unswitch_single_loop first optimize all conditions
- using entry checks, then discover still reachable blocks in the
- loop and find the condition only among those still reachable bbs. */
- else if (num != 0)
+ if (cost <= (unsigned)param_max_unswitch_insns)
{
- if (found == loop->num_nodes)
- found = i;
- continue;
+ predicate = pred;
+ break;
}
- else
+ else if (dump_file && (dump_flags & TDF_DETAILS))
{
- found = i;
- break;
+ fprintf (dump_file, ";; Not unswitching condition, loop too big "
+ "(%d insns): ", cost);
+ print_generic_expr (dump_file, pred->condition);
+ fprintf (dump_file, "\n");
}
-
- update_stmt (stmt);
}
- if (num != 0)
+ if (predicate != NULL)
{
- basic_block *tos, *worklist;
-
- /* When called recursively, first do a quick discovery
- of reachable bbs after the above changes and only
- consider conditions in still reachable bbs. */
- tos = worklist = XNEWVEC (basic_block, loop->num_nodes);
-
- for (i = 0; i < loop->num_nodes; i++)
- bbs[i]->flags &= ~BB_REACHABLE;
-
- /* Start with marking header. */
- *tos++ = bbs[0];
- bbs[0]->flags |= BB_REACHABLE;
+ if (!dbg_cnt (loop_unswitch))
+ goto exit;
- /* Iterate: find everything reachable from what we've already seen
- within the same innermost loop. Don't look through false edges
- if condition is always true or true edges if condition is
- always false. */
- while (tos != worklist)
+ if (dump_file && (dump_flags & TDF_DETAILS))
{
- basic_block b = *--tos;
- edge e;
- edge_iterator ei;
- int flags = 0;
-
- if (EDGE_COUNT (b->succs) == 2)
- {
- gimple *stmt = last_stmt (b);
- if (stmt
- && gimple_code (stmt) == GIMPLE_COND)
- {
- gcond *cond_stmt = as_a <gcond *> (stmt);
- if (gimple_cond_true_p (cond_stmt))
- flags = EDGE_FALSE_VALUE;
- else if (gimple_cond_false_p (cond_stmt))
- flags = EDGE_TRUE_VALUE;
- }
- }
-
- FOR_EACH_EDGE (e, ei, b->succs)
- {
- basic_block dest = e->dest;
-
- if (dest->loop_father == loop
- && !(dest->flags & BB_REACHABLE)
- && !(e->flags & flags))
- {
- *tos++ = dest;
- dest->flags |= BB_REACHABLE;
- }
- }
+ fprintf (dump_file, ";; Unswitching loop with condition: ");
+ print_generic_expr (dump_file, predicate->condition);
+ fprintf (dump_file, "\n");
}
- free (worklist);
-
- /* Find a bb to unswitch on. */
- for (; found < loop->num_nodes; found++)
- if ((bbs[found]->flags & BB_REACHABLE)
- && (predicate = tree_may_unswitch_on (bbs[found], loop, ranger)))
- break;
-
- if (found == loop->num_nodes)
- goto exit;
- }
-
- if (!dbg_cnt (loop_unswitch))
- goto exit;
-
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, ";; Unswitching loop with condition: ");
- print_generic_expr (dump_file, predicate->condition);
- fprintf (dump_file, "\n");
- }
+ initialize_original_copy_tables ();
+ /* Unswitch the loop on this condition. */
+ nloop = tree_unswitch_loop (loop, gimple_bb (predicate->stmt),
+ predicate->condition);
+ if (!nloop)
+ {
+ free_original_copy_tables ();
+ goto exit;
+ }
- initialize_original_copy_tables ();
- /* Unswitch the loop on this condition. */
- nloop = tree_unswitch_loop (loop, bbs[found], predicate->condition);
- if (!nloop)
- {
+ /* Update the SSA form after unswitching. */
+ update_ssa (TODO_update_ssa);
free_original_copy_tables ();
- goto exit;
- }
- /* Update the SSA form after unswitching. */
- update_ssa (TODO_update_ssa);
- free_original_copy_tables ();
-
- /* Invoke itself on modified loops. */
- tree_unswitch_single_loop (nloop, num + 1, ranger, predicate, false);
- tree_unswitch_single_loop (loop, num + 1, ranger, predicate, true);
- delete predicate;
- free (bbs);
- return true;
+ /* Invoke itself on modified loops. */
+ tree_unswitch_single_loop (nloop, num + 1, ranger, predicate, false);
+ tree_unswitch_single_loop (loop, num + 1, ranger, predicate, true);
+ changed = true;
+ }
exit:
+ for (auto predicate: candidates)
+ delete predicate;
free (bbs);
- delete predicate;
return changed;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-11-22 12:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-11-19 16:27 [gcc(refs/users/marxin/heads/loop-unswitch-improvement)] Improve costing model - make it selective Martin Liska
2021-11-22 12:45 Martin Liska
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).