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/MachineMemOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
Alkis Evlogimenos
committed
#include "llvm/CodeGen/Passes.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> EnableFastSpilling("fast-spill",
cl::init(false), cl::Hidden);
Evan Cheng
committed
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 {
AU.setPreservesCFG();
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);
AU.addPreserved<ProcessImplicitDefs>();
AU.addRequired<ProcessImplicitDefs>();
AU.addPreserved<SlotIndexes>();
AU.addRequiredTransitive<SlotIndexes>();
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;
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
VNInfoAllocator.Reset();
Evan Cheng
committed
while (!CloneMIs.empty()) {
MachineInstr *MI = CloneMIs.back();
CloneMIs.pop_back();
mf_->DeleteMachineInstr(MI);
}
}
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>();
Owen Anderson
committed
allocatableRegs_ = tri_->getAllocatableSet(fn);
Alkis Evlogimenos
committed
Alkis Evlogimenos
committed
Alkis Evlogimenos
committed
}
void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
OS << "********** INTERVALS **********\n";
for (const_iterator I = begin(), E = end(); I != E; ++I) {
I->second->print(OS, tri_);
OS << "\n";
Evan Cheng
committed
printInstrs(OS);
}
void LiveIntervals::printInstrs(raw_ostream &OS) const {
OS << "********** MACHINEINSTRS **********\n";
for (MachineFunction::iterator mbbi = mf_->begin(), mbbe = mf_->end();
mbbi != mbbe; ++mbbi) {
OS << "BB#" << mbbi->getNumber()
<< ":\t\t# derived from " << mbbi->getName() << "\n";
for (MachineBasicBlock::iterator mii = mbbi->begin(),
mie = mbbi->end(); mii != mie; ++mii) {
OS << getInstructionIndex(mii) << '\t' << *mii;
Evan Cheng
committed
void LiveIntervals::dumpInstrs() const {
printInstrs(errs());
}
/// 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 (SlotIndex index = I->start.getBaseIndex(),
end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
Bill Wendling
committed
index != end;
index = index.getNextIndex()) {
MachineInstr *MI = getInstructionFromIndex(index);
if (!MI)
continue; // skip deleted instructions
Bill Wendling
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);
Bill Wendling
committed
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
/// 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 (SlotIndex index = I->start.getBaseIndex(),
end = I->end.getPrevSlot().getBaseIndex().getNextIndex();
index != end;
index = index.getNextIndex()) {
MachineInstr *MI = getInstructionFromIndex(index);
if (!MI)
continue; // skip deleted instructions
Evan Cheng
committed
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;
}
Evan Cheng
committed
static void printRegName(unsigned reg, const TargetRegisterInfo* tri_) {
if (TargetRegisterInfo::isPhysicalRegister(reg))
Alkis Evlogimenos
committed
}
Alkis Evlogimenos
committed
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
Alkis Evlogimenos
committed
MachineBasicBlock::iterator mi,
MachineOperand& MO,
Evan Cheng
committed
unsigned MOIdx,
LiveInterval &interval) {
DEBUG({
errs() << "\t\tregister: ";
Evan Cheng
committed
printRegName(interval.reg, tri_);
// 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
Evan Cheng
committed
LiveVariables::VarInfo& vi = lv_->getVarInfo(interval.reg);
if (interval.empty()) {
// Get the Idx of the defining instructions.
// Earlyclobbers move back one, so that they overlap the live range
// of inputs.
if (MO.isEarlyClobber())
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?
killIdx = getInstructionIndex(vi.Kills[0]).getDefIndex();
// 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);
ValNo->addKill(killIdx);
// 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.
LiveRange NewLR(defIndex, getMBBEndIdx(mbb).getNextIndex().getLoadIndex(),
ValNo);
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(mf_->getBlockNumbered(*I)),
getMBBEndIdx(mf_->getBlockNumbered(*I)).getNextIndex().getLoadIndex(),
ValNo);
interval.addRange(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];
SlotIndex killIdx =
getInstructionIndex(Kill).getDefIndex();
LiveRange LR(getMBBStartIdx(Kill->getParent()), killIdx, ValNo);
ValNo->addKill(killIdx);
}
} 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.
SlotIndex DefIndex = interval.getValNumInfo(0)->def.getDefIndex();
SlotIndex RedefIndex = MIIdx.getDefIndex();
if (MO.isEarlyClobber())
const LiveRange *OldLR =
interval.getLiveRangeContaining(RedefIndex.getUseIndex());
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.
Lang Hames
committed
VNInfo *ValNo = interval.getNextValue(OldValNo->def, OldValNo->getCopy(),
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;
Lang Hames
committed
OldValNo->setCopy(0);
// Add the new live interval which replaces the range for the input copy.
LiveRange LR(DefIndex, RedefIndex, ValNo);
DEBUG(errs() << " replace range with " << LR);
ValNo->addKill(RedefIndex);
// 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.getStoreIndex(),
OldValNo));
DEBUG({
errs() << " RESULT: ";
interval.print(errs(), tri_);
});
} 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()) {
// Remove the old range that we now know has an incorrect number.
VNInfo *VNI = interval.getValNumInfo(0);
MachineInstr *Killer = vi.Kills[0];
SlotIndex Start = getMBBStartIdx(Killer->getParent());
SlotIndex End = getInstructionIndex(Killer).getDefIndex();
DEBUG({
errs() << " Removing [" << Start << "," << End << "] from: ";
interval.print(errs(), tri_);
errs() << "\n";
});
interval.removeRange(Start, End);
assert(interval.ranges.size() == 1 &&
Evan Cheng
committed
"Newly discovered PHI interval has >1 ranges.");
MachineBasicBlock *killMBB = getMBBFromIndex(VNI->def);
DEBUG({
errs() << " RESULT: ";
interval.print(errs(), 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(SlotIndex(getMBBStartIdx(Killer->getParent()), true),
DEBUG(errs() << " replace range with " << LR);
LR.valno->addKill(End);
DEBUG({
errs() << " RESULT: ";
interval.print(errs(), 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.
if (MO.isEarlyClobber())
Evan Cheng
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
SlotIndex killIndex = getMBBEndIdx(mbb).getNextIndex().getLoadIndex();
LiveRange LR(defIndex, killIndex, ValNo);
Alkis Evlogimenos
committed
Alkis Evlogimenos
committed
}
void LiveIntervals::handlePhysicalRegisterDef(MachineBasicBlock *MBB,
Alkis Evlogimenos
committed
MachineBasicBlock::iterator mi,
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.
DEBUG({
errs() << "\t\tregister: ";
Evan Cheng
committed
printRegName(interval.reg, tri_);
SlotIndex baseIndex = MIIdx;
SlotIndex start = baseIndex.getDefIndex();
// Earlyclobbers move back one.
if (MO.isEarlyClobber())
// 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)
// For earlyclobbers, the defSlot was pushed back one; the extra
// advance below compensates.
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)
while (++mi != MBB->end()) {
if (getInstructionFromIndex(baseIndex) == 0)
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
if (mi->killsRegister(interval.reg, tri_)) {
goto exit;
Evan Cheng
committed
} else {
int DefIdx = mi->findRegisterDefOperandIdx(interval.reg, false, tri_);
if (DefIdx != -1) {
if (mi->isRegTiedToUseOperand(DefIdx)) {
// Two-address instruction.
Evan Cheng
committed
} 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)
Evan Cheng
committed
}
goto exit;
}
Owen Anderson
committed
// 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);
LR.valno->addKill(end);
Alkis Evlogimenos
committed
}
void LiveIntervals::handleRegisterDef(MachineBasicBlock *MBB,
MachineBasicBlock::iterator MI,
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,
DEBUG({
errs() << "\t\tlivein register: ";
Evan Cheng
committed
printRegName(interval.reg, tri_);
// 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();
SlotIndex baseIndex = MIIdx;
SlotIndex start = baseIndex;
if (getInstructionFromIndex(baseIndex) == 0)
baseIndex = indexes_->getNextNonNullIndex(baseIndex);
SlotIndex end = baseIndex;
bool SeenDefUse = false;
Owen Anderson
committed
while (mi != MBB->end()) {
if (mi->killsRegister(interval.reg, tri_)) {
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)
SeenDefUse = true;
}
++mi;
if (mi != MBB->end()) {
}
// Live-in register might not be used at all.
if (!SeenDefUse) {
end = baseIndex;
}
VNInfo *vni =
interval.getNextValue(SlotIndex(getMBBStartIdx(MBB), true),
0, false, VNInfoAllocator);
vni->setIsPHIDef(true);
LiveRange LR(start, end, vni);
LR.valno->addKill(end);
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() {
Daniel Dunbar
committed
DEBUG(errs() << "********** COMPUTING LIVE INTERVALS **********\n"
<< "********** Function: "
<< ((Value*)mf_->getFunction())->getName() << '\n');
Evan Cheng
committed
SmallVector<unsigned, 8> UndefUses;
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.
Jakob Stoklund Olesen
committed
DEBUG(errs() << MBB->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))
handleLiveInRegister(MBB, MIIndex, getOrCreateInterval(*AS),
true);
Owen Anderson
committed
// Skip over empty initial indices.
if (getInstructionFromIndex(MIIndex) == 0)
MIIndex = indexes_->getNextNonNullIndex(MIIndex);
Owen Anderson
committed
for (; MI != miEnd; ++MI) {
DEBUG(errs() << MIIndex << "\t" << *MI);
for (int i = MI->getNumOperands() - 1; i >= 0; --i) {
MachineOperand &MO = MI->getOperand(i);
Evan Cheng
committed
if (!MO.isReg() || !MO.getReg())
continue;
// handle register defs - build intervals
Evan Cheng
committed
if (MO.isDef())
Evan Cheng
committed
handleRegisterDef(MBB, MI, MIIndex, MO, i);
Evan Cheng
committed
else if (MO.isUndef())
UndefUses.push_back(MO.getReg());
Owen Anderson
committed
// Move to the next instr slot.
MIIndex = indexes_->getNextNonNullIndex(MIIndex);
Alkis Evlogimenos
committed
}
Evan Cheng
committed
// Create empty intervals for registers defined by implicit_def's (except
// for those implicit_def that define values which are liveout of their
// blocks.
for (unsigned i = 0, e = UndefUses.size(); i != e; ++i) {
unsigned UndefReg = UndefUses[i];
(void)getOrCreateInterval(UndefReg);
}
Alkis Evlogimenos
committed
}
Alkis Evlogimenos
committed
Owen Anderson
committed
LiveInterval* LiveIntervals::createInterval(unsigned reg) {
float Weight = TargetRegisterInfo::isPhysicalRegister(reg) ? HUGE_VALF : 0.0F;
Owen Anderson
committed
return new LiveInterval(reg, Weight);
/// dupInterval - Duplicate a live interval. The caller is responsible for
/// managing the allocated memory.
LiveInterval* LiveIntervals::dupInterval(LiveInterval *li) {
LiveInterval *NewLI = createInterval(li->reg);
NewLI->Copy(*li, mri_, getVNInfoAllocator());
return NewLI;
}
Evan Cheng
committed
/// getVNInfoSourceReg - Helper function that parses the specified VNInfo
/// copy field and returns the source register that defines it.
unsigned LiveIntervals::getVNInfoSourceReg(const VNInfo *VNI) const {
Lang Hames
committed
if (!VNI->getCopy())
Evan Cheng
committed
return 0;
Lang Hames
committed
if (VNI->getCopy()->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
Evan Cheng
committed
// If it's extracting out of a physical register, return the sub-register.
Lang Hames
committed
unsigned Reg = VNI->getCopy()->getOperand(1).getReg();
Evan Cheng
committed
if (TargetRegisterInfo::isPhysicalRegister(Reg))
Lang Hames
committed
Reg = tri_->getSubReg(Reg, VNI->getCopy()->getOperand(2).getImm());
Evan Cheng
committed
return Reg;
Lang Hames
committed
} else if (VNI->getCopy()->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
VNI->getCopy()->getOpcode() == TargetInstrInfo::SUBREG_TO_REG)
return VNI->getCopy()->getOperand(2).getReg();
Evan Cheng
committed
Evan Cheng
committed
unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
Lang Hames
committed
if (tii_->isMoveInstr(*VNI->getCopy(), SrcReg, DstReg, SrcSubReg, DstSubReg))
Evan Cheng
committed
return SrcReg;
llvm_unreachable("Unrecognized copy instruction!");
Evan Cheng
committed
return 0;
}
//===----------------------------------------------------------------------===//
// Register allocator hooks.
//
Evan Cheng
committed
/// getReMatImplicitUse - If the remat definition MI has one (for now, we only
/// allow one) virtual register operand, then its uses are implicitly using
/// the register. Returns the virtual register.
unsigned LiveIntervals::getReMatImplicitUse(const LiveInterval &li,
MachineInstr *MI) const {
unsigned RegOp = 0;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || !MO.isUse())
Evan Cheng
committed
continue;
unsigned Reg = MO.getReg();
if (Reg == 0 || Reg == li.reg)
continue;
if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
!allocatableRegs_[Reg])
continue;
Evan Cheng
committed
// FIXME: For now, only remat MI with at most one register operand.
assert(!RegOp &&
"Can't rematerialize instruction with multiple register operand!");
RegOp = MO.getReg();
Dan Gohman
committed
#ifndef NDEBUG
Evan Cheng
committed
break;
Dan Gohman
committed
#endif
Evan Cheng
committed
}
return RegOp;
}
/// isValNoAvailableAt - Return true if the val# of the specified interval
/// which reaches the given instruction also reaches the specified use index.
bool LiveIntervals::isValNoAvailableAt(const LiveInterval &li, MachineInstr *MI,
SlotIndex UseIdx) const {
SlotIndex Index = getInstructionIndex(MI);
Evan Cheng
committed
VNInfo *ValNo = li.FindLiveRangeContaining(Index)->valno;
LiveInterval::const_iterator UI = li.FindLiveRangeContaining(UseIdx);
return UI != li.end() && UI->valno == ValNo;
}
/// isReMaterializable - Returns true if the definition MI of the specified
/// val# of the specified interval is re-materializable.
bool LiveIntervals::isReMaterializable(const LiveInterval &li,
Evan Cheng
committed
const VNInfo *ValNo, MachineInstr *MI,
SmallVectorImpl<LiveInterval*> &SpillIs,
Evan Cheng
committed
bool &isLoad) {
if (!tii_->isTriviallyReMaterializable(MI, aa_))
return false;
// Target-specific code can mark an instruction as being rematerializable
// if it has one virtual reg use, though it had better be something like
// a PIC base register which is likely to be live everywhere.
Dan Gohman
committed
unsigned ImpUse = getReMatImplicitUse(li, MI);
if (ImpUse) {
const LiveInterval &ImpLi = getInterval(ImpUse);
for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg),
re = mri_->use_end(); ri != re; ++ri) {
MachineInstr *UseMI = &*ri;
Dan Gohman
committed
if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo)
continue;
if (!isValNoAvailableAt(ImpLi, MI, UseIdx))
return false;
}
// If a register operand of the re-materialized instruction is going to
// be spilled next, then it's not legal to re-materialize this instruction.
for (unsigned i = 0, e = SpillIs.size(); i != e; ++i)
if (ImpUse == SpillIs[i]->reg)
return false;
Dan Gohman
committed
}
return true;
Evan Cheng
committed
}
Evan Cheng
committed
/// isReMaterializable - Returns true if the definition MI of the specified
/// val# of the specified interval is re-materializable.
bool LiveIntervals::isReMaterializable(const LiveInterval &li,
const VNInfo *ValNo, MachineInstr *MI) {
SmallVector<LiveInterval*, 4> Dummy1;
bool Dummy2;
return isReMaterializable(li, ValNo, MI, Dummy1, Dummy2);
}
Evan Cheng
committed
/// isReMaterializable - Returns true if every definition of MI of every
/// val# of the specified interval is re-materializable.
bool LiveIntervals::isReMaterializable(const LiveInterval &li,
SmallVectorImpl<LiveInterval*> &SpillIs,
bool &isLoad) {
Evan Cheng
committed
isLoad = false;
for (LiveInterval::const_vni_iterator i = li.vni_begin(), e = li.vni_end();
i != e; ++i) {
const VNInfo *VNI = *i;
Evan Cheng
committed
continue; // Dead val#.
// Is the def for the val# rematerializable?
Evan Cheng
committed
return false;
MachineInstr *ReMatDefMI = getInstructionFromIndex(VNI->def);
Evan Cheng
committed
bool DefIsLoad = false;
Evan Cheng
committed
if (!ReMatDefMI ||
!isReMaterializable(li, VNI, ReMatDefMI, SpillIs, DefIsLoad))
Evan Cheng
committed
isLoad |= DefIsLoad;
/// FilterFoldedOps - Filter out two-address use operands. Return
/// true if it finds any issue with the operands that ought to prevent
/// folding.
static bool FilterFoldedOps(MachineInstr *MI,
SmallVector<unsigned, 2> &Ops,
unsigned &MRInfo,
SmallVector<unsigned, 2> &FoldOps) {
MRInfo = 0;
for (unsigned i = 0, e = Ops.size(); i != e; ++i) {
unsigned OpIdx = Ops[i];
Evan Cheng
committed
MachineOperand &MO = MI->getOperand(OpIdx);
// FIXME: fold subreg use.
Evan Cheng
committed
if (MO.getSubReg())
return true;
Evan Cheng
committed
if (MO.isDef())
MRInfo |= (unsigned)VirtRegMap::isMod;
else {
// Filter out two-address use operand(s).
if (MI->isRegTiedToDefOperand(OpIdx)) {
MRInfo = VirtRegMap::isModRef;
continue;
}
MRInfo |= (unsigned)VirtRegMap::isRef;
}
FoldOps.push_back(OpIdx);
Evan Cheng
committed
}
return false;
}
/// tryFoldMemoryOperand - Attempts to fold either a spill / restore from
/// slot / to reg or any rematerialized load into ith operand of specified
/// MI. If it is successul, MI is updated with the newly created MI and
/// returns true.
bool LiveIntervals::tryFoldMemoryOperand(MachineInstr* &MI,
VirtRegMap &vrm, MachineInstr *DefMI,
SmallVector<unsigned, 2> &Ops,
bool isSS, int Slot, unsigned Reg) {
// If it is an implicit def instruction, just delete it.
if (MI->getOpcode() == TargetInstrInfo::IMPLICIT_DEF) {
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
++numFolds;
return true;
}
// Filter the list of operand indexes that are to be folded. Abort if
// any operand will prevent folding.
unsigned MRInfo = 0;
SmallVector<unsigned, 2> FoldOps;
if (FilterFoldedOps(MI, Ops, MRInfo, FoldOps))
return false;
Evan Cheng
committed
Evan Cheng
committed
// The only time it's safe to fold into a two address instruction is when
// it's folding reload and spill from / into a spill stack slot.
if (DefMI && (MRInfo & VirtRegMap::isMod))
Evan Cheng
committed
return false;
MachineInstr *fmi = isSS ? tii_->foldMemoryOperand(*mf_, MI, FoldOps, Slot)
: tii_->foldMemoryOperand(*mf_, MI, FoldOps, DefMI);
// Remember this instruction uses the spill slot.
if (isSS) vrm.addSpillSlotUse(Slot, fmi);
// Attempt to fold the memory reference into the instruction. If
// we can do this, we don't need to insert spill code.
MachineBasicBlock &MBB = *MI->getParent();
if (isSS && !mf_->getFrameInfo()->isImmutableObjectIndex(Slot))
vrm.virtFolded(Reg, MI, fmi, (VirtRegMap::ModRef)MRInfo);
vrm.transferRestorePts(MI, fmi);
vrm.transferEmergencySpills(MI, fmi);
++numFolds;
Evan Cheng
committed
/// canFoldMemoryOperand - Returns true if the specified load / store
/// folding is possible.
bool LiveIntervals::canFoldMemoryOperand(MachineInstr *MI,
SmallVector<unsigned, 2> &Ops,
// Filter the list of operand indexes that are to be folded. Abort if
// any operand will prevent folding.
unsigned MRInfo = 0;
Evan Cheng
committed
SmallVector<unsigned, 2> FoldOps;
if (FilterFoldedOps(MI, Ops, MRInfo, FoldOps))
return false;
Evan Cheng
committed
// It's only legal to remat for a use, not a def.
if (ReMat && (MRInfo & VirtRegMap::isMod))
return false;
Evan Cheng
committed
Evan Cheng
committed
return tii_->canFoldMemoryOperand(MI, FoldOps);
}
bool LiveIntervals::intervalIsInOneMBB(const LiveInterval &li) const {
LiveInterval::Ranges::const_iterator itr = li.ranges.begin();
MachineBasicBlock *mbb = indexes_->getMBBCoveringRange(itr->start, itr->end);
if (mbb == 0)
return false;
for (++itr; itr != li.ranges.end(); ++itr) {
MachineBasicBlock *mbb2 =
indexes_->getMBBCoveringRange(itr->start, itr->end);
if (mbb2 != mbb)
Evan Cheng
committed
/// rewriteImplicitOps - Rewrite implicit use operands of MI (i.e. uses of
/// interval on to-be re-materialized operands of MI) with new register.
void LiveIntervals::rewriteImplicitOps(const LiveInterval &li,
MachineInstr *MI, unsigned NewVReg,
VirtRegMap &vrm) {
// There is an implicit use. That means one of the other operand is
// being remat'ed and the remat'ed instruction has li.reg as an
// use operand. Make sure we rewrite that as well.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg())
Evan Cheng
committed
continue;
unsigned Reg = MO.getReg();
if (Reg == 0 || TargetRegisterInfo::isPhysicalRegister(Reg))
continue;
if (!vrm.isReMaterialized(Reg))
continue;
MachineInstr *ReMatMI = vrm.getReMaterializedMI(Reg);
MachineOperand *UseMO = ReMatMI->findRegisterUseOperand(li.reg);
if (UseMO)
UseMO->setReg(NewVReg);
Evan Cheng
committed
}
}
/// rewriteInstructionForSpills, rewriteInstructionsForSpills - Helper functions
/// for addIntervalsForSpills to rewrite uses / defs for the given live range.
Evan Cheng
committed
bool LiveIntervals::
Evan Cheng
committed
rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
MachineInstr *MI,
MachineInstr *ReMatOrigDefMI, MachineInstr *ReMatDefMI,
unsigned Slot, int LdSlot,
bool isLoad, bool isLoadSS, bool DefIsReMat, bool CanDelete,
Evan Cheng
committed
VirtRegMap &vrm,