[llvm-bugs] [Bug 31411] New: [regalloc] A problem caused by the interaction between split and evict
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Dec 16 14:09:50 PST 2016
https://llvm.org/bugs/show_bug.cgi?id=31411
Bug ID: 31411
Summary: [regalloc] A problem caused by the interaction between
split and evict
Product: libraries
Version: trunk
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: Register Allocator
Assignee: unassignedbugs at nondot.org
Reporter: wmi at google.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
For the testcase 1.cc:
~/workarea/llvm-r287002/dbuild/bin/clang -std=c++11 -fno-omit-frame-pointer
-fno-exceptions -O2 -S 1.cc -o 1.s
In BB#41 we found some fishy code. The movq instructions pairs below indicates
some problem in reg split.
# BB#41: # %if.then.i201
# in Loop: Header=BB0_35 Depth=2
xorl %eax, %eax
cmpl %r10d, %r12d
setl %al
movq -56(%rbp), %rcx # 8-byte Reload
=======>
movq %r13, %rdi
movq %r15, %r13
movq %r10, %r15
movq %r8, %r10
=======>
movq %rcx, %r8
addq %rax, %r8
movq -136(%rbp), %rax # 8-byte Reload
movslq 56(%rax), %rax
shlq $3, %rax
negq %rax
movq (%rdi,%rax), %rax
movq %r8, %rcx
movq %rcx, -56(%rbp) # 8-byte Spill
addq %r8, %rax
=======>
movq %r10, %r8
movq %r15, %r10
movq %r13, %r15
movq %rdi, %r13
=======>
movq %rax, (%r13)
We do some digging here and find the problem is about the interaction of split
and evict:
Suppose physical register %R1 is used in BB#41 but available elsewhere. virtual
registers: VR1,VR2,VR3,VR4 lives through BB#41. Register pressure is high in
the function so VR1 is split into VR1_a and VR1_b with %R1 available for VR1_a.
VR10 holds %R2.
BB#41
VR1_b = VR1_a;
...
def R1;
...
use R1;
...
VR1_a = VR1_b;
VR1_b is the remainder interval the stage of which is marked as SPILL after the
split, and it is local to BB#41. Because VR1_a is longer than VR1_b, VR1_a will
be allocated before VR1_b in the queue after split. VR1_a will easily get %R1.
VR1_b is marked as SPILL but it is shorter than VR1, so it can now evict VR10
for %R2, and VR1_b will get %R2. Note VR1_a and VR1_b get different physical
registers so the copies pair "VR1_b = VR1_a" and "VR1_a = VR1_b" cannot be
coalesced.
Since %R2 is only used in BB#41 but available elsewhere, it looks the same as
%R1 above. Then VR2 will be split in the same way as VR1 and generate another
pair of copies. So on for VR3, VR4...
I think a cause of the problem is:
VR1 cannot evict VR10 for %R2 before it is split, but after split, VR1_b can
evict VR10 because it is shorter now and has higher weight than VR1.
Since VR10 will be evicted anyway by VR1_b, why not do that before split, so
that VR1 can be allocated to %R2 without splitting, and no copies will be
inserted into BB#41.
However, it is not cheap to know that one of new vregs generated from splitting
VR1 can evict VR10 beforehand.
We can have an alternative solution here. Raising the priority of remainder
interval (VR1_b) after split so that VR1_b will be allocated before VR1_a.
VR1_b will still evict VR10 and get %R2. When allocating VR1_a, it can choose
between %R2 and %R1 and will more likely to choose %R2 because of hint, and the
copies will be coalesced.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20161216/ad2e6242/attachment.html>
More information about the llvm-bugs
mailing list