Open Quuxplusone opened 8 years ago
We hoist ccc
in GVN (when we perform PRE). I'm not sure why we don't hoist the other two variables as they don't seem entirely different and if it makes really sense performing this transformation as part of GVN. Daniel/Sebastian, any opinion about it?
Also, FWIW, gcc hoists all the three loads outside of the loop, i.e.
.Ltext0:
foo(int const*):
.LFB0:
.LVL0:
movl bbb(%rip), %esi
movl aaa(%rip), %ecx
movl ccc(%rip), %edx
.L5:
.LBB2:
addq $4, %rdi
.LVL1:
movl -4(%rdi), %eax
.LVL2:
cmpl %eax, %edx
jge .L2
addl %eax, %esi
movl %esi, bbb(%rip)
.L2:
cmpl %esi, %eax
jle .L3
addl %eax, %ecx
movl %ecx, aaa(%rip)
.L3:
cmpl %ecx, %eax
jle .L4
addl %eax, %edx
movl %edx, ccc(%rip)
.L4:
testl %eax, %eax
jns .L5
.LBE2:
rep ret
.LFE0:
ccc:
.long 30
bbb:
.long 20
aaa:
.long 10
(In reply to comment #1)
We hoist
ccc
in GVN (when we perform PRE). I'm not sure why we don't hoist the other two variables as they don't seem entirely different and if it makes really sense performing this transformation as part of GVN. Daniel/Sebastian, any opinion about it?
Can you paste attach the LLVM IR right before PRE?
Attached hoist-pregvn.ll
(2403 bytes, application/octet-stream): pre-gvn ir
Yet another reason to move to NewGVN =) Well, thanks for taking care of it in the current GVN, at least we'll have a test case to make sure it won't regress when we do the switch
Actually, i was trying the wrong branch.
That issue was already fixed, AFAIK.
This issue is different, where it doesn't understand the nonFuncLocal type of
clobber, and thus thinks it's unavailable.
Instead, it means it can be recreated anywhere up the CFG, which it also
doesn't understand.
I've attached a fix that works for global values.
We lack the PRE infrastructure to make this more general (in general, we can
move anything where we can prove the operands or available, or we can recreate
them)
I don't have time to test this further :)
Note also that because GVN understands nothing about phi nodes, it generates a
ton of duplicate ones that it requires a large number of passes to clean up :(
NewGVN definitely fixes that.
In any case, patch attached, if someone wants to push it along.
Attached pre-non-local.diff
(5948 bytes, text/plain): Patch to fix this issue
(note that this also causes pre-single-pred.ll to fail because we are now able
to completely move the load out of the loop.
yay)
Thanks!
I noticed about lack of phi handling (this actually was the original reason why
I started looking @NewGVN, because we have some cases internally which could
greatly benefit by the new phi-predication mechanism).
For now,I'll test this more, try to bootstrap etc..
It would be good to make this more general but I'm not entirely sure it's worth
our time in particular with a complete rewrite behind the door. So, assuming
the fix is safe, I'd rather land it as is and focus our effort on NewGVN. Makes
sense? Otherwise I'll keep the fix in our private tree for the time being.
We are basically going to want to rewrite PRE in terms of GVN + MemorySSA anyway, so i'm pretty sure we get nothing from trying to generalize this.
It's also non-trivial.
It's basically "reimplement a real GVNPRE in LLVM".
Doing the operand availability/etc calculations sparsely and quickly is .... not easy (it either requires memoizing and wasting a lot of memory, or giving up and using bitvector dataflow).
(In reply to comment #11)
> We are basically going to want to rewrite PRE in terms of GVN + MemorySSA
> anyway, so i'm pretty sure we get nothing from trying to generalize this.
>
> It's also non-trivial.
>
> It's basically "reimplement a real GVNPRE in LLVM".
>
> Doing the operand availability/etc calculations sparsely and quickly is ....
> not easy (it either requires memoizing and wasting a lot of memory, or
> giving up and using bitvector dataflow).
(so yeah, makes sense :P)
I did some additional testing and checked in r284311.
I'll leave this bug open for a bit to ensure no regressions are introduced.
This was reverted back at rL284796 and is still as bad as when it was first reported:
hoist-pregvn.ll
(2403 bytes, application/octet-stream)pre-non-local.diff
(5948 bytes, text/plain)