//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "splitter"
+#define DEBUG_TYPE "regalloc"
#include "SplitKit.h"
#include "LiveRangeEdit.h"
#include "VirtRegMap.h"
#include "llvm/CodeGen/CalcSpillWeights.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
+#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
AllowSplit("spiller-splits-edges",
cl::desc("Allow critical edge splitting during spilling"));
+//===----------------------------------------------------------------------===//
+// Edge Bundles
+//===----------------------------------------------------------------------===//
+
+/// compute - Compute the edge bundles for MF. Bundles depend only on the CFG.
+void EdgeBundles::compute(const MachineFunction *mf) {
+ MF = mf;
+ EC.clear();
+ EC.grow(2 * MF->size());
+
+ for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
+ ++I) {
+ const MachineBasicBlock &MBB = *I;
+ unsigned OutE = 2 * MBB.getNumber() + 1;
+ // Join the outgoing bundle with the ingoing bundles of all successors.
+ for (MachineBasicBlock::const_succ_iterator SI = MBB.succ_begin(),
+ SE = MBB.succ_end(); SI != SE; ++SI)
+ EC.join(OutE, 2 * (*SI)->getNumber());
+ }
+ EC.compress();
+}
+
+/// view - Visualize the annotated bipartite CFG with Graphviz.
+void EdgeBundles::view() const {
+ ViewGraph(*this, "EdgeBundles");
+}
+
+/// Specialize WriteGraph, the standard implementation won't work.
+raw_ostream &llvm::WriteGraph(raw_ostream &O, const EdgeBundles &G,
+ bool ShortNames,
+ const std::string &Title) {
+ const MachineFunction *MF = G.getMachineFunction();
+
+ O << "digraph {\n";
+ for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ I != E; ++I) {
+ unsigned BB = I->getNumber();
+ O << "\t\"BB#" << BB << "\" [ shape=box ]\n"
+ << '\t' << G.getBundle(BB, false) << " -> \"BB#" << BB << "\"\n"
+ << "\t\"BB#" << BB << "\" -> " << G.getBundle(BB, true) << '\n';
+ }
+ O << "}\n";
+ return O;
+}
+
+
//===----------------------------------------------------------------------===//
// Split Analysis
//===----------------------------------------------------------------------===//
analyzeUses();
}
-const MachineLoop *SplitAnalysis::getBestSplitLoop() {
- assert(curli_ && "Call analyze() before getBestSplitLoop");
+void SplitAnalysis::getSplitLoops(LoopPtrSet &Loops) {
+ assert(curli_ && "Call analyze() before getSplitLoops");
if (usingLoops_.empty())
- return 0;
+ return;
- LoopPtrSet Loops;
LoopBlocks Blocks;
BlockPtrSet CriticalExits;
// FIXME: We could split a live range with multiple uses in a peripheral
// block and still make progress. However, it is possible that splitting
// another live range will insert copies into a peripheral block, and
- // there is a small chance we can enter an infinity loop, inserting copies
+ // there is a small chance we can enter an infinite loop, inserting copies
// forever.
// For safety, stick to splitting live ranges with uses outside the
// periphery.
- DEBUG(dbgs() << ": multiple peripheral uses\n");
+ DEBUG(dbgs() << ": multiple peripheral uses");
break;
case ContainedInLoop:
DEBUG(dbgs() << ": fully contained\n");
Loops.insert(Loop);
}
- DEBUG(dbgs() << " getBestSplitLoop found " << Loops.size()
+ DEBUG(dbgs() << " getSplitLoops found " << Loops.size()
<< " candidate loops.\n");
+}
+const MachineLoop *SplitAnalysis::getBestSplitLoop() {
+ LoopPtrSet Loops;
+ getSplitLoops(Loops);
if (Loops.empty())
return 0;
return Best;
}
+/// isBypassLoop - Return true if curli is live through Loop and has no uses
+/// inside the loop. Bypass loops are candidates for splitting because it can
+/// prevent interference inside the loop.
+bool SplitAnalysis::isBypassLoop(const MachineLoop *Loop) {
+ // If curli is live into the loop header and there are no uses in the loop, it
+ // must be live in the entire loop and live on at least one exiting edge.
+ return !usingLoops_.count(Loop) &&
+ lis_.isLiveInToMBB(*curli_, Loop->getHeader());
+}
+
+/// getBypassLoops - Get all the maximal bypass loops. These are the bypass
+/// loops whose parent is not a bypass loop.
+void SplitAnalysis::getBypassLoops(LoopPtrSet &BypassLoops) {
+ SmallVector<MachineLoop*, 8> Todo(loops_.begin(), loops_.end());
+ while (!Todo.empty()) {
+ MachineLoop *Loop = Todo.pop_back_val();
+ if (!usingLoops_.count(Loop)) {
+ // This is either a bypass loop or completely irrelevant.
+ if (lis_.isLiveInToMBB(*curli_, Loop->getHeader()))
+ BypassLoops.insert(Loop);
+ // Either way, skip the child loops.
+ continue;
+ }
+
+ // The child loops may be bypass loops.
+ Todo.append(Loop->begin(), Loop->end());
+ }
+}
+
+
//===----------------------------------------------------------------------===//
// LiveIntervalMap
//===----------------------------------------------------------------------===//
void LiveIntervalMap::reset(LiveInterval *li) {
li_ = li;
valueMap_.clear();
+ liveOutCache_.clear();
}
bool LiveIntervalMap::isComplexMapped(const VNInfo *ParentVNI) const {
// Now for the fun part. We know that ParentVNI potentially has multiple defs,
// and we may need to create even more phi-defs to preserve VNInfo SSA form.
- // Perform a depth-first search for predecessor blocks where we know the
- // dominating VNInfo. Insert phi-def VNInfos along the path back to IdxMBB.
-
- // Track MBBs where we have created or learned the dominating value.
- // This may change during the DFS as we create new phi-defs.
- typedef DenseMap<MachineBasicBlock*, VNInfo*> MBBValueMap;
- MBBValueMap DomValue;
- typedef SplitAnalysis::BlockPtrSet BlockPtrSet;
- BlockPtrSet Visited;
-
- // Iterate over IdxMBB predecessors in a depth-first order.
- // Skip begin() since that is always IdxMBB.
- for (idf_ext_iterator<MachineBasicBlock*, BlockPtrSet>
- IDFI = llvm::next(idf_ext_begin(IdxMBB, Visited)),
- IDFE = idf_ext_end(IdxMBB, Visited); IDFI != IDFE;) {
- MachineBasicBlock *MBB = *IDFI;
- SlotIndex End = lis_.getMBBEndIdx(MBB).getPrevSlot();
-
- // We are operating on the restricted CFG where ParentVNI is live.
- if (parentli_.getVNInfoAt(End) != ParentVNI) {
- IDFI.skipChildren();
- continue;
+ // Perform a search for all predecessor blocks where we know the dominating
+ // VNInfo. Insert phi-def VNInfos along the path back to IdxMBB.
+ DEBUG(dbgs() << "\n Reaching defs for BB#" << IdxMBB->getNumber()
+ << " at " << Idx << " in " << *li_ << '\n');
+
+ // Blocks where li_ should be live-in.
+ SmallVector<MachineDomTreeNode*, 16> LiveIn;
+ LiveIn.push_back(mdt_[IdxMBB]);
+
+ // Using liveOutCache_ as a visited set, perform a BFS for all reaching defs.
+ for (unsigned i = 0; i != LiveIn.size(); ++i) {
+ MachineBasicBlock *MBB = LiveIn[i]->getBlock();
+ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+ PE = MBB->pred_end(); PI != PE; ++PI) {
+ MachineBasicBlock *Pred = *PI;
+ // Is this a known live-out block?
+ std::pair<LiveOutMap::iterator,bool> LOIP =
+ liveOutCache_.insert(std::make_pair(Pred, LiveOutPair()));
+ // Yes, we have been here before.
+ if (!LOIP.second) {
+ DEBUG(if (VNInfo *VNI = LOIP.first->second.first)
+ dbgs() << " known valno #" << VNI->id
+ << " at BB#" << Pred->getNumber() << '\n');
+ continue;
+ }
+
+ // Does Pred provide a live-out value?
+ SlotIndex Last = lis_.getMBBEndIdx(Pred).getPrevSlot();
+ if (VNInfo *VNI = extendTo(Pred, Last)) {
+ MachineBasicBlock *DefMBB = lis_.getMBBFromIndex(VNI->def);
+ DEBUG(dbgs() << " found valno #" << VNI->id
+ << " from BB#" << DefMBB->getNumber()
+ << " at BB#" << Pred->getNumber() << '\n');
+ LiveOutPair &LOP = LOIP.first->second;
+ LOP.first = VNI;
+ LOP.second = mdt_[DefMBB];
+ continue;
+ }
+ // No, we need a live-in value for Pred as well
+ if (Pred != IdxMBB)
+ LiveIn.push_back(mdt_[Pred]);
}
+ }
- // Do we have a dominating value in this block?
- VNInfo *VNI = extendTo(MBB, End);
- if (!VNI) {
- ++IDFI;
- continue;
- }
-
- // Yes, VNI dominates MBB. Make sure we visit MBB again from other paths.
- Visited.erase(MBB);
-
- // Track the path back to IdxMBB, creating phi-defs
- // as needed along the way.
- for (unsigned PI = IDFI.getPathLength()-1; PI != 0; --PI) {
- // Start from MBB's immediate successor. End at IdxMBB.
- MachineBasicBlock *Succ = IDFI.getPath(PI-1);
- std::pair<MBBValueMap::iterator, bool> InsP =
- DomValue.insert(MBBValueMap::value_type(Succ, VNI));
-
- // This is the first time we backtrack to Succ.
- if (InsP.second)
- continue;
-
- // We reached Succ again with the same VNI. Nothing is going to change.
- VNInfo *OVNI = InsP.first->second;
- if (OVNI == VNI)
- break;
+ // We may need to add phi-def values to preserve the SSA form.
+ // This is essentially the same iterative algorithm that SSAUpdater uses,
+ // except we already have a dominator tree, so we don't have to recompute it.
+ VNInfo *IdxVNI = 0;
+ unsigned Changes;
+ do {
+ Changes = 0;
+ DEBUG(dbgs() << " Iterating over " << LiveIn.size() << " blocks.\n");
+ // Propagate live-out values down the dominator tree, inserting phi-defs when
+ // necessary. Since LiveIn was created by a BFS, going backwards makes it more
+ // likely for us to visit immediate dominators before their children.
+ for (unsigned i = LiveIn.size(); i; --i) {
+ MachineDomTreeNode *Node = LiveIn[i-1];
+ MachineBasicBlock *MBB = Node->getBlock();
+ MachineDomTreeNode *IDom = Node->getIDom();
+ LiveOutPair IDomValue;
+ // We need a live-in value to a block with no immediate dominator?
+ // This is probably an unreachable block that has survived somehow.
+ bool needPHI = !IDom;
+
+ // Get the IDom live-out value.
+ if (!needPHI) {
+ LiveOutMap::iterator I = liveOutCache_.find(IDom->getBlock());
+ if (I != liveOutCache_.end())
+ IDomValue = I->second;
+ else
+ // If IDom is outside our set of live-out blocks, there must be new
+ // defs, and we need a phi-def here.
+ needPHI = true;
+ }
- // Succ already has a phi-def. No need to continue.
- SlotIndex Start = lis_.getMBBStartIdx(Succ);
- if (OVNI->def == Start)
- break;
+ // IDom dominates all of our predecessors, but it may not be the immediate
+ // dominator. Check if any of them have live-out values that are properly
+ // dominated by IDom. If so, we need a phi-def here.
+ if (!needPHI) {
+ for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(),
+ PE = MBB->pred_end(); PI != PE; ++PI) {
+ LiveOutPair Value = liveOutCache_[*PI];
+ if (!Value.first || Value.first == IDomValue.first)
+ continue;
+ // This predecessor is carrying something other than IDomValue.
+ // It could be because IDomValue hasn't propagated yet, or it could be
+ // because MBB is in the dominance frontier of that value.
+ if (mdt_.dominates(IDom, Value.second)) {
+ needPHI = true;
+ break;
+ }
+ }
+ }
- // We have a collision between the old and new VNI at Succ. That means
- // neither dominates and we need a new phi-def.
- VNI = li_->getNextValue(Start, 0, lis_.getVNInfoAllocator());
- VNI->setIsPHIDef(true);
- InsP.first->second = VNI;
-
- // Replace OVNI with VNI in the remaining path.
- for (; PI > 1 ; --PI) {
- MBBValueMap::iterator I = DomValue.find(IDFI.getPath(PI-2));
- if (I == DomValue.end() || I->second != OVNI)
- break;
- I->second = VNI;
+ // Create a phi-def if required.
+ if (needPHI) {
+ ++Changes;
+ SlotIndex Start = lis_.getMBBStartIdx(MBB);
+ VNInfo *VNI = li_->getNextValue(Start, 0, lis_.getVNInfoAllocator());
+ VNI->setIsPHIDef(true);
+ DEBUG(dbgs() << " - BB#" << MBB->getNumber()
+ << " phi-def #" << VNI->id << " at " << Start << '\n');
+ // We no longer need li_ to be live-in.
+ LiveIn.erase(LiveIn.begin()+(i-1));
+ // Blocks in LiveIn are either IdxMBB, or have a value live-through.
+ if (MBB == IdxMBB)
+ IdxVNI = VNI;
+ // Check if we need to update live-out info.
+ LiveOutMap::iterator I = liveOutCache_.find(MBB);
+ if (I == liveOutCache_.end() || I->second.second == Node) {
+ // We already have a live-out defined in MBB, so this must be IdxMBB.
+ assert(MBB == IdxMBB && "Adding phi-def to known live-out");
+ li_->addRange(LiveRange(Start, Idx.getNextSlot(), VNI));
+ } else {
+ // This phi-def is also live-out, so color the whole block.
+ li_->addRange(LiveRange(Start, lis_.getMBBEndIdx(MBB), VNI));
+ I->second = LiveOutPair(VNI, Node);
+ }
+ } else if (IDomValue.first) {
+ // No phi-def here. Remember incoming value for IdxMBB.
+ if (MBB == IdxMBB)
+ IdxVNI = IDomValue.first;
+ // Propagate IDomValue if needed:
+ // MBB is live-out and doesn't define its own value.
+ LiveOutMap::iterator I = liveOutCache_.find(MBB);
+ if (I != liveOutCache_.end() && I->second.second != Node &&
+ I->second.first != IDomValue.first) {
+ ++Changes;
+ I->second = IDomValue;
+ DEBUG(dbgs() << " - BB#" << MBB->getNumber()
+ << " idom valno #" << IDomValue.first->id
+ << " from BB#" << IDom->getBlock()->getNumber() << '\n');
+ }
}
}
+ DEBUG(dbgs() << " - made " << Changes << " changes.\n");
+ } while (Changes);
- // No need to search the children, we found a dominating value.
- IDFI.skipChildren();
- }
+ assert(IdxVNI && "Didn't find value for Idx");
- // The search should at least find a dominating value for IdxMBB.
- assert(!DomValue.empty() && "Couldn't find a reaching definition");
+#ifndef NDEBUG
+ // Check the liveOutCache_ invariants.
+ for (LiveOutMap::iterator I = liveOutCache_.begin(), E = liveOutCache_.end();
+ I != E; ++I) {
+ assert(I->first && "Null MBB entry in cache");
+ assert(I->second.first && "Null VNInfo in cache");
+ assert(I->second.second && "Null DomTreeNode in cache");
+ if (I->second.second->getBlock() == I->first)
+ continue;
+ for (MachineBasicBlock::pred_iterator PI = I->first->pred_begin(),
+ PE = I->first->pred_end(); PI != PE; ++PI)
+ assert(liveOutCache_.lookup(*PI) == I->second && "Bad invariant");
+ }
+#endif
- // Since we went through the trouble of a full DFS visiting all reaching defs,
- // the values in DomValue are now accurate. No more phi-defs are needed for
- // these blocks, so we can color the live ranges.
+ // Since we went through the trouble of a full BFS visiting all reaching defs,
+ // the values in LiveIn are now accurate. No more phi-defs are needed
+ // for these blocks, so we can color the live ranges.
// This makes the next mapValue call much faster.
- VNInfo *IdxVNI = 0;
- for (MBBValueMap::iterator I = DomValue.begin(), E = DomValue.end(); I != E;
- ++I) {
- MachineBasicBlock *MBB = I->first;
- VNInfo *VNI = I->second;
- SlotIndex Start = lis_.getMBBStartIdx(MBB);
- if (MBB == IdxMBB) {
- // Don't add full liveness to IdxMBB, stop at Idx.
- if (Start != Idx)
- li_->addRange(LiveRange(Start, Idx.getNextSlot(), VNI));
- // The caller had better add some liveness to IdxVNI, or it leaks.
- IdxVNI = VNI;
- } else
- li_->addRange(LiveRange(Start, lis_.getMBBEndIdx(MBB), VNI));
+ for (unsigned i = 0, e = LiveIn.size(); i != e; ++i) {
+ MachineBasicBlock *MBB = LiveIn[i]->getBlock();
+ SlotIndex Start = lis_.getMBBStartIdx(MBB);
+ if (MBB == IdxMBB) {
+ li_->addRange(LiveRange(Start, Idx.getNextSlot(), IdxVNI));
+ continue;
+ }
+ // Anything in LiveIn other than IdxMBB is live-through.
+ VNInfo *VNI = liveOutCache_.lookup(MBB).first;
+ assert(VNI && "Missing block value");
+ li_->addRange(LiveRange(Start, lis_.getMBBEndIdx(MBB), VNI));
}
- assert(IdxVNI && "Didn't find value for Idx");
return IdxVNI;
}
// 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.
-VNInfo *LiveIntervalMap::extendTo(MachineBasicBlock *MBB, SlotIndex Idx) {
+VNInfo *LiveIntervalMap::extendTo(const MachineBasicBlock *MBB, SlotIndex Idx) {
assert(li_ && "call reset first");
LiveInterval::iterator I = std::upper_bound(li_->begin(), li_->end(), Idx);
if (I == li_->begin())
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
//===----------------------------------------------------------------------===//
/// Create a new SplitEditor for editing the LiveInterval analyzed by SA.
-SplitEditor::SplitEditor(SplitAnalysis &sa, LiveIntervals &lis, VirtRegMap &vrm,
+SplitEditor::SplitEditor(SplitAnalysis &sa,
+ LiveIntervals &lis,
+ VirtRegMap &vrm,
+ MachineDominatorTree &mdt,
LiveRangeEdit &edit)
: sa_(sa), lis_(lis), vrm_(vrm),
mri_(vrm.getMachineFunction().getRegInfo()),
tii_(*vrm.getMachineFunction().getTarget().getInstrInfo()),
+ tri_(*vrm.getMachineFunction().getTarget().getRegisterInfo()),
edit_(edit),
- dupli_(lis_, edit.getParent()),
- openli_(lis_, edit.getParent())
+ dupli_(lis_, mdt, edit.getParent()),
+ openli_(lis_, mdt, edit.getParent())
{
+ // We don't need an AliasAnalysis since we will only be performing
+ // cheap-as-a-copy remats anyway.
+ edit_.anyRematerializable(lis_, tii_, 0);
}
bool SplitEditor::intervalsLiveAt(SlotIndex Idx) const {
return false;
}
+VNInfo *SplitEditor::defFromParent(LiveIntervalMap &Reg,
+ VNInfo *ParentVNI,
+ SlotIndex UseIdx,
+ MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator I) {
+ VNInfo *VNI = 0;
+ MachineInstr *CopyMI = 0;
+ SlotIndex Def;
+
+ // Attempt cheap-as-a-copy rematerialization.
+ LiveRangeEdit::Remat RM(ParentVNI);
+ if (edit_.canRematerializeAt(RM, UseIdx, true, lis_)) {
+ Def = edit_.rematerializeAt(MBB, I, Reg.getLI()->reg, RM,
+ lis_, tii_, tri_);
+ } else {
+ // Can't remat, just insert a copy from parent.
+ CopyMI = BuildMI(MBB, I, DebugLoc(), tii_.get(TargetOpcode::COPY),
+ Reg.getLI()->reg).addReg(edit_.getReg());
+ Def = lis_.InsertMachineInstrInMaps(CopyMI).getDefIndex();
+ }
+
+ // Define the value in Reg.
+ VNI = Reg.defValue(ParentVNI, Def);
+ VNI->setCopy(CopyMI);
+
+ // Add minimal liveness for the new value.
+ if (UseIdx < Def)
+ UseIdx = Def;
+ Reg.getLI()->addRange(LiveRange(Def, UseIdx.getNextSlot(), VNI));
+ return VNI;
+}
+
/// Create a new virtual register and live interval.
void SplitEditor::openIntv() {
assert(!openli_.getLI() && "Previous LI not closed before openIntv");
-
if (!dupli_.getLI())
dupli_.reset(&edit_.create(mri_, lis_, vrm_));
/// not live before Idx, a COPY is not inserted.
void SplitEditor::enterIntvBefore(SlotIndex Idx) {
assert(openli_.getLI() && "openIntv not called before enterIntvBefore");
+ Idx = Idx.getUseIndex();
DEBUG(dbgs() << " enterIntvBefore " << Idx);
- VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(Idx.getUseIndex());
+ VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(Idx);
if (!ParentVNI) {
DEBUG(dbgs() << ": not live\n");
return;
truncatedValues.insert(ParentVNI);
MachineInstr *MI = lis_.getInstructionFromIndex(Idx);
assert(MI && "enterIntvBefore called with invalid index");
- VNInfo *VNI = openli_.defByCopyFrom(edit_.getReg(), ParentVNI,
- *MI->getParent(), MI);
- openli_.getLI()->addRange(LiveRange(VNI->def, Idx.getDefIndex(), VNI));
+
+ defFromParent(openli_, ParentVNI, Idx, *MI->getParent(), MI);
+
DEBUG(dbgs() << ": " << *openli_.getLI() << '\n');
}
/// enterIntvAtEnd - Enter openli at the end of MBB.
void SplitEditor::enterIntvAtEnd(MachineBasicBlock &MBB) {
assert(openli_.getLI() && "openIntv not called before enterIntvAtEnd");
- SlotIndex End = lis_.getMBBEndIdx(&MBB);
+ SlotIndex End = lis_.getMBBEndIdx(&MBB).getPrevSlot();
DEBUG(dbgs() << " enterIntvAtEnd BB#" << MBB.getNumber() << ", " << End);
- VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(End.getPrevSlot());
+ VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(End);
if (!ParentVNI) {
DEBUG(dbgs() << ": not live\n");
return;
}
DEBUG(dbgs() << ": valno " << ParentVNI->id);
truncatedValues.insert(ParentVNI);
- VNInfo *VNI = openli_.defByCopyFrom(edit_.getReg(), ParentVNI,
- MBB, MBB.getFirstTerminator());
- // Make sure openli is live out of MBB.
- openli_.getLI()->addRange(LiveRange(VNI->def, End, VNI));
+ defFromParent(openli_, ParentVNI, End, MBB, MBB.getFirstTerminator());
DEBUG(dbgs() << ": " << *openli_.getLI() << '\n');
}
DEBUG(dbgs() << " leaveIntvAfter " << Idx);
// The interval must be live beyond the instruction at Idx.
- VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(Idx.getBoundaryIndex());
+ Idx = Idx.getBoundaryIndex();
+ VNInfo *ParentVNI = edit_.getParent().getVNInfoAt(Idx);
if (!ParentVNI) {
DEBUG(dbgs() << ": not live\n");
return;
DEBUG(dbgs() << ": valno " << ParentVNI->id);
MachineBasicBlock::iterator MII = lis_.getInstructionFromIndex(Idx);
- MachineBasicBlock *MBB = MII->getParent();
- VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI, *MBB,
- llvm::next(MII));
+ VNInfo *VNI = defFromParent(dupli_, ParentVNI, Idx,
+ *MII->getParent(), llvm::next(MII));
+
+ // Make sure that openli is properly extended from Idx to the new copy.
+ // FIXME: This shouldn't be necessary for remats.
+ openli_.addSimpleRange(Idx, VNI->def, ParentVNI);
- // Finally we must make sure that openli is properly extended from Idx to the
- // new copy.
- openli_.addSimpleRange(Idx.getBoundaryIndex(), VNI->def, ParentVNI);
DEBUG(dbgs() << ": " << *openli_.getLI() << '\n');
}
return;
}
- // We are going to insert a back copy, so we must have a dupli_.
- VNInfo *VNI = dupli_.defByCopyFrom(openli_.getLI()->reg, ParentVNI,
- MBB, MBB.begin());
+ VNInfo *VNI = defFromParent(dupli_, ParentVNI, Start, MBB,
+ MBB.SkipPHIsAndLabels(MBB.begin()));
// Finally we must make sure that openli is properly extended from Start to
// the new copy.
for (MachineRegisterInfo::reg_iterator RI = mri_.reg_begin(reg),
RE = mri_.reg_end(); RI != RE;) {
MachineOperand &MO = RI.getOperand();
+ unsigned OpNum = RI.getOperandNo();
MachineInstr *MI = MO.getParent();
++RI;
if (MI->isDebugValue()) {
DEBUG(dbgs() << " rewr BB#" << MI->getParent()->getNumber() << '\t'<< Idx);
assert(LI && "No register was live at use");
MO.setReg(LI->reg);
+ if (MO.isUse() && !MI->isRegTiedToDefOperand(OpNum))
+ MO.setIsKill(LI->killedAt(Idx.getDefIndex()));
DEBUG(dbgs() << '\t' << *MI);
}
}
for (LiveInterval::const_vni_iterator I = parent.vni_begin(),
E = parent.vni_end(); I != E; ++I) {
const VNInfo *VNI = *I;
+ // Don't transfer unused values to the new intervals.
+ if (VNI->isUnused())
+ continue;
// Original def is contained in the split intervals.
if (intervalsLiveAt(VNI->def)) {
// Did this value escape?
dupli_.addSimpleRange(LR.start, LR.end, LR.valno);
}
}
+
+ // Extend dupli_ to be live out of any critical loop predecessors.
+ // This means we have multiple registers live out of those blocks.
+ // The alternative would be to split the critical edges.
+ if (criticalPreds_.empty())
+ return;
+ for (SplitAnalysis::BlockPtrSet::iterator I = criticalPreds_.begin(),
+ E = criticalPreds_.end(); I != E; ++I)
+ dupli_.extendTo(*I, lis_.getMBBEndIdx(*I).getPrevSlot());
+ criticalPreds_.clear();
}
void SplitEditor::finish() {
sa_.getCriticalExits(Blocks, CriticalExits);
assert(CriticalExits.empty() && "Cannot break critical exits yet");
+ // Get critical predecessors so computeRemainder can deal with them.
+ sa_.getCriticalPreds(Blocks, criticalPreds_);
+
// Create new live interval for the loop.
openIntv();
- // Insert copies in the predecessors.
- for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
- E = Blocks.Preds.end(); I != E; ++I) {
- MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
- enterIntvAtEnd(MBB);
+ // Insert copies in the predecessors if live-in to the header.
+ if (lis_.isLiveInToMBB(edit_.getParent(), Loop->getHeader())) {
+ for (SplitAnalysis::BlockPtrSet::iterator I = Blocks.Preds.begin(),
+ E = Blocks.Preds.end(); I != E; ++I) {
+ MachineBasicBlock &MBB = const_cast<MachineBasicBlock&>(**I);
+ enterIntvAtEnd(MBB);
+ }
}
// Switch all loop blocks.