Now that cast instructions are more finely grained, it's not needed to compare the original type of the casts, only the original size can matter. So, do not hash & compare the original types but only the orignal sizes. This allow much more casts instructions to be CSEed away. Note: like noted in the code, even the original size shouldn't matter as identical sources should implies identical original sizes but this can't yet be guaranted. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- The patch is available for review & testing in the Git repository at: git://github.com/lucvoo/sparse-dev.git cse-cast before being promoted to the stable tree at: git://github.com/lucvoo/sparse.git master ---------------------------------------------------------------- cse.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/cse.c b/cse.c index 33cc40dc7..e69fc81fb 100644 --- a/cse.c +++ b/cse.c @@ -95,14 +95,12 @@ void cse_collect(struct instruction *insn) case OP_TRUNC: case OP_PTRCAST: case OP_UTPTR: case OP_PTRTU: - /* - * 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); + if (!insn->orig_type || insn->orig_type->bit_size < 0) + return; hash += hashval(insn->src); + + // Note: see corresponding line in insn_compare() + hash += hashval(insn->orig_type->bit_size); break; /* Other */ @@ -165,6 +163,7 @@ static int insn_compare(const void *_i1, const void *_i2) { const struct instruction *i1 = _i1; const struct instruction *i2 = _i2; + int size1, size2; int diff; if (i1->opcode != i2->opcode) @@ -243,13 +242,18 @@ static int insn_compare(const void *_i1, const void *_i2) case OP_TRUNC: case OP_PTRCAST: case OP_UTPTR: case OP_PTRTU: - /* - * 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; + + // Note: if it can be guaranted that identical ->src + // implies identical orig_type->bit_size, then this + // test and the hashing of the original size in + // cse_collect() are not needed. + // It must be generaly true but it isn't guaranted (yet). + size1 = i1->orig_type->bit_size; + size2 = i2->orig_type->bit_size; + if (size1 != size2) + return size1 < size2 ? -1 : 1; break; default: -- 2.18.0 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html