aboutsummaryrefslogtreecommitdiffstats
path: root/cse.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-23 19:43:16 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:04:38 -0700
commitec0abd07637bd9075d13edc1ae5adccd7697edca (patch)
treee5dcd096bc2b8536ac972a704c259416126f437f /cse.c
parent3c6c27fe15154293724fb640cf7de166a0e8677d (diff)
downloadsparse-ec0abd07637bd9075d13edc1ae5adccd7697edca.tar.gz
sparse-ec0abd07637bd9075d13edc1ae5adccd7697edca.tar.xz
sparse-ec0abd07637bd9075d13edc1ae5adccd7697edca.zip
Kill trivially dead instructions
That is - simple instructions with no users.
Diffstat (limited to 'cse.c')
-rw-r--r--cse.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/cse.c b/cse.c
index f7d27ff..7dd8c9d 100644
--- a/cse.c
+++ b/cse.c
@@ -64,10 +64,57 @@ static unsigned long clean_up_phi(struct instruction *insn)
return hash;
}
+static void try_to_kill(struct instruction *);
+
+static void kill_use(pseudo_t pseudo)
+{
+ if (pseudo->type == PSEUDO_REG) {
+ if (ptr_list_size((struct ptr_list *)pseudo->users) == 1) {
+ try_to_kill(pseudo->def);
+ }
+ }
+}
+
+static void try_to_kill(struct instruction *insn)
+{
+ int opcode = insn->opcode;
+ switch (opcode) {
+ case OP_BINARY ... OP_BINCMP_END:
+ insn->bb = NULL;
+ kill_use(insn->src1);
+ kill_use(insn->src2);
+ return;
+ case OP_NOT: case OP_NEG:
+ insn->bb = NULL;
+ kill_use(insn->src1);
+ return;
+
+ case OP_PHI: case OP_SETVAL:
+ insn->bb = NULL;
+ return;
+ }
+}
+
+/*
+ * Kill trivially dead instructions
+ */
+static int dead_insn(struct instruction *insn, pseudo_t src1, pseudo_t src2)
+{
+ if (!insn->target->users) {
+ insn->bb = NULL;
+ kill_use(src1);
+ kill_use(src2);
+ return 1;
+ }
+ return 0;
+}
+
static void clean_up_one_instruction(struct basic_block *bb, struct instruction *insn)
{
unsigned long hash;
+ if (!insn->bb)
+ return;
if (insn->bb != bb)
warning(bb->pos, "instruction with bad bb");
hash = insn->opcode;
@@ -90,22 +137,30 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
case OP_SET_LT: case OP_SET_GT:
case OP_SET_B: case OP_SET_A:
case OP_SET_BE: case OP_SET_AE:
+ if (dead_insn(insn, insn->src1, insn->src2))
+ return;
hash += hashval(insn->src1);
hash += hashval(insn->src2);
break;
/* Unary */
case OP_NOT: case OP_NEG:
+ if (dead_insn(insn, insn->src1, VOID))
+ return;
hash += hashval(insn->src1);
break;
case OP_SETVAL:
+ if (dead_insn(insn, VOID, VOID))
+ return;
hash += hashval(insn->val);
hash += hashval(insn->symbol);
break;
/* Other */
case OP_PHI:
+ if (dead_insn(insn, VOID, VOID))
+ return;
hash += clean_up_phi(insn);
break;