48#include "llvm/Config/llvm-config.h"
68#define DEBUG_TYPE "livedebugvars"
74STATISTIC(NumInsertedDebugValues,
"Number of DBG_VALUEs inserted");
75STATISTIC(NumInsertedDebugLabels,
"Number of DBG_LABELs inserted");
80 "Debug Variable Analysis",
false,
false)
102class DbgVariableValue {
106 : WasIndirect(WasIndirect), WasList(WasList),
Expression(&Expr) {
107 assert(!(WasIndirect && WasList) &&
108 "DBG_VALUE_LISTs should not be indirect.");
110 for (
unsigned LocNo : NewLocs) {
111 auto It =
find(LocNoVec, LocNo);
112 if (It == LocNoVec.
end())
117 unsigned OpIdx = LocNoVec.
size();
118 unsigned DuplicatingIdx = std::distance(LocNoVec.
begin(), It);
129 if (LocNoVec.
size() < 64) {
130 LocNoCount = LocNoVec.
size();
131 if (LocNoCount > 0) {
132 LocNos = std::make_unique<unsigned[]>(LocNoCount);
133 std::copy(LocNoVec.
begin(), LocNoVec.
end(), loc_nos_begin());
137 "locations, dropping...\n");
142 DIExpression::get(Expr.
getContext(), {dwarf::DW_OP_LLVM_arg, 0});
146 FragmentInfoOpt->SizeInBits);
147 LocNos = std::make_unique<unsigned[]>(LocNoCount);
152 DbgVariableValue() : LocNoCount(0), WasIndirect(
false), WasList(
false) {}
153 DbgVariableValue(
const DbgVariableValue &
Other)
154 : LocNoCount(
Other.LocNoCount), WasIndirect(
Other.getWasIndirect()),
156 if (
Other.getLocNoCount()) {
157 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
158 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
162 DbgVariableValue &operator=(
const DbgVariableValue &
Other) {
165 if (
Other.getLocNoCount()) {
166 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
167 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
171 LocNoCount =
Other.getLocNoCount();
172 WasIndirect =
Other.getWasIndirect();
173 WasList =
Other.getWasList();
179 uint8_t getLocNoCount()
const {
return LocNoCount; }
180 bool containsLocNo(
unsigned LocNo)
const {
183 bool getWasIndirect()
const {
return WasIndirect; }
184 bool getWasList()
const {
return WasList; }
187 DbgVariableValue decrementLocNosAfterPivot(
unsigned Pivot)
const {
189 for (
unsigned LocNo : loc_nos())
192 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
197 for (
unsigned LocNo : loc_nos())
201 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
204 DbgVariableValue changeLocNo(
unsigned OldLocNo,
unsigned NewLocNo)
const {
206 NewLocNos.
assign(loc_nos_begin(), loc_nos_end());
207 auto OldLocIt =
find(NewLocNos, OldLocNo);
208 assert(OldLocIt != NewLocNos.
end() &&
"Old location must be present.");
209 *OldLocIt = NewLocNo;
210 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
213 bool hasLocNoGreaterThan(
unsigned LocNo)
const {
215 [LocNo](
unsigned ThisLocNo) {
return ThisLocNo > LocNo; });
219 for (
const unsigned &Loc : loc_nos())
220 OS << (&Loc == loc_nos_begin() ?
" " :
", ") << Loc;
224 const DbgVariableValue &
RHS) {
225 if (std::tie(
LHS.LocNoCount,
LHS.WasIndirect,
LHS.WasList,
227 std::tie(
RHS.LocNoCount,
RHS.WasIndirect,
RHS.WasList,
RHS.Expression))
229 return std::equal(
LHS.loc_nos_begin(),
LHS.loc_nos_end(),
230 RHS.loc_nos_begin());
234 const DbgVariableValue &
RHS) {
238 unsigned *loc_nos_begin() {
return LocNos.get(); }
239 const unsigned *loc_nos_begin()
const {
return LocNos.get(); }
240 unsigned *loc_nos_end() {
return LocNos.get() + LocNoCount; }
241 const unsigned *loc_nos_end()
const {
return LocNos.get() + LocNoCount; }
252 std::unique_ptr<unsigned[]> LocNos;
253 uint8_t LocNoCount : 6;
254 bool WasIndirect : 1;
290 const std::optional<DIExpression::FragmentInfo> Fragment;
294 UserValue *next =
nullptr;
323 std::optional<DIExpression::FragmentInfo> Fragment,
DebugLoc L,
325 : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(
this),
329 UserValue *getLeader() {
330 UserValue *l = leader;
331 while (l != l->leader)
337 UserValue *getNext()
const {
return next; }
340 static UserValue *
merge(UserValue *L1, UserValue *L2) {
341 L2 = L2->getLeader();
344 L1 = L1->getLeader();
354 End->next = L1->next;
370 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
371 if (locations[i].
isReg() &&
373 locations[i].getSubReg() == LocMO.
getSubReg())
376 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
381 locations.
back().clearParent();
383 if (locations.
back().isReg()) {
384 if (locations.
back().isDef())
385 locations.
back().setIsDead(
false);
386 locations.
back().setIsUse();
388 return locations.
size() - 1;
393 void removeLocationIfUnused(
unsigned LocNo) {
396 const DbgVariableValue &
DbgValue =
I.value();
404 const DbgVariableValue &
DbgValue =
I.value();
405 if (
DbgValue.hasLocNoGreaterThan(LocNo))
406 I.setValueUnchecked(
DbgValue.decrementLocNosAfterPivot(LocNo));
411 void mapVirtRegs(
LDVImpl *LDV);
419 DbgVariableValue
DbgValue(Locs, IsIndirect, IsList, Expr);
422 if (!
I.valid() ||
I.start() !=
Idx)
446 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
460 void addDefsFromCopies(
513 : Label(label), dl(std::move(L)), loc(
Idx) {}
518 return Label == L && dl->getInlinedAt() == IA && loc ==
Index;
547 std::map<unsigned, PHIValPos> PHIValToPos;
566 bool EmitDone =
false;
569 bool ModifiedMF =
false;
579 VRMap virtRegToEqClass;
587 std::optional<DIExpression::FragmentInfo> Fragment,
591 UserValue *lookupVirtReg(
Register VirtReg);
634 void computeIntervals();
646 StashedDebugInstrs.
clear();
649 virtRegToEqClass.clear();
652 assert((!ModifiedMF || EmitDone) &&
653 "Dbg values are not emitted in LDV");
659 void mapVirtReg(
Register VirtReg, UserValue *EC);
676#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
682 auto *Scope = cast<DIScope>(
DL.getScope());
684 CommentOS << Scope->getFilename();
685 CommentOS <<
':' <<
DL.getLine();
686 if (
DL.getCol() != 0)
687 CommentOS <<
':' <<
DL.getCol();
703 if (
const auto *V = dyn_cast<const DILocalVariable>(
Node)) {
706 }
else if (
const auto *L = dyn_cast<const DILabel>(
Node)) {
712 OS << Res <<
"," << Line;
713 auto *InlinedAt =
DL ?
DL->getInlinedAt() :
nullptr;
715 if (
DebugLoc InlinedAtDL = InlinedAt) {
729 OS <<
" [" <<
I.start() <<
';' <<
I.stop() <<
"):";
730 if (
I.value().isUndef())
733 I.value().printLocNos(
OS);
734 if (
I.value().getWasIndirect())
736 else if (
I.value().getWasList())
740 for (
unsigned i = 0, e = locations.size(); i != e; ++i) {
741 OS <<
" Loc" << i <<
'=';
742 locations[i].print(
OS,
TRI);
757 OS <<
"********** DEBUG VARIABLES **********\n";
758 for (
auto &userValue : userValues)
759 userValue->print(
OS,
TRI);
760 OS <<
"********** DEBUG LABELS **********\n";
761 for (
auto &userLabel : userLabels)
762 userLabel->print(
OS,
TRI);
766void UserValue::mapVirtRegs(
LDVImpl *LDV) {
768 if (MO.isReg() && MO.getReg().isVirtual())
769 LDV->mapVirtReg(MO.getReg(),
this);
774 std::optional<DIExpression::FragmentInfo> Fragment,
779 UserValue *&UV = userVarMap[
ID];
781 userValues.push_back(
782 std::make_unique<UserValue>(Var, Fragment,
DL,
allocator));
783 UV = userValues.back().get();
788void LDVImpl::mapVirtReg(
Register VirtReg, UserValue *EC) {
790 UserValue *&Leader = virtRegToEqClass[VirtReg];
791 Leader = UserValue::merge(Leader, EC);
794UserValue *LDVImpl::lookupVirtReg(
Register VirtReg) {
795 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
796 return UV->getLeader();
803 if (!
MI.isDebugValue()) {
807 if (!
MI.getDebugVariableOp().isMetadata()) {
808 LLVM_DEBUG(
dbgs() <<
"Can't handle DBG_VALUE* with invalid variable: "
812 if (
MI.isNonListDebugValue() &&
813 (
MI.getNumOperands() != 4 ||
814 !(
MI.getDebugOffset().isImm() ||
MI.getDebugOffset().isReg()))) {
823 bool Discard =
false;
825 if (
Op.isReg() &&
Op.getReg().isVirtual()) {
827 if (!LIS->hasInterval(Reg)) {
851 bool IsIndirect =
MI.isDebugOffsetImm();
853 assert(
MI.getDebugOffset().getImm() == 0 &&
854 "DBG_VALUE with nonzero offset");
855 bool IsList =
MI.isDebugValueList();
862 MI.debug_operands().end()),
863 IsIndirect, IsList, *Expr);
871 UV->addDef(
Idx, UndefMOs,
false, IsList, *Expr);
878 assert(
MI.isDebugValueLike() ||
MI.isDebugPHI());
882 if (
MI.isDebugValueLike())
885 return MO.isReg() && MO.getReg().isVirtual();
887 "MIs should not refer to Virtual Registers in InstrRef mode.");
890 auto NextInst = std::next(
MI.getIterator());
891 auto *
MBB =
MI.getParent();
892 MI.removeFromParent();
893 StashedDebugInstrs.push_back({&
MI,
Idx,
MBB});
899 if (
MI.getNumOperands() != 1 || !
MI.getOperand(0).isMetadata()) {
908 for (
auto const &L : userLabels) {
909 if (
L->matches(Label,
DL->getInlinedAt(),
Idx)) {
915 userLabels.push_back(std::make_unique<UserLabel>(Label,
DL,
Idx));
921 bool Changed =
false;
927 if (!
MBBI->isDebugOrPseudoInstr()) {
935 ? LIS->getMBBStartIdx(&
MBB)
936 : LIS->getInstructionIndex(*std::prev(
MBBI)).getRegSlot();
942 if (InstrRef && (
MBBI->isNonListDebugValue() ||
MBBI->isDebugPHI() ||
943 MBBI->isDebugRef())) {
948 }
else if ((
MBBI->isDebugValue() && handleDebugValue(*
MBBI,
Idx)) ||
949 (
MBBI->isDebugLabel() && handleDebugLabel(*
MBBI,
Idx))) {
954 }
while (
MBBI != MBBE &&
MBBI->isDebugOrPseudoInstr());
960void UserValue::extendDef(
962 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
972 for (
auto &LII : LiveIntervalInfo) {
974 assert(LR && LII.second.second &&
"Missing range info for Idx.");
976 assert(Segment && Segment->
valno == LII.second.second &&
977 "Invalid VNInfo for Idx given?");
978 if (Segment->
end < Stop) {
980 Kills = {Stop, {LII.first}};
981 }
else if (Segment->
end == Stop && Kills) {
984 Kills->second.push_back(LII.first);
989 if (
I.valid() &&
I.start() <= Start) {
991 Start = Start.getNextSlot();
992 if (
I.value() !=
DbgValue ||
I.stop() != Start) {
994 Kills = std::nullopt;
1002 if (
I.valid() &&
I.start() < Stop) {
1005 Kills = std::nullopt;
1009 DbgVariableValue ExtDbgValue(
DbgValue);
1010 I.insert(Start, Stop, std::move(ExtDbgValue));
1014void UserValue::addDefsFromCopies(
1022 [](
auto LocI) {
return !LocI.second->reg().isVirtual(); }))
1029 for (
auto &LocInterval : LocIntervals) {
1030 unsigned LocNo = LocInterval.first;
1037 Register DstReg =
MI->getOperand(0).getReg();
1057 assert(DstVNI && DstVNI->
def ==
Idx.getRegSlot() &&
"Bad copy value");
1058 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
1062 if (CopyValues.
empty())
1066 for (
auto &LocInterval : LocIntervals)
1067 LLVM_DEBUG(
dbgs() <<
"Got " << CopyValues[LocInterval.first].size()
1068 <<
" copies of " << *LocInterval.second <<
'\n');
1074 if (
I.valid() &&
I.start() <= KilledAt)
1076 DbgVariableValue NewValue(
DbgValue);
1077 for (
auto &LocInterval : LocIntervals) {
1078 unsigned LocNo = LocInterval.first;
1079 bool FoundCopy =
false;
1080 for (
auto &LIAndVNI : CopyValues[LocNo]) {
1082 const VNInfo *DstVNI = LIAndVNI.second;
1085 LLVM_DEBUG(
dbgs() <<
"Kill at " << KilledAt <<
" covered by valno #"
1086 << DstVNI->
id <<
" in " << *DstLI <<
'\n');
1088 assert(CopyMI && CopyMI->
isCopy() &&
"Bad copy value");
1089 unsigned NewLocNo = getLocationNo(CopyMI->
getOperand(0));
1090 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
1100 NewDefs.push_back(std::make_pair(KilledAt, NewValue));
1110 if (!
I.value().isUndef())
1111 Defs.
push_back(std::make_pair(
I.start(),
I.value()));
1114 for (
unsigned i = 0; i != Defs.
size(); ++i) {
1116 DbgVariableValue
DbgValue = Defs[i].second;
1119 bool ShouldExtendDef =
false;
1120 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1123 ShouldExtendDef |= !LocMO.
isReg();
1126 ShouldExtendDef =
true;
1128 const VNInfo *VNI =
nullptr;
1134 LIs[LocNo] = {LI, VNI};
1136 if (ShouldExtendDef) {
1137 std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> Kills;
1142 bool AnySubreg =
false;
1143 for (
unsigned LocNo : Kills->second) {
1150 KilledLocIntervals.
push_back({LocNo, LI});
1162 addDefsFromCopies(
DbgValue, KilledLocIntervals, Kills->first, Defs,
1182 if (!dl.getInlinedAt())
1202 if (
Range.first ==
Range.first->getParent()->begin())
1207 if (PrevEnd &&
I.start() < PrevEnd) {
1213 I.setStopUnchecked(PrevEnd);
1224 I.advanceTo(RStart);
1228 if (
I.start() < RStart) {
1230 I.setStartUnchecked(RStart);
1232 trimmedDefs.insert(RStart);
1249 if (PrevEnd &&
I.start() < PrevEnd)
1250 I.setStopUnchecked(PrevEnd);
1253void LDVImpl::computeIntervals() {
1257 for (
const auto &UV : userValues) {
1258 UV->computeIntervals(MF->getRegInfo(), *
TRI, *LIS, LS);
1259 UV->mapVirtRegs(
this);
1263bool LDVImpl::runOnMachineFunction(
MachineFunction &mf,
bool InstrRef) {
1268 LLVM_DEBUG(
dbgs() <<
"********** COMPUTING LIVE DEBUG VARIABLES: "
1269 << mf.
getName() <<
" **********\n");
1271 bool Changed = collectDebugValues(mf, InstrRef);
1278 for (
const auto &PHIIt : MF->DebugPHIPositions) {
1282 unsigned SubReg = Position.SubReg;
1285 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
1286 RegToPHIIdx[
Reg].push_back(PHIIt.first);
1289 ModifiedMF = Changed;
1296 if (
MI.isDebugInstr())
1315 return static_cast<LDVImpl *
>(pImpl)->runOnMachineFunction(mf, InstrRef);
1318void LiveDebugVariables::releaseMemory() {
1325 delete static_cast<LDVImpl*
>(pImpl);
1336 dbgs() <<
"Splitting Loc" << OldLocNo <<
'\t';
1339 bool DidChange =
false;
1352 if (!LocMapI.
valid())
1356 while (LocMapI.
valid() && LII != LIE) {
1363 if (LocMapI.
value().containsLocNo(OldLocNo) &&
1364 LII->start < LocMapI.
stop()) {
1368 MO.
setSubReg(locations[OldLocNo].getSubReg());
1369 NewLocNo = getLocationNo(MO);
1375 DbgVariableValue OldDbgValue = LocMapI.
value();
1378 if (LStart < LII->start)
1380 if (LStop > LII->end)
1384 LocMapI.
setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
1387 if (LStart < LocMapI.
start()) {
1388 LocMapI.
insert(LStart, LocMapI.
start(), OldDbgValue);
1390 assert(LocMapI.
valid() &&
"Unexpected coalescing");
1392 if (LStop > LocMapI.
stop()) {
1394 LocMapI.
insert(LII->end, LStop, OldDbgValue);
1400 if (LII->end < LocMapI.
stop()) {
1406 if (!LocMapI.
valid())
1423 removeLocationIfUnused(OldLocNo);
1426 dbgs() <<
"Split result: \t";
1435 bool DidChange =
false;
1438 for (
unsigned i = locations.size(); i ; --i) {
1439 unsigned LocNo = i-1;
1443 DidChange |= splitLocation(LocNo, NewRegs, LIS);
1449 auto RegIt = RegToPHIIdx.find(OldReg);
1450 if (RegIt == RegToPHIIdx.end())
1453 std::vector<std::pair<Register, unsigned>> NewRegIdxes;
1455 for (
unsigned InstrID : RegIt->second) {
1456 auto PHIIt = PHIValToPos.find(InstrID);
1457 assert(PHIIt != PHIValToPos.end());
1459 assert(OldReg == PHIIt->second.Reg);
1462 for (
auto NewReg : NewRegs) {
1464 auto LII = LI.
find(Slot);
1465 if (LII != LI.
end() && LII->start <= Slot) {
1467 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
1469 PHIIt->second.Reg = NewReg;
1481 RegToPHIIdx.erase(RegIt);
1482 for (
auto &RegAndInstr : NewRegIdxes)
1483 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
1488 splitPHIRegister(OldReg, NewRegs);
1492 bool DidChange =
false;
1493 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
1494 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
1500 UserValue *UV = lookupVirtReg(OldReg);
1502 mapVirtReg(NewReg, UV);
1525 for (
unsigned I = 0, E = locations.size();
I != E; ++
I) {
1526 bool Spilled =
false;
1527 unsigned SpillOffset = 0;
1559 auto InsertResult = NewLocations.
insert({Loc, {Spilled, SpillOffset}});
1560 unsigned NewLocNo = std::distance(NewLocations.
begin(), InsertResult.first);
1561 LocNoMap[
I] = NewLocNo;
1566 SpillOffsets.
clear();
1567 for (
auto &Pair : NewLocations) {
1569 unsigned SpillOffset;
1570 std::tie(Spilled, SpillOffset) = Pair.second;
1571 locations.push_back(Pair.first);
1573 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
1574 SpillOffsets[NewLocNo] = SpillOffset;
1583 I.setValueUnchecked(
I.value().remapLocNos(LocNoMap));
1584 I.setStart(
I.start());
1593 Idx =
Idx.getBaseIndex();
1615 auto MapIt = BBSkipInstsMap.
find(
MBB);
1616 if (MapIt == BBSkipInstsMap.
end())
1619 BeginIt = std::next(MapIt->second);
1622 BBSkipInstsMap[
MBB] = std::prev(
I);
1625 Idx =
Idx.getPrevIndex();
1647 while (
I !=
MBB->
end() && !
I->isTerminator()) {
1652 return I->definesRegister(Reg, &
TRI);
1655 return std::next(
I);
1670 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
1684 for (
unsigned LocNo :
DbgValue.loc_nos())
1688 ++NumInsertedDebugValues;
1690 assert(cast<DILocalVariable>(Variable)
1692 "Expected inlined-at fields to agree");
1699 bool IsIndirect =
DbgValue.getWasIndirect();
1700 bool IsList =
DbgValue.getWasList();
1701 for (
unsigned I = 0, E = LocSpills.
size();
I != E; ++
I) {
1717 assert((!LocSpills[
I] || MOs[
I].isFI()) &&
1718 "a spilled location must be a frame index");
1721 unsigned DbgValueOpcode =
1722 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
1738 ++NumInsertedDebugLabels;
1757 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1760 bool Spilled = SpillIt != SpillOffsets.
end();
1762 LocSpillOffsets.
push_back(Spilled ? SpillIt->second : 0);
1768 if (trimmedDefs.count(Start))
1769 Start = Start.getPrevIndex();
1771 LLVM_DEBUG(
auto &dbg =
dbgs(); dbg <<
"\t[" << Start <<
';' << Stop <<
"):";
1777 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs, LocSpillOffsets,
1778 LIS,
TII,
TRI, BBSkipInstsMap);
1781 while (Stop > MBBEnd) {
1788 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs,
1789 LocSpillOffsets, LIS,
TII,
TRI, BBSkipInstsMap);
1805 insertDebugLabel(&*
MBB, loc, LIS,
TII, BBSkipInstsMap);
1810void LDVImpl::emitDebugValues(
VirtRegMap *VRM) {
1811 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG VARIABLES **********\n");
1818 for (
auto &userValue : userValues) {
1820 userValue->rewriteLocations(*VRM, *MF, *
TII, *
TRI, SpillOffsets);
1821 userValue->emitDebugValues(VRM, *LIS, *
TII, *
TRI, SpillOffsets,
1824 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG LABELS **********\n");
1825 for (
auto &userLabel : userLabels) {
1827 userLabel->emitDebugLabel(*LIS, *
TII, BBSkipInstsMap);
1830 LLVM_DEBUG(
dbgs() <<
"********** EMITTING DEBUG PHIS **********\n");
1833 for (
auto &It : PHIValToPos) {
1836 unsigned InstNum = It.first;
1837 auto Slot = It.second.SI;
1839 unsigned SubReg = It.second.SubReg;
1844 unsigned PhysReg = VRM->
getPhys(Reg);
1846 PhysReg =
TRI->getSubReg(PhysReg,
SubReg);
1849 TII->get(TargetOpcode::DBG_PHI));
1850 Builder.addReg(PhysReg);
1851 Builder.addImm(InstNum);
1855 unsigned SpillSize, SpillOffset;
1857 unsigned regSizeInBits =
TRI->getRegSizeInBits(*TRC);
1859 regSizeInBits =
TRI->getSubRegIdxSize(
SubReg);
1865 TII->getStackSlotRange(TRC,
SubReg, SpillSize, SpillOffset, *MF);
1867 if (
Success && SpillOffset == 0) {
1869 TII->get(TargetOpcode::DBG_PHI));
1871 Builder.addImm(InstNum);
1875 Builder.addImm(regSizeInBits);
1879 if (SpillOffset != 0) {
1880 dbgs() <<
"DBG_PHI for Vreg " <<
Reg <<
" subreg " <<
SubReg <<
1881 " has nonzero offset\n";
1890 LLVM_DEBUG(
dbgs() <<
"********** EMITTING INSTR REFERENCES **********\n");
1898 for (
auto *StashIt = StashedDebugInstrs.begin();
1899 StashIt != StashedDebugInstrs.end(); ++StashIt) {
1904 auto EmitInstsHere = [
this, &StashIt,
MBB,
Idx,
1911 auto NextItem = std::next(StashIt);
1912 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx ==
Idx) {
1913 assert(NextItem->MBB ==
MBB &&
"Instrs with same slot index should be"
1914 "in the same block");
1917 NextItem = std::next(StashIt);
1926 EmitInstsHere(InsertPos);
1932 auto PostDebug = std::next(Pos->getIterator());
1934 EmitInstsHere(PostDebug);
1942 EmitInstsHere(Pos->getIterator());
1952 EmitInstsHere(TermIt);
1958 BBSkipInstsMap.
clear();
1966#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
static void clear(coro::Shape &Shape)
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
static ManagedStatic< cl::opt< bool, true >, CreateDebug > Debug
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
std::optional< std::vector< StOtherPiece > > Other
const HexagonInstrInfo * TII
static bool isUndef(ArrayRef< int > Mask)
This file implements a coalescing interval map for small objects.
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...
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)
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 found DebugLoc that has a DILocation, given a range of instructions.
unsigned const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
static bool isReg(const MCInst &MI, unsigned OpNo)
modulo schedule Modulo Schedule test pass
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)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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 void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
static 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 std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static 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 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 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.
This class represents an Operation in the Expression.
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
Class representing an expression and its matching format.
DISubprogram * getSubprogram() const
Get the attached subprogram.
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
const KeyT & stop() const
stop - Return the end of the current interval.
bool valid() const
valid - Return true if the current position is valid, false for end().
const KeyT & start() const
start - Return the beginning of the current interval.
const ValT & value() const
value - Return the mapped value at the current interval.
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps.
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.
LexicalScope - This class is used to track scope information.
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
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.
void emitDebugValues(VirtRegMap *VRM)
emitDebugValues - Emit new DBG_VALUE instructions reflecting the changes that happened during registe...
~LiveDebugVariables() override
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
Result of a LiveRange query.
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
This class represents the liveness of a register, stack slot, etc.
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.
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
LLVMContext & getContext() const
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
iterator SkipPHIsLabelsAndDebug(iterator I, Register Reg=Register(), bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
instr_iterator instr_end()
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Analysis pass which computes a MachineDominatorTree.
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.
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.
DenseMap< unsigned, DebugPHIRegallocPos > DebugPHIPositions
Map of debug instruction numbers to the position of their PHI instructions during register allocation...
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.
void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void substPhysReg(MCRegister Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
void setIsDebug(bool Val=true)
Register getReg() const
getReg - Returns the register number.
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)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static constexpr bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical 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 getNextSlot() const
Returns the next slot in the index list.
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
SlotIndex getNextNonNullIndex(SlotIndex Index)
Returns the next non-null index, if one exists.
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...
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
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
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
VNInfo - Value Number 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 isAssignedReg(Register virtReg) const
returns true if the specified virtual register is not mapped to a stack slot or rematerialized.
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.
Reg
All possible values of the reg field in the ModR/M byte.
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.
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...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
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.
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.
void initializeLiveDebugVariablesPass(PassRegistry &)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
This represents a simple continuous liveness interval for a value.