#include "llvm/CodeGen/LiveDebugVariables.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/LiveInterval.h"
#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SlotIndexes.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/CodeGen/TargetOpcodes.h"
#include "llvm/CodeGen/TargetRegisterInfo.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/VirtRegMap.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Function.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <map>
#include <memory>
#include <optional>
#include <utility>
usingnamespacellvm;
#define DEBUG_TYPE …
static cl::opt<bool>
EnableLDV("live-debug-variables", cl::init(true),
cl::desc("Enable the live debug variables pass"), cl::Hidden);
STATISTIC(NumInsertedDebugValues, "Number of DBG_VALUEs inserted");
STATISTIC(NumInsertedDebugLabels, "Number of DBG_LABELs inserted");
char LiveDebugVariables::ID = …;
INITIALIZE_PASS_BEGIN(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTreeWrapperPass)
INITIALIZE_PASS_DEPENDENCY(LiveIntervalsWrapperPass)
INITIALIZE_PASS_END(LiveDebugVariables, DEBUG_TYPE,
"Debug Variable Analysis", false, false)
void LiveDebugVariables::getAnalysisUsage(AnalysisUsage &AU) const { … }
LiveDebugVariables::LiveDebugVariables() : … { … }
enum : unsigned { … };
namespace {
class DbgVariableValue { … };
}
LocMap;
SpillOffsetMap;
BlockSkipInstsMap;
namespace {
class LDVImpl;
class UserValue { … };
class UserLabel { … };
class LDVImpl { … };
}
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
static void printDebugLoc(const DebugLoc &DL, raw_ostream &CommentOS,
const LLVMContext &Ctx) {
if (!DL)
return;
auto *Scope = cast<DIScope>(DL.getScope());
CommentOS << Scope->getFilename();
CommentOS << ':' << DL.getLine();
if (DL.getCol() != 0)
CommentOS << ':' << DL.getCol();
DebugLoc InlinedAtDL = DL.getInlinedAt();
if (!InlinedAtDL)
return;
CommentOS << " @[ ";
printDebugLoc(InlinedAtDL, CommentOS, Ctx);
CommentOS << " ]";
}
static void printExtendedName(raw_ostream &OS, const DINode *Node,
const DILocation *DL) {
const LLVMContext &Ctx = Node->getContext();
StringRef Res;
unsigned Line = 0;
if (const auto *V = dyn_cast<const DILocalVariable>(Node)) {
Res = V->getName();
Line = V->getLine();
} else if (const auto *L = dyn_cast<const DILabel>(Node)) {
Res = L->getName();
Line = L->getLine();
}
if (!Res.empty())
OS << Res << "," << Line;
auto *InlinedAt = DL ? DL->getInlinedAt() : nullptr;
if (InlinedAt) {
if (DebugLoc InlinedAtDL = InlinedAt) {
OS << " @[";
printDebugLoc(InlinedAtDL, OS, Ctx);
OS << "]";
}
}
}
void UserValue::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
OS << "!\"";
printExtendedName(OS, Variable, dl);
OS << "\"\t";
for (LocMap::const_iterator I = locInts.begin(); I.valid(); ++I) {
OS << " [" << I.start() << ';' << I.stop() << "):";
if (I.value().isUndef())
OS << " undef";
else {
I.value().printLocNos(OS);
if (I.value().getWasIndirect())
OS << " ind";
else if (I.value().getWasList())
OS << " list";
}
}
for (unsigned i = 0, e = locations.size(); i != e; ++i) {
OS << " Loc" << i << '=';
locations[i].print(OS, TRI);
}
OS << '\n';
}
void UserLabel::print(raw_ostream &OS, const TargetRegisterInfo *TRI) {
OS << "!\"";
printExtendedName(OS, Label, dl);
OS << "\"\t";
OS << loc;
OS << '\n';
}
void LDVImpl::print(raw_ostream &OS) {
OS << "********** DEBUG VARIABLES **********\n";
for (auto &userValue : userValues)
userValue->print(OS, TRI);
OS << "********** DEBUG LABELS **********\n";
for (auto &userLabel : userLabels)
userLabel->print(OS, TRI);
}
#endif
void UserValue::mapVirtRegs(LDVImpl *LDV) { … }
UserValue *
LDVImpl::getUserValue(const DILocalVariable *Var,
std::optional<DIExpression::FragmentInfo> Fragment,
const DebugLoc &DL) { … }
void LDVImpl::mapVirtReg(Register VirtReg, UserValue *EC) { … }
UserValue *LDVImpl::lookupVirtReg(Register VirtReg) { … }
bool LDVImpl::handleDebugValue(MachineInstr &MI, SlotIndex Idx) { … }
MachineBasicBlock::iterator LDVImpl::handleDebugInstr(MachineInstr &MI,
SlotIndex Idx) { … }
bool LDVImpl::handleDebugLabel(MachineInstr &MI, SlotIndex Idx) { … }
bool LDVImpl::collectDebugValues(MachineFunction &mf, bool InstrRef) { … }
void UserValue::extendDef(
SlotIndex Idx, DbgVariableValue DbgValue,
SmallDenseMap<unsigned, std::pair<LiveRange *, const VNInfo *>>
&LiveIntervalInfo,
std::optional<std::pair<SlotIndex, SmallVector<unsigned>>> &Kills,
LiveIntervals &LIS) { … }
void UserValue::addDefsFromCopies(
DbgVariableValue DbgValue,
SmallVectorImpl<std::pair<unsigned, LiveInterval *>> &LocIntervals,
SlotIndex KilledAt,
SmallVectorImpl<std::pair<SlotIndex, DbgVariableValue>> &NewDefs,
MachineRegisterInfo &MRI, LiveIntervals &LIS) { … }
void UserValue::computeIntervals(MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI,
LiveIntervals &LIS, LexicalScopes &LS) { … }
void LDVImpl::computeIntervals() { … }
bool LDVImpl::runOnMachineFunction(MachineFunction &mf, bool InstrRef) { … }
static void removeDebugInstrs(MachineFunction &mf) { … }
bool LiveDebugVariables::runOnMachineFunction(MachineFunction &mf) { … }
void LiveDebugVariables::releaseMemory() { … }
LiveDebugVariables::~LiveDebugVariables() { … }
bool
UserValue::splitLocation(unsigned OldLocNo, ArrayRef<Register> NewRegs,
LiveIntervals& LIS) { … }
bool
UserValue::splitRegister(Register OldReg, ArrayRef<Register> NewRegs,
LiveIntervals &LIS) { … }
void LDVImpl::splitPHIRegister(Register OldReg, ArrayRef<Register> NewRegs) { … }
void LDVImpl::splitRegister(Register OldReg, ArrayRef<Register> NewRegs) { … }
void LiveDebugVariables::
splitRegister(Register OldReg, ArrayRef<Register> NewRegs, LiveIntervals &LIS) { … }
void UserValue::rewriteLocations(VirtRegMap &VRM, const MachineFunction &MF,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
SpillOffsetMap &SpillOffsets) { … }
static MachineBasicBlock::iterator
findInsertLocation(MachineBasicBlock *MBB, SlotIndex Idx, LiveIntervals &LIS,
BlockSkipInstsMap &BBSkipInstsMap) { … }
static MachineBasicBlock::iterator
findNextInsertLocation(MachineBasicBlock *MBB, MachineBasicBlock::iterator I,
SlotIndex StopIdx, ArrayRef<MachineOperand> LocMOs,
LiveIntervals &LIS, const TargetRegisterInfo &TRI) { … }
void UserValue::insertDebugValue(MachineBasicBlock *MBB, SlotIndex StartIdx,
SlotIndex StopIdx, DbgVariableValue DbgValue,
ArrayRef<bool> LocSpills,
ArrayRef<unsigned> SpillOffsets,
LiveIntervals &LIS, const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
BlockSkipInstsMap &BBSkipInstsMap) { … }
void UserLabel::insertDebugLabel(MachineBasicBlock *MBB, SlotIndex Idx,
LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap) { … }
void UserValue::emitDebugValues(VirtRegMap *VRM, LiveIntervals &LIS,
const TargetInstrInfo &TII,
const TargetRegisterInfo &TRI,
const SpillOffsetMap &SpillOffsets,
BlockSkipInstsMap &BBSkipInstsMap) { … }
void UserLabel::emitDebugLabel(LiveIntervals &LIS, const TargetInstrInfo &TII,
BlockSkipInstsMap &BBSkipInstsMap) { … }
void LDVImpl::emitDebugValues(VirtRegMap *VRM) { … }
void LiveDebugVariables::emitDebugValues(VirtRegMap *VRM) { … }
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LiveDebugVariables::dump() const {
if (pImpl)
static_cast<LDVImpl*>(pImpl)->print(dbgs());
}
#endif