mContext(), mBuilder(mContext), mIsModuleFinalized(true), mJitNumber(0), mVWidth(simdWidth),
mArch(arch)
{
+ mpCurrentModule = nullptr;
+ mpExec = nullptr;
+
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetDisassembler();
- TargetOptions tOpts;
- tOpts.AllowFPOpFusion = FPOpFusion::Fast;
- tOpts.NoInfsFPMath = false;
- tOpts.NoNaNsFPMath = false;
- tOpts.UnsafeFPMath = false;
-
- // tOpts.PrintMachineCode = true;
-
- std::unique_ptr<Module> newModule(new Module("", mContext));
- mpCurrentModule = newModule.get();
-
- StringRef hostCPUName;
-
// force JIT to use the same CPU arch as the rest of swr
if (mArch.AVX512F())
{
#if USE_SIMD16_SHADERS
if (mArch.AVX512ER())
{
- hostCPUName = StringRef("knl");
+ mHostCpuName = StringRef("knl");
}
else
{
- hostCPUName = StringRef("skylake-avx512");
+ mHostCpuName = StringRef("skylake-avx512");
}
mUsingAVX512 = true;
#else
- hostCPUName = StringRef("core-avx2");
+ mHostCpuName = StringRef("core-avx2");
#endif
if (mVWidth == 0)
{
}
else if (mArch.AVX2())
{
- hostCPUName = StringRef("core-avx2");
+ mHostCpuName = StringRef("core-avx2");
if (mVWidth == 0)
{
mVWidth = 8;
{
if (mArch.F16C())
{
- hostCPUName = StringRef("core-avx-i");
+ mHostCpuName = StringRef("core-avx-i");
}
else
{
- hostCPUName = StringRef("corei7-avx");
+ mHostCpuName = StringRef("corei7-avx");
}
if (mVWidth == 0)
{
}
- auto optLevel = CodeGenOpt::Aggressive;
+ mOptLevel = CodeGenOpt::Aggressive;
if (KNOB_JIT_OPTIMIZATION_LEVEL >= CodeGenOpt::None &&
KNOB_JIT_OPTIMIZATION_LEVEL <= CodeGenOpt::Aggressive)
{
- optLevel = CodeGenOpt::Level(KNOB_JIT_OPTIMIZATION_LEVEL);
+ mOptLevel = CodeGenOpt::Level(KNOB_JIT_OPTIMIZATION_LEVEL);
}
- mpCurrentModule->setTargetTriple(sys::getProcessTriple());
- mpExec = EngineBuilder(std::move(newModule))
- .setTargetOptions(tOpts)
- .setOptLevel(optLevel)
- .setMCPU(hostCPUName)
- .create();
-
if (KNOB_JIT_ENABLE_CACHE)
{
- mCache.Init(this, hostCPUName, optLevel);
- mpExec->setObjectCache(&mCache);
+ mCache.Init(this, mHostCpuName, mOptLevel);
}
-#if LLVM_USE_INTEL_JITEVENTS
- JITEventListener* vTune = JITEventListener::createIntelJITEventListener();
- mpExec->RegisterJITEventListener(vTune);
-#endif
+ SetupNewModule();
+ mIsModuleFinalized = true;
// fetch function signature
#if USE_SIMD16_SHADERS
#endif
}
+void JitManager::CreateExecEngine(std::unique_ptr<Module> pModule)
+{
+ TargetOptions tOpts;
+ tOpts.AllowFPOpFusion = FPOpFusion::Fast;
+ tOpts.NoInfsFPMath = false;
+ tOpts.NoNaNsFPMath = false;
+ tOpts.UnsafeFPMath = false;
+
+ // tOpts.PrintMachineCode = true;
+
+ mpExec = EngineBuilder(std::move(pModule))
+ .setTargetOptions(tOpts)
+ .setOptLevel(mOptLevel)
+ .setMCPU(mHostCpuName)
+ .create();
+
+ if (KNOB_JIT_ENABLE_CACHE)
+ {
+ mpExec->setObjectCache(&mCache);
+ }
+
+#if LLVM_USE_INTEL_JITEVENTS
+ JITEventListener* vTune = JITEventListener::createIntelJITEventListener();
+ mpExec->RegisterJITEventListener(vTune);
+#endif
+
+ mvExecEngines.push_back(mpExec);
+}
+
//////////////////////////////////////////////////////////////////////////
/// @brief Create new LLVM module.
void JitManager::SetupNewModule()
std::unique_ptr<Module> newModule(new Module("", mContext));
mpCurrentModule = newModule.get();
mpCurrentModule->setTargetTriple(sys::getProcessTriple());
- mpExec->addModule(std::move(newModule));
+ CreateExecEngine(std::move(newModule));
mIsModuleFinalized = false;
}
struct JitManager
{
JitManager(uint32_t w, const char* arch, const char* core);
- ~JitManager(){};
+ ~JitManager()
+ {
+ for (auto* pExec : mvExecEngines)
+ {
+ delete pExec;
+ }
+ }
- JitLLVMContext mContext; ///< LLVM compiler
- llvm::IRBuilder<> mBuilder; ///< LLVM IR Builder
- llvm::ExecutionEngine* mpExec;
- JitCache mCache;
+ JitLLVMContext mContext; ///< LLVM compiler
+ llvm::IRBuilder<> mBuilder; ///< LLVM IR Builder
+ llvm::ExecutionEngine* mpExec;
+ std::vector<llvm::ExecutionEngine*> mvExecEngines;
+ JitCache mCache;
+ llvm::StringRef mHostCpuName;
+ llvm::CodeGenOpt::Level mOptLevel;
// Need to be rebuilt after a JIT and before building new IR
llvm::Module* mpCurrentModule;
// Debugging support
std::unordered_map<llvm::StructType*, llvm::DIType*> mDebugStructMap;
+ void CreateExecEngine(std::unique_ptr<llvm::Module> M);
void SetupNewModule();
void DumpAsm(llvm::Function* pFunction, const char* fileName);
static void DumpToFile(llvm::Function* f, const char* fileName);
- static void DumpToFile(llvm::Module* M, const char* fileName, llvm::AssemblyAnnotationWriter* annotater = nullptr);
+ static void DumpToFile(llvm::Module* M,
+ const char* fileName,
+ llvm::AssemblyAnnotationWriter* annotater = nullptr);
static std::string GetOutputDir();
// Debugging support methods
class InterleaveAssemblyAnnotater : public llvm::AssemblyAnnotationWriter
{
public:
- void emitInstructionAnnot(const llvm::Instruction *pInst, llvm::formatted_raw_ostream &OS) override;
+ void emitInstructionAnnot(const llvm::Instruction* pInst,
+ llvm::formatted_raw_ostream& OS) override;
std::vector<std::string> mAssembly;
+
private:
uint32_t mCurrentLineNo = 0;
};