<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jul 19, 2016, at 1:11 PM, Sergey Yakoushkin <<a href="mailto:sergey.yakoushkin@gmail.com" class="">sergey.yakoushkin@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">Hi Matthias,<div class=""><br class=""></div><div class="">Thanks for quick reply. I have few questions about sub-register support.</div><div class=""><br class=""></div><div class="">I'm currently using LLVM 3.8. Could you send links to recent patches/reviews?</div></div></div></blockquote><div>Given the time the 3.8 branch was created it should definitely have all the subregister liveness tracking code, it may not have all the things necessary to enable the scheduler enhancements though.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div><div class=""><br class=""></div><div class="">1) Does LLVM maintain sub-register liveness while splitting live intervals?<br class=""></div></div></div></div></blockquote><div>No, currently subregister liveness information is dropped if registers get split or spilled.</div><div>There are currently some issues with recalculating liveness after invasive changes relating to the fact that you cannot set undef/dead flags on subregister granularity in todays llvm. There is no such problem when the liveness information is computed before register coalescing and the coalescer itself has code to update the liveness information rather than recomputing it.</div><div>The spilling and splitting code currently takes the easy way out and drops the subregister information (so you are only left with the liveness of the superregister). This hasn't been a problem for GPUs as those typically have many register so spilling and splitting are untypical operations.</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div><div class="">2) How sub-register kill/dead flags and BB liveins should look after regalloc?</div></div></div></div></blockquote><div>The kill and the dead flag describes the whole machine operand:</div><div> %vreg0<dead>. // dead def of the whole vreg0</div><div> %vreg1.sub1<dead>. // dead def of the sub1 subregisters (the other subregs may be live)</div><div> = %vreg2<undef>. // undef %vreg2 usage <=> the operand does not affect vreg2s liveness</div><div> = %vreg2.sub2<undef>. // undef %vreg2.sub1 usage</div><div><br class=""></div><div> %AL = xxx</div><div> = use %EAX. // this is legal: you only need part of the physreg to be defined for a use to be fine</div><div> = use %EBX<undef> // this still requires the undef flag as the complete register is undefined.</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div><div class="">E.g. target has instructions both for sub-registers and registers.</div><div class="">Composite 64b reg contains 2x32b regs: Rxy = { Rx, Ry }. and scalar/vector add/ld/etc.<br class=""></div><div class=""><br class=""></div><div class="">LiveRangeCalc::findReachingDefs expects to see all sub-registers in BB liveins together with pair registers.<br class=""></div><div class=""><div class=""><br class=""></div><div class=""></div></div><div class="">BB1:</div><div class=""> Rxy<def> = ...</div><div class=""><br class=""></div><div class="">BB2: LiveIn: Rxy and Rx ?</div></div></div></div></blockquote><div>You can either have Rxy in the live-in list, you may also have Rx and Ry separately in the list.</div><div>(Note that each live-in also has a lanemask assigned so you can have situations in which Rxy is in the live-in list</div><div>but the lanemask is telling you that just one of Rx/Ry is actually live)</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class=""><br class=""></div><div class=""> ... = ADD Rx<use><br class=""></div><div class=""><div class=""> ... = VADD Rxy<use></div></div><div class=""><br class=""></div><div class=""><pre style="font-family: monospace, fixed; font-size: 9pt; border: 1px solid rgb(196, 207, 229); padding: 4px 6px; margin: 4px 8px 4px 2px; overflow: auto; word-wrap: break-word; line-height: 15px; background-color: rgb(251, 252, 253);" class="">00284 <span style="color:rgb(224,128,0)" class="">if</span> (<a href="http://llvm.org/docs/doxygen/html/classllvm_1_1TargetRegisterInfo.html#a055858b14215864ed367a8db6c19d6f6" title="Return true if the specified register number is in the physical register namespace." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">TargetRegisterInfo::isPhysicalRegister</a>(PhysReg) &&
<a name="m_1675424170679260381_l00285" style="color:rgb(61,87,140)" class=""></a>00285 !MBB-><a href="http://llvm.org/docs/doxygen/html/classllvm_1_1MachineBasicBlock.html#afe4193a0ecb73443df8c573bb29bd476" title="Return true if the specified register is in the live in set." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">isLiveIn</a>(PhysReg)) {
<a name="m_1675424170679260381_l00286" style="color:rgb(61,87,140)" class=""></a>00286 MBB-><a href="http://llvm.org/docs/doxygen/html/classllvm_1_1MachineBasicBlock.html#af2e482ff2a9253ec6bc2285491496bd6" title="Return the MachineFunction containing this basic block." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">getParent</a>()-><a href="http://llvm.org/docs/doxygen/html/classllvm_1_1MachineFunction.html#a1e613e97a2629a51e5d2d3e6f7b32b50" title="verify - Run the current MachineFunction through the machine code verifier, useful for debugger use..." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">verify</a>();
<a name="m_1675424170679260381_l00287" style="color:rgb(61,87,140)" class=""></a>00287 <a href="http://llvm.org/docs/doxygen/html/namespacellvm.html#ab8e34eca3b0817ef7a127913fbf6d9e4" title="This returns a reference to a raw_ostream for standard error." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">errs</a>() << <span style="color:rgb(0,32,128)" class="">"The register "</span> << <a href="http://llvm.org/docs/doxygen/html/namespacellvm.html#a28f4a9f931a245d69d411d73e5a877a9" title="Prints virtual and physical registers with or without a TRI instance." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">PrintReg</a>(PhysReg)
<a name="m_1675424170679260381_l00288" style="color:rgb(61,87,140)" class=""></a>00288 << <span style="color:rgb(0,32,128)" class="">" needs to be live in to BB#"</span> << MBB-><a href="http://llvm.org/docs/doxygen/html/classllvm_1_1MachineBasicBlock.html#a6acda287e5c19ffb173b0bf8f1dd9c5e" title="MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti..." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">getNumber</a>()
<a name="m_1675424170679260381_l00289" style="color:rgb(61,87,140)" class=""></a>00289 << <span style="color:rgb(0,32,128)" class="">", but is missing from the live-in list.\n"</span>;
<a name="m_1675424170679260381_l00290" style="color:rgb(61,87,140)" class=""></a>00290 <a href="http://llvm.org/docs/doxygen/html/Support_2ErrorHandling_8h.html#ace243f5c25697a1107cce46626b3dc94" title="Marks that the current location is not supposed to be reachable." style="color:rgb(70,101,162);text-decoration:none" target="_blank" class="">llvm_unreachable</a>(<span style="color:rgb(0,32,128)" class="">"Invalid global physical register"</span>);
<a name="m_1675424170679260381_l00291" style="color:rgb(61,87,140)" class=""></a>00291 }</pre></div></div></div></div></blockquote><div>You may be running in the recalculation problems here. Tricky situations may look like this:</div><div><br class=""></div><div>BB0:</div><div> %vreg0 = xxx</div><div> jmp BB2</div><div><br class=""></div><div>BB1:</div><div> %vreg0.sub1<read-undef> = yyy</div><div> jmp BB2</div><div><br class=""></div><div>BB2:</div><div> = use %vreg0. // the instruction only cares about vreg0.sub1 but for some reason encodes the full register.</div><div> // However as we lack a way to add an "undef" flag for vreg0.sub0 the liveness calculation traces</div><div> // backwards and fails to find an actual sub0 definition in BB1.</div><div><br class=""></div><div>If that is your actual problem, there is more discussion and a possible solution being discussed in <a href="https://reviews.llvm.org/D21189" class="">https://reviews.llvm.org/D21189</a>. I must say though that I don't feel comfortable with the complexity added to the code there...</div><div><br class=""></div><div>- Matthias</div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><div class="">3) LLVM coalesces composite register and sub-registers, leaving some sub-registers undefined, but information is lost after regalloc rewriting.<br class=""></div><div class="">Is it expected?</div><div class=""><br class=""></div><div class="">before regalloc:</div><div class="">%vreg:item1<def,read-undef> = MOV_imm 0<br class=""></div>STORE <..#0>, 0, %vreg56<br class=""><br class="">after regalloc:<br class="">%Rx<def> = MOV_imm 0<br class="">STORE <..#0>, 0, %Rxy<div class=""><br class=""></div><div class="">Regards,</div><div class="">Sergey<br class=""></div><div class=""><br class=""></div></div></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Tue, Jul 19, 2016 at 8:48 PM, Matthias Braun <span dir="ltr" class=""><<a href="mailto:mbraun@apple.com" target="_blank" class="">mbraun@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class=""><div class="">Oh that is an old ticket, the items in the TODO below are all done (some are obsolete).</div><div class=""><br class=""></div><div class="">subregister liveness tracking has been available in llvm for roughly a year now and for a few months we also have scheduler extensions in place to allow independent scheduling of subregister definitions.</div><div class=""><br class=""></div><div class="">While I had subregister liveness tracking working for all CPU targets I decided against enabling it in the end. This is because I could not measure any benefits in the generated code, so I couldn't justify the added compiletime.</div><div class=""><br class=""></div><div class="">We do have subregister liveness tracking enabled in production for AMDGPU and an out of tree target, so it certainly works today.</div><span class="HOEnZb"><font color="#888888" class=""><div class=""><br class=""></div><div class="">- Matthias</div></font></span><div class=""><div class="h5"><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Jul 19, 2016, at 9:26 AM, Sergey Yakoushkin <<a href="mailto:sergey.yakoushkin@gmail.com" target="_blank" class="">sergey.yakoushkin@gmail.com</a>> wrote:</div><br class=""><div class=""><div dir="ltr" class="">Hi all,<div class=""><br class=""></div><div class="">I'm working on LLVM-based back-end. We have custom LLVM solution for sub-register liveness tracking.</div><div class=""><br class=""></div><div class="">Recently we tried to replace it with LLVM enableSubRegLiveness and run into multiple issues.</div><div class="">I can't share specific IR snippets now, but failures are related to spilling, undef sub-registers, etc.<br class=""></div><div class=""><br class=""></div><div class="">There is Bug 17557 open since 2013: Enable subregister liveness for scheduling and register allocation.</div><div class=""><a href="https://llvm.org/bugs/show_bug.cgi?id=17557" target="_blank" class="">https://llvm.org/bugs/show_bug.cgi?id=17557</a></div><div class=""><br class=""></div><div class="">with TODO list:</div><div class=""><pre style="white-space:pre-wrap;width:50em" class="">"These are the remaining steps to get Matthias' subregister liveness fully integrated:
- Fix LiveRegUnits to correctly handle regmasks.
- Benchmark/tune compile time.
- Enable subreg liveness on x86 for testing purposes.
- Use LiveRegUnits to fix ARM VMOV widening.
- Fix the scheduler's DAG builder to use bundler iterator, not operand index.
- Discard the master live range after coalescing so that LiveInterval updates don't need to preserve it when we reorder subregister defs.
- Enable subreg scheduling on all targets that enable MI scheduler."</pre></div><div class=""><div class=""><br class=""></div><div class="">Is someone still working on bug fixes and enhancements? any pending patches?</div></div><div class=""><br class=""></div><div class="">R600 back-end is using sub-reg liveness: e.g. r238999 - R600: Re-enable sub-reg liveness (June 2015).</div><div class="">But it seems requirements and use cases are GPU-specific.<br class=""></div><div class=""><br class=""></div><div class="">Does anyone use sub-reg liveness for RISC/CISC+SIMD targets?</div><div class=""><br class=""></div><div class="">Thanks,<br class=""></div><div class="">Sergey</div><div class=""><br class=""></div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Oct 9, 2013 at 11:03 PM, Matthias Braun <span dir="ltr" class=""><<a href="mailto:mbraun@apple.com" target="_blank" class="">mbraun@apple.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word" class=""><br class=""><div class=""><span class=""><div class="">On Oct 8, 2013, at 2:06 PM, Akira Hatanaka <<a href="mailto:ahatanak@gmail.com" target="_blank" class="">ahatanak@gmail.com</a>> wrote:</div><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class="">What I didn't mention in r<span style="font-size:13px;font-family:arial,sans-serif" class="">192119 is that mthi/lo clobbers the other sub-register only if the contents of hi and lo are produced by mult or other arithmetic instructions (div, madd, etc.) It doesn't have this side-effect if it is produced by another mthi/lo. So I don't think making mthi/lo clobber the other half would work.</span></div></div></blockquote></span><div class="">Uh that is indeed nasty, and can’t really be expressed like that in the current RA framework I think.</div><span class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class="">
<div class=""><span style="font-size:13px;font-family:arial,sans-serif" class=""><br class=""></span></div><div class="">For example, this is an illegal sequence of instructions, where instruction 3 makes $hi unpredictable:</div><div class=""><br class=""></div><div class="">1. mult $lo<def>, $hi<def>, $2, $3 // $lo<def>, $hi<def> = $2 * $3</div>
<div class=""><div class="">2. mflo $4, $lo<use> // $4 <- $lo<br class=""></div><div class="">3. mtlo $lo<def>, $6 // $lo <- $6. effectively clobbers $hi too.<br class=""></div></div><div class=""><div class="">4. mfhi $5, $hi<use> // $5 <- $hi</div><div class="">5. mthi $hi<def>, $7 // $hi <- $7</div>
</div><div class=""><div class="">6. madd $lo<def>, $hi<def>, $8, $9, $lo<use>, $hi<use> // $lo<def>, $hi<def> = $2 * $3 + (lo,hi) </div><div class=""><br class=""></div><div class="">Unlike the mtlo instruction in the example above, instruction 5 in the next example does not clobber $hi:</div>
<div class=""><br class=""></div><div class=""><div class="">1. mult $lo<def>, $hi<def>, $2, $3 // $lo<def>, $hi<def> = $2 * $3</div><div class=""><div class="">2. mflo $4, $lo<use> // $4 <- $lo<br class=""></div><div class="">3. mfhi $5, $hi<use> // $5 <- $hi<br class="">
</div></div><div class="">4. mthi $hi<def>, $7 // $hi <- $7.<br class=""></div><div class=""><div class="">5. mtlo $lo<def>, $6 // $lo <- $6. This does not clobber $hi.<br class=""></div><div class=""></div><div class="">6. madd $lo<def>, $hi<def>, $8, $9, $lo<use>, $hi<use> // $lo<def>, $hi<def> = $2 * $3 + (lo,hi) </div>
<div class=""><br class=""></div><div class="">Probably I can define a pseudo instruction "mthilo" that defines both lo and hi and expands to mthi and mtlo after register allocation, which will force register allocator to spill/restore the whole register in most cases (the only exception I can think of is the inline-assembly constraint 'l' for 'lo' register).</div></div></div></div></div></blockquote></span><div class="">That is probably the cleanest solution, with the only downside being that the scheduler can’t place instruction between the mthi and mtlo anymore.</div><div class=""><br class=""></div><div class="">Greetings</div><span class=""><font color="#888888" class=""><div class=""><span style="white-space:pre-wrap" class=""> </span>Matthias</div></font></span><div class=""><div class=""><br class=""><blockquote type="cite" class=""><div dir="ltr" class=""><div class=""><div class=""><div class="">
</div></div></div><div class=""><br class=""></div></div><div class="gmail_extra"><br class=""><br class=""><div class="gmail_quote">On Tue, Oct 8, 2013 at 1:04 PM, Matthias Braun <span dir="ltr" class=""><<a href="mailto:matze@braunis.de" target="_blank" class="">matze@braunis.de</a>></span> wrote:<br class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div class=""><div class="">
<div bgcolor="#FFFFFF" text="#000000" class="">
<br class="">
<div class="">
<div class="">Currently it will always spill /
restore the whole vreg but only spilling the parts that are
actually live would be a nice addition in the future.<br class="">
<br class="">
Looking at r192119’: if “mtlo” writes to $LO and sets $HI to an
unpredictable value, then it should just have an additional
(dead) def operand for $hi, shouldn’t it?<br class="">
<br class="">
Greetings<br class="">
Matthias<br class="">
<br class="">
Am 10/8/13, 11:03 AM, schrieb Akira Hatanaka:<br class="">
</div>
<blockquote type="cite" class="">
<div dir="ltr" class="">
<div class="">Hi,</div>
<div class=""><br class="">
</div>
<div class="">I have a question about the way sub-registers are spilled
and restored that is related to the changes I made in
r192119.</div>
<div class=""><br class="">
</div>
<div class="">Suppose I have the following piece of code with four
instructions. %vreg0 and %vreg1 consist of two sub-registers
indexed by sub_lo and sub_hi.</div>
<div class=""><br class="">
</div>
instr0 %vreg0<def>
<div class="">instr1 %vreg1:sub_lo<def<span style="font-family:arial,sans-serif;font-size:13px" class="">,read-undef</span>><br class="">
</div>
<div class="">instr2 %vreg0<use></div>
<div class="">
<div class="">instr3 %vreg1:sub_hi<def></div>
</div>
<div class=""><br class="">
</div>
<div class="">If register allocator decides to insert spill and restore
instructions for %vreg0, will it spill the whole register
that includes sub-registers lo and hi?</div>
<div class=""><br class="">
</div>
<div class="">instr0 %vreg0<def></div>
<div class="">spill0 %vreg0<br class="">
<div class="">instr1 %vreg1:sub_lo<def<span style="font-family:arial,sans-serif;font-size:13px" class="">,read-undef</span>><br class="">
</div>
spill1 %vreg1:sub_lo<br class="">
restore0 %vreg0<br class="">
<div class="">instr2 %vreg0<use></div>
restore1 %vreg1:sub_lo<br class="">
<div class="">instr3 %vreg1:sub_hi<def></div>
</div>
<div class=""><br class="">
</div>
<div class="">Or will it spill just the lo sub-register?</div>
<div class=""><br class="">
</div>
<div class="">
<div class="">instr0 %vreg0<def></div>
<div class="">spill0 %vreg0:sub_lo<br class="">
<div class="">instr1 %vreg1:sub_lo<def<span style="font-family:arial,sans-serif;font-size:13px" class="">,read-undef</span>><br class="">
</div>
spill1 %vreg1:sub_lo<br class="">
restore0 %vreg0:sub_lo<br class="">
<div class="">instr2 %vreg0<use></div>
restore1 %vreg1:sub_lo<br class="">
<div class="">instr3 %vreg1:sub_hi<def></div>
</div>
</div>
<div class=""><br class="">
</div>
<div class="">If it spills the whole register (both sub-registers lo
and hi), the changes I made should be fine. Otherwise, I
will have to find another way to prevent the problems I
mentioned in r192119's commit log.</div>
<div class=""><br class="">
</div>
</div>
<div class="gmail_extra"><br class="">
<br class="">
<div class="gmail_quote">On Mon, Oct 7, 2013 at 1:11 PM,
Matthias Braun <span dir="ltr" class=""><<a href="mailto:matze@braunis.de" target="_blank" class="">matze@braunis.de</a>></span> wrote:<br class="">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">I've
been working on patches to improve subregister liveness
tracking on llvm and I wanted to inform the llvm community
about the overal design/motivation for them. I will send
the patches to llvm-commits later today.<br class="">
<br class="">
Greetings<br class="">
Matthias Braun<br class="">
<br class="">
<br class="">
Subregisters in llvm<br class="">
====================<br class="">
<br class="">
Some targets can access registers in different ways
resulting in wider or<br class="">
narrower accesses. For example on ARM NEON one of the
single precision<br class="">
floating point registers is called 'S0'. You may also
access 'D0' on arm which<br class="">
is the combination of 'S0' and 'S1' and can store a double
prevision number or<br class="">
2 single precision floats. 'Q0' is the combination of
'S0', 'S1', 'S2' and<br class="">
'S3' (or 'D0' and 'D1') and so on.<br class="">
<br class="">
Before register allocation llvm machine code accesses
values through virtual<br class="">
registers, these get assigned to physical registers later.
Each virtual<br class="">
register has an assigned register class which is a set of
physical registers.<br class="">
So for example on ARM you have a register class containing
all the 'SXX'<br class="">
registers and another one containing all the 'DXX'
registers, ...<br class="">
<br class="">
But sometimes you want to mix narrow and wide accesses to
values. Like loading<br class="">
the 'D0' register but later reading the 'S0' and 'S1'
components separately.<br class="">
This is modeled with subregister operands which specify
that only parts of a<br class="">
wider value are accessed. For example the register class
of the 'DXX'<br class="">
registers supports subregisters calls 'ssub_0' and
'ssub_1' which would<br class="">
result in 'S4' and 'S5' getting used if 'D2' is assigned
to the virtual<br class="">
register later.<br class="">
<br class="">
Typical operations are decomposing wider values or
composing wide values with<br class="">
multiple smaller defs:<br class="">
<br class="">
Decomposing:<br class="">
%vreg1<def> = produce a 'D' value<br class="">
= use 'S' value %vreg1:ssub_0<br class="">
= use 'S' value %vreg1:ssub_1<br class="">
<br class="">
Composing:<br class="">
%vreg1:ssub_0<def,read-undef> = produce an 'S' value<br class="">
%vreg1:ssub_1<def> = produce an 'S' value<br class="">
= use a 'D' value %vreg1<br class="">
<br class="">
Problems / Motivation<br class="">
=====================<br class="">
<br class="">
Currently the llvm register allocator tracks liveness for
whole virtual<br class="">
registers. This can lead to suboptimal code:<br class="">
<br class="">
%vreg0:ssub_0<def,read-undef> = produce an 'S' value<br class="">
%vreg0:ssub_1<def> = produce an 'S' value<br class="">
= use a 'D' value %vreg0<br class="">
%vreg1 = produce an 'S' value<br class="">
= use an 'S' value %vreg1<br class="">
= use an 'S' value %vreg0:ssub_0<br class="">
<br class="">
The current code will realize that vreg0 and vreg1
interfere and assign them<br class="">
to different registers like D0+S2 aka S0+S1+S2; while in
reality after the<br class="">
full use of %vreg0 only %vreg0::ssub_0 must remain in a
register while the<br class="">
subregister used for %vreg0:ssub_1 can be reassigned to
%vreg1. An ideal<br class="">
assignment would be D0+S1 aka S0+S1.<br class="">
<br class="">
A even more pressing problem are artificial dependencies
in the schedule<br class="">
graph. This is a side effect of llvms live range
information being represented<br class="">
in a static single assignment like fashion: Every
definition of a vreg starts<br class="">
a new interval with a new value number. This means that
partial register<br class="">
writes must be modeled as an implicit use of the unwritten
parts of a register<br class="">
and force the creating of a new value number. This in turn
leads to artificial<br class="">
dependencies in the schedule graph for code like the
following where all defs<br class="">
should be independent:<br class="">
<br class="">
%vreg0:ssub_0<def,read-undef> = produce an 'S' value<br class="">
%vreg0:ssub_1<def> = produce an 'S' value<br class="">
%vreg0:ssub_2<def> = produce an 'S' value<br class="">
%vreg0:ssub_3<def> = produce an 'S' value<br class="">
<br class="">
<br class="">
Subegister liveness tracking<br class="">
============================<br class="">
<br class="">
I developed a set of patches which enable liveness
tracking on the subregister<br class="">
level, to overcome the problems mentioned above. After
these changes you can<br class="">
have separate live ranges for subregisters of a virtual
register. With these<br class="">
patches the following code:<br class="">
<br class="">
16B %vreg0:ssub_0<def,read-undef> = ...<br class="">
32B %vreg0:ssub_1<def> = ...<br class="">
48B = %vreg0<br class="">
64B = %vreg0:ssub_0<br class="">
80B %vreg0 = ...<br class="">
96B = %vreg0:ssub_1<br class="">
<br class="">
will be represented as the following live range(s):<br class="">
<br class="">
Common LiveRange: [16r,32r)[32r,64r),[80r,96r)<br class="">
SubRange with Mask 0x0004 (=ssub_0): [16r,64r)[80r,80d)<br class="">
SubRange with Mask 0x0008 (=ssub_1): [32r,48r)[80r,96r)<br class="">
<br class="">
Patches/Changes:<br class="">
* Moves live range management code in the LiveInterval
class to a new<br class="">
class LiveRange, move the previous LiveRange class
(which was just a single<br class="">
interval inside a live range) to LiveRange::Segment.<br class="">
LiveInterval is made a subclass of LiveRange, other code
paths like<br class="">
register units liveness use LiveRange instead of
LiveInterval now.<br class="">
* Introduce a linked list of SubRange objects to the
LiveInterval class.<br class="">
A SubRange is a subclass of LiveRange and contains a
LaneMask indicating<br class="">
which subregisters are represented.<br class="">
* Various algorithms have been adapted to
calculate/preserve subregister<br class="">
liveness.<br class="">
* The register allocator has been adapted to track
interference at the<br class="">
subregister level (LaneMasks are mapped to register
units)<br class="">
<br class="">
Note that SubRegister liveness tracking has to be
explicitely enabled by the<br class="">
target architecture, as it does not provide enough
benefits for the costs on<br class="">
some targets (e.g. having subregister liveness for the
lower/upper 8bit regs<br class="">
on x86 provided nearly no benefits in the llvm-testsuite,
so you can't justify<br class="">
more computations/memory usage for that.<br class="">
_______________________________________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank" class="">LLVMdev@cs.uiuc.edu</a>
<a href="http://llvm.cs.uiuc.edu/" target="_blank" class="">http://llvm.cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br class="">
</blockquote>
</div>
<br class="">
</div>
<br class="">
<fieldset class=""></fieldset>
<br class="">
<pre class="">_______________________________________________
LLVM Developers mailing list
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu/" target="_blank" class="">http://llvm.cs.uiuc.edu</a>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a>
</pre>
</blockquote>
<br class="">
<br class="">
</div>
<br class="">
</div>
</div></div><br class="">_______________________________________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu/" target="_blank" class="">http://llvm.cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br class="">
<br class=""></blockquote></div><br class=""></div>
_______________________________________________<br class="">LLVM Developers mailing list<br class=""><a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu/" target="_blank" class="">http://llvm.cs.uiuc.edu</a><br class=""><a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br class=""></blockquote></div></div></div><br class=""></div><br class="">_______________________________________________<br class="">
LLVM Developers mailing list<br class="">
<a href="mailto:LLVMdev@cs.uiuc.edu" target="_blank" class="">LLVMdev@cs.uiuc.edu</a> <a href="http://llvm.cs.uiuc.edu/" rel="noreferrer" target="_blank" class="">http://llvm.cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" rel="noreferrer" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br class="">
<br class=""></blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></body></html>