serene/src/libserene/jit/layers.cpp

116 lines
3.6 KiB
C++
Raw Normal View History

2021-11-01 15:09:11 +00:00
/* -*- C++ -*-
* Serene Programming Language
*
* Copyright (c) 2019-2021 Sameer Rahmani <lxsameer@gnu.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "serene/jit/layers.h"
#include "serene/context.h"
#include "serene/exprs/fn.h"
#include "serene/exprs/traits.h"
2021-11-01 15:09:11 +00:00
#include <llvm/ExecutionEngine/Orc/ThreadSafeModule.h>
#include <llvm/Support/Error.h> // for report_fatal_error
namespace serene::jit {
// llvm::orc::ThreadSafeModule compileAst(serene::SereneContext &ctx,
// exprs::Ast &ast){
// };
// SerenAstMaterializationUnit::SerenAstMaterializationUnit(
// serene::SereneContext &ctx, SereneAstLayer &l, exprs::Ast &ast)
// : MaterializationUnit(l.getInterface(ast), nullptr), ctx(ctx),
// astLayer(l),
// ast(ast){};
// void SerenAstMaterializationUnit::materialize(
// std::unique_ptr<orc::MaterializationResponsibility> r) {
// astLayer.emit(std::move(r), ast);
// }
/// NS Layer ==================================================================
llvm::orc::ThreadSafeModule compileNS(serene::SereneContext &ctx,
serene::Namespace &ns) {
UNUSED(ctx);
2021-11-06 21:23:37 +00:00
LAYER_LOG("Compile namespace: " + ns.name);
2021-11-01 15:09:11 +00:00
auto maybeModule = ns.compileToLLVM();
if (!maybeModule) {
// TODO: Handle failure
llvm::report_fatal_error("Couldn't compile lazily JIT'd function");
}
return std::move(maybeModule.getValue());
};
NSMaterializationUnit::NSMaterializationUnit(SereneContext &ctx, NSLayer &l,
serene::Namespace &ns)
: MaterializationUnit(l.getInterface(ns), nullptr), ctx(ctx), nsLayer(l),
ns(ns){};
void NSMaterializationUnit::materialize(
std::unique_ptr<orc::MaterializationResponsibility> r) {
nsLayer.emit(std::move(r), ns);
}
llvm::Error NSLayer::add(orc::ResourceTrackerSP &rt, llvm::StringRef nsname,
reader::LocationRange &loc) {
2021-11-06 21:23:37 +00:00
LAYER_LOG("Add namespace: " + nsname);
2021-11-01 15:09:11 +00:00
auto maybeNS = ctx.sourceManager.readNamespace(ctx, nsname.str(), loc);
if (!maybeNS) {
// TODO: Fix this by making Serene errors compatible with llvm::Error
auto err = maybeNS.getError();
return llvm::make_error<llvm::StringError>(
llvm::Twine(err.front()->getMessage()),
std::make_error_code(std::errc::io_error));
}
auto ns = maybeNS.getValue();
2021-11-06 21:23:37 +00:00
LAYER_LOG("Add the materialize unit for: " + nsname);
2021-11-01 15:09:11 +00:00
return rt->getJITDylib().define(
std::make_unique<NSMaterializationUnit>(ctx, *this, *ns), rt);
}
orc::SymbolFlagsMap NSLayer::getInterface(serene::Namespace &ns) {
orc::SymbolFlagsMap Symbols;
for (auto &k : ns.getRootEnv()) {
auto flags = llvm::JITSymbolFlags::Exported;
auto name = k.getFirst();
auto expr = k.getSecond();
if (expr->getType() == exprs::ExprType::Fn) {
flags = flags | llvm::JITSymbolFlags::Callable;
}
auto mangledSym = mangler(k.getFirst());
2021-11-10 19:40:51 +00:00
LAYER_LOG("Mangle symbol for: " + k.getFirst() + " = " << mangledSym);
Symbols[mangledSym] = llvm::JITSymbolFlags(flags);
2021-11-01 15:09:11 +00:00
}
return Symbols;
}
} // namespace serene::jit