public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: guojiufu <guojiufu@linux.ibm.com>
To: gcc-patches@gcc.gnu.org
Cc: guojiufu@linux.ibm.com, wschmidt@linux.ibm.com,
	segher@kernel.crashing.org, dje.gcc@gmail.com
Subject: [PATCH] Check calls before loop unrolling
Date: Thu, 20 Aug 2020 12:34:45 +0800	[thread overview]
Message-ID: <20200820043445.2216872-1-guojiufu@linux.ibm.com> (raw)

Hi,

When unroll loops, if there are calls inside the loop, those calls
may raise negative impacts for unrolling.  This patch adds a param
param_max_unrolled_calls, and checks if the number of calls inside
the loop bigger than this param, loop is prevent from unrolling.

This patch is checking the _average_ number of calls which is the
summary of call numbers multiply the possibility of the call maybe
executed.  The _average_ number could be a fraction, to keep the
precision, the param is the threshold number multiply 10000.

Bootstrap and regtest pass on powerpc64le.  Is this ok for trunk?

gcc/ChangeLog
2020-08-19  Jiufu Guo   <guojiufu@cn.ibm.com>

	* params.opt (param_max_unrolled_average_calls_x10000): New param.
	* cfgloop.h (average_num_loop_calls): New declare.
	* cfgloopanal.c (average_num_loop_calls): New function.
	* loop-unroll.c (decide_unroll_constant_iteration,
	decide_unroll_runtime_iterations,
	decide_unroll_stupid): Check average_num_loop_calls and
	param_max_unrolled_average_calls_x10000.
---
 gcc/cfgloop.h     |  2 ++
 gcc/cfgloopanal.c | 25 +++++++++++++++++++++++++
 gcc/loop-unroll.c | 10 ++++++++++
 gcc/params.opt    |  4 ++++
 4 files changed, 41 insertions(+)

diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 18b404e292f..dab933da150 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #define GCC_CFGLOOP_H
 
 #include "cfgloopmanip.h"
+#include "sreal.h"
 
 /* Structure to hold decision about unrolling/peeling.  */
 enum lpt_dec
@@ -387,6 +388,7 @@ extern vec<edge> get_loop_exit_edges (const class loop *, basic_block * = NULL);
 extern edge single_exit (const class loop *);
 extern edge single_likely_exit (class loop *loop, vec<edge>);
 extern unsigned num_loop_branches (const class loop *);
+extern sreal average_num_loop_calls (const class loop *);
 
 extern edge loop_preheader_edge (const class loop *);
 extern edge loop_latch_edge (const class loop *);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 0b33e8272a7..a314db4e0c0 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -233,6 +233,31 @@ average_num_loop_insns (const class loop *loop)
   return ret;
 }
 
+/* Count the number of call insns in LOOP.  */
+sreal
+average_num_loop_calls (const class loop *loop)
+{
+  basic_block *bbs;
+  rtx_insn *insn;
+  unsigned int i, bncalls;
+  sreal ncalls = 0;
+
+  bbs = get_loop_body (loop);
+  for (i = 0; i < loop->num_nodes; i++)
+    {
+      bncalls = 0;
+      FOR_BB_INSNS (bbs[i], insn)
+	if (CALL_P (insn))
+	  bncalls++;
+
+      ncalls += (sreal) bncalls
+	* bbs[i]->count.to_sreal_scale (loop->header->count);
+    }
+  free (bbs);
+
+  return ncalls;
+}
+
 /* Returns expected number of iterations of LOOP, according to
    measured or guessed profile.
 
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index 693c7768868..56b8fb37d2a 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -370,6 +370,10 @@ decide_unroll_constant_iterations (class loop *loop, int flags)
     nunroll = nunroll_by_av;
   if (nunroll > (unsigned) param_max_unroll_times)
     nunroll = param_max_unroll_times;
+  if (!loop->unroll
+      && (average_num_loop_calls (loop) * (sreal) 10000).to_int ()
+	   > (unsigned) param_max_unrolled_average_calls_x10000)
+    nunroll = 0;
 
   if (targetm.loop_unroll_adjust)
     nunroll = targetm.loop_unroll_adjust (nunroll, loop);
@@ -689,6 +693,9 @@ decide_unroll_runtime_iterations (class loop *loop, int flags)
     nunroll = nunroll_by_av;
   if (nunroll > (unsigned) param_max_unroll_times)
     nunroll = param_max_unroll_times;
+  if ((average_num_loop_calls (loop) * (sreal) 10000).to_int ()
+      > (unsigned) param_max_unrolled_average_calls_x10000)
+    nunroll = 0;
 
   if (targetm.loop_unroll_adjust)
     nunroll = targetm.loop_unroll_adjust (nunroll, loop);
@@ -1173,6 +1180,9 @@ decide_unroll_stupid (class loop *loop, int flags)
     nunroll = nunroll_by_av;
   if (nunroll > (unsigned) param_max_unroll_times)
     nunroll = param_max_unroll_times;
+  if ((average_num_loop_calls (loop) * (sreal) 10000).to_int ()
+      > (unsigned) param_max_unrolled_average_calls_x10000)
+    nunroll = 0;
 
   if (targetm.loop_unroll_adjust)
     nunroll = targetm.loop_unroll_adjust (nunroll, loop);
diff --git a/gcc/params.opt b/gcc/params.opt
index f39e5d1a012..80605861223 100644
--- a/gcc/params.opt
+++ b/gcc/params.opt
@@ -634,6 +634,10 @@ The maximum number of unrollings of a single loop.
 Common Joined UInteger Var(param_max_unrolled_insns) Init(200) Param Optimization
 The maximum number of instructions to consider to unroll in a loop.
 
+-param=max-unrolled-average-calls-x10000=
+Common Joined UInteger Var(param_max_unrolled_average_calls_x10000) Init(0) Param Optimization
+The maximum number of calls to consider to unroll in a loop on average and multiply 10000.
+
 -param=max-unswitch-insns=
 Common Joined UInteger Var(param_max_unswitch_insns) Init(50) Param Optimization
 The maximum number of insns of an unswitched loop.
-- 
2.25.1


             reply	other threads:[~2020-08-20  4:34 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-20  4:34 guojiufu [this message]
2020-08-24  9:16 ` Richard Biener
2020-08-24 11:16   ` Jan Hubicka
2020-08-25  2:26     ` Jiufu Guo
2020-09-16  3:27     ` Jiufu Guo
2020-09-01  3:33 ` Jiufu Guo
2020-11-19 19:13   ` Jeff Law
2020-11-19 19:42     ` Segher Boessenkool
2020-11-19 19:53       ` Jeff Law
2020-11-19 20:01         ` Segher Boessenkool
2020-11-19 22:30           ` Jeff Law
2020-11-19 23:56             ` Segher Boessenkool
2020-11-20  7:48               ` Richard Biener
2020-11-20 14:58                 ` David Edelsohn
2020-11-20 15:22               ` Jan Hubicka
2020-11-20 18:09                 ` Segher Boessenkool
2020-11-23  8:42                   ` Richard Biener

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200820043445.2216872-1-guojiufu@linux.ibm.com \
    --to=guojiufu@linux.ibm.com \
    --cc=dje.gcc@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=segher@kernel.crashing.org \
    --cc=wschmidt@linux.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).