[llvm-commits] [llvm] r114043 - in /llvm/trunk/lib/CodeGen: SplitKit.cpp SplitKit.h

Jakob Stoklund Olesen stoklund at 2pi.dk
Wed Sep 15 17:01:37 PDT 2010


Author: stoklund
Date: Wed Sep 15 19:01:36 2010
New Revision: 114043

URL: http://llvm.org/viewvc/llvm-project?rev=114043&view=rev
Log:
Use the value mapping provided by LiveIntervalMap. This simplifies the code a
great deal because we don't have to worry about maintaining SSA form.

Unconditionally copy back to dupli when the register is live out of the split
range, even if the live-out value was defined outside the range. Skipping the
back-copy only makes sense when the live range is going to spill outside the
split range, and we don't know that it will. Besides, this was a hack to avoid
SSA update issues.

Clear up some confusion about the end point of a half-open LiveRange. Methinks
LiveRanges need to be closed so both start and end are included in the range.
The low bits of a SlotIndex are symbolic, so a half-open range doesn't really
make sense. This would be a pervasive change, though.

Modified:
    llvm/trunk/lib/CodeGen/SplitKit.cpp
    llvm/trunk/lib/CodeGen/SplitKit.h

Modified: llvm/trunk/lib/CodeGen/SplitKit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.cpp?rev=114043&r1=114042&r2=114043&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.cpp Wed Sep 15 19:01:36 2010
@@ -363,10 +363,8 @@
   if (Idx == ParentVNI->def)
     return mapValue(ParentVNI, Idx);
 
-  // This is a complex def. Mark with a NULL in valueMap.
-  VNInfo *&OldVNI = valueMap_[ParentVNI];
-  assert(!OldVNI && "Simple/Complex values mixed");
-  OldVNI = 0;
+  // This is now a complex def. Mark with a NULL in valueMap.
+  valueMap_[ParentVNI] = 0;
 
   // Should we insert a minimal snippet of VNI LiveRange, or can we count on
   // callers to do that? We need it for lookups of complex values.
@@ -417,10 +415,10 @@
          IDFI = idf_begin(IdxMBB),
          IDFE = idf_end(IdxMBB); IDFI != IDFE;) {
     MachineBasicBlock *MBB = *IDFI;
-    SlotIndex End = lis_.getMBBEndIdx(MBB);
+    SlotIndex End = lis_.getMBBEndIdx(MBB).getPrevSlot();
 
     // We are operating on the restricted CFG where ParentVNI is live.
-    if (parentli_.getVNInfoAt(End.getPrevSlot()) != ParentVNI) {
+    if (parentli_.getVNInfoAt(End) != ParentVNI) {
       IDFI.skipChildren();
       continue;
     }
@@ -489,7 +487,7 @@
      if (MBB == IdxMBB) {
        // Don't add full liveness to IdxMBB, stop at Idx.
        if (Start != Idx)
-         li_->addRange(LiveRange(Start, Idx, VNI));
+         li_->addRange(LiveRange(Start, Idx.getNextSlot(), VNI));
        // The caller had better add some liveness to IdxVNI, or it leaks.
        IdxVNI = VNI;
      } else
@@ -511,8 +509,8 @@
   --I;
   if (I->start < lis_.getMBBStartIdx(MBB))
     return 0;
-  if (I->end < Idx)
-    I->end = Idx;
+  if (I->end <= Idx)
+    I->end = Idx.getNextSlot();
   return I->valno;
 }
 
@@ -574,6 +572,20 @@
     addSimpleRange(I->start, std::min(End, I->end), I->valno);
 }
 
+VNInfo *LiveIntervalMap::defByCopyFrom(unsigned Reg,
+                                       const VNInfo *ParentVNI,
+                                       MachineBasicBlock &MBB,
+                                       MachineBasicBlock::iterator I) {
+  const TargetInstrDesc &TID = MBB.getParent()->getTarget().getInstrInfo()->
+    get(TargetOpcode::COPY);
+  MachineInstr *MI = BuildMI(MBB, I, DebugLoc(), TID, li_->reg).addReg(Reg);
+  SlotIndex DefIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
+  VNInfo *VNI = defValue(ParentVNI, DefIdx);
+  VNI->setCopy(MI);
+  li_->addRange(LiveRange(DefIdx, DefIdx.getNextSlot(), VNI));
+  return VNI;
+}
+
 //===----------------------------------------------------------------------===//
 //                               Split Editor
 //===----------------------------------------------------------------------===//
@@ -600,122 +612,56 @@
 }
 
 LiveInterval *SplitEditor::createInterval() {
-  unsigned curli = sa_.getCurLI()->reg;
-  unsigned Reg = mri_.createVirtualRegister(mri_.getRegClass(curli));
+  unsigned Reg = mri_.createVirtualRegister(mri_.getRegClass(curli_->reg));
   LiveInterval &Intv = lis_.getOrCreateInterval(Reg);
   vrm_.grow();
-  vrm_.assignVirt2StackSlot(Reg, vrm_.getStackSlot(curli));
+  vrm_.assignVirt2StackSlot(Reg, vrm_.getStackSlot(curli_->reg));
   return &Intv;
 }
 
-LiveInterval *SplitEditor::getDupLI() {
+/// Create a new virtual register and live interval.
+void SplitEditor::openIntv() {
+  assert(!openli_.getLI() && "Previous LI not closed before openIntv");
+
   if (!dupli_.getLI()) {
     // Create an interval for dupli that is a copy of curli.
     dupli_.reset(createInterval());
     dupli_.getLI()->Copy(*curli_, &mri_, lis_.getVNInfoAllocator());
   }
-  return dupli_.getLI();
-}
-
-VNInfo *SplitEditor::mapValue(const VNInfo *curliVNI) {
-  VNInfo *&VNI = valueMap_[curliVNI];
-  if (!VNI)
-    VNI = openli_.getLI()->createValueCopy(curliVNI, lis_.getVNInfoAllocator());
-  return VNI;
-}
 
-/// Insert a COPY instruction curli -> li. Allocate a new value from li
-/// defined by the COPY. Note that rewrite() will deal with the curli
-/// register, so this function can be used to copy from any interval - openli,
-/// curli, or dupli.
-VNInfo *SplitEditor::insertCopy(LiveInterval &LI,
-                                MachineBasicBlock &MBB,
-                                MachineBasicBlock::iterator I) {
-  MachineInstr *MI = BuildMI(MBB, I, DebugLoc(), tii_.get(TargetOpcode::COPY),
-                             LI.reg).addReg(curli_->reg);
-  SlotIndex DefIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
-  return LI.getNextValue(DefIdx, MI, true, lis_.getVNInfoAllocator());
-}
-
-/// Create a new virtual register and live interval.
-void SplitEditor::openIntv() {
-  assert(!openli_.getLI() && "Previous LI not closed before openIntv");
   openli_.reset(createInterval());
   intervals_.push_back(openli_.getLI());
-  liveThrough_ = false;
 }
 
 /// enterIntvBefore - Enter openli before the instruction at Idx. If curli is
 /// not live before Idx, a COPY is not inserted.
 void SplitEditor::enterIntvBefore(SlotIndex Idx) {
   assert(openli_.getLI() && "openIntv not called before enterIntvBefore");
-
-  // Copy from curli_ if it is live.
-  if (VNInfo *CurVNI = curli_->getVNInfoAt(Idx.getUseIndex())) {
-    MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
-    assert(MI && "enterIntvBefore called with invalid index");
-    VNInfo *VNI = insertCopy(*openli_.getLI(), *MI->getParent(), MI);
-    openli_.getLI()->addRange(LiveRange(VNI->def, Idx.getDefIndex(), VNI));
-
-    // Make sure CurVNI is properly mapped.
-    VNInfo *&mapVNI = valueMap_[CurVNI];
-    // We dont have SSA update yet, so only one entry per value is allowed.
-    assert(!mapVNI && "enterIntvBefore called more than once for the same value");
-    mapVNI = VNI;
+  VNInfo *ParentVNI = curli_->getVNInfoAt(Idx.getUseIndex());
+  if (!ParentVNI) {
+    DEBUG(dbgs() << "    enterIntvBefore " << Idx << ": not live\n");
+    return;
   }
+  MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
+  assert(MI && "enterIntvBefore called with invalid index");
+  openli_.defByCopyFrom(curli_->reg, ParentVNI, *MI->getParent(), MI);
   DEBUG(dbgs() << "    enterIntvBefore " << Idx << ": " << *openli_.getLI()
                << '\n');
 }
 
 /// enterIntvAtEnd - Enter openli at the end of MBB.
-/// PhiMBB is a successor inside openli where a PHI value is created.
-/// Currently, all entries must share the same PhiMBB.
-void SplitEditor::enterIntvAtEnd(MachineBasicBlock &A, MachineBasicBlock &B) {
+void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
   assert(openli_.getLI() && "openIntv not called before enterIntvAtEnd");
-
-  SlotIndex EndA = lis_.getMBBEndIdx(&A);
-  VNInfo *CurVNIA = curli_->getVNInfoAt(EndA.getPrevIndex());
-  if (!CurVNIA) {
-    DEBUG(dbgs() << "    enterIntvAtEnd, curli not live out of BB#"
-                 << A.getNumber() << ".\n");
-    return;
-  }
-
-  // Add a phi kill value and live range out of A.
-  VNInfo *VNIA = insertCopy(*openli_.getLI(), A, A.getFirstTerminator());
-  openli_.getLI()->addRange(LiveRange(VNIA->def, EndA, VNIA));
-
-  // FIXME: If this is the only entry edge, we don't need the extra PHI value.
-  // FIXME: If there are multiple entry blocks (so not a loop), we need proper
-  // SSA update.
-
-  // Now look at the start of B.
-  SlotIndex StartB = lis_.getMBBStartIdx(&B);
-  SlotIndex EndB = lis_.getMBBEndIdx(&B);
-  const LiveRange *CurB = curli_->getLiveRangeContaining(StartB);
-  if (!CurB) {
-    DEBUG(dbgs() << "    enterIntvAtEnd: curli not live in to BB#"
-                 << B.getNumber() << ".\n");
+  SlotIndex End = lis_.getMBBEndIdx(&MBB);
+  VNInfo *ParentVNI = curli_->getVNInfoAt(End.getPrevSlot());
+  if (!ParentVNI) {
+    DEBUG(dbgs() << "    enterIntvAtEnd " << End << ": not live\n");
     return;
   }
-
-  VNInfo *VNIB = openli_.getLI()->getVNInfoAt(StartB);
-  if (!VNIB) {
-    // Create a phi value.
-    VNIB = openli_.getLI()->getNextValue(SlotIndex(StartB, true), 0, false,
-                                         lis_.getVNInfoAllocator());
-    VNIB->setIsPHIDef(true);
-    VNInfo *&mapVNI = valueMap_[CurB->valno];
-    if (mapVNI) {
-      // Multiple copies - must create PHI value.
-      abort();
-    } else {
-      // This is the first copy of dupLR. Mark the mapping.
-      mapVNI = VNIB;
-    }
-
-  }
-
+  VNInfo *VNI = openli_.defByCopyFrom(curli_->reg, ParentVNI,
+                                      MBB, MBB.getFirstTerminator());
+  // Make sure openli is live out of MBB.
+  openli_.getLI()->addRange(LiveRange(VNI->def, End, VNI));
   DEBUG(dbgs() << "    enterIntvAtEnd: " << *openli_.getLI() << '\n');
 }
 
@@ -726,24 +672,7 @@
 
 void SplitEditor::useIntv(SlotIndex Start, SlotIndex End) {
   assert(openli_.getLI() && "openIntv not called before useIntv");
-
-  // Map the curli values from the interval into openli_
-  LiveInterval::const_iterator B = curli_->begin(), E = curli_->end();
-  LiveInterval::const_iterator I = std::lower_bound(B, E, Start);
-
-  if (I != B) {
-    --I;
-    // I begins before Start, but overlaps.
-    if (I->end > Start)
-      openli_.getLI()->addRange(LiveRange(Start, std::min(End, I->end),
-                                mapValue(I->valno)));
-    ++I;
-  }
-
-  // The remaining ranges begin after Start.
-  for (;I != E && I->start < End; ++I)
-    openli_.getLI()->addRange(LiveRange(I->start, std::min(End, I->end),
-                                        mapValue(I->valno)));
+  openli_.addRange(Start, End);
   DEBUG(dbgs() << "    use [" << Start << ';' << End << "): "
                << *openli_.getLI() << '\n');
 }
@@ -752,32 +681,24 @@
 void SplitEditor::leaveIntvAfter(SlotIndex Idx) {
   assert(openli_.getLI() && "openIntv not called before leaveIntvAfter");
 
-  const LiveRange *CurLR = curli_->getLiveRangeContaining(Idx.getDefIndex());
-  if (!CurLR || CurLR->end <= Idx.getBoundaryIndex()) {
+  // The interval must be live beyond the instruction at Idx.
+  SlotIndex EndIdx = Idx.getNextIndex().getBaseIndex();
+  VNInfo *ParentVNI = curli_->getVNInfoAt(EndIdx);
+  if (!ParentVNI) {
     DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": not live\n");
     return;
   }
 
-  // Was this value of curli live through openli?
-  if (!openli_.getLI()->liveAt(CurLR->valno->def)) {
-    DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": using external value\n");
-    liveThrough_ = true;
-    return;
-  }
+  MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
+  assert(MI && "leaveIntvAfter called with invalid index");
 
-  // We are going to insert a back copy, so we must have a dupli_.
-  LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Idx.getDefIndex());
-  assert(DupLR && "dupli not live into block, but curli is?");
+  VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
+                                  *MI->getParent(), MI);
+
+  // Finally we must make sure that openli is properly extended from Idx to the
+  // new copy.
+  openli_.mapValue(ParentVNI, VNI->def.getUseIndex());
 
-  // Insert the COPY instruction.
-  MachineBasicBlock::iterator I = lis_.getInstructionFromIndex(Idx);
-  MachineInstr *MI = BuildMI(*I->getParent(), llvm::next(I), I->getDebugLoc(),
-                             tii_.get(TargetOpcode::COPY), dupli_.getLI()->reg)
-                       .addReg(openli_.getLI()->reg);
-  SlotIndex CopyIdx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
-  openli_.getLI()->addRange(LiveRange(Idx.getDefIndex(), CopyIdx,
-                            mapValue(CurLR->valno)));
-  DupLR->valno->def = CopyIdx;
   DEBUG(dbgs() << "    leaveIntvAfter " << Idx << ": " << *openli_.getLI()
                << '\n');
 }
@@ -788,68 +709,23 @@
   assert(openli_.getLI() && "openIntv not called before leaveIntvAtTop");
 
   SlotIndex Start = lis_.getMBBStartIdx(&MBB);
-  const LiveRange *CurLR = curli_->getLiveRangeContaining(Start);
+  VNInfo *ParentVNI = curli_->getVNInfoAt(Start);
 
   // Is curli even live-in to MBB?
-  if (!CurLR) {
+  if (!ParentVNI) {
     DEBUG(dbgs() << "    leaveIntvAtTop at " << Start << ": not live\n");
     return;
   }
 
-  // Is curli defined by PHI at the beginning of MBB?
-  bool isPHIDef = CurLR->valno->isPHIDef() &&
-                  CurLR->valno->def.getBaseIndex() == Start;
-
-  // If MBB is using a value of curli that was defined outside the openli range,
-  // we don't want to copy it back here.
-  if (!isPHIDef && !openli_.getLI()->liveAt(CurLR->valno->def)) {
-    DEBUG(dbgs() << "    leaveIntvAtTop at " << Start
-                 << ": using external value\n");
-    liveThrough_ = true;
-    return;
-  }
-
   // We are going to insert a back copy, so we must have a dupli_.
-  LiveRange *DupLR = getDupLI()->getLiveRangeContaining(Start);
-  assert(DupLR && "dupli not live into block, but curli is?");
+  VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
+                                     MBB, MBB.begin());
 
-  // Insert the COPY instruction.
-  MachineInstr *MI = BuildMI(MBB, MBB.begin(), DebugLoc(),
-                             tii_.get(TargetOpcode::COPY), dupli_.getLI()->reg)
-                       .addReg(openli_.getLI()->reg);
-  SlotIndex Idx = lis_.InsertMachineInstrInMaps(MI).getDefIndex();
-
-  // Adjust dupli and openli values.
-  if (isPHIDef) {
-    // dupli was already a PHI on entry to MBB. Simply insert an openli PHI,
-    // and shift the dupli def down to the COPY.
-    VNInfo *VNI = openli_.getLI()->getNextValue(SlotIndex(Start,true), 0, false,
-                                                lis_.getVNInfoAllocator());
-    VNI->setIsPHIDef(true);
-    openli_.getLI()->addRange(LiveRange(VNI->def, Idx, VNI));
-
-    dupli_.getLI()->removeRange(Start, Idx);
-    DupLR->valno->def = Idx;
-    DupLR->valno->setIsPHIDef(false);
-  } else {
-    // The dupli value was defined somewhere inside the openli range.
-    DEBUG(dbgs() << "    leaveIntvAtTop source value defined at "
-                 << DupLR->valno->def << "\n");
-    // FIXME: We may not need a PHI here if all predecessors have the same
-    // value.
-    VNInfo *VNI = openli_.getLI()->getNextValue(SlotIndex(Start,true), 0, false,
-                                                lis_.getVNInfoAllocator());
-    VNI->setIsPHIDef(true);
-    openli_.getLI()->addRange(LiveRange(VNI->def, Idx, VNI));
-
-    // FIXME: What if DupLR->valno is used by multiple exits? SSA Update.
-
-    // closeIntv is going to remove the superfluous live ranges.
-    DupLR->valno->def = Idx;
-    DupLR->valno->setIsPHIDef(false);
-  }
+  // Finally we must make sure that openli is properly extended from Start to
+  // the new copy.
+  openli_.mapValue(ParentVNI, VNI->def.getUseIndex());
 
-  DEBUG(dbgs() << "    leaveIntvAtTop at " << Idx << ": " << *openli_.getLI()
+  DEBUG(dbgs() << "    leaveIntvAtTop at " << Start << ": " << *openli_.getLI()
                << '\n');
 }
 
@@ -861,22 +737,14 @@
   DEBUG(dbgs() << "    closeIntv cleaning up\n");
   DEBUG(dbgs() << "    open " << *openli_.getLI() << '\n');
 
-  if (liveThrough_) {
-    DEBUG(dbgs() << "    value live through region, leaving dupli as is.\n");
-  } else {
-    // live out with copies inserted, or killed by region. Either way we need to
-    // remove the overlapping region from dupli.
-    getDupLI();
-    for (LiveInterval::iterator I = openli_.getLI()->begin(),
-         E = openli_.getLI()->end(); I != E; ++I) {
-      dupli_.getLI()->removeRange(I->start, I->end);
-    }
-    // FIXME: A block branching to the entry block may also branch elsewhere
-    // curli is live. We need both openli and curli to be live in that case.
-    DEBUG(dbgs() << "    dup2 " << *dupli_.getLI() << '\n');
-  }
+  for (LiveInterval::iterator I = openli_.getLI()->begin(),
+       E = openli_.getLI()->end(); I != E; ++I) {
+    dupli_.getLI()->removeRange(I->start, I->end);
+  }
+  // FIXME: A block branching to the entry block may also branch elsewhere
+  // curli is live. We need both openli and curli to be live in that case.
+  DEBUG(dbgs() << "    dup2 " << *dupli_.getLI() << '\n');
   openli_.reset(0);
-  valueMap_.clear();
 }
 
 /// rewrite - after all the new live ranges have been created, rewrite
@@ -957,7 +825,7 @@
   for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
        E = Blocks.Preds.end(); I != E; ++I) {
     MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
-    enterIntvAtEnd(MBB, *Loop->getHeader());
+    enterIntvAtEnd(MBB);
   }
 
   // Switch all loop blocks.

Modified: llvm/trunk/lib/CodeGen/SplitKit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SplitKit.h?rev=114043&r1=114042&r2=114043&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SplitKit.h (original)
+++ llvm/trunk/lib/CodeGen/SplitKit.h Wed Sep 15 19:01:36 2010
@@ -162,8 +162,8 @@
   ValueMap valueMap_;
 
   // extendTo - Find the last li_ value defined in MBB at or before Idx. The
-  // parentli_ is assumed to be live at Idx. Extend the live range to Idx.
-  // Return the found VNInfo, or NULL.
+  // parentli is assumed to be live at Idx. Extend the live range to include
+  // Idx. Return the found VNInfo, or NULL.
   VNInfo *extendTo(MachineBasicBlock *MBB, SlotIndex Idx);
 
   // addSimpleRange - Add a simple range from parentli_ to li_.
@@ -200,6 +200,14 @@
   /// All needed values whose def is not inside [Start;End) must be defined
   /// beforehand so mapValue will work.
   void addRange(SlotIndex Start, SlotIndex End);
+
+  /// defByCopyFrom - Insert a copy from Reg to li, assuming that Reg carries
+  /// ParentVNI. Add a minimal live range for the new value and return it.
+  VNInfo *defByCopyFrom(unsigned Reg,
+                        const VNInfo *ParentVNI,
+                        MachineBasicBlock &MBB,
+                        MachineBasicBlock::iterator I);
+
 };
 
 
@@ -236,20 +244,6 @@
   /// register class and spill slot as curli.
   LiveInterval *createInterval();
 
-  /// getDupLI - Ensure dupli is created and return it.
-  LiveInterval *getDupLI();
-
-  /// valueMap_ - Map values in cupli to values in openli. These are direct 1-1
-  /// mappings, and do not include values created by inserted copies.
-  DenseMap<const VNInfo*, VNInfo*> valueMap_;
-
-  /// mapValue - Return the openIntv value that corresponds to the given curli
-  /// value.
-  VNInfo *mapValue(const VNInfo *curliVNI);
-
-  /// A dupli value is live through openIntv.
-  bool liveThrough_;
-
   /// All the new intervals created for this split are added to intervals_.
   SmallVectorImpl<LiveInterval*> &intervals_;
 
@@ -259,7 +253,7 @@
 
   /// Insert a COPY instruction curli -> li. Allocate a new value from li
   /// defined by the COPY
-  VNInfo *insertCopy(LiveInterval &LI,
+  VNInfo *insertCopy(LiveIntervalMap &LI,
                      MachineBasicBlock &MBB,
                      MachineBasicBlock::iterator I);
 
@@ -280,9 +274,7 @@
   void enterIntvBefore(SlotIndex Idx);
 
   /// enterIntvAtEnd - Enter openli at the end of MBB.
-  /// PhiMBB is a successor inside openli where a PHI value is created.
-  /// Currently, all entries must share the same PhiMBB.
-  void enterIntvAtEnd(MachineBasicBlock &MBB, MachineBasicBlock &PhiMBB);
+  void enterIntvAtEnd(MachineBasicBlock &MBB);
 
   /// useIntv - indicate that all instructions in MBB should use openli.
   void useIntv(const MachineBasicBlock &MBB);





More information about the llvm-commits mailing list