All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
To: linux-sparse@vger.kernel.org
Cc: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Subject: [PATCH] experimental: code sinking
Date: Fri,  4 Dec 2020 17:33:15 +0100	[thread overview]
Message-ID: <20201204163315.68538-1-luc.vanoostenryck@gmail.com> (raw)

A lot of the false 'context imbalance' warnings are caused by
a potential jump-threading being blocked between 2 conditional
branches on the same condition because the second CBR belong
to a non-empty BB. Often the offending instructions can be moved
to some other BB, sometimes even with some added advantages.

This patch help a bit with these false warnings by doing a limited
form of code sinking: blocking instructions with a single user
are moved in the BB where they're used, possibly making the
original BB empty and thus making the jump-threading possible.

Note: It's not the intention to use the patch as is.
      Ideally, it should first be checked if the original BB
      can be made empty before moving the instructions around,
      but this should be coordinated with other ways of moving
      these instructions.

Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
 Makefile    |  1 +
 code-sink.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 optimize.c  |  2 ++
 optimize.h  |  3 ++
 4 files changed, 98 insertions(+)
 create mode 100644 code-sink.c

diff --git a/Makefile b/Makefile
index 313664467151..5ba54659f625 100644
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,7 @@ LIB_OBJS :=
 LIB_OBJS += allocate.o
 LIB_OBJS += builtin.o
 LIB_OBJS += char.o
+LIB_OBJS += code-sink.o
 LIB_OBJS += compat-$(OS).o
 LIB_OBJS += cse.o
 LIB_OBJS += dissect.o
diff --git a/code-sink.c b/code-sink.c
new file mode 100644
index 000000000000..566ddec028a0
--- /dev/null
+++ b/code-sink.c
@@ -0,0 +1,92 @@
+#include "optimize.h"
+#include "lib.h"
+#include "linearize.h"
+
+
+static inline struct instruction *get_user(pseudo_t p)
+{
+	struct pseudo_user *pu;
+
+	FOR_EACH_PTR(p->users, pu) {
+		if (!pu)
+			continue;
+		return pu->insn;
+	} END_FOR_EACH_PTR(pu);
+	return NULL;
+}
+
+static bool sink_insn(struct instruction *insn, struct basic_block *bb)
+{
+	struct instruction *curr;
+
+	FOR_EACH_PTR(bb->insns, curr) {
+		if (!curr->bb)
+			continue;
+		if (curr->opcode == OP_PHI)
+			continue;
+		INSERT_CURRENT(insn, curr);
+		insn->bb = bb;
+		return true;
+	} END_FOR_EACH_PTR(curr);
+	return false;
+}
+
+static int code_sink_bb(struct basic_block *bb)
+{
+	struct instruction *insn;
+	int changed = 0;
+
+	FOR_EACH_PTR_REVERSE(bb->insns, insn) {
+		struct instruction *user;
+		pseudo_t target;
+
+		if (!insn->bb)
+			continue;
+		switch (insn->opcode) {
+		case OP_BINARY ... OP_BINCMP_END:
+		case OP_UNOP ... OP_UNOP_END:
+		case OP_SYMADDR:
+		case OP_SLICE:
+		case OP_SEL: case OP_FMADD:
+		case OP_LABEL: case OP_SETVAL: case OP_SETFVAL:
+			break;
+		case OP_CBR:
+		case OP_INLINED_CALL:
+		case OP_NOP:
+			continue;
+		default:
+			continue;
+		}
+
+		target = insn->target;
+		if (!one_use(target))
+			continue;
+		user = get_user(target);
+		if (!user || !user->bb || user->bb == bb)
+			continue;
+		if (!sink_insn(insn, user->bb))
+			continue;
+		DELETE_CURRENT_PTR(insn);
+		changed = 1;
+	} END_FOR_EACH_PTR_REVERSE(insn);
+	return changed;
+}
+
+int code_sink(struct entrypoint *ep)
+{
+	struct basic_block *bb;
+	int changed = 0;
+
+	FOR_EACH_PTR(ep->bbs, bb) {
+		struct instruction *last;
+
+		if (!bb->ep)
+			continue;
+		last = last_instruction(bb->insns);
+		switch (last->opcode) {
+		case OP_CBR:
+			changed |= code_sink_bb(bb);
+		}
+	} END_FOR_EACH_PTR(bb);
+	return changed;
+}
diff --git a/optimize.c b/optimize.c
index 3351e67b9d5e..b652b0e76d2a 100644
--- a/optimize.c
+++ b/optimize.c
@@ -105,6 +105,8 @@ repeat:
 		pack_basic_blocks(ep);
 		if (repeat_phase & REPEAT_CFG_CLEANUP)
 			cleanup_cfg(ep);
+		if (code_sink(ep))
+			repeat_phase |= REPEAT_CSE;
 	} while (repeat_phase);
 
 	vrfy_flow(ep);
diff --git a/optimize.h b/optimize.h
index 31e2cf081704..d9ac9cd48ea2 100644
--- a/optimize.h
+++ b/optimize.h
@@ -6,4 +6,7 @@ struct entrypoint;
 /* optimize.c */
 void optimize(struct entrypoint *ep);
 
+/* sink.c */
+int code_sink(struct entrypoint *ep);
+
 #endif
-- 
2.29.2


             reply	other threads:[~2020-12-04 16:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-04 16:33 Luc Van Oostenryck [this message]
2020-12-04 17:13 ` [PATCH] experimental: code sinking Linus Torvalds
2020-12-04 17:45   ` Luc Van Oostenryck
2020-12-04 18:15     ` Linus Torvalds
2020-12-04 20:23       ` Luc Van Oostenryck

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=20201204163315.68538-1-luc.vanoostenryck@gmail.com \
    --to=luc.vanoostenryck@gmail.com \
    --cc=linux-sparse@vger.kernel.org \
    /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.