1 //===- SPIRVToLLVMDbgTran.h - Converts SPIR-V DebugInfo to LLVM -*- C++ -*-===// 2 // 3 // The LLVM/SPIR-V Translator 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 // Copyright (c) 2018 Intel Corporation. All rights reserved. 9 // 10 // Permission is hereby granted, free of charge, to any person obtaining a 11 // copy of this software and associated documentation files (the "Software"), 12 // to deal with the Software without restriction, including without limitation 13 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 14 // and/or sell copies of the Software, and to permit persons to whom the 15 // Software is furnished to do so, subject to the following conditions: 16 // 17 // Redistributions of source code must retain the above copyright notice, 18 // this list of conditions and the following disclaimers. 19 // Redistributions in binary form must reproduce the above copyright notice, 20 // this list of conditions and the following disclaimers in the documentation 21 // and/or other materials provided with the distribution. 22 // Neither the names of Intel Corporation, nor the names of its 23 // contributors may be used to endorse or promote products derived from this 24 // Software without specific prior written permission. 25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH 31 // THE SOFTWARE. 32 // 33 //===----------------------------------------------------------------------===// 34 // 35 // This file implements translation of debug info from SPIR-V to LLVM metadata 36 // 37 //===----------------------------------------------------------------------===// 38 39 #ifndef SPIRVTOLLVMDBGTRAN_H 40 #define SPIRVTOLLVMDBGTRAN_H 41 42 #include "SPIRVInstruction.h" 43 44 #include "llvm/IR/DIBuilder.h" 45 #include "llvm/IR/DebugLoc.h" 46 47 #include <unordered_map> 48 49 namespace llvm { 50 class Module; 51 class Value; 52 class Instruction; 53 class Type; 54 } // namespace llvm 55 using namespace llvm; 56 57 namespace SPIRV { 58 class SPIRVToLLVM; 59 class SPIRVEntry; 60 class SPIRVFunction; 61 class SPIRVValue; 62 63 class SPIRVToLLVMDbgTran { 64 public: 65 typedef std::vector<SPIRVWord> SPIRVWordVec; 66 67 SPIRVToLLVMDbgTran(SPIRVModule *TBM, Module *TM, SPIRVToLLVM *Reader); 68 void addDbgInfoVersion(); 69 void transDbgInfo(const SPIRVValue *SV, Value *V); 70 template <typename T = MDNode> transDebugInst(const SPIRVExtInst * DebugInst)71 T *transDebugInst(const SPIRVExtInst *DebugInst) { 72 assert((DebugInst->getExtSetKind() == SPIRVEIS_Debug || 73 DebugInst->getExtSetKind() == SPIRVEIS_OpenCL_DebugInfo_100) && 74 "Unexpected extended instruction set"); 75 auto It = DebugInstCache.find(DebugInst); 76 if (It != DebugInstCache.end()) 77 return static_cast<T *>(It->second); 78 MDNode *Res = transDebugInstImpl(DebugInst); 79 DebugInstCache[DebugInst] = Res; 80 return static_cast<T *>(Res); 81 } 82 Instruction *transDebugIntrinsic(const SPIRVExtInst *DebugInst, 83 BasicBlock *BB); 84 void finalize(); 85 86 private: 87 DIFile *getFile(const SPIRVId SourceId); 88 DIFile *getDIFile(const std::string &FileName, 89 Optional<DIFile::ChecksumInfo<StringRef>> CS = None); 90 DIFile *getDIFile(const SPIRVEntry *E); 91 unsigned getLineNo(const SPIRVEntry *E); 92 93 MDNode *transDebugInstImpl(const SPIRVExtInst *DebugInst); 94 95 llvm::DebugLoc transDebugLocation(const SPIRVExtInst *DebugInst); 96 97 llvm::DebugLoc transDebugScope(const SPIRVInstruction *Inst); 98 99 MDNode *transDebugInlined(const SPIRVExtInst *Inst); 100 101 DICompileUnit *transCompileUnit(const SPIRVExtInst *DebugInst); 102 103 DIBasicType *transTypeBasic(const SPIRVExtInst *DebugInst); 104 105 DIDerivedType *transTypeQualifier(const SPIRVExtInst *DebugInst); 106 107 DIType *transTypePointer(const SPIRVExtInst *DebugInst); 108 109 DICompositeType *transTypeArray(const SPIRVExtInst *DebugInst); 110 111 DICompositeType *transTypeVector(const SPIRVExtInst *DebugInst); 112 113 DICompositeType *transTypeComposite(const SPIRVExtInst *DebugInst); 114 115 DINode *transTypeMember(const SPIRVExtInst *DebugInst); 116 117 DINode *transTypeEnum(const SPIRVExtInst *DebugInst); 118 119 DINode *transTemplateParameter(const SPIRVExtInst *DebugInst); 120 DINode *transTemplateTemplateParameter(const SPIRVExtInst *DebugInst); 121 DINode *transTemplateParameterPack(const SPIRVExtInst *DebugInst); 122 123 MDNode *transTemplate(const SPIRVExtInst *DebugInst); 124 125 DINode *transTypeFunction(const SPIRVExtInst *DebugInst); 126 127 DINode *transTypePtrToMember(const SPIRVExtInst *DebugInst); 128 129 DINode *transLexicalBlock(const SPIRVExtInst *DebugInst); 130 DINode *transLexicalBlockDiscriminator(const SPIRVExtInst *DebugInst); 131 132 DINode *transFunction(const SPIRVExtInst *DebugInst); 133 134 DINode *transFunctionDecl(const SPIRVExtInst *DebugInst); 135 136 MDNode *transGlobalVariable(const SPIRVExtInst *DebugInst); 137 138 DINode *transLocalVariable(const SPIRVExtInst *DebugInst); 139 140 DINode *transTypedef(const SPIRVExtInst *DebugInst); 141 142 DINode *transInheritance(const SPIRVExtInst *DebugInst); 143 144 DINode *transImportedEntry(const SPIRVExtInst *DebugInst); 145 146 DINode *transModule(const SPIRVExtInst *DebugInst); 147 148 MDNode *transExpression(const SPIRVExtInst *DebugInst); 149 150 SPIRVModule *BM; 151 Module *M; 152 DIBuilder Builder; 153 SPIRVToLLVM *SPIRVReader; 154 DICompileUnit *CU; 155 bool Enable; 156 std::unordered_map<std::string, DIFile *> FileMap; 157 std::unordered_map<SPIRVId, DISubprogram *> FuncMap; 158 std::unordered_map<const SPIRVExtInst *, MDNode *> DebugInstCache; 159 160 struct SplitFileName { 161 SplitFileName(const std::string &FileName); 162 std::string BaseName; 163 std::string Path; 164 }; 165 166 DIScope *getScope(const SPIRVEntry *ScopeInst); 167 SPIRVExtInst *getDbgInst(const SPIRVId Id); 168 getDbgInst(const SPIRVId Id)169 template <SPIRVWord OpCode> SPIRVExtInst *getDbgInst(const SPIRVId Id) { 170 if (SPIRVExtInst *DI = getDbgInst(Id)) { 171 if (DI->getExtOp() == OpCode) { 172 return DI; 173 } 174 } 175 return nullptr; 176 } 177 const std::string &getString(const SPIRVId Id); 178 std::string findModuleProducer(); 179 Optional<DIFile::ChecksumInfo<StringRef>> ParseChecksum(StringRef Text); 180 }; 181 } // namespace SPIRV 182 183 #endif // SPIRVTOLLVMDBGTRAN_H 184