#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/TargetFrameLowering.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/GenericIteratedDominanceFrontier.h"
#include "llvm/Support/TypeSize.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/SSAUpdaterImpl.h"
#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdint>
#include <functional>
#include <queue>
#include <tuple>
#include <utility>
#include <vector>
#include "InstrRefBasedImpl.h"
#include "LiveDebugValues.h"
#include <optional>
usingnamespacellvm;
usingnamespaceLiveDebugValues;
#undef DEBUG_TYPE
#define DEBUG_TYPE …
static cl::opt<bool> EmulateOldLDV("emulate-old-livedebugvalues", cl::Hidden,
cl::desc("Act like old LiveDebugValues did"),
cl::init(false));
static cl::opt<unsigned>
StackWorkingSetLimit("livedebugvalues-max-stack-slots", cl::Hidden,
cl::desc("livedebugvalues-stack-ws-limit"),
cl::init(250));
DbgOpID DbgOpID::UndefID = …;
class TransferTracker { … };
ValueIDNum ValueIDNum::EmptyValue = …;
ValueIDNum ValueIDNum::TombstoneValue = …;
#ifndef NDEBUG
void ResolvedDbgOp::dump(const MLocTracker *MTrack) const {
if (IsConst) {
dbgs() << MO;
} else {
dbgs() << MTrack->LocIdxToName(Loc);
}
}
void DbgOp::dump(const MLocTracker *MTrack) const {
if (IsConst) {
dbgs() << MO;
} else if (!isUndef()) {
dbgs() << MTrack->IDAsString(ID);
}
}
void DbgOpID::dump(const MLocTracker *MTrack, const DbgOpIDMap *OpStore) const {
if (!OpStore) {
dbgs() << "ID(" << asU32() << ")";
} else {
OpStore->find(*this).dump(MTrack);
}
}
void DbgValue::dump(const MLocTracker *MTrack,
const DbgOpIDMap *OpStore) const {
if (Kind == NoVal) {
dbgs() << "NoVal(" << BlockNo << ")";
} else if (Kind == VPHI || Kind == Def) {
if (Kind == VPHI)
dbgs() << "VPHI(" << BlockNo << ",";
else
dbgs() << "Def(";
for (unsigned Idx = 0; Idx < getDbgOpIDs().size(); ++Idx) {
getDbgOpID(Idx).dump(MTrack, OpStore);
if (Idx != 0)
dbgs() << ",";
}
dbgs() << ")";
}
if (Properties.Indirect)
dbgs() << " indir";
if (Properties.DIExpr)
dbgs() << " " << *Properties.DIExpr;
}
#endif
MLocTracker::MLocTracker(MachineFunction &MF, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const TargetLowering &TLI)
: … { … }
LocIdx MLocTracker::trackRegister(unsigned ID) { … }
void MLocTracker::writeRegMask(const MachineOperand *MO, unsigned CurBB,
unsigned InstID) { … }
std::optional<SpillLocationNo> MLocTracker::getOrTrackSpillLoc(SpillLoc L) { … }
std::string MLocTracker::LocIdxToName(LocIdx Idx) const { … }
std::string MLocTracker::IDAsString(const ValueIDNum &Num) const { … }
#ifndef NDEBUG
LLVM_DUMP_METHOD void MLocTracker::dump() {
for (auto Location : locations()) {
std::string MLocName = LocIdxToName(Location.Value.getLoc());
std::string DefName = Location.Value.asString(MLocName);
dbgs() << LocIdxToName(Location.Idx) << " --> " << DefName << "\n";
}
}
LLVM_DUMP_METHOD void MLocTracker::dump_mloc_map() {
for (auto Location : locations()) {
std::string foo = LocIdxToName(Location.Idx);
dbgs() << "Idx " << Location.Idx.asU64() << " " << foo << "\n";
}
}
#endif
MachineInstrBuilder
MLocTracker::emitLoc(const SmallVectorImpl<ResolvedDbgOp> &DbgOps,
const DebugVariable &Var, const DILocation *DILoc,
const DbgValueProperties &Properties) { … }
InstrRefBasedLDV::InstrRefBasedLDV() = default;
bool InstrRefBasedLDV::isCalleeSaved(LocIdx L) const { … }
bool InstrRefBasedLDV::isCalleeSavedReg(Register R) const { … }
#ifndef NDEBUG
#endif
std::optional<SpillLocationNo>
InstrRefBasedLDV::extractSpillBaseRegAndOffset(const MachineInstr &MI) { … }
std::optional<LocIdx>
InstrRefBasedLDV::findLocationForMemOperand(const MachineInstr &MI) { … }
bool InstrRefBasedLDV::transferDebugValue(const MachineInstr &MI) { … }
std::optional<ValueIDNum> InstrRefBasedLDV::getValueForInstrRef(
unsigned InstNo, unsigned OpNo, MachineInstr &MI,
const FuncValueTable *MLiveOuts, const FuncValueTable *MLiveIns) { … }
bool InstrRefBasedLDV::transferDebugInstrRef(MachineInstr &MI,
const FuncValueTable *MLiveOuts,
const FuncValueTable *MLiveIns) { … }
bool InstrRefBasedLDV::transferDebugPHI(MachineInstr &MI) { … }
void InstrRefBasedLDV::transferRegisterDef(MachineInstr &MI) { … }
void InstrRefBasedLDV::performCopy(Register SrcRegNum, Register DstRegNum) { … }
std::optional<SpillLocationNo>
InstrRefBasedLDV::isSpillInstruction(const MachineInstr &MI,
MachineFunction *MF) { … }
bool InstrRefBasedLDV::isLocationSpill(const MachineInstr &MI,
MachineFunction *MF, unsigned &Reg) { … }
std::optional<SpillLocationNo>
InstrRefBasedLDV::isRestoreInstruction(const MachineInstr &MI,
MachineFunction *MF, unsigned &Reg) { … }
bool InstrRefBasedLDV::transferSpillOrRestoreInst(MachineInstr &MI) { … }
bool InstrRefBasedLDV::transferRegisterCopy(MachineInstr &MI) { … }
void InstrRefBasedLDV::accumulateFragmentMap(MachineInstr &MI) { … }
void InstrRefBasedLDV::process(MachineInstr &MI,
const FuncValueTable *MLiveOuts,
const FuncValueTable *MLiveIns) { … }
void InstrRefBasedLDV::produceMLocTransferFunction(
MachineFunction &MF, SmallVectorImpl<MLocTransferMap> &MLocTransfer,
unsigned MaxNumBlocks) { … }
bool InstrRefBasedLDV::mlocJoin(
MachineBasicBlock &MBB, SmallPtrSet<const MachineBasicBlock *, 16> &Visited,
FuncValueTable &OutLocs, ValueTable &InLocs) { … }
void InstrRefBasedLDV::findStackIndexInterference(
SmallVectorImpl<unsigned> &Slots) { … }
void InstrRefBasedLDV::placeMLocPHIs(
MachineFunction &MF, SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
FuncValueTable &MInLocs, SmallVectorImpl<MLocTransferMap> &MLocTransfer) { … }
void InstrRefBasedLDV::buildMLocValueMap(
MachineFunction &MF, FuncValueTable &MInLocs, FuncValueTable &MOutLocs,
SmallVectorImpl<MLocTransferMap> &MLocTransfer) { … }
void InstrRefBasedLDV::BlockPHIPlacement(
const SmallPtrSetImpl<MachineBasicBlock *> &AllBlocks,
const SmallPtrSetImpl<MachineBasicBlock *> &DefBlocks,
SmallVectorImpl<MachineBasicBlock *> &PHIBlocks) { … }
bool InstrRefBasedLDV::pickVPHILoc(
SmallVectorImpl<DbgOpID> &OutValues, const MachineBasicBlock &MBB,
const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs,
const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders) { … }
std::optional<ValueIDNum> InstrRefBasedLDV::pickOperandPHILoc(
unsigned DbgOpIdx, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts,
FuncValueTable &MOutLocs,
const SmallVectorImpl<const MachineBasicBlock *> &BlockOrders) { … }
bool InstrRefBasedLDV::vlocJoin(
MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
DbgValue &LiveIn) { … }
void InstrRefBasedLDV::getBlocksForScope(
const DILocation *DILoc,
SmallPtrSetImpl<const MachineBasicBlock *> &BlocksToExplore,
const SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks) { … }
void InstrRefBasedLDV::buildVLocValueMap(
const DILocation *DILoc,
const SmallSet<DebugVariableID, 4> &VarsWeCareAbout,
SmallPtrSetImpl<MachineBasicBlock *> &AssignBlocks, LiveInsT &Output,
FuncValueTable &MOutLocs, FuncValueTable &MInLocs,
SmallVectorImpl<VLocTracker> &AllTheVLocs) { … }
void InstrRefBasedLDV::placePHIsForSingleVarDefinition(
const SmallPtrSetImpl<MachineBasicBlock *> &InScopeBlocks,
MachineBasicBlock *AssignMBB, SmallVectorImpl<VLocTracker> &AllTheVLocs,
DebugVariableID VarID, LiveInsT &Output) { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
void InstrRefBasedLDV::dump_mloc_transfer(
const MLocTransferMap &mloc_transfer) const {
for (const auto &P : mloc_transfer) {
std::string foo = MTracker->LocIdxToName(P.first);
std::string bar = MTracker->IDAsString(P.second);
dbgs() << "Loc " << foo << " --> " << bar << "\n";
}
}
#endif
void InstrRefBasedLDV::initialSetup(MachineFunction &MF) { … }
void InstrRefBasedLDV::makeDepthFirstEjectionMap(
SmallVectorImpl<unsigned> &EjectionMap,
const ScopeToDILocT &ScopeToDILocation,
ScopeToAssignBlocksT &ScopeToAssignBlocks) { … }
bool InstrRefBasedLDV::depthFirstVLocAndEmit(
unsigned MaxNumBlocks, const ScopeToDILocT &ScopeToDILocation,
const ScopeToVarsT &ScopeToVars, ScopeToAssignBlocksT &ScopeToAssignBlocks,
LiveInsT &Output, FuncValueTable &MOutLocs, FuncValueTable &MInLocs,
SmallVectorImpl<VLocTracker> &AllTheVLocs, MachineFunction &MF,
const TargetPassConfig &TPC) { … }
bool InstrRefBasedLDV::emitTransfers() { … }
bool InstrRefBasedLDV::ExtendRanges(MachineFunction &MF,
MachineDominatorTree *DomTree,
TargetPassConfig *TPC,
unsigned InputBBLimit,
unsigned InputDbgValLimit) { … }
LDVImpl *llvm::makeInstrRefBasedLiveDebugValues() { … }
namespace {
class LDVSSABlock;
class LDVSSAUpdater;
BlockValueNum;
class LDVSSAPhi { … };
class LDVSSABlockIterator { … };
class LDVSSABlock { … };
class LDVSSAUpdater { … };
LDVSSABlock *LDVSSABlockIterator::operator*() { … }
#ifndef NDEBUG
raw_ostream &operator<<(raw_ostream &out, const LDVSSAPhi &PHI) {
out << "SSALDVPHI " << PHI.PHIValNum;
return out;
}
#endif
}
namespace llvm {
template <> class SSAUpdaterTraits<LDVSSAUpdater> { … };
}
std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIs(
MachineFunction &MF, const FuncValueTable &MLiveOuts,
const FuncValueTable &MLiveIns, MachineInstr &Here, uint64_t InstrNum) { … }
std::optional<ValueIDNum> InstrRefBasedLDV::resolveDbgPHIsImpl(
MachineFunction &MF, const FuncValueTable &MLiveOuts,
const FuncValueTable &MLiveIns, MachineInstr &Here, uint64_t InstrNum) { … }