Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/gallium/drivers/swr/rasterizer/jitter/JitManager.h
4574 views
1
/****************************************************************************
2
* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved.
3
*
4
* Permission is hereby granted, free of charge, to any person obtaining a
5
* copy of this software and associated documentation files (the "Software"),
6
* to deal in the Software without restriction, including without limitation
7
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
* and/or sell copies of the Software, and to permit persons to whom the
9
* Software is furnished to do so, subject to the following conditions:
10
*
11
* The above copyright notice and this permission notice (including the next
12
* paragraph) shall be included in all copies or substantial portions of the
13
* Software.
14
*
15
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21
* IN THE SOFTWARE.
22
*
23
* @file JitManager.h
24
*
25
* @brief JitManager contains the LLVM data structures used for JIT generation
26
*
27
* Notes:
28
*
29
******************************************************************************/
30
#pragma once
31
32
#include "jit_pch.hpp"
33
#include "common/isa.hpp"
34
#include <llvm/IR/AssemblyAnnotationWriter.h>
35
36
37
//////////////////////////////////////////////////////////////////////////
38
/// JitInstructionSet
39
/// @brief Subclass of InstructionSet that allows users to override
40
/// the reporting of support for certain ISA features. This allows capping
41
/// the jitted code to a certain feature level, e.g. jit AVX level code on
42
/// a platform that supports AVX2.
43
//////////////////////////////////////////////////////////////////////////
44
class JitInstructionSet : public InstructionSet
45
{
46
public:
47
JitInstructionSet(const char* requestedIsa) : isaRequest(requestedIsa)
48
{
49
std::transform(isaRequest.begin(), isaRequest.end(), isaRequest.begin(), ::tolower);
50
51
if (isaRequest == "avx")
52
{
53
bForceAVX = true;
54
bForceAVX2 = false;
55
bForceAVX512 = false;
56
}
57
else if (isaRequest == "avx2")
58
{
59
bForceAVX = false;
60
bForceAVX2 = true;
61
bForceAVX512 = false;
62
}
63
else if (isaRequest == "avx512")
64
{
65
bForceAVX = false;
66
bForceAVX2 = false;
67
bForceAVX512 = true;
68
}
69
};
70
71
bool AVX2(void) { return bForceAVX ? 0 : InstructionSet::AVX2(); }
72
bool AVX512F(void) { return (bForceAVX | bForceAVX2) ? 0 : InstructionSet::AVX512F(); }
73
bool AVX512ER(void) { return (bForceAVX | bForceAVX2) ? 0 : InstructionSet::AVX512ER(); }
74
bool BMI2(void) { return bForceAVX ? 0 : InstructionSet::BMI2(); }
75
76
private:
77
bool bForceAVX = false;
78
bool bForceAVX2 = false;
79
bool bForceAVX512 = false;
80
std::string isaRequest;
81
};
82
83
struct JitLLVMContext : llvm::LLVMContext
84
{
85
};
86
87
//////////////////////////////////////////////////////////////////////////
88
/// JitCache
89
//////////////////////////////////////////////////////////////////////////
90
struct JitManager; // Forward Decl
91
class JitCache : public llvm::ObjectCache
92
{
93
public:
94
/// constructor
95
JitCache();
96
virtual ~JitCache() {}
97
98
void Init(JitManager* pJitMgr, const llvm::StringRef& cpu, llvm::CodeGenOpt::Level level)
99
{
100
mCpu = cpu.str();
101
mpJitMgr = pJitMgr;
102
mOptLevel = level;
103
}
104
105
/// notifyObjectCompiled - Provides a pointer to compiled code for Module M.
106
void notifyObjectCompiled(const llvm::Module* M, llvm::MemoryBufferRef Obj) override;
107
108
/// Returns a pointer to a newly allocated MemoryBuffer that contains the
109
/// object which corresponds with Module M, or 0 if an object is not
110
/// available.
111
std::unique_ptr<llvm::MemoryBuffer> getObject(const llvm::Module* M) override;
112
113
const char* GetModuleCacheDir() { return mModuleCacheDir.c_str(); }
114
115
private:
116
std::string mCpu;
117
llvm::SmallString<MAX_PATH> mCacheDir;
118
llvm::SmallString<MAX_PATH> mModuleCacheDir;
119
uint32_t mCurrentModuleCRC = 0;
120
JitManager* mpJitMgr = nullptr;
121
llvm::CodeGenOpt::Level mOptLevel = llvm::CodeGenOpt::None;
122
123
/// Calculate actual directory where module will be cached.
124
/// This is always a subdirectory of mCacheDir. Full absolute
125
/// path name will be stored in mCurrentModuleCacheDir
126
void CalcModuleCacheDir();
127
};
128
129
//////////////////////////////////////////////////////////////////////////
130
/// JitManager
131
//////////////////////////////////////////////////////////////////////////
132
struct JitManager
133
{
134
JitManager(uint32_t w, const char* arch, const char* core);
135
~JitManager()
136
{
137
for (auto* pExec : mvExecEngines)
138
{
139
delete pExec;
140
}
141
}
142
143
JitLLVMContext mContext; ///< LLVM compiler
144
llvm::IRBuilder<> mBuilder; ///< LLVM IR Builder
145
llvm::ExecutionEngine* mpExec;
146
std::vector<llvm::ExecutionEngine*> mvExecEngines;
147
JitCache mCache;
148
llvm::StringRef mHostCpuName;
149
llvm::CodeGenOpt::Level mOptLevel;
150
151
// Need to be rebuilt after a JIT and before building new IR
152
llvm::Module* mpCurrentModule;
153
bool mIsModuleFinalized;
154
uint32_t mJitNumber;
155
156
uint32_t mVWidth;
157
158
bool mUsingAVX512 = false;
159
160
// fetch shader types
161
llvm::FunctionType* mFetchShaderTy;
162
163
JitInstructionSet mArch;
164
165
// Debugging support
166
std::unordered_map<llvm::StructType*, llvm::DIType*> mDebugStructMap;
167
168
void CreateExecEngine(std::unique_ptr<llvm::Module> M);
169
void SetupNewModule();
170
171
void DumpAsm(llvm::Function* pFunction, const char* fileName);
172
static void DumpToFile(llvm::Function* f, const char* fileName);
173
static void DumpToFile(llvm::Module* M,
174
const char* fileName,
175
llvm::AssemblyAnnotationWriter* annotater = nullptr);
176
static std::string GetOutputDir();
177
178
// Debugging support methods
179
llvm::DIType* GetDebugType(llvm::Type* pTy);
180
llvm::DIType* GetDebugIntegerType(llvm::Type* pTy);
181
llvm::DIType* GetDebugArrayType(llvm::Type* pTy);
182
llvm::DIType* GetDebugVectorType(llvm::Type* pTy);
183
llvm::DIType* GetDebugFunctionType(llvm::Type* pTy);
184
185
llvm::DIType* GetDebugStructType(llvm::Type* pType)
186
{
187
llvm::StructType* pStructTy = llvm::cast<llvm::StructType>(pType);
188
if (mDebugStructMap.find(pStructTy) == mDebugStructMap.end())
189
{
190
return nullptr;
191
}
192
return mDebugStructMap[pStructTy];
193
}
194
195
llvm::DIType*
196
CreateDebugStructType(llvm::StructType* pType,
197
const std::string& name,
198
llvm::DIFile* pFile,
199
uint32_t lineNum,
200
const std::vector<std::pair<std::string, uint32_t>>& members);
201
};
202
203
class InterleaveAssemblyAnnotater : public llvm::AssemblyAnnotationWriter
204
{
205
public:
206
void emitInstructionAnnot(const llvm::Instruction* pInst,
207
llvm::formatted_raw_ostream& OS) override;
208
std::vector<std::string> mAssembly;
209
210
private:
211
uint32_t mCurrentLineNo = 0;
212
};
213
214