aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-13 23:23:28 +0100
committerLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2020-11-17 18:03:24 +0100
commit6b5e7cf5ac390f12472f914737c8a947eed0afe0 (patch)
treee97c13b3412d0ce021b29101f143a1559fa17479
parent09474b0a451bd4e3baea5e1a5e04f9b28f644bb3 (diff)
downloadsparse-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.c2
-rw-r--r--optimize.c4
-rw-r--r--validation/optim/memops-missed01.c23
-rw-r--r--validation/optim/memops-missed02.c14
4 files changed, 40 insertions, 3 deletions
diff --git a/memops.c b/memops.c
index f071e556..badcdbbb 100644
--- a/memops.c
+++ b/memops.c
@@ -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:
diff --git a/optimize.c b/optimize.c
index bfab74c0..8ab105bc 100644
--- a/optimize.c
+++ b/optimize.c
@@ -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\\.
+ */