[llvm-commits] [llvm] r59587 - in /llvm/trunk: lib/CodeGen/PreAllocSplitting.cpp test/CodeGen/X86/pre-split2.ll

Evan Cheng evan.cheng at apple.com
Tue Nov 18 22:09:24 PST 2008


Awesome! Thanks Owen. Can you refactor to avoid code duplication in  
Rematerialize?

Evan

On Nov 18, 2008, at 8:28 PM, Owen Anderson <resistor at mac.com> wrote:

> Author: resistor
> Date: Tue Nov 18 22:28:29 2008
> New Revision: 59587
>
> URL: http://llvm.org/viewvc/llvm-project?rev=59587&view=rev
> Log:
> Add support for rematerialization in pre-alloc-splitting.
>
> Modified:
>    llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
>    llvm/trunk/test/CodeGen/X86/pre-split2.ll
>
> Modified: llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp?rev=59587&r1=59586&r2=59587&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp (original)
> +++ llvm/trunk/lib/CodeGen/PreAllocSplitting.cpp Tue Nov 18 22:28:29  
> 2008
> @@ -39,6 +39,7 @@
> static cl::opt<int> PreSplitLimit("pre-split-limit", cl::init(-1),  
> cl::Hidden);
>
> STATISTIC(NumSplits, "Number of intervals split");
> +STATISTIC(NumRemats, "Number of intervals split by  
> rematerialization");
>
> namespace {
>   class VISIBILITY_HIDDEN PreAllocSplitting : public  
> MachineFunctionPass {
> @@ -153,6 +154,11 @@
>
>     bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB,
>                         MachineBasicBlock* BarrierMBB);
> +    bool Rematerialize(unsigned vreg, VNInfo* ValNo,
> +                       MachineInstr* DefMI,
> +                       MachineBasicBlock::iterator RestorePt,
> +                       unsigned RestoreIdx,
> +                       SmallPtrSet<MachineInstr*, 4>& RefsInMBB);
>   };
> } // end anonymous namespace
>
> @@ -627,6 +633,90 @@
>   return;
> }
>
> +bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo,
> +                                      MachineInstr* DefMI,
> +                                      MachineBasicBlock::iterator  
> RestorePt,
> +                                      unsigned RestoreIdx,
> +                                    SmallPtrSet<MachineInstr*, 4>&  
> RefsInMBB) {
> +  MachineBasicBlock& MBB = *RestorePt->getParent();
> +
> +  MachineBasicBlock::iterator KillPt = BarrierMBB->end();
> +  unsigned KillIdx = 0;
> +  if (ValNo->def == ~0U || DefMI->getParent() == BarrierMBB)
> +    KillPt = findSpillPoint(BarrierMBB, Barrier, NULL, RefsInMBB,  
> KillIdx);
> +  else
> +    KillPt = findNextEmptySlot(DefMI->getParent(), DefMI, KillIdx);
> +
> +  if (KillPt == DefMI->getParent()->end())
> +    return false;
> +
> +  TII->reMaterialize(MBB, RestorePt, vreg, DefMI);
> +  LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx);
> +
> +  if (KillPt->getParent() == BarrierMBB) {
> +    UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1,
> +                           LIs->getDefIndex(RestoreIdx));
> +
> +    ++NumSplits;
> +    ++NumRemats;
> +    return true;
> +  }
> +
> +  // Shrink wrap the live interval by walking up the CFG and find the
> +  // new kills.
> +  // Now let's find all the uses of the val#.
> +  DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4> >  
> Uses;
> +  DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4> >  
> UseMIs;
> +  SmallPtrSet<MachineBasicBlock*, 4> Seen;
> +  SmallVector<MachineBasicBlock*, 4> UseMBBs;
> +  for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI- 
> >reg),
> +         UE = MRI->use_end(); UI != UE; ++UI) {
> +    MachineOperand &UseMO = UI.getOperand();
> +    MachineInstr *UseMI = UseMO.getParent();
> +    unsigned UseIdx = LIs->getInstructionIndex(UseMI);
> +    LiveInterval::iterator ULR = CurrLI- 
> >FindLiveRangeContaining(UseIdx);
> +    if (ULR->valno != ValNo)
> +      continue;
> +    MachineBasicBlock *UseMBB = UseMI->getParent();
> +    // Remember which other mbb's use this val#.
> +    if (Seen.insert(UseMBB) && UseMBB != BarrierMBB)
> +      UseMBBs.push_back(UseMBB);
> +    DenseMap<MachineBasicBlock*, SmallVector<MachineOperand*, 4>  
> >::iterator
> +      UMII = Uses.find(UseMBB);
> +    if (UMII != Uses.end()) {
> +      DenseMap<MachineBasicBlock*, SmallPtrSet<MachineInstr*, 4>  
> >::iterator
> +        UMII2 = UseMIs.find(UseMBB);
> +      UMII->second.push_back(&UseMO);
> +      UMII2->second.insert(UseMI);
> +    } else {
> +      SmallVector<MachineOperand*, 4> Ops;
> +      Ops.push_back(&UseMO);
> +      Uses.insert(std::make_pair(UseMBB, Ops));
> +      SmallPtrSet<MachineInstr*, 4> MIs;
> +      MIs.insert(UseMI);
> +      UseMIs.insert(std::make_pair(UseMBB, MIs));
> +    }
> +  }
> +
> +  // Walk up the predecessor chains.
> +  SmallPtrSet<MachineBasicBlock*, 8> Visited;
> +  ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI- 
> >getParent(), Visited,
> +                         Uses, UseMIs, UseMBBs);
> +
> +  // FIXME: If ValNo->hasPHIKill is false, then renumber the val# by
> +  // the restore.
> +
> +  // Remove live range from barrier to the restore. FIXME: Find a  
> better
> +  // point to re-start the live interval.
> +  UpdateRegisterInterval(ValNo, LIs->getUseIndex(BarrierIdx)+1,
> +                         LIs->getDefIndex(RestoreIdx));
> +
> +  ++NumSplits;
> +  ++NumRemats;
> +  return true;
> +
> +}
> +
> /// SplitRegLiveInterval - Split (spill and restore) the given live  
> interval
> /// so it would not cross the barrier that's being processed. Shrink  
> wrap
> /// (minimize) the live interval to the last uses.
> @@ -644,11 +734,8 @@
>     abort();
>   }
>
> -  // FIXME: For now, if definition is rematerializable, do not split.
>   MachineInstr *DefMI = (ValNo->def != ~0U)
>     ? LIs->getInstructionFromIndex(ValNo->def) : NULL;
> -  if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI))
> -    return false;
>
>   // If this would create a new join point, do not split.
>   if (DefMI && createsNewJoin(LR, DefMI->getParent(), Barrier- 
> >getParent()))
> @@ -670,6 +757,11 @@
>   if (RestorePt == BarrierMBB->end())
>     return false;
>
> +  if (DefMI && LIs->isReMaterializable(*LI, ValNo, DefMI))
> +    if (Rematerialize(LI->reg, ValNo, DefMI, RestorePt,
> +                      RestoreIndex, RefsInMBB))
> +    return true;
> +
>   // Add a spill either before the barrier or after the definition.
>   MachineBasicBlock *DefMBB = DefMI ? DefMI->getParent() : NULL;
>   const TargetRegisterClass *RC = MRI->getRegClass(CurrLI->reg);
>
> Modified: llvm/trunk/test/CodeGen/X86/pre-split2.ll
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/pre-split2.ll?rev=59587&r1=59586&r2=59587&view=diff
>
> === 
> === 
> === 
> =====================================================================
> --- llvm/trunk/test/CodeGen/X86/pre-split2.ll (original)
> +++ llvm/trunk/test/CodeGen/X86/pre-split2.ll Tue Nov 18 22:28:29 2008
> @@ -1,5 +1,5 @@
> ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split - 
> stats |& \
> -; RUN:   not grep {pre-alloc-split}
> +; RUN:   grep {pre-alloc-split} | count 2
>
> define i32 @t() {
> entry:
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list