16#include "llvm/IR/IntrinsicsDirectX.h"
20#define DEBUG_TYPE "dx-debug-info"
33 Constant *ZeroOffset = ConstantInt::get(Int64Ty, 0);
49 Function *
F = getDeclarationIfExists(&M, Intrinsic::dbg_value);
57 {FT->getParamType(0), Int64Ty, FT->getParamType(1), FT->getParamType(2)},
63 for (
User *U :
F->users()) {
73 Res.
Modified = M.convertFromNewDbgValues();
87 std::pair<Instruction *, DbgValueInst *>>
96 F.removeFnAttrs(AttrMask);
97 F.removeRetAttrs(AttrMask);
98 for (
unsigned ArgNo = 0; ArgNo !=
F.arg_size(); ++ArgNo)
99 F.removeParamAttrs(ArgNo, AttrMask);
101 bool IsEntryBlock =
true;
102 DbgVariablesSeen.
clear();
106 DbgValueFragments.
clear();
108 I.eraseMetadataIf([](
unsigned KindID,
MDNode *) {
109 return KindID == LLVMContext::MD_DIAssignID;
112 NextNonDebugInst = &
I;
116 DL->eraseFromParent();
133 bool Replace = DV->getIntrinsicID() != Intrinsic::dbg_value;
149 std::pair<Instruction *, DbgValueInst *> &
DbgValue = DbgValues[V];
150 std::pair<Instruction *, DbgValueInst *> &DbgValueFragment =
151 DbgValueFragments[{V, E}];
155 if (DbgValueFragment.first == NextNonDebugInst) {
156 DV->eraseFromParent();
164 if (DbgValueFragment.second &&
165 DbgValueFragment.second ==
DbgValue.second &&
166 DbgValueFragment.second->getValue() == DV->getValue()) {
178 if (
A.isStringAttribute() ||
179 (
A.getKindAsEnum() != Attribute::NoUnwind &&
180 A.getKindAsEnum() != Attribute::Memory))
186 std::next(DV->getIterator())));
189 DV->eraseFromParent();
194 DbgValue = DbgValueFragment = {NextNonDebugInst, NewDV};
203 if (!DV || DbgVariablesSeen.
contains(DV->getVariable()))
206 DV->eraseFromParent();
210 DbgVariablesSeen.
insert(DV->getVariable());
213 IsEntryBlock =
false;
222 [](
Metadata *M) { return isa<DILabel>(M); }),
224 SP->replaceRetainedNodes(
MDTuple::get(M.getContext(), MDs));
243 M.getContext(), Lang,
CU->getFile(),
CU->getProducer(),
244 CU->isOptimized(),
CU->getFlags(),
CU->getRuntimeVersion(),
245 CU->getSplitDebugFilename(),
CU->getEmissionKind(),
246 CU->getEnumTypes(),
CU->getRetainedTypes(),
CU->getGlobalVariables(),
247 CU->getImportedEntities(),
CU->getMacros(),
CU->getDWOId(),
248 CU->getSplitDebugInlining(),
CU->getDebugInfoForProfiling(),
249 CU->getNameTableKind(),
CU->getRangesBaseAddress(),
CU->getSysRoot(),
255 std::vector<std::pair<const DICompileUnit *, const Metadata *>> CUSubprograms;
267 static constexpr auto SupportedDIFlags =
269 static constexpr auto SupportedDISPFlags =
271 if (SP->isDistinct() || SP->getFlags() & ~SupportedDIFlags ||
272 SP->getSPFlags() & ~SupportedDISPFlags) {
274 M.getContext(), SP->getScope(), SP->getName(), SP->getLinkageName(),
275 SP->getFile(), SP->getLine(), SP->getType(), SP->getScopeLine(),
276 SP->getContainingType(), SP->getVirtualIndex(),
277 SP->getThisAdjustment(), SP->getFlags() & SupportedDIFlags,
278 SP->getSPFlags() & SupportedDISPFlags, SP->getUnit(),
279 SP->getTemplateParams(), SP->getDeclaration(), SP->getRetainedNodes(),
280 SP->getThrownTypes(), SP->getAnnotations(), SP->getTargetFuncName(),
281 SP->getKeyInstructionsEnabled());
286 const Metadata *FunctionMD = It->second;
293 CUSubprograms.push_back(
294 {SP->getUnit(),
static_cast<const Metadata *
>(SP)});
298 CUSubprograms.begin(), CUSubprograms.end(), [](
auto &&
A,
auto &&
B) {
299 return std::less<const DICompileUnit *>()(A.first, B.first);
301 for (
auto It = CUSubprograms.begin(), End = CUSubprograms.end(); It != End;) {
308 }
while (++It != End && It->first ==
CU);
309 const auto *SubprogramsMD =
MDTuple::get(M.getContext(), Subprograms);
315 GV.getDebugInfo(GVEs);
317 if (GVE->getExpression()->getNumElements())
323 It->second =
nullptr;
332 const Metadata *Scope = CB->getScope();
343 SR->getName(), SR->getSizeInBits(),
344 SR->getAlignInBits(), dwarf::DW_ATE_unsigned,
345 SR->getNumExtraInhabitants(),
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static void replaceDbgVariableIntr(DbgVariableIntrinsic *DVI, Function *NewF, DXILDebugInfoMap &Res)
static void replaceDbgValue(Module &M, DXILDebugInfoMap &Res)
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
Class recording the (high level) value of a variable.
This class stores enough information to efficiently remove some attributes from an existing AttrBuild...
AttributeMask & addAttribute(Attribute::AttrKind Val)
Add an attribute to the mask.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
LLVM Basic Block Representation.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
void setTailCall(bool IsTc=true)
This is an important base class in LLVM.
A pair of DIGlobalVariable and DIExpression.
Base class for scope-like contexts.
Wrapper structure that holds source language identity metadata that includes language name,...
uint32_t getVersion() const
Returns language version. Only valid for versioned language names.
bool hasVersionedName() const
uint16_t getName() const
Returns a versioned or unversioned language name.
Subprogram description. Uses SubclassData1.
DISPFlags
Debug info subprogram flags.
This represents the llvm.dbg.value instruction.
This is the common base class for debug info intrinsics for variables.
Utility to find all debug info in a module.
LLVM_ABI void processModule(const Module &M)
Process entire module and collect debug info anchors.
LLVM_ABI void reset()
Clear all lists.
iterator_range< global_variable_expression_iterator > global_variables() const
iterator_range< subprogram_iterator > subprograms() const
iterator_range< type_iterator > types() const
iterator_range< scope_iterator > scopes() const
iterator_range< compile_unit_iterator > compile_units() const
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
void removeFnAttrs(const AttributeMask &Attrs)
AttributeList getAttributes() const
Return the attribute list for this Function.
void copyAttributesFrom(const Function *Src)
copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
Intrinsic::ID getIntrinsicID() const
Return the intrinsic ID of this intrinsic.
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
A Module instance is used to store all the information related to an LLVM module.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
Value * getOperand(unsigned i) const
LLVM Value Representation.
LLVMContext & getContext() const
All values hold a context through their type.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool Modified
Whether the run modified the IR of the module the map was produced for.
InstMap InstReplace
Completely replace one instruction with another in ValueEnumerator.
MDMap MDExtra
Enumerate extra metadata when Key is encountered in ValueEnumerator.
FuncMap FuncReplace
Completely replace one function with another in ValueEnumerator.
MDMap MDReplace
Completely replace one metadata with another in ValueEnumerator.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
std::optional< SourceLanguage > toDW_LANG(SourceLanguageName name, uint32_t version)
Convert a DWARF 6 pair of language name and version to a DWARF 5 DW_LANG.
DXILDebugInfoMap run(Module &M)
const AttributeMask & getNonDXILAttributeMask()
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto cast_or_null(const Y &Val)
auto reverse(ContainerTy &&C)
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.