[PATCH] D20627: Do not rename registers that do not start an independent live range
Krzysztof Parzyszek via llvm-commits
llvm-commits at lists.llvm.org
Wed May 25 08:52:59 PDT 2016
kparzysz created this revision.
kparzysz added reviewers: qcolombet, MatzeB.
kparzysz added a subscriber: llvm-commits.
kparzysz set the repository for this revision to rL LLVM.
With subregister liveness tracking enabled, the aggressive anti-dependency breaker can rename only a part of a live super-register.
This situation happened on Hexagon while experimenting with the subregister liveness tracking.
This is the relevant code before the post-RA scheduler, which the interesting instructions marked:
```
BB#9: derived from LLVM BB %for.end30
Live Ins: %R16 %R17 %R19 %R22 %R23
Predecessors according to CFG: BB#0 BB#8
[...]
--> %R2<def> = A2_add %R23, %R17<kill>
%R6<def> = M2_mpyi %R16, %R16
%R22<def,tied1> = M2_accii %R22<tied0>, %R2<kill>, 2
%R7<def> = A2_tfrsi <ga:@.str>
%R3<def> = A2_tfr %R16<kill>
%D2<def> = A2_tfrp %D0<kill>
%R2<def> = L2_loadri_io %R29, 28; mem:LD4[FixedStack5]
%R2<def> = M2_mpyi %R6<kill>, %R2<kill>
--> %R23<def> = S2_asr_i_r %R22, 31
S2_storeri_io %R29<kill>, 0, %R7<kill>; mem:ST4[Stack]
--> %D0<def> = A2_tfrp %D11<kill>
J2_call <ga:@check> ; imp-refs removed for brevity
```
The register D11 is a pair R23:R22. What happens next is that the anti-dependency breaker identifies the anti-dependency on R23 between the first instruction and the S2_asr_i_r. It will then proceed to rename D11 to D13 (i.e. R27:R26) and R23 to R27. The problem is that R22 is still live at this point and is not renamed (to R26).
The relevant part of the DAG before renaming:
```
SU(0): %R2<def> = A2_add %R23, %R17<kill>
# preds left : 0
# succs left : 3
# rdefs left : 0
Latency : 1
Depth : 0
Height : 5
Successors:
out SU(6): Latency=1 Reg=%R2
val SU(2): Latency=1 Reg=%R2
antiSU(8): Latency=0 Reg=%R23
[...]
SU(8): %R23<def> = S2_asr_i_r %R22, 31
# preds left : 2
# succs left : 1
# rdefs left : 0
Latency : 1
Depth : 2
Height : 2
Predecessors:
val SU(2): Latency=1 Reg=%R22
antiSU(0): Latency=0 Reg=%R23
Successors:
val SU(10): Latency=1 Reg=%D11
[...]
SU(10): %D0<def> = A2_tfrp %D11<kill>
# preds left : 3
# succs left : 1
# rdefs left : 0
Latency : 1
Depth : 3
Height : 1
Predecessors:
val SU(8): Latency=1 Reg=%D11
antiSU(5): Latency=0 Reg=%D0
val SU(2): Latency=1 Reg=%D11
Successors:
ch SU(4294967295) *: Latency=1
```
Subsequently:
```
===== Aggressive anti-dependency breaking
Available regs: ...
Anti: %D0<def> = A2_tfrp %D11<kill>
Def Groups: D0=g0->g0(via R0)->g0(via R1)
Antidep reg: D0 (zero group)
Use Groups: D11=g0->g415(last-use) R22->g416(last-use) R23->g417(last-use)
Anti: S2_storeri_io %R29<kill>, 0, %R7<kill>; mem:ST4[Stack]
Def Groups:
Use Groups: R29=g0->g418(last-use) R7=g0->g419(last-use)
Anti: %R23<def> = S2_asr_i_r %R22, 31
Def Groups: R23=g417->g415(via D11)
Antidep reg: R23
Rename Candidates for Group g415:
D11: DoubleRegs :: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 D10 D11 D12 D13
R23: IntRegs :: R0 R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28
Find Registers: [D13: D13 R27]
Breaking anti-dependence edge on R23: D11->D13(1 refs) R23->R27(1 refs)
Use Groups: R22=g416
```
The final code is this. Note that R22 has not been renamed, even though its super-register use (i.e. D11 in the last instruction before the call) has been renamed to D13:
```
BB#9: derived from LLVM BB %for.end30
Live Ins: %R16 %R17 %R19 %R22 %R23
Predecessors according to CFG: BB#0 BB#8
[...]
%R2<def> = A2_add %R23<kill>, %R17<kill>
%D2<def> = A2_tfrp %D0<kill>
%R6<def> = M2_mpyi %R16, %R16
%R0<def> = L2_loadri_io %R29, 28; mem:LD4[FixedStack5]
%R22<def,tied1> = M2_accii %R22<tied0>, %R2<kill>, 2
%R2<def> = M2_mpyi %R6<kill>, %R0<kill>
%R3<def> = A2_tfr %R16<kill>
%R7<def> = A2_tfrsi <ga:@.str>
--> %R27<def> = S2_asr_i_r %R22<kill>, 31
S2_storeri_io %R29<kill>, 0, %R7<kill>; mem:ST4[Stack]
--> %D0<def> = A2_tfrp %D13<kill>
J2_call <ga:@check>
```
The proposed solution is to avoid breaking of anti-dependencies on registers that do not start independent live ranges. If the definition of the anti-dep register has successors based on any alias of the anti-dep register, that alias must be completely covered by the anti-dep register.
Repository:
rL LLVM
http://reviews.llvm.org/D20627
Files:
lib/CodeGen/AggressiveAntiDepBreaker.cpp
Index: lib/CodeGen/AggressiveAntiDepBreaker.cpp
===================================================================
--- lib/CodeGen/AggressiveAntiDepBreaker.cpp
+++ lib/CodeGen/AggressiveAntiDepBreaker.cpp
@@ -898,6 +898,29 @@
}
if (AntiDepReg == 0) continue;
+
+ // If the definition of the anti-dependency register does not start
+ // a new live range, bail out. This can happen if the anti-dep
+ // register is a sub-register of another register whose live range
+ // spans over PathSU. In such case, PathSU defines only a part of
+ // the larger register.
+ BitVector Aliases(TRI->getNumRegs());
+ for (MCRegAliasIterator AI(AntiDepReg, TRI, true); AI.isValid(); ++AI)
+ Aliases.set(*AI);
+ for (SDep S : PathSU->Succs) {
+ SDep::Kind K = S.getKind();
+ if (K != SDep::Data && K != SDep::Output && K != SDep::Anti)
+ continue;
+ unsigned R = S.getReg();
+ if (!Aliases[R])
+ continue;
+ if (R == AntiDepReg || TRI->isSubRegister(AntiDepReg, R))
+ continue;
+ AntiDepReg = 0;
+ break;
+ }
+
+ if (AntiDepReg == 0) continue;
}
assert(AntiDepReg != 0);
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D20627.58433.patch
Type: text/x-patch
Size: 1315 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160525/2cd4c714/attachment-0001.bin>
More information about the llvm-commits
mailing list