48#include "llvm/Config/llvm-config.h"
67#define DEBUG_TYPE "livedebugvars"
73STATISTIC(NumInsertedDebugValues,
"Number of DBG_VALUEs inserted");
74STATISTIC(NumInsertedDebugLabels,
"Number of DBG_LABELs inserted");
79 "Debug Variable Analysis",
false,
false)
101class DbgVariableValue {
105 : WasIndirect(WasIndirect), WasList(WasList),
Expression(&Expr) {
106 assert(!(WasIndirect && WasList) &&
107 "DBG_VALUE_LISTs should not be indirect.");
109 for (
unsigned LocNo : NewLocs) {
110 auto It =
find(LocNoVec, LocNo);
111 if (It == LocNoVec.
end())
116 unsigned OpIdx = LocNoVec.
size();
117 unsigned DuplicatingIdx = std::distance(LocNoVec.
begin(), It);
128 if (LocNoVec.
size() < 64) {
129 LocNoCount = LocNoVec.
size();
130 if (LocNoCount > 0) {
131 LocNos = std::make_unique<unsigned[]>(LocNoCount);
132 std::copy(LocNoVec.
begin(), LocNoVec.
end(), loc_nos_begin());
136 "locations, dropping...\n");
141 DIExpression::get(Expr.
getContext(), {dwarf::DW_OP_LLVM_arg, 0});
145 FragmentInfoOpt->SizeInBits);
146 LocNos = std::make_unique<unsigned[]>(LocNoCount);
151 DbgVariableValue() : LocNoCount(0), WasIndirect(
false), WasList(
false) {}
152 DbgVariableValue(
const DbgVariableValue &
Other)
153 : LocNoCount(
Other.LocNoCount), WasIndirect(
Other.getWasIndirect()),
155 if (
Other.getLocNoCount()) {
156 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
157 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
161 DbgVariableValue &operator=(
const DbgVariableValue &
Other) {
164 if (
Other.getLocNoCount()) {
165 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
166 std::copy(
Other.loc_nos_begin(),
Other.loc_nos_end(), loc_nos_begin());
170 LocNoCount =
Other.getLocNoCount();
171 WasIndirect =
Other.getWasIndirect();
172 WasList =
Other.getWasList();
178 uint8_t getLocNoCount()
const {
return LocNoCount; }
179 bool containsLocNo(
unsigned LocNo)
const {
182 bool getWasIndirect()
const {
return WasIndirect; }
183 bool getWasList()
const {
return WasList; }
186 DbgVariableValue decrementLocNosAfterPivot(
unsigned Pivot)
const {
188 for (
unsigned LocNo : loc_nos())
191 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
196 for (
unsigned LocNo : loc_nos())
200 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
203 DbgVariableValue changeLocNo(
unsigned OldLocNo,
unsigned NewLocNo)
const {
205 NewLocNos.
assign(loc_nos_begin(), loc_nos_end());
206 auto OldLocIt =
find(NewLocNos, OldLocNo);
207 assert(OldLocIt != NewLocNos.
end() &&
"Old location must be present.");
208 *OldLocIt = NewLocNo;
209 return DbgVariableValue(NewLocNos, WasIndirect, WasList, *
Expression);
212 bool hasLocNoGreaterThan(
unsigned LocNo)
const {
214 [LocNo](
unsigned ThisLocNo) {
return ThisLocNo > LocNo; });
218 for (
const unsigned &Loc : loc_nos())
219 OS << (&Loc == loc_nos_begin() ?
" " :
", ") << Loc;
223 const DbgVariableValue &
RHS) {
224 if (std::tie(
LHS.LocNoCount,
LHS.WasIndirect,
LHS.WasList,
226 std::tie(
RHS.LocNoCount,
RHS.WasIndirect,
RHS.WasList,
RHS.Expression))
228 return std::equal(
LHS.loc_nos_begin(),
LHS.loc_nos_end(),
229 RHS.loc_nos_begin());
233 const DbgVariableValue &
RHS) {
237 unsigned *loc_nos_begin() {
return LocNos.get(); }
238 const unsigned *loc_nos_begin()
const {
return LocNos.get(); }
239 unsigned *loc_nos_end() {
return LocNos.get() + LocNoCount; }
240 const unsigned *loc_nos_end()
const {
return LocNos.get() + LocNoCount; }
251 std::unique_ptr<unsigned[]> LocNos;
252 uint8_t LocNoCount : 6;
253 bool WasIndirect : 1;
289 const std::optional<DIExpression::FragmentInfo> Fragment;
293 UserValue *next =
nullptr;
322 std::optional<DIExpression::FragmentInfo> Fragment,
DebugLoc L,
324 : Variable(var), Fragment(Fragment), dl(std::move(L)), leader(
this),
328 UserValue *getLeader() {
329 UserValue *l = leader;
330 while (l != l->leader)
336 UserValue *getNext()
const {
return next; }
339 static UserValue *
merge(UserValue *L1, UserValue *L2) {
340 L2 = L2->getLeader();
343 L1 = L1->getLeader();
353 End->next = L1->next;
369 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
370 if (locations[i].
isReg() &&
372 locations[i].getSubReg() == LocMO.
getSubReg())
375 for (
unsigned i = 0, e = locations.
size(); i != e; ++i)
380 locations.
back().clearParent();
382 if (locations.
back().isReg()) {
383 if (locations.
back().isDef())
384 locations.
back().setIsDead(
false);
385 locations.
back().setIsUse();
387 return locations.
size() - 1;
392 void removeLocationIfUnused(
unsigned LocNo) {
395 const DbgVariableValue &
DbgValue =
I.value();
403 const DbgVariableValue &
DbgValue =
I.value();
404 if (
DbgValue.hasLocNoGreaterThan(LocNo))
405 I.setValueUnchecked(
DbgValue.decrementLocNosAfterPivot(LocNo));
410 void mapVirtRegs(
LDVImpl *LDV);
418 DbgVariableValue
DbgValue(Locs, IsIndirect, IsList, Expr);
421 if (!
I.valid() ||
I.start() !=
Idx)
445 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
459 void addDefsFromCopies(
512 : Label(label), dl(std::move(L)), loc(
Idx) {}
517 return Label == L && dl->getInlinedAt() == IA && loc ==
Index;
546 std::map<unsigned, PHIValPos> PHIValToPos;
565 bool EmitDone =
false;
568 bool ModifiedMF =
false;
578 VRMap virtRegToEqClass;
586 std::optional<DIExpression::FragmentInfo> Fragment,
590 UserValue *lookupVirtReg(
Register VirtReg);
633 void computeIntervals();
645 StashedDebugInstrs.
clear();
648 virtRegToEqClass.clear();
651 assert((!ModifiedMF || EmitDone) &&
652 "Dbg values are not emitted in LDV");
658 void mapVirtReg(
Register VirtReg, UserValue *EC);
675#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
681 auto *Scope = cast<DIScope>(
DL.getScope());
683 CommentOS << Scope->getFilename();
684 CommentOS <<
':' <<
DL.getLine();
685 if (
DL.getCol() != 0)
686 CommentOS <<
':' <<
DL.getCol();
702 if (
const auto *V = dyn_cast<const DILocalVariable>(
Node)) {
705 }
else if (
const auto *L = dyn_cast<const DILabel>(
Node)) {
711 OS << Res <<
"," << Line;
712 auto *InlinedAt =
DL ?
DL->getInlinedAt() :
nullptr;
714 if (
DebugLoc InlinedAtDL = InlinedAt) {
728 OS <<
" [" <<
I.start() <<
';' <<
I.stop() <<
"):";
729 if (
I.value().isUndef())
732 I.value().printLocNos(
OS);
733 if (
I.value().getWasIndirect())
735 else if (
I.value().getWasList())
739 for (
unsigned i = 0, e = locations.size(); i != e; ++i) {
740 OS <<
" Loc" << i <<
'=';
741 locations[i].print(
OS,
TRI);
756 OS <<
"********** DEBUG VARIABLES **********\n";
757 for (
auto &userValue : userValues)
758 userValue->print(
OS,
TRI);
759 OS <<
"********** DEBUG LABELS **********\n";
760 for (
auto &userLabel : userLabels)
761 userLabel->print(
OS,
TRI);
765void UserValue::mapVirtRegs(
LDVImpl *LDV) {
766 for (
unsigned i = 0, e = locations.size(); i != e; ++i)
767 if (locations[i].
isReg() && locations[i].
getReg().isVirtual())
768 LDV->mapVirtReg(locations[i].
getReg(),
this);
773 std::optional<DIExpression::FragmentInfo> Fragment,
778 UserValue *&UV = userVarMap[
ID];
780 userValues.push_back(
781 std::make_unique<UserValue>(Var, Fragment,
DL,
allocator));
782 UV = userValues.back().get();
787void LDVImpl::mapVirtReg(
Register VirtReg, UserValue *EC) {
789 UserValue *&Leader = virtRegToEqClass[VirtReg];
790 Leader = UserValue::merge(Leader, EC);
793UserValue *LDVImpl::lookupVirtReg(
Register VirtReg) {
794 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
795 return UV->getLeader();
802 if (!
MI.isDebugValue()) {
806 if (!
MI.getDebugVariableOp().isMetadata()) {
807 LLVM_DEBUG(
dbgs() <<
"Can't handle DBG_VALUE* with invalid variable: "
811 if (
MI.isNonListDebugValue() &&
812 (
MI.getNumOperands() != 4 ||
813 !(
MI.getDebugOffset().isImm() ||
MI.getDebugOffset().isReg()))) {
822 bool Discard =
false;
824 if (
Op.isReg() &&
Op.getReg().isVirtual()) {
826 if (!LIS->hasInterval(Reg)) {
850 bool IsIndirect =
MI.isDebugOffsetImm();
852 assert(
MI.getDebugOffset().getImm() == 0 &&
853 "DBG_VALUE with nonzero offset");
854 bool IsList =
MI.isDebugValueList();
861 MI.debug_operands().end()),
862 IsIndirect, IsList, *Expr);
870 UV->addDef(
Idx, UndefMOs,
false, IsList, *Expr);
877 assert(
MI.isDebugValueLike() ||
MI.isDebugPHI());
881 if (
MI.isDebugValueLike())
884 return MO.isReg() && MO.getReg().isVirtual();
886 "MIs should not refer to Virtual Registers in InstrRef mode.");
889 auto NextInst = std::next(
MI.getIterator());
890 auto *
MBB =
MI.getParent();
891 MI.removeFromParent();
892 StashedDebugInstrs.push_back({&
MI,
Idx,
MBB});
898 if (
MI.getNumOperands() != 1 || !
MI.getOperand(0).isMetadata()) {
907 for (
auto const &L : userLabels) {
908 if (
L->matches(Label,
DL->getInlinedAt(),
Idx)) {
914 userLabels.push_back(std::make_unique<UserLabel>(Label,
DL,
Idx));
920 bool Changed =
false;
926 if (!
MBBI->isDebugOrPseudoInstr()) {
934 ? LIS->getMBBStartIdx(&
MBB)
935 : LIS->getInstructionIndex(*std::prev(
MBBI)).getRegSlot();
941 if (InstrRef && (
MBBI->isNonListDebugValue() ||
MBBI->isDebugPHI() ||
942 MBBI->isDebugRef())) {
947 }
else if ((
MBBI->isDebugValue() && handleDebugValue(*
MBBI,
Idx)) ||
948 (
MBBI->isDebugLabel() && handleDebugLabel(*
MBBI,
Idx))) {
953 }
while (
MBBI != MBBE &&
MBBI->isDebugOrPseudoInstr());
959void UserValue::extendDef(
961 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
971 for (
auto &LII : LiveIntervalInfo) {
973 assert(LR && LII.second.second &&
"Missing range info for Idx.");
975 assert(Segment && Segment->
valno == LII.second.second &&
976 "Invalid VNInfo for Idx given?");
977 if (Segment->
end < Stop) {
979 Kills = {Stop, {LII.first}};
980 }
else if (Segment->
end == Stop && Kills) {
983 Kills->second.push_back(LII.first);
988 if (
I.valid() &&
I.start() <= Start) {
990 Start = Start.getNextSlot();
991 if (
I.value() !=
DbgValue ||
I.stop() != Start) {
993 Kills = std::nullopt;
1001 if (
I.valid() &&
I.start() < Stop) {
1004 Kills = std::nullopt;
1008 DbgVariableValue ExtDbgValue(
DbgValue);
1009 I.insert(Start, Stop, std::move(ExtDbgValue));
1013void UserValue::addDefsFromCopies(
1021 [](
auto LocI) {
return !LocI.second->reg().isVirtual(); }))
1028 for (
auto &LocInterval : LocIntervals) {
1029 unsigned LocNo = LocInterval.first;
1036 Register DstReg =
MI->getOperand(0).getReg();
1056 assert(DstVNI && DstVNI->
def ==
Idx.getRegSlot() &&
"Bad copy value");
1057 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
1061 if (CopyValues.
empty())
1065 for (
auto &LocInterval : LocIntervals)
1066 LLVM_DEBUG(
dbgs() <<
"Got " << CopyValues[LocInterval.first].size()
1067 <<
" copies of " << *LocInterval.second <<
'\n');
1073 if (
I.valid() &&
I.start() <= KilledAt)
1075 DbgVariableValue NewValue(
DbgValue);
1076 for (
auto &LocInterval : LocIntervals) {
1077 unsigned LocNo = LocInterval.first;
1078 bool FoundCopy =
false;
1079 for (
auto &LIAndVNI : CopyValues[LocNo]) {
1081 const VNInfo *DstVNI = LIAndVNI.second;
1084 LLVM_DEBUG(
dbgs() <<
"Kill at " << KilledAt <<
" covered by valno #"
1085 << DstVNI->
id <<
" in " << *DstLI <<
'\n');
1087 assert(CopyMI && CopyMI->
isCopy() &&
"Bad copy value");
1088 unsigned NewLocNo = getLocationNo(CopyMI->
getOperand(0));
1089 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
1099 NewDefs.push_back(std::make_pair(KilledAt, NewValue));
1109 if (!
I.value().isUndef())
1110 Defs.
push_back(std::make_pair(
I.start(),
I.value()));
1113 for (
unsigned i = 0; i != Defs.
size(); ++i) {
1115 DbgVariableValue
DbgValue = Defs[i].second;
1118 bool ShouldExtendDef =
false;
1119 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1122 ShouldExtendDef |= !LocMO.
isReg();
1125 ShouldExtendDef =
true;
1127 const VNInfo *VNI =
nullptr;
1133 LIs[LocNo] = {LI, VNI};
1135 if (ShouldExtendDef) {
1136 std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> Kills;
1141 bool AnySubreg =
false;
1142 for (
unsigned LocNo : Kills->second) {
1149 KilledLocIntervals.
push_back({LocNo, LI});
1161 addDefsFromCopies(
DbgValue, KilledLocIntervals, Kills->first, Defs,
1181 if (!dl.getInlinedAt())
1201 if (
Range.first ==
Range.first->getParent()->begin())
1206 if (PrevEnd &&
I.start() < PrevEnd) {
1212 I.setStopUnchecked(PrevEnd);
1223 I.advanceTo(RStart);
1227 if (
I.start() < RStart) {
1229 I.setStartUnchecked(RStart);
1231 trimmedDefs.insert(RStart);
1248 if (PrevEnd &&
I.start() < PrevEnd)
1249 I.setStopUnchecked(PrevEnd);
1252void LDVImpl::computeIntervals() {
1256 for (
unsigned i = 0, e = userValues.size(); i != e; ++i) {
1257 userValues[i]->computeIntervals(MF->getRegInfo(), *
TRI, *LIS, LS);
1258 userValues[i]->mapVirtRegs(
this);
1262bool LDVImpl::runOnMachineFunction(
MachineFunction &mf,
bool InstrRef) {
1267 LLVM_DEBUG(
dbgs() <<
"********** COMPUTING LIVE DEBUG VARIABLES: "
1268 << mf.
getName() <<
" **********\n");
1270 bool Changed = collectDebugValues(mf, InstrRef);
1277 for (
const auto &PHIIt : MF->DebugPHIPositions) {
1281 unsigned SubReg = Position.SubReg;
1284 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
1285 RegToPHIIdx[
Reg].push_back(PHIIt.first);
1288 ModifiedMF = Changed;
1295 if (
MI.isDebugInstr())
1314 return static_cast<LDVImpl *
>(pImpl)->runOnMachineFunction(mf, InstrRef);
1317void LiveDebugVariables::releaseMemory() {
1324 delete static_cast<LDVImpl*
>(pImpl);
1335 dbgs() <<
"Splitting Loc" << OldLocNo <<
'\t';
1338 bool DidChange =
false;
1351 if (!LocMapI.
valid())
1355 while (LocMapI.
valid() && LII != LIE) {
1362 if (LocMapI.
value().containsLocNo(OldLocNo) &&
1363 LII->start < LocMapI.
stop()) {
1367 MO.
setSubReg(locations[OldLocNo].getSubReg());
1368 NewLocNo = getLocationNo(MO);
1374 DbgVariableValue OldDbgValue = LocMapI.
value();
1377 if (LStart < LII->start)
1379 if (LStop > LII->end)
1383 LocMapI.
setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
1386 if (LStart < LocMapI.
start()) {
1387 LocMapI.
insert(LStart, LocMapI.
start(), OldDbgValue);
1389 assert(LocMapI.
valid() &&
"Unexpected coalescing");
1391 if (LStop > LocMapI.
stop()) {
1393 LocMapI.
insert(LII->end, LStop, OldDbgValue);
1399 if (LII->end < LocMapI.
stop()) {
1405 if (!LocMapI.
valid())
1422 removeLocationIfUnused(OldLocNo);
1425 dbgs() <<
"Split result: \t";
1434 bool DidChange =
false;
1437 for (
unsigned i = locations.size(); i ; --i) {
1438 unsigned LocNo = i-1;
1442 DidChange |= splitLocation(LocNo, NewRegs, LIS);
1448 auto RegIt = RegToPHIIdx.find(OldReg);
1449 if (RegIt == RegToPHIIdx.end())
1452 std::vector<std::pair<Register, unsigned>> NewRegIdxes;
1454 for (
unsigned InstrID : RegIt->second) {
1455 auto PHIIt = PHIValToPos.find(InstrID);
1456 assert(PHIIt != PHIValToPos.end());
1458 assert(OldReg == PHIIt->second.Reg);
1461 for (
auto NewReg : NewRegs) {
1463 auto LII = LI.
find(Slot);
1464 if (LII != LI.
end() && LII->start <= Slot) {
1466 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
1468 PHIIt->second.Reg = NewReg;
1480 RegToPHIIdx.erase(RegIt);
1481 for (
auto &RegAndInstr : NewRegIdxes)
1482 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
1487 splitPHIRegister(OldReg, NewRegs);
1491 bool DidChange =
false;
1492 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
1493 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
1499 UserValue *UV = lookupVirtReg(OldReg);
1501 mapVirtReg(NewReg, UV);
1524 for (
unsigned I = 0,
E = locations.size();
I !=
E; ++
I) {
1525 bool Spilled =
false;
1526 unsigned SpillOffset = 0;
1558 auto InsertResult = NewLocations.
insert({Loc, {Spilled, SpillOffset}});
1559 unsigned NewLocNo = std::distance(NewLocations.
begin(), InsertResult.first);
1560 LocNoMap[
I] = NewLocNo;
1565 SpillOffsets.
clear();
1566 for (
auto &Pair : NewLocations) {
1568 unsigned SpillOffset;
1569 std::tie(Spilled, SpillOffset) = Pair.second;
1570 locations.push_back(Pair.first);
1572 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
1573 SpillOffsets[NewLocNo] = SpillOffset;
1582 I.setValueUnchecked(
I.value().remapLocNos(LocNoMap));
1583 I.setStart(
I.start());
1592 Idx =
Idx.getBaseIndex();
1614 auto MapIt = BBSkipInstsMap.
find(
MBB);
1615 if (MapIt == BBSkipInstsMap.
end())
1618 BeginIt = std::next(MapIt->second);
1621 BBSkipInstsMap[
MBB] = std::prev(
I);
1624 Idx =
Idx.getPrevIndex();
1646 while (
I !=
MBB->
end() && !
I->isTerminator()) {
1651 return I->definesRegister(Reg, &
TRI);
1654 return std::next(
I);
1669 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
1683 for (
unsigned LocNo :
DbgValue.loc_nos())
1687 ++NumInsertedDebugValues;
1689 assert(cast<DILocalVariable>(Variable)
1691 "Expected inlined-at fields to agree");
1698 bool IsIndirect =
DbgValue.getWasIndirect();
1699 bool IsList =
DbgValue.getWasList();
1700 for (
unsigned I = 0,
E = LocSpills.
size();
I !=
E; ++
I) {
1716 assert((!LocSpills[
I] || MOs[
I].isFI()) &&
1717 "a spilled location must be a frame index");
1720 unsigned DbgValueOpcode =
1721 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
1737 ++NumInsertedDebugLabels;
1756 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1759 bool Spilled = SpillIt != SpillOffsets.
end();
1761 LocSpillOffsets.
push_back(Spilled ? SpillIt->second : 0);
1767 if (trimmedDefs.count(Start))
1768 Start = Start.getPrevIndex();
1770 LLVM_DEBUG(
auto &dbg =
dbgs(); dbg <<
"\t[" << Start <<
';' << Stop <<
"):";
1776 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs, LocSpillOffsets,
1777 LIS,
TII,
TRI, BBSkipInstsMap);
1780 while (Stop > MBBEnd) {
1787 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs,
1788 LocSpillOffsets, LIS,
TII,
TRI, BBSkipInstsMap);
1804 insertDebugLabel(&*
MBB, loc, LIS,
TII, BBSkipInstsMap);
1809void LDVImpl::emitDebugValues(
VirtRegMap *VRM) {
1810 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG VARIABLES **********\n");
1817 for (
auto &userValue : userValues) {
1819 userValue->rewriteLocations(*VRM, *MF, *
TII, *
TRI, SpillOffsets);
1820 userValue->emitDebugValues(VRM, *LIS, *
TII, *
TRI, SpillOffsets,
1823 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG LABELS **********\n");
1824 for (
auto &userLabel : userLabels) {
1826 userLabel->emitDebugLabel(*LIS, *
TII, BBSkipInstsMap);
1829 LLVM_DEBUG(
dbgs() <<
"********** EMITTING DEBUG PHIS **********\n");
1832 for (
auto &It : PHIValToPos) {
1835 unsigned InstNum = It.first;
1836 auto Slot = It.second.SI;
1838 unsigned SubReg = It.second.SubReg;
1843 unsigned PhysReg = VRM->
getPhys(Reg);
1845 PhysReg =
TRI->getSubReg(PhysReg,
SubReg);
1848 TII->get(TargetOpcode::DBG_PHI));
1854 unsigned SpillSize, SpillOffset;
1856 unsigned regSizeInBits =
TRI->getRegSizeInBits(*TRC);
1858 regSizeInBits =
TRI->getSubRegIdxSize(
SubReg);
1864 TII->getStackSlotRange(TRC,
SubReg, SpillSize, SpillOffset, *MF);
1866 if (
Success && SpillOffset == 0) {
1868 TII->get(TargetOpcode::DBG_PHI));
1874 Builder.addImm(regSizeInBits);
1878 if (SpillOffset != 0) {
1879 dbgs() <<
"DBG_PHI for Vreg " <<
Reg <<
" subreg " <<
SubReg <<
1880 " has nonzero offset\n";
1889 LLVM_DEBUG(
dbgs() <<
"********** EMITTING INSTR REFERENCES **********\n");
1897 for (
auto *StashIt = StashedDebugInstrs.begin();
1898 StashIt != StashedDebugInstrs.end(); ++StashIt) {
1903 auto EmitInstsHere = [
this, &StashIt,
MBB,
Idx,
1910 auto NextItem = std::next(StashIt);
1911 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx ==
Idx) {
1912 assert(NextItem->MBB ==
MBB &&
"Instrs with same slot index should be"
1913 "in the same block");
1916 NextItem = std::next(StashIt);
1925 EmitInstsHere(InsertPos);
1931 auto PostDebug = std::next(Pos->getIterator());
1933 EmitInstsHere(PostDebug);
1941 EmitInstsHere(Pos->getIterator());
1951 EmitInstsHere(TermIt);
1957 BBSkipInstsMap.
clear();
1965#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)
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.
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
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
#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
iterator SkipPHIsLabelsAndDebug(iterator I, bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
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.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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)
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.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr)
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.