aboutsummaryrefslogtreecommitdiffstats
path: root/cse.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-09-24 10:41:58 -0700
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-24 10:41:58 -0700
commitc66ae1d7d99dbb6de5c72acf2add61b5ea0c5de2 (patch)
tree9e7b764ccdf6f6c94e6bd9e722b21207857c0431 /cse.c
parent32b088d20cc852c8641a5ff881eb18e5ca48d372 (diff)
downloadsparse-c66ae1d7d99dbb6de5c72acf2add61b5ea0c5de2.tar.gz
sparse-c66ae1d7d99dbb6de5c72acf2add61b5ea0c5de2.tar.xz
sparse-c66ae1d7d99dbb6de5c72acf2add61b5ea0c5de2.zip
Do stupid and crappy CSE on casts.
It's better than nothing, but I need to re-do cast linearization some day. Right now we squirrell away the whole original type, but the fact is, we only need to save away a few bits of "type of cast". We need to know if it's sign-extending, and whether the source or destination are floating point values. And the source size, of course. But we don't really need to know the detailed original type. Oh, well. This makes at least trivial things look much better.
Diffstat (limited to 'cse.c')
-rw-r--r--cse.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/cse.c b/cse.c
index 42b177c..57c66ba 100644
--- a/cse.c
+++ b/cse.c
@@ -84,6 +84,19 @@ static void clean_up_one_instruction(struct basic_block *bb, struct instruction
hash += hashval(insn->symbol);
break;
+ case OP_CAST:
+ case OP_SCAST:
+ case OP_PTRCAST:
+ /*
+ * This is crap! Many "orig_types" are the
+ * same as far as casts go, we should generate
+ * some kind of "type hash" that is identical
+ * for identical casts
+ */
+ hash += hashval(insn->orig_type);
+ hash += hashval(insn->src);
+ break;
+
/* Other */
case OP_PHI: {
pseudo_t phi;
@@ -209,6 +222,18 @@ static int insn_compare(const void *_i1, const void *_i2)
case OP_PHI:
return phi_list_compare(i1->phi_list, i2->phi_list);
+ case OP_CAST:
+ case OP_SCAST:
+ case OP_PTRCAST:
+ /*
+ * This is crap! See the comments on hashing.
+ */
+ if (i1->orig_type != i2->orig_type)
+ return i1->orig_type < i2->orig_type ? -1 : 1;
+ if (i1->src != i2->src)
+ return i1->src < i2->src ? -1 : 1;
+ break;
+
default:
warning(i1->pos, "bad instruction on hash chain");
}