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"),
302 unsigned Location : 24;
303 unsigned Quality : 8;
308 : Location(L.asU64()), Quality(static_cast<
unsigned>(Q)) {}
321 std::optional<LocationQuality>
351 bool IsValueValid =
true;
352 unsigned LastUseBeforeDef = 0;
368 IsValueValid =
false;
378 auto ValuesPreferredLoc = ValueToLoc.
find(Num);
379 if (ValuesPreferredLoc->second.isIllegal()) {
385 LastUseBeforeDef = std::max(LastUseBeforeDef,
386 static_cast<unsigned>(Num.
getInst()));
390 IsValueValid =
false;
396 LocIdx M = ValuesPreferredLoc->second.getLoc();
406 if (LastUseBeforeDef) {
418 auto Result =
ActiveVLocs.insert(std::make_pair(Var, NewValue));
420 Result.first->second = NewValue;
447 for (
const auto &VLoc : VLocs)
449 for (
DbgOpID OpID : VLoc.second.getDbgOpIDs())
450 if (!OpID.ID.IsConst)
467 auto VIt = ValueToLoc.
find(VNum);
468 if (VIt == ValueToLoc.
end())
471 auto &Previous = VIt->second;
474 std::optional<LocationQuality> ReplacementQuality =
476 if (ReplacementQuality)
481 for (
const auto &Var : VLocs) {
511 for (
auto &
Use : MIt->second) {
516 assert(!
Op.isUndef() &&
"UseBeforeDef erroneously created for a "
517 "DbgValue with undef values.");
526 if (ValueToLoc.
empty())
535 auto VIt = ValueToLoc.
find(LocValueID);
536 if (VIt == ValueToLoc.
end())
539 auto &Previous = VIt->second;
542 std::optional<LocationQuality> ReplacementQuality =
544 if (ReplacementQuality)
550 for (
auto &
Use : MIt->second) {
561 LocIdx NewLoc = ValueToLoc.
find(
Op.ID)->second.getLoc();
570 if (DbgOps.
size() !=
Use.Values.size())
622 return Reg != SP && Reg !=
FP;
639 auto NonVariadicExpression =
641 if (!NonVariadicExpression)
643 DIExpr = *NonVariadicExpression;
668 MI.getDebugLoc()->getInlinedAt());
672 if (
MI.isUndefDebugValue() ||
677 for (
LocIdx Loc : It->second.loc_indices())
707 MI.getDebugLoc()->getInlinedAt());
714 for (
LocIdx Loc : It->second.loc_indices())
719 if (NewLocs.
empty()) {
739 for (
LocIdx Loc : LostVLocIt->second.loc_indices()) {
749 for (
const auto &LostMLoc : LostMLocs)
764 It->second.Ops.assign(NewLocs);
765 It->second.Properties = Properties;
774 bool MakeUndef =
true) {
796 std::optional<LocIdx> NewLoc;
798 if (Loc.Value == OldValue)
803 if (!NewLoc && !MakeUndef) {
805 for (
const auto &Var : ActiveMLocIt->second) {
806 auto &Prop =
ActiveVLocs.find(Var)->second.Properties;
818 for (
const auto &Var : ActiveMLocIt->second) {
833 DbgOps.
insert(DbgOps.
begin(), ActiveVLocIt->second.Ops.size(),
843 for (
LocIdx Loc : ActiveVLocIt->second.loc_indices()) {
849 ActiveVLocIt->second.Ops = DbgOps;
856 for (
auto &LocVarIt : LostMLocs) {
859 "Variable was using this MLoc, but ActiveMLocs[MLoc] has no "
861 LostMLocIt->second.erase(LocVarIt.second);
867 VarLocs[NewLoc->asU64()] = OldValue;
872 ActiveMLocIt->second.clear();
873 if (!NewMLocs.
empty())
874 for (
auto &Var : NewMLocs)
898 for (
const auto &Var : MovingVars) {
903 std::replace(ActiveVLocIt->second.Ops.begin(),
904 ActiveVLocIt->second.Ops.end(),
SrcOp,
DstOp);
907 ActiveVLocIt->second.Properties);
932 MIB.addMetadata(Properties.
DIExpr);
993 LocIdxToIDNum(
ValueIDNum::EmptyValue), LocIdxToLocID(0) {
1031 if (
Size > 60000 || Offs > 60000)
1067 if (MaskPair.first->clobbersPhysReg(
ID)) {
1069 ValNum = {
CurBB, MaskPair.second, NewIdx};
1090 Masks.push_back(std::make_pair(MO, InstID));
1096 if (SpillID.
id() == 0) {
1100 return std::nullopt;
1105 for (
unsigned StackIdx = 0; StackIdx <
NumSlotIdxes; ++StackIdx) {
1126 return Twine(
"slot ")
1143 std::string MLocName =
LocIdxToName(Location.Value.getLoc());
1144 std::string DefName = Location.Value.asString(MLocName);
1152 dbgs() <<
"Idx " << Location.Idx.asU64() <<
" " << foo <<
"\n";
1166 ?
TII.
get(TargetOpcode::DBG_VALUE_LIST)
1167 :
TII.
get(TargetOpcode::DBG_VALUE);
1169#ifdef EXPENSIVE_CHECKS
1172 return Op.IsConst || !
Op.Loc.isIllegal();
1174 "Did not expect illegal ops in DbgOps.");
1177 "Expected to have either one DbgOp per MI LocationOp, or none.");
1190 auto EmitUndef = [&]() {
1202 bool Indirect = Properties.
Indirect;
1224 unsigned short Offset = StackIdx.second;
1235 unsigned Base = Spill.SpillBase;
1251 bool UseDerefSize =
false;
1253 unsigned DerefSizeInBytes = ValueSizeInBits / 8;
1255 unsigned VariableSizeInBits = Fragment->SizeInBits;
1256 if (VariableSizeInBits != ValueSizeInBits || Expr->
isComplex())
1257 UseDerefSize =
true;
1259 if (*
Size != ValueSizeInBits) {
1260 UseDerefSize =
true;
1266 bool StackValue =
false;
1273 OffsetOps.
push_back(dwarf::DW_OP_deref);
1280 OffsetOps.
push_back(dwarf::DW_OP_deref_size);
1286 OffsetOps.
push_back(dwarf::DW_OP_deref);
1319 if (CalleeSavedRegs.
test(*RAI))
1333std::optional<SpillLocationNo>
1334InstrRefBasedLDV::extractSpillBaseRegAndOffset(
const MachineInstr &
MI) {
1336 "Spill instruction does not have exactly one memory operand?");
1337 auto MMOI =
MI.memoperands_begin();
1340 "Inconsistent memory operand in spill instruction");
1341 int FI = cast<FixedStackPseudoSourceValue>(PVal)->getFrameIndex();
1348std::optional<LocIdx>
1350 std::optional<SpillLocationNo>
SpillLoc = extractSpillBaseRegAndOffset(
MI);
1352 return std::nullopt;
1358 auto *MemOperand = *
MI.memoperands_begin();
1360 assert(SizeInBits.
hasValue() &&
"Expected to find a valid size!");
1367 return std::nullopt;
1375bool InstrRefBasedLDV::transferDebugValue(
const MachineInstr &
MI) {
1376 if (!
MI.isDebugValue())
1379 assert(
MI.getDebugVariable()->isValidLocationForIntrinsic(
MI.getDebugLoc()) &&
1380 "Expected inlined-at fields to agree");
1385 if (Scope ==
nullptr)
1391 if (MO.isReg() && MO.getReg() != 0)
1392 (void)MTracker->
readReg(MO.getReg());
1401 if (!
MI.isUndefDebugValue()) {
1407 }
else if (MO.isImm() || MO.isFPImm() || MO.isCImm()) {
1424std::optional<ValueIDNum> InstrRefBasedLDV::getValueForInstrRef(
1440 LowerBoundIt->Src == SoughtSub.Src) {
1441 std::tie(InstNo, OpNo) = LowerBoundIt->Dest;
1442 SoughtSub.Src = LowerBoundIt->Dest;
1443 if (
unsigned Subreg = LowerBoundIt->Subreg)
1444 SeenSubregs.push_back(Subreg);
1450 std::optional<ValueIDNum> NewID;
1454 auto InstrIt = DebugInstrNumToInstr.find(InstNo);
1456 if (InstrIt != DebugInstrNumToInstr.end()) {
1457 const MachineInstr &TargetInstr = *InstrIt->second.first;
1466 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, *L);
1479 NewID =
ValueIDNum(BlockNo, InstrIt->second.second, L);
1485 {
dbgs() <<
"Seen instruction reference to illegal operand\n"; });
1489 }
else if (PHIIt != DebugPHINumToValue.
end() && PHIIt->InstrNum == InstNo) {
1492 assert(MLiveOuts && MLiveIns);
1493 NewID = resolveDbgPHIs(*
MI.getParent()->getParent(), *MLiveOuts, *MLiveIns,
1506 if (NewID && !SeenSubregs.empty()) {
1514 for (
unsigned Subreg :
reverse(SeenSubregs)) {
1518 Size = (
Size == 0) ? ThisSize : std::min(
Size, ThisSize);
1526 if (NewID && !MTracker->
isSpill(L)) {
1532 if (TRCI->contains(Reg))
1534 assert(TRC &&
"Couldn't find target register class?");
1546 if (SubregSize ==
Size && SubregOffset ==
Offset) {
1554 NewID = std::nullopt;
1559 NewID =
ValueIDNum(NewID->getBlock(), NewID->getInst(), NewLoc);
1564 NewID = std::nullopt;
1574 if (!
MI.isDebugRef())
1579 if (!VTracker && !TTracker)
1587 "Expected inlined-at fields to agree");
1592 if (Scope ==
nullptr)
1598 assert(!MO.
isReg() &&
"DBG_INSTR_REF should not contain registers");
1609 std::optional<ValueIDNum> NewID =
1610 getValueForInstrRef(InstNo, OpNo,
MI, MLiveOuts, MLiveIns);
1627 VTracker->
defVar(
MI, Properties, DbgOpIDs);
1636 for (
DbgOpID OpID : DbgOpIDs) {
1646 for (
const DbgOp &
Op : DbgOps) {
1648 if (FoundLocs.
insert({Op.ID, TransferTracker::LocationAndQuality()})
1653 for (
auto Location : MTracker->
locations()) {
1656 auto ValueToFindIt =
find(ValuesToFind,
ID);
1657 if (ValueToFindIt == ValuesToFind.
end())
1659 auto &Previous = FoundLocs.
find(
ID)->second;
1662 std::optional<TransferTracker::LocationQuality> ReplacementQuality =
1664 if (ReplacementQuality) {
1666 if (Previous.isBest()) {
1667 ValuesToFind.
erase(ValueToFindIt);
1668 if (ValuesToFind.
empty())
1692 if (!DbgOps.empty() && NewLocs.
empty()) {
1693 bool IsValidUseBeforeDef =
true;
1695 for (
auto ValueLoc : FoundLocs) {
1697 LocIdx FoundLoc = ValueLoc.second.getLoc();
1703 IsValidUseBeforeDef =
false;
1706 LastUseBeforeDef = std::max(LastUseBeforeDef, NewID.
getInst());
1708 if (IsValidUseBeforeDef) {
1710 DbgOps, LastUseBeforeDef);
1726 if (!
MI.isDebugPHI())
1730 if (VTracker || TTracker)
1736 unsigned InstrNum =
MI.getOperand(1).getImm();
1738 auto EmitBadPHI = [
this, &
MI, InstrNum]() ->
bool {
1744 {InstrNum,
MI.getParent(), std::nullopt, std::nullopt});
1753 auto PHIRec = DebugPHIRecord(
1760 }
else if (MO.
isFI()) {
1767 return EmitBadPHI();
1778 return EmitBadPHI();
1781 assert(
MI.getNumOperands() == 3 &&
"Stack DBG_PHI with no size?");
1782 unsigned slotBitSize =
MI.getOperand(2).getImm();
1784 unsigned SpillID = MTracker->
getLocID(*SpillNo, {slotBitSize, 0});
1789 auto DbgPHI = DebugPHIRecord({InstrNum,
MI.getParent(), Result,
SpillLoc});
1797 {
dbgs() <<
"Seen DBG_PHI with unrecognised operand format\n"; });
1798 return EmitBadPHI();
1807 if (
MI.isImplicitDef()) {
1817 }
else if (
MI.isMetaInstruction())
1825 bool CallChangesSP =
false;
1826 if (AdjustsStackInCalls &&
MI.isCall() &&
MI.getOperand(0).isSymbol() &&
1827 !strcmp(
MI.getOperand(0).getSymbolName(), StackProbeSymbolName.
data()))
1828 CallChangesSP =
true;
1832 auto IgnoreSPAlias = [
this, &
MI, CallChangesSP](
Register R) ->
bool {
1835 return MI.isCall() && MTracker->
SPAliases.count(R);
1847 !IgnoreSPAlias(MO.
getReg())) {
1860 MTracker->
defReg(DeadReg, CurBB, CurInst);
1862 for (
const auto *MO : RegMaskPtrs)
1867 if (std::optional<SpillLocationNo> SpillNo =
1868 extractSpillBaseRegAndOffset(
MI)) {
1885 for (
uint32_t DeadReg : DeadRegs) {
1892 if (!RegMaskPtrs.empty()) {
1899 if (IgnoreSPAlias(Reg))
1902 for (
const auto *MO : RegMaskPtrs)
1910 if (std::optional<SpillLocationNo> SpillNo =
1911 extractSpillBaseRegAndOffset(
MI)) {
1921void InstrRefBasedLDV::performCopy(
Register SrcRegNum,
Register DstRegNum) {
1924 MTracker->
defReg(*RAI, CurBB, CurInst);
1927 MTracker->
setReg(DstRegNum, SrcValue);
1931 unsigned SrcSubReg = SRI.getSubReg();
1932 unsigned SubRegIdx = SRI.getSubRegIndex();
1933 unsigned DstSubReg = TRI->
getSubReg(DstRegNum, SubRegIdx);
1948 MTracker->
setReg(DstSubReg, CpyValue);
1952std::optional<SpillLocationNo>
1956 if (!
MI.hasOneMemOperand())
1957 return std::nullopt;
1960 auto MMOI =
MI.memoperands_begin();
1963 return std::nullopt;
1965 if (!
MI.getSpillSize(TII) && !
MI.getFoldedSpillSize(TII))
1966 return std::nullopt;
1969 return extractSpillBaseRegAndOffset(
MI);
1974 if (!isSpillInstruction(
MI, MF))
1982std::optional<SpillLocationNo>
1985 if (!
MI.hasOneMemOperand())
1986 return std::nullopt;
1990 if (
MI.getRestoreSize(TII)) {
1991 Reg =
MI.getOperand(0).getReg();
1992 return extractSpillBaseRegAndOffset(
MI);
1994 return std::nullopt;
1997bool InstrRefBasedLDV::transferSpillOrRestoreInst(
MachineInstr &
MI) {
2026 if (std::optional<SpillLocationNo> Loc = isSpillInstruction(
MI, MF)) {
2029 for (
unsigned SlotIdx = 0; SlotIdx < MTracker->
NumSlotIdxes; ++SlotIdx) {
2031 std::optional<LocIdx> MLoc = MTracker->
getSpillMLoc(SpillID);
2040 MTracker->
setMLoc(*MLoc, Def);
2047 if (isLocationSpill(
MI, MF, Reg)) {
2052 auto DoTransfer = [&](
Register SrcReg,
unsigned SpillID) {
2053 auto ReadValue = MTracker->
readReg(SrcReg);
2055 MTracker->
setMLoc(DstLoc, ReadValue);
2068 unsigned SpillID = MTracker->
getLocID(Loc, SubregIdx);
2069 DoTransfer(SR, SpillID);
2075 DoTransfer(Reg, SpillID);
2077 std::optional<SpillLocationNo> Loc = isRestoreInstruction(
MI, MF, Reg);
2089 MTracker->
defReg(*RAI, CurBB, CurInst);
2093 auto DoTransfer = [&](
Register DestReg,
unsigned SpillID) {
2095 auto ReadValue = MTracker->
readMLoc(SrcIdx);
2096 MTracker->
setReg(DestReg, ReadValue);
2101 unsigned SpillID = MTracker->
getLocID(*Loc, Subreg);
2102 DoTransfer(SR, SpillID);
2107 unsigned SpillID = MTracker->
getLocID(*Loc, {
Size, 0});
2108 DoTransfer(Reg, SpillID);
2125 if (SrcReg == DestReg)
2154 if (MLocIt == TTracker->
ActiveMLocs.
end() || MLocIt->second.empty())
2157 ClobberedLocs[ClobberedLoc] =
Value;
2162 InstrRefBasedLDV::performCopy(SrcReg, DestReg);
2168 for (
auto LocVal : ClobberedLocs) {
2169 TTracker->
clobberMloc(LocVal.first, LocVal.second,
MI.getIterator(),
false);
2182 MTracker->
defReg(SrcReg, CurBB, CurInst);
2196 MI.getDebugLoc()->getInlinedAt());
2197 FragmentInfo ThisFragment = MIVar.getFragmentOrDefault();
2202 auto SeenIt = SeenFragments.
find(MIVar.getVariable());
2203 if (SeenIt == SeenFragments.
end()) {
2205 OneFragment.
insert(ThisFragment);
2206 SeenFragments.
insert({MIVar.getVariable(), OneFragment});
2208 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2215 OverlapFragments.
insert({{MIVar.getVariable(), ThisFragment}, {}});
2216 if (!IsInOLapMap.second)
2219 auto &ThisFragmentsOverlaps = IsInOLapMap.first->second;
2220 auto &AllSeenFragments = SeenIt->second;
2225 for (
const auto &ASeenFragment : AllSeenFragments) {
2229 ThisFragmentsOverlaps.push_back(ASeenFragment);
2232 auto ASeenFragmentsOverlaps =
2233 OverlapFragments.
find({MIVar.getVariable(), ASeenFragment});
2234 assert(ASeenFragmentsOverlaps != OverlapFragments.
end() &&
2235 "Previously seen var fragment has no vector of overlaps");
2236 ASeenFragmentsOverlaps->second.push_back(ThisFragment);
2240 AllSeenFragments.insert(ThisFragment);
2249 if (transferDebugValue(
MI))
2251 if (transferDebugInstrRef(
MI, MLiveOuts, MLiveIns))
2253 if (transferDebugPHI(
MI))
2255 if (transferRegisterCopy(
MI))
2257 if (transferSpillOrRestoreInst(
MI))
2259 transferRegisterDef(
MI);
2262void InstrRefBasedLDV::produceMLocTransferFunction(
2278 for (
auto &BV : BlockMasks)
2282 for (
auto &
MBB : MF) {
2294 for (
auto &
MI :
MBB) {
2297 process(
MI,
nullptr,
nullptr);
2300 if (
MI.isDebugValueLike())
2301 accumulateFragmentMap(
MI);
2305 if (
uint64_t InstrNo =
MI.peekDebugInstrNum()) {
2306 auto InstrAndPos = std::make_pair(&
MI, CurInst);
2308 DebugInstrNumToInstr.insert(std::make_pair(InstrNo, InstrAndPos));
2311 assert(InsertResult.second);
2322 for (
auto Location : MTracker->
locations()) {
2325 if (
P.isPHI() &&
P.getLoc() ==
Idx.asU64())
2329 auto &TransferMap = MLocTransfer[CurBB];
2330 auto Result = TransferMap.insert(std::make_pair(
Idx.asU64(),
P));
2337 for (
auto &
P : MTracker->
Masks) {
2338 BlockMasks[CurBB].clearBitsNotInMask(
P.first->getRegMask(), BVWords);
2344 for (
auto Location : MTracker->
locations()) {
2362 for (
unsigned Bit : BV.
set_bits()) {
2365 auto &TransferMap = MLocTransfer[
I];
2374 TransferMap.insert(std::make_pair(
Idx.asU64(), NotGeneratedNum));
2379 ValueID = NotGeneratedNum;
2385bool InstrRefBasedLDV::mlocJoin(
2389 bool Changed =
false;
2402 return BBToOrder.find(
A)->second < BBToOrder.find(
B)->second;
2407 if (BlockOrders.
size() == 0) {
2412 <<
" from entry which may lead out of "
2413 "bound access to VarLocs\n");
2419 for (
auto Location : MTracker->
locations()) {
2424 ValueIDNum FirstVal = OutLocs[*BlockOrders[0]][
Idx.asU64()];
2429 if (InLocs[
Idx.asU64()] != FirstVal) {
2430 InLocs[
Idx.asU64()] = FirstVal;
2438 bool Disagree =
false;
2439 for (
unsigned int I = 1;
I < BlockOrders.size(); ++
I) {
2441 const ValueIDNum &PredLiveOut = OutLocs[*PredMBB][
Idx.asU64()];
2444 if (FirstVal == PredLiveOut)
2457 InLocs[
Idx.asU64()] = FirstVal;
2466void InstrRefBasedLDV::findStackIndexInterference(
2486 if (!Pair.first.second)
2492void InstrRefBasedLDV::placeMLocPHIs(
2496 findStackIndexInterference(StackUnits);
2508 for (
auto Location : MTracker->
locations()) {
2517 bool AnyIllegal =
false;
2526 FoundRegUnits.
insert(*URoot);
2532 NormalLocsToPHI.
insert(L);
2536 RegUnitsToPHIUp.
insert(FoundRegUnits.
begin(), FoundRegUnits.
end());
2542 auto CollectPHIsForLoc = [&](
LocIdx L) {
2545 for (
unsigned int I = 0;
I < OrderToBB.size(); ++
I) {
2547 const auto &TransferFunc = MLocTransfer[
MBB->
getNumber()];
2548 if (TransferFunc.contains(L))
2555 if (!DefBlocks.
empty())
2561 BlockPHIPlacement(AllBlocks, DefBlocks, PHIBlocks);
2564 auto InstallPHIsAtLoc = [&PHIBlocks, &MInLocs](
LocIdx L) {
2570 for (
LocIdx L : NormalLocsToPHI) {
2571 CollectPHIsForLoc(L);
2573 InstallPHIsAtLoc(L);
2579 for (
unsigned Idx : StackUnits) {
2582 CollectPHIsForLoc(L);
2583 InstallPHIsAtLoc(L);
2589 unsigned ThisSize, ThisOffset;
2590 std::tie(ThisSize, ThisOffset) = Pair.first;
2596 InstallPHIsAtLoc(ThisL);
2602 for (
Register R : RegUnitsToPHIUp) {
2604 CollectPHIsForLoc(L);
2607 InstallPHIsAtLoc(L);
2617 InstallPHIsAtLoc(AliasLoc);
2622void InstrRefBasedLDV::buildMLocValueMap(
2625 std::priority_queue<unsigned int, std::vector<unsigned int>,
2626 std::greater<unsigned int>>
2637 for (
unsigned int I = 0;
I < BBToOrder.size(); ++
I) {
2639 OnWorklist.
insert(OrderToBB[
I]);
2640 AllBlocks.
insert(OrderToBB[
I]);
2644 for (
auto Location : MTracker->
locations())
2653 placeMLocPHIs(MF, AllBlocks, MInLocs, MLocTransfer);
2664 while (!Worklist.empty() || !Pending.empty()) {
2668 while (!Worklist.empty()) {
2675 InLocsChanged = mlocJoin(*
MBB, Visited, MOutLocs, MInLocs[*
MBB]);
2676 InLocsChanged |= Visited.
insert(
MBB).second;
2689 for (
auto &
P : MLocTransfer[CurBB]) {
2690 if (
P.second.getBlock() == CurBB &&
P.second.isPHI()) {
2693 ToRemap.
push_back(std::make_pair(
P.first, NewID));
2696 assert(
P.second.getBlock() == CurBB);
2697 ToRemap.
push_back(std::make_pair(
P.first,
P.second));
2703 for (
auto &
P : ToRemap)
2709 bool OLChanged =
false;
2710 for (
auto Location : MTracker->
locations()) {
2726 if (BBToOrder[s] > BBToOrder[
MBB]) {
2728 if (OnWorklist.
insert(s).second)
2729 Worklist.push(BBToOrder[s]);
2732 if (OnPending.
insert(s).second)
2733 Pending.push(BBToOrder[s]);
2738 Worklist.swap(Pending);
2743 assert(Pending.empty() &&
"Pending should be empty");
2750void InstrRefBasedLDV::BlockPHIPlacement(
2759 IDF.setLiveInBlocks(AllBlocks);
2760 IDF.setDefiningBlocks(DefBlocks);
2761 IDF.calculate(PHIBlocks);
2764bool InstrRefBasedLDV::pickVPHILoc(
2770 if (BlockOrders.
empty())
2777 auto FirstValueIt = LiveOuts.
find(BlockOrders[0]);
2778 if (FirstValueIt == LiveOuts.end())
2780 const DbgValue &FirstValue = *FirstValueIt->second;
2782 for (
const auto p : BlockOrders) {
2783 auto OutValIt = LiveOuts.find(p);
2784 if (OutValIt == LiveOuts.end())
2787 const DbgValue &OutVal = *OutValIt->second;
2810 if (FirstValOp != OutValOp) {
2831 std::optional<ValueIDNum> JoinedOpLoc =
2832 pickOperandPHILoc(
Idx,
MBB, LiveOuts, MOutLocs, BlockOrders);
2840 OutValues.
append(NewDbgOps);
2844std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc(
2854 for (
const auto p : BlockOrders) {
2855 auto OutValIt = LiveOuts.find(p);
2856 assert(OutValIt != LiveOuts.end());
2857 const DbgValue &OutVal = *OutValIt->second;
2859 DbgOp OutValOp = DbgOpStore.
find(OutValOpID);
2872 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2873 if (MOutLocs[*p][
I] == ValToLookFor)
2884 for (
unsigned int I = 0;
I < NumLocs; ++
I) {
2886 if (MOutLocs[*p][
I] == MPHI)
2897 for (
unsigned int I = 1;
I < Locs.
size(); ++
I) {
2898 auto &LocVec = Locs[
I];
2900 std::set_intersection(CandidateLocs.
begin(), CandidateLocs.
end(),
2901 LocVec.begin(), LocVec.end(), std::inserter(NewCandidates, NewCandidates.
begin()));
2902 CandidateLocs = NewCandidates;
2904 if (CandidateLocs.
empty())
2905 return std::nullopt;
2917bool InstrRefBasedLDV::vlocJoin(
2922 bool Changed =
false;
2928 return BBToOrder[
A] < BBToOrder[
B];
2933 unsigned CurBlockRPONum = BBToOrder[&
MBB];
2939 int BackEdgesStart = 0;
2940 for (
auto *p : BlockOrders) {
2943 if (!BlocksToExplore.
contains(p)) {
2949 DbgValue &OutLoc = *VLOCOutLocs.find(p)->second;
2953 unsigned ThisBBRPONum = BBToOrder[
p];
2954 if (ThisBBRPONum < CurBlockRPONum)
2957 Values.
push_back(std::make_pair(p, &OutLoc));
2963 if (Bail || Values.
size() == 0)
2969 const DbgValue &FirstVal = *Values[0].second;
2975 Changed = LiveIn != FirstVal;
2984 for (
const auto &V : Values) {
2985 if (!
V.second->Properties.isJoinable(FirstVal.
Properties))
2989 if (!
V.second->hasJoinableLocOps(FirstVal))
2994 bool Disagree =
false;
2995 for (
auto &V : Values) {
2996 if (*
V.second == FirstVal)
3002 if (
V.second->hasIdenticalValidLocOps(FirstVal))
3009 std::distance(Values.begin(), &V) >= BackEdgesStart)
3017 Changed = LiveIn != FirstVal;
3024 Changed = LiveIn != VPHI;
3031void InstrRefBasedLDV::getBlocksForScope(
3041 BlocksToExplore.
insert(AssignBlocks.
begin(), AssignBlocks.
end());
3051 for (
const auto *
MBB : BlocksToExplore) {
3061 if (BlocksToExplore.count(succ))
3063 if (!ArtificialBlocks.count(succ))
3066 DFS.push_back({succ, succ->succ_begin()});
3070 while (!DFS.empty()) {
3074 if (CurSucc == CurBB->
succ_end()) {
3081 if (!ToAdd.
count(*CurSucc) && ArtificialBlocks.count(*CurSucc)) {
3083 DFS.push_back({*CurSucc, (*CurSucc)->succ_begin()});
3091 BlocksToExplore.insert(ToAdd.
begin(), ToAdd.
end());
3094void InstrRefBasedLDV::buildVLocValueMap(
3103 std::priority_queue<unsigned int, std::vector<unsigned int>,
3104 std::greater<unsigned int>>
3116 return BBToOrder[
A] < BBToOrder[
B];
3119 getBlocksForScope(DILoc, BlocksToExplore, AssignBlocks);
3125 if (BlocksToExplore.
size() == 1)
3132 for (
const auto *
MBB : BlocksToExplore)
3136 for (
const auto *
MBB : BlocksToExplore)
3140 unsigned NumBlocks = BlockOrders.
size();
3150 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3159 LiveOutIdx.reserve(NumBlocks);
3160 LiveInIdx.reserve(NumBlocks);
3161 for (
unsigned I = 0;
I < NumBlocks; ++
I) {
3162 LiveOutIdx[BlockOrders[
I]] = &LiveOuts[
I];
3163 LiveInIdx[BlockOrders[
I]] = &LiveIns[
I];
3170 for (
const auto &Var : VarsWeCareAbout) {
3173 for (
unsigned int I = 0;
I < NumBlocks; ++
I) {
3175 LiveIns[
I] = EmptyDbgValue;
3176 LiveOuts[
I] = EmptyDbgValue;
3183 auto &TransferFunc = AllTheVLocs[ExpMBB->getNumber()].Vars;
3184 if (TransferFunc.contains(Var))
3192 if (DefBlocks.
size() == 1) {
3193 placePHIsForSingleVarDefinition(MutBlocksToExplore, *DefBlocks.
begin(),
3194 AllTheVLocs, Var, Output);
3199 BlockPHIPlacement(MutBlocksToExplore, DefBlocks, PHIBlocks);
3203 unsigned BlockNo = PHIMBB->getNumber();
3204 DbgValue *LiveIn = LiveInIdx[PHIMBB];
3208 for (
auto *
MBB : BlockOrders) {
3209 Worklist.push(BBToOrder[
MBB]);
3220 bool FirstTrip =
true;
3221 while (!Worklist.empty() || !Pending.empty()) {
3222 while (!Worklist.empty()) {
3223 auto *
MBB = OrderToBB[Worklist.top()];
3227 auto LiveInsIt = LiveInIdx.find(
MBB);
3228 assert(LiveInsIt != LiveInIdx.end());
3229 DbgValue *LiveIn = LiveInsIt->second;
3233 bool InLocsChanged =
3234 vlocJoin(*
MBB, LiveOutIdx, BlocksToExplore, *LiveIn);
3251 if (pickVPHILoc(JoinedOps, *
MBB, LiveOutIdx, MOutLocs, Preds)) {
3253 InLocsChanged |= NewLocPicked;
3259 if (!InLocsChanged && !FirstTrip)
3263 bool OLChanged =
false;
3267 auto TransferIt = VTracker.
Vars.find(Var);
3268 if (TransferIt != VTracker.
Vars.end()) {
3272 if (*LiveOut != NewVal) {
3278 if (*LiveOut != TransferIt->second) {
3279 *LiveOut = TransferIt->second;
3285 if (*LiveOut != *LiveIn) {
3300 if (!LiveInIdx.contains(s))
3303 if (BBToOrder[s] > BBToOrder[
MBB]) {
3304 if (OnWorklist.
insert(s).second)
3305 Worklist.push(BBToOrder[s]);
3306 }
else if (OnPending.
insert(s).second && (FirstTrip || OLChanged)) {
3307 Pending.push(BBToOrder[s]);
3311 Worklist.swap(Pending);
3321 for (
auto *
MBB : BlockOrders) {
3330 Var.getFragment() &&
"Fragment info missing during value prop");
3331 Output[
MBB->
getNumber()].push_back(std::make_pair(Var, *BlockLiveIn));
3335 BlockOrders.clear();
3336 BlocksToExplore.clear();
3339void InstrRefBasedLDV::placePHIsForSingleVarDefinition(
3355 auto ValueIt = VLocs.
Vars.find(Var);
3366 for (
auto *ScopeBlock : InScopeBlocks) {
3370 Output[ScopeBlock->getNumber()].push_back({Var,
Value});
3377#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
3380 for (
const auto &
P : mloc_transfer) {
3383 dbgs() <<
"Loc " << foo <<
" --> " << bar <<
"\n";
3392 EmptyExpr = DIExpression::get(Context, {});
3394 auto hasNonArtificialLocation = [](
const MachineInstr &
MI) ->
bool {
3396 return DL.getLine() != 0;
3400 for (
auto &
MBB : MF)
3402 ArtificialBlocks.insert(&
MBB);
3406 unsigned int RPONumber = 0;
3408 OrderToBB[RPONumber] =
MBB;
3409 BBToOrder[
MBB] = RPONumber;
3416 if (!BBToOrder.contains(&
MBB))
3422#ifdef EXPENSIVE_CHECKS
3425 if (MF.DebugValueSubstitutions.size() > 2) {
3426 for (
auto It = MF.DebugValueSubstitutions.begin();
3427 It != std::prev(MF.DebugValueSubstitutions.end()); ++It) {
3428 assert(It->Src != std::next(It)->Src &&
"Duplicate variable location "
3429 "substitution seen");
3438void InstrRefBasedLDV::makeDepthFirstEjectionMap(
3440 const ScopeToDILocT &ScopeToDILocation,
3441 ScopeToAssignBlocksT &ScopeToAssignBlocks) {
3448 WorkStack.
push_back({TopScope, TopScope->getChildren().
size() - 1});
3450 while (!WorkStack.
empty()) {
3451 auto &ScopePosition = WorkStack.
back();
3453 ssize_t ChildNum = ScopePosition.second--;
3456 if (ChildNum >= 0) {
3459 auto &ChildScope =
Children[ChildNum];
3461 std::make_pair(ChildScope, ChildScope->getChildren().size() - 1));
3468 auto DILocationIt = ScopeToDILocation.find(WS);
3469 if (DILocationIt != ScopeToDILocation.end()) {
3470 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3471 ScopeToAssignBlocks.find(WS)->second);
3472 for (
const auto *
MBB : BlocksToExplore) {
3474 if (EjectionMap[BBNum] == 0)
3478 BlocksToExplore.clear();
3484bool InstrRefBasedLDV::depthFirstVLocAndEmit(
3485 unsigned MaxNumBlocks,
const ScopeToDILocT &ScopeToDILocation,
3486 const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,
3491 TTracker =
new TransferTracker(TII, MTracker, MF, *TRI, CalleeSavedRegs, TPC);
3502 makeDepthFirstEjectionMap(EjectionMap, ScopeToDILocation,
3503 ScopeToAssignBlocks);
3510 AllTheVLocs[BBNum].
clear();
3516 TTracker->
loadInlocs(
MBB, MInLocs[
MBB], DbgOpStore, Output[BBNum], NumLocs);
3520 for (
auto &
MI :
MBB) {
3521 process(
MI, &MOutLocs, &MInLocs);
3530 Output[BBNum].clear();
3531 AllTheVLocs[BBNum].
clear();
3537 unsigned HighestDFSIn = 0;
3540 while (!WorkStack.
empty()) {
3541 auto &ScopePosition = WorkStack.
back();
3543 ssize_t ChildNum = ScopePosition.second++;
3550 auto DILocIt = ScopeToDILocation.find(WS);
3551 if (HighestDFSIn <= WS->getDFSIn() && DILocIt != ScopeToDILocation.end()) {
3553 auto &VarsWeCareAbout = ScopeToVars.find(WS)->second;
3554 auto &BlocksInScope = ScopeToAssignBlocks.find(WS)->second;
3556 buildVLocValueMap(DILoc, VarsWeCareAbout, BlocksInScope, Output, MOutLocs,
3557 MInLocs, AllTheVLocs);
3560 HighestDFSIn = std::max(HighestDFSIn, WS->
getDFSIn());
3564 if (ChildNum < (ssize_t)
Children.size()) {
3566 auto &ChildScope =
Children[ChildNum];
3567 WorkStack.
push_back(std::make_pair(ChildScope, 0));
3573 auto DILocationIt = ScopeToDILocation.find(WS);
3574 if (DILocationIt == ScopeToDILocation.end())
3577 getBlocksForScope(DILocationIt->second, BlocksToExplore,
3578 ScopeToAssignBlocks.find(WS)->second);
3579 for (
const auto *
MBB : BlocksToExplore)
3583 BlocksToExplore.clear();
3592 for (
auto *
MBB : ArtificialBlocks)
3596 return emitTransfers(AllVarsNumbering);
3599bool InstrRefBasedLDV::emitTransfers(
3612 MI->getDebugLoc()->getInlinedAt());
3620 for (
const auto &Pair : Insts)
3625 if (
P.Pos->isTerminator())
3629 for (
const auto &Pair : Insts)
3643 unsigned InputDbgValLimit) {
3651 this->DomTree = DomTree;
3662 STI.getFrameLowering()->stackProbeFunctionModifiesSP();
3663 if (AdjustsStackInCalls)
3664 StackProbeSymbolName = STI.getTargetLowering()->getStackProbeSymbolName(MF);
3676 for (
auto &
MBB : MF)
3687 produceMLocTransferFunction(MF, MLocTransfer,
MaxNumBlocks);
3700 buildMLocValueMap(MF, MInLocs, MOutLocs, MLocTransfer);
3704 for (
auto &DBG_PHI : DebugPHINumToValue) {
3706 if (!DBG_PHI.ValueRead)
3720 Num = ResolvedValue;
3727 for (
auto &OrderPair : OrderToBB) {
3730 VTracker = &vlocs[CurBB];
3734 for (
auto &
MI :
MBB) {
3735 process(
MI, &MOutLocs, &MInLocs);
3757 unsigned VarAssignCount = 0;
3758 for (
unsigned int I = 0;
I < OrderToBB.size(); ++
I) {
3759 auto *
MBB = OrderToBB[
I];
3762 for (
auto &idx : VTracker->
Vars) {
3763 const auto &Var = idx.first;
3765 assert(ScopeLoc !=
nullptr);
3769 assert(Scope !=
nullptr);
3771 AllVarsNumbering.
insert(std::make_pair(Var, AllVarsNumbering.
size()));
3772 ScopeToVars[
Scope].insert(Var);
3773 ScopeToAssignBlocks[
Scope].insert(VTracker->
MBB);
3774 ScopeToDILocation[
Scope] = ScopeLoc;
3779 bool Changed =
false;
3785 VarAssignCount > InputDbgValLimit) {
3786 LLVM_DEBUG(
dbgs() <<
"Disabling InstrRefBasedLDV: " << MF.getName()
3789 <<
" variable assignments, exceeding limits.\n");
3794 Changed = depthFirstVLocAndEmit(
3795 MaxNumBlocks, ScopeToDILocation, ScopeToVars, ScopeToAssignBlocks,
3796 SavedLiveIns, MOutLocs, MInLocs, vlocs, MF, AllVarsNumbering, *TPC);
3805 ArtificialBlocks.clear();
3809 DebugInstrNumToInstr.clear();
3810 DebugPHINumToValue.clear();
3811 OverlapFragments.
clear();
3812 SeenFragments.
clear();
3813 SeenDbgPHIs.clear();
3838 LDVSSABlock *ParentBlock;
3839 BlockValueNum PHIValNum;
3840 LDVSSAPhi(BlockValueNum PHIValNum, LDVSSABlock *ParentBlock)
3841 : ParentBlock(ParentBlock), PHIValNum(PHIValNum) {}
3843 LDVSSABlock *
getParent() {
return ParentBlock; }
3848class LDVSSABlockIterator {
3851 LDVSSAUpdater &Updater;
3854 LDVSSAUpdater &Updater)
3855 : PredIt(PredIt), Updater(Updater) {}
3857 bool operator!=(
const LDVSSABlockIterator &OtherIt)
const {
3858 return OtherIt.PredIt != PredIt;
3861 LDVSSABlockIterator &operator++() {
3875 LDVSSAUpdater &Updater;
3881 : BB(BB), Updater(Updater) {}
3884 return LDVSSABlockIterator(BB.
succ_begin(), Updater);
3888 return LDVSSABlockIterator(BB.
succ_end(), Updater);
3892 LDVSSAPhi *newPHI(BlockValueNum
Value) {
3893 PHIList.emplace_back(
Value,
this);
3894 return &PHIList.back();
3898 PHIListT &phis() {
return PHIList; }
3904class LDVSSAUpdater {
3919 : Loc(
L), MLiveIns(MLiveIns) {}
3922 for (
auto &
Block : BlockMap)
3923 delete Block.second;
3930 ~LDVSSAUpdater() { reset(); }
3935 auto it = BlockMap.find(BB);
3936 if (it == BlockMap.end()) {
3937 BlockMap[BB] =
new LDVSSABlock(*BB, *
this);
3938 it = BlockMap.find(BB);
3945 BlockValueNum getValue(LDVSSABlock *LDVBB) {
3946 return MLiveIns[LDVBB->BB][Loc.
asU64()].asU64();
3950LDVSSABlock *LDVSSABlockIterator::operator*() {
3951 return Updater.getSSALDVBlock(*PredIt);
3957 out <<
"SSALDVPHI " <<
PHI.PHIValNum;
3983 class PHI_iterator {
4009 return PHI_iterator(
PHI,
true);
4017 Preds->
push_back(BB->Updater.getSSALDVBlock(Pred));
4023 static BlockValueNum
GetUndefVal(LDVSSABlock *BB, LDVSSAUpdater *Updater) {
4027 BlockValueNum Num =
ValueIDNum(BB->BB.getNumber(), 0, Updater->Loc).
asU64();
4028 Updater->UndefMap[&BB->BB] = Num;
4038 LDVSSAUpdater *Updater) {
4039 BlockValueNum PHIValNum = Updater->getValue(BB);
4040 LDVSSAPhi *
PHI = BB->newPHI(PHIValNum);
4041 Updater->PHIs[PHIValNum] =
PHI;
4048 PHI->IncomingValues.push_back(std::make_pair(Pred, Val));
4053 static LDVSSAPhi *
ValueIsPHI(BlockValueNum Val, LDVSSAUpdater *Updater) {
4054 return Updater->PHIs.lookup(Val);
4060 LDVSSAPhi *
PHI = ValueIsPHI(Val, Updater);
4061 if (
PHI &&
PHI->IncomingValues.size() == 0)
4073std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(
4078 auto SeenDbgPHIIt = SeenDbgPHIs.find(std::make_pair(&Here, InstrNum));
4079 if (SeenDbgPHIIt != SeenDbgPHIs.end())
4080 return SeenDbgPHIIt->second;
4082 std::optional<ValueIDNum>
Result =
4083 resolveDbgPHIsImpl(MF, MLiveOuts, MLiveIns, Here, InstrNum);
4084 SeenDbgPHIs.insert({std::make_pair(&Here, InstrNum),
Result});
4088std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
4093 auto RangePair = std::equal_range(DebugPHINumToValue.begin(),
4094 DebugPHINumToValue.end(), InstrNum);
4095 auto LowerIt = RangePair.first;
4096 auto UpperIt = RangePair.second;
4099 if (LowerIt == UpperIt)
4100 return std::nullopt;
4106 auto DBGPHIRange =
make_range(LowerIt, UpperIt);
4107 for (
const DebugPHIRecord &DBG_PHI : DBGPHIRange)
4108 if (!DBG_PHI.ValueRead)
4109 return std::nullopt;
4112 if (std::distance(LowerIt, UpperIt) == 1)
4113 return *LowerIt->ValueRead;
4119 LocIdx Loc = *LowerIt->ReadLoc;
4128 LDVSSAUpdater Updater(Loc, MLiveIns);
4136 for (
const auto &DBG_PHI : DBGPHIRange) {
4137 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4142 LDVSSABlock *HereBlock = Updater.getSSALDVBlock(Here.
getParent());
4143 const auto &AvailIt = AvailableValues.
find(HereBlock);
4144 if (AvailIt != AvailableValues.
end()) {
4153 BlockValueNum ResultInt = Impl.GetValue(Updater.getSSALDVBlock(Here.
getParent()));
4170 for (
const auto &DBG_PHI : DBGPHIRange) {
4171 LDVSSABlock *
Block = Updater.getSSALDVBlock(DBG_PHI.MBB);
4173 ValidatedValues.
insert(std::make_pair(
Block, Num));
4178 for (
auto &
PHI : CreatedPHIs)
4181 llvm::sort(SortedPHIs, [&](LDVSSAPhi *
A, LDVSSAPhi *
B) {
4182 return BBToOrder[&
A->getParent()->BB] < BBToOrder[&
B->getParent()->BB];
4185 for (
auto &
PHI : SortedPHIs) {
4189 for (
auto &PHIIt :
PHI->IncomingValues) {
4191 if (Updater.UndefMap.contains(&PHIIt.first->BB))
4192 return std::nullopt;
4195 const ValueTable &BlockLiveOuts = MLiveOuts[PHIIt.first->BB];
4197 auto VVal = ValidatedValues.
find(PHIIt.first);
4198 if (VVal == ValidatedValues.
end()) {
4203 ValueToCheck = ThisBlockValueNum;
4207 ValueToCheck = VVal->second;
4210 if (BlockLiveOuts[Loc.
asU64()] != ValueToCheck)
4211 return std::nullopt;
4215 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
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< DebugVariable, 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.
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...
MachineInstrBuilder emitLoc(const SmallVectorImpl< ResolvedDbgOp > &DbgOps, const DebugVariable &Var, const DbgValueProperties &Properties)
Create a DBG_VALUE based on debug operands DbgOps.
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.
void defVar(const MachineInstr &MI, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOpID > &DebugOps)
SmallDenseMap< DebugVariable, const DILocation *, 8 > Scopes
MapVector< DebugVariable, 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...
void loadVarInloc(MachineBasicBlock &MBB, DbgOpIDMap &DbgOpStore, const DenseMap< ValueIDNum, LocationAndQuality > &ValueToLoc, DebugVariable Var, DbgValue Value)
For a variable Var with the live-in value Value, attempts to resolve the DbgValue to a concrete DBG_V...
void loadInlocs(MachineBasicBlock &MBB, ValueTable &MLocs, DbgOpIDMap &DbgOpStore, const SmallVectorImpl< std::pair< DebugVariable, DbgValue > > &VLocs, unsigned NumLocs)
Load object with live-in variable values.
const BitVector & CalleeSavedRegs
const TargetLowering * TLI
DenseSet< DebugVariable > UseBeforeDefVariables
The set of variables that are in UseBeforeDefs and can become a location once the relevant value is d...
SmallVector< ValueIDNum, 32 > VarLocs
Local cache of what-value-is-in-what-LocIdx.
DenseMap< DebugVariable, ResolvedDbgValue > ActiveVLocs
Map from DebugVariable to it's current location and qualifying meta information.
MLocTracker * MTracker
This machine location tracker is assumed to always contain the up-to-date value mapping for all machi...
TransferTracker(const TargetInstrInfo *TII, MLocTracker *MTracker, MachineFunction &MF, const TargetRegisterInfo &TRI, const BitVector &CalleeSavedRegs, const TargetPassConfig &TPC)
DenseMap< LocIdx, SmallSet< DebugVariable, 4 > > ActiveMLocs
Map from LocIdxes to which DebugVariables are based that location.
bool recoverAsEntryValue(const DebugVariable &Var, const DbgValueProperties &Prop, const ValueIDNum &Num)
SmallVector< MachineInstr *, 4 > PendingDbgValues
Temporary cache of DBG_VALUEs to be entered into the Transfers collection.
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
void addUseBeforeDef(const DebugVariable &Var, const DbgValueProperties &Properties, const SmallVectorImpl< DbgOp > &DbgOps, unsigned Inst)
Record that Var has value ID, a value that becomes available later in the function.
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
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 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< 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.
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
MachineDomTree & 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 GetUndefVal(LDVSSABlock *BB, LDVSSAUpdater *Updater)
GetUndefVal - 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.
Interval::succ_iterator succ_end(Interval *I)
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.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
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...
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< 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 ...
DebugVariable Var
Identity of this variable.
DbgValueProperties Properties
Additional variable properties.
SmallVector< DbgOp > Values
Value of this variable, def'd in block.
UseBeforeDef(ArrayRef< DbgOp > Values, const DebugVariable &Var, const DbgValueProperties &Properties)
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::...