| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209 |
- ///////////////////////////////////////////////////////////////////////////////
- // //
- // DxcPixDxilDebugInfo.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. //
- // //
- // Defines the main class for dxcompiler's API for PIX support. //
- // //
- ///////////////////////////////////////////////////////////////////////////////
- #include "dxc/Support/WinIncludes.h"
- #include "dxc/Support/exception.h"
- #include "llvm/IR/Instructions.h"
- #include "llvm/IR/DebugInfo.h"
- #include "llvm/IR/DebugInfoMetadata.h"
- #include "DxcPixLiveVariables.h"
- #include "DxcPixDxilDebugInfo.h"
- #include "DxcPixBase.h"
- #include "dxc/DxilPixPasses/DxilPixVirtualRegisters.h"
- STDMETHODIMP dxil_debug_info::DxcPixDxilDebugInfo::GetLiveVariablesAt(
- _In_ DWORD InstructionOffset,
- _COM_Outptr_ IDxcPixDxilLiveVariables **ppLiveVariables)
- {
- return m_LiveVars->GetLiveVariablesAtInstruction(
- FindInstruction(InstructionOffset),
- ppLiveVariables);
- }
- STDMETHODIMP dxil_debug_info::DxcPixDxilDebugInfo::IsVariableInRegister(
- _In_ DWORD InstructionOffset,
- _In_ const wchar_t *VariableName)
- {
- return S_OK;
- }
- STDMETHODIMP dxil_debug_info::DxcPixDxilDebugInfo::GetFunctionName(
- _In_ DWORD InstructionOffset,
- _Outptr_result_z_ BSTR *ppFunctionName)
- {
- llvm::Instruction *IP = FindInstruction(InstructionOffset);
- const llvm::DITypeIdentifierMap EmptyMap;
- if (const llvm::DebugLoc &DL = IP->getDebugLoc())
- {
- auto *S = llvm::dyn_cast<llvm::DIScope>(DL.getScope());
- while(S != nullptr && !llvm::isa<llvm::DICompileUnit>(S))
- {
- if (auto *SS = llvm::dyn_cast<llvm::DISubprogram>(S))
- {
- *ppFunctionName = CComBSTR(CA2W(SS->getName().data())).Detach();
- return S_OK;
- }
- S = S->getScope().resolve(EmptyMap);
- }
- }
- *ppFunctionName = CComBSTR(L"<???>").Detach();
- return S_FALSE;
- }
- STDMETHODIMP dxil_debug_info::DxcPixDxilDebugInfo::GetStackDepth(
- _In_ DWORD InstructionOffset,
- _Outptr_ DWORD *StackDepth
- )
- {
- llvm::Instruction *IP = FindInstruction(InstructionOffset);
- DWORD Depth = 0;
- llvm::DebugLoc DL = IP->getDebugLoc();
- while (DL && DL.getInlinedAtScope() != nullptr)
- {
- DL = DL.getInlinedAt();
- ++Depth;
- }
- *StackDepth = Depth;
- return S_OK;
- }
- #include "DxilDiaSession.h"
- dxil_debug_info::DxcPixDxilDebugInfo::DxcPixDxilDebugInfo(
- IMalloc *pMalloc,
- dxil_dia::Session *pSession)
- : m_pMalloc(pMalloc)
- , m_pSession(pSession)
- , m_LiveVars(new LiveVariables())
- {
- m_LiveVars->Init(this);
- }
- dxil_debug_info::DxcPixDxilDebugInfo::~DxcPixDxilDebugInfo() = default;
- llvm::Module* dxil_debug_info::DxcPixDxilDebugInfo::GetModuleRef()
- {
- return &m_pSession->ModuleRef();
- }
- llvm::Instruction* dxil_debug_info::DxcPixDxilDebugInfo::FindInstruction(
- DWORD InstructionOffset
- ) const
- {
- const auto Instructions = m_pSession->InstructionsRef();
- auto it = Instructions.find(InstructionOffset);
- if (it == Instructions.end())
- {
- throw hlsl::Exception(E_BOUNDS, "Out-of-bounds: Instruction offset");
- }
- return const_cast<llvm::Instruction *>(it->second);
- }
- STDMETHODIMP
- dxil_debug_info::DxcPixDxilDebugInfo::InstructionOffsetsFromSourceLocation(
- _In_ const wchar_t *FileName, _In_ DWORD SourceLine,
- _In_ DWORD SourceColumn,
- _COM_Outptr_ IDxcPixDxilInstructionOffsets **ppOffsets)
- {
- return dxil_debug_info::NewDxcPixDxilDebugInfoObjectOrThrow<
- dxil_debug_info::DxcPixDxilInstructionOffsets>(
- ppOffsets, m_pMalloc, m_pSession, FileName, SourceLine, SourceColumn);
- }
- static bool CompareFilenames(const wchar_t * l, const char * r)
- {
- while (*l && *r) {
- bool theSame = false;
- if (*l == L'/' && *r == '\\') {
- theSame = true;
- }
- if (*l == L'\\' && *r == '/') {
- theSame = true;
- }
- if (!theSame) {
- if (::tolower(*l) != ::tolower(*r)) {
- return false;
- }
- }
- l++;
- r++;
- }
- if (*l || *r) {
- return false;
- }
- return true;
- }
- dxil_debug_info::DxcPixDxilInstructionOffsets::DxcPixDxilInstructionOffsets(
- IMalloc *pMalloc,
- dxil_dia::Session *pSession,
- const wchar_t *FileName,
- DWORD SourceLine,
- DWORD SourceColumn)
- {
- assert(SourceColumn == 0);
- (void)SourceColumn;
- auto files = pSession->Contents()->operands();
- for (const auto& file : files)
- {
- auto candidateFilename = llvm::dyn_cast<llvm::MDString>(file->getOperand(0))
- ->getString();
- if (CompareFilenames(FileName, candidateFilename.str().c_str()))
- {
- auto Fn = pSession->DxilModuleRef().GetEntryFunction();
- auto &Blocks = Fn->getBasicBlockList();
- for (auto& CurrentBlock : Blocks) {
- auto& Is = CurrentBlock.getInstList();
- for (auto& Inst : Is) {
- auto & debugLoc = Inst.getDebugLoc();
- if (debugLoc)
- {
- unsigned line = debugLoc.getLine();
- if (line == SourceLine)
- {
- std::uint32_t InstructionNumber;
- if (pix_dxil::PixDxilInstNum::FromInst(&Inst, &InstructionNumber))
- {
- m_offsets.push_back(InstructionNumber);
- }
- }
- }
- }
- }
- }
- }
- }
- DWORD dxil_debug_info::DxcPixDxilInstructionOffsets::GetCount()
- {
- return static_cast<DWORD>(m_offsets.size());
- }
- DWORD dxil_debug_info::DxcPixDxilInstructionOffsets::GetOffsetByIndex(DWORD Index)
- {
- if (Index < static_cast<DWORD>(m_offsets.size()))
- {
- return m_offsets[Index];
- }
- return static_cast<DWORD>(-1);
- }
|