|
12 | 12 | #include <array> |
13 | 13 |
|
14 | 14 | #include "dxc/DXIL/DxilShaderModel.h" |
| 15 | +#include "clang/AST/DeclTemplate.h" |
15 | 16 | #include "clang/Frontend/FrontendAction.h" |
16 | 17 | #include "clang/SPIRV/SpirvInstruction.h" |
17 | 18 | #include "clang/SPIRV/SpirvType.h" |
18 | 19 | #include "llvm/ADT/DenseMap.h" |
19 | 20 | #include "llvm/ADT/DenseMapInfo.h" |
| 21 | +#include "llvm/ADT/MapVector.h" |
| 22 | +#include "llvm/ADT/StringMap.h" |
20 | 23 | #include "llvm/Support/Allocator.h" |
21 | 24 |
|
22 | 25 | namespace clang { |
23 | 26 | namespace spirv { |
24 | 27 |
|
| 28 | +class SpirvModule; |
| 29 | + |
| 30 | +struct RichDebugInfo { |
| 31 | + RichDebugInfo(SpirvDebugSource *src, SpirvDebugCompilationUnit *cu) |
| 32 | + : source(src), compilationUnit(cu) { |
| 33 | + scopeStack.push_back(cu); |
| 34 | + } |
| 35 | + RichDebugInfo() : source(nullptr), compilationUnit(nullptr), scopeStack() {} |
| 36 | + |
| 37 | + // The HLL source code |
| 38 | + SpirvDebugSource *source; |
| 39 | + |
| 40 | + // The compilation unit (topmost debug info node) |
| 41 | + SpirvDebugCompilationUnit *compilationUnit; |
| 42 | + |
| 43 | + // Stack of lexical scopes |
| 44 | + std::vector<SpirvDebugInstruction *> scopeStack; |
| 45 | +}; |
| 46 | + |
25 | 47 | // Provides DenseMapInfo for spv::StorageClass so that we can use |
26 | 48 | // spv::StorageClass as key to DenseMap. |
27 | 49 | // |
@@ -139,10 +161,66 @@ class SpirvContext { |
139 | 161 | /// Deallocates the memory pointed by the given pointer. |
140 | 162 | void deallocate(void *ptr) const {} |
141 | 163 |
|
| 164 | + // === DebugTypes === |
| 165 | + |
| 166 | + // TODO: Replace uint32_t with an enum for encoding. |
| 167 | + SpirvDebugType *getDebugTypeBasic(const SpirvType *spirvType, |
| 168 | + llvm::StringRef name, SpirvConstant *size, |
| 169 | + uint32_t encoding); |
| 170 | + |
| 171 | + SpirvDebugType *getDebugTypeMember(llvm::StringRef name, SpirvDebugType *type, |
| 172 | + SpirvDebugSource *source, uint32_t line, |
| 173 | + uint32_t column, |
| 174 | + SpirvDebugInstruction *parent, |
| 175 | + uint32_t flags, uint32_t offsetInBits, |
| 176 | + uint32_t sizeInBits, const APValue *value); |
| 177 | + |
| 178 | + SpirvDebugTypeComposite *getDebugTypeComposite(const SpirvType *spirvType, |
| 179 | + llvm::StringRef name, |
| 180 | + SpirvDebugSource *source, |
| 181 | + uint32_t line, uint32_t column, |
| 182 | + SpirvDebugInstruction *parent, |
| 183 | + llvm::StringRef linkageName, |
| 184 | + uint32_t flags, uint32_t tag); |
| 185 | + |
| 186 | + SpirvDebugType *getDebugType(const SpirvType *spirvType); |
| 187 | + |
| 188 | + SpirvDebugType *getDebugTypeArray(const SpirvType *spirvType, |
| 189 | + SpirvDebugInstruction *elemType, |
| 190 | + llvm::ArrayRef<uint32_t> elemCount); |
| 191 | + |
| 192 | + SpirvDebugType *getDebugTypeVector(const SpirvType *spirvType, |
| 193 | + SpirvDebugInstruction *elemType, |
| 194 | + uint32_t elemCount); |
| 195 | + |
| 196 | + SpirvDebugType *getDebugTypeFunction(const SpirvType *spirvType, |
| 197 | + uint32_t flags, SpirvDebugType *ret, |
| 198 | + llvm::ArrayRef<SpirvDebugType *> params); |
| 199 | + |
| 200 | + SpirvDebugTypeTemplate *createDebugTypeTemplate( |
| 201 | + const ClassTemplateSpecializationDecl *templateType, |
| 202 | + SpirvDebugInstruction *target, |
| 203 | + const llvm::SmallVector<SpirvDebugTypeTemplateParameter *, 2> ¶ms); |
| 204 | + |
| 205 | + SpirvDebugTypeTemplate * |
| 206 | + getDebugTypeTemplate(const ClassTemplateSpecializationDecl *templateType); |
| 207 | + |
| 208 | + SpirvDebugTypeTemplateParameter *createDebugTypeTemplateParameter( |
| 209 | + const TemplateArgument *templateArg, llvm::StringRef name, |
| 210 | + SpirvDebugType *type, SpirvInstruction *value, SpirvDebugSource *source, |
| 211 | + uint32_t line, uint32_t column); |
| 212 | + |
| 213 | + SpirvDebugTypeTemplateParameter * |
| 214 | + getDebugTypeTemplateParameter(const TemplateArgument *templateArg); |
| 215 | + |
| 216 | + // Moves all debug type instructions to module and makes the data structures |
| 217 | + // that contain the debug type instructions empty. After calling this method, |
| 218 | + // module will have the ownership of debug type instructions. |
| 219 | + void moveDebugTypesToModule(SpirvModule *module); |
| 220 | + |
142 | 221 | // === Types === |
143 | 222 |
|
144 | 223 | const VoidType *getVoidType() const { return voidType; } |
145 | | - |
146 | 224 | const BoolType *getBoolType() const { return boolType; } |
147 | 225 | const IntegerType *getSIntType(uint32_t bitwidth); |
148 | 226 | const IntegerType *getUIntType(uint32_t bitwidth); |
@@ -237,6 +315,47 @@ class SpirvContext { |
237 | 315 | return curShaderModelKind == ShaderModelKind::Amplification; |
238 | 316 | } |
239 | 317 |
|
| 318 | + /// Function to get all RichDebugInfo (i.e., the current status of |
| 319 | + /// compilation units). |
| 320 | + llvm::StringMap<RichDebugInfo> &getDebugInfo() { return debugInfo; } |
| 321 | + |
| 322 | + /// Function to let the lexical scope stack grow when it enters a |
| 323 | + /// new lexical scope. |
| 324 | + void pushDebugLexicalScope(RichDebugInfo *info, SpirvDebugInstruction *scope); |
| 325 | + |
| 326 | + /// Function to pop the last element from the lexical scope stack. |
| 327 | + void popDebugLexicalScope(RichDebugInfo *info) { |
| 328 | + info->scopeStack.pop_back(); |
| 329 | + currentLexicalScope = info->scopeStack.back(); |
| 330 | + } |
| 331 | + |
| 332 | + /// Function to get the last lexical scope that the SpirvEmitter |
| 333 | + /// class instance entered. |
| 334 | + SpirvDebugInstruction *getCurrentLexicalScope() { |
| 335 | + return currentLexicalScope; |
| 336 | + } |
| 337 | + |
| 338 | + /// Function to add/get the mapping from a SPIR-V type to its Decl for |
| 339 | + /// a struct type. |
| 340 | + void registerStructDeclForSpirvType(const SpirvType *spvTy, |
| 341 | + const DeclContext *decl) { |
| 342 | + assert(spvTy != nullptr && decl != nullptr); |
| 343 | + spvStructTypeToDecl[spvTy] = decl; |
| 344 | + } |
| 345 | + const DeclContext *getStructDeclForSpirvType(const SpirvType *spvTy) { |
| 346 | + return spvStructTypeToDecl[spvTy]; |
| 347 | + } |
| 348 | + |
| 349 | + /// Function to add/get the mapping from a FunctionDecl to its DebugFunction. |
| 350 | + void registerDebugFunctionForDecl(const FunctionDecl *decl, |
| 351 | + SpirvDebugFunction *fn) { |
| 352 | + assert(decl != nullptr && fn != nullptr); |
| 353 | + declToDebugFunction[decl] = fn; |
| 354 | + } |
| 355 | + SpirvDebugFunction *getDebugFunctionForDecl(const FunctionDecl *decl) { |
| 356 | + return declToDebugFunction[decl]; |
| 357 | + } |
| 358 | + |
240 | 359 | private: |
241 | 360 | /// \brief The allocator used to create SPIR-V entity objects. |
242 | 361 | /// |
@@ -294,6 +413,35 @@ class SpirvContext { |
294 | 413 | // Major/Minor hlsl profile version. |
295 | 414 | uint32_t majorVersion; |
296 | 415 | uint32_t minorVersion; |
| 416 | + |
| 417 | + /// File name to rich debug info map. When the main source file |
| 418 | + /// includes header files, we create an element of debugInfo for |
| 419 | + /// each file. RichDebugInfo includes DebugSource, |
| 420 | + /// DebugCompilationUnit and scopeStack which keeps lexical scopes |
| 421 | + /// recursively. |
| 422 | + llvm::StringMap<RichDebugInfo> debugInfo; |
| 423 | + SpirvDebugInstruction *currentLexicalScope; |
| 424 | + |
| 425 | + // Mapping from SPIR-V type to debug type instruction. |
| 426 | + // The purpose is not to generate several DebugType* instructions for the same |
| 427 | + // type if the type is used for several variables. |
| 428 | + llvm::MapVector<const SpirvType *, SpirvDebugType *> debugTypes; |
| 429 | + |
| 430 | + // Mapping from template decl to DebugTypeTemplate. |
| 431 | + llvm::MapVector<const ClassTemplateSpecializationDecl *, |
| 432 | + SpirvDebugTypeTemplate *> |
| 433 | + typeTemplates; |
| 434 | + |
| 435 | + // Mapping from template parameter decl to DebugTypeTemplateParameter. |
| 436 | + llvm::MapVector<const TemplateArgument *, SpirvDebugTypeTemplateParameter *> |
| 437 | + typeTemplateParams; |
| 438 | + |
| 439 | + // Mapping from SPIR-V type to Decl for a struct type. |
| 440 | + llvm::DenseMap<const SpirvType *, const DeclContext *> spvStructTypeToDecl; |
| 441 | + |
| 442 | + // Mapping from FunctionDecl to SPIR-V debug function. |
| 443 | + llvm::DenseMap<const FunctionDecl *, SpirvDebugFunction *> |
| 444 | + declToDebugFunction; |
297 | 445 | }; |
298 | 446 |
|
299 | 447 | } // end namespace spirv |
|
0 commit comments