Commit 1764d63b by Alexander Monakov Committed by Alexander Monakov

ifcvt: improve cost estimation (PR 87047)

	PR rtl-optimization/87047
	* ifcvt.c (average_cost): New static function.  Use it...
	(noce_process_if_block): ... here.

testsuite/
	* gcc.dg/pr87047.c: New test.

From-SVN: r276466
parent a264ea9a
2019-10-02 Alexander Monakov <amonakov@ispras.ru>
PR rtl-optimization/87047
* ifcvt.c (average_cost): New static function. Use it...
(noce_process_if_block): ... here.
2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com> 2019-10-02 Aaron Sawdey <acsawdey@linux.ibm.com>
* config/rs6000/rs6000-protos.h (expand_block_move): Change prototype. * config/rs6000/rs6000-protos.h (expand_block_move): Change prototype.
......
...@@ -3358,6 +3358,16 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) ...@@ -3358,6 +3358,16 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb)
return count > 1 && count <= param; return count > 1 && count <= param;
} }
/* Compute average of two given costs weighted by relative probabilities
of respective basic blocks in an IF-THEN-ELSE. E is the IF-THEN edge.
With P as the probability to take the IF-THEN branch, return
P * THEN_COST + (1 - P) * ELSE_COST. */
static unsigned
average_cost (unsigned then_cost, unsigned else_cost, edge e)
{
return else_cost + e->probability.apply ((signed) (then_cost - else_cost));
}
/* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert /* Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert
it without using conditional execution. Return TRUE if we were successful it without using conditional execution. Return TRUE if we were successful
at converting the block. */ at converting the block. */
...@@ -3413,10 +3423,9 @@ noce_process_if_block (struct noce_if_info *if_info) ...@@ -3413,10 +3423,9 @@ noce_process_if_block (struct noce_if_info *if_info)
&if_info->else_simple)) &if_info->else_simple))
return false; return false;
if (else_bb == NULL) if (speed_p)
if_info->original_cost += then_cost; if_info->original_cost += average_cost (then_cost, else_cost,
else if (speed_p) find_edge (test_bb, then_bb));
if_info->original_cost += MIN (then_cost, else_cost);
else else
if_info->original_cost += then_cost + else_cost; if_info->original_cost += then_cost + else_cost;
......
...@@ -97,8 +97,8 @@ struct noce_if_info ...@@ -97,8 +97,8 @@ struct noce_if_info
/* An estimate of the original costs. When optimizing for size, this is the /* An estimate of the original costs. When optimizing for size, this is the
combined cost of COND, JUMP and the costs for THEN_BB and ELSE_BB. combined cost of COND, JUMP and the costs for THEN_BB and ELSE_BB.
When optimizing for speed, we use the costs of COND plus the minimum of When optimizing for speed, we use the costs of COND plus weighted average
the costs for THEN_BB and ELSE_BB, as computed in the next field. */ of the costs for THEN_BB and ELSE_BB, as computed in the next field. */
unsigned int original_cost; unsigned int original_cost;
/* Maximum permissible cost for the unconditional sequence we should /* Maximum permissible cost for the unconditional sequence we should
......
2019-10-02 Alexander Monakov <amonakov@ispras.ru>
PR rtl-optimization/87047
* gcc.dg/pr87047.c: New test.
2019-10-02 Martin Jambor <mjambor@suse.cz> 2019-10-02 Martin Jambor <mjambor@suse.cz>
PR testsuite/91842 PR testsuite/91842
......
/* { dg-do compile { target { { i?86-*-* x86_64-*-* } && { ! ia32 } } } } */
/* { dg-options "-fdump-rtl-ce1 -O2" } */
typedef unsigned long long uint64_t;
static uint64_t umulh(uint64_t a, uint64_t b)
{
return (unsigned __int128)a*b >> 64;
}
uint64_t f(uint64_t a, uint64_t b, int c)
{
if (c)
a = umulh(a, (b-umulh(a,b))<<44) << 1;
return a;
}
/* { dg-final { scan-rtl-dump "0 true changes made" "ce1" } } */
/* { dg-final { scan-assembler-not "cmov" } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment