<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Dec 2, 2016 at 5:44 AM, Gerolf Hoflehner <span dir="ltr"><<a href="mailto:ghoflehner@apple.com" target="_blank">ghoflehner@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">On which targets & apps/benchmarks do you expect a speed-up? In practice I expect spills/fills to be hard to beat by longer remat sequences.</div></blockquote><div><br></div><div>We think that this will be helpful in RISC architectures such as MIPS, ARM and PowerPC. An example case is mentioned in first mail in mail-chain I gave link of. But as far as benchmarks is concerned, we are still looking for examples in testsuit. <br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Thanks</div><div>Gerolf</div><div><br><div><blockquote type="cite"><div><div class="h5"><div>On Nov 27, 2016, at 12:37 PM, Nirav Rana via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div><br class="m_816775642411431713Apple-interchange-newline"></div></div><div><div><div class="h5"><div dir="ltr">Hello LLVM Developers,<div><br></div><div>We are working on extending currently available register rematerialization to include cases where sequence of multiple instructions is required to rematerialize a value.</div><div><br></div><div>We had a discussion on this in community mailing list and link is here:  </div><div><a href="http://lists.llvm.org/pipermail/llvm-dev/2016-September/subject.html#104777" target="_blank">http://lists.llvm.org/<wbr>pipermail/llvm-dev/2016-<wbr>September/subject.html#104777</a><br></div><div><br></div><div>From the above discussion and studying the code we believe that extension can be implemented in same flow as current remat is implemented. What we unterstood is RegAlloc<>.cpp will try to allocate register to live-range, and if not possible, will call InlineSpiller.cpp to spill the live range. InlineSpiller.cpp will try to first rematerialize the register value if possible with help of LiveRangeEdit.cpp which provides various methods for checking if value is rematable or not.</div><div><br></div><div>So we have added a new function in LiveRangeEdit that traverses sequence of instruction in use-def chain recursively (instead of only current instruction in consideration) upto depth 6 (arbitrarily taken for testing) to check if value can be rematerialized with the sequence of instruction or not.</div><div><br></div><div>Here is the code:</div><div>//New function added for checking complex multi-instruction-sequence rematerializable</div><div>bool LiveRangeEdit::<wbr>checkComplexRematerializable(<wbr>VNInfo *VNI,</div><div>                                          const MachineInstr *DefMI,</div><div>                                          unsigned int depth,</div><div>                                          AliasAnalysis *aa) {</div><div>  if(TII.<wbr>isReMaterializablePossible(*<wbr>DefMI, aa))</div><div>    return false;</div><div>  DEBUG(dbgs() << " ComplexRemat MI: " << *DefMI);</div><div>  for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {</div><div>    const MachineOperand &MO = DefMI->getOperand(i);</div><div><br></div><div>    if (!MO.isReg() || !MO.getReg() || !MO.readsReg())</div><div>      continue;</div><div>    if (TargetRegisterInfo::<wbr>isPhysicalRegister(MO.getReg()<wbr>)) {</div><div>      if (MRI.isConstantPhysReg(MO.<wbr>getReg(), *DefMI->getParent()-><wbr>getParent()))</div><div>        continue;</div><div>      //If not constant then check its def</div><div>      if(depth > 6)</div><div>        return false;</div><div><br></div><div>      LiveInterval &li = LIS.getInterval(MO.getReg());</div><div>      SlotIndex UseIdx = LIS.getInstructionIndex(*<wbr>DefMI);</div><div>      VNInfo *UseVNInfo = li.getVNInfoAt(UseIdx);</div><div><br></div><div>      MachineInstr *NewDefMI = LIS.getInstructionFromIndex(<wbr>UseVNInfo->def);</div><div>      if(!<wbr>checkComplexRematerializable(<wbr>UseVNInfo, NewDefMI, depth+1, aa))</div><div>        return false;</div><div>    }</div><div>  }</div><div>  Remattable.insert(VNI);     //May have to add new data structure</div><div>  return true;</div><div>} </div><div><br></div><div>In above function we are calling a new function TII.<wbr>isReMaterializablePossible(*<wbr>DefMI, aa) which will act as early heuristic and return false by checking if instruction is definitely not rematerialize. We have found some cases from TargetInstrInfo::<wbr>isReallyTriviallyReMaterializa<wbr>bleGeneric and code for same is here:</div><div><br></div><div><div>bool TargetInstrInfo::<wbr>isReMaterializablePossible(</div><div>    const MachineInstr &MI, AliasAnalysis *AA) const {</div><div>  const MachineFunction &MF = *MI.getParent()->getParent();</div><div>  const MachineRegisterInfo &MRI = MF.getRegInfo();</div><div><br></div><div>  // Remat clients assume operand 0 is the defined register.</div><div>  if (!MI.getNumOperands() || !MI.getOperand(0).isReg())</div><div>    return false;</div><div>  unsigned DefReg = MI.getOperand(0).getReg();</div><div><br></div><div>  // A sub-register definition can only be rematerialized if the instruction</div><div>  // doesn't read the other parts of the register.  Otherwise it is really a</div><div>  // read-modify-write operation on the full virtual register which cannot be</div><div>  // moved safely.</div><div>  if (TargetRegisterInfo::<wbr>isVirtualRegister(DefReg) &&</div><div>      MI.getOperand(0).getSubReg() && MI.readsVirtualRegister(<wbr>DefReg))</div><div>    return false;</div><div><br></div><div>  // Avoid instructions obviously unsafe for remat.</div><div>  if (MI.isNotDuplicable() || MI.mayStore() || MI.hasUnmodeledSideEffects())</div><div>    return false;</div><div><br></div><div>  // Don't remat inline asm. We have no idea how expensive it is</div><div>  // even if it's side effect free.</div><div>  if (MI.isInlineAsm())</div><div>    return false;</div><div>}</div></div><div><br></div><div>We have following doubts and require guidance and suggestion to move ahead:</div><div>1. Is the approach we are following feasible?</div><div>2. What will be the suitable method to store the sequence of instruction for recomputing value which will be used during transformation.</div><div>3. Suggestion for deciding termination condition for checking use-def chain as it should be terminated when remat will be costly that spill. </div><div>4. What other cases or instruction could be included in isReMaterializablePossible() function. Some suggestions for direction to look in.</div><div><br></div><div>Any other suggestions will also be helpful for us to move in right direction.</div><div><br></div><div>- Nirav</div></div></div></div>
______________________________<wbr>_________________<br>LLVM Developers mailing list<br><a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br><a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br></div></blockquote></div><br></div></div></blockquote></div><br></div></div>