diff options
author | Alexander Monakov <amonakov@ispras.ru> | 2019-10-02 18:37:12 +0300 |
---|---|---|
committer | Alexander Monakov <amonakov@gcc.gnu.org> | 2019-10-02 18:37:12 +0300 |
commit | 1764d63bd98c6c08e993f5c39dfa0247985b1642 (patch) | |
tree | 8afecb03e7053f721f894c1ca4ab7fa0bc95928e /gcc | |
parent | a264ea9a5bbbbf78ea8c53b675584d1f218e20db (diff) | |
download | gcc-1764d63bd98c6c08e993f5c39dfa0247985b1642.zip gcc-1764d63bd98c6c08e993f5c39dfa0247985b1642.tar.gz gcc-1764d63bd98c6c08e993f5c39dfa0247985b1642.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ifcvt.c | 17 | ||||
-rw-r--r-- | gcc/ifcvt.h | 4 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr87047.c | 19 |
5 files changed, 45 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5dc5331..4f7edd2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +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> * config/rs6000/rs6000-protos.h (expand_block_move): Change prototype. diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index e0c9522..8bc6f53 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -3358,6 +3358,16 @@ bb_ok_for_noce_convert_multiple_sets (basic_block test_bb) 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 it without using conditional execution. Return TRUE if we were successful at converting the block. */ @@ -3413,10 +3423,9 @@ noce_process_if_block (struct noce_if_info *if_info) &if_info->else_simple)) return false; - if (else_bb == NULL) - if_info->original_cost += then_cost; - else if (speed_p) - if_info->original_cost += MIN (then_cost, else_cost); + if (speed_p) + if_info->original_cost += average_cost (then_cost, else_cost, + find_edge (test_bb, then_bb)); else if_info->original_cost += then_cost + else_cost; diff --git a/gcc/ifcvt.h b/gcc/ifcvt.h index 153ad96..40ad744 100644 --- a/gcc/ifcvt.h +++ b/gcc/ifcvt.h @@ -97,8 +97,8 @@ struct noce_if_info /* 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. - When optimizing for speed, we use the costs of COND plus the minimum of - the costs for THEN_BB and ELSE_BB, as computed in the next field. */ + When optimizing for speed, we use the costs of COND plus weighted average + of the costs for THEN_BB and ELSE_BB, as computed in the next field. */ unsigned int original_cost; /* Maximum permissible cost for the unconditional sequence we should diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f09db23..d6cd8ca 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +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> PR testsuite/91842 diff --git a/gcc/testsuite/gcc.dg/pr87047.c b/gcc/testsuite/gcc.dg/pr87047.c new file mode 100644 index 0000000..cb26ea4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr87047.c @@ -0,0 +1,19 @@ +/* { 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" } } */ |