| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // DxilDiaSymbolsManager.cpp //
- // Copyright (C) Microsoft Corporation. All rights reserved. //
- // This file is distributed under the University of Illinois Open Source //
- // License. See LICENSE.TXT for details. //
- // //
- // DIA API implementation for DXIL modules. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "DxilDiaSymbolManager.h"
- #include <cctype>
- #include <functional>
- #include <type_traits>
- #include <comdef.h>
- #include "dxc/DxilPIXPasses/DxilPIXVirtualRegisters.h"
- #include "dxc/Support/Unicode.h"
- #include "llvm/ADT/DenseMap.h"
- #include "llvm/ADT/STLExtras.h"
- #include "llvm/IR/Constants.h"
- #include "llvm/IR/DebugInfo.h"
- #include "llvm/IR/DebugInfoMetadata.h"
- #include "llvm/IR/Function.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/Intrinsics.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Support/raw_ostream.h"
- #include "DxilDiaSession.h"
- #include "DxilDiaTableSymbols.h"
- static constexpr std::uint32_t kNullSymbolID = 0;
- namespace dxil_dia {
- namespace hlsl_symbols {
- // HLSL Symbol Hierarchy
- // ---- ------ ---------
- //
- // +---------------+
- // | Program (EXE) | Global Scope
- // +------+--------+
- // |
- // +--------^-----------+
- // | Compiland (Shader) | Compilation Unit
- // +--------+-----------+
- // |
- // +------------+------------+--------+-------+------------+--------------+
- // | | | | | | |
- // +----^----+ +---^---+ +----^---+ | +---^---+ +----^----+ +-----^-----+
- // | Details | | Flags | | Target | | | Entry | | Defines | | Arguments | Synthetic Symbols
- // +---------+ +-------+ +--------+ | +-------+ +---------+ +-----------+
- // |
- // |
- // +---------------+------------+----+-----+-------------+-----------+
- // | | | | | |
- // +-----^-----+ +-----^-----+ +--^--+ +---^--+ +---^--+ +--^--+
- // | Function0 | | Function1 | | ... | | UDT0 | | UDT1 | | ... | Source Symbols
- // +-----+-----+ +-----+-----+ +-----+ +---+--+ +---+--+ +-----+
- // | | | |
- // +----^----+ +----^----+ +----^----+ +----^----+
- // | Locals0 | | Locals1 | | Fields0 | | Fields1 |
- // +---------+ +---------+ +---------+ +---------+
- static const std::string & DxilEntryName(Session *pSession);
- template <typename S, typename... C, typename = typename std::enable_if<!std::is_same<Symbol, S>::value>::type>
- HRESULT AllocAndInit(
- IMalloc *pMalloc,
- Session *pSession,
- DWORD dwIndex,
- DWORD dwSymTag,
- S **ppSymbol,
- C... ctorArgs) {
- *ppSymbol = S::Alloc(pMalloc, ctorArgs...);
- if (*ppSymbol == nullptr) {
- return E_OUTOFMEMORY;
- }
- (*ppSymbol)->AddRef();
- (*ppSymbol)->Init(pSession, dwIndex, dwSymTag);
- return S_OK;
- }
- template <typename T, typename R>
- T *dyn_cast_to_ditype(R ref) {
- return llvm::dyn_cast<T>((llvm::Metadata *) ref);
- }
- template <typename T, typename R>
- T *dyn_cast_to_ditype_or_null(R ref) {
- return llvm::dyn_cast_or_null<T>((llvm::Metadata *) ref);
- }
- template <typename N>
- struct DISymbol : public Symbol {
- DISymbol(IMalloc *M, N Node) : Symbol(M), m_pNode(Node) {}
- N m_pNode;
- };
- template <typename N>
- struct TypedSymbol : public DISymbol<N> {
- TypedSymbol(IMalloc *M, N Node, DWORD dwTypeID, llvm::DIType *Type) : DISymbol(M, Node), m_dwTypeID(dwTypeID), m_pType(Type) {}
- STDMETHODIMP get_type(
- /* [retval][out] */ IDiaSymbol **ppRetVal) override {
- if (ppRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *ppRetVal = false;
- if (m_pType == nullptr) {
- return S_FALSE;
- }
- Symbol *ret;
- IFR(m_pSession->SymMgr().GetSymbolByID(m_dwTypeID, &ret));
- *ppRetVal = ret;
- return S_OK;
- }
- const DWORD m_dwTypeID;
- llvm::DIType *m_pType;
- };
- struct GlobalScopeSymbol : public Symbol {
- DXC_MICROCOM_TM_ALLOC(GlobalScopeSymbol)
- explicit GlobalScopeSymbol(IMalloc *M) : Symbol(M) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class GlobalScope final : public SymbolManager::SymbolFactory {
- public:
- GlobalScope(DWORD ID, DWORD ParentID)
- : SymbolManager::SymbolFactory(ID, ParentID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- return hlsl_symbols::GlobalScopeSymbol::Create(pMalloc, pSession, ppRet);
- }
- };
- } // namespace symbol_factory
- struct CompilandSymbol : public DISymbol<llvm::DICompileUnit *> {
- DXC_MICROCOM_TM_ALLOC(CompilandSymbol)
- explicit CompilandSymbol(IMalloc *M, llvm::DICompileUnit *CU) : DISymbol<llvm::DICompileUnit *>(M, CU) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, llvm::DICompileUnit *CU, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class Compiland final : public SymbolManager::SymbolFactory {
- public:
- Compiland(DWORD ID, DWORD ParentID, llvm::DICompileUnit *CU)
- : SymbolManager::SymbolFactory(ID, ParentID), m_CU(CU) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(hlsl_symbols::CompilandSymbol::Create(pMalloc, pSession, m_CU, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- private:
- llvm::DICompileUnit *m_CU;
- };
- } // namespace symbol_factory
- struct CompilandDetailsSymbol : public Symbol {
- DXC_MICROCOM_TM_ALLOC(CompilandDetailsSymbol)
- explicit CompilandDetailsSymbol(IMalloc *M) : Symbol(M) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- #pragma region IDiaSymbol implementation
- // DEFINE_SIMPLE_GETTER is used to generate the boilerplate needed for the
- // property getters needed by this symbol. name is the property name (as
- // defined in IDiaSymbol::get_<name>. There should be a static (non-const OK)
- // function defined in this class as
- //
- // <RetTy> <name>(CompilandDetailsSymbol * <this>)
- //
- // <RetTy> **must** match the property type in IDiaSymbol::get_<name>'s
- // parameter; <this> is literally the this pointer. The function needs to
- // be static (thus requiring the explicit <this> parameter) so that
- // DEFINE_SIMPLE_GETTER can use decltype(name(nullptr)) in order to
- // define the property parameter type.
- #define DEFINE_SIMPLE_GETTER(name) \
- STDMETHODIMP get_ ## name(decltype(name(nullptr)) *pValue) override { \
- if (pValue == nullptr) { \
- return E_INVALIDARG; \
- } \
- *pValue = name(this); \
- return S_OK; \
- }
- static constexpr DWORD platform(CompilandDetailsSymbol *) { return 256; }
- static constexpr DWORD language(CompilandDetailsSymbol *) { return 16; }
- static constexpr BOOL hasDebugInfo(CompilandDetailsSymbol *) { return true; }
- static BSTR compilerName(CompilandDetailsSymbol *) {
- CComBSTR retval;
- retval.Append("dxcompiler");
- return retval.Detach();
- }
- static DWORD frontEndMajor(CompilandDetailsSymbol *self) {
- return self->m_pSession->DxilModuleRef().GetShaderModel()->GetMajor();
- }
- static DWORD frontEndMinor(CompilandDetailsSymbol *self) {
- return self->m_pSession->DxilModuleRef().GetShaderModel()->GetMinor();
- }
- DEFINE_SIMPLE_GETTER(platform);
- DEFINE_SIMPLE_GETTER(language);
- DEFINE_SIMPLE_GETTER(frontEndMajor);
- DEFINE_SIMPLE_GETTER(frontEndMinor);
- DEFINE_SIMPLE_GETTER(hasDebugInfo);
- DEFINE_SIMPLE_GETTER(compilerName);
- #undef DEFINE_SIMPLE_GETTER
- #pragma endregion
- };
- namespace symbol_factory {
- class CompilandDetails final : public SymbolManager::SymbolFactory {
- public:
- CompilandDetails(DWORD ID, DWORD ParentID)
- : SymbolManager::SymbolFactory(ID, ParentID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(hlsl_symbols::CompilandDetailsSymbol::Create(pMalloc, pSession, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- };
- } // namespace symbol_factory
- struct CompilandEnvSymbol : public Symbol {
- DXC_MICROCOM_TM_ALLOC(CompilandEnvSymbol)
- explicit CompilandEnvSymbol(IMalloc *M) : Symbol(M) {}
- static HRESULT CreateFlags(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- static HRESULT CreateTarget(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- static HRESULT CreateEntry(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- static HRESULT CreateDefines(IMalloc *pMalloc, Session *pSession, Symbol **pSym);
- static HRESULT CreateArguments(IMalloc *pMalloc, Session *pSession, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- using CompilandEnvCreateFn = HRESULT(IMalloc *, Session *, Symbol **);
- template<CompilandEnvCreateFn C>
- class CompilandEnv final : public SymbolManager::SymbolFactory {
- public:
- CompilandEnv(DWORD ID, DWORD ParentID)
- : SymbolManager::SymbolFactory(ID, ParentID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(C(pMalloc, pSession, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- };
- } // namespace symbol_factory
- struct FunctionSymbol : public TypedSymbol<llvm::DISubprogram *> {
- DXC_MICROCOM_TM_ALLOC(FunctionSymbol)
- FunctionSymbol(IMalloc *M, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DISubprogram *>(M, Node, dwTypeID, Type) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class Function final : public SymbolManager::SymbolFactory {
- public:
- Function(DWORD ID, DWORD ParentID, llvm::DISubprogram *Node, DWORD TypeID)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_TypeID(TypeID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(FunctionSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Node->getType(), ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
- return S_OK;
- }
- private:
- llvm::DISubprogram *m_Node;
- DWORD m_TypeID;
- };
- } // namespace symbol_factory
- struct FunctionBlockSymbol : public Symbol {
- DXC_MICROCOM_TM_ALLOC(FunctionBlockSymbol)
- explicit FunctionBlockSymbol(IMalloc *M) : Symbol(M) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class FunctionBlock final : public SymbolManager::SymbolFactory {
- public:
- FunctionBlock(DWORD ID, DWORD ParentID)
- : SymbolManager::SymbolFactory(ID, ParentID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(FunctionBlockSymbol::Create(pMalloc, pSession, m_ID, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- };
- } // namespace symbol_factory
- struct TypeSymbol : public DISymbol<llvm::DIType *> {
- using LazySymbolName = std::function<HRESULT(Session *, std::string *)>;
- DXC_MICROCOM_TM_ALLOC(TypeSymbol)
- TypeSymbol(IMalloc *M, llvm::DIType *Node, LazySymbolName LazySymbolName) : DISymbol<llvm::DIType *>(M, Node), m_lazySymbolName(LazySymbolName) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, DWORD st, llvm::DIType *Node, LazySymbolName LazySymbolName, Symbol **ppSym);
- STDMETHODIMP get_name(
- /* [retval][out] */ BSTR *pRetVal) override;
- STDMETHODIMP get_baseType(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_length(
- /* [retval][out] */ ULONGLONG *pRetVal) override;
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- LazySymbolName m_lazySymbolName;
- };
- namespace symbol_factory {
- class Type final : public SymbolManager::SymbolFactory {
- public:
- Type(DWORD ID, DWORD ParentID, DWORD st, llvm::DIType *Node, TypeSymbol::LazySymbolName LazySymbolName)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_st(st), m_Node(Node), m_LazySymbolName(LazySymbolName) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(TypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_st, m_Node, m_LazySymbolName, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- private:
- DWORD m_st;
- llvm::DIType *m_Node;
- TypeSymbol::LazySymbolName m_LazySymbolName;
- };
- } // namespace symbol_factory
- struct TypedefTypeSymbol : public TypeSymbol {
- DXC_MICROCOM_TM_ALLOC(TypedefTypeSymbol)
- TypedefTypeSymbol(IMalloc *M, llvm::DIType *Node, DWORD dwBaseTypeID) : TypeSymbol(M, Node, nullptr), m_dwBaseTypeID(dwBaseTypeID) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwBaseTypeID, Symbol **ppSym);
- STDMETHODIMP get_type(
- /* [retval][out] */ IDiaSymbol **ppRetVal) override;
- const DWORD m_dwBaseTypeID;
- };
- namespace symbol_factory {
- class TypedefType final : public SymbolManager::SymbolFactory {
- public:
- TypedefType(DWORD ID, DWORD ParentID, llvm::DIType *Node, DWORD BaseTypeID)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_BaseTypeID(BaseTypeID) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(TypedefTypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_BaseTypeID, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
- return S_OK;
- }
- private:
- llvm::DIType *m_Node;
- DWORD m_BaseTypeID;
- };
- } // namespace symbol_factory
- struct VectorTypeSymbol : public TypeSymbol {
- DXC_MICROCOM_TM_ALLOC(VectorTypeSymbol)
- VectorTypeSymbol(IMalloc *M, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts) : TypeSymbol(M, Node, nullptr), m_ElemTyID(dwElemTyID), m_NumElts(NumElts) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts, Symbol **ppSym);
- STDMETHODIMP get_count(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_type(
- /* [retval][out] */ IDiaSymbol **ppRetVal) override;
- std::uint32_t m_ElemTyID;
- std::uint32_t m_NumElts;
- };
- namespace symbol_factory {
- class VectorType final : public SymbolManager::SymbolFactory {
- public:
- VectorType(DWORD ID, DWORD ParentID, llvm::DIType *Node, DWORD ElemTyID, std::uint32_t NumElts)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_ElemTyID(ElemTyID), m_NumElts(NumElts) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(VectorTypeSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_ElemTyID, m_NumElts, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
- return S_OK;
- }
- private:
- llvm::DIType *m_Node;
- DWORD m_ElemTyID;
- std::uint32_t m_NumElts;
- };
- } // namespace symbol_factory
- struct UDTSymbol : public TypeSymbol {
- DXC_MICROCOM_TM_ALLOC(UDTSymbol)
- UDTSymbol(IMalloc *M, llvm::DICompositeType *Node, LazySymbolName LazyName) : TypeSymbol(M, Node, LazyName) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DICompositeType *Node, LazySymbolName LazySymbolName, Symbol **ppSym);
- };
- namespace symbol_factory {
- class UDT final : public SymbolManager::SymbolFactory {
- public:
- UDT(DWORD ID, DWORD ParentID, llvm::DICompositeType *Node, TypeSymbol::LazySymbolName LazySymbolName)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_LazySymbolName(LazySymbolName) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(UDTSymbol::Create(pMalloc, pSession, m_ParentID, m_ID, m_Node, m_LazySymbolName, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- return S_OK;
- }
- private:
- llvm::DICompositeType *m_Node;
- TypeSymbol::LazySymbolName m_LazySymbolName;
- };
- } // namespace symbol_factory
- struct GlobalVariableSymbol : public TypedSymbol<llvm::DIGlobalVariable *> {
- DXC_MICROCOM_TM_ALLOC(GlobalVariableSymbol)
- GlobalVariableSymbol(IMalloc *M, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DIGlobalVariable *>(M, GV, dwTypeID, Type) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class GlobalVariable final : public SymbolManager::SymbolFactory {
- public:
- GlobalVariable(DWORD ID, DWORD ParentID, llvm::DIGlobalVariable *GV, DWORD TypeID, llvm::DIType *Type)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_GV(GV), m_TypeID(TypeID), m_Type(Type) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(GlobalVariableSymbol::Create(pMalloc, pSession, m_ID, m_GV, m_TypeID, m_Type, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_GV->getName().str().c_str(), CP_UTF8));
- (*ppRet)->SetIsHLSLData(true);
- return S_OK;
- }
- private:
- llvm::DIGlobalVariable *m_GV;
- DWORD m_TypeID;
- llvm::DIType *m_Type;
- };
- } // namespace symbol_factory
- struct LocalVariableSymbol : public TypedSymbol<llvm::DIVariable *> {
- DXC_MICROCOM_TM_ALLOC(LocalVariableSymbol)
- LocalVariableSymbol(IMalloc *M, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD dwDxilRegNum) : TypedSymbol<llvm::DIVariable *>(M, Node, dwTypeID, Type), m_dwOffsetInUDT(dwOffsetInUDT), m_dwDxilRegNum(dwDxilRegNum) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD m_dwDxilRegNum, Symbol **ppSym);
- STDMETHODIMP get_locationType(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_isAggregated(
- /* [retval][out] */ BOOL *pRetVal) override;
- STDMETHODIMP get_registerType(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_offsetInUdt(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_sizeInUdt(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_numberOfRegisterIndices(
- /* [retval][out] */ DWORD *pRetVal) override;
- STDMETHODIMP get_numericProperties(
- /* [in] */ DWORD cnt,
- /* [out] */ DWORD *pcnt,
- /* [size_is][out] */ DWORD *pProperties) override;
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- const DWORD m_dwOffsetInUDT;
- const DWORD m_dwDxilRegNum;
- };
- namespace symbol_factory {
- class LocalVarInfo {
- public:
- LocalVarInfo() = default;
- LocalVarInfo(const LocalVarInfo &) = delete;
- LocalVarInfo(LocalVarInfo &&) = default;
- DWORD GetVarID() const { return m_dwVarID; }
- DWORD GetOffsetInUDT() const { return m_dwOffsetInUDT; }
- DWORD GetDxilRegister() const { return m_dwDxilRegister; }
- void SetVarID(DWORD dwVarID) { m_dwVarID = dwVarID; }
- void SetOffsetInUDT(DWORD dwOffsetInUDT) { m_dwOffsetInUDT = dwOffsetInUDT; }
- void SetDxilRegister(DWORD dwDxilReg) { m_dwDxilRegister = dwDxilReg; }
- private:
- DWORD m_dwVarID = 0;
- DWORD m_dwOffsetInUDT = 0;
- DWORD m_dwDxilRegister = 0;
- };
- class LocalVariable final : public SymbolManager::SymbolFactory {
- public:
- LocalVariable(DWORD ID, DWORD ParentID, llvm::DIVariable *Node, DWORD TypeID, llvm::DIType *Type, std::shared_ptr<LocalVarInfo> VI)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_TypeID(TypeID), m_Type(Type), m_VI(VI) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(LocalVariableSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Type, m_VI->GetOffsetInUDT(), m_VI->GetDxilRegister(), ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
- (*ppRet)->SetDataKind(m_Node->getTag() == llvm::dwarf::DW_TAG_arg_variable ? DataIsParam : DataIsLocal);
- return S_OK;
- }
- private:
- llvm::DIVariable *m_Node;
- DWORD m_TypeID;
- llvm::DIType *m_Type;
- std::shared_ptr<LocalVarInfo> m_VI;
- };
- } // namespace symbol_factory
- struct UDTFieldSymbol : public TypedSymbol<llvm::DIDerivedType *> {
- DXC_MICROCOM_TM_ALLOC(UDTFieldSymbol)
- UDTFieldSymbol(IMalloc *M, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type) : TypedSymbol<llvm::DIDerivedType *>(M, Node, dwTypeID, Type) {}
- static HRESULT Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym);
- STDMETHODIMP get_offset(
- /* [retval][out] */ LONG *pRetVal) override;
- HRESULT GetChildren(std::vector<CComPtr<Symbol>> *children) override;
- };
- namespace symbol_factory {
- class UDTField final : public SymbolManager::SymbolFactory {
- public:
- UDTField(DWORD ID, DWORD ParentID, llvm::DIDerivedType *Node, DWORD TypeID, llvm::DIType *Type)
- : SymbolManager::SymbolFactory(ID, ParentID),
- m_Node(Node), m_TypeID(TypeID), m_Type(Type) {}
- virtual HRESULT Create(Session *pSession, Symbol **ppRet) override {
- IMalloc *pMalloc = pSession->GetMallocNoRef();
- IFR(UDTFieldSymbol::Create(pMalloc, pSession, m_ID, m_Node, m_TypeID, m_Type, ppRet));
- (*ppRet)->SetLexicalParent(m_ParentID);
- (*ppRet)->SetName(CA2W(m_Node->getName().str().c_str(), CP_UTF8));
- (*ppRet)->SetDataKind(m_Node->isStaticMember() ? DataIsStaticLocal : DataIsMember);
- return S_OK;
- }
- private:
- llvm::DIDerivedType *m_Node;
- DWORD m_TypeID;
- llvm::DIType *m_Type;
- };
- } // namespace symbol_factory
- class SymbolManagerInit {
- public:
- using SymbolCtor = std::function<HRESULT(Session *pSession, DWORD ID, Symbol **ppSym)>;
- using LazySymbolName = TypeSymbol::LazySymbolName;
- class TypeInfo {
- public:
- TypeInfo() = delete;
- TypeInfo(const TypeInfo &) = delete;
- TypeInfo(TypeInfo &&) = default;
- explicit TypeInfo(DWORD dwTypeID) : m_dwTypeID(dwTypeID) {}
- DWORD GetTypeID() const { return m_dwTypeID; }
- DWORD GetCurrentSizeInBytes() const { return m_dwCurrentSizeInBytes; }
- const std::vector<llvm::DIType *> &GetLayout() const { return m_Layout; }
- void Embed(const TypeInfo &TI);
- void AddBasicType(llvm::DIBasicType *BT);
- private:
- DWORD m_dwTypeID;
- std::vector<llvm::DIType *> m_Layout;
- DWORD m_dwCurrentSizeInBytes = 0;
- };
- using TypeToInfoMap = llvm::DenseMap<llvm::DIType *, std::unique_ptr<TypeInfo> >;
- // Because of the way the VarToID map is constructed, the
- // vector<LocalVarInfo> may need to grow. The Symbol Constructor for local
- // variable captures the LocalVarInfo for the local variable it creates, and
- // it needs access to the information on this map (thus a by-value capture is
- // not enough). We heap-allocate the VarInfos, and the local variables symbol
- // constructors capture the pointer - meaning everything should be fine
- // even if the vector is moved around.
- using LocalVarToIDMap = llvm::DenseMap<
- llvm::DILocalVariable *,
- std::vector<std::shared_ptr<symbol_factory::LocalVarInfo>>>;
- using UDTFieldToIDMap = llvm::DenseMap<llvm::DIDerivedType *, DWORD>;
- SymbolManagerInit(
- Session *pSession,
- std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> *pSymCtors,
- SymbolManager::ScopeToIDMap *pScopeToSym,
- SymbolManager::IDToLiveRangeMap *pSymToLR);
- template <typename Factory, typename... Args>
- HRESULT AddSymbol(DWORD dwParentID, DWORD *pNewSymID, Args&&... args) {
- if (dwParentID > m_SymCtors.size()) {
- return E_FAIL;
- }
- const DWORD dwNewSymID = m_SymCtors.size() + 1;
- m_SymCtors.emplace_back(std::unique_ptr<Factory>(new Factory(dwNewSymID, dwParentID, std::forward<Args>(args)...)));
- *pNewSymID = dwNewSymID;
- IFR(AddParent(dwParentID));
- return S_OK;
- }
- HRESULT CreateFunctionsForAllCUs();
- HRESULT CreateGlobalVariablesForAllCUs();
- HRESULT CreateLocalVariables();
- HRESULT CreateLiveRanges();
- HRESULT IsDbgDeclareCall(llvm::Module *M, const llvm::Instruction *I,
- DWORD *pReg, DWORD *pRegSize,
- llvm::DILocalVariable **LV, uint64_t *pStartOffset,
- uint64_t *pEndOffset,
- dxil_dia::Session::RVA *pLowestUserRVA,
- dxil_dia::Session::RVA *pHighestUserRVA);
- HRESULT GetDxilAllocaRegister(llvm::Instruction *I, DWORD *pRegNum, DWORD *pRegSize);
- HRESULT PopulateParentToChildrenIDMap(SymbolManager::ParentToChildrenMap *pParentToChildren);
- private:
- HRESULT GetTypeInfo(llvm::DIType *T, TypeInfo **TI);
- template<typename Factory, typename... Args>
- HRESULT AddType(DWORD dwParentID, llvm::DIType *T, DWORD *pNewSymID, Args&&... args) {
- IFR(AddSymbol<Factory>(dwParentID, pNewSymID, std::forward<Args>(args)...));
- if (!m_TypeToInfo.insert(std::make_pair(T, llvm::make_unique<TypeInfo>(*pNewSymID))).second) {
- return E_FAIL;
- }
- return S_OK;
- }
- HRESULT AddParent(DWORD dwParentIndex);
- HRESULT CreateFunctionBlockForLocalScope(llvm::DILocalScope *LS, DWORD *pNewSymID);
- HRESULT CreateFunctionBlockForInstruction(llvm::Instruction *I);
- HRESULT CreateFunctionBlocksForFunction(llvm::Function *F);
- HRESULT CreateFunctionsForCU(llvm::DICompileUnit *CU);
- HRESULT CreateGlobalVariablesForCU(llvm::DICompileUnit *CU);
- HRESULT GetScopeID(llvm::DIScope *S, DWORD *pScopeID);
- HRESULT CreateType(llvm::DIType *T, DWORD *pNewTypeID);
- HRESULT CreateSubroutineType(DWORD dwParentID, llvm::DISubroutineType *ST, DWORD *pNewTypeID);
- HRESULT CreateBasicType(DWORD dwParentID, llvm::DIBasicType *VT, DWORD *pNewTypeID);
- HRESULT CreateCompositeType(DWORD dwParentID, llvm::DICompositeType *CT, DWORD *pNewTypeID);
- HRESULT CreateHLSLType(llvm::DICompositeType *T, DWORD *pNewTypeID);
- HRESULT IsHLSLVectorType(llvm::DICompositeType *T, DWORD *pEltTyID, std::uint32_t *pElemCnt);
- HRESULT CreateHLSLVectorType(llvm::DICompositeType *T, DWORD pEltTyID, std::uint32_t pElemCnt, DWORD *pNewTypeID);
- HRESULT HandleDerivedType(DWORD dwParentID, llvm::DIDerivedType *DT, DWORD *pNewTypeID);
- HRESULT CreateLocalVariable(DWORD dwParentID, llvm::DILocalVariable *LV);
- HRESULT GetTypeLayout(llvm::DIType *Ty, std::vector<DWORD> *pRet);
- HRESULT CreateUDTField(DWORD dwParentID, llvm::DIDerivedType *Field);
- Session &m_Session;
- std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> &m_SymCtors;
- SymbolManager::ScopeToIDMap &m_ScopeToSym;
- SymbolManager::IDToLiveRangeMap &m_SymToLR;
- // vector of parents, i.e., for each i in parents[i], parents[i] is the
- // parent of m_symbol[i].
- std::vector<std::uint32_t> m_Parent;
- LocalVarToIDMap m_VarToID;
- UDTFieldToIDMap m_FieldToID;
- TypeToInfoMap m_TypeToInfo;
- TypeInfo &CurrentUDTInfo() { return *m_pCurUDT; }
- TypeInfo *m_pCurUDT = nullptr;
- struct UDTScope {
- UDTScope() = delete;
- UDTScope(const UDTScope &) = delete;
- UDTScope(UDTScope &&) = default;
- UDTScope(TypeInfo **pCur, TypeInfo *pNext) : m_pCur(pCur), m_pPrev(*pCur) {
- *pCur = pNext;
- }
- ~UDTScope() { *m_pCur = m_pPrev; }
- TypeInfo **m_pCur;
- TypeInfo *m_pPrev;
- };
- UDTScope BeginUDTScope(TypeInfo *pNext) {
- return UDTScope(&m_pCurUDT, pNext);
- }
- };
- } // namespace hlsl_symbols
- } // namespace dxil_dia
- STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_baseType(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = btNoType;
- if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(m_pNode)) {
- const DWORD SizeInBits = BT->getSizeInBits();
- switch (BT->getEncoding()) {
- case llvm::dwarf::DW_ATE_boolean:
- *pRetVal = btBool; break;
- case llvm::dwarf::DW_ATE_unsigned:
- *pRetVal = btUInt; break;
- case llvm::dwarf::DW_ATE_signed:
- *pRetVal = btInt; break;
- case llvm::dwarf::DW_ATE_float:
- *pRetVal = btFloat; break;
- }
- }
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_length(
- /* [retval][out] */ ULONGLONG *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = 0;
- if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(m_pNode)) {
- static constexpr DWORD kNumBitsPerByte = 8;
- const DWORD SizeInBits = BT->getSizeInBits();
- *pRetVal = SizeInBits / kNumBitsPerByte;
- }
- return S_OK;
- }
- static const std::string &dxil_dia::hlsl_symbols::DxilEntryName(Session *pSession) {
- return pSession->DxilModuleRef().GetEntryFunctionName();
- }
- HRESULT dxil_dia::hlsl_symbols::GlobalScopeSymbol::Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslProgramId, SymTagExe, (GlobalScopeSymbol**)ppSym));
- (*ppSym)->SetName(L"HLSL");
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::GlobalScopeSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- return m_pSession->SymMgr().ChildrenOf(this, children);
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandSymbol::Create(IMalloc *pMalloc, Session *pSession, llvm::DICompileUnit *CU, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandId, SymTagCompiland, (CompilandSymbol**)ppSym, CU));
- (*ppSym)->SetName(L"main");
- if (pSession->MainFileName()) {
- llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(pSession->MainFileName()->getOperand(0)->getOperand(0))->getString();
- std::string str(strRef.begin(), strRef.size()); // To make sure str is null terminated
- (*ppSym)->SetSourceFileName(_bstr_t(Unicode::UTF8ToUTF16StringOrThrow(str.data()).c_str()));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- return m_pSession->SymMgr().ChildrenOf(this, children);
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandDetailsSymbol::Create(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandDetailsId, SymTagCompilandDetails, (CompilandDetailsSymbol**)ppSym));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandDetailsSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- children->clear();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateFlags(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvFlagsId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
- (*ppSym)->SetName(L"hlslFlags");
- const char *specialCases[] = { "/T", "-T", "-D", "/D", "-E", "/E", };
- llvm::MDNode *argsNode = pSession->Arguments()->getOperand(0);
- // Construct a double null terminated string for defines with L"\0" as a delimiter
- CComBSTR pBSTR;
- for (llvm::MDNode::op_iterator it = argsNode->op_begin(); it != argsNode->op_end(); ++it) {
- llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(*it)->getString();
- bool skip = false;
- bool skipTwice = false;
- for (unsigned i = 0; i < _countof(specialCases); i++) {
- if (strRef == specialCases[i]) {
- skipTwice = true;
- skip = true;
- break;
- }
- else if (strRef.startswith(specialCases[i])) {
- skip = true;
- break;
- }
- }
- if (skip) {
- if (skipTwice)
- ++it;
- continue;
- }
- std::string str(strRef.begin(), strRef.size());
- CA2W cv(str.c_str(), CP_UTF8);
- pBSTR.Append(cv);
- pBSTR.Append(L"\0", 1);
- }
- pBSTR.Append(L"\0", 1);
- VARIANT Variant;
- Variant.bstrVal = pBSTR;
- Variant.vt = VARENUM::VT_BSTR;
- (*ppSym)->SetValue(&Variant);
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateTarget(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvTargetId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
- (*ppSym)->SetName(L"hlslTarget");
- (*ppSym)->SetValue(pSession->DxilModuleRef().GetShaderModel()->GetName());
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateEntry(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvEntryId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
- (*ppSym)->SetName(L"hlslEntry");
- (*ppSym)->SetValue(DxilEntryName(pSession).c_str());
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateDefines(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvDefinesId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
- (*ppSym)->SetName(L"hlslDefines");
- llvm::MDNode *definesNode = pSession->Defines()->getOperand(0);
- // Construct a double null terminated string for defines with L"\0" as a delimiter
- CComBSTR pBSTR;
- for (llvm::MDNode::op_iterator it = definesNode->op_begin(); it != definesNode->op_end(); ++it) {
- llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(*it)->getString();
- std::string str(strRef.begin(), strRef.size());
- CA2W cv(str.c_str(), CP_UTF8);
- pBSTR.Append(cv);
- pBSTR.Append(L"\0", 1);
- }
- pBSTR.Append(L"\0", 1);
- VARIANT Variant;
- Variant.bstrVal = pBSTR;
- Variant.vt = VARENUM::VT_BSTR;
- (*ppSym)->SetValue(&Variant);
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::CreateArguments(IMalloc *pMalloc, Session *pSession, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, HlslCompilandEnvArgumentsId, SymTagCompilandEnv, (CompilandEnvSymbol**)ppSym));
- (*ppSym)->SetName(L"hlslArguments");
- auto Arguments = pSession->Arguments()->getOperand(0);
- auto NumArguments = Arguments->getNumOperands();
- std::string args;
- for (unsigned i = 0; i < NumArguments; ++i) {
- llvm::StringRef strRef = llvm::dyn_cast<llvm::MDString>(Arguments->getOperand(i))->getString();
- if (!args.empty())
- args.push_back(' ');
- args = args + strRef.str();
- }
- (*ppSym)->SetValue(args.c_str());
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::CompilandEnvSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- children->clear();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::FunctionSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DISubprogram *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagFunction, (FunctionSymbol**)ppSym, Node, dwTypeID, Type));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::FunctionSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- return m_pSession->SymMgr().ChildrenOf(this, children);
- }
- HRESULT dxil_dia::hlsl_symbols::FunctionBlockSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagBlock, (FunctionBlockSymbol**)ppSym));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::FunctionBlockSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- return m_pSession->SymMgr().ChildrenOf(this, children);
- }
- HRESULT dxil_dia::hlsl_symbols::TypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, DWORD st, llvm::DIType *Node, LazySymbolName LazySymbolName, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, st, (TypeSymbol**)ppSym, Node, LazySymbolName));
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::TypeSymbol::get_name(
- /* [retval][out] */ BSTR *pRetVal) {
- DxcThreadMalloc TM(m_pSession->GetMallocNoRef());
- if (m_lazySymbolName != nullptr) {
- DXASSERT(!this->HasName(), "Setting type name multiple times.");
- std::string Name;
- IFR(m_lazySymbolName(m_pSession, &Name));
- this->SetName(CA2W(Name.c_str(), CP_UTF8));
- m_lazySymbolName = nullptr;
- }
- return Symbol::get_name(pRetVal);
- }
- HRESULT dxil_dia::hlsl_symbols::TypeSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- return m_pSession->SymMgr().ChildrenOf(this, children);
- }
- HRESULT dxil_dia::hlsl_symbols::VectorTypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwElemTyID, std::uint32_t NumElts, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagVectorType, (VectorTypeSymbol**)ppSym, Node, dwElemTyID, NumElts));
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::VectorTypeSymbol::get_count(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = m_NumElts;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::VectorTypeSymbol::get_type(
- /* [retval][out] */ IDiaSymbol **ppRetVal) {
- if (ppRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *ppRetVal = false;
- Symbol *ret;
- IFR(m_pSession->SymMgr().GetSymbolByID(m_ElemTyID, &ret));
- *ppRetVal = ret;
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::UDTSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DICompositeType *Node, LazySymbolName LazySymbolName, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagUDT, (UDTSymbol**)ppSym, Node, LazySymbolName));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::TypedefTypeSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwParentID, DWORD dwID, llvm::DIType *Node, DWORD dwBaseTypeID, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagTypedef, (TypedefTypeSymbol**)ppSym, Node, dwBaseTypeID));
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::TypedefTypeSymbol::get_type(
- /* [retval][out] */ IDiaSymbol **ppRetVal) {
- if (ppRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *ppRetVal = nullptr;
- Symbol *ret = nullptr;
- IFR(m_pSession->SymMgr().GetSymbolByID(m_dwBaseTypeID, &ret));
- *ppRetVal = ret;
- return S_FALSE;
- }
- HRESULT dxil_dia::hlsl_symbols::GlobalVariableSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIGlobalVariable *GV, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (GlobalVariableSymbol**)ppSym, GV, dwTypeID, Type));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::GlobalVariableSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- children->clear();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::LocalVariableSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIVariable *Node, DWORD dwTypeID, llvm::DIType *Type, DWORD dwOffsetInUDT, DWORD dwDxilRegNum, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (LocalVariableSymbol**)ppSym, Node, dwTypeID, Type, dwOffsetInUDT, dwDxilRegNum));
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_locationType(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = LocIsEnregistered;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_isAggregated(
- /* [retval][out] */ BOOL *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = m_pType->getTag() == llvm::dwarf::DW_TAG_member;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_registerType(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- static constexpr DWORD kPixTraceVirtualRegister = 0xfe;
- *pRetVal = kPixTraceVirtualRegister;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_offsetInUdt(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = m_dwOffsetInUDT;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_sizeInUdt(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- static constexpr DWORD kBitsPerByte = 8;
- //auto *DT = llvm::cast<llvm::DIDerivedType>(m_pType);
- *pRetVal = 4; //DT->getSizeInBits() / kBitsPerByte;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_numberOfRegisterIndices(
- /* [retval][out] */ DWORD *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- *pRetVal = 1;
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::LocalVariableSymbol::get_numericProperties(
- /* [in] */ DWORD cnt,
- /* [out] */ DWORD *pcnt,
- /* [size_is][out] */ DWORD *pProperties) {
- if (pcnt == nullptr || pProperties == nullptr || cnt != 1) {
- return E_INVALIDARG;
- }
- pProperties[0] = m_dwDxilRegNum;
- *pcnt = 1;
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::LocalVariableSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- children->clear();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::UDTFieldSymbol::Create(IMalloc *pMalloc, Session *pSession, DWORD dwID, llvm::DIDerivedType *Node, DWORD dwTypeID, llvm::DIType *Type, Symbol **ppSym) {
- IFR(AllocAndInit(pMalloc, pSession, dwID, SymTagData, (UDTFieldSymbol**)ppSym, Node, dwTypeID, Type));
- return S_OK;
- }
- STDMETHODIMP dxil_dia::hlsl_symbols::UDTFieldSymbol::get_offset(
- /* [retval][out] */ LONG *pRetVal) {
- if (pRetVal == nullptr) {
- return E_INVALIDARG;
- }
- static constexpr DWORD kBitsPerByte = 8;
- *pRetVal = m_pNode->getOffsetInBits() / kBitsPerByte;
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::UDTFieldSymbol::GetChildren(std::vector<CComPtr<Symbol>> *children) {
- children->clear();
- return S_OK;
- }
- dxil_dia::hlsl_symbols::SymbolManagerInit::SymbolManagerInit(
- Session *pSession,
- std::vector<std::unique_ptr<SymbolManager::SymbolFactory>> *pSymCtors,
- SymbolManager::ScopeToIDMap *pScopeToSym,
- SymbolManager::IDToLiveRangeMap *pSymToLR)
- : m_Session(*pSession),
- m_SymCtors(*pSymCtors),
- m_ScopeToSym(*pScopeToSym),
- m_SymToLR(*pSymToLR) {
- DXASSERT_ARGS(m_Parent.size() == m_SymCtors.size(),
- "parent and symbol array size mismatch: %d vs %d",
- m_Parent.size(),
- m_SymCtors.size());
- }
- void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::Embed(const TypeInfo &TI) {
- for (const auto &E : TI.GetLayout()) {
- m_Layout.emplace_back(E);
- }
- m_dwCurrentSizeInBytes += TI.m_dwCurrentSizeInBytes;
- }
- void dxil_dia::hlsl_symbols::SymbolManagerInit::TypeInfo::AddBasicType(llvm::DIBasicType *BT) {
- m_Layout.emplace_back(BT);
- static constexpr DWORD kNumBitsPerByte = 8;
- m_dwCurrentSizeInBytes += BT->getSizeInBits() / kNumBitsPerByte;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetTypeInfo(llvm::DIType *T, TypeInfo **TI) {
- auto tyInfoIt = m_TypeToInfo.find(T);
- if (tyInfoIt == m_TypeToInfo.end()) {
- return E_FAIL;
- }
- *TI = tyInfoIt->second.get();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::AddParent(DWORD dwParentIndex) {
- m_Parent.emplace_back(dwParentIndex);
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlockForLocalScope(llvm::DILocalScope *LS, DWORD *pNewSymID) {
- if (LS == nullptr) {
- return E_FAIL;
- }
- auto lsIT = m_ScopeToSym.find(LS);
- if (lsIT != m_ScopeToSym.end()) {
- *pNewSymID = lsIT->second;
- return S_OK;
- }
- llvm::DILocalScope *ParentLS = nullptr;
- if (auto *Location = llvm::dyn_cast<llvm::DILocation>(LS)) {
- ParentLS = Location->getInlinedAtScope();
- if (ParentLS == nullptr) {
- ParentLS = Location->getScope();
- }
- } else if (auto *Block = llvm::dyn_cast<llvm::DILexicalBlock>(LS)) {
- ParentLS = Block->getScope();
- } else if (auto *BlockFile = llvm::dyn_cast<llvm::DILexicalBlockFile>(LS)) {
- ParentLS = BlockFile->getScope();
- }
- if (ParentLS == nullptr) {
- return E_FAIL;
- }
- DWORD dwParentID;
- IFR(CreateFunctionBlockForLocalScope(ParentLS, &dwParentID));
- IFR(AddSymbol<symbol_factory::FunctionBlock>(dwParentID, pNewSymID));
- m_ScopeToSym.insert(std::make_pair(LS, *pNewSymID));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlockForInstruction(llvm::Instruction *I) {
- const llvm::DebugLoc &DL = I->getDebugLoc();
- if (!DL) {
- return S_OK;
- }
- llvm::MDNode *LocalScope = DL.getInlinedAtScope();
- if (LocalScope == nullptr) {
- LocalScope = DL.getScope();
- }
- if (LocalScope == nullptr) {
- return S_OK;
- }
- auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
- if (LS == nullptr) {
- return E_FAIL;
- }
- auto localScopeIt = m_ScopeToSym.find(LS);
- if (localScopeIt == m_ScopeToSym.end()) {
- DWORD dwUnusedNewSymID;
- IFR(CreateFunctionBlockForLocalScope(LS, &dwUnusedNewSymID));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionBlocksForFunction(llvm::Function *F) {
- for (llvm::BasicBlock &BB : *F) {
- for (llvm::Instruction &I : BB) {
- IFR(CreateFunctionBlockForInstruction(&I));
- }
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionsForCU(llvm::DICompileUnit *CU) {
- bool FoundFunctions = false;
- for (llvm::DISubprogram *SubProgram : CU->getSubprograms()) {
- DWORD dwNewFunID;
- const DWORD dwParentID = SubProgram->isLocalToUnit() ? HlslCompilandId : HlslProgramId;
- DWORD dwSubprogramTypeID;
- IFR(CreateType(SubProgram->getType(), &dwSubprogramTypeID));
- IFR(AddSymbol<symbol_factory::Function>(dwParentID, &dwNewFunID, SubProgram, dwSubprogramTypeID));
- m_ScopeToSym.insert(std::make_pair(SubProgram, dwNewFunID));
- }
- for (llvm::DISubprogram* SubProgram : CU->getSubprograms()) {
- if (llvm::Function *F = SubProgram->getFunction()) {
- IFR(CreateFunctionBlocksForFunction(F));
- FoundFunctions = true;
- }
- }
- if (!FoundFunctions) {
- // This works around an old bug in dxcompiler whose effects are still
- // sometimes present in PIX users' traces. (The bug was that the subprogram(s)
- // weren't pointing to their contained function.)
- llvm::Module *M = &m_Session.ModuleRef();
- auto &DM = M->GetDxilModule();
- llvm::Function *EntryPoint = DM.GetEntryFunction();
- IFR(CreateFunctionBlocksForFunction(EntryPoint));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateFunctionsForAllCUs() {
- for (llvm::DICompileUnit *pCU : m_Session.InfoRef().compile_units()) {
- IFR(CreateFunctionsForCU(pCU));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateGlobalVariablesForCU(llvm::DICompileUnit *CU) {
- for (llvm::DIGlobalVariable *GlobalVariable : CU->getGlobalVariables()) {
- DWORD dwUnusedNewGVID;
- const DWORD dwParentID = GlobalVariable->isLocalToUnit() ? HlslCompilandId : HlslProgramId;
- auto *GVType = dyn_cast_to_ditype<llvm::DIType>(GlobalVariable->getType());
- DWORD dwGVTypeID;
- IFR(CreateType(GVType, &dwGVTypeID));
- IFR(AddSymbol<symbol_factory::GlobalVariable>(dwParentID, &dwUnusedNewGVID, GlobalVariable, dwGVTypeID, GVType));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateGlobalVariablesForAllCUs() {
- for (llvm::DICompileUnit *pCU : m_Session.InfoRef().compile_units()) {
- IFR(CreateGlobalVariablesForCU(pCU));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetScopeID(llvm::DIScope *S, DWORD *pScopeID) {
- auto ParentScopeIt = m_ScopeToSym.find(S);
- if (ParentScopeIt != m_ScopeToSym.end()) {
- *pScopeID = ParentScopeIt->second;
- } else {
- auto *ParentScopeTy = llvm::dyn_cast<llvm::DIType>(S);
- if (!ParentScopeTy) {
- // Any non-existing scope must be a type.
- return E_FAIL;
- }
- IFR(CreateType(ParentScopeTy, pScopeID));
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateType(llvm::DIType *Type, DWORD *pNewTypeID) {
- if (Type == nullptr) {
- return E_FAIL;
- }
- auto lsIT = m_TypeToInfo.find(Type);
- if (lsIT != m_TypeToInfo.end()) {
- *pNewTypeID = lsIT->second->GetTypeID();
- return S_OK;
- }
- if (auto *ST = llvm::dyn_cast<llvm::DISubroutineType>(Type)) {
- IFR(CreateSubroutineType(HlslProgramId, ST, pNewTypeID));
- return S_OK;
- } else if (auto *BT = llvm::dyn_cast<llvm::DIBasicType>(Type)) {
- IFR(CreateBasicType(HlslProgramId, BT, pNewTypeID));
- return S_OK;
- } else if (auto *CT = llvm::dyn_cast<llvm::DICompositeType>(Type)) {
- DWORD dwParentID = HlslProgramId;
- if (auto *ParentScope = dyn_cast_to_ditype_or_null<llvm::DIScope>(CT->getScope())) {
- IFR(GetScopeID(ParentScope, &dwParentID));
- }
- IFR(CreateCompositeType(dwParentID, CT, pNewTypeID));
- return S_OK;
- } else if (auto *DT = llvm::dyn_cast<llvm::DIDerivedType>(Type)) {
- DWORD dwParentID = HlslProgramId;
- if (auto *ParentScope = dyn_cast_to_ditype_or_null<llvm::DIScope>(DT->getScope())) {
- IFR(GetScopeID(ParentScope, &dwParentID));
- }
- IFR(HandleDerivedType(dwParentID, DT, pNewTypeID));
- return S_OK;
- }
- return E_FAIL;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateSubroutineType(DWORD dwParentID, llvm::DISubroutineType *ST, DWORD *pNewTypeID) {
- LazySymbolName LazyName;
- llvm::DITypeRefArray Types = ST->getTypeArray();
- if (Types.size() > 0) {
- std::vector<DWORD> TypeIDs;
- TypeIDs.reserve(Types.size());
- for (llvm::Metadata *M : Types) {
- auto *Ty = dyn_cast_to_ditype_or_null<llvm::DIType>(M);
- if (Ty == nullptr) {
- TypeIDs.emplace_back(kNullSymbolID);
- } else {
- DWORD dwTyID;
- IFR(CreateType(Ty, &dwTyID));
- TypeIDs.emplace_back(dwTyID);
- }
- }
- LazyName = [TypeIDs](Session *pSession, std::string *Name) -> HRESULT {
- Name->clear();
- llvm::raw_string_ostream OS(*Name);
- OS.SetUnbuffered();
- bool first = true;
- bool firstArg = true;
- auto &SM = pSession->SymMgr();
- for (DWORD ID : TypeIDs) {
- if (!first && !firstArg) {
- OS << ", ";
- }
- if (ID == kNullSymbolID) {
- OS << "void";
- } else {
- CComPtr<Symbol> SymTy;
- IFR(SM.GetSymbolByID(ID, &SymTy));
- CComBSTR name;
- IFR(SymTy->get_name(&name));
- if (!name) {
- OS << "???";
- } else {
- OS << CW2A((BSTR)name, CP_UTF8);
- }
- }
- if (first) {
- OS << "(";
- }
- firstArg = first;
- first = false;
- }
- OS << ")";
- return S_OK;
- };
- }
- IFR(AddType<symbol_factory::Type>(dwParentID, ST, pNewTypeID, SymTagFunctionType, ST, LazyName));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateBasicType(DWORD dwParentID, llvm::DIBasicType *BT, DWORD *pNewTypeID) {
- DXASSERT_ARGS(dwParentID == HlslProgramId,
- "%d vs %d",
- dwParentID,
- HlslProgramId);
- LazySymbolName LazyName = [BT](Session *pSession, std::string *Name) -> HRESULT {
- *Name = BT->getName();
- return S_OK;
- };
- IFR(AddType<symbol_factory::Type>(dwParentID, BT, pNewTypeID, SymTagBaseType, BT, LazyName));
- TypeInfo *TI;
- IFR(GetTypeInfo(BT, &TI));
- TI->AddBasicType(BT);
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateCompositeType(DWORD dwParentID, llvm::DICompositeType *CT, DWORD *pNewTypeID) {
- switch (CT->getTag()) {
- case llvm::dwarf::DW_TAG_array_type: {
- auto *BaseType = dyn_cast_to_ditype_or_null<llvm::DIType>(CT->getBaseType());
- if (BaseType == nullptr) {
- return E_FAIL;
- }
- DWORD dwBaseTypeID = kNullSymbolID;
- IFR(CreateType(BaseType, &dwBaseTypeID));
- auto LazyName = [CT, dwBaseTypeID](Session *pSession, std::string *Name) -> HRESULT {
- auto &SM = pSession->SymMgr();
- Name->clear();
- llvm::raw_string_ostream OS(*Name);
- OS.SetUnbuffered();
- auto *BaseTy = llvm::dyn_cast<llvm::DIType>(CT->getBaseType());
- if (BaseTy == nullptr) {
- return E_FAIL;
- }
- CComPtr<Symbol> SymTy;
- IFR(SM.GetSymbolByID(dwBaseTypeID, &SymTy));
- CComBSTR name;
- IFR(SymTy->get_name(&name));
- if (!name) {
- OS << "???";
- } else {
- OS << CW2A((BSTR)name, CP_UTF8);
- }
- OS << "[";
- bool first = true;
- for (llvm::DINode *N : CT->getElements()) {
- if (!first) {
- OS << "][";
- }
- first = false;
- if (N != nullptr) {
- if (auto *SubRange = llvm::dyn_cast<llvm::DISubrange>(N)) {
- OS << SubRange->getCount();
- } else {
- OS << "???";
- }
- }
- }
- OS << "]";
- return S_OK;
- };
- IFR(AddType<symbol_factory::Type>(dwParentID, CT, pNewTypeID, SymTagArrayType, CT, LazyName));
- TypeInfo *ctTI;
- IFR(GetTypeInfo(CT, &ctTI));
- TypeInfo *baseTI;
- IFR(GetTypeInfo(BaseType, &baseTI));
- int64_t embedCount = 1;
- for (llvm::DINode *N : CT->getElements()) {
- if (N != nullptr) {
- if (auto *SubRange = llvm::dyn_cast<llvm::DISubrange>(N)) {
- embedCount *= SubRange->getCount();
- } else {
- return E_FAIL;
- }
- }
- }
- for (int64_t i = 0; i < embedCount; ++i) {
- ctTI->Embed(*baseTI);
- }
- return S_OK;
- }
- case llvm::dwarf::DW_TAG_class_type: {
- HRESULT hr;
- IFR(hr = CreateHLSLType(CT, pNewTypeID));
- if (hr == S_OK) {
- return S_OK;
- }
- break;
- }
- }
- auto LazyName = [CT](Session *pSession, std::string *Name) -> HRESULT {
- *Name = CT->getName();
- return S_OK;
- };
- IFR(AddType<symbol_factory::UDT>(dwParentID, CT, pNewTypeID, CT, LazyName));
- TypeInfo *udtTI;
- IFR(GetTypeInfo(CT, &udtTI));
- auto udtScope = BeginUDTScope(udtTI);
- for (llvm::DINode *N : CT->getElements()) {
- if (auto *Field = llvm::dyn_cast<llvm::DIType>(N)) {
- DWORD dwUnusedFieldID;
- IFR(CreateType(Field, &dwUnusedFieldID));
- }
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLType(llvm::DICompositeType *T, DWORD *pNewTypeID) {
- DWORD dwEltTyID;
- std::uint32_t ElemCnt;
- HRESULT hr;
- IFR(hr = IsHLSLVectorType(T, &dwEltTyID, &ElemCnt));
- if (hr == S_OK) {
- // e.g. float4, int2 etc
- return CreateHLSLVectorType(T, dwEltTyID, ElemCnt, pNewTypeID);
- }
- return S_FALSE;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::IsHLSLVectorType(llvm::DICompositeType *T, DWORD *pEltTyID, std::uint32_t *pElemCnt) {
- llvm::StringRef Name = T->getName();
- if (!Name.startswith("vector<")) {
- return S_FALSE;
- }
- llvm::DITemplateParameterArray Args = T->getTemplateParams();
- if (Args.size() != 2) {
- return E_FAIL;
- }
- auto *ElemTyParam = llvm::dyn_cast<llvm::DITemplateTypeParameter>(Args[0]);
- if (ElemTyParam == nullptr) {
- return E_FAIL;
- }
- auto *ElemTy = dyn_cast_to_ditype<llvm::DIType>(ElemTyParam->getType());
- if (ElemTy == nullptr) {
- return E_FAIL;
- }
- DWORD dwEltTyID;
- IFR(CreateType(ElemTy, &dwEltTyID));
- auto *ElemCntParam = llvm::dyn_cast<llvm::DITemplateValueParameter>(Args[1]);
- if (ElemCntParam == nullptr) {
- return E_FAIL;
- }
- auto *ElemCntMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(ElemCntParam->getValue());
- auto *ElemCnt = llvm::dyn_cast_or_null<llvm::ConstantInt>(ElemCntMD->getValue());
- if (ElemCnt == nullptr) {
- return E_FAIL;
- }
- if (ElemCnt->getLimitedValue() > 4) {
- return E_FAIL;
- }
- *pEltTyID = dwEltTyID;
- *pElemCnt = ElemCnt->getLimitedValue();
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateHLSLVectorType(llvm::DICompositeType *T, DWORD pEltTyID, std::uint32_t pElemCnt, DWORD *pNewTypeID) {
- llvm::DITemplateParameterArray Args = T->getTemplateParams();
- if (Args.size() != 2) {
- return E_FAIL;
- }
- auto *ElemTyParam = llvm::dyn_cast<llvm::DITemplateTypeParameter>(Args[0]);
- if (ElemTyParam == nullptr) {
- return E_FAIL;
- }
- auto *ElemTy = dyn_cast_to_ditype<llvm::DIType>(ElemTyParam->getType());
- if (ElemTy == nullptr) {
- return E_FAIL;
- }
- DWORD dwElemTyID;
- IFT(CreateType(ElemTy, &dwElemTyID));
- auto *ElemCntParam = llvm::dyn_cast<llvm::DITemplateValueParameter>(Args[1]);
- if (ElemCntParam == nullptr) {
- return E_FAIL;
- }
- auto *ElemCntMD = llvm::dyn_cast<llvm::ConstantAsMetadata>(ElemCntParam->getValue());
- auto *ElemCnt = llvm::dyn_cast_or_null<llvm::ConstantInt>(ElemCntMD->getValue());
- if (ElemCnt == nullptr) {
- return E_FAIL;
- }
- if (ElemCnt->getLimitedValue() > 4) {
- return E_FAIL;
- }
- const DWORD dwParentID = HlslProgramId;
- IFR(AddType<symbol_factory::VectorType>(dwParentID, T, pNewTypeID, T, dwElemTyID, ElemCnt->getLimitedValue()));
- TypeInfo *vecTI;
- IFR(GetTypeInfo(T, &vecTI));
- TypeInfo *elemTI;
- IFR(GetTypeInfo(ElemTy, &elemTI));
- for (std::uint64_t i = 0; i < ElemCnt->getLimitedValue(); ++i) {
- vecTI->Embed(*elemTI);
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::HandleDerivedType(DWORD dwParentID, llvm::DIDerivedType *DT, DWORD *pNewTypeID) {
- DWORD st;
- LazySymbolName LazyName;
- DWORD dwBaseTypeID = kNullSymbolID;
- auto *BaseTy = llvm::dyn_cast_or_null<llvm::DIType>(DT->getBaseType());
- if (BaseTy != nullptr) {
- IFR(CreateType(BaseTy, &dwBaseTypeID));
- }
- auto LazyNameWithQualifier = [dwBaseTypeID, DT](Session *pSession, std::string *Name, const char *Qualifier) -> HRESULT {
- auto &SM = pSession->SymMgr();
- Name->clear();
- llvm::raw_string_ostream OS(*Name);
- OS.SetUnbuffered();
- auto *BaseTy = llvm::dyn_cast<llvm::DIType>(DT->getBaseType());
- if (BaseTy == nullptr) {
- return E_FAIL;
- }
- CComPtr<Symbol> SymTy;
- IFR(SM.GetSymbolByID(dwBaseTypeID, &SymTy));
- CComBSTR name;
- IFR(SymTy->get_name(&name));
- if (!name) {
- OS << "???";
- } else {
- OS << CW2A((BSTR)name, CP_UTF8);
- }
- OS << Qualifier;
- return S_OK;
- };
- switch (DT->getTag()) {
- case llvm::dwarf::DW_TAG_member: {
- // Type is not really a type, but rather a struct member.
- IFR(CreateUDTField(dwParentID, DT));
- return S_OK;
- }
- default:
- st = SymTagBlock;
- LazyName = [](Session *pSession, std::string *Name) -> HRESULT {
- Name->clear();
- return S_OK;
- };
- break;
- case llvm::dwarf::DW_TAG_typedef: {
- if (dwBaseTypeID == kNullSymbolID) {
- return E_FAIL;
- }
- IFR(AddType<symbol_factory::TypedefType>(dwParentID, DT, pNewTypeID, DT, dwBaseTypeID));
- TypeInfo *dtTI;
- IFR(GetTypeInfo(DT, &dtTI));
- TypeInfo *baseTI;
- IFR(GetTypeInfo(BaseTy, &baseTI));
- dtTI->Embed(*baseTI);
- return S_OK;
- }
- case llvm::dwarf::DW_TAG_const_type: {
- if (dwBaseTypeID == kNullSymbolID) {
- return E_FAIL;
- }
- st = SymTagCustomType;
- LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " const");
- break;
- }
- case llvm::dwarf::DW_TAG_pointer_type: {
- if (dwBaseTypeID == kNullSymbolID) {
- return E_FAIL;
- }
- st = SymTagPointerType;
- LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " *");
- break;
- }
- case llvm::dwarf::DW_TAG_reference_type: {
- if (dwBaseTypeID == kNullSymbolID) {
- return E_FAIL;
- }
- st = SymTagCustomType;
- LazyName = std::bind(LazyNameWithQualifier, std::placeholders::_1, std::placeholders::_2, " &");
- break;
- }
- }
- IFR(AddType<symbol_factory::Type>(dwParentID, DT, pNewTypeID, st, DT, LazyName));
- if (DT->getTag() == llvm::dwarf::DW_TAG_const_type) {
- TypeInfo *dtTI;
- IFR(GetTypeInfo(DT, &dtTI));
- TypeInfo *baseTI;
- IFR(GetTypeInfo(BaseTy, &baseTI));
- dtTI->Embed(*baseTI);
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLocalVariable(DWORD dwParentID, llvm::DILocalVariable *LV) {
- auto *LVTy = dyn_cast_to_ditype<llvm::DIType>(LV->getType());
- if (LVTy == nullptr) {
- return E_FAIL;
- }
- if (m_VarToID.count(LV) != 0) {
- return S_OK;
- }
- DWORD dwLVTypeID;
- IFR(CreateType(LVTy, &dwLVTypeID));
- TypeInfo *varTI;
- IFR(GetTypeInfo(LVTy, &varTI));
- DWORD dwOffsetInUDT = 0;
- auto &newVars = m_VarToID[LV];
- std::vector<llvm::DIType *> Tys = varTI->GetLayout();
- for (llvm::DIType *Ty : Tys) {
- TypeInfo *TI;
- IFR(GetTypeInfo(Ty, &TI));
- const DWORD dwTypeID = TI->GetTypeID();
- DWORD dwNewLVID;
- newVars.emplace_back(std::make_shared<symbol_factory::LocalVarInfo>());
- std::shared_ptr<symbol_factory::LocalVarInfo> VI = newVars.back();
- IFR(AddSymbol<symbol_factory::LocalVariable>(dwParentID, &dwNewLVID, LV, dwLVTypeID, LVTy, VI));
- VI->SetVarID(dwNewLVID);
- VI->SetOffsetInUDT(dwOffsetInUDT);
- static constexpr DWORD kNumBitsPerByte = 8;
- dwOffsetInUDT += Ty->getSizeInBits() / kNumBitsPerByte;
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetTypeLayout(llvm::DIType *Ty, std::vector<DWORD> *pRet) {
- pRet->clear();
- TypeInfo *TI;
- IFR(GetTypeInfo(Ty, &TI));
- for (llvm::DIType * T : TI->GetLayout()) {
- TypeInfo *eTI;
- IFR(GetTypeInfo(T, &eTI));
- pRet->emplace_back(eTI->GetTypeID());
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateUDTField(DWORD dwParentID, llvm::DIDerivedType *Field) {
- auto *FieldTy = dyn_cast_to_ditype<llvm::DIType>(Field->getBaseType());
- if (FieldTy == nullptr) {
- return E_FAIL;
- }
- if (m_FieldToID.count(Field) != 0) {
- return S_OK;
- }
- DWORD dwLVTypeID;
- IFR(CreateType(FieldTy, &dwLVTypeID));
- if (m_pCurUDT != nullptr) {
- const DWORD dwOffsetInBytes = CurrentUDTInfo().GetCurrentSizeInBytes();
- DXASSERT_ARGS(dwOffsetInBytes == Field->getOffsetInBits() / 8,
- "%d vs %d",
- dwOffsetInBytes,
- Field->getOffsetInBits() / 8);
- TypeInfo *lvTI;
- IFR(GetTypeInfo(FieldTy, &lvTI));
- CurrentUDTInfo().Embed(*lvTI);
- }
- DWORD dwNewLVID;
- IFR(AddSymbol<symbol_factory::UDTField>(dwParentID, &dwNewLVID, Field, dwLVTypeID, FieldTy));
- m_FieldToID.insert(std::make_pair(Field, dwNewLVID));
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLocalVariables() {
- llvm::Module *M = &m_Session.ModuleRef();
- llvm::Function *DbgDeclare = llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::dbg_declare);
- for (llvm::Value *U : DbgDeclare->users()) {
- auto *CI = llvm::dyn_cast<llvm::CallInst>(U);
- auto *LS = llvm::dyn_cast_or_null<llvm::DILocalScope>(CI->getDebugLoc()->getInlinedAtScope());
- auto SymIt = m_ScopeToSym.find(LS);
- if (SymIt == m_ScopeToSym.end()) {
- return E_FAIL;
- }
- auto *LocalNameMetadata = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(1));
- if (auto *LV = llvm::dyn_cast<llvm::DILocalVariable>(LocalNameMetadata->getMetadata())) {
- const DWORD dwParentID = SymIt->second;
- IFR(CreateLocalVariable(dwParentID, LV));
- }
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::CreateLiveRanges() {
- // Simple algorithm:
- // live_range = map from SymbolID to SymbolManager.LiveRange
- // end_of_scope = map from Scope to RVA
- // for each I in reverse(pSession.InstructionsRef):
- // scope = I.scope
- // if scope not in end_of_scope:
- // end_of_scope[scope] = rva(I)
- // if I is dbg.declare:
- // live_range[symbol of I] = SymbolManager.LiveRange[FirstUseRVA, end_of_scope[scope]]
- llvm::Module *M = &m_Session.ModuleRef();
- m_SymToLR.clear();
- const auto &Instrs = m_Session.InstructionsRef();
- llvm::DenseMap<llvm::DILocalScope *, Session::RVA> EndOfScope;
- for (auto It = Instrs.rbegin(); It != Instrs.rend(); ++It) {
- const Session::RVA RVA = It->first;
- const auto *I = It->second;
- const llvm::DebugLoc &DL = I->getDebugLoc();
- if (!DL) {
- continue;
- }
- llvm::MDNode *LocalScope = DL.getScope();
- if (LocalScope == nullptr) {
- continue;
- }
- auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
- if (LS == nullptr) {
- return E_FAIL;
- }
- if (EndOfScope.count(LS) == 0) {
- EndOfScope.insert(std::make_pair(LS, RVA + 1));
- }
- auto endOfScopeRVA = EndOfScope.find(LS)->second;
- DWORD Reg;
- DWORD RegSize;
- llvm::DILocalVariable *LV;
- uint64_t StartOffset;
- uint64_t EndOffset;
- Session::RVA FirstUseRVA;
- Session::RVA LastUseRVA;
- HRESULT hr = IsDbgDeclareCall(M, I, &Reg, &RegSize, &LV, &StartOffset,
- &EndOffset, &FirstUseRVA, &LastUseRVA);
- if (hr != S_OK) {
- continue;
- }
- endOfScopeRVA = std::max<Session::RVA>(endOfScopeRVA, LastUseRVA);
- auto varIt = m_VarToID.find(LV);
- if (varIt == m_VarToID.end()) {
- // All variables should already have been seen and created.
- return E_FAIL;
- }
- for (auto &Var : varIt->second) {
- const DWORD dwOffsetInUDT = Var->GetOffsetInUDT();
- if (dwOffsetInUDT < StartOffset || dwOffsetInUDT >= EndOffset) {
- continue;
- }
- DXASSERT_ARGS((dwOffsetInUDT - StartOffset) % 4 == 0,
- "Invalid byte offset %d into variable",
- (dwOffsetInUDT - StartOffset));
- const DWORD dwRegIndex = (dwOffsetInUDT - StartOffset) / 4;
- if (dwRegIndex >= RegSize) {
- continue;
- }
- Var->SetDxilRegister(Reg + dwRegIndex);
- m_SymToLR[Var->GetVarID()] = SymbolManager::LiveRange{
- static_cast<uint32_t>(FirstUseRVA),
- endOfScopeRVA - static_cast<uint32_t>(FirstUseRVA)
- };
- }
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::IsDbgDeclareCall(
- llvm::Module *M, const llvm::Instruction *I, DWORD *pReg, DWORD *pRegSize,
- llvm::DILocalVariable **LV, uint64_t *pStartOffset, uint64_t *pEndOffset,
- dxil_dia::Session::RVA *pLowestUserRVA,
- dxil_dia::Session::RVA *pHighestUserRVA) {
- auto *CI = llvm::dyn_cast<llvm::CallInst>(I);
- if (CI == nullptr) {
- return S_FALSE;
- }
- llvm::Function *DbgDeclare = llvm::Intrinsic::getDeclaration(M, llvm::Intrinsic::dbg_declare);
- if (CI->getCalledFunction() != DbgDeclare) {
- return S_FALSE;
- }
- *LV = nullptr;
- *pReg = *pRegSize = 0;
- *pStartOffset = *pEndOffset = 0;
- *pLowestUserRVA = 0;
- *pHighestUserRVA = 0;
- std::vector<dxil_dia::Session::RVA> usesRVAs;
- bool HasRegister = false;
- if (auto *RegMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(0))) {
- if (auto *RegVM = llvm::dyn_cast<llvm::ValueAsMetadata>(RegMV->getMetadata())) {
- if (auto *Reg = llvm::dyn_cast<llvm::Instruction>(RegVM->getValue())) {
- HRESULT hr;
- IFR(hr = GetDxilAllocaRegister(Reg, pReg, pRegSize));
- if (hr != S_OK) {
- return hr;
- }
- HasRegister = true;
- llvm::iterator_range<llvm::Value::user_iterator> users = Reg->users();
- for (llvm::User *user : users) {
- auto *inst = llvm::dyn_cast<llvm::Instruction>(user);
- if (inst != nullptr) {
- auto rva = m_Session.RvaMapRef().find(inst);
- usesRVAs.push_back(rva->second);
- }
- }
- }
- }
- }
- if (!HasRegister) {
- return E_FAIL;
- }
- if (!usesRVAs.empty()) {
- *pLowestUserRVA = *std::min_element(usesRVAs.begin(), usesRVAs.end());
- *pHighestUserRVA = *std::max_element(usesRVAs.begin(), usesRVAs.end());
- }
- if (auto *LVMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(1))) {
- *LV = llvm::dyn_cast<llvm::DILocalVariable>(LVMV->getMetadata());
- if (*LV == nullptr) {
- return E_FAIL;
- }
- }
- if (auto *FieldsMV = llvm::dyn_cast<llvm::MetadataAsValue>(CI->getArgOperand(2))) {
- auto *Fields = llvm::dyn_cast<llvm::DIExpression>(FieldsMV->getMetadata());
- if (Fields == nullptr) {
- return E_FAIL;
- }
- static constexpr uint64_t kNumBytesPerDword = 4;
- if (Fields->isBitPiece()) {
- const uint64_t BitPieceOffset = Fields->getBitPieceOffset();
- const uint64_t BitPieceSize = Fields->getBitPieceSize();
- // dxcompiler had a bug (fixed in
- // 4870297404a37269e24ddce7db3bd94a8110fff8) where the BitPieceSize
- // was defined in bytes, not bits. We use the register size in bits to
- // verify if Size is bits or bytes.
- if (*pRegSize * kNumBytesPerDword == BitPieceSize) {
- // Size is bytes.
- *pStartOffset = BitPieceOffset;
- *pEndOffset = *pStartOffset + BitPieceSize;
- } else {
- // Size is (should be) bits; pStartOffset/pEndOffset should be bytes.
- // We don't expect to encounter bit pieces more granular than bytes.
- static constexpr uint64_t kNumBitsPerByte = 8;
- (void)kNumBitsPerByte;
- assert(BitPieceOffset % kNumBitsPerByte == 0);
- assert(BitPieceSize % kNumBitsPerByte == 0);
- *pStartOffset = BitPieceOffset / kNumBitsPerByte;
- *pEndOffset = *pStartOffset + (BitPieceSize / kNumBitsPerByte);
- }
- } else {
- *pStartOffset = 0;
- *pEndOffset = *pRegSize * kNumBytesPerDword;
- }
- }
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::GetDxilAllocaRegister(llvm::Instruction *I, DWORD *pRegNum, DWORD *pRegSize) {
- auto *Alloca = llvm::dyn_cast<llvm::AllocaInst>(I);
- if (Alloca == nullptr) {
- return S_FALSE;
- }
- std::uint32_t uRegNum;
- std::uint32_t uRegSize;
- if (!pix_dxil::PixAllocaReg::FromInst(Alloca, &uRegNum, &uRegSize)) {
- return S_FALSE;
- }
- *pRegNum = uRegNum;
- *pRegSize = uRegSize;
- return S_OK;
- }
- HRESULT dxil_dia::hlsl_symbols::SymbolManagerInit::PopulateParentToChildrenIDMap(SymbolManager::ParentToChildrenMap *pParentToChildren) {
- DXASSERT_ARGS(m_SymCtors.size() == m_Parent.size(),
- "parents vector must be the same size of symbols ctor vector: %d vs %d",
- m_SymCtors.size(),
- m_Parent.size());
- for (size_t i = 0; i < m_Parent.size(); ++i) {
- #ifndef NDEBUG
- {
- CComPtr<Symbol> S;
- IFT(m_SymCtors[i]->Create(&m_Session, &S));
- DXASSERT_ARGS(S->GetID() == i + 1,
- "Invalid symbol index %d for %d",
- S->GetID(),
- i + 1);
- }
- #endif // !NDEBUG
- DXASSERT_ARGS(m_Parent[i] != kNullSymbolID || (i + 1) == HlslProgramId,
- "Parentless symbol %d", i + 1);
- if (m_Parent[i] != kNullSymbolID) {
- pParentToChildren->emplace(m_Parent[i], i + 1);
- }
- }
- return S_OK;
- }
- dxil_dia::SymbolManager::SymbolFactory::SymbolFactory(DWORD ID, DWORD ParentID)
- : m_ID(ID), m_ParentID(ParentID) {}
- dxil_dia::SymbolManager::SymbolFactory::~SymbolFactory() = default;
- dxil_dia::SymbolManager::SymbolManager() = default;
- dxil_dia::SymbolManager::~SymbolManager() {
- m_pSession = nullptr;
- }
- void dxil_dia::SymbolManager::Init(Session *pSes) {
- DXASSERT(m_pSession == nullptr, "SymbolManager already initialized");
- m_pSession = pSes;
- m_symbolCtors.clear();
- m_parentToChildren.clear();
- llvm::DebugInfoFinder &DIFinder = pSes->InfoRef();
- if (DIFinder.compile_unit_count() != 1) {
- throw hlsl::Exception(E_FAIL);
- }
- llvm::DICompileUnit *ShaderCU = *DIFinder.compile_units().begin();
- hlsl_symbols::SymbolManagerInit SMI(pSes, &m_symbolCtors, &m_scopeToID, &m_symbolToLiveRange);
- DWORD dwHlslProgramID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::GlobalScope>(kNullSymbolID, &dwHlslProgramID));
- DXASSERT_ARGS(dwHlslProgramID == HlslProgramId,
- "%d vs %d",
- dwHlslProgramID,
- HlslProgramId);
- DWORD dwHlslCompilandID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::Compiland>(dwHlslProgramID, &dwHlslCompilandID, ShaderCU));
- m_scopeToID.insert(std::make_pair(ShaderCU, dwHlslCompilandID));
- DXASSERT_ARGS(dwHlslCompilandID == HlslCompilandId,
- "%d vs %d",
- dwHlslCompilandID,
- HlslCompilandId);
- DWORD dwHlslCompilandDetailsId;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandDetails>(dwHlslCompilandID, &dwHlslCompilandDetailsId));
- DXASSERT_ARGS(dwHlslCompilandDetailsId == HlslCompilandDetailsId,
- "%d vs %d",
- dwHlslCompilandDetailsId,
- HlslCompilandDetailsId);
- DWORD dwHlslCompilandEnvFlagsID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateFlags>>(dwHlslCompilandID, &dwHlslCompilandEnvFlagsID));
- DXASSERT_ARGS(dwHlslCompilandEnvFlagsID == HlslCompilandEnvFlagsId,
- "%d vs %d",
- dwHlslCompilandEnvFlagsID,
- HlslCompilandEnvFlagsId);
- DWORD dwHlslCompilandEnvTargetID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateTarget>>(dwHlslCompilandID, &dwHlslCompilandEnvTargetID));
- DXASSERT_ARGS(dwHlslCompilandEnvTargetID == HlslCompilandEnvTargetId,
- "%d vs %d",
- dwHlslCompilandEnvTargetID,
- HlslCompilandEnvTargetId);
- DWORD dwHlslCompilandEnvEntryID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateEntry>>(dwHlslCompilandID, &dwHlslCompilandEnvEntryID));
- DXASSERT_ARGS(dwHlslCompilandEnvEntryID == HlslCompilandEnvEntryId,
- "%d vs %d",
- dwHlslCompilandEnvEntryID,
- HlslCompilandEnvEntryId);
- DWORD dwHlslCompilandEnvDefinesID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateDefines>>(dwHlslCompilandID, &dwHlslCompilandEnvDefinesID));
- DXASSERT_ARGS(dwHlslCompilandEnvDefinesID == HlslCompilandEnvDefinesId,
- "%d vs %d",
- dwHlslCompilandEnvDefinesID,
- HlslCompilandEnvDefinesId);
- DWORD dwHlslCompilandEnvArgumentsID;
- IFT(SMI.AddSymbol<hlsl_symbols::symbol_factory::CompilandEnv<hlsl_symbols::CompilandEnvSymbol::CreateArguments>>(dwHlslCompilandID, &dwHlslCompilandEnvArgumentsID));
- DXASSERT_ARGS(dwHlslCompilandEnvArgumentsID == HlslCompilandEnvArgumentsId,
- "%d vs %d",
- dwHlslCompilandEnvArgumentsID,
- HlslCompilandEnvArgumentsId);
- IFT(SMI.CreateFunctionsForAllCUs());
- IFT(SMI.CreateGlobalVariablesForAllCUs());
- IFT(SMI.CreateLocalVariables());
- IFT(SMI.CreateLiveRanges());
- IFT(SMI.PopulateParentToChildrenIDMap(&m_parentToChildren));
- }
- HRESULT dxil_dia::SymbolManager::GetSymbolByID(size_t id, Symbol **ppSym) const {
- if (ppSym == nullptr) {
- return E_INVALIDARG;
- }
- *ppSym = nullptr;
- if (m_pSession == nullptr) {
- return E_FAIL;
- }
- if (id <= 0) {
- return E_INVALIDARG;
- }
- if (id > m_symbolCtors.size()) {
- return S_FALSE;
- }
- DxcThreadMalloc TM(m_pSession->GetMallocNoRef());
- IFR(m_symbolCtors[id - 1]->Create(m_pSession, ppSym));
- return S_OK;
- }
- HRESULT dxil_dia::SymbolManager::GetLiveRangeOf(Symbol *pSym, LiveRange *LR) const {
- const DWORD dwSymID = pSym->GetID();
- if (dwSymID <= 0 || dwSymID > m_symbolCtors.size()) {
- return E_INVALIDARG;
- }
- auto symIt = m_symbolToLiveRange.find(dwSymID);
- if (symIt == m_symbolToLiveRange.end()) {
- return S_FALSE;
- }
- *LR = symIt->second;
- return S_OK;
- }
- HRESULT dxil_dia::SymbolManager::GetGlobalScope(Symbol **ppSym) const {
- return GetSymbolByID(HlslProgramId, ppSym);
- }
- HRESULT dxil_dia::SymbolManager::ChildrenOf(DWORD ID, std::vector<CComPtr<Symbol>> *pChildren) const {
- pChildren->clear();
- auto childrenList = m_parentToChildren.equal_range(ID);
- for (auto it = childrenList.first; it != childrenList.second; ++it) {
- CComPtr<Symbol> Child;
- IFR(GetSymbolByID(it->second, &Child));
- pChildren->emplace_back(Child);
- }
- return S_OK;
- }
- HRESULT dxil_dia::SymbolManager::ChildrenOf(Symbol *pSym, std::vector<CComPtr<Symbol>> *pChildren) const {
- const std::uint32_t pSymID = pSym->GetID();
- IFR(ChildrenOf(pSymID, pChildren));
- return S_OK;
- }
- HRESULT dxil_dia::SymbolManager::DbgScopeOf(const llvm::Instruction *instr, SymbolChildrenEnumerator **ppRet) const {
- *ppRet = nullptr;
- const llvm::DebugLoc &DL = instr->getDebugLoc();
- if (!DL) {
- return S_FALSE;
- }
- llvm::MDNode *LocalScope = DL.getInlinedAtScope();
- if (LocalScope == nullptr) {
- LocalScope = DL.getScope();
- }
- if (LocalScope == nullptr) {
- return S_FALSE;
- }
- auto *LS = llvm::dyn_cast<llvm::DILocalScope>(LocalScope);
- if (LS == nullptr) {
- // This is a failure as instructions should always live in a DILocalScope
- return E_FAIL;
- }
- auto scopeIt = m_scopeToID.find(LS);
- if (scopeIt == m_scopeToID.end()) {
- // This is a failure because all scopes should already exist in the symbol manager.
- return E_FAIL;
- }
- CComPtr<SymbolChildrenEnumerator> ret = SymbolChildrenEnumerator::Alloc(m_pSession->GetMallocNoRef());
- if (!ret) {
- return E_OUTOFMEMORY;
- }
- CComPtr<Symbol> s;
- IFR(GetSymbolByID(scopeIt->second, &s));
- std::vector<CComPtr<Symbol>> children{s};
- ret->Init(std::move(children));
- *ppRet = ret.Detach();
- return S_OK;
- }
|