mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-22 15:00:55 +08:00
Use post-dom info to update if/switch predicate
2019-09-19 Feng Xue <fxue@os.amperecomputing.com> * ipa-fnsummary.c (set_cond_stmt_execution_predicate): Do not compute trivial predicate for condition branch. (set_switch_stmt_execution_predicate): Do not compute trivial predicate for switch case. (compute_bb_predicates): Update predicate based on post-dominating relationship. (analyze_function_body): Calculate post-dominating information. 2019-09-19 Feng Xue <fxue@os.amperecomputing.com> * gcc.dg/ipa/pr91089.c: Add a new function and pattern. From-SVN: r275963
This commit is contained in:
parent
c449d3ae28
commit
efe126563b
@ -1,3 +1,13 @@
|
||||
2019-09-19 Feng Xue <fxue@os.amperecomputing.com>
|
||||
|
||||
* ipa-fnsummary.c (set_cond_stmt_execution_predicate): Do not compute
|
||||
trivial predicate for condition branch.
|
||||
(set_switch_stmt_execution_predicate): Do not compute trivial predicate
|
||||
for switch case.
|
||||
(compute_bb_predicates): Update predicate based on post-dominating
|
||||
relationship.
|
||||
(analyze_function_body): Calculate post-dominating information.
|
||||
|
||||
2019-09-19 Richard Sandiford <richard.sandiford@arm.com>
|
||||
|
||||
* tree-vectorizer.h (vectorizable_condition): Take an int
|
||||
|
@ -1197,8 +1197,14 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
||||
? code : inverted_code);
|
||||
/* invert_tree_comparison will return ERROR_MARK on FP
|
||||
comparsions that are not EQ/NE instead of returning proper
|
||||
unordered one. Be sure it is not confused with NON_CONSTANT. */
|
||||
if (this_code != ERROR_MARK)
|
||||
unordered one. Be sure it is not confused with NON_CONSTANT.
|
||||
|
||||
And if the edge's target is the final block of diamond CFG graph
|
||||
of this conditional statement, we do not need to compute
|
||||
predicate for the edge because the final block's predicate must
|
||||
be at least as that of the first block of the statement. */
|
||||
if (this_code != ERROR_MARK
|
||||
&& !dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
|
||||
{
|
||||
predicate p
|
||||
= add_condition (summary, index, size, &aggpos, this_code,
|
||||
@ -1282,18 +1288,38 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
||||
*(predicate *) e->aux = false;
|
||||
}
|
||||
|
||||
e = gimple_switch_edge (cfun, last, 0);
|
||||
/* Set BOUND_COUNT to maximum count to bypass computing predicate for
|
||||
default case if its target basic block is in convergence point of all
|
||||
switch cases, which can be determined by checking whether it
|
||||
post-dominates the switch statement. */
|
||||
if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
|
||||
bound_count = INT_MAX;
|
||||
|
||||
n = gimple_switch_num_labels (last);
|
||||
for (case_idx = 1; case_idx < n; ++case_idx)
|
||||
{
|
||||
tree cl = gimple_switch_label (last, case_idx);
|
||||
tree min, max;
|
||||
tree min = CASE_LOW (cl);
|
||||
tree max = CASE_HIGH (cl);
|
||||
predicate p;
|
||||
|
||||
e = gimple_switch_edge (cfun, last, case_idx);
|
||||
min = CASE_LOW (cl);
|
||||
max = CASE_HIGH (cl);
|
||||
/* The case value might not have same type as switch expression,
|
||||
extend the value based on the expression type. */
|
||||
if (TREE_TYPE (min) != type)
|
||||
min = wide_int_to_tree (type, wi::to_wide (min));
|
||||
|
||||
if (!max)
|
||||
max = min;
|
||||
else if (TREE_TYPE (max) != type)
|
||||
max = wide_int_to_tree (type, wi::to_wide (max));
|
||||
|
||||
/* The case's target basic block is in convergence point of all switch
|
||||
cases, its predicate should be at least as that of the switch
|
||||
statement. */
|
||||
if (dominated_by_p (CDI_POST_DOMINATORS, bb, e->dest))
|
||||
p = true;
|
||||
else if (min == max)
|
||||
p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
|
||||
unshare_expr_without_location (min));
|
||||
else
|
||||
@ -1305,6 +1331,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
||||
unshare_expr_without_location (max));
|
||||
p = p1 & p2;
|
||||
}
|
||||
e = gimple_switch_edge (cfun, last, case_idx);
|
||||
*(class predicate *) e->aux
|
||||
= p.or_with (summary->conds, *(class predicate *) e->aux);
|
||||
|
||||
@ -1334,9 +1361,6 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|
||||
}
|
||||
}
|
||||
|
||||
if (!max)
|
||||
max = min;
|
||||
|
||||
/* Create/extend a case range. And we count endpoints of range set,
|
||||
this number nearly equals to number of conditions that we will create
|
||||
for predicate of default case. */
|
||||
@ -1463,10 +1487,10 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p == false)
|
||||
gcc_checking_assert (!bb->aux);
|
||||
else
|
||||
if (p != false)
|
||||
{
|
||||
basic_block pdom_bb;
|
||||
|
||||
if (!bb->aux)
|
||||
{
|
||||
done = false;
|
||||
@ -1485,6 +1509,34 @@ compute_bb_predicates (struct ipa_func_body_info *fbi,
|
||||
*((predicate *) bb->aux) = p;
|
||||
}
|
||||
}
|
||||
|
||||
/* For switch/if statement, we can OR-combine predicates of all
|
||||
its cases/branches to get predicate for basic block in their
|
||||
convergence point, but sometimes this will generate very
|
||||
complicated predicate. Actually, we can get simplified
|
||||
predicate in another way by using the fact that predicate
|
||||
for a basic block must also hold true for its post dominators.
|
||||
To be specific, basic block in convergence point of
|
||||
conditional statement should include predicate of the
|
||||
statement. */
|
||||
pdom_bb = get_immediate_dominator (CDI_POST_DOMINATORS, bb);
|
||||
if (pdom_bb == EXIT_BLOCK_PTR_FOR_FN (my_function) || !pdom_bb)
|
||||
;
|
||||
else if (!pdom_bb->aux)
|
||||
{
|
||||
done = false;
|
||||
pdom_bb->aux = edge_predicate_pool.allocate ();
|
||||
*((predicate *) pdom_bb->aux) = p;
|
||||
}
|
||||
else if (p != *(predicate *) pdom_bb->aux)
|
||||
{
|
||||
p = p.or_with (summary->conds, *(predicate *)pdom_bb->aux);
|
||||
if (p != *(predicate *) pdom_bb->aux)
|
||||
{
|
||||
done = false;
|
||||
*((predicate *) pdom_bb->aux) = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2089,6 +2141,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
||||
if (opt_for_fn (node->decl, optimize))
|
||||
{
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
if (!early)
|
||||
loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
|
||||
else
|
||||
@ -2469,6 +2522,7 @@ analyze_function_body (struct cgraph_node *node, bool early)
|
||||
else if (!ipa_edge_args_sum)
|
||||
ipa_free_all_node_params ();
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
}
|
||||
if (dump_file)
|
||||
{
|
||||
|
@ -1,8 +1,13 @@
|
||||
2019-09-19 Feng Xue <fxue@os.amperecomputing.com>
|
||||
|
||||
* gcc.dg/ipa/pr91089.c: Add a new function and pattern.
|
||||
|
||||
2019-09-19 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR tree-optimization/91812
|
||||
* gcc.dg/torture/pr91812.c: New testcase.
|
||||
|
||||
>>>>>>> .r275960
|
||||
2019-09-19 Tom Tromey <tromey@adacore.com>
|
||||
|
||||
* gnat.dg/bias1.adb: New testcase.
|
||||
|
@ -41,6 +41,52 @@ int callee (int i)
|
||||
return data += i;
|
||||
}
|
||||
|
||||
int fn2 ();
|
||||
|
||||
int callee_complex_predicate (int i)
|
||||
{
|
||||
switch (i )
|
||||
{
|
||||
case 0:
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
case 1:
|
||||
fn ();
|
||||
fn ();
|
||||
case -1:
|
||||
fn ();
|
||||
case -2:
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
fn ();
|
||||
data += i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == 1000)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 100; j++)
|
||||
fn2 ();
|
||||
}
|
||||
return i + 3;
|
||||
}
|
||||
|
||||
int caller ()
|
||||
{
|
||||
return callee (-127) +
|
||||
@ -60,3 +106,4 @@ int caller ()
|
||||
/* { dg-final { scan-ipa-dump "op0 != 0" "fnsummary" } } */
|
||||
/* { dg-final { scan-ipa-dump "op0 < 5" "fnsummary" } } */
|
||||
/* { dg-final { scan-ipa-dump "op0 > 7" "fnsummary" } } */
|
||||
/* { dg-final { scan-ipa-dump "loop depth: 1 .+ time:\[ \]*\[0-9\]+ predicate: \\(op0 == 1000\\)\[\r\n]+" "fnsummary" } } */
|
||||
|
Loading…
x
Reference in New Issue
Block a user