aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-02-16 05:57:01 +0100
committerChristopher Li <sparse@chrisli.org>2017-02-16 20:43:07 +0800
commitaa07c1187a8971e40a710826a5efecb79812bc8b (patch)
treee086564e2bab075753691f4c09b2dfbf23220469
parentb25e49741013d3b6af9e57fd4e4edb0f0f62ba51 (diff)
downloadsparse-dev-aa07c1187a8971e40a710826a5efecb79812bc8b.tar.gz
add killing of pure calls
OP_CALL were ignored by kill_instruction() but there are two cases were something can or must be done: 1) if the function is pure, it is free of side-effects and can thus be optimized away like others instructions. 2) if force-killed then we need to adjust the usage of all the arguments. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r--simplify.c11
-rw-r--r--validation/kill-pure-call.c17
2 files changed, 28 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index b8944f0f..cacf81f9 100644
--- a/simplify.c
+++ b/simplify.c
@@ -236,6 +236,17 @@ void kill_insn(struct instruction *insn, int force)
kill_use(&insn->cond);
break;
+ case OP_CALL:
+ if (!force) {
+ /* a "pure" function can be killed too */
+ if (!(insn->func->type == PSEUDO_SYM))
+ return;
+ if (!(insn->func->sym->ctype.modifiers & MOD_PURE))
+ return;
+ }
+ kill_use_list(insn->arguments);
+ break;
+
case OP_ENTRY:
/* ignore */
return;
diff --git a/validation/kill-pure-call.c b/validation/kill-pure-call.c
new file mode 100644
index 00000000..d3f78c02
--- /dev/null
+++ b/validation/kill-pure-call.c
@@ -0,0 +1,17 @@
+int side(int a);
+int pure(int a) __attribute__((pure));
+
+int keep(int a) { return side(a) && 0; }
+int kill(int a) { return pure(a) && 0; }
+
+/*
+ * check-name: kill-pure-call
+ * check-command: test-linearize -Wno-decl $file
+ * check-description:
+ * See that the call is optimized away but only
+ * when the function is "pure".
+ *
+ * check-output-ignore
+ * check-output-contains: call\\..* side
+ * check-output-excludes: call\\..* pure
+ */