diff options
| author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-06-30 12:01:29 +0200 |
|---|---|---|
| committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2018-06-30 20:38:23 +0200 |
| commit | 6fc095ca97f6a93e151bbc98fde897e867b7c750 (patch) | |
| tree | 3cb7052ed43564c0e70181e225c6145d4d6f666f | |
| parent | 7bba241ec6218e6f72094b7b081cd21443151184 (diff) | |
| parent | a19d607fdac63d50024f239e410c803ad59d77cb (diff) | |
| download | sparse-dev-6fc095ca97f6a93e151bbc98fde897e867b7c750.tar.gz | |
Merge branch 'cse-cast' into tip
* cse: try the next pair instead of keeping the first instruction
* cse: compare casts only by kind a size, not by C type.
| -rw-r--r-- | cse.c | 30 | ||||
| -rw-r--r-- | validation/optim/cse-cmp-next.c | 15 |
2 files changed, 33 insertions, 12 deletions
@@ -94,14 +94,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 */ @@ -164,6 +162,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) @@ -241,13 +240,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: @@ -359,6 +363,8 @@ static struct instruction * try_to_cse(struct entrypoint *ep, struct instruction i1 = cse_one_instruction(i2, i1); remove_instruction(&b1->insns, i1, 1); add_instruction_to_end(i1, common); + } else { + i1 = i2; } return i1; diff --git a/validation/optim/cse-cmp-next.c b/validation/optim/cse-cmp-next.c new file mode 100644 index 00000000..50fdbac0 --- /dev/null +++ b/validation/optim/cse-cmp-next.c @@ -0,0 +1,15 @@ +void foo(int p, int i, int f, int *ref, int *dst, int *src) +{ + if (p) + f = ref[i]; + if (f) + dst[i] = src[i]; +} + +/* + * check-name: cse-cmp-next + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1,2): mul\\. + */ |
