From 65b6aa4020b928c01f46bca518194f0171afcab1 Mon Sep 17 00:00:00 2001 From: Sameer Rahmani Date: Sun, 13 Jun 2021 22:40:58 +0100 Subject: [PATCH] Add the IR generation facilities to Namespace and Expression --- .ignore_sanitize | 1 + bin/serene.cpp | 13 +- builder | 5 +- include/serene/exprs/call.h | 1 + include/serene/exprs/def.h | 1 + include/serene/exprs/expression.h | 6 +- include/serene/exprs/fn.h | 1 + include/serene/exprs/list.h | 1 + include/serene/exprs/number.h | 2 + include/serene/exprs/symbol.h | 1 + include/serene/namespace.h | 29 ++- include/serene/sir/CMakeLists.txt | 5 - include/serene/sir/dialect.td | 104 --------- include/serene/sir/generator.hpp | 79 ------- .../slir/{generator.h => generatable.h} | 64 +++--- include/serene/slir/slir.h | 21 +- include/serene/{sir/sir.hpp => slir/utils.h} | 39 ++-- include/serene/traits.h | 8 +- src/serene/CMakeLists.txt | 8 +- src/serene/exprs/number.cpp | 14 ++ src/serene/namespace.cpp | 48 ++++- src/serene/sir/dialect.cpp | 46 ---- src/serene/sir/generator.cpp | 200 ------------------ src/serene/sir/sir.cpp | 59 ------ src/serene/sir/value_op.cpp | 34 --- .../slir/{generator.cpp => generatable.cpp} | 169 +++++++-------- src/serene/slir/slir.cpp | 66 ------ .../dialect.hpp => src/serene/slir/utils.cpp | 31 ++- 28 files changed, 253 insertions(+), 803 deletions(-) create mode 100644 .ignore_sanitize delete mode 100644 include/serene/sir/CMakeLists.txt delete mode 100644 include/serene/sir/dialect.td delete mode 100644 include/serene/sir/generator.hpp rename include/serene/slir/{generator.h => generatable.h} (58%) rename include/serene/{sir/sir.hpp => slir/utils.h} (73%) delete mode 100644 src/serene/sir/dialect.cpp delete mode 100644 src/serene/sir/generator.cpp delete mode 100644 src/serene/sir/sir.cpp delete mode 100644 src/serene/sir/value_op.cpp rename src/serene/slir/{generator.cpp => generatable.cpp} (59%) delete mode 100644 src/serene/slir/slir.cpp rename include/serene/sir/dialect.hpp => src/serene/slir/utils.cpp (67%) diff --git a/.ignore_sanitize b/.ignore_sanitize new file mode 100644 index 0000000..5ec155e --- /dev/null +++ b/.ignore_sanitize @@ -0,0 +1 @@ +#leak:mlir::Region::emplaceBlock \ No newline at end of file diff --git a/bin/serene.cpp b/bin/serene.cpp index 3a5d940..58d7b0d 100644 --- a/bin/serene.cpp +++ b/bin/serene.cpp @@ -27,6 +27,7 @@ #include "serene/namespace.h" #include "serene/reader/reader.h" #include "serene/reader/semantics.h" +#include "serene/slir/generatable.h" #include "serene/slir/slir.h" #include #include @@ -37,7 +38,7 @@ using namespace serene; namespace cl = llvm::cl; namespace { -enum Action { None, DumpAST, DumpIR, DumpSemantic }; +enum Action { None, DumpAST, DumpIR, DumpSLIR, DumpSemantic }; } static cl::opt inputFile(cl::Positional, @@ -49,7 +50,8 @@ static cl::opt emitAction( "emit", cl::desc("Select what to dump."), cl::values(clEnumValN(DumpSemantic, "ast1", "Output the AST after one level of analysis only")), - cl::values(clEnumValN(DumpIR, "slir", "Output the SLIR only")), + cl::values(clEnumValN(DumpIR, "ir", "Output the lowered IR only")), + cl::values(clEnumValN(DumpSLIR, "slir", "Output the SLIR only")), cl::values(clEnumValN(DumpAST, "ast", "Output the AST only")) ); @@ -112,7 +114,12 @@ int main(int argc, char *argv[]) { if (isSet.succeeded()) { ctx->insertNS(ns); - serene::slir::dumpSLIR(*ctx, ns->name); + serene::slir::dumpIR(*ns); + // if (mlir::failed(ns->generateIR(*ctx))) { + // // TODO: Replace with an actual error + // llvm::outs() << "Can't generate IR for namespace\n"; + // } + // serene::slir::dumpSLIR(*ctx, ns->name); } else { llvm::outs() << "Can't set the tree of the namespace!\n"; } diff --git a/builder b/builder index 7db0844..a92c69e 100755 --- a/builder +++ b/builder @@ -6,6 +6,9 @@ command=$1 export CC=$(which clang) export CXX=$(which clang++) export LDFLAGS="-fuse-ld=lld" + +export ASAN_OPTIONS=check_initialization_order=1 +export LSAN_OPTIONS=suppressions=`pwd`/.ignore_sanitize ROOT_DIR=`pwd` BUILD_DIR=$ROOT_DIR/build @@ -21,7 +24,7 @@ function popd_build() { function compile() { pushed_build - ninja + ninja -j `nproc` popd_build } diff --git a/include/serene/exprs/call.h b/include/serene/exprs/call.h index 6426372..182db7f 100644 --- a/include/serene/exprs/call.h +++ b/include/serene/exprs/call.h @@ -55,6 +55,7 @@ public: ExprType getType() const; std::string toString() const; MaybeNode analyze(SereneContext &); + void generateIR(serene::Namespace &){}; static bool classof(const Expression *e); diff --git a/include/serene/exprs/def.h b/include/serene/exprs/def.h index 972d8a8..36f8868 100644 --- a/include/serene/exprs/def.h +++ b/include/serene/exprs/def.h @@ -54,6 +54,7 @@ public: ExprType getType() const; std::string toString() const; MaybeNode analyze(SereneContext &); + void generateIR(serene::Namespace &){}; static bool classof(const Expression *e); diff --git a/include/serene/exprs/expression.h b/include/serene/exprs/expression.h index 8a35169..598991d 100644 --- a/include/serene/exprs/expression.h +++ b/include/serene/exprs/expression.h @@ -34,10 +34,6 @@ namespace serene { -namespace reader { -class SereneContext; -} - /// Contains all the builtin AST expressions including those which do not appear /// in the syntax directly. Like function definitions. namespace exprs { @@ -82,6 +78,8 @@ public: /// /// \param ctx is the context object of the semantic analyzer. virtual MaybeNode analyze(SereneContext &ctx) = 0; + + virtual void generateIR(serene::Namespace &ns) = 0; }; /// Create a new `node` of type `T` and forwards any given parameter diff --git a/include/serene/exprs/fn.h b/include/serene/exprs/fn.h index 4997366..4fa0506 100644 --- a/include/serene/exprs/fn.h +++ b/include/serene/exprs/fn.h @@ -58,6 +58,7 @@ public: ExprType getType() const; std::string toString() const; MaybeNode analyze(SereneContext &); + void generateIR(serene::Namespace &){}; static bool classof(const Expression *e); diff --git a/include/serene/exprs/list.h b/include/serene/exprs/list.h index dfc2fda..9671f03 100644 --- a/include/serene/exprs/list.h +++ b/include/serene/exprs/list.h @@ -67,6 +67,7 @@ public: std::vector::iterator end(); MaybeNode analyze(SereneContext &); + void generateIR(serene::Namespace &){}; static bool classof(const Expression *e); diff --git a/include/serene/exprs/number.h b/include/serene/exprs/number.h index 4a6b3d8..14fc5e3 100644 --- a/include/serene/exprs/number.h +++ b/include/serene/exprs/number.h @@ -27,6 +27,7 @@ #include "serene/context.h" #include "serene/exprs/expression.h" +#include "serene/namespace.h" #include "llvm/Support/FormatVariadic.h" namespace serene { @@ -57,6 +58,7 @@ struct Number : public Expression { // TODO: This is horrible, we need to fix it after the mvp int toI64(); + void generateIR(serene::Namespace &); ~Number() = default; }; diff --git a/include/serene/exprs/symbol.h b/include/serene/exprs/symbol.h index b66f4c9..f1ac266 100644 --- a/include/serene/exprs/symbol.h +++ b/include/serene/exprs/symbol.h @@ -52,6 +52,7 @@ public: static bool classof(const Expression *e); MaybeNode analyze(SereneContext &); + void generateIR(serene::Namespace &){}; ~Symbol() = default; }; diff --git a/include/serene/namespace.h b/include/serene/namespace.h index 45a884f..8a1303d 100644 --- a/include/serene/namespace.h +++ b/include/serene/namespace.h @@ -22,16 +22,20 @@ * SOFTWARE. */ -#ifndef NAMESPACE_H -#define NAMESPACE_H +#ifndef SERENE_NAMESPACE_H +#define SERENE_NAMESPACE_H #include "serene/environment.h" +#include "serene/slir/generatable.h" +#include "serene/traits.h" #include "serene/utils.h" -#include "llvm/ADT/SmallString.h" #include +#include #include #include #include +#include +#include #include #include #include @@ -51,26 +55,41 @@ using Ast = std::vector; /// Serene's namespaces are the unit of compilation. Any code that needs to be /// compiled has to be in a namespace. The official way to create a new /// namespace is to use the `makeNamespace` function. -class Namespace { +class Namespace : public WithTrait { private: + SereneContext &ctx; bool initialized = false; std::atomic fn_counter = 0; exprs::Ast tree; + mlir::OpBuilder builder; public: mlir::StringRef name; llvm::Optional filename; + mlir::ModuleOp module; /// The root environment of the namespace on the semantic analysis phase. /// Which is a mapping from names to AST nodes ( no evaluation ). Environment semanticEnv; Environment symbolTable; - Namespace(llvm::StringRef ns_name, llvm::Optional filename); + Namespace(SereneContext &ctx, llvm::StringRef ns_name, + llvm::Optional filename); exprs::Ast &getTree(); mlir::LogicalResult setTree(exprs::Ast &); uint nextFnCounter(); + + mlir::OpBuilder &getBuilder(); + mlir::ModuleOp &getModule(); + SereneContext &getContext(); + + // Generatable Trait + mlir::ModuleOp &generate(); + mlir::LogicalResult runPasses(); + void dumpSLIR(); + void dumpToIR(); + ~Namespace(); }; diff --git a/include/serene/sir/CMakeLists.txt b/include/serene/sir/CMakeLists.txt deleted file mode 100644 index ff81eff..0000000 --- a/include/serene/sir/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_TARGET_DEFINITIONS dialect.td) -mlir_tablegen(ops.hpp.inc -gen-op-decls) -mlir_tablegen(ops.cpp.inc -gen-op-defs) -mlir_tablegen(dialect.hpp.inc -gen-dialect-decls) -add_public_tablegen_target(SereneDialectGen) diff --git a/include/serene/sir/dialect.td b/include/serene/sir/dialect.td deleted file mode 100644 index 18d6833..0000000 --- a/include/serene/sir/dialect.td +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef SERENE_DIALECT -#define SERENE_DIALECT - -include "mlir/IR/OpBase.td" -include "mlir/Interfaces/SideEffectInterfaces.td" - - -// Dialect definition. It will directly generate the SereneDialect class -def Serene_Dialect : Dialect { - let name = "serene"; - let cppNamespace = "::serene::sir"; - let summary = "Primary IR of serene language."; - let description = [{ - This dialect tries to map the special forms of a lisp into - IR level operations. - }]; -} - -// Base class for Serene dialect operations. This operation inherits from the base -// `Op` class in OpBase.td, and provides: -// * The parent dialect of the operation. -// * The mnemonic for the operation, or the name without the dialect prefix. -// * A list of traits for the operation. -class Serene_Op traits = []> : - Op; - - -// All of the types will extend this class. -class Serene_Type : TypeDef { } - - -// def SymbolType : Serene_Type<"Symbol"> { - -// let mnemonic = "symbol"; - -// let summary = "A typical Lisp symbol"; - -// let description = [{ -// A symbol is just a name and nothing more. Just a name -// to give to a value or to use it as it is. -// }]; - -// // let cppNamespace = "::serene::sir"; -// let parameters = (ins "std::string":$name); - -// // We define the printer inline. -// let printer = [{ -// $_printer << "Symbol<" << getImpl()->name << ">"; -// }]; - -// // The parser is defined here also. -// let parser = [{ -// if ($_parser.parseLess()) -// return Type(); - -// std::string name; -// if ($_parser.parseInteger(name)) -// return Type(); - -// return get($_ctxt, name); -// }]; -// } - -def ValueOp: Serene_Op<"value"> { - - let summary = "This operation represent a value"; - let description = [{ - some description - }]; - - let arguments = (ins I64Attr:$value); - let results = (outs I64); - - // let verifier = [{ return serene::sir::verify(*this); }]; - - let builders = [ - OpBuilder<(ins "int":$value), [{ - // Build from fix 64 bit int - build(odsBuilder, odsState, odsBuilder.getI64Type(), (uint64_t) value); - }]>, - - ]; -} - -def FnIdOp: Serene_Op<"fn_id"> { - - let summary = "This operation is just a place holder for an anonymouse function"; - let description = [{ - A place holder for an anonymous function. For example consider an expression - like `(def a (fn (x) x))`, in this case we don't immediately create an anonymous - function since we need to set the name and create the function later. - }]; - - let arguments = (ins StrAttr:$name); - let results = (outs NoneType); - - let builders = [ - OpBuilder<(ins "std::string":$name), [{ - // Build from fix 64 bit int - build(odsBuilder, odsState, odsBuilder.getNoneType(), odsBuilder.getStringAttr(name)); - }]>, - ]; -} -#endif // SERENE_DIALECT diff --git a/include/serene/sir/generator.hpp b/include/serene/sir/generator.hpp deleted file mode 100644 index be8ad7c..0000000 --- a/include/serene/sir/generator.hpp +++ /dev/null @@ -1,79 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#ifndef GENERATOR_H -#define GENERATOR_H - -#include "mlir/IR/Builders.h" -#include "mlir/IR/BuiltinOps.h" -#include "mlir/IR/Identifier.h" -#include "mlir/IR/MLIRContext.h" -#include "serene/expr.hpp" -#include "serene/list.hpp" -#include "serene/namespace.h" -#include "serene/number.hpp" -#include "serene/symbol.hpp" -#include "llvm/ADT/ScopedHashTable.h" -#include -#include -#include - -namespace serene { -namespace sir { - -using FnIdPair = std::pair; - -class Generator { -private: - ::mlir::OpBuilder builder; - ::mlir::ModuleOp module; - std::unique_ptr<::serene::Namespace> ns; - std::atomic_int anonymousFnCounter{1}; - llvm::DenseMap anonymousFunctions; - llvm::ScopedHashTable symbolTable; - - // TODO: Should we use builder here? maybe there is a better option - ::mlir::Location toMLIRLocation(serene::reader::Location *); - - // mlir::FuncOp generateFn(serene::reader::Location, std::string, List *, - // List *); - -public: - Generator(mlir::MLIRContext &context, ::serene::Namespace *ns) - : builder(&context), - module(mlir::ModuleOp::create(builder.getUnknownLoc(), ns->name)) { - this->ns.reset(ns); - } - - mlir::Operation *generate(Number *); - mlir::Operation *generate(AExpr *); - mlir::Value generate(List *); - mlir::ModuleOp generate(); - ~Generator(); -}; - -} // namespace sir - -} // namespace serene - -#endif diff --git a/include/serene/slir/generator.h b/include/serene/slir/generatable.h similarity index 58% rename from include/serene/slir/generator.h rename to include/serene/slir/generatable.h index cd9ddf5..f509239 100644 --- a/include/serene/slir/generator.h +++ b/include/serene/slir/generatable.h @@ -22,50 +22,50 @@ * SOFTWARE. */ -#ifndef GENERATOR_H -#define GENERATOR_H +#ifndef SERENE_SLIR_GENERATABLE_H +#define SERENE_SLIR_GENERATABLE_H #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Identifier.h" -#include "serene/context.h" -#include "serene/exprs/expression.h" -#include "serene/exprs/list.h" -#include "serene/exprs/number.h" -#include "serene/exprs/symbol.h" -#include "serene/namespace.h" -#include "llvm/ADT/ScopedHashTable.h" -#include +#include "serene/reader/location.h" +#include "serene/traits.h" #include +namespace serene { +class Namespace; +} + namespace serene::slir { -class Generator { -private: - serene::SereneContext &ctx; - mlir::OpBuilder builder; - mlir::ModuleOp module; - std::shared_ptr ns; - - // TODO: Should we use builder here? maybe there is a better option - mlir::Location toMLIRLocation(serene::reader::Location &); - +template +class GeneratableUnit : public TraitBase { public: - Generator(serene::SereneContext &ctx, llvm::StringRef ns_name) - : ctx(ctx), builder(&ctx.mlirContext), - module(mlir::ModuleOp::create(builder.getUnknownLoc(), ns_name)) { - this->ns = ctx.getNS(ns_name); + GeneratableUnit(){}; + GeneratableUnit(const GeneratableUnit &) = delete; + + void generate(serene::Namespace &ns) { + // TODO: should we return any status or possible error here or + // should we just populate them in a ns wide state? + this->Object().generateIR(ns); }; - - void generate(exprs::Number &); - mlir::Operation *generate(exprs::Expression *); - mlir::Value generate(exprs::List *); - mlir::ModuleOp generate(); - - serene::Namespace &getNs(); - ~Generator(); }; +template class Generatable : public TraitBase { +public: + Generatable(){}; + Generatable(const Generatable &) = delete; + + mlir::ModuleOp &generate(); + mlir::LogicalResult runPasses(); + void dumpSLIR(); + void dumpIR() { this->Object().dumpToIR(); }; +}; + +template void dumpIR(Generatable &t) { t.dumpIR(); }; + +template void dumpSLIR(Generatable &t) { t.dumpSLIR(); }; + } // namespace serene::slir #endif diff --git a/include/serene/slir/slir.h b/include/serene/slir/slir.h index 4e514a0..004e8f9 100644 --- a/include/serene/slir/slir.h +++ b/include/serene/slir/slir.h @@ -27,28 +27,11 @@ #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/MLIRContext.h" #include "serene/exprs/expression.h" -#include "serene/namespace.h" -#include "serene/slir/generator.h" +#include "serene/slir/generatable.h" #include namespace serene { -namespace slir { - -class SLIR { - -private: - serene::SereneContext &context; - -public: - SLIR(serene::SereneContext &ctx); - - mlir::OwningModuleRef generate(llvm::StringRef ns_name); - - ~SLIR(); -}; - -void dumpSLIR(serene::SereneContext &ctx, llvm::StringRef ns_name); -} // namespace slir +namespace slir {} // namespace slir } // namespace serene diff --git a/include/serene/sir/sir.hpp b/include/serene/slir/utils.h similarity index 73% rename from include/serene/sir/sir.hpp rename to include/serene/slir/utils.h index a2ed24a..9d3422c 100644 --- a/include/serene/sir/sir.hpp +++ b/include/serene/slir/utils.h @@ -1,7 +1,7 @@ -/** +/* -*- C++ -*- * Serene programming language. * - * Copyright (c) 2020 Sameer Rahmani + * Copyright (c) 2019-2021 Sameer Rahmani * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -21,34 +21,25 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ -#ifndef SIR_H -#define SIR_H + +#ifndef SERENE_SLIR_UTILS_H +#define SERENE_SLIR_UTILS_H #include "mlir/IR/BuiltinOps.h" -#include "mlir/IR/MLIRContext.h" -#include "serene/exprs/expression.h" -#include "serene/sir/generator.hpp" -#include +#include "serene/reader/location.h" namespace serene { -namespace sir { +class Namespace; +} -class SIR { +namespace serene::slir { -private: - mlir::MLIRContext context; +/** + * Convert a Serene location to MLIR FileLineLoc Location + */ +::mlir::Location toMLIRLocation(serene::Namespace &, + serene::reader::Location &); -public: - SIR(); - - mlir::OwningModuleRef generate(serene::Namespace *ns); - - ~SIR(); -}; - -void dumpSIR(exprs::ast &t); -} // namespace sir - -} // namespace serene +} // namespace serene::slir #endif diff --git a/include/serene/traits.h b/include/serene/traits.h index 012f8c7..8d8c793 100644 --- a/include/serene/traits.h +++ b/include/serene/traits.h @@ -104,9 +104,11 @@ class TraitBase { protected: /// Statically casts the object to the concrete type object to be /// used in the Trait Types. - const ConcreteType &Object() const { - return static_cast(*this); - }; + // const ConcreteType &Object() const { + // return static_cast(*this); + // }; + + ConcreteType &Object() { return static_cast(*this); }; }; template diff --git a/src/serene/CMakeLists.txt b/src/serene/CMakeLists.txt index 2a53d71..7961322 100644 --- a/src/serene/CMakeLists.txt +++ b/src/serene/CMakeLists.txt @@ -30,7 +30,8 @@ set(HEADER_LIST "${INCLUDE_DIR}/serene/slir/slir.h" "${INCLUDE_DIR}/serene/slir/dialect.h" - "${INCLUDE_DIR}/serene/slir/generator.h" + "${INCLUDE_DIR}/serene/slir/generatable.h" + "${INCLUDE_DIR}/serene/slir/utils.h" "${INCLUDE_DIR}/serene/namespace.h" "${INCLUDE_DIR}/serene/passes/slir_lowering.h") @@ -60,10 +61,11 @@ add_library(serene errors/error.cpp # IR - slir/slir.cpp slir/dialect.cpp slir/value_op.cpp - slir/generator.cpp + slir/generatable.cpp + slir/utils.cpp + passes/slir_lowering.cpp ${HEADER_LIST}) diff --git a/src/serene/exprs/number.cpp b/src/serene/exprs/number.cpp index aa7378f..625a55d 100644 --- a/src/serene/exprs/number.cpp +++ b/src/serene/exprs/number.cpp @@ -24,6 +24,8 @@ */ #include "serene/exprs/number.h" +#include "serene/slir/dialect.h" +#include "serene/slir/utils.h" namespace serene { namespace exprs { @@ -44,5 +46,17 @@ bool Number::classof(const Expression *e) { int Number::toI64() { return std::stoi(this->value); }; +void Number::generateIR(serene::Namespace &ns) { + mlir::OpBuilder &builder = ns.getBuilder(); + mlir::ModuleOp &module = ns.getModule(); + + auto op = builder.create( + serene::slir::toMLIRLocation(ns, location.start), toI64()); + + if (op) { + module.push_back(op); + } + // TODO: in case of failure attach the error to the NS +}; } // namespace exprs } // namespace serene diff --git a/src/serene/namespace.cpp b/src/serene/namespace.cpp index 26f2b81..ac7a702 100644 --- a/src/serene/namespace.cpp +++ b/src/serene/namespace.cpp @@ -23,10 +23,14 @@ */ #include "serene/namespace.h" +#include "mlir/IR/BuiltinOps.h" +#include "serene/context.h" #include "serene/exprs/expression.h" #include "serene/llvm/IR/Value.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" +#include #include using namespace std; @@ -34,9 +38,11 @@ using namespace llvm; namespace serene { -Namespace::Namespace(llvm::StringRef ns_name, +Namespace::Namespace(SereneContext &ctx, llvm::StringRef ns_name, llvm::Optional filename) - : name(ns_name) { + : ctx(ctx), builder(&ctx.mlirContext), name(ns_name), + // TODO: Fix the unknown location by pointing to the `ns` form + module(mlir::ModuleOp::create(builder.getUnknownLoc(), ns_name)) { if (filename.hasValue()) { this->filename.emplace(filename.getValue().str()); } @@ -56,15 +62,49 @@ mlir::LogicalResult Namespace::setTree(exprs::Ast &t) { std::shared_ptr makeNamespace(SereneContext &ctx, llvm::StringRef name, llvm::Optional filename, bool setCurrent) { - auto nsPtr = std::make_shared(name, filename); + auto nsPtr = std::make_shared(ctx, name, filename); ctx.insertNS(nsPtr); if (setCurrent) { - assert(ctx.setCurrentNS(nsPtr->name) && "Couldn't set the current NS"); + if (!ctx.setCurrentNS(nsPtr->name)) { + throw std::runtime_error("Couldn't set the current NS"); + } } return nsPtr; }; uint Namespace::nextFnCounter() { return fn_counter++; }; + +mlir::OpBuilder &Namespace::getBuilder() { return this->builder; }; +mlir::ModuleOp &Namespace::getModule() { return this->module; }; +SereneContext &Namespace::getContext() { return this->ctx; }; + +mlir::ModuleOp &Namespace::generate() { + for (auto &x : getTree()) { + x->generateIR(*this); + } + + return module; +} + +mlir::LogicalResult Namespace::runPasses() { return ctx.pm.run(module); }; + +void Namespace::dumpSLIR() { + mlir::ModuleOp &m = generate(); + m->dump(); +}; + +void Namespace::dumpToIR() { + // We don't want this module just yet + + mlir::ModuleOp &m = generate(); + if (mlir::failed(runPasses())) { + // TODO: throw a proper errer + return; + } + + m->dump(); +}; + Namespace::~Namespace() {} } // namespace serene diff --git a/src/serene/sir/dialect.cpp b/src/serene/sir/dialect.cpp deleted file mode 100644 index c5be304..0000000 --- a/src/serene/sir/dialect.cpp +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#include "serene/sir/dialect.hpp" - -#include "mlir/IR/Builders.h" -#include "mlir/IR/BuiltinTypes.h" -#include "mlir/IR/OpImplementation.h" - -namespace serene { -namespace sir { - -/// Dialect initialization, the instance will be owned by the context. This is -/// the point of registration of types and operations for the dialect. -void SereneDialect::initialize() { - addOperations< -#define GET_OP_LIST -#include "serene/sir/ops.cpp.inc" - >(); -} - -} // namespace sir -} // namespace serene - -#define GET_OP_CLASSES -#include "serene/sir/ops.cpp.inc" diff --git a/src/serene/sir/generator.cpp b/src/serene/sir/generator.cpp deleted file mode 100644 index 2bee14e..0000000 --- a/src/serene/sir/generator.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "serene/sir/generator.hpp" -#include "mlir/IR/Builders.h" -#include "mlir/IR/BuiltinOps.h" -#include "mlir/IR/Identifier.h" -#include "mlir/IR/MLIRContext.h" -#include "mlir/IR/Value.h" -#include "serene/expr.hpp" -#include "serene/sir/dialect.hpp" -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/ScopedHashTable.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" - -namespace serene { -namespace sir { - -mlir::ModuleOp Generator::generate() { - // for (auto x : ns->Tree()) { - // generate(x.get()); - // } - - return module; -}; - -mlir::Operation *Generator::generate(AExpr *x) { - // switch (x->getType()) { - // case SereneType::Number: { - // return generate(llvm::cast(x)); - // } - - // case SereneType::List: { - // generate(llvm::cast(x)); - // return nullptr; - // } - - // default: { - return builder.create(builder.getUnknownLoc(), (uint64_t)3); - // } - // } -}; - -mlir::Value Generator::generate(List *l) { - // auto first = l->at(0); - - // if (!first) { - // // Empty list. - // // TODO: Return Nil or empty list. - - // // Just for now. - // return builder.create(builder.getUnknownLoc(), (uint64_t)0); - // } - - // if (first->get()->getType() == SereneType::Symbol) { - // auto fnNameSymbol = llvm::dyn_cast(first->get()); - - // if (fnNameSymbol->getName() == "fn") { - // if (l->count() <= 3) { - // module.emitError("'fn' form needs exactly 2 arguments."); - // } - - // auto args = llvm::dyn_cast(l->at(1).getValue().get()); - // auto body = llvm::dyn_cast(l->from(2).get()); - - // if (!args) { - // module.emitError("The first element of 'def' has to be a symbol."); - // } - - // // Create a new anonymous function and push it to the anonymous - // functions - // // map, later on we - // auto loc(fnNameSymbol->location->start); - // auto anonymousName = fmt::format("__fn_{}__", anonymousFnCounter); - // anonymousFnCounter++; - - // auto fn = generateFn(loc, anonymousName, args, body); - // mlir::Identifier fnid = builder.getIdentifier(anonymousName); - // anonymousFunctions.insert({fnid, fn}); - // return builder.create(builder.getUnknownLoc(), fnid.str()); - // } - // } - // // auto rest = l->from(1); - // // auto loc = toMLIRLocation(&first->get()->location->start); - // // for (auto x : *rest) { - // // generate(x.get()); - // // } - - return builder.create(builder.getUnknownLoc(), (uint64_t)100); -}; - -// mlir::FuncOp Generator::generateFn(serene::reader::Location loc, -// std::string name, List *args, List *body) -// { - -// auto location = toMLIRLocation(&loc); -// llvm::SmallVector arg_types(args->count(), -// builder.getI64Type()); -// auto func_type = builder.getFunctionType(arg_types, builder.getI64Type()); -// auto proto = mlir::FuncOp::create(location, name, func_type); -// mlir::FuncOp fn(proto); - -// if (!fn) { -// module.emitError("Can not create the function."); -// } - -// auto &entryBlock = *fn.addEntryBlock(); -// llvm::ScopedHashTableScope -// scope(symbolTable); - -// // Declare all the function arguments in the symbol table. -// for (const auto arg : -// llvm::zip(args->asArrayRef(), entryBlock.getArguments())) { - -// auto argSymbol = llvm::dyn_cast(std::get<0>(arg).get()); -// if (!argSymbol) { -// module.emitError("Function parameters must be symbols"); -// } -// if (symbolTable.count(argSymbol->getName())) { -// return nullptr; -// } -// symbolTable.insert(argSymbol->getName(), std::get<1>(arg)); -// } - -// // Set the insertion point in the builder to the beginning of the function -// // body, it will be used throughout the codegen to create operations in -// this -// // function. -// builder.setInsertionPointToStart(&entryBlock); - -// // Emit the body of the function. -// if (!generate(body)) { -// fn.erase(); -// return nullptr; -// } - -// // // Implicitly return void if no return statement was emitted. -// // // FIXME: we may fix the parser instead to always return the last -// // expression -// // // (this would possibly help the REPL case later) -// // ReturnOp returnOp; - -// // if (!entryBlock.empty()) -// // returnOp = dyn_cast(entryBlock.back()); -// // if (!returnOp) { -// // builder.create(loc(funcAST.getProto()->loc())); -// // } else if (returnOp.hasOperand()) { -// // // Otherwise, if this return operation has an operand then add a -// result -// // to -// // // the function. -// // function.setType(builder.getFunctionType(function.getType().getInputs(), -// // getType(VarType{}))); -// // } - -// return fn; -// } - -mlir::Operation *Generator::generate(Number *x) { - return builder.create(builder.getUnknownLoc(), x->toI64()); -}; - -/** - * Convert a Serene location to MLIR FileLineLoc Location - */ -::mlir::Location Generator::toMLIRLocation(serene::reader::Location *loc) { - auto file = ns->filename; - std::string filename{file.getValueOr("REPL")}; - - return mlir::FileLineColLoc::get(builder.getIdentifier(filename), loc->line, - loc->col); -} - -Generator::~Generator(){}; -} // namespace sir - -} // namespace serene diff --git a/src/serene/sir/sir.cpp b/src/serene/sir/sir.cpp deleted file mode 100644 index a965910..0000000 --- a/src/serene/sir/sir.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "serene/sir/sir.hpp" -#include "mlir/IR/MLIRContext.h" -#include "serene/exprs/expression.h" -#include "serene/sir/dialect.hpp" -#include "serene/sir/generator.hpp" -#include - -namespace serene { -namespace sir { -SIR::SIR() { context.getOrLoadDialect<::serene::sir::SereneDialect>(); } - -mlir::OwningModuleRef SIR::generate(::serene::Namespace *ns) { - auto g = std::make_unique(context, ns); - - return g->generate(); -}; - -SIR::~SIR() {} - -void dumpSIR(exprs::ast &t) { - auto ns = new ::serene::Namespace("user", llvm::None); - - SIR s{}; - - if (failed(ns->setTree(t))) { - llvm::errs() << "Can't set the body of the namespace"; - return; - } - - auto module = s.generate(ns); - module->dump(); -}; - -} // namespace sir -} // namespace serene diff --git a/src/serene/sir/value_op.cpp b/src/serene/sir/value_op.cpp deleted file mode 100644 index d901296..0000000 --- a/src/serene/sir/value_op.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Serene programming language. - * - * Copyright (c) 2020 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "mlir/IR/Builders.h" -#include "mlir/IR/MLIRContext.h" -#include "mlir/IR/Value.h" -#include "serene/sir/dialect.hpp" -#include "serene/sir/sir.hpp" -#include "llvm/Support/Casting.h" - -namespace serene { -namespace sir {} // namespace sir -} // namespace serene diff --git a/src/serene/slir/generator.cpp b/src/serene/slir/generatable.cpp similarity index 59% rename from src/serene/slir/generator.cpp rename to src/serene/slir/generatable.cpp index 67a4da0..cbd8c5f 100644 --- a/src/serene/slir/generator.cpp +++ b/src/serene/slir/generatable.cpp @@ -22,14 +22,16 @@ * SOFTWARE. */ -#include "serene/slir/generator.h" +#include "serene/slir/generatable.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/Identifier.h" #include "mlir/IR/MLIRContext.h" #include "mlir/IR/Value.h" -#include "serene/exprs/expression.h" +#include "mlir/Support/LogicalResult.h" +//#include "serene/exprs/expression.h" #include "serene/exprs/traits.h" +#include "serene/namespace.h" #include "serene/slir/dialect.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopedHashTable.h" @@ -40,83 +42,82 @@ namespace serene { namespace slir { -mlir::ModuleOp Generator::generate() { - for (auto &x : ns->getTree()) { - auto *num = llvm::dyn_cast(x.get()); - if (num) { - generate(*num); - } else { - llvm::outs() << "else\n"; - } - } - - return module; +template mlir::ModuleOp &Generatable::generate() { + return this->Object().generate(); }; -mlir::Operation *Generator::generate(exprs::Expression *x) { - // switch (x->getType()) { - // case SereneType::Number: { - // return generate(llvm::cast(x)); - // } - - // case SereneType::List: { - // generate(llvm::cast(x)); - // return nullptr; - // } - - // default: { - return builder.create(builder.getUnknownLoc(), (uint64_t)3); - // } - // } +template mlir::LogicalResult Generatable::runPasses() { + return this->Object().runPasses(); }; -mlir::Value Generator::generate(exprs::List *l) { - // auto first = l->at(0); - - // if (!first) { - // // Empty list. - // // TODO: Return Nil or empty list. - - // // Just for now. - // return builder.create(builder.getUnknownLoc(), (uint64_t)0); - // } - - // if (first->get()->getType() == SereneType::Symbol) { - // auto fnNameSymbol = llvm::dyn_cast(first->get()); - - // if (fnNameSymbol->getName() == "fn") { - // if (l->count() <= 3) { - // module.emitError("'fn' form needs exactly 2 arguments."); - // } - - // auto args = llvm::dyn_cast(l->at(1).getValue().get()); - // auto body = llvm::dyn_cast(l->from(2).get()); - - // if (!args) { - // module.emitError("The first element of 'def' has to be a symbol."); - // } - - // // Create a new anonymous function and push it to the anonymous - // functions - // // map, later on we - // auto loc(fnNameSymbol->location->start); - // auto anonymousName = fmt::format("__fn_{}__", anonymousFnCounter); - // anonymousFnCounter++; - - // auto fn = generateFn(loc, anonymousName, args, body); - // mlir::Identifier fnid = builder.getIdentifier(anonymousName); - // anonymousFunctions.insert({fnid, fn}); - // return builder.create(builder.getUnknownLoc(), fnid.str()); - // } - // } - // // auto rest = l->from(1); - // // auto loc = toMLIRLocation(&first->get()->location->start); - // // for (auto x : *rest) { - // // generate(x.get()); - // // } - return builder.create(builder.getUnknownLoc(), (uint64_t)100); +template void Generatable::dumpSLIR() { + this->Object().dumpSLIR(); }; +// mlir::Operation *Generatable::generate(exprs::Expression *x) { +// switch (x->getType()) { +// case SereneType::Number: { +// return generate(llvm::cast(x)); +// } + +// case SereneType::List: { +// generate(llvm::cast(x)); +// return nullptr; +// } + +// default: { +// return builder.create(builder.getUnknownLoc(), (uint64_t)3); +// } +// } +//}; + +// mlir::Value Generator::generate(exprs::List *l) { +// auto first = l->at(0); + +// if (!first) { +// // Empty list. +// // TODO: Return Nil or empty list. + +// // Just for now. +// return builder.create(builder.getUnknownLoc(), (uint64_t)0); +// } + +// if (first->get()->getType() == SereneType::Symbol) { +// auto fnNameSymbol = llvm::dyn_cast(first->get()); + +// if (fnNameSymbol->getName() == "fn") { +// if (l->count() <= 3) { +// module.emitError("'fn' form needs exactly 2 arguments."); +// } + +// auto args = llvm::dyn_cast(l->at(1).getValue().get()); +// auto body = llvm::dyn_cast(l->from(2).get()); + +// if (!args) { +// module.emitError("The first element of 'def' has to be a symbol."); +// } + +// // Create a new anonymous function and push it to the anonymous +// functions +// // map, later on we +// auto loc(fnNameSymbol->location->start); +// auto anonymousName = fmt::format("__fn_{}__", anonymousFnCounter); +// anonymousFnCounter++; + +// auto fn = generateFn(loc, anonymousName, args, body); +// mlir::Identifier fnid = builder.getIdentifier(anonymousName); +// anonymousFunctions.insert({fnid, fn}); +// return builder.create(builder.getUnknownLoc(), fnid.str()); +// } +// } +// // auto rest = l->from(1); +// // auto loc = toMLIRLocation(&first->get()->location->start); +// // for (auto x : *rest) { +// // generate(x.get()); +// // } +// return builder.create(builder.getUnknownLoc(), (uint64_t)100); +//}; + // mlir::FuncOp Generator::generateFn(serene::reader::Location loc, // std::string name, List *args, List *body) // { @@ -183,28 +184,6 @@ mlir::Value Generator::generate(exprs::List *l) { // return fn; // } - -void Generator::generate(exprs::Number &x) { - auto op = - builder.create(toMLIRLocation(x.location.start), x.toI64()); - - if (op) { - module.push_back(op); - } -}; - -/** - * Convert a Serene location to MLIR FileLineLoc Location - */ -::mlir::Location Generator::toMLIRLocation(serene::reader::Location &loc) { - auto file = this->ns->filename; - std::string filename{file.getValueOr("REPL")}; - - return mlir::FileLineColLoc::get(builder.getIdentifier(filename), loc.line, - loc.col); -} - -Generator::~Generator(){}; } // namespace slir } // namespace serene diff --git a/src/serene/slir/slir.cpp b/src/serene/slir/slir.cpp deleted file mode 100644 index 77d0a0c..0000000 --- a/src/serene/slir/slir.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -*- C++ -*- - * Serene programming language. - * - * Copyright (c) 2019-2021 Sameer Rahmani - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#include "serene/slir/slir.h" -#include "mlir/IR/MLIRContext.h" -#include "serene/exprs/expression.h" -#include "serene/namespace.h" -#include "serene/slir/dialect.h" -#include "serene/slir/generator.h" -#include "llvm/Support/raw_ostream.h" -#include - -namespace serene { -namespace slir { - -SLIR::SLIR(serene::SereneContext &ctx) : context(ctx) { - context.mlirContext.getOrLoadDialect(); -} - -mlir::OwningModuleRef SLIR::generate(llvm::StringRef ns_name) { - auto g = std::make_unique(context, ns_name); - - return g->generate(); -}; - -SLIR::~SLIR() {} - -void dumpSLIR(serene::SereneContext &ctx, llvm::StringRef ns_name) { - SLIR s(ctx); - auto ns = ctx.getNS(ns_name); - - assert(ns && "No such a namespace to dump!"); - - auto module = s.generate(ns_name); - - if (mlir::failed(ctx.pm.run(*module))) { - // TODO: throw a proper errer - llvm::outs() << "Pass manager has faild!\n"; - } - - module->dump(); -}; - -} // namespace slir -} // namespace serene diff --git a/include/serene/sir/dialect.hpp b/src/serene/slir/utils.cpp similarity index 67% rename from include/serene/sir/dialect.hpp rename to src/serene/slir/utils.cpp index 949fb90..20acc6b 100644 --- a/include/serene/sir/dialect.hpp +++ b/src/serene/slir/utils.cpp @@ -1,7 +1,7 @@ -/** +/* -*- C++ -*- * Serene programming language. * - * Copyright (c) 2020 Sameer Rahmani + * Copyright (c) 2019-2021 Sameer Rahmani * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -22,22 +22,19 @@ * SOFTWARE. */ -#ifndef DIALECT_H_ -#define DIALECT_H_ - #include "mlir/IR/BuiltinOps.h" -#include "mlir/IR/Dialect.h" -#include "mlir/Interfaces/SideEffectInterfaces.h" +#include "serene/namespace.h" +#include "serene/reader/location.h" -// Include the auto-generated header file containing the declaration of the -// serene's dialect. -#include "serene/sir/dialect.hpp.inc" +namespace serene::slir { +::mlir::Location toMLIRLocation(serene::Namespace &ns, + serene::reader::Location &loc) { + mlir::OpBuilder &builder = ns.getBuilder(); + auto file = ns.filename; + std::string filename{file.getValueOr("REPL")}; -// Include the auto-generated header file containing the declarations of the -// serene's operations. -// for more on GET_OP_CLASSES: https://mlir.llvm.org/docs/OpDefinitions/ -#define GET_OP_CLASSES + return mlir::FileLineColLoc::get(builder.getIdentifier(filename), loc.line, + loc.col); +} -#include "serene/sir/ops.hpp.inc" - -#endif // DIALECT_H_ +} // namespace serene::slir