diff options
| -rw-r--r-- | llvm/lib/CodeGen/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/InlineSpiller.cpp | 125 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/LiveRangeEdit.cpp | 64 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/LiveRangeEdit.h | 70 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SplitKit.cpp | 53 | ||||
| -rw-r--r-- | llvm/lib/CodeGen/SplitKit.h | 18 | 
6 files changed, 206 insertions, 125 deletions
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt index a2e04ffe65f..dbf5dca3f22 100644 --- a/llvm/lib/CodeGen/CMakeLists.txt +++ b/llvm/lib/CodeGen/CMakeLists.txt @@ -23,6 +23,7 @@ add_llvm_library(LLVMCodeGen    LiveIntervalAnalysis.cpp    LiveStackAnalysis.cpp    LiveVariables.cpp +  LiveRangeEdit.cpp    LocalStackSlotAllocation.cpp    LowerSubregs.cpp    MachineBasicBlock.cpp diff --git a/llvm/lib/CodeGen/InlineSpiller.cpp b/llvm/lib/CodeGen/InlineSpiller.cpp index 5fdc59ad667..60181d7cdfa 100644 --- a/llvm/lib/CodeGen/InlineSpiller.cpp +++ b/llvm/lib/CodeGen/InlineSpiller.cpp @@ -14,6 +14,7 @@  #define DEBUG_TYPE "spiller"  #include "Spiller.h" +#include "LiveRangeEdit.h"  #include "SplitKit.h"  #include "VirtRegMap.h"  #include "llvm/CodeGen/LiveIntervalAnalysis.h" @@ -44,11 +45,9 @@ class InlineSpiller : public Spiller {    SplitAnalysis splitAnalysis_;    // Variables that are valid during spill(), but used by multiple methods. -  LiveInterval *li_; -  SmallVectorImpl<LiveInterval*> *newIntervals_; +  LiveRangeEdit *edit_;    const TargetRegisterClass *rc_;    int stackSlot_; -  const SmallVectorImpl<LiveInterval*> *spillIs_;    // Values of the current interval that can potentially remat.    SmallPtrSet<VNInfo*, 8> reMattable_; @@ -78,11 +77,11 @@ public:               SmallVectorImpl<LiveInterval*> &newIntervals,               SmallVectorImpl<LiveInterval*> &spillIs); +  void spill(LiveRangeEdit &); +  private:    bool split(); -  bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, -                          SlotIndex UseIdx);    bool reMaterializeFor(MachineBasicBlock::iterator MI);    void reMaterializeAll(); @@ -105,11 +104,11 @@ Spiller *createInlineSpiller(MachineFunctionPass &pass,  /// split - try splitting the current interval into pieces that may allocate  /// separately. Return true if successful.  bool InlineSpiller::split() { -  splitAnalysis_.analyze(li_); +  splitAnalysis_.analyze(&edit_->getParent());    // Try splitting around loops.    if (const MachineLoop *loop = splitAnalysis_.getBestSplitLoop()) { -    SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_) +    SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)        .splitAroundLoop(loop);      return true;    } @@ -117,14 +116,14 @@ bool InlineSpiller::split() {    // Try splitting into single block intervals.    SplitAnalysis::BlockPtrSet blocks;    if (splitAnalysis_.getMultiUseBlocks(blocks)) { -    SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_) +    SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)        .splitSingleBlocks(blocks);      return true;    }    // Try splitting inside a basic block.    if (const MachineBasicBlock *MBB = splitAnalysis_.getBlockForInsideSplit()) { -    SplitEditor(splitAnalysis_, lis_, vrm_, *newIntervals_) +    SplitEditor(splitAnalysis_, lis_, vrm_, *edit_)        .splitInsideBlock(MBB);      return true;    } @@ -132,48 +131,16 @@ bool InlineSpiller::split() {    return false;  } -/// allUsesAvailableAt - Return true if all registers used by OrigMI at -/// OrigIdx are also available with the same value at UseIdx. -bool InlineSpiller::allUsesAvailableAt(const MachineInstr *OrigMI, -                                       SlotIndex OrigIdx, -                                       SlotIndex UseIdx) { -  OrigIdx = OrigIdx.getUseIndex(); -  UseIdx = UseIdx.getUseIndex(); -  for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { -    const MachineOperand &MO = OrigMI->getOperand(i); -    if (!MO.isReg() || !MO.getReg() || MO.getReg() == li_->reg) -      continue; -    // Reserved registers are OK. -    if (MO.isUndef() || !lis_.hasInterval(MO.getReg())) -      continue; -    // We don't want to move any defs. -    if (MO.isDef()) -      return false; -    // We cannot depend on virtual registers in spillIs_. They will be spilled. -    for (unsigned si = 0, se = spillIs_->size(); si != se; ++si) -      if ((*spillIs_)[si]->reg == MO.getReg()) -        return false; - -    LiveInterval &LI = lis_.getInterval(MO.getReg()); -    const VNInfo *OVNI = LI.getVNInfoAt(OrigIdx); -    if (!OVNI) -      continue; -    if (OVNI != LI.getVNInfoAt(UseIdx)) -      return false; -  } -  return true; -} - -/// reMaterializeFor - Attempt to rematerialize li_->reg before MI instead of +/// reMaterializeFor - Attempt to rematerialize edit_->getReg() before MI instead of  /// reloading it.  bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {    SlotIndex UseIdx = lis_.getInstructionIndex(MI).getUseIndex(); -  VNInfo *OrigVNI = li_->getVNInfoAt(UseIdx); +  VNInfo *OrigVNI = edit_->getParent().getVNInfoAt(UseIdx);    if (!OrigVNI) {      DEBUG(dbgs() << "\tadding <undef> flags: ");      for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {        MachineOperand &MO = MI->getOperand(i); -      if (MO.isReg() && MO.isUse() && MO.getReg() == li_->reg) +      if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg())          MO.setIsUndef();      }      DEBUG(dbgs() << UseIdx << '\t' << *MI); @@ -185,17 +152,17 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {      return false;    }    MachineInstr *OrigMI = lis_.getInstructionFromIndex(OrigVNI->def); -  if (!allUsesAvailableAt(OrigMI, OrigVNI->def, UseIdx)) { +  if (!edit_->allUsesAvailableAt(OrigMI, OrigVNI->def, UseIdx, lis_)) {      usedValues_.insert(OrigVNI);      DEBUG(dbgs() << "\tcannot remat for " << UseIdx << '\t' << *MI);      return false;    } -  // If the instruction also writes li_->reg, it had better not require the same +  // If the instruction also writes edit_->getReg(), it had better not require the same    // register for uses and defs.    bool Reads, Writes;    SmallVector<unsigned, 8> Ops; -  tie(Reads, Writes) = MI->readsWritesVirtualRegister(li_->reg, &Ops); +  tie(Reads, Writes) = MI->readsWritesVirtualRegister(edit_->getReg(), &Ops);    if (Writes) {      for (unsigned i = 0, e = Ops.size(); i != e; ++i) {        MachineOperand &MO = MI->getOperand(Ops[i]); @@ -208,11 +175,8 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {    }    // Alocate a new register for the remat. -  unsigned NewVReg = mri_.createVirtualRegister(rc_); -  vrm_.grow(); -  LiveInterval &NewLI = lis_.getOrCreateInterval(NewVReg); +  LiveInterval &NewLI = edit_->create(mri_, lis_, vrm_);    NewLI.markNotSpillable(); -  newIntervals_->push_back(&NewLI);    // Finally we can rematerialize OrigMI before MI.    MachineBasicBlock &MBB = *MI->getParent(); @@ -224,8 +188,8 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {    // Replace operands    for (unsigned i = 0, e = Ops.size(); i != e; ++i) {      MachineOperand &MO = MI->getOperand(Ops[i]); -    if (MO.isReg() && MO.isUse() && MO.getReg() == li_->reg) { -      MO.setReg(NewVReg); +    if (MO.isReg() && MO.isUse() && MO.getReg() == edit_->getReg()) { +      MO.setReg(NewLI.reg);        MO.setIsKill();      }    } @@ -237,14 +201,14 @@ bool InlineSpiller::reMaterializeFor(MachineBasicBlock::iterator MI) {    return true;  } -/// reMaterializeAll - Try to rematerialize as many uses of li_ as possible, +/// reMaterializeAll - Try to rematerialize as many uses as possible,  /// and trim the live ranges after.  void InlineSpiller::reMaterializeAll() {    // Do a quick scan of the interval values to find if any are remattable.    reMattable_.clear();    usedValues_.clear(); -  for (LiveInterval::const_vni_iterator I = li_->vni_begin(), -       E = li_->vni_end(); I != E; ++I) { +  for (LiveInterval::const_vni_iterator I = edit_->getParent().vni_begin(), +       E = edit_->getParent().vni_end(); I != E; ++I) {      VNInfo *VNI = *I;      if (VNI->isUnused())        continue; @@ -258,10 +222,10 @@ void InlineSpiller::reMaterializeAll() {    if (reMattable_.empty())      return; -  // Try to remat before all uses of li_->reg. +  // Try to remat before all uses of edit_->getReg().    bool anyRemat = false;    for (MachineRegisterInfo::use_nodbg_iterator -       RI = mri_.use_nodbg_begin(li_->reg); +       RI = mri_.use_nodbg_begin(edit_->getReg());         MachineInstr *MI = RI.skipInstruction();)       anyRemat |= reMaterializeFor(MI); @@ -287,16 +251,17 @@ void InlineSpiller::reMaterializeAll() {    if (!anyRemoved)      return; -  // Removing values may cause debug uses where li_ is not live. -  for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(li_->reg); +  // Removing values may cause debug uses where parent is not live. +  for (MachineRegisterInfo::use_iterator RI = mri_.use_begin(edit_->getReg());         MachineInstr *MI = RI.skipInstruction();) {      if (!MI->isDebugValue())        continue; -    // Try to preserve the debug value if li_ is live immediately after it. +    // Try to preserve the debug value if parent is live immediately after it.      MachineBasicBlock::iterator NextMI = MI;      ++NextMI;      if (NextMI != MI->getParent()->end() && !lis_.isNotInMIMap(NextMI)) { -      VNInfo *VNI = li_->getVNInfoAt(lis_.getInstructionIndex(NextMI)); +      SlotIndex Idx = lis_.getInstructionIndex(NextMI); +      VNInfo *VNI = edit_->getParent().getVNInfoAt(Idx);        if (VNI && (VNI->hasPHIKill() || usedValues_.count(VNI)))          continue;      } @@ -314,7 +279,7 @@ bool InlineSpiller::coalesceStackAccess(MachineInstr *MI) {      return false;    // We have a stack access. Is it the right register and slot? -  if (reg != li_->reg || FI != stackSlot_) +  if (reg != edit_->getReg() || FI != stackSlot_)      return false;    DEBUG(dbgs() << "Coalescing stack access: " << *MI); @@ -385,14 +350,16 @@ void InlineSpiller::insertSpill(LiveInterval &NewLI,  void InlineSpiller::spill(LiveInterval *li,                            SmallVectorImpl<LiveInterval*> &newIntervals,                            SmallVectorImpl<LiveInterval*> &spillIs) { -  DEBUG(dbgs() << "Inline spilling " << *li << "\n"); -  assert(li->isSpillable() && "Attempting to spill already spilled value."); -  assert(!li->isStackSlot() && "Trying to spill a stack slot."); +  LiveRangeEdit edit(*li, newIntervals, spillIs); +  spill(edit); +} -  li_ = li; -  newIntervals_ = &newIntervals; -  rc_ = mri_.getRegClass(li->reg); -  spillIs_ = &spillIs; +void InlineSpiller::spill(LiveRangeEdit &edit) { +  edit_ = &edit; +  DEBUG(dbgs() << "Inline spilling " << edit.getParent() << "\n"); +  assert(edit.getParent().isSpillable() && +         "Attempting to spill already spilled value."); +  assert(!edit.getParent().isStackSlot() && "Trying to spill a stack slot.");    if (split())      return; @@ -400,15 +367,16 @@ void InlineSpiller::spill(LiveInterval *li,    reMaterializeAll();    // Remat may handle everything. -  if (li_->empty()) +  if (edit_->getParent().empty())      return; -  stackSlot_ = vrm_.getStackSlot(li->reg); +  rc_ = mri_.getRegClass(edit.getReg()); +  stackSlot_ = vrm_.getStackSlot(edit.getReg());    if (stackSlot_ == VirtRegMap::NO_STACK_SLOT) -    stackSlot_ = vrm_.assignVirt2StackSlot(li->reg); +    stackSlot_ = vrm_.assignVirt2StackSlot(edit.getReg());    // Iterate over instructions using register. -  for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(li->reg); +  for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(edit.getReg());         MachineInstr *MI = RI.skipInstruction();) {      // Debug values are not allowed to affect codegen. @@ -436,7 +404,7 @@ void InlineSpiller::spill(LiveInterval *li,      // Analyze instruction.      bool Reads, Writes;      SmallVector<unsigned, 8> Ops; -    tie(Reads, Writes) = MI->readsWritesVirtualRegister(li->reg, &Ops); +    tie(Reads, Writes) = MI->readsWritesVirtualRegister(edit.getReg(), &Ops);      // Attempt to fold memory ops.      if (foldMemoryOperand(MI, Ops)) @@ -444,9 +412,7 @@ void InlineSpiller::spill(LiveInterval *li,      // Allocate interval around instruction.      // FIXME: Infer regclass from instruction alone. -    unsigned NewVReg = mri_.createVirtualRegister(rc_); -    vrm_.grow(); -    LiveInterval &NewLI = lis_.getOrCreateInterval(NewVReg); +    LiveInterval &NewLI = edit.create(mri_, lis_, vrm_);      NewLI.markNotSpillable();      if (Reads) @@ -456,7 +422,7 @@ void InlineSpiller::spill(LiveInterval *li,      bool hasLiveDef = false;      for (unsigned i = 0, e = Ops.size(); i != e; ++i) {        MachineOperand &MO = MI->getOperand(Ops[i]); -      MO.setReg(NewVReg); +      MO.setReg(NewLI.reg);        if (MO.isUse()) {          if (!MI->isRegTiedToDefOperand(Ops[i]))            MO.setIsKill(); @@ -471,6 +437,5 @@ void InlineSpiller::spill(LiveInterval *li,        insertSpill(NewLI, MI);      DEBUG(dbgs() << "\tinterval: " << NewLI << '\n'); -    newIntervals.push_back(&NewLI);    }  } diff --git a/llvm/lib/CodeGen/LiveRangeEdit.cpp b/llvm/lib/CodeGen/LiveRangeEdit.cpp new file mode 100644 index 00000000000..8a123fbe701 --- /dev/null +++ b/llvm/lib/CodeGen/LiveRangeEdit.cpp @@ -0,0 +1,64 @@ +//===--- LiveRangeEdit.cpp - Basic tools for editing a register live range --===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeEdit class represents changes done to a virtual register when it +// is spilled or split. +//===----------------------------------------------------------------------===// + +#include "LiveRangeEdit.h" +#include "VirtRegMap.h" +#include "llvm/CodeGen/LiveIntervalAnalysis.h" +#include "llvm/CodeGen/MachineRegisterInfo.h" + +using namespace llvm; + +LiveInterval &LiveRangeEdit::create(MachineRegisterInfo &mri, +                                    LiveIntervals &lis, +                                    VirtRegMap &vrm) { +  const TargetRegisterClass *RC = mri.getRegClass(parent_.reg); +  unsigned VReg = mri.createVirtualRegister(RC); +  vrm.grow(); +  LiveInterval &li = lis.getOrCreateInterval(VReg); +  newRegs_.push_back(&li); +  return li; +} + +/// allUsesAvailableAt - Return true if all registers used by OrigMI at +/// OrigIdx are also available with the same value at UseIdx. +bool LiveRangeEdit::allUsesAvailableAt(const MachineInstr *OrigMI, +                                       SlotIndex OrigIdx, +                                       SlotIndex UseIdx, +                                       LiveIntervals &lis) { +  OrigIdx = OrigIdx.getUseIndex(); +  UseIdx = UseIdx.getUseIndex(); +  for (unsigned i = 0, e = OrigMI->getNumOperands(); i != e; ++i) { +    const MachineOperand &MO = OrigMI->getOperand(i); +    if (!MO.isReg() || !MO.getReg() || MO.getReg() == getReg()) +      continue; +    // Reserved registers are OK. +    if (MO.isUndef() || !lis.hasInterval(MO.getReg())) +      continue; +    // We don't want to move any defs. +    if (MO.isDef()) +      return false; +    // We cannot depend on virtual registers in uselessRegs_. +    for (unsigned ui = 0, ue = uselessRegs_.size(); ui != ue; ++ui) +      if (uselessRegs_[ui]->reg == MO.getReg()) +        return false; + +    LiveInterval &li = lis.getInterval(MO.getReg()); +    const VNInfo *OVNI = li.getVNInfoAt(OrigIdx); +    if (!OVNI) +      continue; +    if (OVNI != li.getVNInfoAt(UseIdx)) +      return false; +  } +  return true; +} + diff --git a/llvm/lib/CodeGen/LiveRangeEdit.h b/llvm/lib/CodeGen/LiveRangeEdit.h new file mode 100644 index 00000000000..6abeda8a97f --- /dev/null +++ b/llvm/lib/CodeGen/LiveRangeEdit.h @@ -0,0 +1,70 @@ +//===---- LiveRangeEdit.h - Basic tools for split and spill -----*- C++ -*-===// +// +//                     The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// The LiveRangeEdit class represents changes done to a virtual register when it +// is spilled or split. +// +// The parent register is never changed. Instead, a number of new virtual +// registers are created and added to the newRegs vector. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CODEGEN_LIVERANGEEDIT_H +#define LLVM_CODEGEN_LIVERANGEEDIT_H + +#include "llvm/CodeGen/LiveInterval.h" + +namespace llvm { + +class LiveIntervals; +class MachineRegisterInfo; +class VirtRegMap; + +class LiveRangeEdit { +  LiveInterval &parent_; +  SmallVectorImpl<LiveInterval*> &newRegs_; +  const SmallVectorImpl<LiveInterval*> &uselessRegs_; + +  /// firstNew_ - Index of the first register added to newRegs_. +  const unsigned firstNew_; + +public: +  /// Create a LiveRangeEdit for breaking down parent into smaller pieces. +  /// @param parent The register being spilled or split. +  /// @param newRegs List to receive any new registers created. This needn't be +  ///                empty initially, any existing registers are ignored. +  /// @param uselessRegs List of registers that can't be used when +  ///        rematerializing values because they are about to be removed. +  LiveRangeEdit(LiveInterval &parent, +                SmallVectorImpl<LiveInterval*> &newRegs, +                const SmallVectorImpl<LiveInterval*> &uselessRegs) +    : parent_(parent), newRegs_(newRegs), uselessRegs_(uselessRegs), +      firstNew_(newRegs.size()) {} + +  LiveInterval &getParent() const { return parent_; } +  unsigned getReg() const { return parent_.reg; } + +  /// Iterator for accessing the new registers added by this edit. +  typedef SmallVectorImpl<LiveInterval*>::const_iterator iterator; +  iterator begin() const { return newRegs_.begin()+firstNew_; } +  iterator end() const { return newRegs_.end(); } + +  /// create - Create a new register with the same class as parentReg_. +  LiveInterval &create(MachineRegisterInfo&, LiveIntervals&, VirtRegMap&); + +  /// allUsesAvailableAt - Return true if all registers used by OrigMI at +  /// OrigIdx are also available with the same value at UseIdx. +  bool allUsesAvailableAt(const MachineInstr *OrigMI, SlotIndex OrigIdx, +                          SlotIndex UseIdx, LiveIntervals &lis); + +}; + +} + +#endif diff --git a/llvm/lib/CodeGen/SplitKit.cpp b/llvm/lib/CodeGen/SplitKit.cpp index 2ab7fa83e51..ea551bb623a 100644 --- a/llvm/lib/CodeGen/SplitKit.cpp +++ b/llvm/lib/CodeGen/SplitKit.cpp @@ -14,6 +14,7 @@  #define DEBUG_TYPE "splitter"  #include "SplitKit.h" +#include "LiveRangeEdit.h"  #include "VirtRegMap.h"  #include "llvm/CodeGen/CalcSpillWeights.h"  #include "llvm/CodeGen/LiveIntervalAnalysis.h" @@ -580,15 +581,14 @@ VNInfo *LiveIntervalMap::defByCopyFrom(unsigned Reg,  /// Create a new SplitEditor for editing the LiveInterval analyzed by SA.  SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm, -                         SmallVectorImpl<LiveInterval*> &intervals) +                         LiveRangeEdit &edit)    : sa_(sa), lis_(lis), vrm_(vrm),      mri_(vrm.getMachineFunction().getRegInfo()),      tii_(*vrm.getMachineFunction().getTarget().getInstrInfo()), +    edit_(edit),      curli_(sa_.getCurLI()),      dupli_(lis_, *curli_), -    openli_(lis_, *curli_), -    intervals_(intervals), -    firstInterval(intervals_.size()) +    openli_(lis_, *curli_)  {    assert(curli_ && "SplitEditor created from empty SplitAnalysis"); @@ -599,17 +599,9 @@ SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm,  } -LiveInterval *SplitEditor::createInterval() { -  unsigned Reg = mri_.createVirtualRegister(mri_.getRegClass(curli_->reg)); -  LiveInterval &Intv = lis_.getOrCreateInterval(Reg); -  vrm_.grow(); -  vrm_.assignVirt2StackSlot(Reg, vrm_.getStackSlot(curli_->reg)); -  return &Intv; -} -  bool SplitEditor::intervalsLiveAt(SlotIndex Idx) const { -  for (int i = firstInterval, e = intervals_.size(); i != e; ++i) -    if (intervals_[i]->liveAt(Idx)) +  for (LiveRangeEdit::iterator I = edit_.begin(), E = edit_.end(); I != E; ++I) +    if (*I != dupli_.getLI() && (*I)->liveAt(Idx))        return true;    return false;  } @@ -619,10 +611,9 @@ void SplitEditor::openIntv() {    assert(!openli_.getLI() && "Previous LI not closed before openIntv");    if (!dupli_.getLI()) -    dupli_.reset(createInterval()); +    dupli_.reset(&edit_.create(mri_, lis_, vrm_)); -  openli_.reset(createInterval()); -  intervals_.push_back(openli_.getLI()); +  openli_.reset(&edit_.create(mri_, lis_, vrm_));  }  /// enterIntvBefore - Enter openli before the instruction at Idx. If curli is @@ -749,8 +740,9 @@ void SplitEditor::rewrite(unsigned reg) {      SlotIndex Idx = lis_.getInstructionIndex(MI);      Idx = MO.isUse() ? Idx.getUseIndex() : Idx.getDefIndex();      LiveInterval *LI = 0; -    for (unsigned i = firstInterval, e = intervals_.size(); i != e; ++i) { -      LiveInterval *testli = intervals_[i]; +    for (LiveRangeEdit::iterator I = edit_.begin(), E = edit_.end(); I != E; +         ++I) { +      LiveInterval *testli = *I;        if (testli->liveAt(Idx)) {          LI = testli;          break; @@ -769,9 +761,10 @@ SplitEditor::addTruncSimpleRange(SlotIndex Start, SlotIndex End, VNInfo *VNI) {    typedef std::pair<LiveInterval::const_iterator,                      LiveInterval::const_iterator> IIPair;    SmallVector<IIPair, 8> Iters; -  for (int i = firstInterval, e = intervals_.size(); i != e; ++i) { -    LiveInterval::const_iterator I = intervals_[i]->find(Start); -    LiveInterval::const_iterator E = intervals_[i]->end(); +  for (LiveRangeEdit::iterator LI = edit_.begin(), LE = edit_.end(); LI != LE; +       ++LI) { +    LiveInterval::const_iterator I = (*LI)->find(Start); +    LiveInterval::const_iterator E = (*LI)->end();      if (I != E)        Iters.push_back(std::make_pair(I, E));    } @@ -868,20 +861,16 @@ void SplitEditor::finish() {    if (unsigned NumComp = ConEQ.Classify(dupli_.getLI())) {      DEBUG(dbgs() << "  Remainder has " << NumComp << " connected components: "                   << *dupli_.getLI() << '\n'); -    unsigned firstComp = intervals_.size(); -    intervals_.push_back(dupli_.getLI());      // Did the remainder break up? Create intervals for all the components.      if (NumComp > 1) { +      SmallVector<LiveInterval*, 8> dups; +      dups.push_back(dupli_.getLI());        for (unsigned i = 1; i != NumComp; ++i) -        intervals_.push_back(createInterval()); -      ConEQ.Distribute(&intervals_[firstComp]); +        dups.push_back(&edit_.create(mri_, lis_, vrm_)); +      ConEQ.Distribute(&dups[0]);        // Rewrite uses to the new regs.        rewrite(dupli_.getLI()->reg);      } -  } else { -    DEBUG(dbgs() << "  dupli became empty?\n"); -    lis_.removeInterval(dupli_.getLI()->reg); -    dupli_.reset(0);    }    // Rewrite instructions. @@ -889,8 +878,8 @@ void SplitEditor::finish() {    // Calculate spill weight and allocation hints for new intervals.    VirtRegAuxInfo vrai(vrm_.getMachineFunction(), lis_, sa_.loops_); -  for (unsigned i = firstInterval, e = intervals_.size(); i != e; ++i) { -    LiveInterval &li = *intervals_[i]; +  for (LiveRangeEdit::iterator I = edit_.begin(), E = edit_.end(); I != E; ++I){ +    LiveInterval &li = **I;      vrai.CalculateRegClass(li.reg);      vrai.CalculateWeightAndHint(li);      DEBUG(dbgs() << "  new interval " << mri_.getRegClass(li.reg)->getName() diff --git a/llvm/lib/CodeGen/SplitKit.h b/llvm/lib/CodeGen/SplitKit.h index dff3765ec38..005ceda3c2a 100644 --- a/llvm/lib/CodeGen/SplitKit.h +++ b/llvm/lib/CodeGen/SplitKit.h @@ -20,6 +20,7 @@ namespace llvm {  class LiveInterval;  class LiveIntervals; +class LiveRangeEdit;  class MachineInstr;  class MachineLoop;  class MachineLoopInfo; @@ -238,6 +239,9 @@ class SplitEditor {    MachineRegisterInfo &mri_;    const TargetInstrInfo &tii_; +  /// edit_ - The current parent register and new intervals created. +  LiveRangeEdit &edit_; +    /// curli_ - The immutable interval we are currently splitting.    const LiveInterval *const curli_; @@ -249,17 +253,6 @@ class SplitEditor {    /// Currently open LiveInterval.    LiveIntervalMap openli_; -  /// createInterval - Create a new virtual register and LiveInterval with same -  /// register class and spill slot as curli. -  LiveInterval *createInterval(); - -  /// All the new intervals created for this split are added to intervals_. -  SmallVectorImpl<LiveInterval*> &intervals_; - -  /// The index into intervals_ of the first interval we added. There may be -  /// others from before we got it. -  unsigned firstInterval; -    /// intervalsLiveAt - Return true if any member of intervals_ is live at Idx.    bool intervalsLiveAt(SlotIndex Idx) const; @@ -281,8 +274,7 @@ class SplitEditor {  public:    /// Create a new SplitEditor for editing the LiveInterval analyzed by SA.    /// Newly created intervals will be appended to newIntervals. -  SplitEditor(SplitAnalysis &SA, LiveIntervals&, VirtRegMap&, -              SmallVectorImpl<LiveInterval*> &newIntervals); +  SplitEditor(SplitAnalysis &SA, LiveIntervals&, VirtRegMap&, LiveRangeEdit&);    /// getAnalysis - Get the corresponding analysis.    SplitAnalysis &getAnalysis() { return sa_; }  | 

