49#include "llvm/Config/llvm-config.h"
69#define DEBUG_TYPE "livedebugvars"
75STATISTIC(NumInsertedDebugValues,
"Number of DBG_VALUEs inserted");
76STATISTIC(NumInsertedDebugLabels,
"Number of DBG_LABELs inserted");
81 "Debug Variable Analysis",
false,
false)
103class DbgVariableValue {
105 DbgVariableValue(ArrayRef<unsigned> NewLocs,
bool WasIndirect,
bool WasList,
106 const DIExpression &Expr)
107 : WasIndirect(WasIndirect), WasList(WasList), Expression(&Expr) {
108 assert(!(WasIndirect && WasList) &&
109 "DBG_VALUE_LISTs should not be indirect.");
110 SmallVector<unsigned> LocNoVec;
111 for (
unsigned LocNo : NewLocs) {
112 auto It =
find(LocNoVec, LocNo);
113 if (It == LocNoVec.
end())
119 unsigned DuplicatingIdx = std::distance(LocNoVec.
begin(), It);
130 if (LocNoVec.
size() < 64) {
131 LocNoCount = LocNoVec.
size();
132 if (LocNoCount > 0) {
133 LocNos = std::make_unique<unsigned[]>(LocNoCount);
138 "locations, dropping...\n");
143 DIExpression::get(Expr.
getContext(), {dwarf::DW_OP_LLVM_arg, 0});
146 Expression, FragmentInfoOpt->OffsetInBits,
147 FragmentInfoOpt->SizeInBits);
148 LocNos = std::make_unique<unsigned[]>(LocNoCount);
153 DbgVariableValue() : LocNoCount(0), WasIndirect(
false), WasList(
false) {}
154 DbgVariableValue(
const DbgVariableValue &
Other)
155 : LocNoCount(
Other.LocNoCount), WasIndirect(
Other.getWasIndirect()),
156 WasList(
Other.getWasList()), Expression(
Other.getExpression()) {
157 if (
Other.getLocNoCount()) {
158 LocNos.reset(new unsigned[Other.getLocNoCount()]);
159 std::copy(Other.loc_nos_begin(), Other.loc_nos_end(), loc_nos_begin());
163 DbgVariableValue &operator=(
const DbgVariableValue &
Other) {
166 if (
Other.getLocNoCount()) {
167 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
168 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
172 LocNoCount =
Other.getLocNoCount();
173 WasIndirect =
Other.getWasIndirect();
174 WasList =
Other.getWasList();
175 Expression =
Other.getExpression();
179 const DIExpression *getExpression()
const {
return Expression; }
180 uint8_t getLocNoCount()
const {
return LocNoCount; }
181 bool containsLocNo(
unsigned LocNo)
const {
184 bool getWasIndirect()
const {
return WasIndirect; }
185 bool getWasList()
const {
return WasList; }
188 DbgVariableValue decrementLocNosAfterPivot(
unsigned Pivot)
const {
189 SmallVector<unsigned, 4> NewLocNos;
190 for (
unsigned LocNo : loc_nos())
193 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
196 DbgVariableValue remapLocNos(ArrayRef<unsigned> LocNoMap)
const {
197 SmallVector<unsigned> NewLocNos;
198 for (
unsigned LocNo : loc_nos())
202 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
205 DbgVariableValue changeLocNo(
unsigned OldLocNo,
unsigned NewLocNo)
const {
206 SmallVector<unsigned> NewLocNos;
207 NewLocNos.
assign(loc_nos_begin(), loc_nos_end());
208 auto OldLocIt =
find(NewLocNos, OldLocNo);
209 assert(OldLocIt != NewLocNos.
end() &&
"Old location must be present.");
210 *OldLocIt = NewLocNo;
211 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *Expression);
214 bool hasLocNoGreaterThan(
unsigned LocNo)
const {
216 [LocNo](
unsigned ThisLocNo) {
return ThisLocNo > LocNo; });
219 void printLocNos(llvm::raw_ostream &OS)
const {
220 for (
const unsigned &Loc : loc_nos())
221 OS << (&Loc == loc_nos_begin() ?
" " :
", ") << Loc;
225 const DbgVariableValue &
RHS) {
226 if (std::tie(
LHS.LocNoCount,
LHS.WasIndirect,
LHS.WasList,
228 std::tie(
RHS.LocNoCount,
RHS.WasIndirect,
RHS.WasList,
RHS.Expression))
230 return std::equal(
LHS.loc_nos_begin(),
LHS.loc_nos_end(),
231 RHS.loc_nos_begin());
235 const DbgVariableValue &
RHS) {
239 unsigned *loc_nos_begin() {
return LocNos.get(); }
240 const unsigned *loc_nos_begin()
const {
return LocNos.get(); }
241 unsigned *loc_nos_end() {
return LocNos.get() + LocNoCount; }
242 const unsigned *loc_nos_end()
const {
return LocNos.get() + LocNoCount; }
243 ArrayRef<unsigned> loc_nos()
const {
244 return ArrayRef<unsigned>(LocNos.get(), LocNoCount);
253 std::unique_ptr<unsigned[]> LocNos;
254 uint8_t LocNoCount : 6;
255 bool WasIndirect : 1;
257 const DIExpression *Expression =
nullptr;
291 const std::optional<DIExpression::FragmentInfo> Fragment;
295 UserValue *next =
nullptr;
324 std::optional<DIExpression::FragmentInfo> Fragment,
DebugLoc L,
326 : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(
this),
330 UserValue *getLeader() {
331 UserValue *l = leader;
332 while (l != l->leader)
338 UserValue *getNext()
const {
return next; }
341 static UserValue *
merge(UserValue *L1, UserValue *L2) {
342 L2 = L2->getLeader();
345 L1 = L1->getLeader();
355 End->next = L1->next;
371 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
372 if (locations[i].
isReg() &&
374 locations[i].getSubReg() == LocMO.
getSubReg())
377 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
382 locations.
back().clearParent();
384 if (locations.
back().isReg()) {
385 if (locations.
back().isDef())
386 locations.
back().setIsDead(
false);
387 locations.
back().setIsUse();
389 return locations.
size() - 1;
394 void removeLocationIfUnused(
unsigned LocNo) {
396 for (LocMap::const_iterator
I = locInts.
begin();
I.valid(); ++
I) {
397 const DbgVariableValue &
DbgValue =
I.value();
404 for (LocMap::iterator
I = locInts.
begin();
I.valid(); ++
I) {
405 const DbgVariableValue &
DbgValue =
I.value();
406 if (
DbgValue.hasLocNoGreaterThan(LocNo))
407 I.setValueUnchecked(
DbgValue.decrementLocNosAfterPivot(LocNo));
412 void mapVirtRegs(
LDVImpl *LDV);
420 DbgVariableValue
DbgValue(Locs, IsIndirect, IsList, Expr);
422 LocMap::iterator
I = locInts.
find(Idx);
423 if (!
I.valid() ||
I.start() != Idx)
447 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
461 void addDefsFromCopies(
514 : Label(label), dl(std::move(L)), loc(Idx) {}
519 return Label == L && dl->getInlinedAt() == IA && loc == Index;
550 std::map<unsigned, PHIValPos> PHIValToPos;
569 bool EmitDone =
false;
572 bool ModifiedMF =
false;
582 VRMap virtRegToEqClass;
590 std::optional<DIExpression::FragmentInfo> Fragment,
594 UserValue *lookupVirtReg(
Register VirtReg);
637 void computeIntervals();
649 StashedDebugInstrs.clear();
652 virtRegToEqClass.clear();
655 assert((!ModifiedMF || EmitDone) &&
656 "Dbg values are not emitted in LDV");
692 CommentOS << Scope->getFilename();
693 CommentOS <<
':' <<
DL.getLine();
694 if (
DL.getCol() != 0)
695 CommentOS <<
':' <<
DL.getCol();
720 OS << Res <<
"," << Line;
721 auto *InlinedAt =
DL ?
DL->getInlinedAt() :
nullptr;
723 if (
DebugLoc InlinedAtDL = InlinedAt) {
736 for (LocMap::const_iterator
I = locInts.begin();
I.valid(); ++
I) {
737 OS <<
" [" <<
I.start() <<
';' <<
I.stop() <<
"):";
738 if (
I.value().isUndef())
741 I.value().printLocNos(OS);
742 if (
I.value().getWasIndirect())
744 else if (
I.value().getWasList())
748 for (
unsigned i = 0, e = locations.size(); i != e; ++i) {
749 OS <<
" Loc" << i <<
'=';
750 locations[i].print(OS,
TRI);
765 OS <<
"********** DEBUG VARIABLES **********\n";
766 for (
auto &userValue : userValues)
767 userValue->print(OS, TRI);
768 OS <<
"********** DEBUG LABELS **********\n";
769 for (
auto &userLabel : userLabels)
770 userLabel->print(OS, TRI);
775 if (MO.isReg() && MO.getReg().isVirtual())
779UserValue *LiveDebugVariables::LDVImpl::getUserValue(
781 std::optional<DIExpression::FragmentInfo> Fragment,
const DebugLoc &
DL) {
785 UserValue *&UV = userVarMap[
ID];
787 userValues.push_back(
788 std::make_unique<UserValue>(Var, Fragment,
DL,
allocator));
789 UV = userValues.back().get();
796 UserValue *&Leader = virtRegToEqClass[VirtReg];
797 Leader = UserValue::merge(Leader, EC);
800UserValue *LiveDebugVariables::LDVImpl::lookupVirtReg(
Register VirtReg) {
801 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
802 return UV->getLeader();
806bool LiveDebugVariables::LDVImpl::handleDebugValue(
MachineInstr &
MI,
810 if (!
MI.isDebugValue()) {
814 if (!
MI.getDebugVariableOp().isMetadata()) {
815 LLVM_DEBUG(
dbgs() <<
"Can't handle DBG_VALUE* with invalid variable: "
819 if (
MI.isNonListDebugValue() &&
820 (
MI.getNumOperands() != 4 ||
821 !(
MI.getDebugOffset().isImm() ||
MI.getDebugOffset().isReg()))) {
830 bool Discard =
false;
831 for (
const MachineOperand &
Op :
MI.debug_operands()) {
832 if (
Op.isReg() &&
Op.getReg().isVirtual()) {
834 if (!LIS->hasInterval(
Reg)) {
838 LLVM_DEBUG(
dbgs() <<
"Discarding debug info (no LIS interval): " << Idx
844 const LiveInterval &LI = LIS->getInterval(
Reg);
845 LiveQueryResult LRQ = LI.
Query(Idx);
850 LLVM_DEBUG(
dbgs() <<
"Discarding debug info (reg not live): " << Idx
858 bool IsIndirect =
MI.isDebugOffsetImm();
860 assert(
MI.getDebugOffset().getImm() == 0 &&
861 "DBG_VALUE with nonzero offset");
862 bool IsList =
MI.isDebugValueList();
863 const DILocalVariable *Var =
MI.getDebugVariable();
864 const DIExpression *Expr =
MI.getDebugExpression();
869 MI.debug_operands().end()),
870 IsIndirect, IsList, *Expr);
878 UV->addDef(Idx, UndefMOs,
false, IsList, *Expr);
884LiveDebugVariables::LDVImpl::handleDebugInstr(MachineInstr &
MI, SlotIndex Idx) {
885 assert(
MI.isDebugValueLike() ||
MI.isDebugPHI());
889 if (
MI.isDebugValueLike())
891 [](
const MachineOperand &MO) {
892 return MO.isReg() && MO.getReg().isVirtual();
894 "MIs should not refer to Virtual Registers in InstrRef mode.");
897 auto NextInst = std::next(
MI.getIterator());
898 auto *
MBB =
MI.getParent();
899 MI.removeFromParent();
900 StashedDebugInstrs.push_back({&
MI, Idx,
MBB});
904bool LiveDebugVariables::LDVImpl::handleDebugLabel(MachineInstr &
MI,
907 if (
MI.getNumOperands() != 1 || !
MI.getOperand(0).isMetadata()) {
913 const DILabel *
Label =
MI.getDebugLabel();
916 for (
auto const &L : userLabels) {
917 if (
L->matches(Label,
DL->getInlinedAt(), Idx)) {
923 userLabels.push_back(std::make_unique<UserLabel>(Label,
DL, Idx));
928bool LiveDebugVariables::LDVImpl::collectDebugValues(MachineFunction &mf,
931 for (MachineBasicBlock &
MBB : mf) {
936 if (!
MBBI->isDebugOrPseudoInstr()) {
944 ? LIS->getMBBStartIdx(&
MBB)
945 : LIS->getInstructionIndex(*std::prev(
MBBI)).getRegSlot();
951 if (InstrRef && (
MBBI->isNonListDebugValue() ||
MBBI->isDebugPHI() ||
952 MBBI->isDebugRef())) {
953 MBBI = handleDebugInstr(*
MBBI, Idx);
957 }
else if ((
MBBI->isDebugValue() && handleDebugValue(*
MBBI, Idx)) ||
958 (
MBBI->isDebugLabel() && handleDebugLabel(*
MBBI, Idx))) {
963 }
while (
MBBI != MBBE &&
MBBI->isDebugOrPseudoInstr());
969void UserValue::extendDef(
970 SlotIndex Idx, DbgVariableValue DbgValue,
971 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
973 std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
974 LiveIntervals &LIS) {
975 SlotIndex
Start = Idx;
978 LocMap::iterator
I = locInts.find(Start);
981 for (
auto &LII : LiveIntervalInfo) {
983 assert(LR && LII.second.second &&
"Missing range info for Idx.");
985 assert(Segment && Segment->
valno == LII.second.second &&
986 "Invalid VNInfo for Idx given?");
987 if (Segment->
end < Stop) {
989 Kills = {Stop, {LII.first}};
990 }
else if (Segment->
end == Stop && Kills) {
993 Kills->second.push_back(LII.first);
998 if (
I.valid() &&
I.start() <= Start) {
1001 if (
I.value() != DbgValue ||
I.stop() != Start) {
1003 Kills = std::nullopt;
1011 if (
I.valid() &&
I.start() < Stop) {
1014 Kills = std::nullopt;
1018 DbgVariableValue ExtDbgValue(DbgValue);
1019 I.insert(Start, Stop, std::move(ExtDbgValue));
1023void UserValue::addDefsFromCopies(
1024 DbgVariableValue DbgValue,
1025 SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,
1027 SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,
1028 MachineRegisterInfo &
MRI, LiveIntervals &LIS) {
1031 [](
auto LocI) {
return !LocI.second->reg().isVirtual(); }))
1035 SmallDenseMap<unsigned,
1038 for (
auto &LocInterval : LocIntervals) {
1039 unsigned LocNo = LocInterval.first;
1040 LiveInterval *LI = LocInterval.second;
1041 for (MachineOperand &MO :
MRI.use_nodbg_operands(LI->
reg())) {
1046 Register DstReg =
MI->getOperand(0).getReg();
1058 LocMap::iterator
I = locInts.find(Idx.
getRegSlot(
true));
1059 if (!
I.valid() ||
I.value() != DbgValue)
1067 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
1071 if (CopyValues.
empty())
1075 for (
auto &LocInterval : LocIntervals)
1076 LLVM_DEBUG(
dbgs() <<
"Got " << CopyValues[LocInterval.first].size()
1077 <<
" copies of " << *LocInterval.second <<
'\n');
1082 LocMap::iterator
I = locInts.find(KilledAt);
1083 if (
I.valid() &&
I.start() <= KilledAt)
1085 DbgVariableValue NewValue(DbgValue);
1086 for (
auto &LocInterval : LocIntervals) {
1087 unsigned LocNo = LocInterval.first;
1088 bool FoundCopy =
false;
1089 for (
auto &LIAndVNI : CopyValues[LocNo]) {
1090 LiveInterval *DstLI = LIAndVNI.first;
1091 const VNInfo *DstVNI = LIAndVNI.second;
1094 LLVM_DEBUG(
dbgs() <<
"Kill at " << KilledAt <<
" covered by valno #"
1095 << DstVNI->
id <<
" in " << *DstLI <<
'\n');
1097 assert(CopyMI && CopyMI->
isCopy() &&
"Bad copy value");
1098 unsigned NewLocNo = getLocationNo(CopyMI->
getOperand(0));
1099 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
1109 NewDefs.push_back(std::make_pair(KilledAt, NewValue));
1112void UserValue::computeIntervals(MachineRegisterInfo &
MRI,
1113 const TargetRegisterInfo &
TRI,
1114 LiveIntervals &LIS, LexicalScopes &LS) {
1118 for (LocMap::const_iterator
I = locInts.begin();
I.valid(); ++
I)
1119 if (!
I.value().isUndef())
1120 Defs.
push_back(std::make_pair(
I.start(),
I.value()));
1123 for (
unsigned i = 0; i != Defs.
size(); ++i) {
1124 SlotIndex Idx = Defs[i].first;
1125 DbgVariableValue DbgValue = Defs[i].second;
1126 SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>> LIs;
1127 bool ShouldExtendDef =
false;
1128 for (
unsigned LocNo : DbgValue.loc_nos()) {
1129 const MachineOperand &LocMO = locations[LocNo];
1131 ShouldExtendDef |= !LocMO.
isReg();
1134 ShouldExtendDef =
true;
1135 LiveInterval *LI =
nullptr;
1136 const VNInfo *VNI =
nullptr;
1142 LIs[LocNo] = {LI, VNI};
1144 if (ShouldExtendDef) {
1145 std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> Kills;
1146 extendDef(Idx, DbgValue, LIs, Kills, LIS);
1150 bool AnySubreg =
false;
1151 for (
unsigned LocNo : Kills->second) {
1152 const MachineOperand &LocMO = this->locations[LocNo];
1158 KilledLocIntervals.
push_back({LocNo, LI});
1170 addDefsFromCopies(DbgValue, KilledLocIntervals, Kills->first, Defs,
1190 if (!dl.getInlinedAt())
1193 LexicalScope *
Scope =
LS.findLexicalScope(dl);
1198 LocMap::iterator
I = locInts.begin();
1210 if (
Range.first ==
Range.first->getParent()->begin())
1215 if (PrevEnd &&
I.start() < PrevEnd) {
1216 SlotIndex IStop =
I.stop();
1217 DbgVariableValue DbgValue =
I.value();
1221 I.setStopUnchecked(PrevEnd);
1228 I.insert(RStart, IStop, DbgValue);
1232 I.advanceTo(RStart);
1236 if (
I.start() < RStart) {
1238 I.setStartUnchecked(RStart);
1240 trimmedDefs.insert(RStart);
1257 if (PrevEnd &&
I.start() < PrevEnd)
1258 I.setStopUnchecked(PrevEnd);
1261void LiveDebugVariables::LDVImpl::computeIntervals() {
1263 LS.scanFunction(*MF);
1265 for (
const auto &UV : userValues) {
1266 UV->computeIntervals(MF->getRegInfo(), *
TRI, *LIS, LS);
1267 UV->mapVirtRegs(
this);
1276 LLVM_DEBUG(
dbgs() <<
"********** COMPUTING LIVE DEBUG VARIABLES: "
1277 << mf.
getName() <<
" **********\n");
1279 bool Changed = collectDebugValues(mf, InstrRef);
1286 for (
const auto &PHIIt : MF->DebugPHIPositions) {
1290 unsigned SubReg = Position.SubReg;
1293 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
1294 RegToPHIIdx[Reg].push_back(PHIIt.first);
1304 if (
MI.isDebugInstr())
1313 Impl = std::make_unique<LiveDebugVariables>();
1314 Impl->analyze(mf, LIS);
1327 LDV.analyze(MF, LIS);
1346 MachineFunctionAnalysisManager::Invalidator &) {
1351 return !PAC.preservedWhenStateless();
1362 PImpl.reset(
new LDVImpl(LIS));
1367 PImpl->runOnMachineFunction(MF, InstrRef);
1378 dbgs() <<
"Splitting Loc" << OldLocNo <<
'\t';
1381 bool DidChange =
false;
1382 LocMap::iterator LocMapI;
1383 LocMapI.setMap(locInts);
1394 if (!LocMapI.valid())
1398 while (LocMapI.valid() && LII != LIE) {
1400 LII = LI->
advanceTo(LII, LocMapI.start());
1405 if (LocMapI.value().containsLocNo(OldLocNo) &&
1406 LII->start < LocMapI.stop()) {
1410 MO.
setSubReg(locations[OldLocNo].getSubReg());
1411 NewLocNo = getLocationNo(MO);
1415 SlotIndex LStart = LocMapI.start();
1416 SlotIndex LStop = LocMapI.stop();
1417 DbgVariableValue OldDbgValue = LocMapI.value();
1420 if (LStart < LII->start)
1421 LocMapI.setStartUnchecked(LII->start);
1422 if (LStop > LII->end)
1423 LocMapI.setStopUnchecked(LII->end);
1426 LocMapI.setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
1429 if (LStart < LocMapI.start()) {
1430 LocMapI.insert(LStart, LocMapI.start(), OldDbgValue);
1432 assert(LocMapI.valid() &&
"Unexpected coalescing");
1434 if (LStop > LocMapI.stop()) {
1436 LocMapI.insert(LII->end, LStop, OldDbgValue);
1442 if (LII->end < LocMapI.stop()) {
1445 LocMapI.advanceTo(LII->start);
1448 if (!LocMapI.valid())
1450 LII = LI->
advanceTo(LII, LocMapI.start());
1465 removeLocationIfUnused(OldLocNo);
1468 dbgs() <<
"Split result: \t";
1476 LiveIntervals &LIS) {
1477 bool DidChange =
false;
1480 for (
unsigned i = locations.size(); i ; --i) {
1481 unsigned LocNo = i-1;
1482 const MachineOperand *Loc = &locations[LocNo];
1485 DidChange |= splitLocation(LocNo, NewRegs, LIS);
1492 auto RegIt = RegToPHIIdx.find(OldReg);
1493 if (RegIt == RegToPHIIdx.end())
1496 std::vector<std::pair<Register, unsigned>> NewRegIdxes;
1498 for (
unsigned InstrID : RegIt->second) {
1499 auto PHIIt = PHIValToPos.find(InstrID);
1500 assert(PHIIt != PHIValToPos.end());
1501 const SlotIndex &Slot = PHIIt->second.SI;
1502 assert(OldReg == PHIIt->second.Reg);
1505 for (
auto NewReg : NewRegs) {
1507 auto LII = LI.
find(Slot);
1508 if (LII != LI.
end() && LII->start <= Slot) {
1510 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
1512 PHIIt->second.Reg = NewReg;
1524 RegToPHIIdx.erase(RegIt);
1525 for (
auto &RegAndInstr : NewRegIdxes)
1526 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
1536 bool DidChange =
false;
1537 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
1538 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
1544 UserValue *UV = lookupVirtReg(OldReg);
1552 PImpl->splitRegister(OldReg, NewRegs);
1569 for (
unsigned I = 0, E = locations.size();
I != E; ++
I) {
1570 bool Spilled =
false;
1571 unsigned SpillOffset = 0;
1574 if (
Loc.isReg() &&
Loc.getReg() &&
Loc.getReg().isVirtual()) {
1586 bool Success =
TII.getStackSlotRange(TRC,
Loc.getSubReg(), SpillSize,
1602 auto InsertResult = NewLocations.
insert({Loc, {Spilled, SpillOffset}});
1603 unsigned NewLocNo = std::distance(NewLocations.
begin(), InsertResult.first);
1604 LocNoMap[
I] = NewLocNo;
1609 SpillOffsets.
clear();
1610 for (
auto &Pair : NewLocations) {
1612 unsigned SpillOffset;
1613 std::tie(Spilled, SpillOffset) = Pair.second;
1614 locations.push_back(Pair.first);
1616 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
1617 SpillOffsets[NewLocNo] = SpillOffset;
1625 for (LocMap::iterator
I = locInts.begin();
I.valid(); ++
I) {
1626 I.setValueUnchecked(
I.value().remapLocNos(LocNoMap));
1627 I.setStart(
I.start());
1658 auto MapIt = BBSkipInstsMap.
find(
MBB);
1659 if (MapIt == BBSkipInstsMap.
end())
1660 BeginIt =
MBB->begin();
1662 BeginIt = std::next(MapIt->second);
1663 auto I =
MBB->SkipPHIsLabelsAndDebug(BeginIt);
1665 BBSkipInstsMap[
MBB] = std::prev(
I);
1672 auto It =
MI->isTerminator() ?
MBB->getFirstTerminator()
1688 return MBB->instr_end();
1691 while (
I !=
MBB->end() && !
I->isTerminator()) {
1696 return I->definesRegister(
Reg, &
TRI);
1699 return std::next(
I);
1705void UserValue::insertDebugValue(MachineBasicBlock *
MBB, SlotIndex StartIdx,
1706 SlotIndex StopIdx, DbgVariableValue DbgValue,
1708 ArrayRef<unsigned> SpillOffsets,
1709 LiveIntervals &LIS,
const TargetInstrInfo &
TII,
1710 const TargetRegisterInfo &
TRI,
1714 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
1720 if (DbgValue.isUndef()) {
1721 MOs.
assign(DbgValue.loc_nos().size(),
1728 for (
unsigned LocNo : DbgValue.loc_nos())
1732 ++NumInsertedDebugValues;
1736 "Expected inlined-at fields to agree");
1742 const DIExpression *Expr = DbgValue.getExpression();
1743 bool IsIndirect = DbgValue.getWasIndirect();
1744 bool IsList = DbgValue.getWasList();
1745 for (
unsigned I = 0,
E = LocSpills.
size();
I !=
E; ++
I) {
1754 SmallVector<uint64_t, 4>
Ops;
1756 Ops.push_back(dwarf::DW_OP_deref);
1761 assert((!LocSpills[
I] || MOs[
I].isFI()) &&
1762 "a spilled location must be a frame index");
1765 unsigned DbgValueOpcode =
1766 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
1777void UserLabel::insertDebugLabel(MachineBasicBlock *
MBB, SlotIndex Idx,
1778 LiveIntervals &LIS,
const TargetInstrInfo &
TII,
1782 ++NumInsertedDebugLabels;
1787void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
1788 const TargetInstrInfo &
TII,
1789 const TargetRegisterInfo &
TRI,
1794 for (LocMap::const_iterator
I = locInts.begin();
I.valid();) {
1795 SlotIndex
Start =
I.start();
1796 SlotIndex Stop =
I.stop();
1797 DbgVariableValue DbgValue =
I.value();
1799 SmallVector<bool> SpilledLocs;
1800 SmallVector<unsigned> LocSpillOffsets;
1801 for (
unsigned LocNo : DbgValue.loc_nos()) {
1803 !DbgValue.isUndef() ? SpillOffsets.
find(LocNo) : SpillOffsets.
end();
1804 bool Spilled = SpillIt != SpillOffsets.
end();
1806 LocSpillOffsets.
push_back(Spilled ? SpillIt->second : 0);
1812 if (trimmedDefs.count(Start))
1816 DbgValue.printLocNos(dbg));
1821 insertDebugValue(&*
MBB, Start, Stop, DbgValue, SpilledLocs, LocSpillOffsets,
1822 LIS,
TII,
TRI, BBSkipInstsMap);
1825 while (Stop > MBBEnd) {
1832 insertDebugValue(&*
MBB, Start, Stop, DbgValue, SpilledLocs,
1833 LocSpillOffsets, LIS,
TII,
TRI, BBSkipInstsMap);
1843void UserLabel::emitDebugLabel(LiveIntervals &LIS,
const TargetInstrInfo &
TII,
1849 insertDebugLabel(&*
MBB, loc, LIS,
TII, BBSkipInstsMap);
1855 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG VARIABLES **********\n");
1862 for (
auto &userValue : userValues) {
1864 userValue->rewriteLocations(*VRM, *MF, *
TII, *TRI, SpillOffsets);
1865 userValue->emitDebugValues(VRM, *LIS, *
TII, *TRI, SpillOffsets,
1868 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG LABELS **********\n");
1869 for (
auto &userLabel : userLabels) {
1871 userLabel->emitDebugLabel(*LIS, *
TII, BBSkipInstsMap);
1874 LLVM_DEBUG(
dbgs() <<
"********** EMITTING DEBUG PHIS **********\n");
1876 auto Slots = LIS->getSlotIndexes();
1877 for (
auto &It : PHIValToPos) {
1880 unsigned InstNum = It.first;
1881 auto Slot = It.second.SI;
1883 unsigned SubReg = It.second.SubReg;
1887 unsigned PhysReg = VRM->
getPhys(Reg);
1889 PhysReg = TRI->getSubReg(PhysReg,
SubReg);
1892 TII->get(TargetOpcode::DBG_PHI));
1893 Builder.addReg(PhysReg);
1894 Builder.addImm(InstNum);
1898 unsigned SpillSize, SpillOffset;
1900 unsigned regSizeInBits = TRI->getRegSizeInBits(*TRC);
1902 regSizeInBits = TRI->getSubRegIdxSize(
SubReg);
1908 TII->getStackSlotRange(TRC,
SubReg, SpillSize, SpillOffset, *MF);
1910 if (
Success && SpillOffset == 0) {
1912 TII->get(TargetOpcode::DBG_PHI));
1914 Builder.addImm(InstNum);
1918 Builder.addImm(regSizeInBits);
1923 <<
" has nonzero offset\n";
1929 MF->DebugPHIPositions.clear();
1931 LLVM_DEBUG(
dbgs() <<
"********** EMITTING INSTR REFERENCES **********\n");
1939 for (
auto *StashIt = StashedDebugInstrs.begin();
1940 StashIt != StashedDebugInstrs.end(); ++StashIt) {
1945 auto EmitInstsHere = [
this, &StashIt,
MBB, Idx,
1948 MBB->insert(InsertPos,
MI);
1952 auto NextItem = std::next(StashIt);
1953 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx == Idx) {
1954 assert(NextItem->MBB ==
MBB &&
"Instrs with same slot index should be"
1955 "in the same block");
1956 MBB->insert(InsertPos, NextItem->MI);
1958 NextItem = std::next(StashIt);
1964 if (Idx == Slots->getMBBStartIdx(
MBB)) {
1967 EmitInstsHere(InsertPos);
1971 if (
MachineInstr *Pos = Slots->getInstructionFromIndex(Idx)) {
1975 EmitInstsHere(PostDebug);
1980 for (; Idx < End; Idx = Slots->getNextNonNullIndex(Idx)) {
1981 Pos = Slots->getInstructionFromIndex(Idx);
1983 EmitInstsHere(Pos->getIterator());
1992 auto TermIt =
MBB->getFirstTerminator();
1993 EmitInstsHere(TermIt);
1999 BBSkipInstsMap.
clear();
2004 PImpl->emitDebugValues(VRM);
2007#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
Function Alias Analysis false
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
const HexagonInstrInfo * TII
This file implements a coalescing interval map for small objects.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
static void printExtendedName(raw_ostream &OS, const DINode *Node, const DILocation *DL)
static MachineBasicBlock::iterator findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS, BlockSkipInstsMap &BBSkipInstsMap)
Find an iterator for inserting a DBG_VALUE instruction.
static MachineBasicBlock::iterator findNextInsertLocation(MachineBasicBlock *MBB, MachineBasicBlock::iterator I, SlotIndex StopIdx, ArrayRef< MachineOperand > LocMOs, LiveIntervals &LIS, const TargetRegisterInfo &TRI)
Find an iterator for inserting the next DBG_VALUE instruction (or end if no more insert locations fou...
DenseMap< MachineBasicBlock *, MachineBasicBlock::iterator > BlockSkipInstsMap
Cache to save the location where it can be used as the starting position as input for calling Machine...
IntervalMap< SlotIndex, DbgVariableValue, 4 > LocMap
Map of where a user value is live to that value.
static cl::opt< bool > EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden)
static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS, const LLVMContext &Ctx)
DenseMap< unsigned, unsigned > SpillOffsetMap
Map of stack slot offsets for spilled locations.
static void removeDebugInstrs(MachineFunction &mf)
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
static DebugLoc getDebugLoc(MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
Return the first DebugLoc that has line number information, given a range of instructions.
static bool isUndef(const MachineInstr &MI)
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Promote Memory to Register
static MCRegister getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
MachineInstr unsigned OpIdx
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
SI Optimize VGPR LiveRange
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Class recording the (high level) value of a variable.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - Get the array size.
static LLVM_ABI void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
static LLVM_ABI DIExpression * appendOpsToArg(const DIExpression *Expr, ArrayRef< uint64_t > Ops, unsigned ArgNo, bool StackValue=false)
Create a copy of Expr by appending the given list of Ops to each instance of the operand DW_OP_LLVM_a...
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static LLVM_ABI DIExpression * replaceArg(const DIExpression *Expr, uint64_t OldArg, uint64_t NewArg)
Create a copy of Expr with each instance of DW_OP_LLVM_arg, \p OldArg replaced with DW_OP_LLVM_arg,...
static LLVM_ABI std::optional< DIExpression * > createFragmentExpression(const DIExpression *Expr, unsigned OffsetInBits, unsigned SizeInBits)
Create a DIExpression to describe one part of an aggregate variable that is fragmented across multipl...
static LLVM_ABI DIExpression * prepend(const DIExpression *Expr, uint8_t Flags, int64_t Offset=0)
Prepend DIExpr with a deref and offset operation and optionally turn it into a stack value or/and an ...
Tagged DWARF-like metadata node.
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
DISubprogram * getSubprogram() const
Get the attached subprogram.
const_iterator begin() const
typename Sizer::Allocator Allocator
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end().
This is an important class for using LLVM in a threaded context.
This class provides interface to collect and use lexical scoping information from machine instruction...
Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
LiveDebugVariablesWrapperLegacy()
bool runOnMachineFunction(MachineFunction &) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &) const override
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
LDVImpl(LiveIntervals *LIS)
void print(raw_ostream &)
void splitRegister(Register OldReg, ArrayRef< Register > NewRegs)
Replace all references to OldReg with NewRegs.
bool runOnMachineFunction(MachineFunction &mf, bool InstrRef)
void mapVirtReg(Register VirtReg, UserValue *EC)
Map virtual register to an equivalence class.
void clear()
Release all memory.
void emitDebugValues(VirtRegMap *VRM)
Recreate DBG_VALUE instruction from data structures.
void splitPHIRegister(Register OldReg, ArrayRef< Register > NewRegs)
Replace any PHI referring to OldReg with its corresponding NewReg, if present.
void dump() const
dump - Print data structures to dbgs().
void splitRegister(Register OldReg, ArrayRef< Register > NewRegs, LiveIntervals &LIS)
splitRegister - Move any user variables in OldReg to the live ranges in NewRegs where they are live.
LiveDebugVariables()
Implementation of the LiveDebugVariables pass.
void print(raw_ostream &OS) const
void analyze(MachineFunction &MF, LiveIntervals *LIS)
void emitDebugValues(VirtRegMap *VRM)
emitDebugValues - Emit new DBG_VALUE instructions reflecting the changes that happened during registe...
bool invalidate(MachineFunction &MF, const PreservedAnalyses &PA, MachineFunctionAnalysisManager::Invalidator &Inv)
LiveInterval - This class represents the liveness of a register, or stack slot.
bool hasInterval(Register Reg) const
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
SlotIndexes * getSlotIndexes() const
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
LiveInterval & getInterval(Register Reg)
bool isNotInMIMap(const MachineInstr &Instr) const
Returns true if the specified machine instr has been removed or was never entered in the map.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
Segments::iterator iterator
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position,...
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
LLVM_ABI iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
LLVMContext & getContext() const
An RAII based helper class to modify MachineFunctionProperties when running pass.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
MachineFunctionPass(char &ID)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Location of a PHI instruction that is also a debug-info variable value, for the duration of register ...
bool useDebugInstrRef() const
Returns true if the function's variable locations are tracked with instruction referencing.
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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
Representation of each machine instruction.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsDebug(bool Val=true)
Register getReg() const
getReg - Returns the register number.
LLVM_ABI bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static MachineOperand CreateFI(int Idx)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
This class implements a map that also provides access to all stored values in a deterministic order.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
AnalysisType & getAnalysis() const
getAnalysis<AnalysisType>() - This function is used by subclasses to get to the analysis information ...
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.
PreservedAnalysisChecker getChecker() const
Build a checker for this PreservedAnalyses and the specified analysis type.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
SlotIndex - An opaque wrapper around machine indexes.
SlotIndex getNextIndex() const
Returns the next index.
static bool isEarlierEqualInstr(SlotIndex A, SlotIndex B)
Return true if A refers to the same instruction as B or an earlier one.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
SlotIndex getPrevIndex() const
Returns the previous index.
SlotIndex getNextSlot() const
Returns the next slot in the index list.
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
SlotIndex getIndexBefore(const MachineInstr &MI) const
getIndexBefore - Returns the index of the last indexed instruction before MI, or the start index of i...
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr bool empty() const
empty - Check if the string is empty.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
unsigned id
The ID number of this value.
SlotIndex def
The index of the defining instruction.
int getStackSlot(Register virtReg) const
returns the stack slot mapped to the specified virtual register
MachineFunction & getMachineFunction() const
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
bool isAssignedReg(Register virtReg) const
returns true if the specified virtual register is not mapped to a stack slot or rematerialized.
static constexpr int NO_STACK_SLOT
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
bool operator!=(uint64_t V1, const APInt &V2)
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
This is used to track range of instructions with identical lexical scope.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
@ Success
The lock was released successfully.
DWARFExpression::Operation Op
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in 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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
A special type used by analysis passes to provide an address that identifies that particular analysis...