[llvm-dev] Extending Register Rematerialization
Nirav Rana via llvm-dev
llvm-dev at lists.llvm.org
Fri Dec 2 09:13:59 PST 2016
On Fri, Dec 2, 2016 at 5:44 AM, Gerolf Hoflehner <ghoflehner at apple.com>
wrote:
> 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.
>
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.
>
> Thanks
> Gerolf
>
> On Nov 27, 2016, at 12:37 PM, Nirav Rana via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
> Hello LLVM Developers,
>
> We are working on extending currently available register rematerialization
> to include cases where sequence of multiple instructions is required to
> rematerialize a value.
>
> We had a discussion on this in community mailing list and link is here:
> http://lists.llvm.org/pipermail/llvm-dev/2016-
> September/subject.html#104777
>
> 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.
>
> 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.
>
> Here is the code:
> //New function added for checking complex multi-instruction-sequence
> rematerializable
> bool LiveRangeEdit::checkComplexRematerializable(VNInfo *VNI,
> const MachineInstr *DefMI,
> unsigned int depth,
> AliasAnalysis *aa) {
> if(TII.isReMaterializablePossible(*DefMI, aa))
> return false;
> DEBUG(dbgs() << " ComplexRemat MI: " << *DefMI);
> for (unsigned i = 0, e = DefMI->getNumOperands(); i != e; ++i) {
> const MachineOperand &MO = DefMI->getOperand(i);
>
> if (!MO.isReg() || !MO.getReg() || !MO.readsReg())
> continue;
> if (TargetRegisterInfo::isPhysicalRegister(MO.getReg())) {
> if (MRI.isConstantPhysReg(MO.getReg(), *DefMI->getParent()->
> getParent()))
> continue;
> //If not constant then check its def
> if(depth > 6)
> return false;
>
> LiveInterval &li = LIS.getInterval(MO.getReg());
> SlotIndex UseIdx = LIS.getInstructionIndex(*DefMI);
> VNInfo *UseVNInfo = li.getVNInfoAt(UseIdx);
>
> MachineInstr *NewDefMI = LIS.getInstructionFromIndex(
> UseVNInfo->def);
> if(!checkComplexRematerializable(UseVNInfo, NewDefMI, depth+1, aa))
> return false;
> }
> }
> Remattable.insert(VNI); //May have to add new data structure
> return true;
> }
>
> In above function we are calling a new function TII.
> isReMaterializablePossible(*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::
> isReallyTriviallyReMaterializableGeneric and code for same is here:
>
> bool TargetInstrInfo::isReMaterializablePossible(
> const MachineInstr &MI, AliasAnalysis *AA) const {
> const MachineFunction &MF = *MI.getParent()->getParent();
> const MachineRegisterInfo &MRI = MF.getRegInfo();
>
> // Remat clients assume operand 0 is the defined register.
> if (!MI.getNumOperands() || !MI.getOperand(0).isReg())
> return false;
> unsigned DefReg = MI.getOperand(0).getReg();
>
> // A sub-register definition can only be rematerialized if the
> instruction
> // doesn't read the other parts of the register. Otherwise it is really
> a
> // read-modify-write operation on the full virtual register which cannot
> be
> // moved safely.
> if (TargetRegisterInfo::isVirtualRegister(DefReg) &&
> MI.getOperand(0).getSubReg() && MI.readsVirtualRegister(DefReg))
> return false;
>
> // Avoid instructions obviously unsafe for remat.
> if (MI.isNotDuplicable() || MI.mayStore() ||
> MI.hasUnmodeledSideEffects())
> return false;
>
> // Don't remat inline asm. We have no idea how expensive it is
> // even if it's side effect free.
> if (MI.isInlineAsm())
> return false;
> }
>
> We have following doubts and require guidance and suggestion to move ahead:
> 1. Is the approach we are following feasible?
> 2. What will be the suitable method to store the sequence of instruction
> for recomputing value which will be used during transformation.
> 3. Suggestion for deciding termination condition for checking use-def
> chain as it should be terminated when remat will be costly that spill.
> 4. What other cases or instruction could be included in
> isReMaterializablePossible() function. Some suggestions for direction to
> look in.
>
> Any other suggestions will also be helpful for us to move in right
> direction.
>
> - Nirav
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20161202/2c6ee4cb/attachment.html>
More information about the llvm-dev
mailing list