Go to the documentation of this file.
48 #include "llvm/Config/llvm-config.h"
66 #define DEBUG_TYPE "livedebugvars"
72 STATISTIC(NumInsertedDebugValues,
"Number of DBG_VALUEs inserted");
73 STATISTIC(NumInsertedDebugLabels,
"Number of DBG_LABELs inserted");
78 "Debug Variable Analysis",
false,
false)
100 class DbgVariableValue {
104 : WasIndirect(WasIndirect), WasList(WasList),
Expression(&Expr) {
105 assert(!(WasIndirect && WasList) &&
106 "DBG_VALUE_LISTs should not be indirect.");
108 for (
unsigned LocNo : NewLocs) {
109 auto It =
find(LocNoVec, LocNo);
110 if (It == LocNoVec.end())
111 LocNoVec.push_back(LocNo);
115 unsigned OpIdx = LocNoVec.size();
116 unsigned DuplicatingIdx = std::distance(LocNoVec.begin(), It);
127 if (LocNoVec.size() < 64) {
128 LocNoCount = LocNoVec.size();
129 if (LocNoCount > 0) {
130 LocNos = std::make_unique<unsigned[]>(LocNoCount);
131 std::copy(LocNoVec.begin(), LocNoVec.end(), loc_nos_begin());
135 "locations, dropping...\n");
141 dwarf::DW_OP_stack_value});
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()]);
161 DbgVariableValue &operator=(
const DbgVariableValue &Other) {
164 if (
Other.getLocNoCount()) {
165 LocNos.reset(
new unsigned[
Other.getLocNoCount()]);
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())
189 NewLocNos.push_back(LocNo !=
UndefLocNo && LocNo > Pivot ? LocNo - 1
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))
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;
293 UserValue *next =
nullptr;
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)
378 locations.push_back(LocMO);
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();
401 locations.
erase(locations.begin() + LocNo);
403 const DbgVariableValue &
DbgValue =
I.value();
404 if (
DbgValue.hasLocNoGreaterThan(LocNo))
405 I.setValueUnchecked(
DbgValue.decrementLocNosAfterPivot(LocNo));
410 void mapVirtRegs(
LDVImpl *LDV);
417 Locs.push_back(getLocationNo(
Op));
418 DbgVariableValue
DbgValue(Locs, IsIndirect, IsList, Expr);
421 if (!
I.valid() ||
I.start() != Idx)
444 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
458 void addDefsFromCopies(
511 : Label(label), dl(
std::move(L)), loc(Idx) {}
516 return Label == L && dl->getInlinedAt() == IA && loc ==
Index;
545 std::map<unsigned, PHIValPos> PHIValToPos;
564 bool EmitDone =
false;
567 bool ModifiedMF =
false;
577 VRMap virtRegToEqClass;
589 UserValue *lookupVirtReg(
Register VirtReg);
632 void computeIntervals();
644 StashedDebugInstrs.
clear();
647 virtRegToEqClass.clear();
650 assert((!ModifiedMF || EmitDone) &&
651 "Dbg values are not emitted in LDV");
657 void mapVirtReg(
Register VirtReg, UserValue *EC);
674 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
680 auto *
Scope = cast<DIScope>(
DL.getScope());
682 CommentOS <<
Scope->getFilename();
683 CommentOS <<
':' <<
DL.getLine();
684 if (
DL.getCol() != 0)
685 CommentOS <<
':' <<
DL.getCol();
701 if (
const auto *V = dyn_cast<const DILocalVariable>(Node)) {
704 }
else if (
const auto *L = dyn_cast<const DILabel>(Node)) {
710 OS << Res <<
"," << Line;
711 auto *InlinedAt =
DL ?
DL->getInlinedAt() :
nullptr;
713 if (
DebugLoc InlinedAtDL = InlinedAt) {
727 OS <<
" [" <<
I.start() <<
';' <<
I.stop() <<
"):";
728 if (
I.value().isUndef())
731 I.value().printLocNos(OS);
732 if (
I.value().getWasIndirect())
734 else if (
I.value().getWasList())
738 for (
unsigned i = 0,
e = locations.size();
i !=
e; ++
i) {
739 OS <<
" Loc" <<
i <<
'=';
740 locations[
i].print(OS,
TRI);
755 OS <<
"********** DEBUG VARIABLES **********\n";
756 for (
auto &userValue : userValues)
757 userValue->print(OS,
TRI);
758 OS <<
"********** DEBUG LABELS **********\n";
759 for (
auto &userLabel : userLabels)
760 userLabel->print(OS,
TRI);
764 void UserValue::mapVirtRegs(
LDVImpl *LDV) {
765 for (
unsigned i = 0,
e = locations.size();
i !=
e; ++
i)
766 if (locations[
i].
isReg() &&
768 LDV->mapVirtReg(locations[
i].
getReg(),
this);
777 UserValue *&UV = userVarMap[
ID];
779 userValues.push_back(
780 std::make_unique<UserValue>(Var, Fragment,
DL, allocator));
781 UV = userValues.back().get();
786 void LDVImpl::mapVirtReg(
Register VirtReg, UserValue *EC) {
788 UserValue *&Leader = virtRegToEqClass[VirtReg];
792 UserValue *LDVImpl::lookupVirtReg(
Register VirtReg) {
793 if (UserValue *UV = virtRegToEqClass.lookup(VirtReg))
794 return UV->getLeader();
801 if (!
MI.isDebugValue()) {
805 if (!
MI.getDebugVariableOp().isMetadata()) {
806 LLVM_DEBUG(
dbgs() <<
"Can't handle DBG_VALUE* with invalid variable: "
810 if (
MI.isNonListDebugValue() &&
811 (
MI.getNumOperands() != 4 ||
812 !(
MI.getDebugOffset().isImm() ||
MI.getDebugOffset().isReg()))) {
821 bool Discard =
false;
825 if (!LIS->hasInterval(
Reg)) {
829 LLVM_DEBUG(
dbgs() <<
"Discarding debug info (no LIS interval): " << Idx
841 LLVM_DEBUG(
dbgs() <<
"Discarding debug info (reg not live): " << Idx
849 bool IsIndirect =
MI.isDebugOffsetImm();
851 assert(
MI.getDebugOffset().getImm() == 0 &&
852 "DBG_VALUE with nonzero offset");
853 bool IsList =
MI.isDebugValueList();
860 MI.debug_operands().end()),
861 IsIndirect, IsList, *Expr);
869 UV->addDef(Idx, UndefMOs,
false, IsList, *Expr);
876 assert(
MI.isDebugValue() ||
MI.isDebugRef() ||
MI.isDebugPHI());
880 if (
MI.isDebugValue())
881 assert(!
MI.getOperand(0).isReg() || !
MI.getOperand(0).getReg().isVirtual());
884 auto NextInst = std::next(
MI.getIterator());
885 auto *
MBB =
MI.getParent();
886 MI.removeFromParent();
887 StashedDebugInstrs.push_back({&
MI, Idx,
MBB});
893 if (
MI.getNumOperands() != 1 || !
MI.getOperand(0).isMetadata()) {
902 for (
auto const &L : userLabels) {
903 if (L->matches(Label,
DL->getInlinedAt(), Idx)) {
909 userLabels.push_back(std::make_unique<UserLabel>(Label,
DL, Idx));
915 bool Changed =
false;
921 if (!
MBBI->isDebugOrPseudoInstr()) {
929 ? LIS->getMBBStartIdx(&
MBB)
930 : LIS->getInstructionIndex(*std::prev(
MBBI)).getRegSlot();
936 if (InstrRef && (
MBBI->isNonListDebugValue() ||
MBBI->isDebugPHI() ||
937 MBBI->isDebugRef())) {
938 MBBI = handleDebugInstr(*
MBBI, Idx);
942 }
else if ((
MBBI->isDebugValue() && handleDebugValue(*
MBBI, Idx)) ||
943 (
MBBI->isDebugLabel() && handleDebugLabel(*
MBBI, Idx))) {
948 }
while (
MBBI != MBBE &&
MBBI->isDebugOrPseudoInstr());
954 void UserValue::extendDef(
956 SmallDenseMap<
unsigned, std::pair<LiveRange *, const VNInfo *>>
966 for (
auto &LII : LiveIntervalInfo) {
968 assert(LR && LII.second.second &&
"Missing range info for Idx.");
970 assert(Segment && Segment->valno == LII.second.second &&
971 "Invalid VNInfo for Idx given?");
972 if (Segment->end < Stop) {
974 Kills = {Stop, {LII.first}};
975 }
else if (Segment->end == Stop && Kills) {
978 Kills->second.push_back(LII.first);
983 if (
I.valid() &&
I.start() <= Start) {
985 Start = Start.getNextSlot();
986 if (
I.value() !=
DbgValue ||
I.stop() != Start) {
996 if (
I.valid() &&
I.start() < Stop) {
1003 DbgVariableValue ExtDbgValue(
DbgValue);
1004 I.insert(Start, Stop,
std::move(ExtDbgValue));
1008 void UserValue::addDefsFromCopies(
1015 if (
any_of(LocIntervals, [](
auto LocI) {
1024 for (
auto &LocInterval : LocIntervals) {
1025 unsigned LocNo = LocInterval.first;
1032 Register DstReg =
MI->getOperand(0).getReg();
1053 CopyValues[LocNo].push_back(std::make_pair(DstLI, DstVNI));
1057 if (CopyValues.
empty())
1060 #if !defined(NDEBUG)
1061 for (
auto &LocInterval : LocIntervals)
1062 LLVM_DEBUG(
dbgs() <<
"Got " << CopyValues[LocInterval.first].size()
1063 <<
" copies of " << *LocInterval.second <<
'\n');
1069 if (
I.valid() &&
I.start() <= KilledAt)
1071 DbgVariableValue NewValue(
DbgValue);
1072 for (
auto &LocInterval : LocIntervals) {
1073 unsigned LocNo = LocInterval.first;
1074 bool FoundCopy =
false;
1075 for (
auto &LIAndVNI : CopyValues[LocNo]) {
1077 const VNInfo *DstVNI = LIAndVNI.second;
1080 LLVM_DEBUG(
dbgs() <<
"Kill at " << KilledAt <<
" covered by valno #"
1081 << DstVNI->
id <<
" in " << *DstLI <<
'\n');
1083 assert(CopyMI && CopyMI->
isCopy() &&
"Bad copy value");
1084 unsigned NewLocNo = getLocationNo(CopyMI->
getOperand(0));
1085 NewValue = NewValue.changeLocNo(LocNo, NewLocNo);
1095 NewDefs.push_back(std::make_pair(KilledAt, NewValue));
1105 if (!
I.value().isUndef())
1106 Defs.push_back(std::make_pair(
I.start(),
I.value()));
1109 for (
unsigned i = 0;
i != Defs.size(); ++
i) {
1111 DbgVariableValue
DbgValue = Defs[
i].second;
1114 bool ShouldExtendDef =
false;
1115 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1118 ShouldExtendDef |= !LocMO.
isReg();
1121 ShouldExtendDef =
true;
1123 const VNInfo *VNI =
nullptr;
1129 LIs[LocNo] = {LI, VNI};
1131 if (ShouldExtendDef) {
1133 extendDef(Idx,
DbgValue, LIs, Kills, LIS);
1137 bool AnySubreg =
false;
1138 for (
unsigned LocNo : Kills->second) {
1145 KilledLocIntervals.push_back({LocNo, LI});
1157 addDefsFromCopies(
DbgValue, KilledLocIntervals, Kills->first, Defs,
1177 if (!dl.getInlinedAt())
1197 if (Range.first == Range.first->getParent()->begin())
1202 if (PrevEnd &&
I.start() < PrevEnd) {
1208 I.setStopUnchecked(PrevEnd);
1219 I.advanceTo(RStart);
1223 if (
I.start() < RStart) {
1225 I.setStartUnchecked(RStart);
1227 trimmedDefs.insert(RStart);
1244 if (PrevEnd &&
I.start() < PrevEnd)
1245 I.setStopUnchecked(PrevEnd);
1248 void LDVImpl::computeIntervals() {
1252 for (
unsigned i = 0,
e = userValues.size();
i !=
e; ++
i) {
1253 userValues[
i]->computeIntervals(MF->getRegInfo(), *
TRI, *LIS,
LS);
1254 userValues[
i]->mapVirtRegs(
this);
1258 bool LDVImpl::runOnMachineFunction(
MachineFunction &mf,
bool InstrRef) {
1263 LLVM_DEBUG(
dbgs() <<
"********** COMPUTING LIVE DEBUG VARIABLES: "
1264 << mf.
getName() <<
" **********\n");
1266 bool Changed = collectDebugValues(mf, InstrRef);
1273 for (
const auto &PHIIt : MF->DebugPHIPositions) {
1277 unsigned SubReg = Position.SubReg;
1280 PHIValToPos.insert(std::make_pair(PHIIt.first, VP));
1281 RegToPHIIdx[
Reg].push_back(PHIIt.first);
1284 ModifiedMF = Changed;
1291 if (
MI.isDebugInstr())
1310 return static_cast<LDVImpl *
>(pImpl)->runOnMachineFunction(mf, InstrRef);
1313 void LiveDebugVariables::releaseMemory() {
1320 delete static_cast<LDVImpl*
>(pImpl);
1331 dbgs() <<
"Splitting Loc" << OldLocNo <<
'\t';
1334 bool DidChange =
false;
1347 if (!LocMapI.
valid())
1351 while (LocMapI.
valid() && LII != LIE) {
1358 if (LocMapI.
value().containsLocNo(OldLocNo) &&
1359 LII->start < LocMapI.
stop()) {
1363 MO.
setSubReg(locations[OldLocNo].getSubReg());
1364 NewLocNo = getLocationNo(MO);
1370 DbgVariableValue OldDbgValue = LocMapI.
value();
1373 if (LStart < LII->start)
1375 if (LStop > LII->end)
1379 LocMapI.
setValue(OldDbgValue.changeLocNo(OldLocNo, NewLocNo));
1382 if (LStart < LocMapI.
start()) {
1383 LocMapI.
insert(LStart, LocMapI.
start(), OldDbgValue);
1385 assert(LocMapI.
valid() &&
"Unexpected coalescing");
1387 if (LStop > LocMapI.
stop()) {
1389 LocMapI.
insert(LII->end, LStop, OldDbgValue);
1395 if (LII->end < LocMapI.
stop()) {
1401 if (!LocMapI.
valid())
1418 removeLocationIfUnused(OldLocNo);
1421 dbgs() <<
"Split result: \t";
1430 bool DidChange =
false;
1433 for (
unsigned i = locations.size();
i ; --
i) {
1434 unsigned LocNo =
i-1;
1438 DidChange |= splitLocation(LocNo, NewRegs, LIS);
1444 auto RegIt = RegToPHIIdx.find(OldReg);
1445 if (RegIt == RegToPHIIdx.end())
1448 std::vector<std::pair<Register, unsigned>> NewRegIdxes;
1450 for (
unsigned InstrID : RegIt->second) {
1451 auto PHIIt = PHIValToPos.find(InstrID);
1452 assert(PHIIt != PHIValToPos.end());
1454 assert(OldReg == PHIIt->second.Reg);
1457 for (
auto NewReg : NewRegs) {
1459 auto LII = LI.
find(Slot);
1460 if (LII != LI.
end() && LII->start <= Slot) {
1462 NewRegIdxes.push_back(std::make_pair(NewReg, InstrID));
1464 PHIIt->second.Reg = NewReg;
1476 RegToPHIIdx.erase(RegIt);
1477 for (
auto &RegAndInstr : NewRegIdxes)
1478 RegToPHIIdx[RegAndInstr.first].push_back(RegAndInstr.second);
1483 splitPHIRegister(OldReg, NewRegs);
1487 bool DidChange =
false;
1488 for (UserValue *UV = lookupVirtReg(OldReg); UV; UV = UV->getNext())
1489 DidChange |= UV->splitRegister(OldReg, NewRegs, *LIS);
1495 UserValue *UV = lookupVirtReg(OldReg);
1497 mapVirtReg(NewReg, UV);
1503 static_cast<LDVImpl*
>(pImpl)->splitRegister(OldReg, NewRegs);
1520 for (
unsigned I = 0,
E = locations.size();
I !=
E; ++
I) {
1521 bool Spilled =
false;
1522 unsigned SpillOffset = 0;
1555 auto InsertResult = NewLocations.
insert({Loc, {Spilled, SpillOffset}});
1556 unsigned NewLocNo = std::distance(NewLocations.
begin(), InsertResult.first);
1557 LocNoMap[
I] = NewLocNo;
1562 SpillOffsets.
clear();
1563 for (
auto &Pair : NewLocations) {
1565 unsigned SpillOffset;
1566 std::tie(Spilled, SpillOffset) = Pair.second;
1567 locations.push_back(Pair.first);
1569 unsigned NewLocNo = std::distance(&*NewLocations.begin(), &Pair);
1570 SpillOffsets[NewLocNo] = SpillOffset;
1579 I.setValueUnchecked(
I.value().remapLocNos(LocNoMap));
1580 I.setStart(
I.start());
1611 auto MapIt = BBSkipInstsMap.
find(
MBB);
1612 if (MapIt == BBSkipInstsMap.
end())
1615 BeginIt = std::next(MapIt->second);
1618 BBSkipInstsMap[
MBB] = std::prev(
I);
1638 Regs.push_back(LocMO.
getReg());
1643 while (
I !=
MBB->
end() && !
I->isTerminator()) {
1648 return I->definesRegister(
Reg, &
TRI);
1651 return std::next(
I);
1666 StopIdx = (MBBEndIdx < StopIdx) ? MBBEndIdx : StopIdx;
1680 for (
unsigned LocNo :
DbgValue.loc_nos())
1681 MOs.push_back(locations[LocNo]);
1684 ++NumInsertedDebugValues;
1686 assert(cast<DILocalVariable>(Variable)
1688 "Expected inlined-at fields to agree");
1695 bool IsIndirect =
DbgValue.getWasIndirect();
1696 bool IsList =
DbgValue.getWasList();
1697 for (
unsigned I = 0,
E = LocSpills.
size();
I !=
E; ++
I) {
1708 Ops.push_back(dwarf::DW_OP_deref);
1713 assert((!LocSpills[
I] || MOs[
I].isFI()) &&
1714 "a spilled location must be a frame index");
1717 unsigned DbgValueOpcode =
1718 IsList ? TargetOpcode::DBG_VALUE_LIST : TargetOpcode::DBG_VALUE;
1734 ++NumInsertedDebugLabels;
1753 for (
unsigned LocNo :
DbgValue.loc_nos()) {
1756 bool Spilled = SpillIt != SpillOffsets.
end();
1757 SpilledLocs.push_back(Spilled);
1758 LocSpillOffsets.push_back(Spilled ? SpillIt->second : 0);
1764 if (trimmedDefs.count(Start))
1765 Start = Start.getPrevIndex();
1767 LLVM_DEBUG(
auto &dbg =
dbgs(); dbg <<
"\t[" << Start <<
';' << Stop <<
"):";
1773 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs, LocSpillOffsets,
1774 LIS,
TII,
TRI, BBSkipInstsMap);
1777 while (Stop > MBBEnd) {
1784 insertDebugValue(&*
MBB, Start, Stop,
DbgValue, SpilledLocs,
1785 LocSpillOffsets, LIS,
TII,
TRI, BBSkipInstsMap);
1801 insertDebugLabel(&*
MBB, loc, LIS,
TII, BBSkipInstsMap);
1806 void LDVImpl::emitDebugValues(
VirtRegMap *VRM) {
1807 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG VARIABLES **********\n");
1814 for (
auto &userValue : userValues) {
1816 userValue->rewriteLocations(*VRM, *MF, *
TII, *
TRI, SpillOffsets);
1817 userValue->emitDebugValues(VRM, *LIS, *
TII, *
TRI, SpillOffsets,
1820 LLVM_DEBUG(
dbgs() <<
"********** EMITTING LIVE DEBUG LABELS **********\n");
1821 for (
auto &userLabel : userLabels) {
1823 userLabel->emitDebugLabel(*LIS, *
TII, BBSkipInstsMap);
1826 LLVM_DEBUG(
dbgs() <<
"********** EMITTING DEBUG PHIS **********\n");
1829 for (
auto &It : PHIValToPos) {
1832 unsigned InstNum = It.first;
1833 auto Slot = It.second.SI;
1835 unsigned SubReg = It.second.SubReg;
1845 TII->get(TargetOpcode::DBG_PHI));
1851 unsigned SpillSize, SpillOffset;
1861 TII->getStackSlotRange(TRC,
SubReg, SpillSize, SpillOffset, *MF);
1863 if (
Success && SpillOffset == 0) {
1865 TII->get(TargetOpcode::DBG_PHI));
1871 Builder.addImm(regSizeInBits);
1875 if (SpillOffset != 0) {
1876 dbgs() <<
"DBG_PHI for Vreg " <<
Reg <<
" subreg " <<
SubReg <<
1877 " has nonzero offset\n";
1886 LLVM_DEBUG(
dbgs() <<
"********** EMITTING INSTR REFERENCES **********\n");
1894 for (
auto StashIt = StashedDebugInstrs.begin();
1895 StashIt != StashedDebugInstrs.end(); ++StashIt) {
1900 auto EmitInstsHere = [
this, &StashIt,
MBB, Idx,
1907 auto NextItem = std::next(StashIt);
1908 while (NextItem != StashedDebugInstrs.end() && NextItem->Idx == Idx) {
1909 assert(NextItem->MBB ==
MBB &&
"Instrs with same slot index should be"
1910 "in the same block");
1913 NextItem = std::next(StashIt);
1922 EmitInstsHere(InsertPos);
1928 auto PostDebug = std::next(Pos->getIterator());
1930 EmitInstsHere(PostDebug);
1938 EmitInstsHere(Pos->getIterator());
1948 EmitInstsHere(TermIt);
1954 BBSkipInstsMap.
clear();
1959 static_cast<LDVImpl*
>(pImpl)->emitDebugValues(VRM);
1962 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
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 ...
iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
This is an optimization pass for GlobalISel generic memory operations.
iterator erase(const_iterator CI)
static 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...
SlotIndexes * getSlotIndexes() const
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)
const KeyT & stop() const
stop - Return the end of the current interval.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
static bool isEarlierEqualInstr(SlotIndex A, SlotIndex B)
Return true if A refers to the same instruction as B or an earlier one.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
virtual const TargetInstrInfo * getInstrInfo() const
bool isNotInMIMap(const MachineInstr &Instr) const
Returns true if the specified machine instr has been removed or was never entered in the map.
VNInfo * valueOutOrDead() const
Returns the value alive at the end of the instruction, if any.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
bool useDebugInstrRef() const
Returns true if the function's variable locations should be tracked with instruction referencing.
iterator advanceTo(iterator I, SlotIndex Pos)
advanceTo - Advance the specified iterator to point to the Segment containing the specified position,...
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
LexicalScope - This class is used to track scope information.
DISubprogram * getSubprogram() const
Get the attached subprogram.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction associated with the given index.
Reg
All possible values of the reg field in the ModR/M byte.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
SlotIndex def
The index of the defining instruction.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
MachineFunction & getMachineFunction() const
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool operator!=(uint64_t V1, const APInt &V2)
This class implements a map that also provides access to all stored values in a deterministic order.
SlotIndex getMBBEndIdx(unsigned Num) const
Returns the last index in the given basic block number.
Result of a LiveRange query.
unsigned const TargetRegisterInfo * TRI
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static void removeDebugInstrs(MachineFunction &mf)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
static bool isUndef(ArrayRef< int > Mask)
SlotIndex beginIndex() const
beginIndex - Return the lowest numbered slot covered.
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static void clear(coro::Shape &Shape)
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.
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...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
TargetInstrInfo - Interface to description of machine instruction set.
iterator_range< use_nodbg_iterator > use_nodbg_operands(Register Reg) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const KeyT & start() const
start - Return the beginning of the current interval.
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
SlotIndex getMBBStartIdx(const MachineBasicBlock *mbb) const
Return the first index in the given basic block.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const MachineOperand & getOperand(unsigned i) const
void setSubReg(unsigned subReg)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Represent the analysis usage information of a pass.
void setStartUnchecked(KeyT a)
setStartUnchecked - Move the start of the current interval without checking for coalescing or overlap...
This requires reassociating to forms of expressions that are already something that reassoc doesn t think about yet These two functions should generate the same code on big endian int * l
const HexagonInstrInfo * TII
static LoopDeletionResult merge(LoopDeletionResult A, LoopDeletionResult B)
MachineOperand class - Representation of each machine instruction operand.
modulo schedule Modulo Schedule test pass
STATISTIC(NumFunctions, "Total number of functions")
This class implements an extremely fast bulk output stream that can only output to a stream.
static MachineOperand CreateFI(int Idx)
LiveInterval - This class represents the liveness of a register, or stack slot.
MachineInstr * getInstructionFromIndex(SlotIndex index) const
Returns the instruction for the given index, or null if the given index has no instruction associated...
bool isAssignedReg(Register virtReg) const
returns true if the specified virtual register is not mapped to a stack slot or rematerialized.
SlotIndex - An opaque wrapper around machine indexes.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
void initializeLiveDebugVariablesPass(PassRegistry &)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
SlotIndex getIndexBefore(const MachineInstr &MI) const
getIndexBefore - Returns the index of the last indexed instruction before MI, or the start index of i...
typename Sizer::Allocator Allocator
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
bool valid() const
valid - Return true if the current position is valid, false for end().
SlotIndex getPrevIndex() const
Returns the previous index.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void setMap(const IntervalMap &m)
setMap - Change the map iterated over.
static MachineBasicBlock::iterator findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS, BlockSkipInstsMap &BBSkipInstsMap)
Find an iterator for inserting a DBG_VALUE instruction.
SlotIndex getBaseIndex() const
Returns the base index for associated with this index.
void advanceTo(KeyT x)
advanceTo - Move to the first interval with stop >= x, or end().
Class recording the (high level) value of a variable.
SlotIndex getMBBStartIdx(unsigned Num) const
Returns the first index in the given basic block number.
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Representation of each machine instruction.
This class represents the liveness of a register, stack slot, etc.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
SlotIndex getMBBEndIdx(const MachineBasicBlock *mbb) const
Return the last index in the given basic block.
unsigned id
The ID number of this value.
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
This is an important class for using LLVM in a threaded context.
const ValT & value() const
value - Return the mapped value at the current interval.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
void dump() const
dump - Print data structures to dbgs().
initializer< Ty > init(const Ty &Val)
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...
Identifies a unique instance of a variable.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
iterator find(const_arg_type_t< KeyT > Val)
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
const_iterator find(KeyT x) const
find - Return an iterator pointing to the first interval ending at or after x, or end().
StandardInstrumentations SI(Debug, VerifyEach)
bool operator==(uint64_t V1, const APInt &V2)
MachineBasicBlock * getMBBFromIndex(SlotIndex index) const
Returns the basic block which the given index falls in.
Register getReg() const
getReg - Returns the register number.
void setIsDebug(bool Val=true)
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
LiveInterval & getInterval(Register Reg)
static bool isReg(const MCInst &MI, unsigned OpNo)
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,...
instr_iterator instr_end()
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.
Class representing an expression and its matching format.
void insert(KeyT a, KeyT b, ValT y)
insert - Insert mapping [a;b] -> y before the current position.
std::pair< const MachineInstr *, const MachineInstr * > InsnRange
InsnRange - This is used to track range of instructions with identical lexical scope.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
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.
static cl::opt< bool > EnableLDV("live-debug-variables", cl::init(true), cl::desc("Enable the live debug variables pass"), cl::Hidden)
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
StringRef - Represent a constant reference to a string, i.e.
Tagged DWARF-like metadata node.
MachineBasicBlock MachineBasicBlock::iterator MBBI
SlotIndex getNextIndex() const
Returns the next index.
Location of a PHI instruction that is also a debug-info variable value, for the duration of register ...
self_iterator getIterator()
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
SlotIndex getNextSlot() const
Returns the next slot in the index list.
INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE, "Debug Variable Analysis", false, false) INITIALIZE_PASS_END(LiveDebugVariables
void setValue(ValT x)
setValue - Change the mapped value of the current interval.
unsigned const MachineRegisterInfo * MRI
Wrapper class representing virtual and physical registers.
unsigned getSubReg() const
LLVM_NODISCARD bool empty() const
LLVMContext & getContext() const
static Optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static void printExtendedName(raw_ostream &OS, const DINode *Node, const DILocation *DL)
static void appendOffset(SmallVectorImpl< uint64_t > &Ops, int64_t Offset)
Append Ops with operations to apply the Offset.
Segments::iterator iterator
Function & getFunction()
Return the LLVM function that this machine code represents.
unsigned getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
void assign(size_type NumElts, ValueParamT Elt)
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
Iterator for intrusive lists based on ilist_node.
void find(KeyT x)
find - Move to the first interval with stop >= x, or end().
VNInfo - Value Number Information.
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
SlotIndex getNextNonNullIndex(SlotIndex Index)
Returns the next non-null index, if one exists.
void setStopUnchecked(KeyT b)
setStopUnchecked - Move the end of the current interval without checking for coalescing or overlaps.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
void setReg(Register Reg)
Change the register this operand corresponds to.
const_iterator begin() const
static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS, const LLVMContext &Ctx)
const Segment * getSegmentContaining(SlotIndex Idx) const
Return the segment that contains the specified index, or null if there is none.
size_t size() const
size - Get the array size.
const MachineInstrBuilder & addMetadata(const MDNode *MD) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
void substPhysReg(MCRegister Reg, const TargetRegisterInfo &)
substPhysReg - Substitute the current register with the physical register Reg, taking any existing Su...
DenseMap< unsigned, DebugPHIRegallocPos > DebugPHIPositions
Map of debug instruction numbers to the position of their PHI instructions during register allocation...
~LiveDebugVariables() override
iterator SkipPHIsLabelsAndDebug(iterator I, bool SkipPseudoOp=true)
Return the first instruction in MBB after I that is not a PHI, label or debug.
bool hasInterval(Register Reg) const
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...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
LexicalScopes - This class provides interface to collect and use lexical scoping information from mac...
we should consider alternate ways to model stack dependencies Lots of things could be done in WebAssemblyTargetTransformInfo cpp there are numerous optimization related hooks that can be overridden in WebAssemblyTargetLowering Instead of the OptimizeReturned which should consider preserving the returned attribute through to MachineInstrs and extending the MemIntrinsicResults pass to do this optimization on calls too That would also let the WebAssemblyPeephole pass clean up dead defs for such as it does for stores Consider implementing and or getMachineCombinerPatterns Find a clean way to fix the problem which leads to the Shrink Wrapping pass being run after the WebAssembly PEI pass When setting multiple variables to the same we currently get code like const It could be done with a smaller encoding like local tee $pop5 local copy
void emitDebugValues(VirtRegMap *VRM)
emitDebugValues - Emit new DBG_VALUE instructions reflecting the changes that happened during registe...
Optional< std::vector< StOtherPiece > > Other
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
int getStackSlot(Register virtReg) const
returns the stack slot mapped to the specified virtual register
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.