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 "regalloc"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/Value.h"
Dan Gohman
committed
#include "llvm/Analysis/AliasAnalysis.h"
Alkis Evlogimenos
committed
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineDominators.h"
Alkis Evlogimenos
committed
#include "llvm/CodeGen/MachineInstr.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/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseSet.h"
#include "LiveRangeCalc.h"
Lang Hames
committed
#include <limits>
Alkis Evlogimenos
committed
using namespace llvm;
Owen Anderson
committed
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
"Live Interval Analysis", false, false)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
Owen Anderson
committed
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
Owen Anderson
committed
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
"Live Interval Analysis", false, false)
Alkis Evlogimenos
committed
Chris Lattner
committed
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesCFG();
Dan Gohman
committed
AU.addRequired<AliasAnalysis>();
AU.addPreserved<AliasAnalysis>();
Evan Cheng
committed
AU.addPreserved<LiveVariables>();
AU.addPreservedID(MachineLoopInfoID);
AU.addRequiredTransitiveID(MachineDominatorsID);
AU.addPreservedID(MachineDominatorsID);
AU.addPreserved<SlotIndexes>();
AU.addRequiredTransitive<SlotIndexes>();
MachineFunctionPass::getAnalysisUsage(AU);
Alkis Evlogimenos
committed
}
LiveIntervals::LiveIntervals() : MachineFunctionPass(ID),
DomTree(0), LRCalc(0) {
initializeLiveIntervalsPass(*PassRegistry::getPassRegistry());
}
LiveIntervals::~LiveIntervals() {
delete LRCalc;
}
Chris Lattner
committed
void LiveIntervals::releaseMemory() {
Owen Anderson
committed
// Free the live intervals themselves.
for (unsigned i = 0, e = VirtRegIntervals.size(); i != e; ++i)
delete VirtRegIntervals[TargetRegisterInfo::index2VirtReg(i)];
VirtRegIntervals.clear();
RegMaskSlots.clear();
RegMaskBits.clear();
RegMaskBlocks.clear();
for (unsigned i = 0, e = RegUnitIntervals.size(); i != e; ++i)
delete RegUnitIntervals[i];
RegUnitIntervals.clear();
// Release VNInfo memory regions, VNInfo objects don't need to be dtor'd.
VNInfoAllocator.Reset();
}
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();
AA = &getAnalysis<AliasAnalysis>();
LV = &getAnalysis<LiveVariables>();
Indexes = &getAnalysis<SlotIndexes>();
DomTree = &getAnalysis<MachineDominatorTree>();
if (!LRCalc)
LRCalc = new LiveRangeCalc();
AllocatableRegs = TRI->getAllocatableSet(fn);
ReservedRegs = TRI->getReservedRegs(fn);
Alkis Evlogimenos
committed
computeLiveInRegUnits();
Alkis Evlogimenos
committed
}
void LiveIntervals::print(raw_ostream &OS, const Module* ) const {
OS << "********** INTERVALS **********\n";
// Dump the regunits.
for (unsigned i = 0, e = RegUnitIntervals.size(); i != e; ++i)
if (LiveInterval *LI = RegUnitIntervals[i])
OS << PrintRegUnit(i, TRI) << " = " << *LI << '\n';
for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
if (hasInterval(Reg))
OS << PrintReg(Reg) << " = " << getInterval(Reg) << '\n';
}
Evan Cheng
committed
printInstrs(OS);
}
void LiveIntervals::printInstrs(raw_ostream &OS) const {
OS << "********** MACHINEINSTRS **********\n";
MF->print(OS, Indexes);
Evan Cheng
committed
void LiveIntervals::dumpInstrs() const {
Evan Cheng
committed
}
static
bool MultipleDefsBySameMI(const MachineInstr &MI, unsigned MOIdx) {
unsigned Reg = MI.getOperand(MOIdx).getReg();
for (unsigned i = MOIdx+1, e = MI.getNumOperands(); i < e; ++i) {
const MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg())
continue;
if (MO.getReg() == Reg && MO.isDef()) {
assert(MI.getOperand(MOIdx).getSubReg() != MO.getSubReg() &&
MI.getOperand(MOIdx).getSubReg() &&
(MO.getSubReg() || MO.isImplicit()));
return true;
}
}
return false;
}
/// isPartialRedef - Return true if the specified def at the specific index is
/// partially re-defining the specified live interval. A common case of this is
/// a definition of the sub-register.
bool LiveIntervals::isPartialRedef(SlotIndex MIIdx, MachineOperand &MO,
LiveInterval &interval) {
if (!MO.getSubReg() || MO.isEarlyClobber())
return false;
SlotIndex RedefIndex = MIIdx.getRegSlot();
const LiveRange *OldLR =
interval.getLiveRangeContaining(RedefIndex.getRegSlot(true));
MachineInstr *DefMI = getInstructionFromIndex(OldLR->valno->def);
if (DefMI != 0) {
return DefMI->findRegisterDefOperandIdx(interval.reg) != -1;
}
return false;
}
void LiveIntervals::handleVirtualRegisterDef(MachineBasicBlock *mbb,
Alkis Evlogimenos
committed
MachineBasicBlock::iterator mi,
MachineOperand& MO,
Evan Cheng
committed
unsigned MOIdx,
LiveInterval &interval) {
DEBUG(dbgs() << "\t\tregister: " << PrintReg(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
LiveVariables::VarInfo& vi = LV->getVarInfo(interval.reg);
if (interval.empty()) {
// Get the Idx of the defining instructions.
SlotIndex defIndex = MIIdx.getRegSlot(MO.isEarlyClobber());
Jakob Stoklund Olesen
committed
// Make sure the first definition is not a partial redefinition.
assert(!MO.readsReg() && "First def cannot also read virtual register "
"missing <undef> flag?");
Jakob Stoklund Olesen
committed
VNInfo *ValNo = interval.getNextValue(defIndex, VNInfoAllocator);
assert(ValNo->id == 0 && "First value in interval is not 0?");
Loading
Loading full blame...