46 #include "llvm/ADT/StringRef.h"
47 #include "llvm/ExecutionEngine/JITSymbol.h"
48 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
49 #include "llvm/ExecutionEngine/Orc/Core.h"
50 #include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
51 #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
52 #include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
53 #include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
54 #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
55 #include "llvm/ExecutionEngine/SectionMemoryManager.h"
56 #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
57 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
58 #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
59 #include "llvm/IR/DataLayout.h"
60 #include "llvm/IR/LLVMContext.h"
61 #include "llvm/IR/LegacyPassManager.h"
62 #include "llvm/Transforms/InstCombine/InstCombine.h"
63 #include "llvm/Transforms/Scalar.h"
64 #include "llvm/Transforms/Scalar/GVN.h"
65 #include "clang/Basic/FileManager.h"
66 #include "llvm/ExecutionEngine/ExecutionEngine.h"
71 using namespace etiss;
74 using namespace clang;
75 using namespace llvm::orc;
83 OrcJit(llvm::orc::JITTargetMachineBuilder JTMB, llvm::DataLayout DL)
84 : ObjectLayer(ES, []() {
return std::make_unique<llvm::SectionMemoryManager>(); })
85 , CompileLayer(ES, ObjectLayer, std::make_unique<llvm::orc::ConcurrentIRCompiler>(std::move(JTMB)))
86 , OptimizeLayer(ES, CompileLayer, optimizeModule)
88 , Mangle(ES, this->DL)
89 , Ctx(std::make_unique<llvm::LLVMContext>())
90 , MainJITDylib(ES.createBareJITDylib(
"<main>"))
92 MainJITDylib.addGenerator(
93 llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(DL.getGlobalPrefix())));
96 static llvm::Expected<std::unique_ptr<OrcJit>>
Create()
98 auto JTMB = llvm::orc::JITTargetMachineBuilder::detectHost();
100 return JTMB.takeError();
102 auto DL = JTMB->getDefaultDataLayoutForTarget();
104 return DL.takeError();
106 return std::make_unique<OrcJit>(std::move(*JTMB), std::move(*DL));
110 llvm::LLVMContext &
getContext() {
return *Ctx.getContext(); }
114 llvm::cantFail(OptimizeLayer.add(MainJITDylib, llvm::orc::ThreadSafeModule(std::move(M), Ctx)));
117 llvm::Expected<llvm::JITEvaluatedSymbol>
lookup(llvm::StringRef Name)
119 return ES.lookup({ &MainJITDylib }, Mangle(Name.str()));
122 bool loadLib(
const std::string &libName,
const std::set<std::string> &libPaths)
124 for (
const auto &libPath : libPaths)
126 SmallString<128> fullPath;
127 sys::path::append(fullPath, libPath,
"lib" + libName +
".so");
128 if (sys::fs::exists(fullPath))
130 MainJITDylib.addGenerator(llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::Load(fullPath.c_str(), DL.getGlobalPrefix())));
138 static llvm::orc::ThreadSafeModule
optimizeModule(llvm::orc::ThreadSafeModule TSM,
139 const llvm::orc::MaterializationResponsibility &R)
141 auto lock = TSM.getContext();
142 auto M = TSM.getModuleUnlocked();
145 auto FPM = std::make_unique<llvm::legacy::FunctionPassManager>(M);
148 FPM->add(llvm::createInstructionCombiningPass());
149 FPM->add(llvm::createReassociatePass());
150 FPM->add(llvm::createGVNPass());
151 FPM->add(llvm::createCFGSimplificationPass());
152 FPM->doInitialization();
163 llvm::orc::ExecutionSession
ES;
170 llvm::orc::ThreadSafeContext
Ctx;
182 InitializeNativeTarget();
183 InitializeNativeTargetAsmPrinter();
184 InitializeNativeTargetAsmParser();
191 throw std::runtime_error(
"fail");
200 void *
LLVMJIT::translate(std::string code, std::set<std::string> headerpaths, std::set<std::string> librarypaths,
201 std::set<std::string> libraries, std::string &error,
bool debug)
203 clang::CompilerInstance CI;
205 DiagnosticOptions *diagOpts =
new DiagnosticOptions();
206 TextDiagnosticPrinter *diagPrinter =
new TextDiagnosticPrinter(llvm::outs(), diagOpts);
208 CI.createDiagnostics(diagPrinter);
209 auto pto = std::make_shared<clang::TargetOptions>();
210 pto->Triple = llvm::sys::getDefaultTargetTriple();
211 TargetInfo *pti = TargetInfo::CreateTargetInfo(CI.getDiagnostics(), pto);
213 CI.createFileManager();
214 CI.createSourceManager(CI.getFileManager());
215 CI.createPreprocessor(clang::TranslationUnitKind::TU_Module);
218 std::vector<std::string>
args;
221 args.push_back(
"-g");
222 args.push_back(
"-O0");
226 args.push_back(
"-O3");
228 args.push_back(
"-std=c99");
230 args.push_back(
"-isystem/usr/include");
231 for (
const auto &headerPath : headerpaths)
233 args.push_back(
"-isystem" + headerPath);
235 args.push_back(
"/etiss_llvm_clang_memory_mapped_file.c");
236 args.push_back(
"-isystem/usr/include/x86_64-linux-gnu");
238 for (
const auto &lib : libraries)
244 error =
"could not load library";
252 std::vector<const char *> argsCStr;
253 for (
const auto &arg :
args)
255 argsCStr.push_back(arg.c_str());
257 if (!CompilerInvocation::CreateFromArgs(CI.getInvocation(), argsCStr, CI.getDiagnostics()))
259 error =
"error on parsing args";
264 auto buffer = MemoryBuffer::getMemBufferCopy(code,
"/etiss_llvm_clang_memory_mapped_file.c");
265 CI.getSourceManager().overrideFileContents(
266 CI.getFileManager().getVirtualFile(
"/etiss_llvm_clang_memory_mapped_file.c", buffer->getBufferSize(), 0),
274 if (!CI.ExecuteAction(action))
276 error =
"failed to execute translation action ";
291 throw std::runtime_error(
"fail");
292 return (
void *)(*func).getAddress();
Header file of the ETISS library.
bool etiss_jit_llvm_init_done_
std::mutex etiss_jit_llvm_init_mu_
llvm::orc::RTDyldObjectLinkingLayer ObjectLayer
static llvm::Expected< std::unique_ptr< OrcJit > > Create()
llvm::orc::IRCompileLayer CompileLayer
OrcJit(llvm::orc::JITTargetMachineBuilder JTMB, llvm::DataLayout DL)
llvm::orc::ThreadSafeContext Ctx
llvm::LLVMContext & getContext()
llvm::orc::IRTransformLayer OptimizeLayer
void addModule(std::unique_ptr< llvm::Module > M)
llvm::orc::ExecutionSession ES
bool loadLib(const std::string &libName, const std::set< std::string > &libPaths)
llvm::Expected< llvm::JITEvaluatedSymbol > lookup(llvm::StringRef Name)
const llvm::DataLayout & getDataLayout() const
llvm::orc::JITDylib & MainJITDylib
llvm::orc::MangleAndInterner Mangle
static llvm::orc::ThreadSafeModule optimizeModule(llvm::orc::ThreadSafeModule TSM, const llvm::orc::MaterializationResponsibility &R)
compiler interface for just in time compilation of generated C code
virtual void * getFunction(void *handle, std::string name, std::string &error)
returns a function pointer to a compiled function from the handle returned by etiss::JIT::translate
std::unordered_set< std::string > loadedLibs_
virtual void free(void *handle)
clean up handled returned by etiss::JIT::translate
virtual void * translate(std::string code, std::set< std::string > headerpaths, std::set< std::string > librarypaths, std::set< std::string > libraries, std::string &error, bool debug=false)
translate C code to executable code and return a handle/pointer that identifies the compilation resul...
Page Table Entry (PTE) defines the composition of Page Frame Number (PFN) and relavant flags.
std::string jitFiles()
Get ETISS JIT files path.