From: Pranith Kumar <bobby.prani@gmail.com>
To: Richard Henderson <rth@twiddle.net>,
"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: alex.bennee@linaro.org
Subject: [Qemu-devel] [RFC v2 PATCH] tcg: Optimize fence instructions
Date: Tue, 9 Aug 2016 19:12:46 -0400 [thread overview]
Message-ID: <20160809231246.4537-1-bobby.prani@gmail.com> (raw)
This commit optimizes fence instructions. Two optimizations are
currently implemented. These are:
1. Unnecessary duplicate fence instructions
If the same fence instruction is detected consecutively, we remove
one instance of it.
ex: mb; mb => mb, strl; strl => strl
2. Merging weaker fence with subsequent/previous stronger fence
load-acquire/store-release fence can be combined with a full fence
without relaxing the ordering constraint.
ex: a) ld; ldaq; mb => ld; mb
b) mb; strl; st => mb; st
Signed-off-by: Pranith Kumar <bobby.prani@gmail.com>
---
v2:
- Properly remove current op
- Reset only when you encounter memory operations or end of block
- Review comments from v1
tcg/optimize.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
tcg/tcg.c | 4 +++
tcg/tcg.h | 1 +
3 files changed, 89 insertions(+)
diff --git a/tcg/optimize.c b/tcg/optimize.c
index cffe89b..5963a39 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -538,6 +538,90 @@ static bool swap_commutative2(TCGArg *p1, TCGArg *p2)
return false;
}
+/* Eliminate duplicate and unnecessary fence instructions */
+void tcg_optimize_mb(TCGContext *s)
+{
+ int oi, oi_next;
+ TCGArg prev_op_mb = -1;
+ TCGOp *prev_op = NULL;
+
+ for (oi = s->gen_op_buf[0].next; oi != 0; oi = oi_next) {
+ TCGOp *op = &s->gen_op_buf[oi];
+ TCGArg *args = &s->gen_opparam_buf[op->args];
+ TCGOpcode opc = op->opc;
+
+ switch (opc) {
+ case INDEX_op_mb:
+ {
+ TCGBar curr_mb_type = args[0] & 0xF0;
+ TCGBar prev_mb_type = prev_op_mb & 0xF0;
+
+ if (curr_mb_type == prev_mb_type ||
+ (curr_mb_type == TCG_BAR_STRL && prev_mb_type == TCG_BAR_SC)) {
+ /* Remove the current weaker barrier op. The previous
+ * barrier is stronger and sufficient.
+ * mb; strl => mb; st
+ */
+ tcg_op_remove(s, op);
+ op = prev_op;
+ break;
+ } else if (curr_mb_type == TCG_BAR_SC &&
+ prev_mb_type == TCG_BAR_LDAQ) {
+ /* Remove the previous weaker barrier op. The current
+ * barrier is stronger and sufficient.
+ * ldaq; mb => ld; mb
+ */
+ tcg_op_remove(s, prev_op);
+ } else if (curr_mb_type == TCG_BAR_STRL &&
+ prev_mb_type == TCG_BAR_LDAQ) {
+ /* Consecutive load-acquire and store-release barriers
+ * can be merged into one stronger SC barrier
+ * ldaq; strl => ld; mb; st
+ */
+ args[0] = (args[0] & 0x0F) | TCG_BAR_SC;
+ tcg_op_remove(s, prev_op);
+ }
+ prev_op_mb = args[0];
+ prev_op = op;
+ break;
+ }
+ case INDEX_op_insn_start:
+ break;
+ case INDEX_op_ld8u_i32:
+ case INDEX_op_ld8u_i64:
+ case INDEX_op_ld8s_i32:
+ case INDEX_op_ld8s_i64:
+ case INDEX_op_ld16u_i32:
+ case INDEX_op_ld16u_i64:
+ case INDEX_op_ld16s_i32:
+ case INDEX_op_ld16s_i64:
+ case INDEX_op_ld_i32:
+ case INDEX_op_ld32u_i64:
+ case INDEX_op_ld32s_i64:
+ case INDEX_op_ld_i64:
+ case INDEX_op_st8_i32:
+ case INDEX_op_st8_i64:
+ case INDEX_op_st16_i32:
+ case INDEX_op_st16_i64:
+ case INDEX_op_st_i32:
+ case INDEX_op_st32_i64:
+ case INDEX_op_st_i64:
+ case INDEX_op_call:
+ prev_op_mb = -1;
+ prev_op = NULL;
+ break;
+ default:
+ if (tcg_op_defs[opc].flags & TCG_OPF_BB_END) {
+ prev_op_mb = -1;
+ prev_op = NULL;
+ }
+ break;
+ }
+
+ oi_next = op->next;
+ }
+}
+
/* Propagate constants and copies, fold constant expressions. */
void tcg_optimize(TCGContext *s)
{
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 42417bd..1db319e 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2587,6 +2587,10 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb)
}
}
+#ifdef USE_TCG_OPTIMIZATIONS
+ tcg_optimize_mb(s);
+#endif
+
#ifdef CONFIG_PROFILER
s->la_time += profile_getclock();
#endif
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 9ed78dc..79bb5bb 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -921,6 +921,7 @@ void tcg_op_remove(TCGContext *s, TCGOp *op);
TCGOp *tcg_op_insert_before(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
TCGOp *tcg_op_insert_after(TCGContext *s, TCGOp *op, TCGOpcode opc, int narg);
+void tcg_optimize_mb(TCGContext *s);
void tcg_optimize(TCGContext *s);
/* only used for debugging purposes */
--
2.9.2
next reply other threads:[~2016-08-09 23:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-09 23:12 Pranith Kumar [this message]
2016-08-09 23:18 ` [Qemu-devel] [RFC v2 PATCH] tcg: Optimize fence instructions no-reply
[not found] ` <9212daae-d1de-7e5b-f5a3-3a60e754de6a@twiddle.net>
2016-08-10 17:58 ` Pranith Kumar
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=20160809231246.4537-1-bobby.prani@gmail.com \
--to=bobby.prani@gmail.com \
--cc=alex.bennee@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=rth@twiddle.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.