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"
75using namespace llvm::orc;
83 OrcJit(llvm::orc::JITTargetMachineBuilder JTMB, llvm::DataLayout
DL)
84 :
ObjectLayer(
ES, []() {
return std::make_unique<llvm::SectionMemoryManager>(); })
89 ,
Ctx(std::make_unique<llvm::LLVMContext>())
93 llvm::cantFail(llvm::orc::DynamicLibrarySearchGenerator::GetForCurrentProcess(
DL.getGlobalPrefix())));
83 OrcJit(llvm::orc::JITTargetMachineBuilder JTMB, llvm::DataLayout
DL) {
…}
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));
96 static llvm::Expected<std::unique_ptr<OrcJit>>
Create() {
…}
117 llvm::Expected<llvm::JITEvaluatedSymbol>
lookup(llvm::StringRef Name)
117 llvm::Expected<llvm::JITEvaluatedSymbol>
lookup(llvm::StringRef Name) {
…}
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())));
122 bool loadLib(
const std::string &libName,
const std::set<std::string> &libPaths) {
…}
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();
138 static llvm::orc::ThreadSafeModule
optimizeModule(llvm::orc::ThreadSafeModule TSM, {
…}
163 llvm::orc::ExecutionSession
ES;
170 llvm::orc::ThreadSafeContext
Ctx;
182 InitializeNativeTarget();
183 InitializeNativeTargetAsmPrinter();
184 InitializeNativeTargetAsmParser();
191 throw std::runtime_error(
"fail");
200void *
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 ";
200void *
LLVMJIT::translate(std::string code, std::set<std::string> headerpaths, std::set<std::string> librarypaths, {
…}
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
llvm::orc::IRCompileLayer CompileLayer
OrcJit(llvm::orc::JITTargetMachineBuilder JTMB, llvm::DataLayout DL)
llvm::orc::ThreadSafeContext Ctx
llvm::orc::IRTransformLayer OptimizeLayer
void addModule(std::unique_ptr< llvm::Module > M)
llvm::Expected< llvm::JITEvaluatedSymbol > lookup(llvm::StringRef Name)
llvm::orc::ExecutionSession ES
bool loadLib(const std::string &libName, const std::set< std::string > &libPaths)
llvm::LLVMContext & getContext()
llvm::orc::JITDylib & MainJITDylib
const llvm::DataLayout & getDataLayout() const
llvm::orc::MangleAndInterner Mangle
static llvm::orc::ThreadSafeModule optimizeModule(llvm::orc::ThreadSafeModule TSM, const llvm::orc::MaterializationResponsibility &R)
static llvm::Expected< std::unique_ptr< OrcJit > > Create()
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.