ifcvt: improve cost estimation (PR 87047)
authorAlexander Monakov <amonakov@ispras.ru>
Wed, 2 Oct 2019 15:37:12 +0000 (18:37 +0300)
committerAlexander Monakov <amonakov@gcc.gnu.org>
Wed, 2 Oct 2019 15:37:12 +0000 (18:37 +0300)
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

gcc/ChangeLog
gcc/ifcvt.c
gcc/ifcvt.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr87047.c [new file with mode: 0644]

index 5dc53312b671db3021bb76d8f757b77fd0700419..4f7edd28ecc637d8b77826e267b34f65dcbc6886 100644 (file)
@@ -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.
index e0c9522057a13371dd77aa52b7b60be3504b94e9..8bc6f53cb38d8ffa41eddf0fb2564e69352d661f 100644 (file)
@@ -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;
 
index 153ad961b2c53b0f7a77f285d8302d2a92d641c3..40ad744bfc2cb48b5a49d6224f86e7d9cd8b5153 100644 (file)
@@ -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
index f09db23a53f292afa266760dd514dfb4021505c2..d6cd8ca2876a80fed6651ea2eeda72a50d9d9a85 100644 (file)
@@ -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 (file)
index 0000000..cb26ea4
--- /dev/null
@@ -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" } } */