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/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/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.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);
Evan Cheng
committed
STATISTIC(numIntervals , "Number of original intervals");
Owen Anderson
committed
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
"Live Interval Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
INITIALIZE_PASS_DEPENDENCY(MachineLoopInfo)
INITIALIZE_PASS_DEPENDENCY(PHIElimination)
INITIALIZE_PASS_DEPENDENCY(TwoAddressInstructionPass)
INITIALIZE_PASS_DEPENDENCY(ProcessImplicitDefs)
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
INITIALIZE_AG_DEPENDENCY(AliasAnalysis)
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.addRequired<MachineLoopInfo>();
AU.addPreserved<MachineLoopInfo>();
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(),
Bob Wilson
committed
E = r2iMap_.end(); I != E; ++I)
Owen Anderson
committed
delete I->second;
// 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();
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";
Jakob Stoklund Olesen
committed
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) {
Jakob Stoklund Olesen
committed
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
Evan Cheng
committed
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. Add an
// <imp-def> of the full register.
// FIXME: LiveIntervals shouldn't modify the code like this. Whoever
// created the machine instruction should annotate it with <undef> flags
// as needed. Then we can simply assert here. The REG_SEQUENCE lowering
// is the main suspect.
if (MO.getSubReg()) {
Jakob Stoklund Olesen
committed
mi->addRegisterDefined(interval.reg);
// Mark all defs of interval.reg on this instruction as reading <undef>.
for (unsigned i = MOIdx, e = mi->getNumOperands(); i != e; ++i) {
MachineOperand &MO2 = mi->getOperand(i);
if (MO2.isReg() && MO2.getReg() == interval.reg && MO2.getSubReg())
Loading
Loading full blame...