diff options
Diffstat (limited to 'lib/CodeGen')
-rw-r--r-- | lib/CodeGen/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/CodeGen/InlineSpiller.cpp | 125 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.cpp | 64 | ||||
-rw-r--r-- | lib/CodeGen/LiveRangeEdit.h | 70 | ||||
-rw-r--r-- | lib/CodeGen/SplitKit.cpp | 53 | ||||
-rw-r--r-- | lib/CodeGen/SplitKit.h | 18 |
6 files changed, 206 insertions, 125 deletions
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt index a2e04ff..dbf5dca 100644 --- a/lib/CodeGen/CMakeLists.txt +++ b/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/lib/CodeGen/InlineSpiller.cpp b/lib/CodeGen/InlineSpiller.cpp index 5fdc59a..60181d7 100644 --- a/lib/CodeGen/InlineSpiller.cpp +++ b/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/lib/CodeGen/LiveRangeEdit.cpp b/lib/CodeGen/LiveRangeEdit.cpp new file mode 100644 index 0000000..8a123fb --- /dev/null +++ b/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/lib/CodeGen/LiveRangeEdit.h b/lib/CodeGen/LiveRangeEdit.h new file mode 100644 index 0000000..6abeda8 --- /dev/null +++ b/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/lib/CodeGen/SplitKit.cpp b/lib/CodeGen/SplitKit.cpp index 2ab7fa8..ea551bb 100644 --- a/lib/CodeGen/SplitKit.cpp +++ b/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/lib/CodeGen/SplitKit.h b/lib/CodeGen/SplitKit.h index dff3765..005ceda 100644 --- a/lib/CodeGen/SplitKit.h +++ b/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_; } |