diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2017-02-16 05:57:01 +0100 |
|---|---|---|
| committer | Christopher Li <sparse@chrisli.org> | 2017-02-16 20:43:07 +0800 |
| commit | aa07c1187a8971e40a710826a5efecb79812bc8b (patch) | |
| tree | e086564e2bab075753691f4c09b2dfbf23220469 | |
| parent | b25e49741013d3b6af9e57fd4e4edb0f0f62ba51 (diff) | |
| download | sparse-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.c | 11 | ||||
| -rw-r--r-- | validation/kill-pure-call.c | 17 |
2 files changed, 28 insertions, 0 deletions
@@ -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 + */ |
