58#define DEBUG_TYPE "regalloc"
62STATISTIC(NumCoalesced,
"Number of copies coalesced");
75class InstrPosIndexes {
77 void unsetInitialized() { IsInitialized =
false; }
79 void init(
const MachineBasicBlock &
MBB) {
81 Instr2PosIndex.
clear();
83 for (
const MachineInstr &
MI :
MBB) {
84 LastIndex += InstrDist;
85 Instr2PosIndex[&
MI] = LastIndex;
92 bool getIndex(
const MachineInstr &
MI,
uint64_t &Index) {
100 assert(
MI.getParent() == CurMBB &&
"MI is not in CurMBB");
101 auto It = Instr2PosIndex.find(&
MI);
102 if (It != Instr2PosIndex.end()) {
116 unsigned Distance = 1;
118 End = std::next(Start);
119 while (Start != CurMBB->begin() &&
120 !Instr2PosIndex.count(&*std::prev(Start))) {
124 while (End != CurMBB->end() && !Instr2PosIndex.count(&*(End))) {
132 Start == CurMBB->begin() ? 0 : Instr2PosIndex.at(&*std::prev(Start));
134 if (End == CurMBB->end())
135 Step =
static_cast<uint64_t>(InstrDist);
138 uint64_t EndIndex = Instr2PosIndex.at(&*End);
139 assert(EndIndex > LastIndex &&
"Index must be ascending order");
140 unsigned NumAvailableIndexes = EndIndex - LastIndex - 1;
159 Step = (NumAvailableIndexes + 1) / (Distance + 1);
164 if (
LLVM_UNLIKELY(!Step || (!LastIndex && Step == InstrDist))) {
166 Index = Instr2PosIndex.at(&
MI);
170 for (
auto I = Start;
I != End; ++
I) {
172 Instr2PosIndex[&*
I] = LastIndex;
174 Index = Instr2PosIndex.at(&
MI);
179 bool IsInitialized =
false;
180 enum { InstrDist = 1024 };
181 const MachineBasicBlock *CurMBB =
nullptr;
182 DenseMap<const MachineInstr *, uint64_t> Instr2PosIndex;
185class RegAllocFastImpl {
188 bool ClearVirtRegs_ =
true)
189 : ShouldAllocateRegisterImpl(
F), StackSlotForVirtReg(-1),
190 ClearVirtRegs(ClearVirtRegs_) {}
193 MachineFrameInfo *MFI =
nullptr;
194 MachineRegisterInfo *MRI =
nullptr;
195 const TargetRegisterInfo *TRI =
nullptr;
196 const TargetInstrInfo *TII =
nullptr;
197 RegisterClassInfo RegClassInfo;
201 MachineBasicBlock *MBB =
nullptr;
204 IndexedMap<int, VirtReg2IndexFunctor> StackSlotForVirtReg;
209 MachineInstr *LastUse =
nullptr;
212 bool LiveOut =
false;
213 bool Reloaded =
false;
216 explicit LiveReg(
Register VirtReg) : VirtReg(VirtReg) {}
217 explicit LiveReg() =
default;
219 unsigned getSparseSetIndex()
const {
return VirtReg.virtRegIndex(); }
222 using LiveRegMap = SparseSet<LiveReg, unsigned, identity, uint16_t>;
225 LiveRegMap LiveVirtRegs;
228 DenseMap<Register, LiveReg> BundleVirtRegsMap;
230 DenseMap<Register, SmallVector<MachineOperand *, 2>> LiveDbgValueMap;
233 DenseMap<Register, SmallVector<MachineInstr *, 1>> DanglingDbgValues;
237 BitVector MayLiveAcrossBlocks;
258 std::vector<unsigned> RegUnitStates;
276 SmallVector<unsigned, 0> UsedInInstr;
278 SmallVector<unsigned, 8> DefOperandIndexes;
283 InstrPosIndexes PosIndexes;
285 void setRegUnitState(MCRegUnit Unit,
unsigned NewState);
286 unsigned getRegUnitState(MCRegUnit Unit)
const;
288 void setPhysRegState(MCRegister PhysReg,
unsigned NewState);
289 bool isPhysRegFree(MCRegister PhysReg)
const;
292 void markRegUsedInInstr(MCRegister PhysReg) {
293 for (MCRegUnit Unit : TRI->regunits(PhysReg))
294 UsedInInstr[
static_cast<unsigned>(
Unit)] = InstrGen | 1;
298 bool isClobberedByRegMasks(MCRegister PhysReg)
const {
299 return llvm::any_of(RegMasks, [PhysReg](
const uint32_t *Mask) {
305 bool isRegUsedInInstr(MCRegister PhysReg,
bool LookAtPhysRegUses)
const {
306 if (LookAtPhysRegUses && isClobberedByRegMasks(PhysReg))
308 for (MCRegUnit Unit : TRI->regunits(PhysReg))
309 if (UsedInInstr[
static_cast<unsigned>(Unit)] >=
310 (InstrGen | !LookAtPhysRegUses))
317 void markPhysRegUsedInInstr(MCRegister PhysReg) {
318 for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
319 assert(UsedInInstr[
static_cast<unsigned>(Unit)] <= InstrGen &&
320 "non-phys use before phys use?");
321 UsedInInstr[
static_cast<unsigned>(
Unit)] = InstrGen;
326 void unmarkRegUsedInInstr(MCRegister PhysReg) {
327 for (MCRegUnit Unit : TRI->regunits(PhysReg))
328 UsedInInstr[
static_cast<unsigned>(
Unit)] = 0;
335 spillImpossible = ~0
u
344 void allocateBasicBlock(MachineBasicBlock &MBB);
349 void findAndSortDefOperandIndexes(
const MachineInstr &
MI);
351 void allocateInstruction(MachineInstr &
MI);
352 void handleDebugValue(MachineInstr &
MI);
353 void handleBundle(MachineInstr &
MI);
355 bool usePhysReg(MachineInstr &
MI, MCRegister PhysReg);
356 bool definePhysReg(MachineInstr &
MI, MCRegister PhysReg);
357 bool displacePhysReg(MachineInstr &
MI, MCRegister PhysReg);
358 void freePhysReg(MCRegister PhysReg);
360 unsigned calcSpillCost(
MCPhysReg PhysReg)
const;
370 void assignVirtToPhysReg(MachineInstr &
MI, LiveReg &, MCRegister PhysReg);
371 void allocVirtReg(MachineInstr &
MI, LiveReg &LR,
Register Hint,
372 bool LookAtPhysRegUses =
false);
373 void allocVirtRegUndef(MachineOperand &MO);
374 void assignDanglingDebugValues(MachineInstr &Def,
Register VirtReg,
376 bool defineLiveThroughVirtReg(MachineInstr &
MI,
unsigned OpNum,
378 bool defineVirtReg(MachineInstr &
MI,
unsigned OpNum,
Register VirtReg,
379 bool LookAtPhysRegUses =
false);
380 bool useVirtReg(MachineInstr &
MI, MachineOperand &MO,
Register VirtReg);
382 MCPhysReg getErrorAssignment(
const LiveReg &LR, MachineInstr &
MI,
386 getMBBBeginInsertionPoint(MachineBasicBlock &MBB,
387 SmallSet<Register, 2> &PrologLiveIns)
const;
389 void reloadAtBegin(MachineBasicBlock &MBB);
390 bool setPhysReg(MachineInstr &
MI, MachineOperand &MO,
391 const LiveReg &Assignment);
396 bool shouldAllocateRegister(
const Register Reg)
const;
397 int getStackSpaceFor(
Register VirtReg);
399 MCRegister AssignedReg,
bool Kill,
bool LiveOut);
406 bool mayBeSpillFromInlineAsmBr(
const MachineInstr &
MI)
const;
408 void dumpState()
const;
412 RegAllocFastImpl Impl;
418 : MachineFunctionPass(ID), Impl(
F, ClearVirtRegs_) {}
421 return Impl.runOnMachineFunction(MF);
424 StringRef getPassName()
const override {
return "Fast Register Allocator"; }
426 void getAnalysisUsage(AnalysisUsage &AU)
const override {
431 MachineFunctionProperties getRequiredProperties()
const override {
432 return MachineFunctionProperties().setNoPHIs();
435 MachineFunctionProperties getSetProperties()
const override {
436 if (Impl.ClearVirtRegs) {
437 return MachineFunctionProperties().setNoVRegs();
440 return MachineFunctionProperties();
443 MachineFunctionProperties getClearedProperties()
const override {
444 return MachineFunctionProperties().setIsSSA();
450char RegAllocFast::ID = 0;
457 if (!ShouldAllocateRegisterImpl)
460 return ShouldAllocateRegisterImpl(*
TRI, *MRI,
Reg);
463void RegAllocFastImpl::setRegUnitState(MCRegUnit Unit,
unsigned NewState) {
464 RegUnitStates[
static_cast<unsigned>(
Unit)] = NewState;
467unsigned RegAllocFastImpl::getRegUnitState(MCRegUnit Unit)
const {
468 return RegUnitStates[
static_cast<unsigned>(
Unit)];
471void RegAllocFastImpl::setPhysRegState(MCRegister PhysReg,
unsigned NewState) {
472 for (MCRegUnit Unit :
TRI->regunits(PhysReg))
473 setRegUnitState(Unit, NewState);
476bool RegAllocFastImpl::isPhysRegFree(MCRegister PhysReg)
const {
477 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
478 if (getRegUnitState(Unit) != regFree)
486int RegAllocFastImpl::getStackSpaceFor(
Register VirtReg) {
488 int SS = StackSlotForVirtReg[VirtReg];
495 unsigned Size =
TRI->getSpillSize(RC);
500 Align CurrentAlign =
ST.getFrameLowering()->getStackAlign();
501 if (Alignment > CurrentAlign && !
TRI->canRealignStack(MF))
508 StackSlotForVirtReg[VirtReg] = FrameIdx;
515 PosIndexes.getIndex(
A, IndexA);
518 PosIndexes.getIndex(
A, IndexA);
519 return IndexA < IndexB;
526bool RegAllocFastImpl::mayBeSpillFromInlineAsmBr(
const MachineInstr &
MI)
const {
531 for (
const auto &
Op :
MI.operands())
538bool RegAllocFastImpl::mayLiveOut(
Register VirtReg) {
544 const MachineInstr *SelfLoopDef =
nullptr;
551 if (DefInst.getParent() !=
MBB) {
555 if (!SelfLoopDef ||
dominates(PosIndexes, DefInst, *SelfLoopDef))
556 SelfLoopDef = &DefInst;
567 static const unsigned Limit = 8;
570 if (UseInst.getParent() !=
MBB || ++
C >= Limit) {
579 if (SelfLoopDef == &UseInst ||
580 !
dominates(PosIndexes, *SelfLoopDef, UseInst)) {
591bool RegAllocFastImpl::mayLiveIn(
Register VirtReg) {
596 static const unsigned Limit = 8;
599 if (DefInst.getParent() !=
MBB || ++
C >= Limit) {
611 Register VirtReg, MCRegister AssignedReg,
612 bool Kill,
bool LiveOut) {
615 int FI = getStackSpaceFor(VirtReg);
627 SmallVectorImpl<MachineOperand *> &LRIDbgOperands = LiveDbgValueMap[VirtReg];
628 SmallMapVector<MachineInstr *, SmallVector<const MachineOperand *>, 2>
630 for (MachineOperand *MO : LRIDbgOperands)
631 SpilledOperandsMap[MO->getParent()].push_back(MO);
632 for (
const auto &MISpilledOperands : SpilledOperandsMap) {
633 MachineInstr &
DBG = *MISpilledOperands.first;
635 if (
DBG.isDebugValueList())
638 *
MBB, Before, *MISpilledOperands.first, FI, MISpilledOperands.second);
641 LLVM_DEBUG(
dbgs() <<
"Inserting debug info due to spill:\n" << *NewDV);
648 MachineInstr *ClonedDV =
MBB->
getParent()->CloneMachineInstr(NewDV);
650 LLVM_DEBUG(
dbgs() <<
"Cloning debug info due to live out spill\n");
656 if (
DBG.isNonListDebugValue()) {
657 MachineOperand &MO =
DBG.getDebugOperand(0);
666 LRIDbgOperands.
clear();
671 Register VirtReg, MCRegister PhysReg) {
674 int FI = getStackSpaceFor(VirtReg);
685 MachineBasicBlock &
MBB, SmallSet<Register, 2> &PrologLiveIns)
const {
694 if (!
TII->isBasicBlockPrologue(*
I) && !mayBeSpillFromInlineAsmBr(*
I))
699 for (MachineOperand &MO :
I->operands()) {
711void RegAllocFastImpl::reloadAtBegin(MachineBasicBlock &
MBB) {
712 if (LiveVirtRegs.empty())
717 for (MachineBasicBlock::RegisterMaskPair
P :
MBB.
liveins())
718 setPhysRegState(
P.PhysReg, regLiveIn);
720 SmallSet<Register, 2> PrologLiveIns;
725 getMBBBeginInsertionPoint(
MBB, PrologLiveIns);
726 for (
const LiveReg &LR : LiveVirtRegs) {
727 MCRegister PhysReg = LR.PhysReg;
728 if (!PhysReg || LR.Error)
731 MCRegUnit FirstUnit = *
TRI->regunits(PhysReg).begin();
732 if (getRegUnitState(FirstUnit) == regLiveIn)
736 "no reload in start block. Missing vreg def?");
738 if (PrologLiveIns.
count(PhysReg)) {
742 reload(
MBB.
begin(), LR.VirtReg, PhysReg);
744 reload(InsertBefore, LR.VirtReg, PhysReg);
746 LiveVirtRegs.clear();
753bool RegAllocFastImpl::usePhysReg(MachineInstr &
MI, MCRegister
Reg) {
755 bool displacedAny = displacePhysReg(
MI,
Reg);
756 setPhysRegState(
Reg, regPreAssigned);
757 markRegUsedInInstr(
Reg);
765bool RegAllocFastImpl::definePhysReg(MachineInstr &
MI, MCRegister
Reg) {
766 bool displacedAny = displacePhysReg(
MI,
Reg);
767 setPhysRegState(
Reg, regPreAssigned);
774bool RegAllocFastImpl::displacePhysReg(MachineInstr &
MI, MCRegister PhysReg) {
775 bool displacedAny =
false;
777 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
778 switch (
unsigned VirtReg = getRegUnitState(Unit)) {
780 LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
781 assert(LRI != LiveVirtRegs.end() &&
"datastructures in sync");
784 while (mayBeSpillFromInlineAsmBr(*ReloadBefore))
786 reload(ReloadBefore, VirtReg, LRI->PhysReg);
788 setPhysRegState(LRI->PhysReg, regFree);
789 LRI->PhysReg = MCRegister();
790 LRI->Reloaded =
true;
795 setRegUnitState(Unit, regFree);
805void RegAllocFastImpl::freePhysReg(MCRegister PhysReg) {
808 MCRegUnit FirstUnit = *
TRI->regunits(PhysReg).begin();
809 switch (
unsigned VirtReg = getRegUnitState(FirstUnit)) {
815 setPhysRegState(PhysReg, regFree);
818 LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
819 assert(LRI != LiveVirtRegs.end());
821 setPhysRegState(LRI->PhysReg, regFree);
822 LRI->PhysReg = MCRegister();
832unsigned RegAllocFastImpl::calcSpillCost(
MCPhysReg PhysReg)
const {
833 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
834 switch (
unsigned VirtReg = getRegUnitState(Unit)) {
840 return spillImpossible;
842 bool SureSpill = StackSlotForVirtReg[VirtReg] != -1 ||
843 findLiveVirtReg(VirtReg)->LiveOut;
844 return SureSpill ? spillClean : spillDirty;
851void RegAllocFastImpl::assignDanglingDebugValues(MachineInstr &Definition,
854 auto UDBGValIter = DanglingDbgValues.
find(VirtReg);
855 if (UDBGValIter == DanglingDbgValues.
end())
858 SmallVectorImpl<MachineInstr *> &Dangling = UDBGValIter->second;
859 for (MachineInstr *DbgValue : Dangling) {
860 assert(DbgValue->isDebugValue());
861 if (!DbgValue->hasDebugOperandForReg(VirtReg))
865 MCRegister SetToReg =
Reg;
868 E = DbgValue->getIterator();
870 if (
I->modifiesRegister(
Reg,
TRI) || --Limit == 0) {
873 SetToReg = MCRegister();
877 for (MachineOperand &MO : DbgValue->getDebugOperandsForReg(VirtReg)) {
889void RegAllocFastImpl::assignVirtToPhysReg(MachineInstr &AtMI, LiveReg &LR,
890 MCRegister PhysReg) {
894 assert(!LR.PhysReg &&
"Already assigned a physreg");
895 assert(PhysReg &&
"Trying to assign no register");
896 LR.PhysReg = PhysReg;
897 setPhysRegState(PhysReg, VirtReg.
id());
899 assignDanglingDebugValues(AtMI, VirtReg, PhysReg);
905 static const unsigned ChainLengthLimit = 3;
906 for (
unsigned C = 0;
C <= ChainLengthLimit; ++
C) {
917 Reg =
Def->getOperand(1).getReg();
926 static const unsigned DefLimit = 3;
931 Reg = traceCopyChain(
Reg);
943void RegAllocFastImpl::allocVirtReg(MachineInstr &
MI, LiveReg &LR,
944 Register Hint0,
bool LookAtPhysRegUses) {
945 const Register VirtReg = LR.VirtReg;
950 <<
" in class " <<
TRI->getRegClassName(&RC)
955 !isRegUsedInInstr(Hint0, LookAtPhysRegUses)) {
957 if (isPhysRegFree(Hint0)) {
960 assignVirtToPhysReg(
MI, LR, Hint0);
971 Register Hint1 = traceCopies(VirtReg);
973 !isRegUsedInInstr(Hint1, LookAtPhysRegUses)) {
975 if (isPhysRegFree(Hint1)) {
978 assignVirtToPhysReg(
MI, LR, Hint1);
989 unsigned BestCost = spillImpossible;
991 for (
MCPhysReg PhysReg : AllocationOrder) {
993 if (isRegUsedInInstr(PhysReg, LookAtPhysRegUses)) {
998 unsigned Cost = calcSpillCost(PhysReg);
1002 assignVirtToPhysReg(
MI, LR, PhysReg);
1006 if (PhysReg == Hint0 || PhysReg == Hint1)
1007 Cost -= spillPrefBonus;
1009 if (
Cost < BestCost) {
1018 LR.PhysReg = getErrorAssignment(LR,
MI, RC);
1023 displacePhysReg(
MI, BestReg);
1024 assignVirtToPhysReg(
MI, LR, BestReg);
1027void RegAllocFastImpl::allocVirtRegUndef(MachineOperand &MO) {
1031 if (!shouldAllocateRegister(VirtReg))
1037 for (
const MachineOperand &Tied :
MI.all_uses()) {
1038 if (!Tied.isTied() || Tied.getReg() != VirtReg)
1041 MI.getOperand(
MI.findTiedOperandIdx(
MI.getOperandNo(&Tied)))
1044 for (MachineOperand &O :
MI.all_uses()) {
1045 if (
O.getReg() != VirtReg)
1048 unsigned SubIdx =
O.isTied() ? 0 :
O.getSubReg();
1049 O.setReg(SubIdx ?
TRI->getSubReg(DefReg, SubIdx) : DefReg);
1056 LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
1058 bool IsRenamable =
true;
1059 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
1060 PhysReg = LRI->PhysReg;
1064 if (AllocationOrder.
empty()) {
1070 PhysReg = getErrorAssignment(*LRI, *MO.
getParent(), RC);
1072 IsRenamable =
false;
1074 PhysReg = AllocationOrder.
front();
1078 if (SubRegIdx != 0) {
1079 PhysReg =
TRI->getSubReg(PhysReg, SubRegIdx);
1089bool RegAllocFastImpl::defineLiveThroughVirtReg(MachineInstr &
MI,
1092 if (!shouldAllocateRegister(VirtReg))
1094 LiveRegMap::iterator LRI = findLiveVirtReg(VirtReg);
1095 if (LRI != LiveVirtRegs.end()) {
1096 MCRegister PrevReg = LRI->PhysReg;
1097 if (PrevReg && isRegUsedInInstr(PrevReg,
true)) {
1099 <<
" (tied/earlyclobber resolution)\n");
1100 freePhysReg(PrevReg);
1101 LRI->PhysReg = MCRegister();
1108 TII->get(TargetOpcode::COPY), PrevReg)
1111 MachineOperand &MO =
MI.getOperand(OpNum);
1116 return defineVirtReg(
MI, OpNum, VirtReg,
true);
1126bool RegAllocFastImpl::defineVirtReg(MachineInstr &
MI,
unsigned OpNum,
1127 Register VirtReg,
bool LookAtPhysRegUses) {
1129 if (!shouldAllocateRegister(VirtReg))
1131 MachineOperand &MO =
MI.getOperand(OpNum);
1132 LiveRegMap::iterator LRI;
1134 std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
1137 if (mayLiveOut(VirtReg)) {
1138 LRI->LiveOut =
true;
1145 if (!LRI->PhysReg) {
1146 allocVirtReg(
MI, *LRI,
Register(), LookAtPhysRegUses);
1148 assert((!isRegUsedInInstr(LRI->PhysReg, LookAtPhysRegUses) || LRI->Error) &&
1149 "TODO: preassign mismatch");
1151 <<
" use existing assignment to "
1155 MCRegister PhysReg = LRI->PhysReg;
1157 if (LRI->Reloaded || LRI->LiveOut) {
1158 if (!
MI.isImplicitDef()) {
1162 <<
" RL: " << LRI->Reloaded <<
'\n');
1163 bool Kill = LRI->LastUse ==
nullptr;
1164 spill(SpillBefore, VirtReg, PhysReg,
Kill, LRI->LiveOut);
1168 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR) {
1169 int FI = StackSlotForVirtReg[VirtReg];
1171 for (MachineOperand &MO :
MI.operands()) {
1173 MachineBasicBlock *Succ = MO.
getMBB();
1182 LRI->LastUse =
nullptr;
1183 }
else if (!LRI->LastUse) {
1188 LRI->LiveOut =
false;
1189 LRI->Reloaded =
false;
1191 if (
MI.getOpcode() == TargetOpcode::BUNDLE) {
1192 BundleVirtRegsMap[VirtReg] = *LRI;
1194 markRegUsedInInstr(PhysReg);
1195 return setPhysReg(
MI, MO, *LRI);
1200bool RegAllocFastImpl::useVirtReg(MachineInstr &
MI, MachineOperand &MO,
1203 if (!shouldAllocateRegister(VirtReg))
1205 LiveRegMap::iterator LRI;
1207 std::tie(LRI, New) = LiveVirtRegs.insert(LiveReg(VirtReg));
1210 if (mayLiveOut(VirtReg)) {
1211 LRI->LiveOut =
true;
1218 assert((!MO.
isKill() || LRI->LastUse == &
MI) &&
"Invalid kill flag");
1222 if (!LRI->PhysReg) {
1225 if (
MI.isCopy() &&
MI.getOperand(1).getSubReg() == 0) {
1226 Hint =
MI.getOperand(0).getReg();
1227 if (
Hint.isVirtual()) {
1228 assert(!shouldAllocateRegister(Hint));
1232 "Copy destination should already be assigned");
1235 allocVirtReg(
MI, *LRI, Hint,
false);
1240 if (
MI.getOpcode() == TargetOpcode::BUNDLE) {
1241 BundleVirtRegsMap[VirtReg] = *LRI;
1243 markRegUsedInInstr(LRI->PhysReg);
1244 return setPhysReg(
MI, MO, *LRI);
1250MCPhysReg RegAllocFastImpl::getErrorAssignment(
const LiveReg &LR,
1264 if (AllocationOrder.
empty()) {
1268 "no registers from class available to allocate", Fn,
1273 assert(!RawRegs.
empty() &&
"register classes cannot have no registers");
1274 return RawRegs.
front();
1277 if (!LR.Error && EmitError) {
1280 if (
MI.isInlineAsm()) {
1281 MI.emitInlineAsmError(
1282 "inline assembly requires more registers than available");
1286 "ran out of registers during register allocation", Fn,
1291 return AllocationOrder.
front();
1296bool RegAllocFastImpl::setPhysReg(MachineInstr &
MI, MachineOperand &MO,
1297 const LiveReg &Assignment) {
1298 MCRegister PhysReg = Assignment.PhysReg;
1299 assert(PhysReg &&
"assignments should always be to a valid physreg");
1327 MI.addRegisterKilled(PhysReg,
TRI,
true);
1336 MI.addRegisterDead(PhysReg,
TRI,
true);
1338 MI.addRegisterDefined(PhysReg,
TRI);
1347void RegAllocFastImpl::dumpState()
const {
1348 for (MCRegUnit Unit :
TRI->regunits()) {
1349 switch (
unsigned VirtReg = getRegUnitState(Unit)) {
1352 case regPreAssigned:
1359 LiveRegMap::const_iterator
I = findLiveVirtReg(VirtReg);
1360 assert(
I != LiveVirtRegs.end() &&
"have LiveVirtRegs entry");
1361 if (
I->LiveOut ||
I->Reloaded) {
1369 assert(
TRI->hasRegUnit(
I->PhysReg, Unit) &&
"inverse mapping present");
1376 for (
const LiveReg &LR : LiveVirtRegs) {
1379 MCRegister PhysReg = LR.PhysReg;
1382 for (MCRegUnit Unit :
TRI->regunits(PhysReg)) {
1383 assert(getRegUnitState(Unit) == VirtReg &&
"inverse map valid");
1391void RegAllocFastImpl::addRegClassDefCounts(
1393 assert(RegClassDefCounts.
size() ==
TRI->getNumRegClasses());
1396 if (!shouldAllocateRegister(
Reg))
1399 for (
unsigned RCIdx = 0, RCIdxEnd =
TRI->getNumRegClasses();
1400 RCIdx != RCIdxEnd; ++RCIdx) {
1404 ++RegClassDefCounts[RCIdx];
1410 for (
unsigned RCIdx = 0, RCIdxEnd =
TRI->getNumRegClasses();
1411 RCIdx != RCIdxEnd; ++RCIdx) {
1413 for (MCRegAliasIterator Alias(
Reg,
TRI,
true); Alias.isValid(); ++Alias) {
1415 ++RegClassDefCounts[RCIdx];
1425void RegAllocFastImpl::findAndSortDefOperandIndexes(
const MachineInstr &
MI) {
1426 DefOperandIndexes.
clear();
1429 for (
unsigned I = 0,
E =
MI.getNumOperands();
I <
E; ++
I) {
1430 const MachineOperand &MO =
MI.getOperand(
I);
1437 markPhysRegUsedInInstr(
Reg);
1447 if (DefOperandIndexes.
size() <= 1)
1455 SmallVector<unsigned> RegClassDefCounts(
TRI->getNumRegClasses(), 0);
1457 for (
const MachineOperand &MO :
MI.all_defs())
1458 addRegClassDefCounts(RegClassDefCounts, MO.
getReg());
1460 llvm::sort(DefOperandIndexes, [&](
unsigned I0,
unsigned I1) {
1461 const MachineOperand &MO0 =
MI.getOperand(I0);
1462 const MachineOperand &MO1 =
MI.getOperand(I1);
1470 unsigned ClassSize0 = RegClassInfo.
getOrder(&RC0).size();
1471 unsigned ClassSize1 = RegClassInfo.
getOrder(&RC1).size();
1473 bool SmallClass0 = ClassSize0 < RegClassDefCounts[RC0.
getID()];
1474 bool SmallClass1 = ClassSize1 < RegClassDefCounts[RC1.
getID()];
1475 if (SmallClass0 > SmallClass1)
1477 if (SmallClass0 < SmallClass1)
1485 if (Livethrough0 > Livethrough1)
1487 if (Livethrough0 < Livethrough1)
1501 unsigned TiedIdx =
MI.findTiedOperandIdx(
MI.getOperandNo(&MO));
1506void RegAllocFastImpl::allocateInstruction(MachineInstr &
MI) {
1529 BundleVirtRegsMap.
clear();
1532 bool HasPhysRegUse =
false;
1533 bool HasRegMask =
false;
1534 bool HasVRegDef =
false;
1535 bool HasDef =
false;
1536 bool HasEarlyClobber =
false;
1537 bool NeedToAssignLiveThroughs =
false;
1538 for (MachineOperand &MO :
MI.operands()) {
1542 if (!shouldAllocateRegister(
Reg))
1548 HasEarlyClobber =
true;
1549 NeedToAssignLiveThroughs =
true;
1553 NeedToAssignLiveThroughs =
true;
1559 bool displacedAny = definePhysReg(
MI,
Reg);
1561 HasEarlyClobber =
true;
1566 HasPhysRegUse =
true;
1580 bool ReArrangedImplicitOps =
true;
1588 if (NeedToAssignLiveThroughs) {
1589 while (ReArrangedImplicitOps) {
1590 ReArrangedImplicitOps =
false;
1591 findAndSortDefOperandIndexes(
MI);
1592 for (
unsigned OpIdx : DefOperandIndexes) {
1593 MachineOperand &MO =
MI.getOperand(OpIdx);
1598 ReArrangedImplicitOps = defineLiveThroughVirtReg(
MI, OpIdx,
Reg);
1600 ReArrangedImplicitOps = defineVirtReg(
MI, OpIdx,
Reg);
1604 if (ReArrangedImplicitOps)
1610 while (ReArrangedImplicitOps) {
1611 ReArrangedImplicitOps =
false;
1612 for (MachineOperand &MO :
MI.all_defs()) {
1615 ReArrangedImplicitOps =
1616 defineVirtReg(
MI,
MI.getOperandNo(&MO),
Reg);
1617 if (ReArrangedImplicitOps)
1628 for (MachineOperand &MO :
reverse(
MI.all_defs())) {
1639 "tied def assigned to clobbered register");
1654 unmarkRegUsedInInstr(
Reg);
1663 for (
const auto *RM : RegMasks)
1666 for (
const LiveReg &LR : LiveVirtRegs) {
1667 MCRegister PhysReg = LR.PhysReg;
1668 if (PhysReg && isClobberedByRegMasks(PhysReg))
1669 displacePhysReg(
MI, PhysReg);
1674 if (HasPhysRegUse) {
1675 for (MachineOperand &MO :
MI.operands()) {
1683 if (!usePhysReg(
MI,
Reg))
1691 bool HasUndefUse =
false;
1692 bool ReArrangedImplicitMOs =
true;
1693 while (ReArrangedImplicitMOs) {
1694 ReArrangedImplicitMOs =
false;
1695 for (MachineOperand &MO :
MI.operands()) {
1713 ReArrangedImplicitMOs = useVirtReg(
MI, MO,
Reg);
1714 if (ReArrangedImplicitMOs)
1723 for (MachineOperand &MO :
MI.all_uses()) {
1728 assert(MO.
isUndef() &&
"Should only have undef virtreg uses left");
1729 allocVirtRegUndef(MO);
1735 if (HasEarlyClobber) {
1736 for (MachineOperand &MO :
reverse(
MI.all_defs())) {
1739 assert(!MO.
getSubReg() &&
"should be already handled in def processing");
1765 (
MI.getOperand(0).getReg() ==
MI.getOperand(1).getReg() ||
1766 MI.getOperand(0).isDead()) &&
1767 MI.getNumOperands() == 2) {
1773void RegAllocFastImpl::handleDebugValue(MachineInstr &
MI) {
1776 assert(
MI.isDebugValue() &&
"not a DBG_VALUE*");
1777 for (
const auto &MO :
MI.debug_operands()) {
1783 if (!shouldAllocateRegister(
Reg))
1787 int SS = StackSlotForVirtReg[
Reg];
1797 LiveRegMap::iterator LRI = findLiveVirtReg(
Reg);
1801 if (LRI != LiveVirtRegs.end() && LRI->PhysReg) {
1803 for (
auto &RegMO : DbgOps)
1804 setPhysReg(
MI, *RegMO, *LRI);
1806 DanglingDbgValues[
Reg].push_back(&
MI);
1811 LiveDbgValueMap[
Reg].append(DbgOps.begin(), DbgOps.end());
1815void RegAllocFastImpl::handleBundle(MachineInstr &
MI) {
1818 while (BundledMI->isBundledWithPred()) {
1819 for (MachineOperand &MO : BundledMI->operands()) {
1827 auto DI = BundleVirtRegsMap.
find(
Reg);
1828 assert(DI != BundleVirtRegsMap.
end() &&
"Unassigned virtual register");
1830 setPhysReg(
MI, MO, DI->second);
1837void RegAllocFastImpl::allocateBasicBlock(MachineBasicBlock &
MBB) {
1841 PosIndexes.unsetInitialized();
1842 RegUnitStates.assign(
TRI->getNumRegUnits(), regFree);
1843 assert(LiveVirtRegs.empty() &&
"Mapping not cleared from last block?");
1846 setPhysRegState(LiveReg.PhysReg, regPreAssigned);
1856 if (
MI.isDebugValue()) {
1857 handleDebugValue(
MI);
1861 allocateInstruction(
MI);
1865 if (
MI.getOpcode() == TargetOpcode::BUNDLE) {
1873 LLVM_DEBUG(
dbgs() <<
"Loading live registers at begin of block.\n");
1878 for (MachineInstr *
MI : Coalesced)
1880 NumCoalesced += Coalesced.size();
1882 for (
auto &UDBGPair : DanglingDbgValues) {
1883 for (MachineInstr *DbgValue : UDBGPair.second) {
1888 LLVM_DEBUG(
dbgs() <<
"Register did not survive for " << *DbgValue
1893 DanglingDbgValues.clear();
1899 LLVM_DEBUG(
dbgs() <<
"********** FAST REGISTER ALLOCATION **********\n"
1900 <<
"********** Function: " << MF.
getName() <<
'\n');
1908 unsigned NumRegUnits =
TRI->getNumRegUnits();
1910 UsedInInstr.
assign(NumRegUnits, 0);
1915 StackSlotForVirtReg.
resize(NumVirtRegs);
1916 LiveVirtRegs.setUniverse(NumVirtRegs);
1917 MayLiveAcrossBlocks.
clear();
1918 MayLiveAcrossBlocks.
resize(NumVirtRegs);
1921 for (MachineBasicBlock &
MBB : MF)
1922 allocateBasicBlock(
MBB);
1924 if (ClearVirtRegs) {
1930 StackSlotForVirtReg.
clear();
1931 LiveDbgValueMap.
clear();
1938 RegAllocFastImpl Impl(Opts.Filter, Opts.ClearVRegs);
1939 bool Changed = Impl.runOnMachineFunction(MF);
1949 bool PrintFilterName = Opts.FilterName !=
"all";
1950 bool PrintNoClearVRegs = !Opts.ClearVRegs;
1951 bool PrintSemicolon = PrintFilterName && PrintNoClearVRegs;
1953 OS <<
"regallocfast";
1954 if (PrintFilterName || PrintNoClearVRegs) {
1956 if (PrintFilterName)
1957 OS <<
"filter=" << Opts.FilterName;
1960 if (PrintNoClearVRegs)
1961 OS <<
"no-clear-vregs";
1969 bool ClearVirtRegs) {
1970 return new RegAllocFast(Ftor, ClearVirtRegs);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
This file defines the DenseMap class.
const HexagonInstrInfo * TII
This file implements an indexed map.
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool isCoalescable(const MachineInstr &MI)
static cl::opt< bool > IgnoreMissingDefs("rafast-ignore-missing-defs", cl::Hidden)
static bool dominates(InstrPosIndexes &PosIndexes, const MachineInstr &A, const MachineInstr &B)
static RegisterRegAlloc fastRegAlloc("fast", "fast register allocator", createFastRegisterAllocator)
static bool isTiedToNotUndef(const MachineInstr &MI, const MachineOperand &MO)
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the SparseSet class derived from the version described in Briggs,...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
const T & front() const
Get the first element.
size_t size() const
Get the array size.
bool empty() const
Check if the array is empty.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
void resize(unsigned N, bool t=false)
Grow or shrink the bitvector.
void clear()
Removes all bits from the bitvector.
BitVector & set()
Set all bits in the bitvector.
Represents analyses that only rely on functions' control flow.
iterator find(const_arg_type_t< KeyT > Val)
FunctionPass class - This class is used to implement most global optimizations.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Store the specified register of the given register class to the specified stack frame index.
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
Load the specified register of the given register class from the specified stack frame index.
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
If the specified machine instruction is a direct store to a stack slot, return the virtual or physica...
void resize(typename StorageT::size_type S)
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
unsigned getID() const
getID() - Return the register class ID number.
ArrayRef< MCPhysReg > getRegisters() const
bool contains(MCRegister Reg) const
contains - Return true if the specified register is included in this register class.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
An RAII based helper class to modify MachineFunctionProperties when running pass.
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
iterator_range< liveout_iterator > liveouts() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator_range< livein_iterator > liveins() const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
LLVM_ABI void dump() const
Instructions::iterator instr_iterator
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
LLVM_ABI bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool isLiveIn(MCRegister Reg, LaneBitmask LaneMask=LaneBitmask::getAll()) const
Return true if the specified register is in the live in set.
bool isSpillSlotObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a spill slot.
LLVM_ABI int CreateSpillStackObject(uint64_t Size, Align Alignment, TargetStackID::Value StackID=TargetStackID::Default)
Create a new statically sized stack object that represents a spill slot, returning a nonnegative iden...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineBasicBlock & front() const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
bool hasDebugOperandForReg(Register Reg) const
Returns whether this debug value has at least one debug operand with the register Reg.
void setDebugValueUndef()
Sets all register debug operands in this debug value instruction to be undef.
const MachineBasicBlock * getParent() const
bool isDebugValue() const
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
bool isInternalRead() const
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
bool isMBB() const
isMBB - Tests if this is a MO_MachineBasicBlock operand.
LLVM_ABI void freezeReservedRegs()
freezeReservedRegs - Called by the register allocator to freeze the set of reserved registers before ...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
iterator_range< def_instr_iterator > def_instructions(Register Reg) const
bool isReserved(MCRegister PhysReg) const
isReserved - Returns true when PhysReg is a reserved register.
MachineOperand * getOneDef(Register Reg) const
Returns the defining operand if there is exactly one operand defining the specified register,...
LLVM_ABI void clearVirtRegs()
clearVirtRegs - Remove all virtual registers (after physreg assignment).
bool isAllocatable(MCRegister PhysReg) const
isAllocatable - Returns true when PhysReg belongs to an allocatable register class and it hasn't been...
iterator_range< use_instr_nodbg_iterator > use_nodbg_instructions(Register Reg) const
const MachineFunction & getMF() const
void addPhysRegsUsedFromRegMask(const uint32_t *RegMask)
addPhysRegsUsedFromRegMask - Mark any registers not in RegMask as used.
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
Wrapper class representing virtual and physical registers.
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr unsigned id() const
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void assign(size_type NumElts, ValueParamT Elt)
void push_back(const T &Elt)
typename DenseT::const_iterator const_iterator
typename DenseT::iterator iterator
Represent a constant reference to a string, i.e.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
An efficient, type-erasing, non-owning reference to a callable.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
initializer< Ty > init(const Ty &Val)
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI FunctionPass * createFastRegisterAllocator()
FastRegisterAllocation Pass - This pass register allocates as fast as possible.
std::function< bool(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)> RegAllocFilterFunc
Filter function for register classes during regalloc.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
@ Kill
The last use of a register.
LLVM_ABI void updateDbgValueForSpill(MachineInstr &Orig, int FrameIndex, Register Reg)
Update a DBG_VALUE whose value has been spilled to FrameIndex.
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI MachineInstr * buildDbgValueForSpill(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const MachineInstr &Orig, int FrameIndex, Register SpillReg)
Clone a DBG_VALUE whose value has been spilled to FrameIndex.
iterator_range< pointer_iterator< WrappedIteratorT > > make_pointer_range(RangeT &&Range)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
MCRegisterClass TargetRegisterClass