aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
authorLuc Van Oostenryck <luc.vanoostenryck@gmail.com>2017-01-04 04:03:21 +0100
committerChristopher Li <sparse@chrisli.org>2017-02-13 09:34:45 +0800
commit5636cd5cbf816f30ee57d580ec4debd8e0bd7581 (patch)
tree1a600d68617996638e90486e72808412a64dc0ef
parentc8757aa484fbc45a33baa0b87fdb248f5f14d01d (diff)
downloadsparse-dev-5636cd5cbf816f30ee57d580ec4debd8e0bd7581.tar.gz
missing load simplification
In memops:find_dominating_parents(), the 'load-load optimization' (see commit cf07903a "Don't bother finding dominating loads if ...") cause some loads simplification to be missed. For example, with the following code: int foo(int *i, int *j) { *i = 6; *j = 1; do { if (*i != 6) (*i)++; (*i)++; } while (*i != *j); return *j; } test-linearize returns something like: foo: .L0: <entry-point> store.32 $6 -> 0[%arg1] store.32 $1 -> 0[%arg2] br .L1 .L1: load.32 %r4 <- 0[%arg1] setne.32 %r5 <- %r4, $6 br %r5, .L4, .L5 .L4: add.32 %r8 <- %r4, $1 store.32 %r8 -> 0[%arg1] br .L5 .L5: load.32 %r10 <- 0[%arg1] add.32 %r11 <- %r10, $1 store.32 %r11 -> 0[%arg1] load.32 %r15 <- 0[%arg2] setne.32 %r16 <- %r11, %r15 br %r16, .L1, .L6 .L6: ret.32 %r15 where we can notice that the first load in .L5 is not needed, the value could be retrieved from %r4 and %r8, like: @@ -8,15 +8,17 @@ .L1: load.32 %r4 <- 0[%arg1] setne.32 %r5 <- %r4, $6 + phisrc.32 %phi4 <- %r4 br %r5, .L4, .L5 .L4: add.32 %r8 <- %r4, $1 store.32 %r8 -> 0[%arg1] + phisrc.32 %phi5 <- %r8 br .L5 .L5: - load.32 %r10 <- 0[%arg1] + phi.32 %r10 <- %phi4, %phi5 add.32 %r11 <- %r10, $1 store.32 %r11 -> 0[%arg1] load.32 %r15 <- 0[%arg2] The fix essentially consists in reverting commit cf07903a but on memops.c's version of find_dominating_parents(). Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@gmail.com> Signed-off-by: Christopher Li <sparse@chrisli.org>
-rw-r--r--memops.c10
1 files changed, 3 insertions, 7 deletions
diff --git a/memops.c b/memops.c
index 6dac1f57..5efdd6f2 100644
--- a/memops.c
+++ b/memops.c
@@ -18,12 +18,10 @@
static int find_dominating_parents(pseudo_t pseudo, struct instruction *insn,
struct basic_block *bb, unsigned long generation, struct pseudo_list **dominators,
- int local, int loads)
+ int local)
{
struct basic_block *parent;
- if (bb_list_size(bb->parents) > 1)
- loads = 0;
FOR_EACH_PTR(bb->parents, parent) {
struct instruction *one;
struct instruction *br;
@@ -41,8 +39,6 @@ static int find_dominating_parents(pseudo_t pseudo, struct instruction *insn,
}
if (!dominance)
continue;
- if (one->opcode == OP_LOAD && !loads)
- continue;
goto found_dominator;
} END_FOR_EACH_PTR_REVERSE(one);
no_dominance:
@@ -50,7 +46,7 @@ no_dominance:
continue;
parent->generation = generation;
- if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local, loads))
+ if (!find_dominating_parents(pseudo, insn, parent, generation, dominators, local))
return 0;
continue;
@@ -124,7 +120,7 @@ static void simplify_loads(struct basic_block *bb)
generation = ++bb_generation;
bb->generation = generation;
dominators = NULL;
- if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local, 1)) {
+ if (find_dominating_parents(pseudo, insn, bb, generation, &dominators, local)) {
/* This happens with initial assignments to structures etc.. */
if (!dominators) {
if (local) {