Newer
Older
//===-- LiveIntervalAnalysis.cpp - Live Interval Analysis -----------------===//
Alkis Evlogimenos
committed
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
Alkis Evlogimenos
committed
//
//===----------------------------------------------------------------------===//
//
// This file implements the LiveInterval analysis pass which is used
// by the Linear Scan Register allocator. This pass linearizes the
// basic blocks of the function in DFS order and uses the
// LiveVariables pass to conservatively compute live intervals for
// each virtual and physical register.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "liveintervals"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "VirtRegMap.h"
#include "llvm/Value.h"
Dan Gohman
committed
#include "llvm/Analysis/AliasAnalysis.h"
Alkis Evlogimenos
committed
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
Evan Cheng
committed
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
Alkis Evlogimenos
committed
#include "llvm/CodeGen/Passes.h"
Dan Gohman
committed
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetRegisterInfo.h"
Alkis Evlogimenos
committed
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
Evan Cheng
committed
#include "llvm/ADT/DepthFirstIterator.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
Lang Hames
committed
#include <limits>
Alkis Evlogimenos
committed
using namespace llvm;
// Hidden options for help debugging.
static cl::opt<bool> DisableReMat("disable-rematerialization",
cl::init(false), cl::Hidden);
static cl::opt<bool> SplitAtBB("split-intervals-at-bb",
cl::init(true), cl::Hidden);
static cl::opt<int> SplitLimit("split-limit",
cl::init(-1), cl::Hidden);
Evan Cheng
committed
static cl::opt<bool> EnableAggressiveRemat("aggressive-remat", cl::Hidden);
static cl::opt<bool> EnableFastSpilling("fast-spill",
cl::init(false), cl::Hidden);
STATISTIC(numIntervals, "Number of original intervals");
STATISTIC(numFolds , "Number of loads/stores folded into instructions");
STATISTIC(numSplits , "Number of intervals split");
static RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis");
Alkis Evlogimenos
committed
Chris Lattner
committed
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
Dan Gohman
committed
AU.addRequired<AliasAnalysis>();
AU.addPreserved<AliasAnalysis>();
AU.addPreserved<LiveVariables>();
AU.addPreservedID(MachineLoopInfoID);
AU.addPreservedID(MachineDominatorsID);
if (!StrongPHIElim) {
AU.addPreservedID(PHIEliminationID);
AU.addRequiredID(PHIEliminationID);
}
AU.addRequiredID(TwoAddressInstructionPassID);
MachineFunctionPass::getAnalysisUsage(AU);
Alkis Evlogimenos
committed
}
Chris Lattner
committed
void LiveIntervals::releaseMemory() {
Owen Anderson
committed
// Free the live intervals themselves.
for (DenseMap<unsigned, LiveInterval*>::iterator I = r2iMap_.begin(),
Owen Anderson
committed
E = r2iMap_.end(); I != E; ++I)
delete I->second;
mi2iMap_.clear();
i2miMap_.clear();
r2iMap_.clear();
terminatorGaps.clear();
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
VNInfoAllocator.Reset();
while (!ClonedMIs.empty()) {
MachineInstr *MI = ClonedMIs.back();
ClonedMIs.pop_back();
mf_->DeleteMachineInstr(MI);
}
}
Evan Cheng
committed
/// processImplicitDefs - Process IMPLICIT_DEF instructions and make sure
/// there is one implicit_def for each use. Add isUndef marker to
/// implicit_def defs and their uses.
void LiveIntervals::processImplicitDefs() {
SmallSet<unsigned, 8> ImpDefRegs;
SmallVector<MachineInstr*, 8> ImpDefMIs;
MachineBasicBlock *Entry = mf_->begin();
SmallPtrSet<MachineBasicBlock*,16> Visited;
for (df_ext_iterator<MachineBasicBlock*, SmallPtrSet<MachineBasicBlock*,16> >
DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited);
DFI != E; ++DFI) {
MachineBasicBlock *MBB = *DFI;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ) {
MachineInstr *MI = &*I;
++I;
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
unsigned Reg = MI->getOperand(0).getReg();
MI->getOperand(0).setIsUndef();
ImpDefRegs.insert(Reg);
ImpDefMIs.push_back(MI);
continue;
}
bool ChangedToImpDef = false;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
Evan Cheng
committed
MachineOperand& MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isUse())
continue;
unsigned Reg = MO.getReg();
if (!Reg)
continue;
if (!ImpDefRegs.count(Reg))
continue;
// Use is a copy, just turn it into an implicit_def.
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
Reg == SrcReg) {
bool isKill = MO.isKill();
MI->setDesc(tii_->get(TargetInstrInfo::IMPLICIT_DEF));
for (int j = MI->getNumOperands() - 1, ee = 0; j > ee; --j)
MI->RemoveOperand(j);
if (isKill)
ImpDefRegs.erase(Reg);
ChangedToImpDef = true;
break;
}
Evan Cheng
committed
MO.setIsUndef();
if (MO.isKill() || MI->isRegTiedToDefOperand(i))
ImpDefRegs.erase(Reg);
}
if (ChangedToImpDef) {
// Backtrack to process this new implicit_def.
--I;
} else {
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isDef())
continue;
ImpDefRegs.erase(MO.getReg());
}
Evan Cheng
committed
}
}
// Any outstanding liveout implicit_def's?
for (unsigned i = 0, e = ImpDefMIs.size(); i != e; ++i) {
MachineInstr *MI = ImpDefMIs[i];
unsigned Reg = MI->getOperand(0).getReg();
if (TargetRegisterInfo::isPhysicalRegister(Reg))
// Physical registers are not liveout (yet).
continue;
if (!ImpDefRegs.count(Reg))
continue;
// If there are multiple defs of the same register and at least one
// is not an implicit_def, do not insert implicit_def's before the
// uses.
bool Skip = false;
for (MachineRegisterInfo::def_iterator DI = mri_->def_begin(Reg),
DE = mri_->def_end(); DI != DE; ++DI) {
if (DI->getOpcode() != TargetInstrInfo::IMPLICIT_DEF) {
Skip = true;
break;
Evan Cheng
committed
}
}
if (Skip)
continue;
for (MachineRegisterInfo::use_iterator UI = mri_->use_begin(Reg),
UE = mri_->use_end(); UI != UE; ) {
MachineOperand &RMO = UI.getOperand();
MachineInstr *RMI = &*UI;
++UI;
Evan Cheng
committed
MachineBasicBlock *RMBB = RMI->getParent();
if (RMBB == MBB)
Evan Cheng
committed
continue;
const TargetRegisterClass* RC = mri_->getRegClass(Reg);
unsigned NewVReg = mri_->createVirtualRegister(RC);
MachineInstrBuilder MIB =
BuildMI(*RMBB, RMI, RMI->getDebugLoc(),
tii_->get(TargetInstrInfo::IMPLICIT_DEF), NewVReg);
(*MIB).getOperand(0).setIsUndef();
Evan Cheng
committed
RMO.setReg(NewVReg);
RMO.setIsUndef();
RMO.setIsKill();
}
}
ImpDefRegs.clear();
ImpDefMIs.clear();
}
}
Owen Anderson
committed
void LiveIntervals::computeNumbering() {
Index2MiMap OldI2MI = i2miMap_;
Owen Anderson
committed
std::vector<IdxMBBPair> OldI2MBB = Idx2MBBMap;
Owen Anderson
committed
Idx2MBBMap.clear();
MBB2IdxMap.clear();
mi2iMap_.clear();
i2miMap_.clear();
terminatorGaps.clear();
Owen Anderson
committed
FunctionSize = 0;
// Number MachineInstrs and MachineBasicBlocks.
// Initialize MBB indexes to a sentinal.
MBB2IdxMap.resize(mf_->getNumBlockIDs(), std::make_pair(~0U,~0U));
unsigned MIIndex = 0;
for (MachineFunction::iterator MBB = mf_->begin(), E = mf_->end();
MBB != E; ++MBB) {
unsigned StartIdx = MIIndex;
Evan Cheng
committed
Owen Anderson
committed
// Insert an empty slot at the beginning of each block.
MIIndex += InstrSlots::NUM;
i2miMap_.push_back(0);
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
if (I == MBB->getFirstTerminator()) {
// Leave a gap for before terminators, this is where we will point
// PHI kills.
bool inserted =
terminatorGaps.insert(std::make_pair(&*MBB, MIIndex)).second;
assert(inserted &&
"Multiple 'first' terminators encountered during numbering.");
inserted = inserted; // Avoid compiler warning if assertions turned off.
i2miMap_.push_back(0);
MIIndex += InstrSlots::NUM;
}
bool inserted = mi2iMap_.insert(std::make_pair(I, MIIndex)).second;
assert(inserted && "multiple MachineInstr -> index mappings");
i2miMap_.push_back(I);
MIIndex += InstrSlots::NUM;
FunctionSize++;
Owen Anderson
committed
// Insert max(1, numdefs) empty slots after every instruction.
unsigned Slots = I->getDesc().getNumDefs();
if (Slots == 0)
Slots = 1;
MIIndex += InstrSlots::NUM * Slots;
while (Slots--)
i2miMap_.push_back(0);
if (MBB->getFirstTerminator() == MBB->end()) {
// Leave a gap for before terminators, this is where we will point
// PHI kills.
bool inserted =
terminatorGaps.insert(std::make_pair(&*MBB, MIIndex)).second;
assert(inserted &&
"Multiple 'first' terminators encountered during numbering.");
inserted = inserted; // Avoid compiler warning if assertions turned off.
i2miMap_.push_back(0);
MIIndex += InstrSlots::NUM;
}
Owen Anderson
committed
Owen Anderson
committed
// Set the MBB2IdxMap entry for this MBB.
MBB2IdxMap[MBB->getNumber()] = std::make_pair(StartIdx, MIIndex - 1);
Idx2MBBMap.push_back(std::make_pair(StartIdx, MBB));
}
std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare());
Owen Anderson
committed
if (!OldI2MI.empty())
for (iterator OI = begin(), OE = end(); OI != OE; ++OI) {
Owen Anderson
committed
for (LiveInterval::iterator LI = OI->second->begin(),
LE = OI->second->end(); LI != LE; ++LI) {
Owen Anderson
committed
// Remap the start index of the live range to the corresponding new
// number, or our best guess at what it _should_ correspond to if the
// original instruction has been erased. This is either the following
// instruction or its predecessor.
Owen Anderson
committed
unsigned index = LI->start / InstrSlots::NUM;
Owen Anderson
committed
unsigned offset = LI->start % InstrSlots::NUM;
Owen Anderson
committed
if (offset == InstrSlots::LOAD) {
Owen Anderson
committed
std::vector<IdxMBBPair>::const_iterator I =
Owen Anderson
committed
std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->start);
Owen Anderson
committed
// Take the pair containing the index
std::vector<IdxMBBPair>::const_iterator J =
(I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I;
Owen Anderson
committed
Owen Anderson
committed
LI->start = getMBBStartIdx(J->second);
} else {
LI->start = mi2iMap_[OldI2MI[index]] + offset;
Owen Anderson
committed
}
Owen Anderson
committed
Owen Anderson
committed
// Remap the ending index in the same way that we remapped the start,
// except for the final step where we always map to the immediately
// following instruction.
Owen Anderson
committed
index = (LI->end - 1) / InstrSlots::NUM;
Owen Anderson
committed
offset = LI->end % InstrSlots::NUM;
if (offset == InstrSlots::LOAD) {
// VReg dies at end of block.
Owen Anderson
committed
std::vector<IdxMBBPair>::const_iterator I =
Owen Anderson
committed
std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), LI->end);
Owen Anderson
committed
LI->end = getMBBEndIdx(I->second) + 1;
Owen Anderson
committed
} else {
Owen Anderson
committed
unsigned idx = index;
while (index < OldI2MI.size() && !OldI2MI[index]) ++index;
if (index != OldI2MI.size())
LI->end = mi2iMap_[OldI2MI[index]] + (idx == index ? offset : 0);
else
LI->end = InstrSlots::NUM * i2miMap_.size();
Owen Anderson
committed
}
Owen Anderson
committed
for (LiveInterval::vni_iterator VNI = OI->second->vni_begin(),
VNE = OI->second->vni_end(); VNI != VNE; ++VNI) {
Owen Anderson
committed
// Remap the VNInfo def index, which works the same as the
// start indices above. VN's with special sentinel defs
// don't need to be remapped.
unsigned index = vni->def / InstrSlots::NUM;
unsigned offset = vni->def % InstrSlots::NUM;
Owen Anderson
committed
if (offset == InstrSlots::LOAD) {
std::vector<IdxMBBPair>::const_iterator I =
Owen Anderson
committed
std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->def);
Owen Anderson
committed
// Take the pair containing the index
std::vector<IdxMBBPair>::const_iterator J =
(I == OldI2MBB.end() && OldI2MBB.size()>0) ? (I-1): I;
Owen Anderson
committed
Owen Anderson
committed
vni->def = getMBBStartIdx(J->second);
} else {
vni->def = mi2iMap_[OldI2MI[index]] + offset;
}
Owen Anderson
committed
}
Owen Anderson
committed
// Remap the VNInfo kill indices, which works the same as
// the end indices above.
Owen Anderson
committed
for (size_t i = 0; i < vni->kills.size(); ++i) {
unsigned killIdx = vni->kills[i].killIdx;
unsigned index = (killIdx - 1) / InstrSlots::NUM;
unsigned offset = killIdx % InstrSlots::NUM;
if (offset == InstrSlots::LOAD) {
assert("Value killed at a load slot.");
/*std::vector<IdxMBBPair>::const_iterator I =
Owen Anderson
committed
std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), vni->kills[i]);
Owen Anderson
committed
vni->kills[i] = getMBBEndIdx(I->second);*/
Owen Anderson
committed
} else {
if (vni->kills[i].isPHIKill) {
std::vector<IdxMBBPair>::const_iterator I =
std::lower_bound(OldI2MBB.begin(), OldI2MBB.end(), index);
--I;
vni->kills[i].killIdx = terminatorGaps[I->second];
} else {
assert(OldI2MI[index] != 0 &&
"Kill refers to instruction not present in index maps.");
vni->kills[i].killIdx = mi2iMap_[OldI2MI[index]] + offset;
}
/*
Owen Anderson
committed
unsigned idx = index;
while (index < OldI2MI.size() && !OldI2MI[index]) ++index;
if (index != OldI2MI.size())
vni->kills[i] = mi2iMap_[OldI2MI[index]] +
(idx == index ? offset : 0);
else
vni->kills[i] = InstrSlots::NUM * i2miMap_.size();
Owen Anderson
committed
}
Owen Anderson
committed
}
Owen Anderson
committed
}
Owen Anderson
committed
}
Lang Hames
committed
void LiveIntervals::scaleNumbering(int factor) {
// Need to
// * scale MBB begin and end points
// * scale all ranges.
// * Update VNI structures.
// * Scale instruction numberings
// Scale the MBB indices.
Idx2MBBMap.clear();
for (MachineFunction::iterator MBB = mf_->begin(), MBBE = mf_->end();
MBB != MBBE; ++MBB) {
std::pair<unsigned, unsigned> &mbbIndices = MBB2IdxMap[MBB->getNumber()];
mbbIndices.first = InstrSlots::scale(mbbIndices.first, factor);
mbbIndices.second = InstrSlots::scale(mbbIndices.second, factor);
Idx2MBBMap.push_back(std::make_pair(mbbIndices.first, MBB));
}
std::sort(Idx2MBBMap.begin(), Idx2MBBMap.end(), Idx2MBBCompare());
// Scale terminator gaps.
for (DenseMap<MachineBasicBlock*, unsigned>::iterator
TGI = terminatorGaps.begin(), TGE = terminatorGaps.end();
TGI != TGE; ++TGI) {
terminatorGaps[TGI->first] = InstrSlots::scale(TGI->second, factor);
}
Lang Hames
committed
// Scale the intervals.
for (iterator LI = begin(), LE = end(); LI != LE; ++LI) {
LI->second->scaleNumbering(factor);
}
// Scale MachineInstrs.
Mi2IndexMap oldmi2iMap = mi2iMap_;
unsigned highestSlot = 0;
for (Mi2IndexMap::iterator MI = oldmi2iMap.begin(), ME = oldmi2iMap.end();
MI != ME; ++MI) {
unsigned newSlot = InstrSlots::scale(MI->second, factor);
mi2iMap_[MI->first] = newSlot;
highestSlot = std::max(highestSlot, newSlot);
}
i2miMap_.clear();
i2miMap_.resize(highestSlot + 1);
for (Mi2IndexMap::iterator MI = mi2iMap_.begin(), ME = mi2iMap_.end();
MI != ME; ++MI) {
i2miMap_[MI->second] = MI->first;
}
}
Owen Anderson
committed
/// runOnMachineFunction - Register allocate the whole function
///
bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
mf_ = &fn;
mri_ = &mf_->getRegInfo();
tm_ = &fn.getTarget();
tri_ = tm_->getRegisterInfo();
tii_ = tm_->getInstrInfo();
Dan Gohman
committed
aa_ = &getAnalysis<AliasAnalysis>();
Owen Anderson
committed
lv_ = &getAnalysis<LiveVariables>();
allocatableRegs_ = tri_->getAllocatableSet(fn);
Alkis Evlogimenos
committed
Evan Cheng
committed
processImplicitDefs();
Owen Anderson
committed
computeNumbering();
Alkis Evlogimenos
committed
Alkis Evlogimenos
committed
}
void LiveIntervals::print(std::ostream &O, const Module* ) const {
O << "********** INTERVALS **********\n";
for (const_iterator I = begin(), E = end(); I != E; ++I) {
Owen Anderson
committed
I->second->print(O, tri_);
O << "********** MACHINEINSTRS **********\n";
for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
mbbi != mbbe; ++mbbi) {
O << ((Value*)mbbi->getBasicBlock())->getName() << ":\n";
for (MachineBasicBlock::iterator mii = mbbi->begin(),
mie = mbbi->end(); mii != mie; ++mii) {
Chris Lattner
committed
O << getInstructionIndex(mii) << '\t' << *mii;
/// conflictsWithPhysRegDef - Returns true if the specified register
/// is defined during the duration of the specified interval.
bool LiveIntervals::conflictsWithPhysRegDef(const LiveInterval &li,
VirtRegMap &vrm, unsigned reg) {
for (LiveInterval::Ranges::const_iterator
I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
for (unsigned index = getBaseIndex(I->start),
end = getBaseIndex(I->end-1) + InstrSlots::NUM; index != end;
index += InstrSlots::NUM) {
// skip deleted instructions
while (index != end && !getInstructionFromIndex(index))
index += InstrSlots::NUM;
if (index == end) break;
MachineInstr *MI = getInstructionFromIndex(index);
Evan Cheng
committed
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
if (SrcReg == li.reg || DstReg == li.reg)
continue;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
MachineOperand& mop = MI->getOperand(i);
if (!mop.isReg())
continue;
unsigned PhysReg = mop.getReg();
if (PhysReg == 0 || PhysReg == li.reg)
continue;
if (TargetRegisterInfo::isVirtualRegister(PhysReg)) {
if (!vrm.hasPhys(PhysReg))
continue;
PhysReg = vrm.getPhys(PhysReg);
if (PhysReg && tri_->regsOverlap(PhysReg, reg))
return true;
}
}
}
return false;
}
Evan Cheng
committed
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
/// conflictsWithPhysRegRef - Similar to conflictsWithPhysRegRef except
/// it can check use as well.
bool LiveIntervals::conflictsWithPhysRegRef(LiveInterval &li,
unsigned Reg, bool CheckUse,
SmallPtrSet<MachineInstr*,32> &JoinedCopies) {
for (LiveInterval::Ranges::const_iterator
I = li.ranges.begin(), E = li.ranges.end(); I != E; ++I) {
for (unsigned index = getBaseIndex(I->start),
end = getBaseIndex(I->end-1) + InstrSlots::NUM; index != end;
index += InstrSlots::NUM) {
// Skip deleted instructions.
MachineInstr *MI = 0;
while (index != end) {
MI = getInstructionFromIndex(index);
if (MI)
break;
index += InstrSlots::NUM;
}
if (index == end) break;
if (JoinedCopies.count(MI))
continue;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand& MO = MI->getOperand(i);
if (!MO.isReg())
continue;
if (MO.isUse() && !CheckUse)
continue;
unsigned PhysReg = MO.getReg();
if (PhysReg == 0 || TargetRegisterInfo::isVirtualRegister(PhysReg))
continue;
if (tri_->isSubRegister(Reg, PhysReg))
return true;
}
}
}
return false;
}
void LiveIntervals::printRegName(unsigned reg) const {
if (TargetRegisterInfo::isPhysicalRegister(reg))
Bill Wendling
committed
cerr << "%reg" << reg;
Alkis Evlogimenos
committed
}
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
Alkis Evlogimenos
committed
MachineBasicBlock::iterator mi,
Owen Anderson
committed
unsigned MIIdx, MachineOperand& MO,
Evan Cheng
committed
unsigned MOIdx,
LiveInterval &interval) {
DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
if (mi->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
DOUT << "is a implicit_def\n";
return;
}
// Virtual registers may be defined multiple times (due to phi
// elimination and 2-addr elimination). Much of what we do only has to be
// done once for the vreg. We use an empty interval to detect the first
// time we see a vreg.
if (interval.empty()) {
// Get the Idx of the defining instructions.
unsigned defIndex = getDefIndex(MIIdx);
// Earlyclobbers move back one.
if (MO.isEarlyClobber())
defIndex = getUseIndex(MIIdx);
VNInfo *ValNo;
Evan Cheng
committed
MachineInstr *CopyMI = NULL;
Evan Cheng
committed
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
Evan Cheng
committed
if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
Evan Cheng
committed
mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
mi->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
Evan Cheng
committed
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
Evan Cheng
committed
CopyMI = mi;
Evan Cheng
committed
// Earlyclobbers move back one.
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
assert(ValNo->id == 0 && "First value in interval is not 0?");
// Loop over all of the blocks that the vreg is defined in. There are
// two cases we have to handle here. The most common case is a vreg
// whose lifetime is contained within a basic block. In this case there
// will be a single kill, in MBB, which comes after the definition.
if (vi.Kills.size() == 1 && vi.Kills[0]->getParent() == mbb) {
// FIXME: what about dead vars?
unsigned killIdx;
if (vi.Kills[0] != mi)
killIdx = getUseIndex(getInstructionIndex(vi.Kills[0]))+1;
else
killIdx = defIndex+1;
// If the kill happens after the definition, we have an intra-block
// live range.
if (killIdx > defIndex) {
Jeffrey Yasskin
committed
assert(vi.AliveBlocks.empty() &&
"Shouldn't be alive across any blocks!");
LiveRange LR(defIndex, killIdx, ValNo);
DOUT << " +" << LR << "\n";
interval.addKill(ValNo, killIdx, false);
// The other case we handle is when a virtual register lives to the end
// of the defining block, potentially live across some blocks, then is
// live into some number of blocks, but gets killed. Start by adding a
// range that goes from this definition to the end of the defining block.
Owen Anderson
committed
LiveRange NewLR(defIndex, getMBBEndIdx(mbb)+1, ValNo);
DOUT << " +" << NewLR;
interval.addRange(NewLR);
// Iterate over all of the blocks that the variable is completely
// live in, adding [insrtIndex(begin), instrIndex(end)+4) to the
// live interval.
Jeffrey Yasskin
committed
for (SparseBitVector<>::iterator I = vi.AliveBlocks.begin(),
E = vi.AliveBlocks.end(); I != E; ++I) {
LiveRange LR(getMBBStartIdx(*I),
getMBBEndIdx(*I)+1, // MBB ends at -1.
ValNo);
interval.addRange(LR);
DOUT << " +" << LR;
}
// Finally, this virtual register is live from the start of any killing
// block to the 'use' slot of the killing instruction.
for (unsigned i = 0, e = vi.Kills.size(); i != e; ++i) {
MachineInstr *Kill = vi.Kills[i];
unsigned killIdx = getUseIndex(getInstructionIndex(Kill))+1;
LiveRange LR(getMBBStartIdx(Kill->getParent()),
killIdx, ValNo);
interval.addKill(ValNo, killIdx, false);
DOUT << " +" << LR;
}
} else {
// If this is the second time we see a virtual register definition, it
// must be due to phi elimination or two addr elimination. If this is
// the result of two address elimination, then the vreg is one of the
// def-and-use register operand.
if (mi->isRegTiedToUseOperand(MOIdx)) {
// If this is a two-address definition, then we have already processed
// the live range. The only problem is that we didn't realize there
// are actually two values in the live interval. Because of this we
// need to take the LiveRegion that defines this register and split it
// into two values.
assert(interval.containsOneValue());
unsigned DefIndex = getDefIndex(interval.getValNumInfo(0)->def);
unsigned RedefIndex = getDefIndex(MIIdx);
if (MO.isEarlyClobber())
RedefIndex = getUseIndex(MIIdx);
const LiveRange *OldLR = interval.getLiveRangeContaining(RedefIndex-1);
VNInfo *OldValNo = OldLR->valno;
// Delete the initial value, which should be short and continuous,
// because the 2-addr copy must be in the same MBB as the redef.
interval.removeRange(DefIndex, RedefIndex);
// Two-address vregs should always only be redefined once. This means
// that at this point, there should be exactly one value number in it.
assert(interval.containsOneValue() && "Unexpected 2-addr liveint!");
Chris Lattner
committed
// The new value number (#1) is defined by the instruction we claimed
// defined value #0.
Evan Cheng
committed
VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->copy,
Evan Cheng
committed
VNInfoAllocator);
ValNo->setFlags(OldValNo->getFlags()); // * <- updating here
Chris Lattner
committed
// Value#0 is now defined by the 2-addr instruction.
Evan Cheng
committed
OldValNo->def = RedefIndex;
OldValNo->copy = 0;
if (MO.isEarlyClobber())
// Add the new live interval which replaces the range for the input copy.
LiveRange LR(DefIndex, RedefIndex, ValNo);
DOUT << " replace range with " << LR;
interval.addKill(ValNo, RedefIndex, false);
// If this redefinition is dead, we need to add a dummy unit live
// range covering the def slot.
Owen Anderson
committed
if (MO.isDead())
interval.addRange(LiveRange(RedefIndex, RedefIndex+1, OldValNo));
} else {
// Otherwise, this must be because of phi elimination. If this is the
// first redefinition of the vreg that we have seen, go back and change
// the live range in the PHI block to be a different value number.
if (interval.containsOneValue()) {
assert(vi.Kills.size() == 1 &&
"PHI elimination vreg should have one kill, the PHI itself!");
// Remove the old range that we now know has an incorrect number.
VNInfo *VNI = interval.getValNumInfo(0);
MachineInstr *Killer = vi.Kills[0];
unsigned Start = getMBBStartIdx(Killer->getParent());
unsigned End = getUseIndex(getInstructionIndex(Killer))+1;
DOUT << " Removing [" << Start << "," << End << "] from: ";
interval.print(DOUT, tri_); DOUT << "\n";
interval.removeRange(Start, End);
assert(interval.ranges.size() == 1 &&
"newly discovered PHI interval has >1 ranges.");
MachineBasicBlock *killMBB = getMBBFromIndex(interval.endNumber());
interval.addKill(VNI, terminatorGaps[killMBB], true);
DOUT << " RESULT: "; interval.print(DOUT, tri_);
// Replace the interval with one of a NEW value number. Note that this
// value number isn't actually defined by an instruction, weird huh? :)
LiveRange LR(Start, End,
interval.getNextValue(mbb->getNumber(), 0, false, VNInfoAllocator));
DOUT << " replace range with " << LR;
interval.addKill(LR.valno, End, false);
DOUT << " RESULT: "; interval.print(DOUT, tri_);
}
// In the case of PHI elimination, each variable definition is only
// live until the end of the block. We've already taken care of the
// rest of the live range.
unsigned defIndex = getDefIndex(MIIdx);
if (MO.isEarlyClobber())
defIndex = getUseIndex(MIIdx);
Chris Lattner
committed
VNInfo *ValNo;
Evan Cheng
committed
MachineInstr *CopyMI = NULL;
Evan Cheng
committed
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
Evan Cheng
committed
if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
Evan Cheng
committed
mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
mi->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
Evan Cheng
committed
tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
Evan Cheng
committed
CopyMI = mi;
ValNo = interval.getNextValue(defIndex, CopyMI, true, VNInfoAllocator);
Chris Lattner
committed
Owen Anderson
committed
unsigned killIndex = getMBBEndIdx(mbb) + 1;
LiveRange LR(defIndex, killIndex, ValNo);
interval.addKill(ValNo, terminatorGaps[mbb], true);
DOUT << " +" << LR;
Alkis Evlogimenos
committed
Alkis Evlogimenos
committed
}
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
Alkis Evlogimenos
committed
MachineBasicBlock::iterator mi,
unsigned MIIdx,
Owen Anderson
committed
MachineOperand& MO,
Chris Lattner
committed
LiveInterval &interval,
Evan Cheng
committed
MachineInstr *CopyMI) {
// A physical register cannot be live across basic block, so its
// lifetime must end somewhere in its defining basic block.
DOUT << "\t\tregister: "; DEBUG(printRegName(interval.reg));
unsigned baseIndex = MIIdx;
unsigned start = getDefIndex(baseIndex);
// Earlyclobbers move back one.
if (MO.isEarlyClobber())
start = getUseIndex(MIIdx);
unsigned end = start;
// If it is not used after definition, it is considered dead at
// the instruction defining it. Hence its interval is:
// [defSlot(def), defSlot(def)+1)
Owen Anderson
committed
if (MO.isDead()) {
goto exit;
Alkis Evlogimenos
committed
// If it is not dead on definition, it must be killed by a
// subsequent instruction. Hence its interval is:
// [defSlot(def), useSlot(kill)+1)
Owen Anderson
committed
baseIndex += InstrSlots::NUM;
while (++mi != MBB->end()) {
Owen Anderson
committed
while (baseIndex / InstrSlots::NUM < i2miMap_.size() &&
getInstructionFromIndex(baseIndex) == 0)
baseIndex += InstrSlots::NUM;
if (mi->killsRegister(interval.reg, tri_)) {
DOUT << " killed";
end = getUseIndex(baseIndex) + 1;
goto exit;
Evan Cheng
committed
} else {
int DefIdx = mi->findRegisterDefOperandIdx(interval.reg, false, tri_);
if (DefIdx != -1) {
if (mi->isRegTiedToUseOperand(DefIdx)) {
// Two-address instruction.
end = getDefIndex(baseIndex);
if (mi->getOperand(DefIdx).isEarlyClobber())
end = getUseIndex(baseIndex);
} else {
// Another instruction redefines the register before it is ever read.
// Then the register is essentially dead at the instruction that defines
// it. Hence its interval is:
// [defSlot(def), defSlot(def)+1)
DOUT << " dead";
end = start + 1;
}
goto exit;
}
Owen Anderson
committed
baseIndex += InstrSlots::NUM;
// The only case we should have a dead physreg here without a killing or
// instruction where we know it's dead is if it is live-in to the function
Evan Cheng
committed
// and never used. Another possible case is the implicit use of the
// physical register has been deleted by two-address pass.
Alkis Evlogimenos
committed
exit:
assert(start < end && "did not find end of interval?");
// Already exists? Extend old live interval.
LiveInterval::iterator OldLR = interval.FindLiveRangeContaining(start);
Evan Cheng
committed
bool Extend = OldLR != interval.end();
VNInfo *ValNo = Extend
? OldLR->valno : interval.getNextValue(start, CopyMI, true, VNInfoAllocator);
Evan Cheng
committed
if (MO.isEarlyClobber() && Extend)
LiveRange LR(start, end, ValNo);
interval.addKill(LR.valno, end, false);
DOUT << " +" << LR << '\n';
Alkis Evlogimenos
committed
}
void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI,
unsigned MIIdx,
Evan Cheng
committed
MachineOperand& MO,
unsigned MOIdx) {
Owen Anderson
committed
if (TargetRegisterInfo::isVirtualRegister(MO.getReg()))
Evan Cheng
committed
handleVirtualRegisterDef(MBB, MI, MIIdx, MO, MOIdx,
Owen Anderson
committed
getOrCreateInterval(MO.getReg()));
else if (allocatableRegs_[MO.getReg()]) {
Evan Cheng
committed
MachineInstr *CopyMI = NULL;
Evan Cheng
committed
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
Evan Cheng
committed
if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
Evan Cheng
committed
MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::SUBREG_TO_REG ||
Evan Cheng
committed
tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
Evan Cheng
committed
CopyMI = MI;
Evan Cheng
committed
handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
Owen Anderson
committed
getOrCreateInterval(MO.getReg()), CopyMI);
Owen Anderson
committed
for (const unsigned* AS = tri_->getSubRegisters(MO.getReg()); *AS; ++AS)
// If MI also modifies the sub-register explicitly, avoid processing it
// more than once. Do not pass in TRI here so it checks for exact match.
if (!MI->modifiesRegister(*AS))
Evan Cheng
committed
handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
Owen Anderson
committed
getOrCreateInterval(*AS), 0);
Alkis Evlogimenos
committed
}
void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB,
DOUT << "\t\tlivein register: "; DEBUG(printRegName(interval.reg));
// Look for kills, if it reaches a def before it's killed, then it shouldn't
// be considered a livein.
MachineBasicBlock::iterator mi = MBB->begin();
unsigned baseIndex = MIIdx;
unsigned start = baseIndex;
Owen Anderson
committed
while (baseIndex / InstrSlots::NUM < i2miMap_.size() &&
getInstructionFromIndex(baseIndex) == 0)
baseIndex += InstrSlots::NUM;
unsigned end = baseIndex;
bool SeenDefUse = false;
Owen Anderson
committed
while (mi != MBB->end()) {
if (mi->killsRegister(interval.reg, tri_)) {
DOUT << " killed";
end = getUseIndex(baseIndex) + 1;
SeenDefUse = true;
} else if (mi->modifiesRegister(interval.reg, tri_)) {
// Another instruction redefines the register before it is ever read.
// Then the register is essentially dead at the instruction that defines
// it. Hence its interval is:
// [defSlot(def), defSlot(def)+1)
DOUT << " dead";
end = getDefIndex(start) + 1;
SeenDefUse = true;
}
baseIndex += InstrSlots::NUM;
++mi;
if (mi != MBB->end()) {
while (baseIndex / InstrSlots::NUM < i2miMap_.size() &&
getInstructionFromIndex(baseIndex) == 0)
baseIndex += InstrSlots::NUM;
}
// Live-in register might not be used at all.
if (!SeenDefUse) {
if (isAlias) {
DOUT << " dead";
end = getDefIndex(MIIdx) + 1;
} else {
DOUT << " live through";
end = baseIndex;
}
VNInfo *vni =
interval.getNextValue(MBB->getNumber(), 0, false, VNInfoAllocator);
vni->setIsPHIDef(true);
LiveRange LR(start, end, vni);
interval.addKill(LR.valno, end, false);
Alkis Evlogimenos
committed
/// computeIntervals - computes the live intervals for virtual
Alkis Evlogimenos
committed
/// registers. for some ordering of the machine instructions [1,N] a
/// live interval is an interval [i, j) where 1 <= i <= j < N for
Alkis Evlogimenos
committed
/// which a variable is live
void LiveIntervals::computeIntervals() {
DOUT << "********** COMPUTING LIVE INTERVALS **********\n"
<< "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n';
Owen Anderson
committed
for (MachineFunction::iterator MBBI = mf_->begin(), E = mf_->end();
MBBI != E; ++MBBI) {
MachineBasicBlock *MBB = MBBI;
Owen Anderson
committed
// Track the index of the current machine instr.
unsigned MIIndex = getMBBStartIdx(MBB);
DOUT << ((Value*)MBB->getBasicBlock())->getName() << ":\n";
MachineBasicBlock::iterator MI = MBB->begin(), miEnd = MBB->end();
Evan Cheng
committed
// Create intervals for live-ins to this BB first.
for (MachineBasicBlock::const_livein_iterator LI = MBB->livein_begin(),
LE = MBB->livein_end(); LI != LE; ++LI) {
handleLiveInRegister(MBB, MIIndex, getOrCreateInterval(*LI));
// Multiple live-ins can alias the same register.
for (const unsigned* AS = tri_->getSubRegisters(*LI); *AS; ++AS)
if (!hasInterval(*AS))