#include "llvm/CodeGen/RegAllocFast.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IndexedMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/SparseSet.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegAllocCommon.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <tuple>
#include <vector>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumStores, "Number of stores added");
STATISTIC(NumLoads, "Number of loads added");
STATISTIC(NumCoalesced, "Number of copies coalesced");
static cl::opt<bool> IgnoreMissingDefs("rafast-ignore-missing-defs",
cl::Hidden);
static RegisterRegAlloc fastRegAlloc("fast", "fast register allocator",
createFastRegisterAllocator);
namespace {
class InstrPosIndexes { … };
class RegAllocFastImpl { … };
class RegAllocFast : public MachineFunctionPass { … };
}
char RegAllocFast::ID = …;
INITIALIZE_PASS(…)
bool RegAllocFastImpl::shouldAllocateRegister(const Register Reg) const { … }
void RegAllocFastImpl::setPhysRegState(MCPhysReg PhysReg, unsigned NewState) { … }
bool RegAllocFastImpl::isPhysRegFree(MCPhysReg PhysReg) const { … }
int RegAllocFastImpl::getStackSpaceFor(Register VirtReg) { … }
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A,
const MachineInstr &B) { … }
bool RegAllocFastImpl::mayLiveOut(Register VirtReg) { … }
bool RegAllocFastImpl::mayLiveIn(Register VirtReg) { … }
void RegAllocFastImpl::spill(MachineBasicBlock::iterator Before,
Register VirtReg, MCPhysReg AssignedReg, bool Kill,
bool LiveOut) { … }
void RegAllocFastImpl::reload(MachineBasicBlock::iterator Before,
Register VirtReg, MCPhysReg PhysReg) { … }
MachineBasicBlock::iterator RegAllocFastImpl::getMBBBeginInsertionPoint(
MachineBasicBlock &MBB, SmallSet<Register, 2> &PrologLiveIns) const { … }
void RegAllocFastImpl::reloadAtBegin(MachineBasicBlock &MBB) { … }
bool RegAllocFastImpl::usePhysReg(MachineInstr &MI, MCPhysReg Reg) { … }
bool RegAllocFastImpl::definePhysReg(MachineInstr &MI, MCPhysReg Reg) { … }
bool RegAllocFastImpl::displacePhysReg(MachineInstr &MI, MCPhysReg PhysReg) { … }
void RegAllocFastImpl::freePhysReg(MCPhysReg PhysReg) { … }
unsigned RegAllocFastImpl::calcSpillCost(MCPhysReg PhysReg) const { … }
void RegAllocFastImpl::assignDanglingDebugValues(MachineInstr &Definition,
Register VirtReg,
MCPhysReg Reg) { … }
void RegAllocFastImpl::assignVirtToPhysReg(MachineInstr &AtMI, LiveReg &LR,
MCPhysReg PhysReg) { … }
static bool isCoalescable(const MachineInstr &MI) { … }
Register RegAllocFastImpl::traceCopyChain(Register Reg) const { … }
Register RegAllocFastImpl::traceCopies(Register VirtReg) const { … }
void RegAllocFastImpl::allocVirtReg(MachineInstr &MI, LiveReg &LR,
Register Hint0, bool LookAtPhysRegUses) { … }
void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) { … }
bool RegAllocFastImpl::defineLiveThroughVirtReg(MachineInstr &MI,
unsigned OpNum,
Register VirtReg) { … }
bool RegAllocFastImpl::defineVirtReg(MachineInstr &MI, unsigned OpNum,
Register VirtReg, bool LookAtPhysRegUses) { … }
bool RegAllocFastImpl::useVirtReg(MachineInstr &MI, MachineOperand &MO,
Register VirtReg) { … }
bool RegAllocFastImpl::setPhysReg(MachineInstr &MI, MachineOperand &MO,
MCPhysReg PhysReg) { … }
#ifndef NDEBUG
void RegAllocFastImpl::dumpState() const {
for (unsigned Unit = 1, UnitE = TRI->getNumRegUnits(); Unit != UnitE;
++Unit) {
switch (unsigned VirtReg = RegUnitStates[Unit]) {
case regFree:
break;
case regPreAssigned:
dbgs() << " " << printRegUnit(Unit, TRI) << "[P]";
break;
case regLiveIn:
llvm_unreachable("Should not have regLiveIn in map");
default: {
dbgs() << ' ' << printRegUnit(Unit, TRI) << '=' << printReg(VirtReg);
LiveRegMap::const_iterator I = findLiveVirtReg(VirtReg);
assert(I != LiveVirtRegs.end() && "have LiveVirtRegs entry");
if (I->LiveOut || I->Reloaded) {
dbgs() << '[';
if (I->LiveOut)
dbgs() << 'O';
if (I->Reloaded)
dbgs() << 'R';
dbgs() << ']';
}
assert(TRI->hasRegUnit(I->PhysReg, Unit) && "inverse mapping present");
break;
}
}
}
dbgs() << '\n';
for (const LiveReg &LR : LiveVirtRegs) {
Register VirtReg = LR.VirtReg;
assert(VirtReg.isVirtual() && "Bad map key");
MCPhysReg PhysReg = LR.PhysReg;
if (PhysReg != 0) {
assert(Register::isPhysicalRegister(PhysReg) && "mapped to physreg");
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
assert(RegUnitStates[Unit] == VirtReg && "inverse map valid");
}
}
}
}
#endif
void RegAllocFastImpl::addRegClassDefCounts(
MutableArrayRef<unsigned> RegClassDefCounts, Register Reg) const { … }
void RegAllocFastImpl::findAndSortDefOperandIndexes(const MachineInstr &MI) { … }
static bool isTiedToNotUndef(const MachineOperand &MO) { … }
void RegAllocFastImpl::allocateInstruction(MachineInstr &MI) { … }
void RegAllocFastImpl::handleDebugValue(MachineInstr &MI) { … }
void RegAllocFastImpl::handleBundle(MachineInstr &MI) { … }
void RegAllocFastImpl::allocateBasicBlock(MachineBasicBlock &MBB) { … }
bool RegAllocFastImpl::runOnMachineFunction(MachineFunction &MF) { … }
PreservedAnalyses RegAllocFastPass::run(MachineFunction &MF,
MachineFunctionAnalysisManager &) { … }
void RegAllocFastPass::printPipeline(
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { … }
FunctionPass *llvm::createFastRegisterAllocator() { … }
FunctionPass *llvm::createFastRegisterAllocator(RegAllocFilterFunc Ftor,
bool ClearVirtRegs) { … }