* [PATCH 1/3] extract has_users() from dead_insn()
2017-06-08 7:39 [PATCH 0/3] kill dead loads Luc Van Oostenryck
@ 2017-06-08 7:39 ` Luc Van Oostenryck
2017-06-08 7:39 ` [PATCH 2/3] let kill_instruction() report if it made some changes or not Luc Van Oostenryck
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2017-06-08 7:39 UTC (permalink / raw)
To: linux-sparse; +Cc: Chris Li, Luc Van Oostenryck
so that it can be reused for others uses.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
simplify.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
diff --git a/simplify.c b/simplify.c
index a141ddd43..65114193a 100644
--- a/simplify.c
+++ b/simplify.c
@@ -301,16 +301,23 @@ void kill_insn(struct instruction *insn, int force)
return;
}
+static int has_users(pseudo_t p)
+{
+ struct pseudo_user *pu;
+ FOR_EACH_PTR(p->users, pu) {
+ if (*pu->userp != VOID)
+ return 1;
+ } END_FOR_EACH_PTR(pu);
+ return 0;
+}
+
/*
* Kill trivially dead instructions
*/
static int dead_insn(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, pseudo_t *src3)
{
- struct pseudo_user *pu;
- FOR_EACH_PTR(insn->target->users, pu) {
- if (*pu->userp != VOID)
- return 0;
- } END_FOR_EACH_PTR(pu);
+ if (has_users(insn->target))
+ return 0;
insn->bb = NULL;
kill_use(src1);
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 2/3] let kill_instruction() report if it made some changes or not
2017-06-08 7:39 [PATCH 0/3] kill dead loads Luc Van Oostenryck
2017-06-08 7:39 ` [PATCH 1/3] extract has_users() from dead_insn() Luc Van Oostenryck
@ 2017-06-08 7:39 ` Luc Van Oostenryck
2017-06-08 7:39 ` [PATCH 3/3] kill dead loads Luc Van Oostenryck
2017-06-09 7:46 ` [PATCH 0/3] " Christopher Li
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2017-06-08 7:39 UTC (permalink / raw)
To: linux-sparse; +Cc: Chris Li, Luc Van Oostenryck
This let us take others actions if no changes have been made
and allow simpler call to this function since its effect on
'repeat_phase' can be directly returned.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
flow.h | 10 +++++-----
simplify.c | 17 ++++++++---------
2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/flow.h b/flow.h
index b592ad4d3..a0a685ec5 100644
--- a/flow.h
+++ b/flow.h
@@ -26,14 +26,14 @@ extern void kill_bb(struct basic_block *);
extern void kill_use(pseudo_t *);
extern void kill_unreachable_bbs(struct entrypoint *ep);
-extern void kill_insn(struct instruction *, int force);
-static inline void kill_instruction(struct instruction *insn)
+extern int kill_insn(struct instruction *, int force);
+static inline int kill_instruction(struct instruction *insn)
{
- kill_insn(insn, 0);
+ return kill_insn(insn, 0);
}
-static inline void kill_instruction_force(struct instruction *insn)
+static inline int kill_instruction_force(struct instruction *insn)
{
- kill_insn(insn, 1);
+ return kill_insn(insn, 1);
}
void check_access(struct instruction *insn);
diff --git a/simplify.c b/simplify.c
index 65114193a..d5e219200 100644
--- a/simplify.c
+++ b/simplify.c
@@ -220,10 +220,10 @@ static void kill_use_list(struct pseudo_list *list)
* the function does that unconditionally (must only be used
* for unreachable instructions.
*/
-void kill_insn(struct instruction *insn, int force)
+int kill_insn(struct instruction *insn, int force)
{
if (!insn || !insn->bb)
- return;
+ return 0;
switch (insn->opcode) {
case OP_SEL:
@@ -265,9 +265,9 @@ void kill_insn(struct instruction *insn, int force)
if (!force) {
/* a "pure" function can be killed too */
if (!(insn->func->type == PSEUDO_SYM))
- return;
+ return 0;
if (!(insn->func->sym->ctype.modifiers & MOD_PURE))
- return;
+ return 0;
}
kill_use_list(insn->arguments);
if (insn->func->type == PSEUDO_REG)
@@ -276,20 +276,20 @@ void kill_insn(struct instruction *insn, int force)
case OP_LOAD:
if (!force && insn->type->ctype.modifiers & MOD_VOLATILE)
- return;
+ return 0;
kill_use(&insn->src);
break;
case OP_STORE:
if (!force)
- return;
+ return 0;
kill_use(&insn->src);
kill_use(&insn->target);
break;
case OP_ENTRY:
/* ignore */
- return;
+ return 0;
case OP_BR:
default:
@@ -297,8 +297,7 @@ void kill_insn(struct instruction *insn, int force)
}
insn->bb = NULL;
- repeat_phase |= REPEAT_CSE;
- return;
+ return repeat_phase |= REPEAT_CSE;
}
static int has_users(pseudo_t p)
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH 3/3] kill dead loads
2017-06-08 7:39 [PATCH 0/3] kill dead loads Luc Van Oostenryck
2017-06-08 7:39 ` [PATCH 1/3] extract has_users() from dead_insn() Luc Van Oostenryck
2017-06-08 7:39 ` [PATCH 2/3] let kill_instruction() report if it made some changes or not Luc Van Oostenryck
@ 2017-06-08 7:39 ` Luc Van Oostenryck
2017-06-09 7:46 ` [PATCH 0/3] " Christopher Li
3 siblings, 0 replies; 5+ messages in thread
From: Luc Van Oostenryck @ 2017-06-08 7:39 UTC (permalink / raw)
To: linux-sparse; +Cc: Chris Li, Luc Van Oostenryck
Like others instructions producing a value, OP_LOADs can be dead.
But currently, dead OP_LOAD are not removed, as dead_insn() do for
others instructions.
Fix this by checking at simplification time if OP_LOADs are dead
and call kill_instruction() if it is the case.
NOTE: the fix is the exact same logic than dead_insn() but dead_insn()
kill without discrimination. In our case we want to keep volatiles
OP_LOADs which kill_instruction() does and dead_insn() does not.
Ideally, dead_insn() should use kill_instruction() but this is
a bigger change which will part of another series.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
---
simplify.c | 6 +++++-
validation/optim/load-dead.c | 11 +++++++++++
2 files changed, 16 insertions(+), 1 deletion(-)
create mode 100644 validation/optim/load-dead.c
diff --git a/simplify.c b/simplify.c
index d5e219200..2c95d8b86 100644
--- a/simplify.c
+++ b/simplify.c
@@ -1189,7 +1189,11 @@ int simplify_instruction(struct instruction *insn)
case OP_NOT: case OP_NEG:
return simplify_unop(insn);
- case OP_LOAD: case OP_STORE:
+ case OP_LOAD:
+ if (!has_users(insn->target))
+ return kill_instruction(insn);
+ /* fall-through */
+ case OP_STORE:
return simplify_memop(insn);
case OP_SYMADDR:
if (dead_insn(insn, NULL, NULL, NULL))
diff --git a/validation/optim/load-dead.c b/validation/optim/load-dead.c
new file mode 100644
index 000000000..52538cc2d
--- /dev/null
+++ b/validation/optim/load-dead.c
@@ -0,0 +1,11 @@
+void foo(int *p) { *p; }
+
+int *p;
+void bar(void) { *p; }
+
+/*
+ * check-name: load-dead
+ * check-command: test-linearize -Wno-decl $file
+ * check-output-ignore
+ * check-output-excludes: load\\.
+ */
--
2.13.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 0/3] kill dead loads
2017-06-08 7:39 [PATCH 0/3] kill dead loads Luc Van Oostenryck
` (2 preceding siblings ...)
2017-06-08 7:39 ` [PATCH 3/3] kill dead loads Luc Van Oostenryck
@ 2017-06-09 7:46 ` Christopher Li
3 siblings, 0 replies; 5+ messages in thread
From: Christopher Li @ 2017-06-09 7:46 UTC (permalink / raw)
To: Luc Van Oostenryck; +Cc: Linux-Sparse
On Thu, Jun 8, 2017 at 12:39 AM, Luc Van Oostenryck
<luc.vanoostenryck@gmail.com> wrote:
> The goal of this series is to eliminate dead loads which,
> especially the deadborn ones which, until now, weren't
> removed.
>
> This series is also available in the git repository at:
> git://github.com/lucvoo/sparse.git kill-dead-loads
This 3 patch looks good to me.
Thanks,
Chris
^ permalink raw reply [flat|nested] 5+ messages in thread