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
next 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).