105#include "llvm/Config/llvm-config.h"
137#define DEBUG_TYPE "livedebugvalues"
142 cl::desc(
"Act like old LiveDebugValues did"),
156 cl::desc(
"livedebugvalues-stack-ws-limit"),
306 unsigned Location : 24;
307 unsigned Quality : 8;
312 : Location(L.asU64()), Quality(static_cast<
unsigned>(Q)) {}
327 return A.first <
B.first;
332 std::optional<LocationQuality>
362 bool IsValueValid =
true;
363 unsigned LastUseBeforeDef = 0;
379 IsValueValid =
false;
391 auto ValuesPreferredLoc = std::lower_bound(
395 assert(ValuesPreferredLoc != ValueToLoc.
end() &&
396 ValuesPreferredLoc->first == Num);
398 if (ValuesPreferredLoc->second.isIllegal()) {
404 LastUseBeforeDef = std::max(LastUseBeforeDef,
405 static_cast<unsigned>(Num.
getInst()));
409 IsValueValid =
false;
415 LocIdx M = ValuesPreferredLoc->second.getLoc();
425 if (LastUseBeforeDef) {
436 auto Result =
ActiveVLocs.insert(std::make_pair(VarID, NewValue));
438 Result.first->second = NewValue;
468 for (
const auto &VLoc : VLocs)
470 for (
DbgOpID OpID : VLoc.second.getDbgOpIDs())
471 if (!OpID.ID.IsConst)
491 auto VIt = std::lower_bound(ValueToLoc.
begin(), ValueToLoc.
end(), Probe,
493 if (VIt == ValueToLoc.
end() || VIt->first != VNum)
496 auto &Previous = VIt->second;
499 std::optional<LocationQuality> ReplacementQuality =
501 if (ReplacementQuality)
506 for (
const auto &Var : VLocs) {
536 for (
auto &
Use : MIt->second) {
541 assert(!
Op.isUndef() &&
"UseBeforeDef erroneously created for a "
542 "DbgValue with undef values.");
551 if (ValueToLoc.
empty())
560 auto VIt = ValueToLoc.
find(LocValueID);
561 if (VIt == ValueToLoc.
end())
564 auto &Previous = VIt->second;
567 std::optional<LocationQuality> ReplacementQuality =
569 if (ReplacementQuality)
575 for (
auto &
Use : MIt->second) {
586 LocIdx NewLoc = ValueToLoc.
find(
Op.ID)->second.getLoc();
595 if (DbgOps.
size() !=
Use.Values.size())
648 return Reg != SP && Reg !=
FP;
665 auto NonVariadicExpression =
667 if (!NonVariadicExpression)
669 DIExpr = *NonVariadicExpression;
695 MI.getDebugLoc()->getInlinedAt());
700 if (
MI.isUndefDebugValue() ||
705 for (
LocIdx Loc : It->second.loc_indices())
735 MI.getDebugLoc()->getInlinedAt());
743 for (
LocIdx Loc : It->second.loc_indices())
748 if (NewLocs.
empty()) {
768 for (
LocIdx Loc : LostVLocIt->second.loc_indices()) {
778 for (
const auto &LostMLoc : LostMLocs)
793 It->second.Ops.assign(NewLocs);
794 It->second.Properties = Properties;
803 bool MakeUndef =
true) {
825 std::optional<LocIdx> NewLoc;
827 if (Loc.Value == OldValue)
832 if (!NewLoc && !MakeUndef) {
835 auto &Prop =
ActiveVLocs.find(VarID)->second.Properties;
862 DbgOps.
insert(DbgOps.
begin(), ActiveVLocIt->second.Ops.size(),
874 for (
LocIdx Loc : ActiveVLocIt->second.loc_indices()) {
880 ActiveVLocIt->second.Ops = DbgOps;
887 for (
auto &LocVarIt : LostMLocs) {
890 "Variable was using this MLoc, but ActiveMLocs[MLoc] has no "
892 LostMLocIt->second.erase(LocVarIt.second);
898 VarLocs[NewLoc->asU64()] = OldValue;
903 ActiveMLocIt->second.clear();
904 if (!NewMLocs.
empty())
934 std::replace(ActiveVLocIt->second.Ops.begin(),
935 ActiveVLocIt->second.Ops.end(),
SrcOp,
DstOp);
939 ActiveVLocIt->second.Properties);
964 MIB.addMetadata(Properties.
DIExpr);
1025 LocIdxToIDNum(
ValueIDNum::EmptyValue), LocIdxToLocID(0) {
1063 if (
Size > 60000 || Offs > 60000)
1099 if (MaskPair.first->clobbersPhysReg(
ID)) {
1101 ValNum = {
CurBB, MaskPair.second, NewIdx};
1122 Masks.push_back(std::make_pair(MO, InstID));
1128 if (SpillID.
id() == 0) {
1132 return std::nullopt;
1137 for (
unsigned StackIdx = 0; StackIdx <
NumSlotIdxes; ++StackIdx) {
1158 return Twine(
"slot ")
1175 std::string MLocName =
LocIdxToName(Location.Value.getLoc());
1176 std::string DefName = Location.Value.asString(MLocName);
1184 dbgs() <<
"Idx " << Location.Idx.asU64() <<
" " << foo <<
"\n";
1196 ?
TII.
get(TargetOpcode::DBG_VALUE_LIST)
1197 :
TII.
get(TargetOpcode::DBG_VALUE);
1199#ifdef EXPENSIVE_CHECKS
1202 return Op.IsConst || !
Op.Loc.isIllegal();
1204 "Did not expect illegal ops in DbgOps.");
1207 "Expected to have either one DbgOp per MI LocationOp, or none.");
1220 auto EmitUndef = [&]() {
1232 bool Indirect = Properties.
Indirect;
1254 unsigned short Offset = StackIdx.second;
1265 unsigned Base = Spill.SpillBase;
1281 bool UseDerefSize =
false;
1283 unsigned DerefSizeInBytes = ValueSizeInBits / 8;
1285 unsigned VariableSizeInBits = Fragment->SizeInBits;
1286 if (VariableSizeInBits != ValueSizeInBits || Expr->
isComplex())
1287 UseDerefSize =
true;
1289 if (*
Size != ValueSizeInBits) {
1290 UseDerefSize =
true;
1296 bool StackValue =
false;
1303 OffsetOps.
push_back(dwarf::DW_OP_deref);
1310 OffsetOps.
push_back(dwarf::DW_OP_deref_size);
1316 OffsetOps.
push_back(dwarf::DW_OP_deref);
1349 if (CalleeSavedRegs.
test(*RAI))
1363std::optional<SpillLocationNo>
1364InstrRefBasedLDV::extractSpillBaseRegAndOffset(
const MachineInstr &
MI) {
1366 "Spill instruction does not have exactly one memory operand?");
1367 auto MMOI =
MI.memoperands_begin();
1370 "Inconsistent memory operand in spill instruction");
1371 int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
1378std::optional<LocIdx>
1380 std::optional<SpillLocationNo>
SpillLoc = extractSpillBaseRegAndOffset(
MI);
1382 return std::nullopt;
1388 auto *MemOperand = *
MI.memoperands_begin();
1390 assert(SizeInBits.
hasValue() &&
"Expected to find a valid size!");
1397 return std::nullopt;
1405bool InstrRefBasedLDV::transferDebugValue(
const MachineInstr &
MI) {
1406 if (!
MI.isDebugValue())
1409 assert(
MI.getDebugVariable()->isValidLocationForIntrinsic(
MI.getDebugLoc()) &&
1410 "Expected inlined-at fields to agree");
1415 if (Scope ==
nullptr)
1421 if (MO.isReg() && MO.getReg() != 0)
1422 (void)MTracker->
readReg(MO.getReg());
1431 if (!
MI.isUndefDebugValue()) {
1437 }
else if (MO.isImm() || MO.isFPImm() || MO.isCImm()) {
1454std::optional<ValueIDNum> InstrRefBasedLDV::getValueForInstrRef(
1470 LowerBoundIt->Src == SoughtSub.Src) {
1471 std::tie(InstNo, OpNo) = LowerBoundIt->Dest;
1472 SoughtSub.Src = LowerBoundIt->Dest;
1473 if (
unsigned Subreg = LowerBoundIt->Subreg)
1474 SeenSubregs.push_back(Subreg);
1480 std::optional<ValueIDNum> NewID;
1484 auto InstrIt = DebugInstrNumToInstr.find(InstNo);
1486 if (InstrIt != DebugInstrNumToInstr.end()) {
1487 const MachineInstr &TargetInstr = *InstrIt->second.first;
1496 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, *L);
1509 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, L);
1515 {
dbgs() <<
"Seen instruction reference to illegal operand\n"; });
1519 }
else if (PHIIt != DebugPHINumToValue.
end() && PHIIt->InstrNum == InstNo) {
1522 assert(MLiveOuts && MLiveIns);
1523 NewID = resolveDbgPHIs(*
MI.getParent()->getParent(), *MLiveOuts, *MLiveIns,
1536 if (NewID && !SeenSubregs.empty()) {
1544 for (
unsigned Subreg :
reverse(SeenSubregs)) {
1548 Size = (
Size == 0) ? ThisSize : std::min(
Size, ThisSize);
1556 if (NewID && !MTracker->
isSpill(L)) {
1562 if (TRCI->contains(Reg))
1564 assert(TRC &&
"Couldn't find target register class?");
1576 if (SubregSize ==
Size && SubregOffset ==
Offset) {
1584 NewID = std::nullopt;
1589 NewID =
ValueIDNum(NewID->getBlock(), NewID->getInst(), NewLoc);
1594 NewID = std::nullopt;
1604 if (!
MI.isDebugRef())
1609 if (!VTracker && !TTracker)
1617 "Expected inlined-at fields to agree");
1622 if (Scope ==
nullptr)
1628 assert(!MO.
isReg() &&
"DBG_INSTR_REF should not contain registers");
1639 std::optional<ValueIDNum> NewID =
1640 getValueForInstrRef(InstNo, OpNo,
MI, MLiveOuts, MLiveIns);
1657 VTracker->
defVar(
MI, Properties, DbgOpIDs);
1666 for (
DbgOpID OpID : DbgOpIDs) {
1676 for (
const DbgOp &
Op : DbgOps) {
1678 if (FoundLocs.
insert({Op.ID, TransferTracker::LocationAndQuality()})
1683 for (
auto Location : MTracker->
locations()) {
1686 auto ValueToFindIt =
find(ValuesToFind,
ID);
1687 if (ValueToFindIt == ValuesToFind.
end())
1689 auto &Previous = FoundLocs.
find(
ID)->second;
1692 std::optional<TransferTracker::LocationQuality> ReplacementQuality =
1694 if (ReplacementQuality) {
1696 if (Previous.isBest()) {
1697 ValuesToFind.
erase(ValueToFindIt);
1698 if (ValuesToFind.
empty())
1722 if (!DbgOps.empty() && NewLocs.
empty()) {
1723 bool IsValidUseBeforeDef =
true;
1725 for (
auto ValueLoc : FoundLocs) {
1727 LocIdx FoundLoc = ValueLoc.second.getLoc();
1733 IsValidUseBeforeDef =
false;
1736 LastUseBeforeDef = std::max(LastUseBeforeDef, NewID.
getInst());
1738 if (IsValidUseBeforeDef) {
1741 DbgOps, LastUseBeforeDef);
1750 MTracker->
emitLoc(NewLocs, V,
MI.getDebugLoc().get(), Properties);
1759 if (!
MI.isDebugPHI())
1763 if (VTracker || TTracker)
1769 unsigned InstrNum =
MI.getOperand(1).getImm();
1771 auto EmitBadPHI = [
this, &
MI, InstrNum]() ->
bool {
1777 {InstrNum,
MI.getParent(), std::nullopt, std::nullopt});
1786 auto PHIRec = DebugPHIRecord(
1793 }
else if (MO.
isFI()) {
1800 return EmitBadPHI();
1811 return EmitBadPHI();
1814 assert(
MI.getNumOperands() == 3 &&
"Stack DBG_PHI with no size?");
1815 unsigned slotBitSize =
MI.getOperand(2).getImm();
1817 unsigned SpillID = MTracker->
getLocID(*SpillNo, {slotBitSize, 0});
1822 auto DbgPHI = DebugPHIRecord({InstrNum,
MI.getParent(), Result,
SpillLoc});
1830 {
dbgs() <<
"Seen DBG_PHI with unrecognised operand format\n"; });
1831 return EmitBadPHI();
1840 if (
MI.isImplicitDef()) {
1850 }
else if (
MI.isMetaInstruction())
1858 bool CallChangesSP =
false;
1859 if (AdjustsStackInCalls &&
MI.isCall() &&
MI.getOperand(0).isSymbol() &&
1860 !strcmp(
MI.getOperand(0).getSymbolName(), StackProbeSymbolName.
data()))
1861 CallChangesSP =
true;
1865 auto IgnoreSPAlias = [
this, &
MI, CallChangesSP](
Register R) ->
bool {
1868 return MI.isCall() && MTracker->
SPAliases.count(R);
1880 !IgnoreSPAlias(MO.
getReg())) {
1893 MTracker->
defReg(DeadReg, CurBB, CurInst);
1895 for (
const auto *MO : RegMaskPtrs)
1900 if (std::optional<SpillLocationNo> SpillNo =
1901 extractSpillBaseRegAndOffset(
MI)) {
1918 for (
uint32_t DeadReg : DeadRegs) {
1925 if (!RegMaskPtrs.empty()) {
1932 if (IgnoreSPAlias(Reg))
1935 for (
const auto *MO : RegMaskPtrs)
1943 if (std::optional<SpillLocationNo> SpillNo =
1944 extractSpillBaseRegAndOffset(
MI)) {
1954void InstrRefBasedLDV::performCopy(
Register SrcRegNum,
Register DstRegNum) {
1957 MTracker->
defReg(*RAI, CurBB, CurInst);
1960 MTracker->
setReg(DstRegNum, SrcValue);
1964 unsigned SrcSubReg = SRI.getSubReg();
1965 unsigned SubRegIdx = SRI.getSubRegIndex();
1966 unsigned DstSubReg = TRI->
getSubReg(DstRegNum, SubRegIdx);
1981 MTracker->
setReg(DstSubReg, CpyValue);
1985std::optional<SpillLocationNo>
1989 if (!
MI.hasOneMemOperand())
1990 return std::nullopt;
1993 auto MMOI =
MI.memoperands_begin();
1996 return std::nullopt;
1998 if (!
MI.getSpillSize(TII) && !
MI.getFoldedSpillSize(TII))
1999 return std::nullopt;
2002 return extractSpillBaseRegAndOffset(
MI);
2007 if (!isSpillInstruction(
MI, MF))
2015std::optional<SpillLocationNo>
2018 if (!
MI.hasOneMemOperand())
2019 return std::nullopt;
2023 if (
MI.getRestoreSize(TII)) {
2024 Reg =
MI.getOperand(0).getReg();
2025 return extractSpillBaseRegAndOffset(
MI);
2027 return std::nullopt;
2030bool InstrRefBasedLDV::transferSpillOrRestoreInst(
MachineInstr &
MI) {
2059 if (std::optional<SpillLocationNo> Loc = isSpillInstruction(
MI, MF)) {
2062 for (
unsigned SlotIdx = 0; SlotIdx < MTracker->
NumSlotIdxes; ++SlotIdx) {
2064 std::optional<LocIdx> MLoc = MTracker->
getSpillMLoc(SpillID);
2073 MTracker->
setMLoc(*MLoc, Def);
2080 if (isLocationSpill(
MI, MF, Reg)) {
2085 auto DoTransfer = [&](
Register SrcReg,
unsigned SpillID) {
2086 auto ReadValue = MTracker->
readReg(SrcReg);
2088 MTracker->
setMLoc(DstLoc, ReadValue);
2101 unsigned SpillID = MTracker->
getLocID(Loc, SubregIdx);
2102 DoTransfer(SR, SpillID);
2108 DoTransfer(Reg, SpillID);
2110 std::optional<SpillLocationNo> Loc = isRestoreInstruction(
MI, MF, Reg);
2122 MTracker->
defReg(*RAI, CurBB, CurInst);
2126 auto DoTransfer = [&](
Register DestReg,
unsigned SpillID) {
2128 auto ReadValue = MTracker->
readMLoc(SrcIdx);
2129 MTracker->
setReg(DestReg, ReadValue);
2134 unsigned SpillID = MTracker->
getLocID(*Loc, Subreg);
2135 DoTransfer(SR, SpillID);
2140 unsigned SpillID = MTracker->
getLocID(*Loc, {
Size, 0});
2141 DoTransfer(Reg, SpillID);
2158 if (SrcReg == DestReg)
2187 if (MLocIt == TTracker->
ActiveMLocs.
end() || MLocIt->second.empty())
2190 ClobberedLocs[ClobberedLoc] =
Value;
2195 InstrRefBasedLDV::performCopy(SrcReg, DestReg);
2201 for (
auto LocVal : ClobberedLocs) {
2202 TTracker->
clobberMloc(LocVal.first, LocVal.second,
MI.getIterator(),
false);
2215 MTracker->
defReg(SrcReg, CurBB, CurInst);
2229 MI.getDebugLoc()->getInlinedAt());
2230 FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
2235 auto SeenIt = SeenFragments.
find(MIVar.getVariable());
2236 if (SeenIt == SeenFragments.
end()) {
2238 OneFragment.
insert(ThisFragment);
2239 SeenFragments.
insert({MIVar.getVariable(), OneFragment});
2241 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2248 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2249 if (!IsInOLapMap.second)
2252 auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
2253 auto &AllSeenFragments = SeenIt->second;
2258 for (
const auto &ASeenFragment : AllSeenFragments) {
2262 ThisFragmentsOverlaps.push_back(ASeenFragment);
2265 auto ASeenFragmentsOverlaps =
2266 OverlapFragments.
find({MIVar.getVariable(), ASeenFragment});
2267 assert(ASeenFragmentsOverlaps != OverlapFragments.
end() &&
2268 "Previously seen var fragment has no vector of overlaps");
2269 ASeenFragmentsOverlaps->second.push_back(ThisFragment);
2273 AllSeenFragments.insert(ThisFragment);
2282 if (transferDebugValue(
MI))
2284 if (transferDebugInstrRef(
MI, MLiveOuts, MLiveIns))
2286 if (transferDebugPHI(
MI))
2288 if (transferRegisterCopy(
MI))
2290 if (transferSpillOrRestoreInst(
MI))
2292 transferRegisterDef(
MI);
2295void InstrRefBasedLDV::produceMLocTransferFunction(
2311 for (
auto &BV : BlockMasks)
2315 for (
auto &
MBB : MF) {
2327 for (
auto &
MI :
MBB) {
2330 process(
MI,
nullptr,
nullptr);
2333 if (
MI.isDebugValueLike())
2334 accumulateFragmentMap(
MI);
2338 if (
uint64_t InstrNo =
MI.peekDebugInstrNum()) {
2339 auto InstrAndPos = std::make_pair(&
MI, CurInst);
2341 DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));
2344 assert(InsertResult.second);
2355 for (
auto Location : MTracker->
locations()) {
2358 if (
P.isPHI() &&
P.getLoc() ==
Idx.asU64())
2362 auto &TransferMap = MLocTransfer[CurBB];
2363 auto Result = TransferMap.insert(std::make_pair(
Idx.asU64(),
P));
2370 for (
auto &
P : MTracker->
Masks) {
2371 BlockMasks[CurBB].clearBitsNotInMask(
P.first->getRegMask(), BVWords);
2377 for (
auto Location : MTracker->
locations()) {
2395 for (
unsigned Bit : BV.
set_bits()) {
2398 auto &TransferMap = MLocTransfer[
I];
2407 TransferMap.insert(std::make_pair(
Idx.asU64(), NotGeneratedNum));
2412 ValueID = NotGeneratedNum;
2418bool InstrRefBasedLDV::mlocJoin(
2422 bool Changed =
false;
2435 return BBToOrder.find(
A)->second < BBToOrder.find(
B)->second;
2440 if (BlockOrders.
size() == 0) {
2445 <<
" from entry which may lead out of "
2446 "bound access to VarLocs\n");
2452 for (
auto Location : MTracker->
locations()) {
2457 ValueIDNum FirstVal = OutLocs[*BlockOrders[0]][
Idx.asU64()];
2462 if (InLocs[
Idx.asU64()] != FirstVal) {
2463 InLocs[
Idx.asU64()] = FirstVal;
2471 bool Disagree =
false;
2472 for (
unsigned int I = 1;
I < BlockOrders.size(); ++
I) {
2474 const ValueIDNum &PredLiveOut = OutLocs[*PredMBB][
Idx.asU64()];
2477 if (FirstVal == PredLiveOut)
2490 InLocs[
Idx.asU64()] = FirstVal;
2499void InstrRefBasedLDV::findStackIndexInterference(
2519 if (!Pair.first.second)
2525void InstrRefBasedLDV::placeMLocPHIs(
2529 findStackIndexInterference(StackUnits);
2541 for (
auto Location : MTracker->
locations()) {
2550 bool AnyIllegal =
false;
2559 FoundRegUnits.
insert(*URoot);
2565 NormalLocsToPHI.
insert(L);
2569 RegUnitsToPHIUp.
insert(FoundRegUnits.
begin(), FoundRegUnits.
end());
2575 auto CollectPHIsForLoc = [&](
LocIdx L) {
2578 for (
unsigned int I = 0;
I < OrderToBB.size(); ++
I) {
2580 const auto &TransferFunc = MLocTransfer[
MBB->
getNumber()];
2581 if (TransferFunc.contains(L))
2588 if (!DefBlocks.
empty())
2594 BlockPHIPlacement(AllBlocks, DefBlocks, PHIBlocks);
2597 auto InstallPHIsAtLoc = [&PHIBlocks, &MInLocs](
LocIdx L) {
2603 for (
LocIdx L : NormalLocsToPHI) {
2604 CollectPHIsForLoc(L);
2606 InstallPHIsAtLoc(L);
2612 for (
unsigned Idx : StackUnits) {
2615 CollectPHIsForLoc(L);
2616 InstallPHIsAtLoc(L);
2622 unsigned ThisSize, ThisOffset;
2623 std::tie(ThisSize, ThisOffset) = Pair.first;
2629 InstallPHIsAtLoc(ThisL);
2635 for (
Register R : RegUnitsToPHIUp) {
2637 CollectPHIsForLoc(L);
2640 InstallPHIsAtLoc(L);
2650 InstallPHIsAtLoc(AliasLoc);
2655void InstrRefBasedLDV::buildMLocValueMap(
2658 std::priority_queue<unsigned int, std::vector<unsigned int>,
2659 std::greater<unsigned int>>
2670 for (
unsigned int I = 0;
I < BBToOrder.size(); ++
I) {
2672 OnWorklist.
insert(OrderToBB[
I]);
2673 AllBlocks.
insert(OrderToBB[
I]);
2677 for (
auto Location : MTracker->
locations())
2686 placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer);
2697 while (!Worklist.empty() || !Pending.empty()) {
2701 while (!Worklist.empty()) {
2708 InLocsChanged = mlocJoin(*
MBB, Visited, MOutLocs, MInLocs[*
MBB]);
2709 InLocsChanged |= Visited.
insert(
MBB).second;
2722 for (
auto &
P : MLocTransfer[CurBB]) {
2723 if (
P.second.getBlock() == CurBB &&
P.second.isPHI()) {
2726 ToRemap.
push_back(std::make_pair(
P.first, NewID));
2729 assert(
P.second.getBlock() == CurBB);
2730 ToRemap.
push_back(std::make_pair(
P.first,
P.second));
2736 for (
auto &
P : ToRemap)
2742 bool OLChanged =
false;
2743 for (
auto Location : MTracker->
locations()) {
2759 if (BBToOrder[s] > BBToOrder[
MBB]) {
2761 if (OnWorklist.
insert(s).second)
2762 Worklist.push(BBToOrder[s]);
2765 if (OnPending.
insert(s).second)
2766 Pending.push(BBToOrder[s]);
2771 Worklist.swap(Pending);
2776 assert(Pending.empty() &&
"Pending should be empty");
2783void InstrRefBasedLDV::BlockPHIPlacement(
2792 IDF.setLiveInBlocks(AllBlocks);
2793 IDF.setDefiningBlocks(DefBlocks);
2794 IDF.calculate(PHIBlocks);
2797bool InstrRefBasedLDV::pickVPHILoc(
2803 if (BlockOrders.
empty())
2810 auto FirstValueIt = LiveOuts.
find(BlockOrders[0]);
2811 if (FirstValueIt == LiveOuts.end())
2813 const DbgValue &FirstValue = *FirstValueIt->second;
2815 for (
const auto p : BlockOrders) {
2816 auto OutValIt = LiveOuts.find(p);
2817 if (OutValIt == LiveOuts.end())
2820 const DbgValue &OutVal = *OutValIt->second;
2843 if (FirstValOp != OutValOp) {
2864 std::optional<ValueIDNum> JoinedOpLoc =
2865 pickOperandPHILoc(
Idx,
MBB, LiveOuts, MOutLocs, BlockOrders);
2873 OutValues.
append(NewDbgOps);
2877std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc(
2887 for (
const auto p : BlockOrders) {
2888 auto OutValIt = LiveOuts.find(p);
2889 assert(OutValIt != LiveOuts.end());
2890 const DbgValue &OutVal = *OutValIt->second;
2892 DbgOp OutValOp = DbgOpStore.
find(OutValOpID);
2905 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2906 if (MOutLocs[*p][
I] == ValToLookFor)
2917 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2919 if (MOutLocs[*p][
I] == MPHI)
2930 for (
unsigned int I = 1;
I < Locs.
size(); ++
I) {
2931 auto &LocVec = Locs[
I];
2933 std::set_intersection(CandidateLocs.
begin(), CandidateLocs.
end(),
2934 LocVec.begin(), LocVec.end(), std::inserter(NewCandidates, NewCandidates.
begin()));
2935 CandidateLocs = NewCandidates;
2937 if (CandidateLocs.
empty())
2938 return std::nullopt;
2950bool InstrRefBasedLDV::vlocJoin(
2955 bool Changed =
false;
2961 return BBToOrder[
A] < BBToOrder[
B];
2966 unsigned CurBlockRPONum = BBToOrder[&
MBB];
2972 int BackEdgesStart = 0;
2973 for (
auto *p : BlockOrders) {
2976 if (!BlocksToExplore.
contains(p)) {
2982 DbgValue &OutLoc = *VLOCOutLocs.find(p)->second;
2986 unsigned ThisBBRPONum = BBToOrder[
p];
2987 if (ThisBBRPONum < CurBlockRPONum)
2990 Values.
push_back(std::make_pair(p, &OutLoc));
2996 if (Bail || Values.
size() == 0)
3002 const DbgValue &FirstVal = *Values[0].second;
3008 Changed = LiveIn != FirstVal;
3017 for (
const auto &V : Values) {
3018 if (!
V.second->Properties.isJoinable(FirstVal.
Properties))
3022 if (!
V.second->hasJoinableLocOps(FirstVal))
3027 bool Disagree =
false;
3028 for (
auto &V : Values) {
3029 if (*
V.second == FirstVal)
3035 if (
V.second->hasIdenticalValidLocOps(FirstVal))
3042 std::distance(Values.begin(), &V) >= BackEdgesStart)
3050 Changed = LiveIn != FirstVal;
3057 Changed = LiveIn != VPHI;
3064void InstrRefBasedLDV::getBlocksForScope(
3074 BlocksToExplore.
insert(AssignBlocks.
begin(), AssignBlocks.
end());
3084 for (
const auto *
MBB : BlocksToExplore) {
3094 if (BlocksToExplore.count(succ))
3096 if (!ArtificialBlocks.count(succ))
3099 DFS.push_back({succ, succ->succ_begin()});
3103 while (!DFS.empty()) {
3107 if (CurSucc == CurBB->
succ_end()) {
3114 if (!ToAdd.
count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {
3116 DFS.push_back({*CurSucc, (*CurSucc)->succ_begin()});
3124 BlocksToExplore.insert(ToAdd.
begin(), ToAdd.
end());
3127void InstrRefBasedLDV::buildVLocValueMap(
3137 std::priority_queue<unsigned int, std::vector<unsigned int>,
3138 std::greater<unsigned int>>
3149 getBlocksForScope(DILoc, BlocksToExplore, AssignBlocks);
3155 if (BlocksToExplore.
size() == 1)
3162 for (
const auto *
MBB : BlocksToExplore)
3168 for (
const auto *
MBB : BlocksToExplore)
3172 for (
unsigned int I : BlockOrderNums)
3174 BlockOrderNums.clear();
3175 unsigned NumBlocks = BlockOrders.
size();
3185 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3194 LiveOutIdx.reserve(NumBlocks);
3195 LiveInIdx.reserve(NumBlocks);
3196 for (
unsigned I = 0;
I < NumBlocks; ++
I) {
3197 LiveOutIdx[BlockOrders[
I]] = &LiveOuts[
I];
3198 LiveInIdx[BlockOrders[
I]] = &LiveIns[
I];
3208 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3210 LiveIns[
I] = EmptyDbgValue;
3211 LiveOuts[
I] = EmptyDbgValue;
3218 auto &TransferFunc = AllTheVLocs[ExpMBB->getNumber()].Vars;
3219 if (TransferFunc.contains(VarID))
3227 if (DefBlocks.
size() == 1) {
3228 placePHIsForSingleVarDefinition(MutBlocksToExplore, *DefBlocks.
begin(),
3229 AllTheVLocs, VarID, Output);
3234 BlockPHIPlacement(MutBlocksToExplore, DefBlocks, PHIBlocks);
3238 unsigned BlockNo = PHIMBB->getNumber();
3239 DbgValue *LiveIn = LiveInIdx[PHIMBB];
3243 for (
auto *
MBB : BlockOrders) {
3244 Worklist.push(BBToOrder[
MBB]);
3255 bool FirstTrip =
true;
3256 while (!Worklist.empty() || !Pending.empty()) {
3257 while (!Worklist.empty()) {
3258 auto *
MBB = OrderToBB[Worklist.top()];
3262 auto LiveInsIt = LiveInIdx.find(
MBB);
3263 assert(LiveInsIt != LiveInIdx.end());
3264 DbgValue *LiveIn = LiveInsIt->second;
3268 bool InLocsChanged =
3269 vlocJoin(*
MBB, LiveOutIdx, BlocksToExplore, *LiveIn);
3286 if (pickVPHILoc(JoinedOps, *
MBB, LiveOutIdx, MOutLocs, Preds)) {
3288 InLocsChanged |= NewLocPicked;
3294 if (!InLocsChanged && !FirstTrip)
3298 bool OLChanged =
false;
3302 auto TransferIt = VTracker.
Vars.find(VarID);
3303 if (TransferIt != VTracker.
Vars.end()) {
3307 if (*LiveOut != NewVal) {
3313 if (*LiveOut != TransferIt->second) {
3314 *LiveOut = TransferIt->second;
3320 if (*LiveOut != *LiveIn) {
3335 if (!LiveInIdx.contains(s))
3338 if (BBToOrder[s] > BBToOrder[
MBB]) {
3339 if (OnWorklist.
insert(s).second)
3340 Worklist.push(BBToOrder[s]);
3341 }
else if (OnPending.
insert(s).second && (FirstTrip || OLChanged)) {
3342 Pending.push(BBToOrder[s]);
3346 Worklist.swap(Pending);
3356 for (
auto *
MBB : BlockOrders) {
3364 [[maybe_unused]]
auto &[Var, DILoc] = DVMap.
lookupDVID(VarID);
3366 Var.getFragment() &&
3367 "Fragment info missing during value prop");
3368 Output[
MBB->
getNumber()].push_back(std::make_pair(VarID, *BlockLiveIn));
3372 BlockOrders.clear();
3373 BlocksToExplore.clear();
3376void InstrRefBasedLDV::placePHIsForSingleVarDefinition(
3392 auto ValueIt = VLocs.
Vars.find(VarID);
3403 for (
auto *ScopeBlock : InScopeBlocks) {
3407 Output[ScopeBlock->getNumber()].push_back({VarID,
Value});
3414#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3417 for (
const auto &
P : mloc_transfer) {
3420 dbgs() <<
"Loc " << foo <<
" --> " << bar <<
"\n";
3429 EmptyExpr = DIExpression::get(Context, {});
3431 auto hasNonArtificialLocation = [](
const MachineInstr &
MI) ->
bool {
3433 return DL.getLine() != 0;
3439 unsigned int Size = 0;
3440 for (
auto &
MBB : MF) {
3443 ArtificialBlocks.insert(&
MBB);
3448 unsigned int RPONumber = 0;
3449 OrderToBB.reserve(
Size);
3450 BBToOrder.reserve(
Size);
3453 OrderToBB.push_back(
MBB);
3454 BBToOrder[
MBB] = RPONumber;
3461 if (!BBToOrder.contains(&
MBB))
3467#ifdef EXPENSIVE_CHECKS
3470 if (MF.DebugValueSubstitutions.size() > 2) {
3471 for (
auto It = MF.DebugValueSubstitutions.begin();
3472 It != std::prev(MF.DebugValueSubstitutions.end()); ++It) {
3473 assert(It->Src != std::next(It)->Src &&
"Duplicate variable location "
3474 "substitution seen");
3483void InstrRefBasedLDV::makeDepthFirstEjectionMap(
3485 const ScopeToDILocT &ScopeToDILocation,
3486 ScopeToAssignBlocksT &ScopeToAssignBlocks) {
3493 WorkStack.
push_back({TopScope, TopScope->getChildren().
size() - 1});
3495 while (!WorkStack.
empty()) {
3496 auto &ScopePosition = WorkStack.
back();
3498 ssize_t ChildNum = ScopePosition.second--;
3501 if (ChildNum >= 0) {
3504 auto &ChildScope =
Children[ChildNum];
3506 std::make_pair(ChildScope, ChildScope->getChildren().size() - 1));
3513 auto DILocationIt = ScopeToDILocation.find(WS);
3514 if (DILocationIt != ScopeToDILocation.end()) {
3515 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3516 ScopeToAssignBlocks.find(WS)->second);
3517 for (
const auto *
MBB : BlocksToExplore) {
3519 if (EjectionMap[BBNum] == 0)
3523 BlocksToExplore.clear();
3529bool InstrRefBasedLDV::depthFirstVLocAndEmit(
3530 unsigned MaxNumBlocks,
const ScopeToDILocT &ScopeToDILocation,
3531 const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,
3536 new TransferTracker(TII, MTracker, MF, DVMap, *TRI, CalleeSavedRegs, TPC);
3547 makeDepthFirstEjectionMap(EjectionMap, ScopeToDILocation,
3548 ScopeToAssignBlocks);
3555 AllTheVLocs[BBNum].
clear();
3561 TTracker->
loadInlocs(
MBB, MInLocs[
MBB], DbgOpStore, Output[BBNum], NumLocs);
3565 for (
auto &
MI :
MBB) {
3566 process(
MI, &MOutLocs, &MInLocs);
3575 Output[BBNum].clear();
3576 AllTheVLocs[BBNum].
clear();
3582 unsigned HighestDFSIn = 0;
3585 while (!WorkStack.
empty()) {
3586 auto &ScopePosition = WorkStack.
back();
3588 ssize_t ChildNum = ScopePosition.second++;
3595 auto DILocIt = ScopeToDILocation.find(WS);
3596 if (HighestDFSIn <= WS->getDFSIn() && DILocIt != ScopeToDILocation.end()) {
3598 auto &VarsWeCareAbout = ScopeToVars.find(WS)->second;
3599 auto &BlocksInScope = ScopeToAssignBlocks.find(WS)->second;
3601 buildVLocValueMap(DILoc, VarsWeCareAbout, BlocksInScope, Output, MOutLocs,
3602 MInLocs, AllTheVLocs);
3605 HighestDFSIn = std::max(HighestDFSIn, WS->
getDFSIn());
3609 if (ChildNum < (ssize_t)
Children.size()) {
3611 auto &ChildScope =
Children[ChildNum];
3612 WorkStack.
push_back(std::make_pair(ChildScope, 0));
3618 auto DILocationIt = ScopeToDILocation.find(WS);
3619 if (DILocationIt == ScopeToDILocation.end())
3622 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3623 ScopeToAssignBlocks.find(WS)->second);
3624 for (
const auto *
MBB : BlocksToExplore)
3628 BlocksToExplore.clear();
3637 for (
auto *
MBB : ArtificialBlocks)
3641 return emitTransfers();
3644bool InstrRefBasedLDV::emitTransfers() {
3658 for (
const auto &Pair :
P.Insts)
3663 if (
P.Pos->isTerminator())
3667 for (
const auto &Pair :
P.Insts)
3681 unsigned InputDbgValLimit) {
3689 this->DomTree = DomTree;
3700 STI.getFrameLowering()->stackProbeFunctionModifiesSP();
3701 if (AdjustsStackInCalls)
3702 StackProbeSymbolName = STI.getTargetLowering()->getStackProbeSymbolName(MF);
3714 for (
auto &
MBB : MF)
3725 produceMLocTransferFunction(MF, MLocTransfer,
MaxNumBlocks);
3738 buildMLocValueMap(MF, MInLocs, MOutLocs, MLocTransfer);
3742 for (
auto &DBG_PHI : DebugPHINumToValue) {
3744 if (!DBG_PHI.ValueRead)
3758 Num = ResolvedValue;
3767 VTracker = &vlocs[CurBB];
3771 for (
auto &
MI : *
MBB) {
3772 process(
MI, &MOutLocs, &MInLocs);
3790 unsigned VarAssignCount = 0;
3791 for (
unsigned int I = 0;
I < OrderToBB.size(); ++
I) {
3792 auto *
MBB = OrderToBB[
I];
3795 for (
auto &idx : VTracker->
Vars) {
3798 assert(ScopeLoc !=
nullptr);
3802 assert(Scope !=
nullptr);
3804 ScopeToVars[
Scope].insert(VarID);
3805 ScopeToAssignBlocks[
Scope].insert(VTracker->
MBB);
3806 ScopeToDILocation[
Scope] = ScopeLoc;
3811 bool Changed =
false;
3817 VarAssignCount > InputDbgValLimit) {
3818 LLVM_DEBUG(
dbgs() <<
"Disabling InstrRefBasedLDV: " << MF.getName()
3821 <<
" variable assignments, exceeding limits.\n");
3826 Changed = depthFirstVLocAndEmit(
3827 MaxNumBlocks, ScopeToDILocation, ScopeToVars, ScopeToAssignBlocks,
3828 SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, *TPC);
3837 ArtificialBlocks.clear();
3841 DebugInstrNumToInstr.clear();
3842 DebugPHINumToValue.clear();
3843 OverlapFragments.
clear();
3844 SeenFragments.
clear();
3845 SeenDbgPHIs.clear();
3871 LDVSSABlock *ParentBlock;
3872 BlockValueNum PHIValNum;
3873 LDVSSAPhi(BlockValueNum PHIValNum, LDVSSABlock *ParentBlock)
3874 : ParentBlock(ParentBlock), PHIValNum(PHIValNum) {}
3876 LDVSSABlock *
getParent() {
return ParentBlock; }
3881class LDVSSABlockIterator {
3884 LDVSSAUpdater &Updater;
3887 LDVSSAUpdater &Updater)
3888 : PredIt(PredIt), Updater(Updater) {}
3890 bool operator!=(
const LDVSSABlockIterator &OtherIt)
const {
3891 return OtherIt.PredIt != PredIt;
3894 LDVSSABlockIterator &operator++() {
3908 LDVSSAUpdater &Updater;
3914 : BB(BB), Updater(Updater) {}
3917 return LDVSSABlockIterator(BB.
succ_begin(), Updater);
3921 return LDVSSABlockIterator(BB.
succ_end(), Updater);
3925 LDVSSAPhi *newPHI(BlockValueNum
Value) {
3926 PHIList.emplace_back(
Value,
this);
3927 return &PHIList.back();
3931 PHIListT &phis() {
return PHIList; }
3937class LDVSSAUpdater {
3952 : Loc(
L), MLiveIns(MLiveIns) {}
3955 for (
auto &
Block : BlockMap)
3956 delete Block.second;
3963 ~LDVSSAUpdater() { reset(); }
3968 auto it = BlockMap.find(BB);
3969 if (it == BlockMap.end()) {
3970 BlockMap[BB] =
new LDVSSABlock(*BB, *
this);
3971 it = BlockMap.find(BB);
3978 BlockValueNum getValue(LDVSSABlock *LDVBB) {
3979 return MLiveIns[LDVBB->BB][Loc.
asU64()].asU64();
3983LDVSSABlock *LDVSSABlockIterator::operator*() {
3984 return Updater.getSSALDVBlock(*PredIt);
3990 out <<
"SSALDVPHI " <<
PHI.PHIValNum;
4016 class PHI_iterator {
4042 return PHI_iterator(
PHI,
true);
4050 Preds->
push_back(BB->Updater.getSSALDVBlock(Pred));
4056 static BlockValueNum
GetPoisonVal(LDVSSABlock *BB, LDVSSAUpdater *Updater) {
4060 BlockValueNum Num =
ValueIDNum(BB->BB.getNumber(), 0, Updater->Loc).
asU64();
4061 Updater->PoisonMap[&BB->BB] = Num;
4071 LDVSSAUpdater *Updater) {
4072 BlockValueNum PHIValNum = Updater->getValue(BB);
4073 LDVSSAPhi *
PHI = BB->newPHI(PHIValNum);
4074 Updater->PHIs[PHIValNum] =
PHI;
4081 PHI->IncomingValues.push_back(std::make_pair(Pred, Val));
4086 static LDVSSAPhi *
ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater) {
4087 return Updater->PHIs.lookup(Val);
4093 LDVSSAPhi *
PHI = ValueIsPHI(Val, Updater);
4094 if (
PHI &&
PHI->IncomingValues.size() == 0)
4106std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(
4111 auto SeenDbgPHIIt = SeenDbgPHIs.find(std::make_pair(&Here, InstrNum));
4112 if (SeenDbgPHIIt != SeenDbgPHIs.end())
4113 return SeenDbgPHIIt->second;
4115 std::optional<ValueIDNum>
Result =
4116 resolveDbgPHIsImpl(MF, MLiveOuts, MLiveIns, Here, InstrNum);
4117 SeenDbgPHIs.insert({std::make_pair(&Here, InstrNum),
Result});
4121std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
4126 auto RangePair = std::equal_range(DebugPHINumToValue.begin(),
4127 DebugPHINumToValue.end(), InstrNum);
4128 auto LowerIt = RangePair.first;
4129 auto UpperIt = RangePair.second;
4132 if (LowerIt == UpperIt)
4133 return std::nullopt;
4139 auto DBGPHIRange =
make_range(LowerIt, UpperIt);
4140 for (
const DebugPHIRecord &DBG_PHI : DBGPHIRange)
4141 if (!DBG_PHI.ValueRead)
4142 return std::nullopt;
4145 if (std::distance(LowerIt, UpperIt) == 1)
4146 return *LowerIt->ValueRead;
4152 LocIdx Loc = *LowerIt->ReadLoc;
4161 LDVSSAUpdater Updater(Loc, MLiveIns);
4169 for (
const auto &DBG_PHI : DBGPHIRange) {
4170 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4175 LDVSSABlock *HereBlock = Updater.getSSALDVBlock(Here.
getParent());
4176 const auto &AvailIt = AvailableValues.
find(HereBlock);
4177 if (AvailIt != AvailableValues.
end()) {
4186 BlockValueNum ResultInt = Impl.GetValue(Updater.getSSALDVBlock(Here.
getParent()));
4203 for (
const auto &DBG_PHI : DBGPHIRange) {
4204 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4206 ValidatedValues.
insert(std::make_pair(
Block, Num));
4211 for (
auto &
PHI : CreatedPHIs)
4214 llvm::sort(SortedPHIs, [&](LDVSSAPhi *
A, LDVSSAPhi *
B) {
4215 return BBToOrder[&
A->getParent()->BB] < BBToOrder[&
B->getParent()->BB];
4218 for (
auto &
PHI : SortedPHIs) {
4222 for (
auto &PHIIt :
PHI->IncomingValues) {
4224 if (Updater.PoisonMap.contains(&PHIIt.first->BB))
4225 return std::nullopt;
4228 const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB];
4230 auto VVal = ValidatedValues.
find(PHIIt.first);
4231 if (VVal == ValidatedValues.
end()) {
4236 ValueToCheck = ThisBlockValueNum;
4240 ValueToCheck = VVal->second;
4243 if (BlockLiveOuts[Loc.
asU64()] != ValueToCheck)
4244 return std::nullopt;
4248 ValidatedValues.
insert({
PHI->ParentBlock, ThisBlockValueNum});
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)
unsigned const TargetRegisterInfo * TRI
const char LLVMTargetMachineRef TM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
Target-Independent Code Generator Pass Configuration Options pass.
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 MachineBasicBlock *, DbgValue * > LiveIdxT
Live in/out structure for the variable values: a per-block map of variables to their values.
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.
InstrRefBasedLDV()
Default construct and initialize the pass.
DIExpression::FragmentInfo FragmentInfo
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?
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()
LocIdx trackRegister(unsigned ID)
Create a LocIdx for an untracked register ID.
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
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
MapVector< DebugVariableID, DbgValue > Vars
Map DebugVariable to the latest Value it's defined to have.
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 ValueIDNum EmptyValue
static 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
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)
TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker, MachineFunction &MF, const DebugVariableMap &DVMap, const TargetRegisterInfo &TRI, const BitVector &CalleeSavedRegs, const TargetPassConfig &TPC)
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
unsigned getNumElements() const
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 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...
bool isComplex() const
Return whether the location is computed on the expression stack, meaning it cannot be a simple regist...
static std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
static std::optional< const DIExpression * > convertToNonVariadicExpression(const DIExpression *Expr)
If Expr is a valid single-location expression, i.e.
bool isDeref() const
Return whether there is exactly one operator and it is a DW_OP_deref;.
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 ...
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.
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)
bool erase(const KeyT &Val)
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.
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
void initialize(const MachineFunction &)
initialize - Scan machine function and constuct lexical scope nest, resets the instance if necessary.
LexicalScope * findLexicalScope(const DILocation *DL)
findLexicalScope - Find lexical scope, either regular or inlined, for the given DebugLoc.
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.
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()
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...
std::vector< MachineBasicBlock * >::const_iterator const_succ_iterator
succ_iterator succ_begin()
bool isEntryBlock() const
Returns true if this is the entry block of the function.
Instructions::iterator instr_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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,...
std::vector< MachineBasicBlock * >::iterator pred_iterator
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool properlyDominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineDominatorTree & getBase()
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.
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...
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...
const_iterator begin() const
const_iterator end() const
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...
Primary interface to the complete machine description for the target machine.
Target-Independent Code Generator Pass Configuration Options.
TMC & getTM() const
Get the right type of TargetMachine for this target.
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.
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
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 TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
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)
auto reverse(ContainerTy &&C)
void sort(IteratorTy Start, IteratorTy End)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly.
detail::concat_range< ValueT, RangeTs... > concat(RangeTs &&... Ranges)
Concatenated range across two or more ranges.
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...
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
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::...