aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2019-10-02 18:37:12 +0300
committerAlexander Monakov <amonakov@gcc.gnu.org>2019-10-02 18:37:12 +0300
commit1764d63bd98c6c08e993f5c39dfa0247985b1642 (patch)
tree8afecb03e7053f721f894c1ca4ab7fa0bc95928e /gcc
parenta264ea9a5bbbbf78ea8c53b675584d1f218e20db (diff)
downloadgcc-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/ChangeLog6
-rw-r--r--gcc/ifcvt.c17
-rw-r--r--gcc/ifcvt.h4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr87047.c19
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" } } */