Setup the base none lazy jit

This commit is contained in:
Sameer Rahmani 2021-11-10 19:40:51 +00:00
parent 1dfc353fa4
commit 981e5171b2
11 changed files with 161 additions and 152 deletions

View File

@ -1,4 +1,2 @@
(def main
(fn () 4))
(def main (fn () 4))
(def main1 (fn (v y n) 3))

View File

@ -123,7 +123,6 @@ class SereneJIT {
// FPM->run(F);
// });
UNUSED(r);
llvm::outs() << "optimodule\n";
return std::move(tsm);
}
@ -160,6 +159,7 @@ public:
orc::ResourceTrackerSP rt = nullptr);
llvm::Expected<llvm::JITEvaluatedSymbol> lookup(llvm::StringRef name) {
JIT_LOG("Looking up symbol: " + name);
return es->lookup({&mainJD}, mangler(name.str()));
}
};

View File

@ -129,7 +129,7 @@ private:
UNUSED(jd);
UNUSED(sym);
UNUSED(ctx);
llvm_unreachable("discard");
// TODO: Check the ctx to see whether we need to remove the sym or not
}
serene::SereneContext &ctx;

View File

@ -138,7 +138,7 @@ public:
/// Set the `loadPaths` to the given \p dirs. `loadPaths` is a vector of
/// directories that Serene will look in order to find a file that constains a
/// namespace which it is looking for.
void setLoadPaths(const std::vector<std::string> &dirs) { loadPaths = dirs; }
void setLoadPaths(std::vector<std::string> &dirs) { loadPaths.swap(dirs); }
/// Return a reference to a `SrcBuffer` with the given ID \p i.
const SrcBuffer &getBufferInfo(unsigned i) const {

View File

@ -15,7 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
add_subdirectory(libserene)
#add_subdirectory(serenec)
add_subdirectory(serenec)
add_subdirectory(serene-repl)
# Testing only available if this is the main app

View File

@ -95,9 +95,10 @@ orc::SymbolFlagsMap NSLayer::getInterface(serene::Namespace &ns) {
for (auto &k : ns.semanticEnv) {
// llvm::JITSymbolFlags::Exported |
auto mangeldSym = mangler(ns.name + "/" + k.getFirst());
LAYER_LOG("Mangeld symbol for: " + k.getFirst() + " = " << mangeldSym);
Symbols[mangeldSym] = llvm::JITSymbolFlags(llvm::JITSymbolFlags::Callable);
auto mangledSym = mangler(ns.name + "/" + k.getFirst());
LAYER_LOG("Mangle symbol for: " + k.getFirst() + " = " << mangledSym);
Symbols[mangledSym] = llvm::JITSymbolFlags(llvm::JITSymbolFlags::Callable |
llvm::JITSymbolFlags::Exported);
}
return Symbols;

View File

@ -32,6 +32,7 @@
#include "serene/reader/reader.h"
#include <llvm/ADT/None.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Error.h>
#include <llvm/Support/TargetSelect.h>
#include <llvm/Support/raw_ostream.h>
@ -120,7 +121,7 @@ SERENE_EXPORT exprs::MaybeNode eval(SereneContext &ctx, exprs::Ast &input) {
llvm::ExitOnError e;
// Get the anonymous expression's JITSymbol.
auto sym = e(ctx.jit->lookup(tmp));
llvm::outs() << "eval here\n";
// Get the symbol's address and cast it to the right type (takes no
// arguments, returns a double) so we can call it as a native function.
auto *f = (int (*)())(intptr_t)sym.getAddress();

View File

@ -21,39 +21,6 @@
namespace serene {
namespace slir {
// std::unique_ptr<llvm::Module> compileToLLVMIR(serene::SereneContext &ctx,
// mlir::ModuleOp &module) {
// // Register the translation to LLVM IR with the MLIR context.
// mlir::registerLLVMDialectTranslation(ctx.mlirContext);
// // Convert the module to LLVM IR in a new LLVM IR context.
// auto llvmModule = mlir::translateModuleToLLVMIR(module, ctx.llvmContext);
// if (!llvmModule) {
// // TODO: Return a Result type instead
// llvm::errs() << "Failed to emit LLVM IR\n";
// throw std::runtime_error("Failed to emit LLVM IR\n");
// }
// // Initialize LLVM targets.
// llvm::InitializeNativeTarget();
// llvm::InitializeNativeTargetAsmPrinter();
// // TODO: replace this call with our own version of setupTargetTriple
// mlir::ExecutionEngine::setupTargetTriple(llvmModule.get());
// /// Optionally run an optimization pipeline over the llvm module.
// auto optPipeline = mlir::makeOptimizingTransformer(
// /*optLevel=*/ctx.getOptimizatioLevel(), /*sizeLevel=*/0,
// /*targetMachine=*/nullptr);
// if (auto err = optPipeline(llvmModule.get())) {
// llvm::errs() << "Failed to optimize LLVM IR " << err << "\n";
// throw std::runtime_error("Failed to optimize LLVM IR");
// }
// return llvmModule;
// };
llvm::Optional<llvm::orc::ThreadSafeModule>
compileToLLVMIR(serene::SereneContext &ctx, mlir::ModuleOp &module) {

View File

@ -38,6 +38,7 @@
#include <llvm/Support/Locale.h>
#include <llvm/Support/MemoryBufferRef.h>
#include <llvm/Support/Path.h>
#include <llvm/Support/raw_ostream.h>
#include <mlir/Support/LogicalResult.h>
namespace serene {

View File

@ -66,6 +66,10 @@ int main(int argc, char *argv[]) {
// Load history
linenoise::LoadHistory(historyFile.c_str());
// TODO: Read the optimization as an input and as part of the global
// public arguments like -l
ctx->setOperationPhase(CompilationPhase::NoOptimization);
while (true) {
// Read line
std::string line;

View File

@ -16,15 +16,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "serene/jit.h"
#include "serene/namespace.h"
#include "serene/reader/location.h"
#include "serene/reader/reader.h"
#include "serene/reader/semantics.h"
#include "serene/serene.h"
#include "serene/serene/engine.h"
#include "serene/slir/generatable.h"
#include "serene/slir/slir.h"
#include <lld/Common/Driver.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Frontend/TextDiagnosticPrinter.h>
@ -32,7 +34,6 @@
#include <llvm/ADT/ArrayRef.h>
#include <llvm/ADT/SmallString.h>
#include <llvm/ADT/StringRef.h>
#include <llvm/ExecutionEngine/Orc/ThreadSafeModule.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/FileSystem.h>
@ -86,7 +87,7 @@ static cl::opt<std::string> outputFile(
static cl::opt<std::string>
outputDir("b", cl::desc("The absolute path to the build directory"),
cl::value_desc("filename"), cl::Required);
cl::value_desc("dir"), cl::Required);
static cl::opt<enum Action> emitAction(
"emit", cl::desc("Select what to dump."), cl::init(Compile),
@ -108,117 +109,151 @@ static cl::opt<enum Action> emitAction(
);
int dumpAsObject(Namespace &ns) {
// TODO: Move the compilation process to the Namespace class
auto maybeModule = ns.compileToLLVM();
// TODO: Fix this call to raise the wrapped error instead
if (!maybeModule) {
// TODO: Rais and error: "Faild to generato LLVM IR for namespace"
return -1;
}
// int dumpAsObject(Namespace &ns) {
// // TODO: Move the compilation process to the Namespace class
// auto maybeModule = ns.compileToLLVM();
// // TODO: Fix this call to raise the wrapped error instead
// if (!maybeModule) {
// // TODO: Rais and error: "Faild to generato LLVM IR for namespace"
// return -1;
// }
auto tsm = maybeModule.getValue();
auto tsc = tsm.getContext();
// auto module = std::move(maybeModule.getValue());
// auto &ctx = ns.getContext();
auto lock = tsc.getLock();
// // TODO: We need to set the triple data layout and everything to that sort
// in
// // one place. We want them for the JIT as well and also we're kinda
// // duplicating what we're doing in `Namespace#compileToLLVM`.
// module->setTargetTriple(ctx.targetTriple);
auto module = tsm.getModuleUnlocked();
auto &ctx = ns.getContext();
// std::string Error;
// const auto *target =
// llvm::TargetRegistry::lookupTarget(ctx.targetTriple, Error);
// TODO: We need to set the triple data layout and everything to that sort in
// one place. We want them for the JIT as well and also we're kinda
// duplicating what we're doing in `Namespace#compileToLLVM`.
// // Print an error and exit if we couldn't find the requested target.
// // This generally occurs if we've forgotten to initialise the
// // TargetRegistry or we have a bogus target triple.
// if (target == nullptr) {
// llvm::errs() << Error;
// return 1;
// }
module->setTargetTriple(ctx.targetTriple);
// const auto *cpu = "generic";
// const auto *features = "";
std::string Error;
const auto *target =
llvm::TargetRegistry::lookupTarget(ctx.targetTriple, Error);
// llvm::TargetOptions opt;
// auto rm = llvm::Optional<llvm::Reloc::Model>();
// auto *targetMachinePtr =
// target->createTargetMachine(ctx.targetTriple, cpu, features, opt, rm);
// auto targetMachine =
// std::unique_ptr<llvm::TargetMachine>(targetMachinePtr);
// Print an error and exit if we couldn't find the requested target.
// This generally occurs if we've forgotten to initialise the
// TargetRegistry or we have a bogus target triple.
if (target == nullptr) {
llvm::errs() << Error;
return 1;
}
// module->setDataLayout(targetMachine->createDataLayout());
const auto *cpu = "generic";
const auto *features = "";
// const auto *filename =
// strcmp(outputFile.c_str(), "-") == 0 ? "output" : outputFile.c_str();
llvm::TargetOptions opt;
auto rm = llvm::Optional<llvm::Reloc::Model>();
auto *targetMachinePtr =
target->createTargetMachine(ctx.targetTriple, cpu, features, opt, rm);
auto targetMachine = std::unique_ptr<llvm::TargetMachine>(targetMachinePtr);
// std::error_code ec;
// const auto pathSize(256);
module->setDataLayout(targetMachine->createDataLayout());
// llvm::SmallString<pathSize> destFile(outputDir);
// llvm::sys::path::append(destFile, filename);
// auto destObjFilePath = llvm::formatv("{0}.o", destFile).str();
// llvm::raw_fd_ostream dest(destObjFilePath, ec, llvm::sys::fs::OF_None);
const auto *filename =
strcmp(outputFile.c_str(), "-") == 0 ? "output" : outputFile.c_str();
// if (ec) {
// llvm::errs() << "Could not open file: " << destObjFilePath;
// llvm::errs() << "Could not open file: " << ec.message();
// return 1;
// }
std::error_code ec;
const auto pathSize(256);
// llvm::legacy::PassManager pass;
// auto fileType = llvm::CGFT_ObjectFile;
llvm::SmallString<pathSize> destFile(outputDir);
llvm::sys::path::append(destFile, filename);
auto destObjFilePath = llvm::formatv("{0}.o", destFile).str();
llvm::raw_fd_ostream dest(destObjFilePath, ec, llvm::sys::fs::OF_None);
// if (targetMachine->addPassesToEmitFile(pass, dest, nullptr, fileType)) {
// llvm::errs() << "TheTargetMachine can't emit a file of this type";
// return 1;
// }
if (ec) {
llvm::errs() << "Could not open file: " << ec.message();
return 1;
}
// pass.run(*module);
// dest.flush();
llvm::legacy::PassManager pass;
auto fileType = llvm::CGFT_ObjectFile;
// if (emitAction == Action::Compile) {
// std::vector<const char *> args = {"serenec"};
if (targetMachine->addPassesToEmitFile(pass, dest, nullptr, fileType)) {
llvm::errs() << "TheTargetMachine can't emit a file of this type";
return 1;
}
// args.push_back("--eh-frame-hdr");
// args.push_back("-m");
// args.push_back("elf_x86_64");
// args.push_back("-dynamic-linker");
// args.push_back("/lib64/ld-linux-x86-64.so.2");
// args.push_back(
// "/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crt1.o");
// args.push_back(
// "/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crti.o");
// args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/crtbegin.o");
// args.push_back("-L");
// args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/");
// args.push_back("-L");
// args.push_back("/usr/lib64/");
pass.run(*module);
dest.flush();
// args.push_back(destObjFilePath.c_str());
// args.push_back("-o");
// args.push_back(destFile.c_str());
// args.push_back("-lgcc");
// args.push_back("--as-needed");
// args.push_back("-lgcc_s");
// args.push_back("--no-as-needed");
// args.push_back("-lc");
// args.push_back("-lgcc");
// args.push_back("--as-needed");
// args.push_back("-lgcc_s");
// args.push_back("--no-as-needed");
// args.push_back("/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/crtend.o");
// args.push_back(
// "/usr/lib/gcc/x86_64-pc-linux-gnu/11.2.0/../../../../lib64/crtn.o");
if (emitAction == Action::Compile) {
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
new clang::DiagnosticOptions;
clang::DiagnosticsEngine diags(
new clang::DiagnosticIDs, opts,
new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
// lld::elf::link(args, false, llvm::outs(), llvm::errs());
clang::driver::Driver d("clang", ctx.targetTriple, diags,
"Serene compiler");
std::vector<const char *> args = {"serenec"};
// // llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> opts =
// // new clang::DiagnosticOptions;
// // clang::DiagnosticsEngine diags(
// // new clang::DiagnosticIDs, opts,
// // new clang::TextDiagnosticPrinter(llvm::errs(), opts.get()));
args.push_back(destObjFilePath.c_str());
args.push_back("-o");
args.push_back(destFile.c_str());
// // clang::driver::Driver d("clang", ctx.targetTriple, diags,
// // "Serene compiler");
// // std::vector<const char *> args = {"serenec"};
d.setCheckInputsExist(false);
// // args.push_back(destObjFilePath.c_str());
// // args.push_back("-o");
// // args.push_back(destFile.c_str());
std::unique_ptr<clang::driver::Compilation> compilation;
compilation.reset(d.BuildCompilation(args));
// // d.setCheckInputsExist(true);
if (!compilation) {
return 1;
}
// // std::unique_ptr<clang::driver::Compilation> compilation;
// // compilation.reset(d.BuildCompilation(args));
llvm::SmallVector<std::pair<int, const clang::driver::Command *>>
failCommand;
// compilation->ExecuteJobs(compilation->getJobs(), failCommand);
// // if (!compilation) {
// // llvm::errs() << "can't create the compilation!\n";
// // return 1;
// // }
d.ExecuteCompilation(*compilation, failCommand);
if (failCommand.empty()) {
llvm::outs() << "Done!\n";
} else {
llvm::errs() << "Linking failed!\n";
}
}
// // llvm::SmallVector<std::pair<int, const clang::driver::Command *>>
// // failCommand;
return 0;
};
// // d.ExecuteCompilation(*compilation, failCommand);
// // if (failCommand.empty()) {
// // llvm::outs() << "Done!\n";
// // } else {
// // llvm::errs() << "Linking failed!\n";
// // failCommand.front().second->Print(llvm::errs(), "\n", false);
// // }
// // }
// return 0;
// };
int main(int argc, char *argv[]) {
initCompiler();
@ -235,7 +270,7 @@ int main(int argc, char *argv[]) {
// default to the current working dir
if (outputDir == "-") {
llvm::errs() << "Error: The build directory is not set. Did you forget to "
"use '-build-dir'?\n";
"use '-b'?\n";
return 1;
}
@ -328,30 +363,32 @@ int main(int argc, char *argv[]) {
return 1;
}
maybeModule.getValue()->dump();
auto tsm = std::move(maybeModule.getValue());
tsm.withModuleDo([](auto &m) { m.dump(); });
break;
};
case Action::RunJIT: {
auto maybeJIT = JIT::make(*ns);
if (!maybeJIT) {
// TODO: panic in here: "Couldn't creat the JIT!"
return -1;
}
auto jit = std::move(maybeJIT.getValue());
// case Action::RunJIT: {
// auto maybeJIT = JIT::make(*ns);
// if (!maybeJIT) {
// // TODO: panic in here: "Couldn't creat the JIT!"
// return -1;
// }
// auto jit = std::move(maybeJIT.getValue());
if (jit->invoke("main")) {
llvm::errs() << "Faild to invoke the 'main' function.\n";
return 1;
}
llvm::outs() << "Done!";
break;
};
// if (jit->invoke("main")) {
// llvm::errs() << "Faild to invoke the 'main' function.\n";
// return 1;
// }
// llvm::outs() << "Done!";
// break;
// };
case Action::Compile:
case Action::CompileToObject: {
return dumpAsObject(*ns);
};
// case Action::Compile:
// case Action::CompileToObject: {
// return dumpAsObject(*ns);
// };
default: {
llvm::errs() << "Action is not supported yet!\n";
};