The values produced by expressions are not always used, it's normal. However this produce useless code that will need to be removed, soon 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 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@xxxxxxxxx> --- flow.h | 1 + simplify.c | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/flow.h b/flow.h index c8e12cf0f..099767d40 100644 --- a/flow.h +++ b/flow.h @@ -20,6 +20,7 @@ extern void simplify_memops(struct entrypoint *ep); extern void pack_basic_blocks(struct entrypoint *ep); extern void convert_instruction_target(struct instruction *insn, pseudo_t src); +extern void remove_dead_insns(struct entrypoint *); extern int simplify_instruction(struct instruction *); extern void kill_bb(struct basic_block *); diff --git a/simplify.c b/simplify.c index a786579e9..066ad04ea 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 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; -- 2.18.0