diff options
author | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-13 23:23:28 +0100 |
---|---|---|
committer | Luc Van Oostenryck <luc.vanoostenryck@gmail.com> | 2020-11-17 18:03:24 +0100 |
commit | 6b5e7cf5ac390f12472f914737c8a947eed0afe0 (patch) | |
tree | e97c13b3412d0ce021b29101f143a1559fa17479 | |
parent | 09474b0a451bd4e3baea5e1a5e04f9b28f644bb3 (diff) | |
download | sparse-6b5e7cf5ac390f12472f914737c8a947eed0afe0.tar.gz |
cfg: call simplify_memops() unconditionally.
Currently, in the main optimization loop, simplify_memops()
is only called if REPEAT_SYMBOL_CLEANUP have been set. This
has (at least) two problems:
1) simplify_memops() may itself create other 'symbol cleanup'
opportunities. That's fine and when it happens REPEAT_SYMBOL_CLEANUP
is correctly set but this is directly lost because repeat_phase
is cleared just after. So, loads and stores are not always
optimized away as they should.
2) Loads & stores are not always done directly on symbols, in
fact, it often happens that they are done on some PSEUDO_REG.
Here too, loads and stores are not always optimized away as
they should.
So, call simplify_memops() unconditionally.
Note: this have only very small effects on the tests' running time:
before after after too
real 4m18.001s real 4m18.655s real 4m19.4
user 71m32.911s user 72m02.701s user 72m06.6
sys 29m06.523s sys 29m01.721s sys 29m06.8
which is under the noise I usually have.
Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
-rw-r--r-- | memops.c | 2 | ||||
-rw-r--r-- | optimize.c | 4 | ||||
-rw-r--r-- | validation/optim/memops-missed01.c | 23 | ||||
-rw-r--r-- | validation/optim/memops-missed02.c | 14 |
4 files changed, 40 insertions, 3 deletions
@@ -146,10 +146,12 @@ static void simplify_loads(struct basic_block *bb) } rewrite_load_instruction(insn, dominators); } else { // cleanup pending phi-sources + int repeat = repeat_phase; pseudo_t phi; FOR_EACH_PTR(dominators, phi) { kill_instruction(phi->def); } END_FOR_EACH_PTR(phi); + repeat_phase = repeat; } } next_load: @@ -84,9 +84,7 @@ repeat: kill_unreachable_bbs(ep); cse_eliminate(ep); - - if (repeat_phase & REPEAT_SYMBOL_CLEANUP) - simplify_memops(ep); + simplify_memops(ep); } while (repeat_phase); pack_basic_blocks(ep); if (repeat_phase & REPEAT_CFG_CLEANUP) diff --git a/validation/optim/memops-missed01.c b/validation/optim/memops-missed01.c new file mode 100644 index 00000000..fc616f19 --- /dev/null +++ b/validation/optim/memops-missed01.c @@ -0,0 +1,23 @@ +void bar(int); + +void foo(void) +{ + char buf[1] = { 42 }; + const char *p = buf; + const char **q = &p; + int ch = 0; + switch (**q) { + case 4: + ch = 2; + } + bar(ch); +} + +/* + * check-name: memops-missed01 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-excludes: store\\. + * check-output-excludes: load\\. + */ diff --git a/validation/optim/memops-missed02.c b/validation/optim/memops-missed02.c new file mode 100644 index 00000000..6f028649 --- /dev/null +++ b/validation/optim/memops-missed02.c @@ -0,0 +1,14 @@ +void foo(int a[]) +{ + int i, val; + for (;; i++) + val = a[i] ? a[i] : val; +} + +/* + * check-name: memops-missed02 + * check-command: test-linearize -Wno-decl $file + * + * check-output-ignore + * check-output-pattern(1): load\\. + */ |