xref: /aosp_15_r20/external/swiftshader/src/Reactor/LLVMReactorDebugInfo.hpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
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