#include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
#include "LiveDebugValues/LiveDebugValues.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/IntervalMap.h"
#include "llvm/ADT/PostOrderIterator.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/UniqueVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugProgramInstruction.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/PrintPasses.h"
#include "llvm/InitializePasses.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <assert.h>
#include <cstdint>
#include <optional>
#include <queue>
#include <sstream>
#include <unordered_map>
usingnamespacellvm;
#define DEBUG_TYPE …
STATISTIC(NumDefsScanned, "Number of dbg locs that get scanned for removal");
STATISTIC(NumDefsRemoved, "Number of dbg locs removed");
STATISTIC(NumWedgesScanned, "Number of dbg wedges scanned");
STATISTIC(NumWedgesChanged, "Number of dbg wedges changed");
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 cl::opt<bool> EnableMemLocFragFill("mem-loc-frag-fill", cl::init(true),
cl::Hidden);
static cl::opt<bool> PrintResults("print-debug-ata", cl::init(false),
cl::Hidden);
static cl::opt<cl::boolOrDefault>
CoalesceAdjacentFragmentsOpt("debug-ata-coalesce-frags", cl::Hidden);
template <> struct llvm::DenseMapInfo<VariableID> { … };
VarLocInsertPt;
namespace std {
template <> struct hash<VarLocInsertPt> { … };
}
class FunctionVarLocsBuilder { … };
void FunctionVarLocs::print(raw_ostream &OS, const Function &Fn) const { … }
void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) { … }
void FunctionVarLocs::clear() { … }
static std::pair<Value *, DIExpression *>
walkToAllocaAndPrependOffsetDeref(const DataLayout &DL, Value *Start,
DIExpression *Expression) { … }
static std::optional<int64_t>
getDerefOffsetInBytes(const DIExpression *DIExpr) { … }
DebugAggregate;
static DebugAggregate getAggregate(const DbgVariableIntrinsic *DII) { … }
static DebugAggregate getAggregate(const DebugVariable &Var) { … }
static bool shouldCoalesceFragments(Function &F) { … }
namespace {
class MemLocFragmentFill { … };
class AssignmentTrackingLowering { … };
}
ArrayRef<VariableID>
AssignmentTrackingLowering::getContainedFragments(VariableID Var) const { … }
void AssignmentTrackingLowering::touchFragment(VariableID Var) { … }
void AssignmentTrackingLowering::setLocKind(BlockInfo *LiveSet, VariableID Var,
LocKind K) { … }
AssignmentTrackingLowering::LocKind
AssignmentTrackingLowering::getLocKind(BlockInfo *LiveSet, VariableID Var) { … }
void AssignmentTrackingLowering::addMemDef(BlockInfo *LiveSet, VariableID Var,
const Assignment &AV) { … }
void AssignmentTrackingLowering::addDbgDef(BlockInfo *LiveSet, VariableID Var,
const Assignment &AV) { … }
static DIAssignID *getIDFromInst(const Instruction &I) { … }
static DIAssignID *getIDFromMarker(const DbgAssignIntrinsic &DAI) { … }
static DIAssignID *getIDFromMarker(const DbgVariableRecord &DVR) { … }
bool AssignmentTrackingLowering::hasVarWithAssignment(
BlockInfo *LiveSet, BlockInfo::AssignmentKind Kind, VariableID Var,
const Assignment &AV) { … }
#ifndef NDEBUG
const char *locStr(AssignmentTrackingLowering::LocKind Loc) {
using LocKind = AssignmentTrackingLowering::LocKind;
switch (Loc) {
case LocKind::Val:
return "Val";
case LocKind::Mem:
return "Mem";
case LocKind::None:
return "None";
};
llvm_unreachable("unknown LocKind");
}
#endif
VarLocInsertPt getNextNode(const DbgRecord *DVR) { … }
VarLocInsertPt getNextNode(const Instruction *Inst) { … }
VarLocInsertPt getNextNode(VarLocInsertPt InsertPt) { … }
DbgAssignIntrinsic *CastToDbgAssign(DbgVariableIntrinsic *DVI) { … }
DbgVariableRecord *CastToDbgAssign(DbgVariableRecord *DVR) { … }
void AssignmentTrackingLowering::emitDbgValue(
AssignmentTrackingLowering::LocKind Kind,
AssignmentTrackingLowering::AssignRecord Source, VarLocInsertPt After) { … }
template <typename T>
void AssignmentTrackingLowering::emitDbgValue(
AssignmentTrackingLowering::LocKind Kind, const T Source,
VarLocInsertPt After) { … }
void AssignmentTrackingLowering::processNonDbgInstruction(
Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::processUntaggedInstruction(
Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::processTaggedInstruction(
Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::processDbgAssign(AssignRecord Assign,
BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::processDbgValue(
PointerUnion<DbgValueInst *, DbgVariableRecord *> DbgValueRecord,
BlockInfo *LiveSet) { … }
template <typename T> static bool hasZeroSizedFragment(T &DbgValue) { … }
void AssignmentTrackingLowering::processDbgInstruction(
DbgInfoIntrinsic &I, AssignmentTrackingLowering::BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::processDbgVariableRecord(
DbgVariableRecord &DVR, AssignmentTrackingLowering::BlockInfo *LiveSet) { … }
void AssignmentTrackingLowering::resetInsertionPoint(Instruction &After) { … }
void AssignmentTrackingLowering::resetInsertionPoint(DbgVariableRecord &After) { … }
void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) { … }
AssignmentTrackingLowering::LocKind
AssignmentTrackingLowering::joinKind(LocKind A, LocKind B) { … }
AssignmentTrackingLowering::Assignment
AssignmentTrackingLowering::joinAssignment(const Assignment &A,
const Assignment &B) { … }
AssignmentTrackingLowering::BlockInfo
AssignmentTrackingLowering::joinBlockInfo(const BlockInfo &A,
const BlockInfo &B) { … }
bool AssignmentTrackingLowering::join(
const BasicBlock &BB, const SmallPtrSet<BasicBlock *, 16> &Visited) { … }
static bool fullyContains(DIExpression::FragmentInfo A,
DIExpression::FragmentInfo B) { … }
static std::optional<at::AssignmentInfo>
getUntaggedStoreAssignmentInfo(const Instruction &I, const DataLayout &Layout) { … }
DbgDeclareInst *DynCastToDbgDeclare(DbgVariableIntrinsic *DVI) { … }
DbgVariableRecord *DynCastToDbgDeclare(DbgVariableRecord *DVR) { … }
static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares(
Function &Fn, FunctionVarLocsBuilder *FnVarLocs,
const DenseSet<DebugAggregate> &VarsWithStackSlot,
AssignmentTrackingLowering::UntaggedStoreAssignmentMap &UntaggedStoreVars,
unsigned &TrackedVariablesVectorSize) { … }
bool AssignmentTrackingLowering::run(FunctionVarLocsBuilder *FnVarLocsBuilder) { … }
bool AssignmentTrackingLowering::emitPromotedVarLocs(
FunctionVarLocsBuilder *FnVarLocs) { … }
static bool
removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) { … }
static bool
removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) { … }
static bool
removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) { … }
static bool removeRedundantDbgLocs(const BasicBlock *BB,
FunctionVarLocsBuilder &FnVarLocs) { … }
static DenseSet<DebugAggregate> findVarsWithStackSlot(Function &Fn) { … }
static void analyzeFunction(Function &Fn, const DataLayout &Layout,
FunctionVarLocsBuilder *FnVarLocs) { … }
FunctionVarLocs
DebugAssignmentTrackingAnalysis::run(Function &F,
FunctionAnalysisManager &FAM) { … }
AnalysisKey DebugAssignmentTrackingAnalysis::Key;
PreservedAnalyses
DebugAssignmentTrackingPrinterPass::run(Function &F,
FunctionAnalysisManager &FAM) { … }
bool AssignmentTrackingAnalysis::runOnFunction(Function &F) { … }
AssignmentTrackingAnalysis::AssignmentTrackingAnalysis()
: … { … }
char AssignmentTrackingAnalysis::ID = …;
INITIALIZE_PASS(…)