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)
106class DbgVariableValue {
110 : WasIndirect(WasIndirect), WasList(WasList),
Expression(&Expr) {
111 assert(!(WasIndirect && WasList) &&
112 "DBG_VALUE_LISTs should not be indirect.");
114 for (
unsigned LocNo : NewLocs) {
115 auto It =
find(LocNoVec, LocNo);
116 if (It == LocNoVec.
end())
122 unsigned DuplicatingIdx = std::distance(LocNoVec.
begin(), It);
133 if (LocNoVec.
size() < 64) {
134 LocNoCount = LocNoVec.
size();
135 if (LocNoCount > 0) {
136 LocNos = std::make_unique<unsigned[]>(LocNoCount);
141 "locations, dropping...\n");
146 DIExpression::get(Expr.
getContext(), {dwarf::DW_OP_LLVM_arg, 0});
150 FragmentInfoOpt->SizeInBits);
151 LocNos = std::make_unique<unsigned[]>(LocNoCount);
156 DbgVariableValue() : LocNoCount(0), WasIndirect(
false), WasList(
false) {}
157 DbgVariableValue(
const DbgVariableValue &
Other)
158 : LocNoCount(
Other.LocNoCount), WasIndirect(
Other.getWasIndirect()),
160 if (
Other.getLocNoCount()) {
161 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
162 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
166 DbgVariableValue &operator=(
const DbgVariableValue &
Other) {
169 if (
Other.getLocNoCount()) {
170 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
171 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
175 LocNoCount =
Other.getLocNoCount();
176 WasIndirect =
Other.getWasIndirect();
177 WasList =
Other.getWasList();
183 uint8_t getLocNoCount()
const {
return LocNoCount; }
184 bool containsLocNo(
unsigned LocNo)
const {
187 bool getWasIndirect()
const {
return WasIndirect; }
188 bool getWasList()
const {
return WasList; }
191 DbgVariableValue decrementLocNosAfterPivot(
unsigned Pivot)
const {
193 for (
unsigned LocNo : loc_nos())
196 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
201 for (
unsigned LocNo : loc_nos())
205 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
208 DbgVariableValue changeLocNo(
unsigned OldLocNo,
unsigned NewLocNo)
const {
210 NewLocNos.
assign(loc_nos_begin(), loc_nos_end());
211 auto OldLocIt =
find(NewLocNos, OldLocNo);
212 assert(OldLocIt != NewLocNos.
end() &&
"Old location must be present.");
213 *OldLocIt = NewLocNo;
214 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
217 bool hasLocNoGreaterThan(
unsigned LocNo)
const {
219 [LocNo](
unsigned ThisLocNo) {
return ThisLocNo > LocNo; });
223 for (
const unsigned &Loc : loc_nos())
224 OS << (&Loc == loc_nos_begin() ?
" " :
", ") << Loc;
228 const DbgVariableValue &
RHS) {
229 if (std::tie(
LHS.LocNoCount,
LHS.WasIndirect,
LHS.WasList,
231 std::tie(
RHS.LocNoCount,
RHS.WasIndirect,
RHS.WasList,
RHS.Expression))
233 return std::equal(
LHS.loc_nos_begin(),
LHS.loc_nos_end(),
234 RHS.loc_nos_begin());
238 const DbgVariableValue &
RHS) {
242 unsigned *loc_nos_begin() {
return LocNos.get(); }
243 const unsigned *loc_nos_begin()
const {
return LocNos.get(); }
244 unsigned *loc_nos_end() {
return LocNos.get() + LocNoCount; }
245 const unsigned *loc_nos_end()
const {
return LocNos.get() + LocNoCount; }
256 std::unique_ptr<unsigned[]> LocNos;
258 bool WasIndirect : 1;
294 const std::optional<DIExpression::FragmentInfo> Fragment;
298 UserValue *next =
nullptr;
327 std::optional<DIExpression::FragmentInfo> Fragment,
DebugLoc L,
329 : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(
this),
333 UserValue *getLeader() {
334 UserValue *l = leader;
335 while (l != l->leader)
341 UserValue *getNext()
const {
return next; }
344 static UserValue *
merge(UserValue *L1, UserValue *L2) {
345 L2 = L2->getLeader();
348 L1 = L1->getLeader();
358 End->next = L1->next;
374 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
375 if (locations[i].
isReg() &&
377 locations[i].getSubReg() == LocMO.
getSubReg())
380 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
385 locations.
back().clearParent();
387 if (locations.
back().isReg()) {
388 if (locations.
back().isDef())
389 locations.
back().setIsDead(
false);
390 locations.
back().setIsUse();
392 return locations.
size() - 1;
397 void removeLocationIfUnused(
unsigned LocNo) {
400 const DbgVariableValue &
DbgValue =
I.value();
408 const DbgVariableValue &
DbgValue =
I.value();
409 if (
DbgValue.hasLocNoGreaterThan(LocNo))
410 I.setValueUnchecked(
DbgValue.decrementLocNosAfterPivot(LocNo));
415 void mapVirtRegs(
LDVImpl *LDV);
423 DbgVariableValue
DbgValue(Locs, IsIndirect, IsList, Expr);
426 if (!
I.valid() ||
I.start() !=
Idx)
450 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
464 void addDefsFromCopies(
517 : Label(label), dl(std::move(L)), loc(
Idx) {}
522 return Label == L && dl->getInlinedAt() == IA && loc ==
Index;
553 std::map<unsigned, PHIValPos> PHIValToPos;
572 bool EmitDone =
false;
575 bool ModifiedMF =
false;
585 VRMap virtRegToEqClass;
593 std::optional<DIExpression::FragmentInfo> Fragment,
597 UserValue *lookupVirtReg(
Register VirtReg);
640 void computeIntervals();
652 StashedDebugInstrs.
clear();
655 virtRegToEqClass.
clear();
658 assert((!ModifiedMF || EmitDone) &&
659 "Dbg values are not emitted in LDV");
693 auto *Scope = cast<DIScope>(
DL.getScope());
695 CommentOS << Scope->getFilename();
696 CommentOS <<
':' <<
DL.getLine();
697 if (
DL.getCol() != 0)
698 CommentOS <<
':' <<
DL.getCol();
714 if (
const auto *V = dyn_cast<const DILocalVariable>(
Node)) {
717 }
else if (
const auto *L = dyn_cast<const DILabel>(
Node)) {
723 OS << Res <<
"," << Line;
724 auto *InlinedAt =
DL ?
DL->getInlinedAt() :
nullptr;
726 if (
DebugLoc InlinedAtDL = InlinedAt) {
740 OS <<
" [" <<
I.start() <<
';' <<
I.stop() <<
"):";
741 if (
I.value().isUndef())
744 I.value().printLocNos(
OS);
745 if (
I.value().getWasIndirect())
747 else if (
I.value().getWasList())
751 for (
unsigned i = 0, e = locations.size(); i != e; ++i) {
752 OS <<
" Loc" << i <<
'=';
753 locations[i].print(
OS,
TRI);
768 OS <<
"********** DEBUG VARIABLES **********\n";
769 for (
auto &userValue : userValues)
770 userValue->print(
OS,
TRI);
771 OS <<
"********** DEBUG LABELS **********\n";
772 for (
auto &userLabel : userLabels)
773 userLabel->print(
OS,
TRI);
778 if (MO.isReg() && MO.getReg().isVirtual())
782UserValue *LiveDebugVariables::LDVImpl::getUserValue(
784 std::optional<DIExpression::FragmentInfo> Fragment,
const DebugLoc &
DL) {
788 UserValue *&UV = userVarMap[
ID];
790 userValues.push_back(
791 std::make_unique<UserValue>(Var, Fragment,
DL,
allocator));
792 UV = userValues.back().get();
799 UserValue *&Leader = virtRegToEqClass[VirtReg];
800 Leader = UserValue::merge(Leader, EC);
803UserValue *LiveDebugVariables::LDVImpl::lookupVirtReg(
Register VirtReg) {
804 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
805 return UV->getLeader();
809bool LiveDebugVariables::LDVImpl::handleDebugValue(
MachineInstr &
MI,
813 if (!
MI.isDebugValue()) {
817 if (!
MI.getDebugVariableOp().isMetadata()) {
818 LLVM_DEBUG(
dbgs() <<
"Can't handle DBG_VALUE* with invalid variable: "
822 if (
MI.isNonListDebugValue() &&
823 (
MI.getNumOperands() != 4 ||
824 !(
MI.getDebugOffset().isImm() ||
MI.getDebugOffset().isReg()))) {
833 bool Discard =
false;
835 if (
Op.isReg() &&
Op.getReg().isVirtual()) {
837 if (!LIS->hasInterval(Reg)) {
861 bool IsIndirect =
MI.isDebugOffsetImm();
863 assert(
MI.getDebugOffset().getImm() == 0 &&
864 "DBG_VALUE with nonzero offset");
865 bool IsList =
MI.isDebugValueList();
872 MI.debug_operands().end()),
873 IsIndirect, IsList, *Expr);
881 UV->addDef(
Idx, UndefMOs,
false, IsList, *Expr);
888 assert(
MI.isDebugValueLike() ||
MI.isDebugPHI());
892 if (
MI.isDebugValueLike())
895 return MO.isReg() && MO.getReg().isVirtual();
897 "MIs should not refer to Virtual Registers in InstrRef mode.");
900 auto NextInst = std::next(
MI.getIterator());
901 auto *
MBB =
MI.getParent();
902 MI.removeFromParent();
903 StashedDebugInstrs.push_back({&
MI,
Idx,
MBB});
907bool LiveDebugVariables::LDVImpl::handleDebugLabel(
MachineInstr &
MI,
910 if (
MI.getNumOperands() != 1 || !
MI.getOperand(0).isMetadata()) {
919 for (
auto const &L : userLabels) {
920 if (
L->matches(Label,
DL->getInlinedAt(),
Idx)) {
926 userLabels.push_back(std::make_unique<UserLabel>(Label,
DL,
Idx));
931bool LiveDebugVariables::LDVImpl::collectDebugValues(
MachineFunction &mf,
933 bool Changed =
false;
939 if (!
MBBI->isDebugOrPseudoInstr()) {
947 ? LIS->getMBBStartIdx(&
MBB)
948 : LIS->getInstructionIndex(*std::prev(
MBBI)).getRegSlot();
954 if (InstrRef && (
MBBI->isNonListDebugValue() ||
MBBI->isDebugPHI() ||
955 MBBI->isDebugRef())) {
960 }
else if ((
MBBI->isDebugValue() && handleDebugValue(*
MBBI,
Idx)) ||
961 (
MBBI->isDebugLabel() && handleDebugLabel(*
MBBI,
Idx))) {
966 }
while (
MBBI != MBBE &&
MBBI->isDebugOrPseudoInstr());
972void UserValue::extendDef(
974 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
984 for (
auto &LII : LiveIntervalInfo) {
986 assert(LR && LII.second.second &&
"Missing range info for Idx.");
988 assert(Segment && Segment->
valno == LII.second.second &&
989 "Invalid VNInfo for Idx given?");
990 if (Segment->
end < Stop) {
992 Kills = {Stop, {LII.first}};
993 }
else if (Segment->
end == Stop && Kills) {
996 Kills->second.push_back(LII.first);
1001 if (
I.valid() &&
I.start() <= Start) {
1003 Start = Start.getNextSlot();
1004 if (
I.value() !=
DbgValue ||
I.stop() != Start) {
1006 Kills = std::nullopt;
1014 if (
I.valid() &&
I.start() < Stop) {
1017 Kills = std::nullopt;
1021 DbgVariableValue ExtDbgValue(
DbgValue);
1022 I.insert(Start, Stop, std::move(ExtDbgValue));
1026void UserValue::addDefsFromCopies(
1034 [](
auto LocI) {
return !LocI.second->reg().isVirtual(); }))
1041 for (
auto &LocInterval : LocIntervals) {
1042 unsigned LocNo = LocInterval.first;
1049 Register DstReg =
MI->getOperand(0).getReg();
1069 assert(DstVNI && DstVNI->
def ==
Idx.getRegSlot() &&
"Bad copy value");
1070 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
1074 if (CopyValues.
empty())
1078 for (
auto &LocInterval : LocIntervals)
1079 LLVM_DEBUG(
dbgs() <<
"Got " << CopyValues[LocInterval.first].size()
1080 <<
" copies of " << *LocInterval.second <<
'\n');
1086 if (
I.valid() &&
I.start() <= KilledAt)
1088 DbgVariableValue NewValue(
DbgValue);
1089 for (
auto &LocInterval : LocIntervals) {
1090 unsigned LocNo = LocInterval.first;
1091 bool FoundCopy =
false;
1092 for (
auto &LIAndVNI : CopyValues[LocNo]) {
1094 const VNInfo *DstVNI = LIAndVNI.second;
1097 LLVM_DEBUG(
dbgs() <<
"Kill at " << KilledAt <<
" covered by valno #"
1098 << DstVNI->
id <<
" in " << *DstLI <<
'\n');
1100 assert(CopyMI && CopyMI->
isCopy() &&
"Bad copy value");
1101 unsigned NewLocNo = getLocationNo(CopyMI->
getOperand(0));
1102 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
1112 NewDefs.push_back(std::make_pair(KilledAt, NewValue));
1122 if (!
I.value().isUndef())
1123 Defs.
push_back(std::make_pair(
I.start(),
I.value()));
1126 for (
unsigned i = 0; i != Defs.
size(); ++i) {
1128 DbgVariableValue
DbgValue = Defs[i].second;
1130 bool ShouldExtendDef =
false;
1131 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1134 ShouldExtendDef |= !LocMO.
isReg();
1137 ShouldExtendDef =
true;
1139 const VNInfo *VNI =
nullptr;
1145 LIs[LocNo] = {LI, VNI};
1147 if (ShouldExtendDef) {
1148 std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> Kills;
1153 bool AnySubreg =
false;
1154 for (
unsigned LocNo : Kills->second) {
1161 KilledLocIntervals.
push_back({LocNo, LI});
1173 addDefsFromCopies(
DbgValue, KilledLocIntervals, Kills->first, Defs,
1193 if (!dl.getInlinedAt())
1213 if (
Range.first ==
Range.first->getParent()->begin())
1218 if (PrevEnd &&
I.start() < PrevEnd) {
1224 I.setStopUnchecked(PrevEnd);
1235 I.advanceTo(RStart);
1239 if (
I.start() < RStart) {
1241 I.setStartUnchecked(RStart);
1243 trimmedDefs.insert(RStart);
1260 if (PrevEnd &&
I.start() < PrevEnd)
1261 I.setStopUnchecked(PrevEnd);
1264void LiveDebugVariables::LDVImpl::computeIntervals() {
1268 for (
const auto &UV : userValues) {
1269 UV->computeIntervals(MF->getRegInfo(), *
TRI, *LIS, LS);
1270 UV->mapVirtRegs(
this);
1279 LLVM_DEBUG(
dbgs() <<
"********** COMPUTING LIVE DEBUG VARIABLES: "
1280 << mf.
getName() <<
" **********\n");
1282 bool Changed = collectDebugValues(mf, InstrRef);
1289 for (
const auto &PHIIt : MF->DebugPHIPositions) {
1293 unsigned SubReg = Position.SubReg;
1295 PHIValPos VP = {SI, Reg,
SubReg};
1296 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
1297 RegToPHIIdx[Reg].push_back(PHIIt.first);
1300 ModifiedMF = Changed;
1307 if (
MI.isDebugInstr())
1314 auto *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
1316 Impl = std::make_unique<LiveDebugVariables>();
1317 Impl->analyze(mf, LIS);
1330 LDV.analyze(MF, LIS);
1354 return !PAC.preservedWhenStateless();
1365 PImpl.reset(
new LDVImpl(LIS));
1370 PImpl->runOnMachineFunction(MF, InstrRef);
1381 dbgs() <<
"Splitting Loc" << OldLocNo <<
'\t';
1384 bool DidChange =
false;
1397 if (!LocMapI.
valid())
1401 while (LocMapI.
valid() && LII != LIE) {
1408 if (LocMapI.
value().containsLocNo(OldLocNo) &&
1409 LII->start < LocMapI.
stop()) {
1413 MO.
setSubReg(locations[OldLocNo].getSubReg());
1414 NewLocNo = getLocationNo(MO);
1420 DbgVariableValue OldDbgValue = LocMapI.
value();
1423 if (LStart < LII->start)
1425 if (LStop > LII->end)
1429 LocMapI.
setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
1432 if (LStart < LocMapI.
start()) {
1433 LocMapI.
insert(LStart, LocMapI.
start(), OldDbgValue);
1435 assert(LocMapI.
valid() &&
"Unexpected coalescing");
1437 if (LStop > LocMapI.
stop()) {
1439 LocMapI.
insert(LII->end, LStop, OldDbgValue);
1445 if (LII->end < LocMapI.
stop()) {
1451 if (!LocMapI.
valid())
1468 removeLocationIfUnused(OldLocNo);
1471 dbgs() <<
"Split result: \t";
1480 bool DidChange =
false;
1483 for (
unsigned i = locations.size(); i ; --i) {
1484 unsigned LocNo = i-1;
1488 DidChange |= splitLocation(LocNo, NewRegs, LIS);
1495 auto RegIt = RegToPHIIdx.find(OldReg);
1496 if (RegIt == RegToPHIIdx.end())
1499 std::vector<std::pair<Register, unsigned>> NewRegIdxes;
1501 for (
unsigned InstrID : RegIt->second) {
1502 auto PHIIt = PHIValToPos.find(InstrID);
1503 assert(PHIIt != PHIValToPos.end());
1504 const SlotIndex &Slot = PHIIt->second.SI;
1505 assert(OldReg == PHIIt->second.Reg);
1508 for (
auto NewReg : NewRegs) {
1510 auto LII = LI.
find(Slot);
1511 if (LII != LI.
end() && LII->start <= Slot) {
1513 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
1515 PHIIt->second.Reg = NewReg;
1527 RegToPHIIdx.erase(RegIt);
1528 for (
auto &RegAndInstr : NewRegIdxes)
1529 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
1535 splitPHIRegister(OldReg, NewRegs);
1539 bool DidChange =
false;
1540 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
1541 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
1547 UserValue *UV = lookupVirtReg(OldReg);
1549 mapVirtReg(NewReg, UV);
1555 PImpl->splitRegister(OldReg, NewRegs);
1572 for (
unsigned I = 0, E = locations.size();
I != E; ++
I) {
1573 bool Spilled =
false;
1574 unsigned SpillOffset = 0;
1605 auto InsertResult = NewLocations.
insert({Loc, {Spilled, SpillOffset}});
1606 unsigned NewLocNo = std::distance(NewLocations.
begin(), InsertResult.first);
1607 LocNoMap[
I] = NewLocNo;
1612 SpillOffsets.
clear();
1613 for (
auto &Pair : NewLocations) {
1615 unsigned SpillOffset;
1616 std::tie(Spilled, SpillOffset) = Pair.second;
1617 locations.push_back(Pair.first);
1619 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
1620 SpillOffsets[NewLocNo] = SpillOffset;
1629 I.setValueUnchecked(
I.value().remapLocNos(LocNoMap));
1630 I.setStart(
I.start());
1639 Idx =
Idx.getBaseIndex();
1661 auto MapIt = BBSkipInstsMap.
find(
MBB);
1662 if (MapIt == BBSkipInstsMap.
end())
1665 BeginIt = std::next(MapIt->second);
1668 BBSkipInstsMap[
MBB] = std::prev(
I);
1671 Idx =
Idx.getPrevIndex();
1694 while (
I !=
MBB->
end() && !
I->isTerminator()) {
1699 return I->definesRegister(Reg, &
TRI);
1702 return std::next(
I);
1717 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
1731 for (
unsigned LocNo :
DbgValue.loc_nos())
1735 ++NumInsertedDebugValues;
1737 assert(cast<DILocalVariable>(Variable)
1739 "Expected inlined-at fields to agree");
1746 bool IsIndirect =
DbgValue.getWasIndirect();
1747 bool IsList =
DbgValue.getWasList();
1748 for (
unsigned I = 0, E = LocSpills.
size();
I != E; ++
I) {
1764 assert((!LocSpills[
I] || MOs[
I].isFI()) &&
1765 "a spilled location must be a frame index");
1768 unsigned DbgValueOpcode =
1769 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
1785 ++NumInsertedDebugLabels;
1804 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1807 bool Spilled = SpillIt != SpillOffsets.
end();
1809 LocSpillOffsets.
push_back(Spilled ? SpillIt->second : 0);
1815 if (trimmedDefs.count(Start))
1816 Start = Start.getPrevIndex();
1818 LLVM_DEBUG(
auto &dbg =
dbgs(); dbg <<
"\t[" << Start <<
';' << Stop <<
"):";
1824 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs, LocSpillOffsets,
1825 LIS,
TII,
TRI, BBSkipInstsMap);
1828 while (Stop > MBBEnd) {
1835 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs,
1836 LocSpillOffsets, LIS,
TII,
TRI, BBSkipInstsMap);
1852 insertDebugLabel(&*
MBB, loc, LIS,
TII, BBSkipInstsMap);
1858 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG VARIABLES **********\n");
1865 for (
auto &userValue : userValues) {
1867 userValue->rewriteLocations(*VRM, *MF, *
TII, *
TRI, SpillOffsets);
1868 userValue->emitDebugValues(VRM, *LIS, *
TII, *
TRI, SpillOffsets,
1871 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG LABELS **********\n");
1872 for (
auto &userLabel : userLabels) {
1874 userLabel->emitDebugLabel(*LIS, *
TII, BBSkipInstsMap);
1877 LLVM_DEBUG(
dbgs() <<
"********** EMITTING DEBUG PHIS **********\n");
1880 for (
auto &It : PHIValToPos) {
1883 unsigned InstNum = It.first;
1884 auto Slot = It.second.SI;
1886 unsigned SubReg = It.second.SubReg;
1890 unsigned PhysReg = VRM->
getPhys(Reg);
1892 PhysReg =
TRI->getSubReg(PhysReg,
SubReg);
1895 TII->get(TargetOpcode::DBG_PHI));
1896 Builder.addReg(PhysReg);
1897 Builder.addImm(InstNum);
1901 unsigned SpillSize, SpillOffset;
1903 unsigned regSizeInBits =
TRI->getRegSizeInBits(*TRC);
1905 regSizeInBits =
TRI->getSubRegIdxSize(
SubReg);
1911 TII->getStackSlotRange(TRC,
SubReg, SpillSize, SpillOffset, *MF);
1913 if (
Success && SpillOffset == 0) {
1915 TII->get(TargetOpcode::DBG_PHI));
1917 Builder.addImm(InstNum);
1921 Builder.addImm(regSizeInBits);
1926 <<
" has nonzero offset\n";
1934 LLVM_DEBUG(
dbgs() <<
"********** EMITTING INSTR REFERENCES **********\n");
1942 for (
auto *StashIt = StashedDebugInstrs.begin();
1943 StashIt != StashedDebugInstrs.end(); ++StashIt) {
1948 auto EmitInstsHere = [
this, &StashIt,
MBB,
Idx,
1955 auto NextItem = std::next(StashIt);
1956 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx ==
Idx) {
1957 assert(NextItem->MBB ==
MBB &&
"Instrs with same slot index should be"
1958 "in the same block");
1961 NextItem = std::next(StashIt);
1967 if (
Idx == Slots->getMBBStartIdx(
MBB)) {
1970 EmitInstsHere(InsertPos);
1976 auto PostDebug = std::next(Pos->getIterator());
1978 EmitInstsHere(PostDebug);
1983 for (;
Idx <
End;
Idx = Slots->getNextNonNullIndex(
Idx)) {
1984 Pos = Slots->getInstructionFromIndex(
Idx);
1986 EmitInstsHere(Pos->getIterator());
1996 EmitInstsHere(TermIt);
2002 BBSkipInstsMap.
clear();
2007 PImpl->emitDebugValues(VRM);
2010#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
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.
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
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.
static bool isUndef(const MachineInstr &MI)
Register 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)
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)
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.
API to communicate dependencies between analyses during invalidation.
A container for analyses that lazily runs them and caches their results.
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.
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...
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...
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
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.
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 insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
LLVM_ABI 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.
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
instr_iterator instr_end()
LLVM_ABI 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.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
LLVM_ABI 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.
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)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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 getNextSlot() const
Returns the next slot in the index list.
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 TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
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 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.
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)
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.
LLVM_ABI void initializeLiveDebugVariablesWrapperLegacyPass(PassRegistry &)
@ Success
The lock was released successfully.
OutputIt copy(R &&Range, OutputIt Out)
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.
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...
This represents a simple continuous liveness interval for a value.