serene/libserene.v0/include/serene/jit/layers.h

165 lines
4.7 KiB
C
Raw Normal View History

2021-11-01 15:09:11 +00:00
/* -*- C++ -*-
* Serene Programming Language
*
2022-01-27 11:44:44 +00:00
* Copyright (c) 2019-2022 Sameer Rahmani <lxsameer@gnu.org>
2021-11-01 15:09:11 +00:00
*
* 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/>.
*/
#ifndef SERENE_JIT_LAYERS_H
#define SERENE_JIT_LAYERS_H
2021-11-19 00:41:28 +00:00
#include "serene/namespace.h"
2021-11-01 15:09:11 +00:00
#include "serene/reader/location.h"
#include "serene/utils.h"
#include <llvm/ADT/StringRef.h>
#include <llvm/ADT/Twine.h>
#include <llvm/ExecutionEngine/JITSymbol.h>
#include <llvm/ExecutionEngine/Orc/Core.h>
#include <llvm/ExecutionEngine/Orc/Layer.h>
#include <llvm/IR/DataLayout.h>
#include <llvm/Support/Error.h>
2021-11-06 21:23:37 +00:00
#define LAYER_LOG(...) \
DEBUG_WITH_TYPE("layer", llvm::dbgs() << "[Layer]: " << __VA_ARGS__ << "\n");
2021-11-01 15:09:11 +00:00
namespace orc = llvm::orc;
namespace serene {
class SereneContext;
class Namespace;
namespace exprs {
class Expression;
using Node = std::shared_ptr<Expression>;
using Ast = std::vector<Node>;
} // namespace exprs
namespace jit {
2021-11-19 00:41:28 +00:00
class AstLayer;
2021-11-01 15:09:11 +00:00
/// This will compile the ast to llvm ir.
2021-11-19 00:41:28 +00:00
llvm::orc::ThreadSafeModule compileAst(Namespace &ns, exprs::Ast &ast);
2021-11-01 15:09:11 +00:00
2021-11-19 00:41:28 +00:00
class AstMaterializationUnit : public orc::MaterializationUnit {
2021-11-01 15:09:11 +00:00
public:
2021-11-19 00:41:28 +00:00
AstMaterializationUnit(Namespace &ns, AstLayer &l, exprs::Ast &ast);
2021-11-01 15:09:11 +00:00
llvm::StringRef getName() const override {
return "SereneAstMaterializationUnit";
}
void
materialize(std::unique_ptr<orc::MaterializationResponsibility> r) override;
private:
void discard(const orc::JITDylib &jd,
const orc::SymbolStringPtr &sym) override {
UNUSED(jd);
UNUSED(sym);
llvm_unreachable("Serene functions are not overridable");
2021-11-01 15:09:11 +00:00
}
2021-11-19 00:41:28 +00:00
Namespace &ns;
AstLayer &astLayer;
2021-11-01 15:09:11 +00:00
exprs::Ast &ast;
};
2021-11-19 00:41:28 +00:00
class AstLayer {
orc::IRLayer &baseLayer;
orc::MangleAndInterner &mangler;
2021-11-12 16:20:22 +00:00
2021-11-19 00:41:28 +00:00
public:
AstLayer(orc::IRLayer &baseLayer, orc::MangleAndInterner &mangler)
: baseLayer(baseLayer), mangler(mangler){};
2021-11-01 15:09:11 +00:00
2021-11-19 00:41:28 +00:00
llvm::Error add(orc::ResourceTrackerSP &rt, Namespace &ns, exprs::Ast &ast) {
return rt->getJITDylib().define(
std::make_unique<AstMaterializationUnit>(ns, *this, ast), rt);
}
2021-11-01 15:09:11 +00:00
2021-11-19 00:41:28 +00:00
void emit(std::unique_ptr<orc::MaterializationResponsibility> mr,
Namespace &ns, exprs::Ast &e) {
2021-11-01 15:09:11 +00:00
2021-11-19 00:41:28 +00:00
baseLayer.emit(std::move(mr), compileAst(ns, e));
}
orc::MaterializationUnit::Interface getInterface(Namespace &ns,
exprs::Ast &e);
2021-11-19 00:41:28 +00:00
};
2021-11-01 15:09:11 +00:00
/// NS Layer ==================================================================
class NSLayer;
/// This will compile the NS to llvm ir.
2021-11-19 00:41:28 +00:00
llvm::orc::ThreadSafeModule compileNS(Namespace &ns);
2021-11-01 15:09:11 +00:00
class NSMaterializationUnit : public orc::MaterializationUnit {
public:
2021-11-19 00:41:28 +00:00
NSMaterializationUnit(NSLayer &l, Namespace &ns);
2021-11-01 15:09:11 +00:00
llvm::StringRef getName() const override { return "NSMaterializationUnit"; }
void
materialize(std::unique_ptr<orc::MaterializationResponsibility> r) override;
private:
void discard(const orc::JITDylib &jd,
const orc::SymbolStringPtr &sym) override {
UNUSED(jd);
UNUSED(sym);
2021-11-19 00:41:28 +00:00
llvm_unreachable("Serene functions are not overridable");
2021-11-10 19:40:51 +00:00
// TODO: Check the ctx to see whether we need to remove the sym or not
2021-11-01 15:09:11 +00:00
}
NSLayer &nsLayer;
2021-11-19 00:41:28 +00:00
Namespace &ns;
2021-11-01 15:09:11 +00:00
};
/// NS Layer is responsible for adding namespaces to the JIT
class NSLayer {
serene::SereneContext &ctx;
orc::IRLayer &baseLayer;
orc::MangleAndInterner &mangler;
const llvm::DataLayout &dl;
public:
2021-11-19 00:41:28 +00:00
NSLayer(SereneContext &ctx, orc::IRLayer &baseLayer,
2021-11-01 15:09:11 +00:00
orc::MangleAndInterner &mangler, const llvm::DataLayout &dl)
: ctx(ctx), baseLayer(baseLayer), mangler(mangler), dl(dl){};
llvm::Error add(orc::ResourceTrackerSP &rt, llvm::StringRef nsname) {
auto loc = serene::reader::LocationRange::UnknownLocation(nsname);
return add(rt, nsname, loc);
}
llvm::Error add(orc::ResourceTrackerSP &rt, llvm::StringRef nsname,
serene::reader::LocationRange &loc);
void emit(std::unique_ptr<orc::MaterializationResponsibility> mr,
serene::Namespace &ns) {
// TODO: We need to pass dl to the compilerNS later to aviod recreating
// the data layout all the time
UNUSED(dl);
2021-11-06 21:23:37 +00:00
LAYER_LOG("Emit namespace");
2021-11-19 00:41:28 +00:00
baseLayer.emit(std::move(mr), compileNS(ns));
2021-11-01 15:09:11 +00:00
}
orc::MaterializationUnit::Interface getInterface(serene::Namespace &ns);
2021-11-01 15:09:11 +00:00
};
} // namespace jit
} // namespace serene
#endif