Konstantin Vladimirov via llvm-dev
2016-Dec-22 16:46 UTC
[llvm-dev] Spill hoisting on RAL: looking for some debugging ideas
Hi, I am debugging private backend and faced interesting problem: sometimes spill hoisting creates double stores. (some output from -debug-only=regalloc). First hoisting: Checking redundant spills for 0 at 16r in %vreg19 [16r,144B:0)[144B,240B:1)[240B,280r:2)[296r,416B:3)[416B,456r:4)[472r,592B:5) 0 at 16r 1 at 144B-phi 2 at 240B-phi 3 at 296r 4 at 416B-phi 5 at 472r Merged to stack int: SS#0 [16r,592B:0) 0 at x hoisted: 16r STbo %vreg19, <fi#0> Second below: Checking redundant spills for 0 at 16r in %vreg19 [16r,96B:0)[144B,240B:1)[296r,416B:2)[416B,456r:3)[472r,592B:4) 0 at 16r 1 at 144B-phi 2 at 296r 3 at 416B-phi 4 at 472r Merged to stack int: SS#0 [16r,592B:0) 0 at x hoisted: 16r STbo %vreg19, <fi#0> Result just prior to rewriting: 20B STbo %vreg19, <fi#0> 24B STbo %vreg19<kill>, <fi#0> --- Original code is like this: int foo(int fst, int snd, int *links) { int ptr; for (ptr = fst; ptr != 0; ptr = links[ptr]) mrglist(); for (ptr = snd; ptr != 0; ptr = links[ptr]) cpylist(); } Without spill hoisting, it spills links in each loop separately into fi#0, but with it, it moves both spills up. In architectures like AARCH64 there are a plenty of callee-saved registers and this bug can not be easily reproduced, so I am trying to understand why spill hoisting do such things in mine case. I found InlineSpiller::eliminateRedundantSpills that seems to be in charge. I traced code down to problem. First time it hoists vreg19 ok. Second time it sees MI, created first time, sees slot index, but then on line: if (LI->getVNInfoAt(Idx) != VNI) continue; it continues. (gdb) p *VNI $21 = {id = 4, def = {lie = {Value = 260284292}}} (gdb) p *LI->getVNInfoAt(Idx) $22 = {id = 0, def = {lie = {Value = 260282980}}} I do not clearly understand this LI/VNI mechanics. How to look where everything gone wrong? Where shall I look first? --- With best regards, Konstantin
Konstantin Vladimirov via llvm-dev
2016-Dec-23 10:10 UTC
[llvm-dev] Spill hoisting on RAL: looking for some debugging ideas
Hi, I found source of error: I have pair of hooks isLoadFromStackSlot / isStoreToStackSlot unimplemented in mine backend. After implementation, store hoisting started to work fine. --- With best regards, Konstantin On Thu, Dec 22, 2016 at 7:46 PM, Konstantin Vladimirov <konstantin.vladimirov at gmail.com> wrote:> Hi, > > I am debugging private backend and faced interesting problem: > sometimes spill hoisting creates double stores. > > (some output from -debug-only=regalloc). > > First hoisting: > > Checking redundant spills for 0 at 16r in %vreg19 > [16r,144B:0)[144B,240B:1)[240B,280r:2)[296r,416B:3)[416B,456r:4)[472r,592B:5) > 0 at 16r 1 at 144B-phi 2 at 240B-phi > 3 at 296r 4 at 416B-phi 5 at 472r > Merged to stack int: SS#0 [16r,592B:0) 0 at x > hoisted: 16r STbo %vreg19, <fi#0> > > Second below: > > Checking redundant spills for 0 at 16r in %vreg19 > [16r,96B:0)[144B,240B:1)[296r,416B:2)[416B,456r:3)[472r,592B:4) 0 at 16r > 1 at 144B-phi 2 at 296r 3 at 416B-phi 4 at 472r > Merged to stack int: SS#0 [16r,592B:0) 0 at x > hoisted: 16r STbo %vreg19, <fi#0> > > Result just prior to rewriting: > > 20B STbo %vreg19, <fi#0> > 24B STbo %vreg19<kill>, <fi#0> > > --- > > Original code is like this: > > int foo(int fst, int snd, int *links) { > int ptr; > for (ptr = fst; ptr != 0; ptr = links[ptr]) > mrglist(); > for (ptr = snd; ptr != 0; ptr = links[ptr]) > cpylist(); > } > > Without spill hoisting, it spills links in each loop separately into > fi#0, but with it, it moves both spills up. In architectures like > AARCH64 there are a plenty of callee-saved registers and this bug can > not be easily reproduced, so I am trying to understand why spill > hoisting do such things in mine case. > > I found InlineSpiller::eliminateRedundantSpills that seems to be in > charge. I traced code down to problem. First time it hoists vreg19 ok. > Second time it sees MI, created first time, sees slot index, but then > on line: > > if (LI->getVNInfoAt(Idx) != VNI) continue; > > it continues. > > (gdb) p *VNI > $21 = {id = 4, def = {lie = {Value = 260284292}}} > (gdb) p *LI->getVNInfoAt(Idx) > $22 = {id = 0, def = {lie = {Value = 260282980}}} > > I do not clearly understand this LI/VNI mechanics. How to look where > everything gone wrong? Where shall I look first? > > --- > With best regards, Konstantin
Maybe Matching Threads
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.
- [LLVMdev] RegisterCoalescing Pass seems to ignore part of CFG.
- Machine Scheduler on Power PC: Latency Limit and Register Pressure