aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/simplify.c
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-01-10 10:24:46 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2018-08-26 01:14:15 +0200
commit2be8fdea5dc4160898bc820e05f65c6f1cd149cb (patch)
tree5148c165602cc9940255f98874607d12b7364d14 /simplify.c
parent9dd1abf2b98f678dba616ddbf587666a14367b9a (diff)
downloadsparse-dev-2be8fdea5dc4160898bc820e05f65c6f1cd149cb.tar.gz
add a function to remove deadborn instructions
The values produced by expressions are not always used, it's normal. However this produce useless code that will need to be removed, sooner or later. Currently, this removal of dead instructions is done as part of the normal instruction simplification where each kind of instruction are checked if it is used or not and, if not, the usage is removed from the operands and the instruction itself is removed. This has several drawbacks: * this is done at each simplification cycle while it is only needed just after linearization * there is a large overlap between what is needed to correctly remove these dead instructions and kill_instruction() * instructions which are not simplified are forgotten for this and thus never removed. Change this by adding a separate function to remove these deadborn instructions. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
Diffstat (limited to 'simplify.c')
-rw-r--r--simplify.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/simplify.c b/simplify.c
index a786579e..76e94a11 100644
--- a/simplify.c
+++ b/simplify.c
@@ -369,6 +369,28 @@ static int dead_insn(struct instruction *insn, pseudo_t *src1, pseudo_t *src2, p
return REPEAT_CSE;
}
+static inline bool has_target(struct instruction *insn)
+{
+ return opcode_table[insn->opcode].flags & OPF_TARGET;
+}
+
+void remove_dead_insns(struct entrypoint *ep)
+{
+ struct basic_block *bb;
+
+ FOR_EACH_PTR_REVERSE(ep->bbs, bb) {
+ struct instruction *insn;
+ FOR_EACH_PTR_REVERSE(bb->insns, insn) {
+ if (!insn->bb)
+ continue;
+ if (!has_target(insn))
+ continue;
+ if (!has_users(insn->target))
+ kill_instruction(insn);
+ } END_FOR_EACH_PTR_REVERSE(insn);
+ } END_FOR_EACH_PTR_REVERSE(bb);
+}
+
static inline int constant(pseudo_t pseudo)
{
return pseudo->type == PSEUDO_VAL;