43 #define DEBUG_TYPE "regalloc"
45 STATISTIC(NumSpilledRanges,
"Number of spilled live ranges");
46 STATISTIC(NumSnippets,
"Number of spilled snippets");
47 STATISTIC(NumSpills,
"Number of spills inserted");
48 STATISTIC(NumSpillsRemoved,
"Number of spills removed");
49 STATISTIC(NumReloads,
"Number of reloads inserted");
50 STATISTIC(NumReloadsRemoved,
"Number of reloads removed");
51 STATISTIC(NumFolded,
"Number of folded stack accesses");
52 STATISTIC(NumFoldedLoads,
"Number of folded loads");
53 STATISTIC(NumRemats,
"Number of rematerialized defs for spilling");
56 cl::desc(
"Disable inline spill hoisting"));
82 MergeableSpillsMap MergeableSpills;
92 void rmRedundantSpills(
104 void runHoistSpills(
unsigned OrigReg,
VNInfo &OrigVNI,
117 MFI(mf.getFrameInfo()),
MRI(mf.getRegInfo()),
118 TII(*mf.getSubtarget().getInstrInfo()),
119 TRI(*mf.getSubtarget().getRegisterInfo()),
121 IPA(LIS, mf.getNumBlockIDs()) {}
126 void hoistAllSpills();
127 void LRE_DidCloneVirtReg(
unsigned,
unsigned)
override;
130 class InlineSpiller :
public Spiller {
164 HoistSpillHelper HSpiller;
166 ~InlineSpiller()
override {}
175 MFI(mf.getFrameInfo()),
MRI(mf.getRegInfo()),
176 TII(*mf.getSubtarget().getInstrInfo()),
177 TRI(*mf.getSubtarget().getRegisterInfo()),
179 HSpiller(pass, mf, vrm) {}
182 void postOptimization()
override;
186 void collectRegsToSpill();
188 bool isRegToSpill(
unsigned Reg) {
return is_contained(RegsToSpill, Reg); }
190 bool isSibling(
unsigned Reg);
196 void reMaterializeAll();
199 bool foldMemoryOperand(
ArrayRef<std::pair<MachineInstr*, unsigned> >,
204 void spillAroundUses(
unsigned Reg);
212 void Spiller::anchor() { }
217 return new InlineSpiller(pass, mf, vrm);
249 bool InlineSpiller::isSnippet(
const LiveInterval &SnipLI) {
250 unsigned Reg = Edit->getReg();
259 if (SnipLI.
getNumValNums() > 2 || !LIS.intervalIsInOneMBB(SnipLI))
266 RI =
MRI.reg_instr_nodbg_begin(SnipLI.
reg),
267 E =
MRI.reg_instr_nodbg_end(); RI !=
E; ) {
284 if (UseMI && &MI != UseMI)
293 void InlineSpiller::collectRegsToSpill() {
294 unsigned Reg = Edit->getReg();
297 RegsToSpill.assign(1, Reg);
298 SnippetCopies.clear();
306 RI =
MRI.reg_instr_begin(Reg),
E =
MRI.reg_instr_end(); RI !=
E; ) {
309 if (!isSibling(SnipReg))
312 if (!isSnippet(SnipLI))
314 SnippetCopies.insert(&MI);
315 if (isRegToSpill(SnipReg))
317 RegsToSpill.push_back(SnipReg);
318 DEBUG(
dbgs() <<
"\talso spill snippet " << SnipLI <<
'\n');
323 bool InlineSpiller::isSibling(
unsigned Reg) {
324 return TargetRegisterInfo::isVirtualRegister(Reg) &&
325 VRM.getOriginal(Reg) == Original;
347 bool InlineSpiller::hoistSpillInsideBB(
LiveInterval &SpillLI,
349 SlotIndex Idx = LIS.getInstructionIndex(CopyMI);
366 assert(StackInt &&
"No stack slot assigned yet.");
369 StackInt->MergeValueInAsValue(OrigLI, OrigVNI, StackInt->getValNumInfo(0));
370 DEBUG(
dbgs() <<
"\tmerged orig valno " << OrigVNI->
id <<
": "
371 << *StackInt <<
'\n');
375 eliminateRedundantSpills(SrcLI, SrcVNI);
383 assert(DefMI &&
"Defining instruction disappeared");
389 MRI.getRegClass(SrcReg), &TRI);
391 LIS.InsertMachineInstrInMaps(*MII);
392 DEBUG(
dbgs() <<
"\thoisted: " << SrcVNI->
def <<
'\t' << *MII);
394 HSpiller.addToMergeableSpills(*MII, StackSlot, Original);
402 assert(VNI &&
"Missing value");
404 WorkList.
push_back(std::make_pair(&SLI, VNI));
405 assert(StackInt &&
"No stack slot assigned yet.");
410 unsigned Reg = LI->
reg;
411 DEBUG(
dbgs() <<
"Checking redundant spills for "
412 << VNI->
id <<
'@' << VNI->
def <<
" in " << *LI <<
'\n');
415 if (isRegToSpill(Reg))
419 StackInt->MergeValueInAsValue(*LI, VNI, StackInt->getValNumInfo(0));
420 DEBUG(
dbgs() <<
"Merged to stack int: " << *StackInt <<
'\n');
424 UI =
MRI.use_instr_nodbg_begin(Reg),
E =
MRI.use_instr_nodbg_end();
429 SlotIndex Idx = LIS.getInstructionIndex(MI);
435 if (isSibling(DstReg)) {
438 assert(DstVNI &&
"Missing defined value");
440 WorkList.
push_back(std::make_pair(&DstLI, DstVNI));
448 DEBUG(
dbgs() <<
"Redundant spill " << Idx <<
'\t' << MI);
451 DeadDefs.push_back(&MI);
453 if (HSpiller.rmFromMergeableSpills(MI, StackSlot))
457 }
while (!WorkList.
empty());
469 WorkList.
push_back(std::make_pair(LI, VNI));
472 if (!UsedValues.insert(VNI).second)
480 WorkList.
push_back(std::make_pair(LI, PVNI));
487 if (!SnippetCopies.count(MI))
490 assert(isRegToSpill(SnipLI.
reg) &&
"Unexpected register in copy");
492 assert(SnipVNI &&
"Snippet undefined before copy");
493 WorkList.
push_back(std::make_pair(&SnipLI, SnipVNI));
494 }
while (!WorkList.
empty());
502 MIBundleOperands::VirtRegInfo RI =
512 DEBUG(
dbgs() <<
"\tadding <undef> flags: ");
522 if (SnippetCopies.count(&MI))
528 RM.OrigMI = LIS.getInstructionFromIndex(OrigVNI->
def);
530 if (!Edit->canRematerializeAt(
RM, OrigVNI, UseIdx,
false)) {
531 markValueUsed(&VirtReg, ParentVNI);
532 DEBUG(
dbgs() <<
"\tcannot remat for " << UseIdx <<
'\t' << MI);
539 markValueUsed(&VirtReg, ParentVNI);
540 DEBUG(
dbgs() <<
"\tcannot remat tied reg: " << UseIdx <<
'\t' << MI);
546 if (
RM.OrigMI->canFoldAsLoad() &&
547 foldMemoryOperand(Ops,
RM.OrigMI)) {
548 Edit->markRematerialized(
RM.ParentVNI);
554 unsigned NewVReg = Edit->createFrom(Original);
558 Edit->rematerializeAt(*MI.
getParent(),
MI, NewVReg,
RM, TRI);
562 auto *NewMI = LIS.getInstructionFromIndex(DefIdx);
566 DEBUG(
dbgs() <<
"\tremat: " << DefIdx <<
'\t'
567 << *LIS.getInstructionFromIndex(DefIdx));
570 for (
const auto &OpPair : Ops) {
577 DEBUG(
dbgs() <<
"\t " << UseIdx <<
'\t' << MI <<
'\n');
585 void InlineSpiller::reMaterializeAll() {
586 if (!Edit->anyRematerializable(AA))
592 bool anyRemat =
false;
593 for (
unsigned Reg : RegsToSpill) {
596 RegI =
MRI.reg_bundle_begin(Reg),
E =
MRI.reg_bundle_end();
604 anyRemat |= reMaterializeFor(LI, MI);
611 for (
unsigned Reg : RegsToSpill) {
622 DEBUG(
dbgs() <<
"All defs dead: " << *MI);
623 DeadDefs.push_back(MI);
629 if (DeadDefs.empty())
631 DEBUG(
dbgs() <<
"Remat created " << DeadDefs.size() <<
" dead defs.\n");
632 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill, AA);
640 unsigned ResultPos = 0;
641 for (
unsigned Reg : RegsToSpill) {
642 if (
MRI.reg_nodbg_empty(Reg)) {
643 Edit->eraseVirtReg(Reg);
646 assert((LIS.hasInterval(Reg) && !LIS.getInterval(Reg).empty()) &&
647 "Reg with empty interval has reference");
648 RegsToSpill[ResultPos++] =
Reg;
650 RegsToSpill.erase(RegsToSpill.begin() + ResultPos, RegsToSpill.end());
651 DEBUG(
dbgs() << RegsToSpill.size() <<
" registers to spill after remat.\n");
660 bool InlineSpiller::coalesceStackAccess(
MachineInstr *MI,
unsigned Reg) {
663 bool IsLoad = InstrReg;
668 if (InstrReg != Reg || FI != StackSlot)
672 HSpiller.rmFromMergeableSpills(*MI, StackSlot);
674 DEBUG(
dbgs() <<
"Coalescing stack access: " << *MI);
675 LIS.RemoveMachineInstrFromMaps(*MI);
694 const char *
const header,
696 char NextLine =
'\n';
697 char SlotIndent =
'\t';
699 if (std::next(B) == E) {
704 dbgs() <<
'\t' << header <<
": " << NextLine;
718 dbgs() << SlotIndent << Idx <<
'\t' << *
I;
730 foldMemoryOperand(
ArrayRef<std::pair<MachineInstr*, unsigned> > Ops,
736 if (Ops.back().first != MI || MI->
isBundled())
739 bool WasCopy = MI->
isCopy();
744 bool SpillSubRegs =
TII.isSubregFoldable() ||
745 MI->
getOpcode() == TargetOpcode::STATEPOINT ||
746 MI->
getOpcode() == TargetOpcode::PATCHPOINT ||
747 MI->
getOpcode() == TargetOpcode::STACKMAP;
752 for (
const auto &OpPair : Ops) {
753 unsigned Idx = OpPair.second;
754 assert(MI == OpPair.first &&
"Instruction conflict during operand folding");
764 if (LoadMI && MO.
isDef())
779 LoadMI ?
TII.foldMemoryOperand(*MI, FoldOps, *LoadMI, &LIS)
780 :
TII.foldMemoryOperand(*MI, FoldOps, StackSlot, &LIS);
788 unsigned Reg = MO->
getReg();
789 if (!Reg || TargetRegisterInfo::isVirtualRegister(Reg) ||
790 MRI.isReserved(Reg)) {
796 MIBundleOperands::PhysRegInfo RI =
802 SlotIndex Idx = LIS.getInstructionIndex(*MI).getRegSlot();
803 LIS.removePhysRegDefAt(Reg, Idx);
808 HSpiller.rmFromMergeableSpills(*MI, FI))
810 LIS.ReplaceMachineInstrInMaps(*MI, *FoldMI);
814 assert(!MIS.empty() &&
"Unexpected empty span of instructions!");
817 LIS.InsertMachineInstrInMaps(MI);
826 if (MO.
getReg() == ImpReg)
835 else if (Ops.front().second == 0) {
837 HSpiller.addToMergeableSpills(*FoldMI, StackSlot, Original);
843 void InlineSpiller::insertReload(
unsigned NewVReg,
850 MRI.getRegClass(NewVReg), &TRI);
852 LIS.InsertMachineInstrRangeInMaps(MIS.begin(),
MI);
860 void InlineSpiller::insertSpill(
unsigned NewVReg,
bool isKill,
866 MRI.getRegClass(NewVReg), &TRI);
868 LIS.InsertMachineInstrRangeInMaps(std::next(MI), MIS.end());
873 HSpiller.addToMergeableSpills(*std::next(MI), StackSlot, Original);
877 void InlineSpiller::spillAroundUses(
unsigned Reg) {
883 RegI =
MRI.reg_bundle_begin(Reg),
E =
MRI.reg_bundle_end();
895 DEBUG(
dbgs() <<
"Modifying debug info due to spill:" <<
"\t" << *MI);
897 assert(cast<DILocalVariable>(Var)->isValidLocationForIntrinsic(DL) &&
898 "Expected inlined-at fields to agree");
900 .addFrameIndex(StackSlot)
908 if (SnippetCopies.count(MI))
912 if (coalesceStackAccess(MI, Reg))
917 MIBundleOperands::VirtRegInfo RI =
924 if (SlotIndex::isSameInstr(Idx, VNI->
def))
929 if (SibReg && isSibling(SibReg)) {
931 if (isRegToSpill(SibReg)) {
932 DEBUG(
dbgs() <<
"Found new snippet copy: " << *MI);
933 SnippetCopies.insert(MI);
937 if (hoistSpillInsideBB(OldLI, *MI)) {
940 DeadDefs.push_back(MI);
946 eliminateRedundantSpills(SibLI, SibLI.
getVNInfoAt(Idx));
952 if (foldMemoryOperand(Ops))
957 unsigned NewVReg = Edit->createFrom(Reg);
960 insertReload(NewVReg, Idx, MI);
963 bool hasLiveDef =
false;
964 for (
const auto &OpPair : Ops) {
968 if (!OpPair.first->isRegTiedToDefOperand(OpPair.second))
975 DEBUG(
dbgs() <<
"\trewrite: " << Idx <<
'\t' << *MI <<
'\n');
980 insertSpill(NewVReg,
true, MI);
985 void InlineSpiller::spillAll() {
987 if (StackSlot == VirtRegMap::NO_STACK_SLOT) {
988 StackSlot = VRM.assignVirt2StackSlot(Original);
989 StackInt = &LSS.getOrCreateInterval(StackSlot,
MRI.getRegClass(Original));
990 StackInt->getNextValue(
SlotIndex(), LSS.getVNInfoAllocator());
992 StackInt = &LSS.getInterval(StackSlot);
994 if (Original != Edit->getReg())
995 VRM.assignVirt2StackSlot(Edit->getReg(), StackSlot);
997 assert(StackInt->getNumValNums() == 1 &&
"Bad stack interval values");
998 for (
unsigned Reg : RegsToSpill)
999 StackInt->MergeSegmentsInAsValue(LIS.getInterval(Reg),
1000 StackInt->getValNumInfo(0));
1001 DEBUG(
dbgs() <<
"Merged spilled regs: " << *StackInt <<
'\n');
1004 for (
unsigned Reg : RegsToSpill)
1005 spillAroundUses(Reg);
1008 if (!DeadDefs.empty()) {
1009 DEBUG(
dbgs() <<
"Eliminating " << DeadDefs.size() <<
" dead defs\n");
1010 Edit->eliminateDeadDefs(DeadDefs, RegsToSpill, AA);
1014 for (
unsigned Reg : RegsToSpill) {
1016 RI =
MRI.reg_instr_begin(Reg),
E =
MRI.reg_instr_end();
1019 assert(SnippetCopies.count(&MI) &&
"Remaining use wasn't a snippet copy");
1021 LIS.RemoveMachineInstrFromMaps(MI);
1027 for (
unsigned Reg : RegsToSpill)
1028 Edit->eraseVirtReg(Reg);
1035 &&
"Trying to spill a stack slot.");
1037 Original = VRM.getOriginal(edit.
getReg());
1038 StackSlot = VRM.getStackSlot(Original);
1042 << TRI.getRegClassName(
MRI.getRegClass(edit.
getReg()))
1044 <<
"\nFrom original " <<
PrintReg(Original) <<
'\n');
1046 "Attempting to spill already spilled value.");
1047 assert(DeadDefs.empty() &&
"Previous spill didn't remove dead defs");
1049 collectRegsToSpill();
1053 if (!RegsToSpill.empty())
1056 Edit->calculateRegClassAndHint(MF,
Loops, MBFI);
1061 void InlineSpiller::postOptimization() { HSpiller.hoistAllSpills(); }
1066 unsigned Original) {
1067 StackSlotToReg[StackSlot] = Original;
1068 SlotIndex Idx = LIS.getInstructionIndex(Spill);
1070 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1071 MergeableSpills[MIdx].insert(&Spill);
1077 bool HoistSpillHelper::rmFromMergeableSpills(
MachineInstr &Spill,
1079 int Original = StackSlotToReg[StackSlot];
1082 SlotIndex Idx = LIS.getInstructionIndex(Spill);
1084 std::pair<int, VNInfo *> MIdx = std::make_pair(StackSlot, OrigVNI);
1085 return MergeableSpills[MIdx].erase(&Spill);
1091 bool HoistSpillHelper::isSpillCandBB(
unsigned OrigReg,
VNInfo &OrigVNI,
1097 Idx = LIS.getInstructionIndex(*MI);
1101 assert((LIS.getInterval(OrigReg)).getVNInfoAt(Idx) == &OrigVNI &&
1104 for (
auto const SibReg : Siblings) {
1118 void HoistSpillHelper::rmRedundantSpills(
1125 for (
const auto CurrentSpill : Spills) {
1130 SlotIndex PIdx = LIS.getInstructionIndex(*PrevSpill);
1131 SlotIndex CIdx = LIS.getInstructionIndex(*CurrentSpill);
1132 MachineInstr *SpillToRm = (CIdx > PIdx) ? CurrentSpill : PrevSpill;
1133 MachineInstr *SpillToKeep = (CIdx > PIdx) ? PrevSpill : CurrentSpill;
1135 SpillBBToSpill[MDT.getBase().getNode(Block)] = SpillToKeep;
1137 SpillBBToSpill[MDT.getBase().getNode(Block)] = CurrentSpill;
1140 for (
const auto SpillToRm : SpillsToRm)
1141 Spills.
erase(SpillToRm);
1151 void HoistSpillHelper::getVisitOrders(
1175 for (
const auto Spill : Spills) {
1179 while (Node != RootIDomNode) {
1182 if (Node != MDT[Block] && SpillBBToSpill[Node]) {
1183 SpillToRm = SpillBBToSpill[MDT[Block]];
1188 }
else if (WorkSet.
count(Node)) {
1191 NodesOnPath.
insert(Node);
1193 Node = Node->getIDom();
1203 SpillsToKeep[MDT[Block]] = 0;
1206 NodesOnPath.
clear();
1212 Orders.
push_back(MDT.getBase().getNode(Root));
1215 const std::vector<MachineDomTreeNode *> &Children = Node->
getChildren();
1216 unsigned NumChildren = Children.size();
1217 for (
unsigned i = 0;
i != NumChildren; ++
i) {
1219 if (WorkSet.
count(Child))
1222 }
while (idx != Orders.
size());
1224 "Orders have different size with WorkSet");
1227 DEBUG(
dbgs() <<
"Orders size is " << Orders.
size() <<
"\n");
1229 for (; RIt != Orders.
rend(); RIt++)
1230 DEBUG(
dbgs() <<
"BB" << (*RIt)->getBlock()->getNumber() <<
",");
1239 void HoistSpillHelper::runHoistSpills(
1254 rmRedundantSpills(Spills, SpillsToRm, SpillBBToSpill);
1257 getVisitOrders(Root, Spills, Orders, SpillsToRm, SpillsToKeep,
1264 typedef std::pair<SmallPtrSet<MachineDomTreeNode *, 16>,
BlockFrequency>
1272 for (; RIt != Orders.
rend(); RIt++) {
1276 if (SpillsToKeep.
find(*RIt) != SpillsToKeep.
end() && !SpillsToKeep[*RIt]) {
1277 SpillsInSubTreeMap[*RIt].first.
insert(*RIt);
1279 SpillsInSubTreeMap[*RIt].second = MBFI.getBlockFreq(Block);
1285 const std::vector<MachineDomTreeNode *> &Children = (*RIt)->getChildren();
1286 unsigned NumChildren = Children.size();
1287 for (
unsigned i = 0;
i != NumChildren; ++
i) {
1289 if (SpillsInSubTreeMap.
find(Child) == SpillsInSubTreeMap.
end())
1297 SpillsInSubTreeMap[*RIt].first;
1299 SubTreeCost += SpillsInSubTreeMap[Child].second;
1300 auto BI = SpillsInSubTreeMap[Child].first.
begin();
1301 auto EI = SpillsInSubTreeMap[Child].first.
end();
1302 SpillsInSubTree.
insert(BI, EI);
1303 SpillsInSubTreeMap.
erase(Child);
1307 SpillsInSubTreeMap[*RIt].first;
1310 if (SpillsInSubTree.
empty())
1314 unsigned LiveReg = 0;
1315 if (!isSpillCandBB(OrigReg, OrigVNI, *Block, LiveReg))
1323 if (SubTreeCost > MBFI.getBlockFreq(Block) * MarginProb) {
1325 for (
const auto SpillBB : SpillsInSubTree) {
1328 if (SpillsToKeep.
find(SpillBB) != SpillsToKeep.
end() &&
1329 !SpillsToKeep[SpillBB]) {
1334 SpillsToKeep.
erase(SpillBB);
1338 SpillsToKeep[*RIt] = LiveReg;
1340 dbgs() <<
"spills in BB: ";
1341 for (
const auto Rspill : SpillsInSubTree)
1342 dbgs() << Rspill->getBlock()->getNumber() <<
" ";
1343 dbgs() <<
"were promoted to BB" << (*RIt)->getBlock()->getNumber()
1346 SpillsInSubTree.clear();
1347 SpillsInSubTree.insert(*RIt);
1348 SubTreeCost = MBFI.getBlockFreq(Block);
1353 for (
const auto Ent : SpillsToKeep) {
1355 SpillsToIns[Ent.first->getBlock()] = Ent.second;
1376 void HoistSpillHelper::hoistAllSpills() {
1382 for (
unsigned i = 0, e =
MRI.getNumVirtRegs();
i != e; ++
i) {
1383 unsigned Reg = TargetRegisterInfo::index2VirtReg(
i);
1384 int Slot = VRM.getStackSlot(Reg);
1385 if (Slot != VirtRegMap::NO_STACK_SLOT)
1386 SlotToOrigReg[Slot] = VRM.getOriginal(Reg);
1387 unsigned Original = VRM.getPreSplitReg(Reg);
1388 if (!
MRI.def_empty(Reg))
1389 Virt2SiblingsMap[Original].insert(Reg);
1393 for (
auto &Ent : MergeableSpills) {
1394 int Slot = Ent.first.first;
1395 unsigned OrigReg = SlotToOrigReg[Slot];
1397 VNInfo *OrigVNI = Ent.first.second;
1399 if (Ent.second.empty())
1403 dbgs() <<
"\nFor Slot" << Slot <<
" and VN" << OrigVNI->
id <<
":\n"
1404 <<
"Equal spills in BB: ";
1405 for (
const auto spill : EqValSpills)
1406 dbgs() << spill->getParent()->getNumber() <<
" ";
1415 runHoistSpills(OrigReg, *OrigVNI, EqValSpills, SpillsToRm, SpillsToIns);
1418 dbgs() <<
"Finally inserted spills in BB: ";
1419 for (
const auto Ispill : SpillsToIns)
1420 dbgs() << Ispill.first->getNumber() <<
" ";
1421 dbgs() <<
"\nFinally removed spills in BB: ";
1422 for (
const auto Rspill : SpillsToRm)
1423 dbgs() << Rspill->getParent()->getNumber() <<
" ";
1429 if (!SpillsToIns.empty() || !SpillsToRm.empty())
1431 StackIntvl.getValNumInfo(0));
1434 for (
auto const Insert : SpillsToIns) {
1436 unsigned LiveReg = Insert.second;
1439 MRI.getRegClass(LiveReg), &TRI);
1440 LIS.InsertMachineInstrRangeInMaps(std::prev(MI), MI);
1445 NumSpills -= SpillsToRm.size();
1446 for (
auto const RMEnt : SpillsToRm) {
1448 for (
unsigned i = RMEnt->getNumOperands();
i; --
i) {
1451 RMEnt->RemoveOperand(
i - 1);
1454 Edit.eliminateDeadDefs(SpillsToRm,
None, AA);
1460 void HoistSpillHelper::LRE_DidCloneVirtReg(
unsigned New,
unsigned Old) {
1461 if (VRM.hasPhys(Old))
1462 VRM.assignVirt2Phys(New, VRM.getPhys(Old));
1463 else if (VRM.getStackSlot(Old) != VirtRegMap::NO_STACK_SLOT)
1464 VRM.assignVirt2StackSlot(New, VRM.getStackSlot(Old));
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
void push_back(const T &Elt)
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
SlotIndex def
The index of the defining instruction.
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
STATISTIC(NumFunctions,"Total number of functions")
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
void MergeValueInAsValue(const LiveRange &RHS, const VNInfo *RHSValNo, VNInfo *LHSValNo)
MergeValueInAsValue - Merge all of the segments of a specific val# in RHS into this live range as the...
bool addRegisterDead(unsigned Reg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI defined a register without a use.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Store the specified register of the given register class to the specified stack frame index...
LiveInterval - This class represents the liveness of a register, or stack slot.
MIBundleOperands - Iterate over all operands in a bundle of machine instructions. ...
bool mayStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly modify memory.
bool isSpillable() const
isSpillable - Can this interval be spilled?
void setIsUndef(bool Val=true)
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
bool isKill() const
Return true if the live-in value is killed by this instruction.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
This class implements a map that also provides access to all stored values in a deterministic order...
void setIsDead(bool Val=true)
VNInfo - Value Number Information.
Determines the latest safe point in a block in which we can insert a split, spill or other instructio...
unsigned getNumValNums() const
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
Callback methods for LiveRangeEdit owners.
VirtRegInfo analyzeVirtReg(unsigned Reg, SmallVectorImpl< std::pair< MachineInstr *, unsigned > > *Ops=nullptr)
analyzeVirtReg - Analyze how the current instruction or bundle uses a virtual register.
bool allDefsAreDead() const
Return true if all the defs of this instruction are dead.
MachineInstrSpan provides an interface to get an iteration range containing the instruction it was in...
DomTreeNodeBase< NodeT > * getIDom() const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
safe Safe Stack instrumentation pass
static void dumpMachineInstrRangeWithSlotIndex(MachineBasicBlock::iterator B, MachineBasicBlock::iterator E, LiveIntervals const &LIS, const char *const header, unsigned VReg=0)
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const override
Load the specified register of the given register class from the specified stack frame index...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
Result of a LiveRange query.
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
PhysRegInfo analyzePhysReg(unsigned Reg, const TargetRegisterInfo *TRI)
analyzePhysReg - Analyze how the current instruction or bundle uses a physical register.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
LLVM_NODISCARD bool empty() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isUnused() const
Returns true if this value is unused.
defusechain_iterator - This class provides iterator support for machine operands in the function that...
void RemoveOperand(unsigned i)
Erase an operand from an instruction, leaving it with one fewer operand than it started with...
bool isBundled() const
Return true if this instruction part of a bundle.
Base class for the actual dominator tree node.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
Printable PrintReg(unsigned Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubRegIdx=0)
Prints virtual and physical registers with or without a TRI instance.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
SlotIndex getPrevSlot() const
Returns the previous slot in the index list.
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
bool isEarlyClobber() const
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
bool erase(const KeyT &Val)
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
bool isIndirectDebugValue() const
A DBG_VALUE is indirect iff the first operand is a register and the second operand is an immediate...
const MachineOperand & getOperand(unsigned i) const
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
LiveInterval & getParent() const
iterator_range< pred_iterator > predecessors()
const DIExpression * getDebugExpression() const
Return the complex address expression referenced by this DBG_VALUE instruction.
LLVM_NODISCARD bool empty() const
unsigned getSubReg() const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
bool isPHIDef() const
Returns true if this value is defined by a PHI instruction (or was, PHI instructions may have been el...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void setIsKill(bool Val=true)
unsigned id
The ID number of this value.
A SetVector that performs no allocations if smaller than a certain size.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
void setDesc(const MCInstrDesc &tid)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one...
MachineOperand class - Representation of each machine instruction operand.
static cl::opt< bool > DisableHoisting("disable-spill-hoist", cl::Hidden, cl::desc("Disable inline spill hoisting"))
unsigned 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...
LLVM_NODISCARD T pop_back_val()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Spiller * createInlineSpiller(MachineFunctionPass &pass, MachineFunction &mf, VirtRegMap &vrm)
Create and return a spiller that will insert spill code directly instead of deferring though VirtRegM...
Representation of each machine instruction.
void setReg(unsigned Reg)
Change the register this operand corresponds to.
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
iterator find(const KeyT &Val)
static unsigned isFullCopyOf(const MachineInstr &MI, unsigned Reg)
isFullCopyOf - If MI is a COPY to or from Reg, return the other register, otherwise return 0...
const DILocalVariable * getDebugVariable() const
Return the debug variable referenced by this DBG_VALUE instruction.
Remat - Information needed to rematerialize at a specific location.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def...
unsigned getReg() const
getReg - Returns the register number.
reverse_iterator rbegin()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx=nullptr) const
Return true if the use operand of the specified index is tied to a def operand.
iterator SkipPHIsLabelsAndDebug(iterator I)
Return the first instruction in MBB after I that is not a PHI, label or debug.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
SlotIndex - An opaque wrapper around machine indexes.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
VNInfo * getVNInfoBefore(SlotIndex Idx) const
getVNInfoBefore - Return the VNInfo that is live up to but not necessarilly including Idx...
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.