Add a barebone MLIR dialect with the necessary cmake changes"

This commit is contained in:
Sameer Rahmani 2021-03-25 00:53:44 +00:00
parent 737b6e1a41
commit 50c2054f0a
14 changed files with 250 additions and 10 deletions

View File

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.16)
project(Serene
VERSION 0.1.0
DESCRIPTION "Serene language is a modern Lisp."
LANGUAGES CXX)
LANGUAGES CXX C)
set(CMAKE_EXPORT_COMPILE_COMMANDS 1)
@ -13,7 +13,7 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
## Settings -----------------------------------------
# specify the C++ standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include)
@ -66,15 +66,37 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
include(FetchContent)
find_package(LLVM REQUIRED CONFIG)
find_package(MLIR REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
message(STATUS "Using MLIRConfig.cmake in: ${MLIR_DIR}")
set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/bin)
set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/lib)
set(MLIR_BINARY_DIR ${CMAKE_BINARY_DIR})
list(APPEND CMAKE_MODULE_PATH "${MLIR_CMAKE_DIR}")
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_DIR}")
include(TableGen)
include(AddLLVM)
include(AddMLIR)
include(HandleLLVMOptions)
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${MLIR_INCLUDE_DIRS})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(${PROJECT_BINARY_DIR}/include)
link_directories(${LLVM_BUILD_LIBRARY_DIR})
add_definitions(${LLVM_DEFINITIONS})
include_directories(${LLVM_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})
llvm_map_components_to_libnames(llvm_libs support core irreader)
# Formatting library
FetchContent_Declare(
fmtlib
@ -90,6 +112,8 @@ if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
# The executable code is here
add_subdirectory(bin)
add_subdirectory(include)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include/)
# Testing only available if this is the main app
# Emergency override SERENE_CMAKE_BUILD_TESTING provided as well
if((CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME OR SERENE_CMAKE_BUILD_TESTING) AND BUILD_TESTING)

View File

@ -1,10 +1,18 @@
add_executable(serene serene.cpp)
target_compile_features(serene PRIVATE cxx_std_20)
# Make sure to generate files related to the dialects first
add_dependencies(serene SereneDialectGen)
target_compile_features(serene PRIVATE cxx_std_14)
target_link_libraries(serene PRIVATE
lserene
${llvm_libs}
fmt::fmt
MLIRAnalysis
MLIRIR
MLIRParser
MLIRSideEffectInterfaces
MLIRTransforms
)

View File

@ -24,6 +24,7 @@
#include "serene/serene.hpp"
#include "serene/reader.hpp"
#include "serene/sir/sir.hpp"
#include <iostream>
#include <llvm/Support/CommandLine.h>
@ -33,7 +34,7 @@ using namespace serene;
namespace cl = llvm::cl;
namespace {
enum Action { None, DumpAST };
enum Action { None, DumpAST, DumpIR };
}
static cl::opt<std::string> inputFile(cl::Positional,
@ -43,6 +44,7 @@ static cl::opt<std::string> inputFile(cl::Positional,
static cl::opt<enum Action>
emitAction("emit", cl::desc("Select what to dump."),
cl::values(clEnumValN(DumpIR, "sir", "Output the SLIR only")),
cl::values(clEnumValN(DumpAST, "ast", "Output the AST only")));
int main(int argc, char *argv[]) {
@ -52,6 +54,14 @@ int main(int argc, char *argv[]) {
case Action::DumpAST: {
FileReader *r = new FileReader(inputFile);
r->dumpAST();
delete r;
return 0;
}
case Action::DumpIR: {
FileReader *r = new FileReader(inputFile);
serene::sir::dumpSIR(r->read());
delete r;
return 0;
}
default: {

1
include/CMakeLists.txt Normal file
View File

@ -0,0 +1 @@
add_subdirectory("serene/sir/")

View File

@ -27,6 +27,7 @@
#include "serene/expr.hpp"
#include "serene/llvm/IR/Value.h"
#include "llvm/ADT/Optional.h"
#include <list>
#include <string>
@ -45,7 +46,7 @@ public:
void cons(ast_node f);
void append(ast_node t);
std::optional<ast_node> at(uint index) const;
llvm::Optional<ast_node> at(uint index) const;
};
using ast_list_node = std::unique_ptr<List>;

View File

@ -0,0 +1,5 @@
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)

View File

@ -0,0 +1,43 @@
/**
* Serene programming language.
*
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
*
* 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 DIALECT_H_
#define DIALECT_H_
#include "mlir/IR/BuiltinOps.h"
#include "mlir/IR/Dialect.h"
#include "mlir/Interfaces/SideEffectInterfaces.h"
// Include the auto-generated header file containing the declaration of the
// serene's dialect.
#include "serene/sir/dialect.hpp.inc"
// 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
#include "serene/sir/ops.hpp.inc"
#endif // DIALECT_H_

View File

@ -0,0 +1,12 @@
#ifndef SERENE_DIALECT
#define SERENE_DIALECT
include "mlir/IR/OpBase.td"
//include "mlir/Interfaces/SideEffectInterfaces.td"
def Serene_Dialect : Dialect {
let name = "serene";
let cppNamespace = "::serene::sir";
}
#endif // SERENE_DIALECT

View File

@ -0,0 +1,46 @@
/**
* Serene programming language.
*
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
*
* 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 SIR_H
#define SIR_H
#include "mlir/IR/MLIRContext.h"
#include "serene/expr.hpp"
namespace serene {
namespace sir {
class SIR {
mlir::MLIRContext context;
public:
SIR();
~SIR();
};
void dumpSIR(std::unique_ptr<ast_tree>);
} // namespace sir
} // namespace serene
#endif

View File

@ -5,6 +5,8 @@ set(HEADER_LIST
"${INCLUDE_DIR}/serene/expr.hpp"
"${INCLUDE_DIR}/serene/serene.hpp"
"${INCLUDE_DIR}/serene/state.hpp"
"${INCLUDE_DIR}/serene/sir/sir.hpp"
"${INCLUDE_DIR}/serene/sir/dialect.hpp"
"${INCLUDE_DIR}/serene/namespace.hpp")
# Make an automatic library - will be static or dynamic based on user setting
@ -15,11 +17,15 @@ add_library(lserene
list.cpp
namespace.cpp
state.cpp
sir/sir.cpp
sir/dialect.cpp
${HEADER_LIST})
# Make sure to generate files related to the dialects first
add_dependencies(lserene SereneDialectGen)
# We need this directory, and users of our library will need it too
target_compile_features(lserene PUBLIC cxx_std_20)
target_compile_features(lserene PUBLIC cxx_std_14)
target_include_directories(lserene PRIVATE ${INCLUDE_DIR})
target_include_directories(lserene PUBLIC ${PROJECT_BINARY_DIR})

View File

@ -26,6 +26,7 @@
#include "serene/expr.hpp"
#include "serene/llvm/IR/Value.h"
#include "serene/symbol.hpp"
#include "llvm/ADT/Optional.h"
#include <bits/c++config.h>
#include <fmt/core.h>
#include <string>
@ -34,14 +35,14 @@ using namespace llvm;
namespace serene {
std::optional<ast_node> List::at(uint index) const {
llvm::Optional<ast_node> List::at(uint index) const {
if (index >= nodes_.size()) {
return std::nullopt;
return llvm::None;
}
auto itr = cbegin(nodes_);
std::advance(itr, index);
return std::make_optional(*itr);
return llvm::Optional<ast_node>(*itr);
}
void List::cons(ast_node node) { nodes_.push_front(std::move(node)); }

View File

@ -113,7 +113,7 @@ ast_list_node Reader::read_list(List *list) {
switch (c) {
case EOF:
throw ReadError((char *)"EOF reached before closing of list");
throw ReadError(const_cast<char *>("EOF reached before closing of list"));
case ')':
list_terminated = true;
break;
@ -170,11 +170,15 @@ void Reader::dumpAST() {
}
std::unique_ptr<ast_tree> FileReader::read() {
// TODO: Add support for relative path as well
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> fileOrErr =
llvm::MemoryBuffer::getFileOrSTDIN(file);
if (std::error_code EC = fileOrErr.getError()) {
llvm::errs() << "Could not open input file: " << EC.message() << "\n";
llvm::errs() << fmt::format("File: '{}'\n", file);
llvm::errs() << "Use absolute path for now\n";
return nullptr;
}

43
src/sir/dialect.cpp Normal file
View File

@ -0,0 +1,43 @@
/**
* Serene programming language.
*
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
*
* 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

36
src/sir/sir.cpp Normal file
View File

@ -0,0 +1,36 @@
/**
* Serene programming language.
*
* Copyright (c) 2020 Sameer Rahmani <lxsameer@gnu.org>
*
* 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/expr.hpp"
#include "serene/sir/dialect.hpp"
namespace serene {
namespace sir {
SIR::SIR() { context.getOrLoadDialect<serene::sir::SereneDialect>(); }
void dumpSIR(std::unique_ptr<ast_tree> tree) {}
} // namespace sir
} // namespace serene