104#include "llvm/Config/llvm-config.h"
136#define DEBUG_TYPE "livedebugvalues"
141 cl::desc(
"Act like old LiveDebugValues did"),
155 cl::desc(
"livedebugvalues-stack-ws-limit"),
304 unsigned Location : 24;
305 unsigned Quality : 8;
310 : Location(L.asU64()), Quality(static_cast<
unsigned>(Q)) {}
325 return A.first <
B.first;
330 std::optional<LocationQuality>
360 bool IsValueValid =
true;
361 unsigned LastUseBeforeDef = 0;
362 bool DbgLocAvailableAndIsEntryVal =
false;
378 IsValueValid =
false;
390 auto ValuesPreferredLoc =
394 assert(ValuesPreferredLoc != ValueToLoc.
end() &&
395 ValuesPreferredLoc->first == Num);
397 if (ValuesPreferredLoc->second.isIllegal()) {
403 LastUseBeforeDef = std::max(LastUseBeforeDef,
404 static_cast<unsigned>(Num.
getInst()));
408 IsValueValid =
false;
414 LocIdx M = ValuesPreferredLoc->second.getLoc();
416 if (
Value.Properties.DIExpr->isEntryValue())
417 DbgLocAvailableAndIsEntryVal =
true;
426 if (LastUseBeforeDef) {
438 if (DbgLocAvailableAndIsEntryVal)
449 Result.first->second = NewValue;
475 for (
const auto &VLoc : VLocs)
477 for (
DbgOpID OpID : VLoc.second.getDbgOpIDs())
478 if (!OpID.ID.IsConst)
499 if (VIt == ValueToLoc.
end() || VIt->first != VNum)
502 auto &Previous = VIt->second;
505 std::optional<LocationQuality> ReplacementQuality =
507 if (ReplacementQuality)
512 for (
const auto &Var : VLocs) {
542 for (
auto &
Use : MIt->second) {
547 assert(!
Op.isUndef() &&
"UseBeforeDef erroneously created for a "
548 "DbgValue with undef values.");
557 if (ValueToLoc.
empty())
566 auto VIt = ValueToLoc.
find(LocValueID);
567 if (VIt == ValueToLoc.
end())
570 auto &Previous = VIt->second;
573 std::optional<LocationQuality> ReplacementQuality =
575 if (ReplacementQuality)
581 for (
auto &
Use : MIt->second) {
592 LocIdx NewLoc = ValueToLoc.
find(
Op.ID)->second.getLoc();
601 if (DbgOps.
size() !=
Use.Values.size())
654 return Reg != SP && Reg !=
FP;
671 auto NonVariadicExpression =
673 if (!NonVariadicExpression)
675 DIExpr = *NonVariadicExpression;
711 MI.getDebugLoc()->getInlinedAt());
716 if (
MI.isUndefDebugValue() ||
MI.getDebugExpression()->isEntryValue() ||
721 for (
LocIdx Loc : It->second.loc_indices())
751 MI.getDebugLoc()->getInlinedAt());
759 for (
LocIdx Loc : It->second.loc_indices())
764 if (NewLocs.
empty()) {
784 for (
LocIdx Loc : LostVLocIt->second.loc_indices()) {
794 for (
const auto &LostMLoc : LostMLocs)
809 It->second.Ops.assign(NewLocs);
810 It->second.Properties = Properties;
819 bool MakeUndef =
true) {
841 std::optional<LocIdx> NewLoc;
843 if (Loc.Value == OldValue)
848 if (!NewLoc && !MakeUndef) {
878 DbgOps.
insert(DbgOps.
begin(), ActiveVLocIt->second.Ops.size(),
890 for (
LocIdx Loc : ActiveVLocIt->second.loc_indices()) {
896 ActiveVLocIt->second.Ops = DbgOps;
903 for (
auto &LocVarIt : LostMLocs) {
906 "Variable was using this MLoc, but ActiveMLocs[MLoc] has no "
908 LostMLocIt->second.erase(LocVarIt.second);
914 VarLocs[NewLoc->asU64()] = OldValue;
919 ActiveMLocIt->second.clear();
920 if (!NewMLocs.
empty())
953 ActiveVLocIt->second.Properties);
978 MIB.addMetadata(Properties.
DIExpr);
1039 LocIdxToIDNum(
ValueIDNum::EmptyValue), LocIdxToLocID(0) {
1077 if (
Size > 60000 || Offs > 60000)
1113 if (MaskPair.first->clobbersPhysReg(
ID)) {
1115 ValNum = {
CurBB, MaskPair.second, NewIdx};
1136 Masks.push_back(std::make_pair(MO, InstID));
1142 if (SpillID.
id() == 0) {
1146 return std::nullopt;
1151 for (
unsigned StackIdx = 0; StackIdx <
NumSlotIdxes; ++StackIdx) {
1172 return Twine(
"slot ")
1189 std::string MLocName =
LocIdxToName(Location.Value.getLoc());
1190 std::string DefName = Location.Value.asString(MLocName);
1198 dbgs() <<
"Idx " << Location.Idx.asU64() <<
" " << foo <<
"\n";
1210 ?
TII.
get(TargetOpcode::DBG_VALUE_LIST)
1211 :
TII.
get(TargetOpcode::DBG_VALUE);
1213#ifdef EXPENSIVE_CHECKS
1216 return Op.IsConst || !
Op.Loc.isIllegal();
1218 "Did not expect illegal ops in DbgOps.");
1221 "Expected to have either one DbgOp per MI LocationOp, or none.");
1234 auto EmitUndef = [&]() {
1246 bool Indirect = Properties.
Indirect;
1268 unsigned short Offset = StackIdx.second;
1279 unsigned Base = Spill.SpillBase;
1295 bool UseDerefSize =
false;
1297 unsigned DerefSizeInBytes = ValueSizeInBits / 8;
1299 unsigned VariableSizeInBits = Fragment->SizeInBits;
1300 if (VariableSizeInBits != ValueSizeInBits || Expr->
isComplex())
1301 UseDerefSize =
true;
1303 if (*
Size != ValueSizeInBits) {
1304 UseDerefSize =
true;
1327 UseDerefSize =
false;
1331 bool StackValue =
false;
1338 OffsetOps.
push_back(dwarf::DW_OP_deref);
1345 OffsetOps.
push_back(dwarf::DW_OP_deref_size);
1351 OffsetOps.
push_back(dwarf::DW_OP_deref);
1384 if (CalleeSavedRegs.
test((*RAI).id()))
1398std::optional<SpillLocationNo>
1399InstrRefBasedLDV::extractSpillBaseRegAndOffset(
const MachineInstr &
MI) {
1401 "Spill instruction does not have exactly one memory operand?");
1402 auto MMOI =
MI.memoperands_begin();
1405 "Inconsistent memory operand in spill instruction");
1406 int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
1413std::optional<LocIdx>
1415 std::optional<SpillLocationNo>
SpillLoc = extractSpillBaseRegAndOffset(
MI);
1417 return std::nullopt;
1423 auto *MemOperand = *
MI.memoperands_begin();
1425 assert(SizeInBits.
hasValue() &&
"Expected to find a valid size!");
1432 return std::nullopt;
1440bool InstrRefBasedLDV::transferDebugValue(
const MachineInstr &
MI) {
1441 if (!
MI.isDebugValue())
1444 assert(
MI.getDebugVariable()->isValidLocationForIntrinsic(
MI.getDebugLoc()) &&
1445 "Expected inlined-at fields to agree");
1450 if (Scope ==
nullptr)
1456 if (MO.isReg() && MO.getReg() != 0)
1457 (void)MTracker->
readReg(MO.getReg());
1466 if (!
MI.isUndefDebugValue()) {
1472 }
else if (MO.isImm() || MO.isFPImm() || MO.isCImm()) {
1489std::optional<ValueIDNum> InstrRefBasedLDV::getValueForInstrRef(
1505 LowerBoundIt->Src == SoughtSub.Src) {
1506 std::tie(InstNo, OpNo) = LowerBoundIt->Dest;
1507 SoughtSub.Src = LowerBoundIt->Dest;
1508 if (
unsigned Subreg = LowerBoundIt->Subreg)
1509 SeenSubregs.push_back(Subreg);
1515 std::optional<ValueIDNum> NewID;
1519 auto InstrIt = DebugInstrNumToInstr.find(InstNo);
1521 if (InstrIt != DebugInstrNumToInstr.end()) {
1522 const MachineInstr &TargetInstr = *InstrIt->second.first;
1531 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, *L);
1544 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, L);
1550 {
dbgs() <<
"Seen instruction reference to illegal operand\n"; });
1554 }
else if (PHIIt != DebugPHINumToValue.
end() && PHIIt->InstrNum == InstNo) {
1557 assert(MLiveOuts && MLiveIns);
1558 NewID = resolveDbgPHIs(*
MI.getParent()->getParent(), *MLiveOuts, *MLiveIns,
1571 if (NewID && !SeenSubregs.empty()) {
1579 for (
unsigned Subreg :
reverse(SeenSubregs)) {
1583 Size = (
Size == 0) ? ThisSize : std::min(
Size, ThisSize);
1591 if (NewID && !MTracker->
isSpill(L)) {
1597 if (TRCI->contains(Reg))
1599 assert(TRC &&
"Couldn't find target register class?");
1611 if (SubregSize ==
Size && SubregOffset ==
Offset) {
1619 NewID = std::nullopt;
1624 NewID =
ValueIDNum(NewID->getBlock(), NewID->getInst(), NewLoc);
1629 NewID = std::nullopt;
1639 if (!
MI.isDebugRef())
1644 if (!VTracker && !TTracker)
1652 "Expected inlined-at fields to agree");
1657 if (Scope ==
nullptr)
1663 assert(!MO.
isReg() &&
"DBG_INSTR_REF should not contain registers");
1674 std::optional<ValueIDNum> NewID =
1675 getValueForInstrRef(InstNo, OpNo,
MI, MLiveOuts, MLiveIns);
1692 VTracker->
defVar(
MI, Properties, DbgOpIDs);
1701 for (
DbgOpID OpID : DbgOpIDs) {
1711 for (
const DbgOp &
Op : DbgOps) {
1717 for (
auto Location : MTracker->
locations()) {
1720 auto ValueToFindIt =
find(ValuesToFind,
ID);
1721 if (ValueToFindIt == ValuesToFind.
end())
1723 auto &Previous = FoundLocs.
find(
ID)->second;
1726 std::optional<TransferTracker::LocationQuality> ReplacementQuality =
1728 if (ReplacementQuality) {
1730 if (Previous.isBest()) {
1731 ValuesToFind.
erase(ValueToFindIt);
1732 if (ValuesToFind.
empty())
1756 if (!DbgOps.empty() && NewLocs.
empty()) {
1757 bool IsValidUseBeforeDef =
true;
1759 for (
auto ValueLoc : FoundLocs) {
1761 LocIdx FoundLoc = ValueLoc.second.getLoc();
1767 IsValidUseBeforeDef =
false;
1770 LastUseBeforeDef = std::max(LastUseBeforeDef, NewID.
getInst());
1772 if (IsValidUseBeforeDef) {
1775 DbgOps, LastUseBeforeDef);
1784 MTracker->
emitLoc(NewLocs, V,
MI.getDebugLoc().get(), Properties);
1793 if (!
MI.isDebugPHI())
1797 if (VTracker || TTracker)
1803 unsigned InstrNum =
MI.getOperand(1).getImm();
1805 auto EmitBadPHI = [
this, &
MI, InstrNum]() ->
bool {
1811 {InstrNum,
MI.getParent(), std::nullopt, std::nullopt});
1820 auto PHIRec = DebugPHIRecord(
1827 }
else if (MO.
isFI()) {
1834 return EmitBadPHI();
1845 return EmitBadPHI();
1848 assert(
MI.getNumOperands() == 3 &&
"Stack DBG_PHI with no size?");
1849 unsigned slotBitSize =
MI.getOperand(2).getImm();
1851 unsigned SpillID = MTracker->
getLocID(*SpillNo, {slotBitSize, 0});
1856 auto DbgPHI = DebugPHIRecord({InstrNum,
MI.getParent(), Result,
SpillLoc});
1864 {
dbgs() <<
"Seen DBG_PHI with unrecognised operand format\n"; });
1865 return EmitBadPHI();
1874 if (
MI.isImplicitDef()) {
1884 }
else if (
MI.isMetaInstruction())
1892 bool CallChangesSP =
false;
1893 if (AdjustsStackInCalls &&
MI.isCall() &&
MI.getOperand(0).isSymbol() &&
1894 !strcmp(
MI.getOperand(0).getSymbolName(), StackProbeSymbolName.
data()))
1895 CallChangesSP =
true;
1899 auto IgnoreSPAlias = [
this, &
MI, CallChangesSP](
Register R) ->
bool {
1902 return MI.isCall() && MTracker->
SPAliases.count(R);
1914 !IgnoreSPAlias(MO.
getReg())) {
1918 DeadRegs.
insert((*RAI).id());
1927 MTracker->
defReg(DeadReg, CurBB, CurInst);
1929 for (
const auto *MO : RegMaskPtrs)
1934 if (std::optional<SpillLocationNo> SpillNo =
1935 extractSpillBaseRegAndOffset(
MI)) {
1952 for (
uint32_t DeadReg : DeadRegs) {
1959 if (!RegMaskPtrs.empty()) {
1966 if (IgnoreSPAlias(Reg))
1969 for (
const auto *MO : RegMaskPtrs)
1977 if (std::optional<SpillLocationNo> SpillNo =
1978 extractSpillBaseRegAndOffset(
MI)) {
1988void InstrRefBasedLDV::performCopy(
Register SrcRegNum,
Register DstRegNum) {
1991 MTracker->
defReg(*RAI, CurBB, CurInst);
1994 MTracker->
setReg(DstRegNum, SrcValue);
1998 unsigned SrcSubReg = SRI.getSubReg();
1999 unsigned SubRegIdx = SRI.getSubRegIndex();
2000 unsigned DstSubReg = TRI->
getSubReg(DstRegNum, SubRegIdx);
2015 MTracker->
setReg(DstSubReg, CpyValue);
2019std::optional<SpillLocationNo>
2023 if (!
MI.hasOneMemOperand())
2024 return std::nullopt;
2027 auto MMOI =
MI.memoperands_begin();
2030 return std::nullopt;
2032 if (!
MI.getSpillSize(TII) && !
MI.getFoldedSpillSize(TII))
2033 return std::nullopt;
2036 return extractSpillBaseRegAndOffset(
MI);
2041 if (!isSpillInstruction(
MI, MF))
2049std::optional<SpillLocationNo>
2052 if (!
MI.hasOneMemOperand())
2053 return std::nullopt;
2057 if (
MI.getRestoreSize(TII)) {
2058 Reg =
MI.getOperand(0).getReg();
2059 return extractSpillBaseRegAndOffset(
MI);
2061 return std::nullopt;
2064bool InstrRefBasedLDV::transferSpillOrRestoreInst(
MachineInstr &
MI) {
2093 if (std::optional<SpillLocationNo> Loc = isSpillInstruction(
MI, MF)) {
2096 for (
unsigned SlotIdx = 0; SlotIdx < MTracker->
NumSlotIdxes; ++SlotIdx) {
2098 std::optional<LocIdx> MLoc = MTracker->
getSpillMLoc(SpillID);
2107 MTracker->
setMLoc(*MLoc, Def);
2114 if (isLocationSpill(
MI, MF, Reg)) {
2119 auto DoTransfer = [&](
Register SrcReg,
unsigned SpillID) {
2120 auto ReadValue = MTracker->
readReg(SrcReg);
2122 MTracker->
setMLoc(DstLoc, ReadValue);
2135 unsigned SpillID = MTracker->
getLocID(Loc, SubregIdx);
2136 DoTransfer(SR, SpillID);
2142 DoTransfer(Reg, SpillID);
2144 std::optional<SpillLocationNo> Loc = isRestoreInstruction(
MI, MF, Reg);
2156 MTracker->
defReg(*RAI, CurBB, CurInst);
2160 auto DoTransfer = [&](
Register DestReg,
unsigned SpillID) {
2162 auto ReadValue = MTracker->
readMLoc(SrcIdx);
2163 MTracker->
setReg(DestReg, ReadValue);
2168 unsigned SpillID = MTracker->
getLocID(*Loc, Subreg);
2169 DoTransfer(SR, SpillID);
2174 unsigned SpillID = MTracker->
getLocID(*Loc, {
Size, 0});
2175 DoTransfer(Reg, SpillID);
2192 if (SrcReg == DestReg)
2221 if (MLocIt == TTracker->
ActiveMLocs.
end() || MLocIt->second.empty())
2224 ClobberedLocs[ClobberedLoc] =
Value;
2229 InstrRefBasedLDV::performCopy(SrcReg, DestReg);
2235 for (
auto LocVal : ClobberedLocs) {
2236 TTracker->
clobberMloc(LocVal.first, LocVal.second,
MI.getIterator(),
false);
2249 MTracker->
defReg(SrcReg, CurBB, CurInst);
2263 MI.getDebugLoc()->getInlinedAt());
2264 FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
2271 SeenIt->second.insert(ThisFragment);
2273 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2280 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2281 if (!IsInOLapMap.second)
2284 auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
2285 auto &AllSeenFragments = SeenIt->second;
2290 for (
const auto &ASeenFragment : AllSeenFragments) {
2294 ThisFragmentsOverlaps.push_back(ASeenFragment);
2297 auto ASeenFragmentsOverlaps =
2298 OverlapFragments.
find({MIVar.getVariable(), ASeenFragment});
2299 assert(ASeenFragmentsOverlaps != OverlapFragments.
end() &&
2300 "Previously seen var fragment has no vector of overlaps");
2301 ASeenFragmentsOverlaps->second.push_back(ThisFragment);
2305 AllSeenFragments.insert(ThisFragment);
2314 if (transferDebugValue(
MI))
2316 if (transferDebugInstrRef(
MI, MLiveOuts, MLiveIns))
2318 if (transferDebugPHI(
MI))
2320 if (transferRegisterCopy(
MI))
2322 if (transferSpillOrRestoreInst(
MI))
2324 transferRegisterDef(
MI);
2327void InstrRefBasedLDV::produceMLocTransferFunction(
2343 for (
auto &BV : BlockMasks)
2347 for (
auto &
MBB : MF) {
2359 for (
auto &
MI :
MBB) {
2362 process(
MI,
nullptr,
nullptr);
2365 if (
MI.isDebugValueLike())
2366 accumulateFragmentMap(
MI);
2370 if (
uint64_t InstrNo =
MI.peekDebugInstrNum()) {
2371 auto InstrAndPos = std::make_pair(&
MI, CurInst);
2373 DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));
2376 assert(InsertResult.second);
2387 for (
auto Location : MTracker->
locations()) {
2390 if (
P.isPHI() &&
P.getLoc() ==
Idx.asU64())
2394 auto &TransferMap = MLocTransfer[CurBB];
2395 auto Result = TransferMap.insert(std::make_pair(
Idx.asU64(),
P));
2402 for (
auto &
P : MTracker->
Masks) {
2403 BlockMasks[CurBB].clearBitsNotInMask(
P.first->getRegMask(), BVWords);
2409 for (
auto Location : MTracker->
locations()) {
2427 for (
unsigned Bit : BV.
set_bits()) {
2430 auto &TransferMap = MLocTransfer[
I];
2439 TransferMap.insert(std::make_pair(
Idx.asU64(), NotGeneratedNum));
2444 ValueID = NotGeneratedNum;
2450bool InstrRefBasedLDV::mlocJoin(
2454 bool Changed =
false;
2465 return BBToOrder.find(
A)->second < BBToOrder.find(
B)->second;
2470 if (BlockOrders.size() == 0) {
2475 <<
" from entry which may lead out of "
2476 "bound access to VarLocs\n");
2482 for (
auto Location : MTracker->
locations()) {
2487 ValueIDNum FirstVal = OutLocs[*BlockOrders[0]][
Idx.asU64()];
2492 if (InLocs[
Idx.asU64()] != FirstVal) {
2493 InLocs[
Idx.asU64()] = FirstVal;
2501 bool Disagree =
false;
2502 for (
unsigned int I = 1;
I < BlockOrders.size(); ++
I) {
2504 const ValueIDNum &PredLiveOut = OutLocs[*PredMBB][
Idx.asU64()];
2507 if (FirstVal == PredLiveOut)
2520 InLocs[
Idx.asU64()] = FirstVal;
2529void InstrRefBasedLDV::findStackIndexInterference(
2549 if (!Pair.first.second)
2555void InstrRefBasedLDV::placeMLocPHIs(
2559 findStackIndexInterference(StackUnits);
2571 for (
auto Location : MTracker->
locations()) {
2580 bool AnyIllegal =
false;
2589 FoundRegUnits.
insert(*URoot);
2595 NormalLocsToPHI.
insert(L);
2605 auto CollectPHIsForLoc = [&](
LocIdx L) {
2609 const auto &TransferFunc = MLocTransfer[
MBB->
getNumber()];
2610 if (TransferFunc.contains(L))
2617 if (!DefBlocks.
empty())
2623 BlockPHIPlacement(AllBlocks, DefBlocks, PHIBlocks);
2626 auto InstallPHIsAtLoc = [&PHIBlocks, &MInLocs](
LocIdx L) {
2632 for (
LocIdx L : NormalLocsToPHI) {
2633 CollectPHIsForLoc(L);
2635 InstallPHIsAtLoc(L);
2641 for (
unsigned Idx : StackUnits) {
2644 CollectPHIsForLoc(L);
2645 InstallPHIsAtLoc(L);
2651 unsigned ThisSize, ThisOffset;
2652 std::tie(ThisSize, ThisOffset) = Pair.first;
2658 InstallPHIsAtLoc(ThisL);
2664 for (
Register R : RegUnitsToPHIUp) {
2666 CollectPHIsForLoc(L);
2669 InstallPHIsAtLoc(L);
2679 InstallPHIsAtLoc(AliasLoc);
2684void InstrRefBasedLDV::buildMLocValueMap(
2687 std::priority_queue<unsigned int, std::vector<unsigned int>,
2688 std::greater<unsigned int>>
2699 for (
unsigned int I = 0;
I < BBToOrder.size(); ++
I) {
2701 OnWorklist.
insert(OrderToBB[
I]);
2702 AllBlocks.
insert(OrderToBB[
I]);
2706 for (
auto Location : MTracker->
locations())
2715 placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer);
2726 while (!Worklist.empty() || !Pending.empty()) {
2730 while (!Worklist.empty()) {
2737 InLocsChanged = mlocJoin(*
MBB, Visited, MOutLocs, MInLocs[*
MBB]);
2738 InLocsChanged |= Visited.
insert(
MBB).second;
2751 for (
auto &
P : MLocTransfer[CurBB]) {
2752 if (
P.second.getBlock() == CurBB &&
P.second.isPHI()) {
2755 ToRemap.
push_back(std::make_pair(
P.first, NewID));
2758 assert(
P.second.getBlock() == CurBB);
2759 ToRemap.
push_back(std::make_pair(
P.first,
P.second));
2765 for (
auto &
P : ToRemap)
2771 bool OLChanged =
false;
2772 for (
auto Location : MTracker->
locations()) {
2788 unsigned Order = BBToOrder[s];
2789 if (Order > BBToOrder[
MBB]) {
2791 if (OnWorklist.
insert(s).second)
2792 Worklist.push(Order);
2795 if (OnPending.
insert(s).second)
2796 Pending.push(Order);
2801 Worklist.swap(Pending);
2806 assert(Pending.empty() &&
"Pending should be empty");
2813void InstrRefBasedLDV::BlockPHIPlacement(
2822 IDF.setLiveInBlocks(AllBlocks);
2823 IDF.setDefiningBlocks(DefBlocks);
2824 IDF.calculate(PHIBlocks);
2827bool InstrRefBasedLDV::pickVPHILoc(
2833 if (BlockOrders.
empty())
2840 auto FirstValueIt = LiveOuts.
find(BlockOrders[0]);
2841 if (FirstValueIt == LiveOuts.end())
2843 const DbgValue &FirstValue = *FirstValueIt->second;
2845 for (
const auto p : BlockOrders) {
2846 auto OutValIt = LiveOuts.find(p);
2847 if (OutValIt == LiveOuts.end())
2850 const DbgValue &OutVal = *OutValIt->second;
2873 if (FirstValOp != OutValOp) {
2894 std::optional<ValueIDNum> JoinedOpLoc =
2895 pickOperandPHILoc(
Idx,
MBB, LiveOuts, MOutLocs, BlockOrders);
2903 OutValues.
append(NewDbgOps);
2907std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc(
2917 for (
const auto p : BlockOrders) {
2918 auto OutValIt = LiveOuts.find(p);
2919 assert(OutValIt != LiveOuts.end());
2920 const DbgValue &OutVal = *OutValIt->second;
2922 DbgOp OutValOp = DbgOpStore.
find(OutValOpID);
2935 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2936 if (MOutLocs[*p][
I] == ValToLookFor)
2947 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2949 if (MOutLocs[*p][
I] == MPHI)
2960 for (
unsigned int I = 1;
I < Locs.
size(); ++
I) {
2961 auto &LocVec = Locs[
I];
2963 std::set_intersection(CandidateLocs.
begin(), CandidateLocs.
end(),
2964 LocVec.begin(), LocVec.end(), std::inserter(NewCandidates, NewCandidates.
begin()));
2965 CandidateLocs = std::move(NewCandidates);
2967 if (CandidateLocs.
empty())
2968 return std::nullopt;
2980bool InstrRefBasedLDV::vlocJoin(
2985 bool Changed =
false;
2991 return BBToOrder[
A] < BBToOrder[
B];
2996 unsigned CurBlockRPONum = BBToOrder[&
MBB];
3002 int BackEdgesStart = 0;
3003 for (
auto *p : BlockOrders) {
3006 if (!BlocksToExplore.
contains(p)) {
3012 DbgValue &OutLoc = *VLOCOutLocs.find(p)->second;
3016 unsigned ThisBBRPONum = BBToOrder[
p];
3017 if (ThisBBRPONum < CurBlockRPONum)
3020 Values.
push_back(std::make_pair(p, &OutLoc));
3026 if (Bail || Values.
size() == 0)
3032 const DbgValue &FirstVal = *Values[0].second;
3038 Changed = LiveIn != FirstVal;
3047 for (
const auto &V : Values) {
3048 if (!
V.second->Properties.isJoinable(FirstVal.
Properties))
3052 if (!
V.second->hasJoinableLocOps(FirstVal))
3057 bool Disagree =
false;
3058 for (
auto &V : Values) {
3059 if (*
V.second == FirstVal)
3065 if (
V.second->hasIdenticalValidLocOps(FirstVal))
3072 std::distance(Values.begin(), &V) >= BackEdgesStart)
3080 Changed = LiveIn != FirstVal;
3087 Changed = LiveIn != VPHI;
3094void InstrRefBasedLDV::getBlocksForScope(
3114 for (
const auto *
MBB : BlocksToExplore) {
3124 if (BlocksToExplore.count(succ))
3126 if (!ArtificialBlocks.count(succ))
3129 DFS.push_back({succ, succ->succ_begin()});
3133 while (!DFS.empty()) {
3137 if (CurSucc == CurBB->
succ_end()) {
3144 if (!ToAdd.
count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {
3146 DFS.push_back({*CurSucc, (*CurSucc)->succ_begin()});
3154 BlocksToExplore.insert_range(ToAdd);
3157void InstrRefBasedLDV::buildVLocValueMap(
3167 std::priority_queue<unsigned int, std::vector<unsigned int>,
3168 std::greater<unsigned int>>
3179 getBlocksForScope(DILoc, BlocksToExplore, AssignBlocks);
3185 if (BlocksToExplore.
size() == 1)
3192 for (
const auto *
MBB : BlocksToExplore)
3198 for (
const auto *
MBB : BlocksToExplore)
3202 for (
unsigned int I : BlockOrderNums)
3204 BlockOrderNums.clear();
3205 unsigned NumBlocks = BlockOrders.
size();
3215 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3224 LiveOutIdx.reserve(NumBlocks);
3225 LiveInIdx.reserve(NumBlocks);
3226 for (
unsigned I = 0;
I < NumBlocks; ++
I) {
3227 LiveOutIdx[BlockOrders[
I]] = &LiveOuts[
I];
3228 LiveInIdx[BlockOrders[
I]] = &LiveIns[
I];
3238 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3240 LiveIns[
I] = EmptyDbgValue;
3241 LiveOuts[
I] = EmptyDbgValue;
3248 auto &TransferFunc = AllTheVLocs[ExpMBB->getNumber()].Vars;
3249 if (TransferFunc.contains(
VarID))
3257 if (DefBlocks.
size() == 1) {
3258 placePHIsForSingleVarDefinition(MutBlocksToExplore, *DefBlocks.
begin(),
3259 AllTheVLocs,
VarID, Output);
3264 BlockPHIPlacement(MutBlocksToExplore, DefBlocks, PHIBlocks);
3268 unsigned BlockNo = PHIMBB->getNumber();
3269 DbgValue *LiveIn = LiveInIdx[PHIMBB];
3273 for (
auto *
MBB : BlockOrders) {
3274 Worklist.push(BBToOrder[
MBB]);
3285 bool FirstTrip =
true;
3286 while (!Worklist.empty() || !Pending.empty()) {
3287 while (!Worklist.empty()) {
3288 auto *
MBB = OrderToBB[Worklist.top()];
3292 auto LiveInsIt = LiveInIdx.find(
MBB);
3293 assert(LiveInsIt != LiveInIdx.end());
3294 DbgValue *LiveIn = LiveInsIt->second;
3298 bool InLocsChanged =
3299 vlocJoin(*
MBB, LiveOutIdx, BlocksToExplore, *LiveIn);
3314 if (pickVPHILoc(JoinedOps, *
MBB, LiveOutIdx, MOutLocs, Preds)) {
3316 InLocsChanged |= NewLocPicked;
3322 if (!InLocsChanged && !FirstTrip)
3326 bool OLChanged =
false;
3330 auto TransferIt = VTracker.
Vars.find(
VarID);
3331 if (TransferIt != VTracker.
Vars.end()) {
3335 if (*LiveOut != NewVal) {
3341 if (*LiveOut != TransferIt->second) {
3342 *LiveOut = TransferIt->second;
3348 if (*LiveOut != *LiveIn) {
3363 if (!LiveInIdx.contains(s))
3366 unsigned Order = BBToOrder[s];
3367 if (Order > BBToOrder[
MBB]) {
3368 if (OnWorklist.
insert(s).second)
3369 Worklist.push(Order);
3370 }
else if (OnPending.
insert(s).second && (FirstTrip || OLChanged)) {
3371 Pending.push(Order);
3375 Worklist.swap(Pending);
3385 for (
auto *
MBB : BlockOrders) {
3395 Var.getFragment() &&
3396 "Fragment info missing during value prop");
3401 BlockOrders.clear();
3402 BlocksToExplore.clear();
3405void InstrRefBasedLDV::placePHIsForSingleVarDefinition(
3432 for (
auto *ScopeBlock : InScopeBlocks) {
3436 Output[ScopeBlock->getNumber()].push_back({
VarID,
Value});
3443#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3446 for (
const auto &
P : mloc_transfer) {
3449 dbgs() <<
"Loc " << foo <<
" --> " << bar <<
"\n";
3458 EmptyExpr = DIExpression::get(Context, {});
3460 auto hasNonArtificialLocation = [](
const MachineInstr &
MI) ->
bool {
3462 return DL.getLine() != 0;
3468 unsigned int Size = 0;
3469 for (
auto &
MBB : MF) {
3472 ArtificialBlocks.insert(&
MBB);
3477 unsigned int RPONumber = 0;
3478 OrderToBB.reserve(
Size);
3479 BBToOrder.reserve(
Size);
3482 OrderToBB.push_back(
MBB);
3483 BBToOrder[
MBB] = RPONumber;
3490 if (!BBToOrder.contains(&
MBB))
3496#ifdef EXPENSIVE_CHECKS
3499 if (MF.DebugValueSubstitutions.size() > 2) {
3500 for (
auto It = MF.DebugValueSubstitutions.begin();
3501 It != std::prev(MF.DebugValueSubstitutions.end()); ++It) {
3502 assert(It->Src != std::next(It)->Src &&
"Duplicate variable location "
3503 "substitution seen");
3512void InstrRefBasedLDV::makeDepthFirstEjectionMap(
3514 const ScopeToDILocT &ScopeToDILocation,
3515 ScopeToAssignBlocksT &ScopeToAssignBlocks) {
3522 WorkStack.
push_back({TopScope, TopScope->getChildren().
size() - 1});
3524 while (!WorkStack.
empty()) {
3525 auto &ScopePosition = WorkStack.
back();
3527 ssize_t ChildNum = ScopePosition.second--;
3530 if (ChildNum >= 0) {
3533 auto &ChildScope =
Children[ChildNum];
3535 std::make_pair(ChildScope, ChildScope->getChildren().size() - 1));
3542 auto DILocationIt = ScopeToDILocation.find(WS);
3543 if (DILocationIt != ScopeToDILocation.end()) {
3544 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3545 ScopeToAssignBlocks.find(WS)->second);
3546 for (
const auto *
MBB : BlocksToExplore) {
3548 if (EjectionMap[BBNum] == 0)
3552 BlocksToExplore.clear();
3558bool InstrRefBasedLDV::depthFirstVLocAndEmit(
3559 unsigned MaxNumBlocks,
const ScopeToDILocT &ScopeToDILocation,
3560 const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,
3563 bool ShouldEmitDebugEntryValues) {
3565 CalleeSavedRegs, ShouldEmitDebugEntryValues);
3576 makeDepthFirstEjectionMap(EjectionMap, ScopeToDILocation,
3577 ScopeToAssignBlocks);
3584 AllTheVLocs[BBNum].
clear();
3590 TTracker->
loadInlocs(
MBB, MInLocs[
MBB], DbgOpStore, Output[BBNum], NumLocs);
3594 for (
auto &
MI :
MBB) {
3595 process(
MI, &MOutLocs, &MInLocs);
3604 Output[BBNum].clear();
3605 AllTheVLocs[BBNum].
clear();
3611 unsigned HighestDFSIn = 0;
3614 while (!WorkStack.
empty()) {
3615 auto &ScopePosition = WorkStack.
back();
3617 ssize_t ChildNum = ScopePosition.second++;
3624 auto DILocIt = ScopeToDILocation.find(WS);
3625 if (HighestDFSIn <= WS->getDFSIn() && DILocIt != ScopeToDILocation.end()) {
3627 auto &VarsWeCareAbout = ScopeToVars.find(WS)->second;
3628 auto &BlocksInScope = ScopeToAssignBlocks.find(WS)->second;
3630 buildVLocValueMap(DILoc, VarsWeCareAbout, BlocksInScope, Output, MOutLocs,
3631 MInLocs, AllTheVLocs);
3634 HighestDFSIn = std::max(HighestDFSIn, WS->
getDFSIn());
3638 if (ChildNum < (ssize_t)
Children.size()) {
3640 auto &ChildScope =
Children[ChildNum];
3641 WorkStack.
push_back(std::make_pair(ChildScope, 0));
3647 auto DILocationIt = ScopeToDILocation.find(WS);
3648 if (DILocationIt == ScopeToDILocation.end())
3651 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3652 ScopeToAssignBlocks.find(WS)->second);
3653 for (
const auto *
MBB : BlocksToExplore)
3657 BlocksToExplore.clear();
3666 for (
auto *
MBB : ArtificialBlocks)
3670 return emitTransfers();
3673bool InstrRefBasedLDV::emitTransfers() {
3687 for (
const auto &Pair :
P.Insts)
3692 if (
P.Pos->isTerminator())
3696 for (
const auto &Pair :
P.Insts)
3708 bool ShouldEmitDebugEntryValues,
3710 unsigned InputDbgValLimit) {
3717 this->DomTree = DomTree;
3728 STI.getFrameLowering()->stackProbeFunctionModifiesSP();
3729 if (AdjustsStackInCalls)
3730 StackProbeSymbolName = STI.getTargetLowering()->getStackProbeSymbolName(MF);
3742 for (
auto &
MBB : MF)
3753 produceMLocTransferFunction(MF, MLocTransfer,
MaxNumBlocks);
3766 buildMLocValueMap(MF, MInLocs, MOutLocs, MLocTransfer);
3770 for (
auto &DBG_PHI : DebugPHINumToValue) {
3772 if (!DBG_PHI.ValueRead)
3786 Num = ResolvedValue;
3795 VTracker = &vlocs[CurBB];
3799 for (
auto &
MI : *
MBB) {
3800 process(
MI, &MOutLocs, &MInLocs);
3818 unsigned VarAssignCount = 0;
3822 for (
auto &idx : VTracker->
Vars) {
3825 assert(ScopeLoc !=
nullptr);
3829 assert(Scope !=
nullptr);
3832 ScopeToAssignBlocks[
Scope].insert(VTracker->
MBB);
3833 ScopeToDILocation[
Scope] = ScopeLoc;
3838 bool Changed =
false;
3844 VarAssignCount > InputDbgValLimit) {
3845 LLVM_DEBUG(
dbgs() <<
"Disabling InstrRefBasedLDV: " << MF.getName()
3848 <<
" variable assignments, exceeding limits.\n");
3853 Changed = depthFirstVLocAndEmit(
3854 MaxNumBlocks, ScopeToDILocation, ScopeToVars, ScopeToAssignBlocks,
3855 SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, ShouldEmitDebugEntryValues);
3864 ArtificialBlocks.clear();
3868 DebugInstrNumToInstr.clear();
3869 DebugPHINumToValue.clear();
3870 OverlapFragments.
clear();
3871 SeenFragments.
clear();
3872 SeenDbgPHIs.clear();
3898 LDVSSABlock *ParentBlock;
3899 BlockValueNum PHIValNum;
3900 LDVSSAPhi(BlockValueNum PHIValNum, LDVSSABlock *ParentBlock)
3901 : ParentBlock(ParentBlock), PHIValNum(PHIValNum) {}
3903 LDVSSABlock *
getParent() {
return ParentBlock; }
3908class LDVSSABlockIterator {
3911 LDVSSAUpdater &Updater;
3914 LDVSSAUpdater &Updater)
3915 : PredIt(PredIt), Updater(Updater) {}
3917 bool operator!=(
const LDVSSABlockIterator &OtherIt)
const {
3918 return OtherIt.PredIt != PredIt;
3921 LDVSSABlockIterator &operator++() {
3935 LDVSSAUpdater &Updater;
3941 : BB(BB), Updater(Updater) {}
3944 return LDVSSABlockIterator(BB.
succ_begin(), Updater);
3948 return LDVSSABlockIterator(BB.
succ_end(), Updater);
3952 LDVSSAPhi *newPHI(BlockValueNum
Value) {
3953 PHIList.emplace_back(
Value,
this);
3954 return &PHIList.back();
3958 PHIListT &phis() {
return PHIList; }
3964class LDVSSAUpdater {
3979 : Loc(
L), MLiveIns(MLiveIns) {}
3982 for (
auto &
Block : BlockMap)
3983 delete Block.second;
3990 ~LDVSSAUpdater() { reset(); }
3995 auto [It,
Inserted] = BlockMap.try_emplace(BB);
3997 It->second =
new LDVSSABlock(*BB, *
this);
4003 BlockValueNum getValue(LDVSSABlock *LDVBB) {
4004 return MLiveIns[LDVBB->BB][Loc.
asU64()].asU64();
4008LDVSSABlock *LDVSSABlockIterator::operator*() {
4009 return Updater.getSSALDVBlock(*PredIt);
4015 out <<
"SSALDVPHI " <<
PHI.PHIValNum;
4041 class PHI_iterator {
4067 return PHI_iterator(
PHI,
true);
4075 Preds->
push_back(BB->Updater.getSSALDVBlock(Pred));
4081 static BlockValueNum
GetPoisonVal(LDVSSABlock *BB, LDVSSAUpdater *Updater) {
4085 BlockValueNum Num =
ValueIDNum(BB->BB.getNumber(), 0, Updater->Loc).
asU64();
4086 Updater->PoisonMap[&BB->BB] = Num;
4096 LDVSSAUpdater *Updater) {
4097 BlockValueNum PHIValNum = Updater->getValue(BB);
4098 LDVSSAPhi *
PHI = BB->newPHI(PHIValNum);
4099 Updater->PHIs[PHIValNum] =
PHI;
4106 PHI->IncomingValues.push_back(std::make_pair(Pred, Val));
4111 static LDVSSAPhi *
ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater) {
4112 return Updater->PHIs.lookup(Val);
4118 LDVSSAPhi *
PHI = ValueIsPHI(Val, Updater);
4119 if (
PHI &&
PHI->IncomingValues.size() == 0)
4131std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(
4136 auto SeenDbgPHIIt = SeenDbgPHIs.find(std::make_pair(&Here, InstrNum));
4137 if (SeenDbgPHIIt != SeenDbgPHIs.end())
4138 return SeenDbgPHIIt->second;
4140 std::optional<ValueIDNum>
Result =
4141 resolveDbgPHIsImpl(MF, MLiveOuts, MLiveIns, Here, InstrNum);
4142 SeenDbgPHIs.insert({std::make_pair(&Here, InstrNum),
Result});
4146std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
4151 auto RangePair = std::equal_range(DebugPHINumToValue.begin(),
4152 DebugPHINumToValue.end(), InstrNum);
4153 auto LowerIt = RangePair.first;
4154 auto UpperIt = RangePair.second;
4157 if (LowerIt == UpperIt)
4158 return std::nullopt;
4164 auto DBGPHIRange =
make_range(LowerIt, UpperIt);
4165 for (
const DebugPHIRecord &DBG_PHI : DBGPHIRange)
4166 if (!DBG_PHI.ValueRead)
4167 return std::nullopt;
4170 if (std::distance(LowerIt, UpperIt) == 1)
4171 return *LowerIt->ValueRead;
4177 LocIdx Loc = *LowerIt->ReadLoc;
4186 LDVSSAUpdater Updater(Loc, MLiveIns);
4194 for (
const auto &DBG_PHI : DBGPHIRange) {
4195 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4200 LDVSSABlock *HereBlock = Updater.getSSALDVBlock(Here.
getParent());
4201 const auto &AvailIt = AvailableValues.
find(HereBlock);
4202 if (AvailIt != AvailableValues.
end()) {
4211 BlockValueNum ResultInt = Impl.GetValue(Updater.getSSALDVBlock(Here.
getParent()));
4228 for (
const auto &DBG_PHI : DBGPHIRange) {
4229 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4231 ValidatedValues.
insert(std::make_pair(
Block, Num));
4237 llvm::sort(SortedPHIs, [&](LDVSSAPhi *
A, LDVSSAPhi *
B) {
4238 return BBToOrder[&
A->getParent()->BB] < BBToOrder[&
B->getParent()->BB];
4241 for (
auto &
PHI : SortedPHIs) {
4245 for (
auto &PHIIt :
PHI->IncomingValues) {
4247 if (Updater.PoisonMap.contains(&PHIIt.first->BB))
4248 return std::nullopt;
4251 const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB];
4253 auto VVal = ValidatedValues.
find(PHIIt.first);
4254 if (VVal == ValidatedValues.
end()) {
4259 ValueToCheck = ThisBlockValueNum;
4263 ValueToCheck = VVal->second;
4266 if (BlockLiveOuts[Loc.
asU64()] != ValueToCheck)
4267 return std::nullopt;
4271 ValidatedValues.
insert({
PHI->ParentBlock, ThisBlockValueNum});
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static cl::opt< unsigned > MaxNumBlocks("debug-ata-max-blocks", cl::init(10000), cl::desc("Maximum num basic blocks before debug info dropped"), cl::Hidden)
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#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
This file defines the DenseMap class.
This file contains constants used for implementing Dwarf debug support.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
Compute iterated dominance frontiers using a linear time algorithm.
const HexagonInstrInfo * TII
static cl::opt< unsigned > StackWorkingSetLimit("livedebugvalues-max-stack-slots", cl::Hidden, cl::desc("livedebugvalues-stack-ws-limit"), cl::init(250))
static cl::opt< bool > EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden, cl::desc("Act like old LiveDebugValues did"), cl::init(false))
static cl::opt< unsigned > InputBBLimit("livedebugvalues-input-bb-limit", cl::desc("Maximum input basic blocks before DBG_VALUE limit applies"), cl::init(10000), cl::Hidden)
Register const TargetRegisterInfo * TRI
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file describes how to lower LLVM code to machine code.
Class storing the complete set of values that are observed by DbgValues within the current function.
DbgOp find(DbgOpID ID) const
Returns the DbgOp associated with ID.
DbgOpID insert(DbgOp Op)
If Op does not already exist in this map, it is inserted and the corresponding DbgOpID is returned.
Meta qualifiers for a value.
const DIExpression * DIExpr
bool isJoinable(const DbgValueProperties &Other) const
unsigned getLocationOpCount() const
Class recording the (high level) value of a variable.
int BlockNo
For a NoVal or VPHI DbgValue, which block it was generated in.
DbgValueProperties Properties
Qualifiers for the ValueIDNum above.
ArrayRef< DbgOpID > getDbgOpIDs() const
void setDbgOpIDs(ArrayRef< DbgOpID > NewIDs)
void dump(const MLocTracker *MTrack=nullptr, const DbgOpIDMap *OpStore=nullptr) const
bool isUnjoinedPHI() const
DbgOpID getDbgOpID(unsigned Index) const
KindT Kind
Discriminator for whether this is a constant or an in-program value.
unsigned getLocationOpCount() const
Mapping from DebugVariable to/from a unique identifying number.
const VarAndLoc & lookupDVID(DebugVariableID ID) const
DebugVariableID insertDVID(DebugVariable &Var, const DILocation *Loc)
DebugVariableID getDVID(const DebugVariable &Var) const
DenseMap< const LexicalScope *, const DILocation * > ScopeToDILocT
Mapping from lexical scopes to a DILocation in that scope.
std::optional< LocIdx > findLocationForMemOperand(const MachineInstr &MI)
SmallVector< SmallVector< VarAndLoc, 8 >, 8 > LiveInsT
Vector (per block) of a collection (inner smallvector) of live-ins.
LLVM_ABI_FOR_TEST InstrRefBasedLDV()
Default construct and initialize the pass.
DIExpression::FragmentInfo FragmentInfo
SmallDenseMap< const MachineBasicBlock *, DbgValue *, 16 > LiveIdxT
Live in/out structure for the variable values: a per-block map of variables to their values.
bool hasFoldedStackStore(const MachineInstr &MI)
bool isCalleeSaved(LocIdx L) const
DenseMap< const LexicalScope *, SmallPtrSet< MachineBasicBlock *, 4 > > ScopeToAssignBlocksT
Mapping from lexical scopes to blocks where variables in that scope are assigned.
bool isCalleeSavedReg(Register R) const
LLVM_DUMP_METHOD void dump_mloc_transfer(const MLocTransferMap &mloc_transfer) const
DenseMap< const LexicalScope *, SmallSet< DebugVariableID, 4 > > ScopeToVarsT
Mapping from lexical scopes to variables in that scope.
Handle-class for a particular "location".
static LocIdx MakeIllegalLoc()
Tracker for what values are in machine locations.
unsigned getLocSizeInBits(LocIdx L) const
How large is this location (aka, how wide is a value defined there?).
bool isRegisterTracked(Register R)
Is register R currently tracked by MLocTracker?
LLVM_ABI_FOR_TEST std::optional< SpillLocationNo > getOrTrackSpillLoc(SpillLoc L)
Find LocIdx for SpillLoc L, creating a new one if it's not tracked.
void loadFromArray(ValueTable &Locs, unsigned NewCurBB)
Load values for each location from array of ValueIDNums.
IndexedMap< unsigned, LocIdxToIndexFunctor > LocIdxToLocID
Inverse map of LocIDToLocIdx.
unsigned getSpillIDWithIdx(SpillLocationNo Spill, unsigned Idx)
Given a spill number, and a slot within the spill, calculate the ID number for that location.
iterator_range< MLocIterator > locations()
Return a range over all locations currently tracked.
SmallSet< Register, 8 > SPAliases
When clobbering register masks, we chose to not believe the machine model and don't clobber SP.
unsigned getLocID(Register Reg)
Produce location ID number for a Register.
const TargetLowering & TLI
const TargetRegisterInfo & TRI
unsigned NumRegs
Cached local copy of the number of registers the target has.
unsigned getNumLocs() const
DenseMap< StackSlotPos, unsigned > StackSlotIdxes
Map from a size/offset pair describing a position in a stack slot, to a numeric identifier for that p...
LocIdx lookupOrTrackRegister(unsigned ID)
void setReg(Register R, ValueIDNum ValueID)
Set a register to a value number.
SpillLocationNo locIDToSpill(unsigned ID) const
Return the spill number that a location ID corresponds to.
void reset()
Wipe any un-necessary location records after traversing a block.
DenseMap< unsigned, StackSlotPos > StackIdxesToPos
Inverse of StackSlotIdxes.
std::string IDAsString(const ValueIDNum &Num) const
void writeRegMask(const MachineOperand *MO, unsigned CurBB, unsigned InstID)
Record a RegMask operand being executed.
std::pair< unsigned short, unsigned short > StackSlotPos
Pair for describing a position within a stack slot – first the size in bits, then the offset.
const TargetInstrInfo & TII
bool isSpill(LocIdx Idx) const
Return true if Idx is a spill machine location.
LocIdx getRegMLoc(Register R)
Determine the LocIdx of an existing register.
MachineInstrBuilder emitLoc(const SmallVectorImpl< ResolvedDbgOp > &DbgOps, const DebugVariable &Var, const DILocation *DILoc, const DbgValueProperties &Properties)
Create a DBG_VALUE based on debug operands DbgOps.
void setMLoc(LocIdx L, ValueIDNum Num)
Set a locaiton to a certain value.
LocToValueType LocIdxToIDNum
Map of LocIdxes to the ValueIDNums that they store.
std::vector< LocIdx > LocIDToLocIdx
"Map" of machine location IDs (i.e., raw register or spill number) to the LocIdx key / number for tha...
SmallVector< std::pair< const MachineOperand *, unsigned >, 32 > Masks
Collection of register mask operands that have been observed.
unsigned NumSlotIdxes
Number of slot indexes the target has – distinct segments of a stack slot that can take on the value ...
UniqueVector< SpillLoc > SpillLocs
Unique-ification of spill.
ValueIDNum readMLoc(LocIdx L)
Read the value of a particular location.
void setMPhis(unsigned NewCurBB)
Reset all locations to contain a PHI value at the designated block.
ValueIDNum readReg(Register R)
void defReg(Register R, unsigned BB, unsigned Inst)
Record a definition of the specified register at the given block / inst.
LLVM_DUMP_METHOD void dump()
LLVM_ABI_FOR_TEST LocIdx trackRegister(unsigned ID)
Create a LocIdx for an untracked register ID.
LLVM_ABI_FOR_TEST MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const TargetLowering &TLI)
LLVM_DUMP_METHOD void dump_mloc_map()
StackSlotPos locIDToSpillIdx(unsigned ID) const
Returns the spill-slot size/offs that a location ID corresponds to.
LocIdx getSpillMLoc(unsigned SpillID)
std::string LocIdxToName(LocIdx Idx) const
Thin wrapper around an integer – designed to give more type safety to spill location numbers.
Collection of DBG_VALUEs observed when traversing a block.
SmallDenseMap< DebugVariableID, const DILocation *, 8 > Scopes
SmallMapVector< DebugVariableID, DbgValue, 8 > Vars
Map DebugVariable to the latest Value it's defined to have.
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
Unique identifier for a value defined by an instruction, as a value type.
static ValueIDNum fromU64(uint64_t v)
std::string asString(const std::string &mlocname) const
static LLVM_ABI_FOR_TEST ValueIDNum EmptyValue
static LLVM_ABI_FOR_TEST ValueIDNum TombstoneValue
uint64_t getBlock() const
LocationAndQuality(LocIdx L, LocationQuality Q)
LocationQuality getQuality() const
Tracker for converting machine value locations and variable values into variable locations (the outpu...
const DebugVariableMap & DVMap
TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker, MachineFunction &MF, const DebugVariableMap &DVMap, const TargetRegisterInfo &TRI, const BitVector &CalleeSavedRegs, bool ShouldEmitDebugEntryValues)
DenseSet< DebugVariableID > UseBeforeDefVariables
The set of variables that are in UseBeforeDefs and can become a location once the relevant value is d...
const BitVector & CalleeSavedRegs
void loadInlocs(MachineBasicBlock &MBB, ValueTable &MLocs, DbgOpIDMap &DbgOpStore, const SmallVectorImpl< std::pair< DebugVariableID, DbgValue > > &VLocs, unsigned NumLocs)
Load object with live-in variable values.
const TargetLowering * TLI
void addUseBeforeDef(DebugVariableID VarID, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOp > &DbgOps, unsigned Inst)
Record that Var has value ID, a value that becomes available later in the function.
SmallVector< ValueIDNum, 32 > VarLocs
Local cache of what-value-is-in-what-LocIdx.
MLocTracker * MTracker
This machine location tracker is assumed to always contain the up-to-date value mapping for all machi...
void transferMlocs(LocIdx Src, LocIdx Dst, MachineBasicBlock::iterator Pos)
Transfer variables based on Src to be based on Dst.
std::optional< LocationQuality > getLocQualityIfBetter(LocIdx L, LocationQuality Min) const
SmallVector< std::pair< DebugVariableID, MachineInstr * >, 4 > PendingDbgValues
Temporary cache of DBG_VALUEs to be entered into the Transfers collection.
bool isEntryValueVariable(const DebugVariable &Var, const DIExpression *Expr) const
void checkInstForNewValues(unsigned Inst, MachineBasicBlock::iterator pos)
After the instruction at index Inst and position pos has been processed, check whether it defines a v...
const TargetInstrInfo * TII
DenseMap< LocIdx, SmallSet< DebugVariableID, 4 > > ActiveMLocs
Map from LocIdxes to which DebugVariables are based that location.
MachineInstrBuilder emitMOLoc(const MachineOperand &MO, const DebugVariable &Var, const DbgValueProperties &Properties)
bool isEntryValueValue(const ValueIDNum &Val) const
const TargetRegisterInfo & TRI
void redefVar(const MachineInstr &MI)
Change a variable value after encountering a DBG_VALUE inside a block.
bool recoverAsEntryValue(DebugVariableID VarID, const DbgValueProperties &Prop, const ValueIDNum &Num)
bool isCalleeSaved(LocIdx L) const
void clobberMloc(LocIdx MLoc, MachineBasicBlock::iterator Pos, bool MakeUndef=true)
Account for a location mloc being clobbered.
void flushDbgValues(MachineBasicBlock::iterator Pos, MachineBasicBlock *MBB)
Helper to move created DBG_VALUEs into Transfers collection.
DenseMap< DebugVariableID, ResolvedDbgValue > ActiveVLocs
Map from DebugVariable to it's current location and qualifying meta information.
DenseMap< unsigned, SmallVector< UseBeforeDef, 1 > > UseBeforeDefs
Map from instruction index (within the block) to the set of UseBeforeDefs that become defined at that...
void clobberMloc(LocIdx MLoc, ValueIDNum OldValue, MachineBasicBlock::iterator Pos, bool MakeUndef=true)
Overload that takes an explicit value OldValue for when the value in MLoc has changed and the Transfe...
SmallVector< Transfer, 32 > Transfers
Collection of transfers (DBG_VALUEs) to be inserted.
bool ShouldEmitDebugEntryValues
void redefVar(const MachineInstr &MI, const DbgValueProperties &Properties, SmallVectorImpl< ResolvedDbgOp > &NewLocs)
Handle a change in variable location within a block.
void loadVarInloc(MachineBasicBlock &MBB, DbgOpIDMap &DbgOpStore, const SmallVectorImpl< ValueLocPair > &ValueToLoc, DebugVariableID VarID, DbgValue Value)
For a variable Var with the live-in value Value, attempts to resolve the DbgValue to a concrete DBG_V...
std::pair< ValueIDNum, LocationAndQuality > ValueLocPair
static bool ValueToLocSort(const ValueLocPair &A, const ValueLocPair &B)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
iterator_range< const_set_bits_iterator > set_bits() const
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
unsigned getNumElements() const
LLVM_ABI bool isImplicit() const
Return whether this is an implicit location description.
static bool fragmentsOverlap(const FragmentInfo &A, const FragmentInfo &B)
Check if fragments overlap between a pair of FragmentInfos.
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...
LLVM_ABI bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
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 std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
LLVM_ABI bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
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 ...
LLVM_ABI bool isSingleLocationExpression() const
Return whether the evaluated expression makes use of a single location at the start of the expression...
DILocalScope * getScope() const
Get the local scope for this variable.
bool isValidLocationForIntrinsic(const DILocation *DL) const
Check that a location is valid for this variable.
LLVM_ABI std::optional< uint64_t > getSizeInBits() const
Determines the size of the variable's type.
This class represents an Operation in the Expression.
Identifies a unique instance of a variable.
const DILocation * getInlinedAt() const
std::optional< FragmentInfo > getFragment() const
const DILocalVariable * getVariable() const
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
bool erase(const KeyT &Val)
void insert_range(Range &&R)
Inserts range of 'std::pair<KeyT, ValueT>' values into the map.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Implements a dense probed hash-table based set.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
DISubprogram * getSubprogram() const
Get the attached subprogram.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Determine the iterated dominance frontier, given a set of defining blocks, and optionally,...
StorageT::size_type size() const
This is an important class for using LLVM in a threaded context.
LexicalScope - This class is used to track scope information.
unsigned getDFSIn() const
SmallVectorImpl< LexicalScope * > & getChildren()
unsigned getDFSOut() const
LLVM_ABI void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary.
LLVM_ABI LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
LLVM_ABI void getMachineBasicBlocks(const DILocation *DL, SmallPtrSetImpl< const MachineBasicBlock * > &MBBs)
getMachineBasicBlocks - Populate given set using machine basic blocks which have machine instructions...
LexicalScope * getCurrentFunctionScope() const
getCurrentFunctionScope - Return lexical scope for the current function.
TypeSize getValue() const
Describe properties that are true of each instruction in the target description file.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
MCRegAliasIterator enumerates all registers aliasing Reg.
MCRegUnitRootIterator enumerates the root registers of a register unit.
bool isValid() const
Check if the iterator is at the end of the list.
unsigned getNumSubRegIndices() const
Return the number of sub-register indices understood by the target.
iterator_range< MCSubRegIterator > subregs(MCRegister Reg) const
Return an iterator range over all sub-registers of Reg, excluding Reg.
unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
iterator_range< MCRegUnitIterator > regunits(MCRegister Reg) const
Returns an iterator range over all regunits for Reg.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Iterator that enumerates the sub-registers of a Reg and the associated sub-register indices.
bool isValid() const
Returns true if this iterator is not yet at the end.
LLVMContext & getContext() const
instr_iterator instr_begin()
SmallVectorImpl< MachineBasicBlock * >::const_iterator const_succ_iterator
LLVM_ABI instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
succ_iterator succ_begin()
LLVM_ABI bool isEntryBlock() const
Returns true if this is the entry block of the function.
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
Instructions::iterator instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI std::string getFullName() const
Return a formatted string to identify this block and its parent function.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
instr_iterator insertAfterBundle(instr_iterator I, MachineInstr *MI)
If I is bundled then insert MI into the instruction list after the end of the bundle,...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool adjustsStack() const
Return true if this function adjusts the stack – e.g., when calling another function.
bool isDeadObjectIndex(int ObjectIdx) const
Returns true if the specified index corresponds to a dead object.
Replacement definition for a debug instruction reference.
SmallVector< DebugSubstitution, 8 > DebugValueSubstitutions
Debug value substitutions: a collection of DebugSubstitution objects, recording changes in where a va...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
static const unsigned int DebugOperandMemNumber
A reserved operand number representing the instructions memory operand, for instructions that have a ...
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
bool hasOneMemOperand() const
Return true if this instruction has exactly one MachineMemOperand.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getInstrRefOpIndex() const
unsigned getInstrRefInstrIndex() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
static unsigned getRegMaskSize(unsigned NumRegs)
Returns number of elements needed for a regmask array.
Register getReg() const
getReg - Returns the register number.
bool isDbgInstrRef() const
bool isFI() const
isFI - Tests if this is a MO_FrameIndex operand.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
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)
Special value supplied for machine level alias analysis.
virtual bool isAliased(const MachineFrameInfo *) const
Test whether the memory pointed to by this PseudoSourceValue may also be pointed to by an LLVM IR Val...
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
BlockValueNum getIncomingValue()
PHI_iterator(LDVSSAPhi *P, bool)
LDVSSABlock * getIncomingBlock()
bool operator!=(const PHI_iterator &X) const
PHI_iterator(LDVSSAPhi *P)
PHI_iterator & operator++()
bool operator==(const PHI_iterator &X) const
LDVSSABlockIterator BlkSucc_iterator
static BlockValueNum CreateEmptyPHI(LDVSSABlock *BB, unsigned NumPreds, LDVSSAUpdater *Updater)
CreateEmptyPHI - Create a (representation of a) PHI in the given block.
static BlockValueNum GetPoisonVal(LDVSSABlock *BB, LDVSSAUpdater *Updater)
GetPoisonVal - Normally creates an IMPLICIT_DEF instruction with a new register.
static BlkSucc_iterator BlkSucc_end(BlkT *BB)
static PHI_iterator PHI_begin(PhiT *PHI)
static void AddPHIOperand(LDVSSAPhi *PHI, BlockValueNum Val, LDVSSABlock *Pred)
AddPHIOperand - Add the specified value as an operand of the PHI for the specified predecessor block.
static void FindPredecessorBlocks(LDVSSABlock *BB, SmallVectorImpl< LDVSSABlock * > *Preds)
FindPredecessorBlocks - Put the predecessors of BB into the Preds vector.
static BlockValueNum GetPHIValue(LDVSSAPhi *PHI)
GetPHIValue - For the specified PHI instruction, return the value that it defines.
static LDVSSAPhi * ValueIsNewPHI(BlockValueNum Val, LDVSSAUpdater *Updater)
ValueIsNewPHI - Like ValueIsPHI but also check if the PHI has no source operands, i....
static PHI_iterator PHI_end(PhiT *PHI)
static LDVSSAPhi * ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater)
ValueIsPHI - Check if the instruction that defines the specified value is a PHI instruction.
static BlkSucc_iterator BlkSucc_begin(BlkT *BB)
Implements a dense probed hash-table based set with some number of buckets stored inline.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
void insert_range(Range &&R)
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void assign(size_type NumElts, ValueParamT Elt)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StackOffset holds a fixed and a scalable offset in bytes.
std::string str() const
str - Get the contents as an std::string.
constexpr const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
virtual void getCalleeSaves(const MachineFunction &MF, BitVector &SavedRegs) const
Returns the callee-saved registers as computed by determineCalleeSaves in the BitVector SavedRegs.
virtual StackOffset getFrameIndexReference(const MachineFunction &MF, int FI, Register &FrameReg) const
getFrameIndexReference - This method should return the base register and offset used to reference a f...
TargetInstrInfo - Interface to description of machine instruction set.
std::optional< DestSourcePair > isCopyLikeInstr(const MachineInstr &MI) const
virtual Register isStoreToStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const
Check for post-frame ptr elimination stack locations as well.
virtual Register isLoadFromStackSlotPostFE(const MachineInstr &MI, int &FrameIndex) const
Check for post-frame ptr elimination stack locations as well.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
unsigned getPointerSizeInBits(unsigned AS) const
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
iterator_range< regclass_iterator > regclasses() const
TypeSize getRegSizeInBits(const TargetRegisterClass &RC) const
Return the size in bits of a register from class RC.
unsigned getSubRegIdxSize(unsigned Idx) const
Get the size of the bit range covered by a sub-register index.
virtual StringRef getRegAsmName(MCRegister Reg) const
Return the assembly name for Reg.
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
virtual Register getFrameRegister(const MachineFunction &MF) const =0
Debug information queries.
virtual void getOffsetOpcodes(const StackOffset &Offset, SmallVectorImpl< uint64_t > &Ops) const
Gets the DWARF expression opcodes for Offset.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
LLVM_ABI std::string str() const
Return the twine contents as a std::string.
Twine concat(const Twine &Suffix) const
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
std::pair< iterator, bool > insert(const ValueT &V)
iterator find(const_arg_type_t< ValueT > V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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...
NodeAddr< DefNode * > Def
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.
MachineBasicBlock::instr_iterator getBundleStart(MachineBasicBlock::instr_iterator I)
Returns an iterator to the first instruction in the bundle containing I.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
APInt operator*(APInt a, uint64_t RHS)
bool operator!=(uint64_t V1, const APInt &V2)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LDVImpl * makeInstrRefBasedLiveDebugValues()
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
auto map_range(ContainerTy &&C, FuncTy F)
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&...Ranges)
Returns a concatenated range across two or more ranges.
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::tuple< const DIScope *, const DIScope *, const DILocalVariable * > VarID
A unique key that represents a debug variable.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
iterator_range< filter_iterator< detail::IterOfRange< RangeT >, PredicateT > > make_filter_range(RangeT &&Range, PredicateT Pred)
Convenience function that takes a range of elements and a predicate, and return a new filter_iterator...
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
void replace(R &&Range, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace which take ranges instead of having to pass begin/end explicitly.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
OutputIt replace_copy(R &&Range, OutputIt Out, const T &OldValue, const T &NewValue)
Provide wrappers to std::replace_copy which take ranges instead of having to pass begin/end explicitl...
bool equal(L &&LRange, R &&RRange)
Wrapper function around std::equal to detect if pair-wise elements between two ranges are the same.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
An ID used in the DbgOpIDMap (below) to lookup a stored DbgOp.
void dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const
static LLVM_ABI_FOR_TEST DbgOpID UndefID
TODO: Might pack better if we changed this to a Struct of Arrays, since MachineOperand is width 32,...
void dump(const MLocTracker *MTrack) const
A collection of ValueTables, one per BB in a function, with convenient accessor methods.
void ejectTableForBlock(const MachineBasicBlock &MBB)
Frees the memory of the ValueTable associated with MBB.
ValueTable & tableForEntryMBB() const
Returns the ValueTable associated with the entry MachineBasicBlock.
bool hasTableFor(MachineBasicBlock &MBB) const
Returns true if the ValueTable associated with MBB has not been freed.
A DbgOp whose ID (if any) has resolved to an actual location, LocIdx.
void dump(const MLocTracker *MTrack) const
Stores the resolved operands (machine locations and constants) and qualifying meta-information needed...
SmallVector< ResolvedDbgOp > Ops
DbgValueProperties Properties
ResolvedDbgValue(SmallVectorImpl< ResolvedDbgOp > &Ops, DbgValueProperties Properties)
auto loc_indices() const
Returns all the LocIdx values used in this struct, in the order in which they appear as operands in t...
Record of all changes in variable locations at a block position.
SmallVector< std::pair< DebugVariableID, MachineInstr * >, 4 > Insts
non-null if we should insert after.
MachineBasicBlock * MBB
Position to insert DBG_VALUes.
MachineBasicBlock::instr_iterator Pos
Record of a use-before-def: created when a value that's live-in to the current block isn't available ...
UseBeforeDef(ArrayRef< DbgOp > Values, DebugVariableID VarID, const DbgValueProperties &Properties)
DbgValueProperties Properties
Additional variable properties.
DebugVariableID VarID
Identity of this variable.
SmallVector< DbgOp > Values
Value of this variable, def'd in block.
Description of the encoding of one expression Op.
Function object to check whether the first component of a container supported by std::get (like std::...