//===-- LiveIntervalAnalysis.cpp - Live Interval Analysis -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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"
#include "llvm/CodeGen/LiveVariables.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include <algorithm>
#include <cmath>
using namespace llvm;
namespace {
// Hidden options for help debugging.
cl::opt<bool> DisableReMat("disable-rematerialization",
cl::init(false), cl::Hidden);
}
STATISTIC(numIntervals, "Number of original intervals");
STATISTIC(numIntervalsAfter, "Number of intervals after coalescing");
STATISTIC(numFolded , "Number of loads/stores folded into instructions");
char LiveIntervals::ID = 0;
namespace {
RegisterPass<LiveIntervals> X("liveintervals", "Live Interval Analysis");
}
void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<LiveVariables>();
AU.addRequired<LiveVariables>();
AU.addPreservedID(PHIEliminationID);
AU.addRequiredID(PHIEliminationID);
AU.addRequiredID(TwoAddressInstructionPassID);
MachineFunctionPass::getAnalysisUsage(AU);
}
void LiveIntervals::releaseMemory() {
Idx2MBBMap.clear();
mi2iMap_.clear();
i2miMap_.clear();
r2iMap_.clear();
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
VNInfoAllocator.Reset();
for (unsigned i = 0, e = ClonedMIs.size(); i != e; ++i)
delete ClonedMIs[i];
}
namespace llvm {
inline bool operator<(unsigned V, const IdxMBBPair &IM) {
return V < IM.first;
}
inline bool operator<(const IdxMBBPair &IM, unsigned V) {
return IM.first < V;
}
struct Idx2MBBCompare {
bool operator()(const IdxMBBPair &LHS, const IdxMBBPair &RHS) const {
return LHS.first < RHS.first;
}
};
}
/// runOnMachineFunction - Register allocate the whole function
///
bool LiveIntervals::runOnMachineFunction(MachineFunction &fn) {
mf_ = &fn;
tm_ = &fn.getTarget();
mri_ = tm_->getRegisterInfo();
tii_ = tm_->getInstrInfo();
lv_ = &getAnalysis<LiveVariables>();
allocatableRegs_ = mri_->getAllocatableSet(fn);
// 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;
for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
I != E; ++I) {
bool inserted = mi2iMap_.insert(std::make_pair(I, MIIndex)).second;
assert(inserted && "multiple MachineInstr -> index mappings");
i2miMap_.push_back(I);
MIIndex += InstrSlots::NUM;
}
// 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());
computeIntervals();
numIntervals += getNumIntervals();
DOUT << "********** INTERVALS **********\n";
for (iterator I = begin(), E = end(); I != E; ++I) {
I->second.print(DOUT, mri_);
DOUT << "\n";
}
numIntervalsAfter += getNumIntervals();
DEBUG(dump());
return true;
}
/// print - Implement the dump method.
void LiveIntervals::print(std::ostream &O, const Module* ) const {
O << "********** INTERVALS **********\n";
for (const_iterator I = begin(), E =