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

Owen Anderson resistor at mac.com
Tue Nov 18 20:28:30 PST 2008


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:





More information about the llvm-commits mailing list