1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2019 The SwiftShader Authors. All Rights Reserved. 2*03ce13f7SAndroid Build Coastguard Worker // 3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); 4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License. 5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at 6*03ce13f7SAndroid Build Coastguard Worker // 7*03ce13f7SAndroid Build Coastguard Worker // http://www.apache.org/licenses/LICENSE-2.0 8*03ce13f7SAndroid Build Coastguard Worker // 9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software 10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, 11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and 13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License. 14*03ce13f7SAndroid Build Coastguard Worker 15*03ce13f7SAndroid Build Coastguard Worker #ifndef rr_LLVMReactorDebugInfo_hpp 16*03ce13f7SAndroid Build Coastguard Worker #define rr_LLVMReactorDebugInfo_hpp 17*03ce13f7SAndroid Build Coastguard Worker 18*03ce13f7SAndroid Build Coastguard Worker #include "Reactor.hpp" 19*03ce13f7SAndroid Build Coastguard Worker #include "ReactorDebugInfo.hpp" 20*03ce13f7SAndroid Build Coastguard Worker 21*03ce13f7SAndroid Build Coastguard Worker #ifdef ENABLE_RR_DEBUG_INFO 22*03ce13f7SAndroid Build Coastguard Worker 23*03ce13f7SAndroid Build Coastguard Worker # include <memory> 24*03ce13f7SAndroid Build Coastguard Worker # include <unordered_map> 25*03ce13f7SAndroid Build Coastguard Worker # include <unordered_set> 26*03ce13f7SAndroid Build Coastguard Worker # include <vector> 27*03ce13f7SAndroid Build Coastguard Worker 28*03ce13f7SAndroid Build Coastguard Worker // Forward declarations 29*03ce13f7SAndroid Build Coastguard Worker namespace llvm { 30*03ce13f7SAndroid Build Coastguard Worker 31*03ce13f7SAndroid Build Coastguard Worker class BasicBlock; 32*03ce13f7SAndroid Build Coastguard Worker class ConstantFolder; 33*03ce13f7SAndroid Build Coastguard Worker class DIBuilder; 34*03ce13f7SAndroid Build Coastguard Worker class DICompileUnit; 35*03ce13f7SAndroid Build Coastguard Worker class DIFile; 36*03ce13f7SAndroid Build Coastguard Worker class DILocation; 37*03ce13f7SAndroid Build Coastguard Worker class DIScope; 38*03ce13f7SAndroid Build Coastguard Worker class DISubprogram; 39*03ce13f7SAndroid Build Coastguard Worker class DIType; 40*03ce13f7SAndroid Build Coastguard Worker class Function; 41*03ce13f7SAndroid Build Coastguard Worker class Instruction; 42*03ce13f7SAndroid Build Coastguard Worker class IRBuilderDefaultInserter; 43*03ce13f7SAndroid Build Coastguard Worker class JITEventListener; 44*03ce13f7SAndroid Build Coastguard Worker class LLVMContext; 45*03ce13f7SAndroid Build Coastguard Worker class LoadedObjectInfo; 46*03ce13f7SAndroid Build Coastguard Worker class Module; 47*03ce13f7SAndroid Build Coastguard Worker class Type; 48*03ce13f7SAndroid Build Coastguard Worker class Value; 49*03ce13f7SAndroid Build Coastguard Worker 50*03ce13f7SAndroid Build Coastguard Worker namespace object { 51*03ce13f7SAndroid Build Coastguard Worker class ObjectFile; 52*03ce13f7SAndroid Build Coastguard Worker } 53*03ce13f7SAndroid Build Coastguard Worker 54*03ce13f7SAndroid Build Coastguard Worker template<typename T, typename Inserter> 55*03ce13f7SAndroid Build Coastguard Worker class IRBuilder; 56*03ce13f7SAndroid Build Coastguard Worker 57*03ce13f7SAndroid Build Coastguard Worker } // namespace llvm 58*03ce13f7SAndroid Build Coastguard Worker 59*03ce13f7SAndroid Build Coastguard Worker namespace rr { 60*03ce13f7SAndroid Build Coastguard Worker 61*03ce13f7SAndroid Build Coastguard Worker class Type; 62*03ce13f7SAndroid Build Coastguard Worker class Value; 63*03ce13f7SAndroid Build Coastguard Worker 64*03ce13f7SAndroid Build Coastguard Worker // DebugInfo generates LLVM DebugInfo IR from the C++ source that calls 65*03ce13f7SAndroid Build Coastguard Worker // into Reactor functions. See docs/ReactorDebugInfo.mk for more information. 66*03ce13f7SAndroid Build Coastguard Worker class DebugInfo 67*03ce13f7SAndroid Build Coastguard Worker { 68*03ce13f7SAndroid Build Coastguard Worker public: 69*03ce13f7SAndroid Build Coastguard Worker using IRBuilder = llvm::IRBuilder<llvm::ConstantFolder, llvm::IRBuilderDefaultInserter>; 70*03ce13f7SAndroid Build Coastguard Worker 71*03ce13f7SAndroid Build Coastguard Worker DebugInfo(IRBuilder *builder, 72*03ce13f7SAndroid Build Coastguard Worker llvm::LLVMContext *context, 73*03ce13f7SAndroid Build Coastguard Worker llvm::Module *module, 74*03ce13f7SAndroid Build Coastguard Worker llvm::Function *function); 75*03ce13f7SAndroid Build Coastguard Worker 76*03ce13f7SAndroid Build Coastguard Worker ~DebugInfo(); 77*03ce13f7SAndroid Build Coastguard Worker 78*03ce13f7SAndroid Build Coastguard Worker // Finalize debug info generation. Must be called before the LLVM module 79*03ce13f7SAndroid Build Coastguard Worker // is built. 80*03ce13f7SAndroid Build Coastguard Worker void Finalize(); 81*03ce13f7SAndroid Build Coastguard Worker 82*03ce13f7SAndroid Build Coastguard Worker // Updates the current source location. 83*03ce13f7SAndroid Build Coastguard Worker void EmitLocation(); 84*03ce13f7SAndroid Build Coastguard Worker 85*03ce13f7SAndroid Build Coastguard Worker // Binds the value to its symbol in the source file. 86*03ce13f7SAndroid Build Coastguard Worker // See docs/ReactorDebugInfo.mk for more information. 87*03ce13f7SAndroid Build Coastguard Worker void EmitVariable(Value *value); 88*03ce13f7SAndroid Build Coastguard Worker 89*03ce13f7SAndroid Build Coastguard Worker // Forcefully flush the binding of the last variable name. 90*03ce13f7SAndroid Build Coastguard Worker // Used for binding the initializer of `For` loops. 91*03ce13f7SAndroid Build Coastguard Worker void Flush(); 92*03ce13f7SAndroid Build Coastguard Worker 93*03ce13f7SAndroid Build Coastguard Worker // NotifyObjectEmitted informs any attached debuggers of the JIT'd 94*03ce13f7SAndroid Build Coastguard Worker // object. 95*03ce13f7SAndroid Build Coastguard Worker static void NotifyObjectEmitted(uint64_t key, const llvm::object::ObjectFile &obj, const llvm::LoadedObjectInfo &l); 96*03ce13f7SAndroid Build Coastguard Worker 97*03ce13f7SAndroid Build Coastguard Worker // NotifyFreeingObject informs any attached debuggers that the JIT'd 98*03ce13f7SAndroid Build Coastguard Worker // object is now invalid. 99*03ce13f7SAndroid Build Coastguard Worker static void NotifyFreeingObject(uint64_t key); 100*03ce13f7SAndroid Build Coastguard Worker 101*03ce13f7SAndroid Build Coastguard Worker private: 102*03ce13f7SAndroid Build Coastguard Worker struct Token 103*03ce13f7SAndroid Build Coastguard Worker { 104*03ce13f7SAndroid Build Coastguard Worker enum Kind 105*03ce13f7SAndroid Build Coastguard Worker { 106*03ce13f7SAndroid Build Coastguard Worker Identifier, 107*03ce13f7SAndroid Build Coastguard Worker Return 108*03ce13f7SAndroid Build Coastguard Worker }; 109*03ce13f7SAndroid Build Coastguard Worker Kind kind; 110*03ce13f7SAndroid Build Coastguard Worker std::string identifier; 111*03ce13f7SAndroid Build Coastguard Worker }; 112*03ce13f7SAndroid Build Coastguard Worker 113*03ce13f7SAndroid Build Coastguard Worker using LineTokens = std::unordered_map<unsigned int, Token>; 114*03ce13f7SAndroid Build Coastguard Worker 115*03ce13f7SAndroid Build Coastguard Worker struct Pending 116*03ce13f7SAndroid Build Coastguard Worker { 117*03ce13f7SAndroid Build Coastguard Worker std::string name; 118*03ce13f7SAndroid Build Coastguard Worker Location location; 119*03ce13f7SAndroid Build Coastguard Worker llvm::DILocation *diLocation = nullptr; 120*03ce13f7SAndroid Build Coastguard Worker llvm::Value *value = nullptr; 121*03ce13f7SAndroid Build Coastguard Worker llvm::Instruction *insertAfter = nullptr; 122*03ce13f7SAndroid Build Coastguard Worker llvm::BasicBlock *block = nullptr; 123*03ce13f7SAndroid Build Coastguard Worker llvm::DIScope *scope = nullptr; 124*03ce13f7SAndroid Build Coastguard Worker bool addNopOnNextLine = false; 125*03ce13f7SAndroid Build Coastguard Worker }; 126*03ce13f7SAndroid Build Coastguard Worker 127*03ce13f7SAndroid Build Coastguard Worker struct Scope 128*03ce13f7SAndroid Build Coastguard Worker { 129*03ce13f7SAndroid Build Coastguard Worker Location location; 130*03ce13f7SAndroid Build Coastguard Worker llvm::DIScope *di; 131*03ce13f7SAndroid Build Coastguard Worker std::unordered_set<std::string> symbols; 132*03ce13f7SAndroid Build Coastguard Worker Pending pending; 133*03ce13f7SAndroid Build Coastguard Worker }; 134*03ce13f7SAndroid Build Coastguard Worker 135*03ce13f7SAndroid Build Coastguard Worker void registerBasicTypes(); 136*03ce13f7SAndroid Build Coastguard Worker 137*03ce13f7SAndroid Build Coastguard Worker void emitPending(Scope &scope, IRBuilder *builder); 138*03ce13f7SAndroid Build Coastguard Worker 139*03ce13f7SAndroid Build Coastguard Worker // Returns the source location of the non-Reactor calling function. 140*03ce13f7SAndroid Build Coastguard Worker Location getCallerLocation() const; 141*03ce13f7SAndroid Build Coastguard Worker 142*03ce13f7SAndroid Build Coastguard Worker // Returns the backtrace for the callstack, starting at the first 143*03ce13f7SAndroid Build Coastguard Worker // non-Reactor file. If limit is non-zero, then a maximum of limit 144*03ce13f7SAndroid Build Coastguard Worker // frames will be returned. 145*03ce13f7SAndroid Build Coastguard Worker Backtrace getCallerBacktrace(size_t limit = 0) const; 146*03ce13f7SAndroid Build Coastguard Worker 147*03ce13f7SAndroid Build Coastguard Worker llvm::DILocation *getLocation(const Backtrace &backtrace, size_t i); 148*03ce13f7SAndroid Build Coastguard Worker 149*03ce13f7SAndroid Build Coastguard Worker llvm::DIType *getOrCreateType(llvm::Type *type); 150*03ce13f7SAndroid Build Coastguard Worker llvm::DIFile *getOrCreateFile(const char *path); 151*03ce13f7SAndroid Build Coastguard Worker const LineTokens *getOrParseFileTokens(const char *path); 152*03ce13f7SAndroid Build Coastguard Worker 153*03ce13f7SAndroid Build Coastguard Worker // Synchronizes diScope with the current backtrace. 154*03ce13f7SAndroid Build Coastguard Worker void syncScope(const Backtrace &backtrace); 155*03ce13f7SAndroid Build Coastguard Worker 156*03ce13f7SAndroid Build Coastguard Worker IRBuilder *builder; 157*03ce13f7SAndroid Build Coastguard Worker llvm::LLVMContext *context; 158*03ce13f7SAndroid Build Coastguard Worker llvm::Module *module; 159*03ce13f7SAndroid Build Coastguard Worker llvm::Function *function; 160*03ce13f7SAndroid Build Coastguard Worker 161*03ce13f7SAndroid Build Coastguard Worker std::unique_ptr<llvm::DIBuilder> diBuilder; 162*03ce13f7SAndroid Build Coastguard Worker llvm::DICompileUnit *diCU; 163*03ce13f7SAndroid Build Coastguard Worker llvm::DISubprogram *diSubprogram; 164*03ce13f7SAndroid Build Coastguard Worker llvm::DILocation *diRootLocation; 165*03ce13f7SAndroid Build Coastguard Worker std::vector<Scope> diScope; 166*03ce13f7SAndroid Build Coastguard Worker std::unordered_map<std::string, llvm::DIFile *> diFiles; 167*03ce13f7SAndroid Build Coastguard Worker std::unordered_map<llvm::Type *, llvm::DIType *> diTypes; 168*03ce13f7SAndroid Build Coastguard Worker std::unordered_map<std::string, std::unique_ptr<LineTokens>> fileTokens; 169*03ce13f7SAndroid Build Coastguard Worker std::vector<const void *> pushed; 170*03ce13f7SAndroid Build Coastguard Worker }; 171*03ce13f7SAndroid Build Coastguard Worker 172*03ce13f7SAndroid Build Coastguard Worker } // namespace rr 173*03ce13f7SAndroid Build Coastguard Worker 174*03ce13f7SAndroid Build Coastguard Worker #endif // ENABLE_RR_DEBUG_INFO 175*03ce13f7SAndroid Build Coastguard Worker 176*03ce13f7SAndroid Build Coastguard Worker #endif // rr_LLVMReactorDebugInfo_hpp 177