mirror of https://github.com/llvm/circt.git
Create the sketch of a FIRRTL dialect, with a single type (firrtl.uint) and a
single registered operations (firrtl.add). Add a testcase showing that these are now being properly checked.
This commit is contained in:
parent
71b7e2cb93
commit
24c3b33447
|
@ -9,10 +9,12 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules")
|
|||
|
||||
|
||||
## Should get this from MLIR build files somehow?
|
||||
set(MLIR_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../llvm-project/mlir/include )
|
||||
set(MLIR_TABLEGEN_EXE mlir-tblgen)
|
||||
set(MLIR_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../llvm-project/mlir)
|
||||
set(MLIR_MAIN_SRC_DIR ${MLIR_SOURCE_DIR})
|
||||
set(MLIR_INCLUDE_DIR ${MLIR_SOURCE_DIR}/include )
|
||||
set(MLIR_BINARY_INCLUDE_DIR ${LLVM_TOOLS_BINARY_DIR}/../tools/mlir/include )
|
||||
|
||||
include(AddSPT)
|
||||
|
||||
# Installing the headers and docs needs to depend on generating any public
|
||||
# tablegen'd targets.
|
||||
|
@ -23,9 +25,10 @@ add_custom_target(spt-doc)
|
|||
include_directories( ${MLIR_INCLUDE_DIR})
|
||||
include_directories( ${MLIR_BINARY_INCLUDE_DIR})
|
||||
include_directories( ${SPT_INCLUDE_DIR})
|
||||
include_directories( ${SPT_MAIN_SRC_DIR})
|
||||
|
||||
#add_subdirectory(include/spt)
|
||||
#add_subdirectory(lib)
|
||||
add_subdirectory(include/spt)
|
||||
add_subdirectory(lib)
|
||||
add_subdirectory(tools)
|
||||
#add_subdirectory(unittests)
|
||||
add_subdirectory(test)
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
#function(spt_tablegen ofn)
|
||||
# tablegen(SPT ${ARGV} "-I${SPT_MAIN_SRC_DIR}" "-I${SPT_INCLUDE_DIR}")
|
||||
# set(TABLEGEN_OUTPUT ${TABLEGEN_OUTPUT} ${CMAKE_CURRENT_BINARY_DIR}/${ofn}
|
||||
# PARENT_SCOPE)
|
||||
#endfunction()
|
||||
|
||||
# TODO: This is to handle the current static registration, but should be
|
||||
# factored out a bit.
|
||||
#function(whole_archive_link target)
|
||||
# add_dependencies(${target} ${ARGN})
|
||||
# if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
|
||||
# set(link_flags "-L${CMAKE_BINARY_DIR}/lib ")
|
||||
# FOREACH(LIB ${ARGN})
|
||||
# string(CONCAT link_flags ${link_flags} "-Wl,-force_load ${CMAKE_BINARY_DIR}/lib/lib${LIB}.a ")
|
||||
# ENDFOREACH(LIB)
|
||||
# elseif(MSVC)
|
||||
# FOREACH(LIB ${ARGN})
|
||||
# string(CONCAT link_flags ${link_flags} "/WHOLEARCHIVE:${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/${LIB}.lib ")
|
||||
# ENDFOREACH(LIB)
|
||||
# else()
|
||||
# set(link_flags "-L${CMAKE_BINARY_DIR}/lib -Wl,--whole-archive,")
|
||||
# FOREACH(LIB ${ARGN})
|
||||
# string(CONCAT link_flags ${link_flags} "-l${LIB},")
|
||||
# ENDFOREACH(LIB)
|
||||
# string(CONCAT link_flags ${link_flags} "--no-whole-archive")
|
||||
# endif()
|
||||
# set_target_properties(${target} PROPERTIES LINK_FLAGS ${link_flags})
|
||||
#endfunction(whole_archive_link)
|
||||
|
||||
# Declare a dialect in the include directory
|
||||
#function(add_mlir_dialect dialect dialect_doc_filename)
|
||||
# set(LLVM_TARGET_DEFINITIONS ${dialect}.td)
|
||||
# mlir_tablegen(${dialect}.h.inc -gen-op-decls)
|
||||
# mlir_tablegen(${dialect}.cpp.inc -gen-op-defs)
|
||||
# add_public_tablegen_target(MLIR${dialect}IncGen)
|
||||
# add_dependencies(mlir-headers MLIR${dialect}IncGen)
|
||||
|
||||
# # Generate Dialect Documentation
|
||||
# set(LLVM_TARGET_DEFINITIONS ${dialect_doc_filename}.td)
|
||||
# tablegen(MLIR ${dialect_doc_filename}.md -gen-op-doc "-I${MLIR_MAIN_SRC_DIR}" "-I${MLIR_INCLUDE_DIR}")
|
||||
# set(GEN_DOC_FILE ${MLIR_BINARY_DIR}/docs/Dialects/${dialect_doc_filename}.md)
|
||||
# add_custom_command(
|
||||
# OUTPUT ${GEN_DOC_FILE}
|
||||
# COMMAND ${CMAKE_COMMAND} -E copy
|
||||
# ${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md
|
||||
# ${GEN_DOC_FILE}
|
||||
# DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${dialect_doc_filename}.md)
|
||||
# add_custom_target(${dialect_doc_filename}DocGen DEPENDS ${GEN_DOC_FILE})
|
||||
# add_dependencies(mlir-doc ${dialect_doc_filename}DocGen)
|
||||
#endfunction()
|
||||
|
||||
# Declare the library associated with a dialect.
|
||||
#function(add_mlir_dialect_library name)
|
||||
# set_property(GLOBAL APPEND PROPERTY MLIR_DIALECT_LIBS ${name})
|
||||
# add_llvm_library(${ARGV})
|
||||
#endfunction(add_mlir_dialect_library)
|
||||
|
||||
# Declare the library associated with a conversion.
|
||||
#function(add_mlir_conversion_library name)
|
||||
# set_property(GLOBAL APPEND PROPERTY MLIR_CONVERSION_LIBS ${name})
|
||||
# add_llvm_library(${ARGV})
|
||||
#endfunction(add_mlir_conversion_library)
|
|
@ -0,0 +1,2 @@
|
|||
add_subdirectory(Dialect)
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
add_subdirectory(FIRRTL)
|
||||
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(IR)
|
|
@ -0,0 +1,3 @@
|
|||
add_mlir_dialect(FIRRTL FIRRTL)
|
||||
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
//===- FIRRTL.td - FIRRTL dialect definition ---------------*- tablegen -*-===//
|
||||
//
|
||||
// This is the operation definition file for FIRRTL dialect operations.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef FIRRTL_OPS
|
||||
#define FIRRTL_OPS
|
||||
|
||||
include "mlir/IR/OpBase.td"
|
||||
|
||||
def FIRRTLDialect : Dialect {
|
||||
let name = "firrtl";
|
||||
|
||||
let summary = "Types and operations for firrtl dialect";
|
||||
let description = [{
|
||||
This dialect defines the `firrtl` dialect, which is used to lower from
|
||||
Chisel code to Verilog. For more information, see the
|
||||
[FIRRTL GitHub page](https://github.com/freechipsproject/firrtl).
|
||||
}];
|
||||
|
||||
let cppNamespace = "firrtl";
|
||||
}
|
||||
|
||||
def FIRRTL_UIntType : DialectType<FIRRTLDialect,
|
||||
CPred<"$_self.isa<UIntType>()">, "UInt type"> {
|
||||
let typeDescription = [{
|
||||
`firrtl.UInt` is an unsigned integer of unknown width.
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// FIRRTL op definitions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Base class for the operation in this dialect
|
||||
class FIRRTLOp<string mnemonic, list<OpTrait> traits = []> :
|
||||
Op<FIRRTLDialect, mnemonic, traits>;
|
||||
|
||||
|
||||
// TODO: Should this be split out to addu/adds?
|
||||
def FIRRTLAddOp : FIRRTLOp<"add", [Commutative]> {
|
||||
let summary = "Add operations";
|
||||
let description = [{
|
||||
Add Operation: x = add (y, z)
|
||||
|
||||
The two options are:
|
||||
* add(UInt, UInt) -> UInt
|
||||
* add(SInt, SInt) -> SInt
|
||||
|
||||
The result width is max(we1, we2)+1
|
||||
The add operation result is the sum of e1 and e2 without loss of precision.
|
||||
}];
|
||||
|
||||
let arguments = (ins AnyType:$lhs, AnyType:$rhs);
|
||||
let results = (outs AnyType:$result);
|
||||
}
|
||||
|
||||
#endif // FIRRTL_OPS
|
|
@ -0,0 +1,56 @@
|
|||
//===- FIRRTL.h - FIRRTL dialect --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// This file defines an MLIR dialect for the FIRRTL IR.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SPT_DIALECT_FIRRTL_FIRRTL_H
|
||||
#define SPT_DIALECT_FIRRTL_FIRRTL_H
|
||||
|
||||
#include "mlir/IR/Dialect.h"
|
||||
#include "mlir/IR/OpDefinition.h"
|
||||
|
||||
namespace spt {
|
||||
namespace firrtl {
|
||||
using namespace mlir;
|
||||
|
||||
class FIRRTLDialect : public Dialect {
|
||||
public:
|
||||
/// Create the dialect in the given `context`.
|
||||
explicit FIRRTLDialect(MLIRContext *context);
|
||||
~FIRRTLDialect();
|
||||
|
||||
Type parseType(DialectAsmParser &parser) const override;
|
||||
void printType(Type, DialectAsmPrinter &) const override;
|
||||
|
||||
static StringRef getDialectNamespace() { return "firrtl"; }
|
||||
};
|
||||
|
||||
namespace FIRRTLTypes {
|
||||
enum Kind {
|
||||
UInt = Type::FIRST_PRIVATE_EXPERIMENTAL_0_TYPE,
|
||||
};
|
||||
} // namespace FIRRTLTypes
|
||||
|
||||
// A unsigned integer type with unknown width.
|
||||
class UIntType : public Type::TypeBase<UIntType, Type> {
|
||||
public:
|
||||
using Base::Base;
|
||||
|
||||
static UIntType get(MLIRContext *context) {
|
||||
return Base::get(context, FIRRTLTypes::Kind::UInt);
|
||||
}
|
||||
|
||||
/// Support method to enable LLVM-style type casting.
|
||||
static bool kindof(unsigned kind) {
|
||||
return kind == FIRRTLTypes::Kind::UInt;
|
||||
}
|
||||
};
|
||||
|
||||
#define GET_OP_CLASSES
|
||||
#include "spt/Dialect/FIRRTL/IR/FIRRTL.h.inc"
|
||||
|
||||
} // namespace firrtl
|
||||
} // namespace spt
|
||||
|
||||
#endif // SPT_DIALECT_FIRRTL_FIRRTL_H
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(Dialect)
|
|
@ -0,0 +1 @@
|
|||
add_subdirectory(FIRRTL)
|
|
@ -0,0 +1,9 @@
|
|||
file(GLOB globbed *.c *.cpp)
|
||||
add_mlir_dialect_library(MLIRFIRRTL
|
||||
${globbed}
|
||||
|
||||
ADDITIONAL_HEADER_DIRS
|
||||
${SPT_MAIN_INCLUDE_DIR}/spt/Dialect/FIRRTL
|
||||
)
|
||||
add_dependencies(MLIRFIRRTL MLIRFIRRTLIncGen LLVMSupport)
|
||||
target_link_libraries(MLIRFIRRTL LLVMSupport)
|
|
@ -0,0 +1,47 @@
|
|||
//===- Dialect.cpp - Implement the FIRRTL dialect -------------------------===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "spt/Dialect/FIRRTL/IR/Ops.h"
|
||||
#include "mlir/IR/StandardTypes.h"
|
||||
#include "mlir/IR/DialectImplementation.h"
|
||||
|
||||
using namespace spt;
|
||||
using namespace firrtl;
|
||||
|
||||
FIRRTLDialect::FIRRTLDialect(MLIRContext *context)
|
||||
: Dialect(getDialectNamespace(), context) {
|
||||
addTypes<UIntType>();
|
||||
addOperations<
|
||||
#define GET_OP_LIST
|
||||
#include "spt/Dialect/FIRRTL/IR/FIRRTL.cpp.inc"
|
||||
>();
|
||||
|
||||
// Support unknown operations because not all LLVM operations are registered.
|
||||
// FIXME(clattner): remove this.
|
||||
allowUnknownOperations();
|
||||
}
|
||||
|
||||
FIRRTLDialect::~FIRRTLDialect() {
|
||||
}
|
||||
|
||||
/// Parse a type registered to this dialect.
|
||||
Type FIRRTLDialect::parseType(DialectAsmParser &parser) const {
|
||||
StringRef tyData = parser.getFullSymbolSpec();
|
||||
|
||||
if (tyData == "uint")
|
||||
return UIntType::get(getContext());
|
||||
|
||||
parser.emitError(parser.getNameLoc(), "unknown firrtl type");
|
||||
return Type();
|
||||
}
|
||||
|
||||
void FIRRTLDialect::printType(Type type, DialectAsmPrinter &os) const {
|
||||
auto uintType = type.dyn_cast<UIntType>();
|
||||
assert(uintType && "printing wrong type");
|
||||
os.getStream() << "uint";
|
||||
}
|
||||
|
||||
|
||||
#define GET_OP_CLASSES
|
||||
#include "spt/Dialect/FIRRTL/IR/FIRRTL.cpp.inc"
|
|
@ -0,0 +1,10 @@
|
|||
//===- DialectRegistration.cpp - Register FIRRTL dialect ------------------===//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "spt/Dialect/FIRRTL/IR/Ops.h"
|
||||
using namespace spt;
|
||||
using namespace firrtl;
|
||||
|
||||
// Static initialization for FIRRTL dialect registration.
|
||||
static mlir::DialectRegistration<FIRRTLDialect> FIRRTLOps;
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: spt-opt %s -split-input-file -verify-diagnostics
|
||||
|
||||
"firrtl.module"() ( {
|
||||
// expected-error @+1 {{unknown firrtl type}}
|
||||
%0 = "firrtl.input"() {name = "in"} : () -> !firrtl.unknowntype
|
||||
}) {name = "MyModule"} : () -> ()
|
||||
|
||||
// -----
|
||||
|
||||
"firrtl.module"() ( {
|
||||
%0 = "firrtl.output"() {name = "out"} : () -> !firrtl.uint
|
||||
%1 = "firrtl.input"() {name = "b"} : () -> ui32
|
||||
%2 = "firrtl.input"() {name = "d"} : () -> ui16
|
||||
// expected-error @+1 {{'firrtl.add' op expected 2 operands, but found 3}}
|
||||
%3 = "firrtl.add"(%1, %2, %3) : (ui32, ui16, ui32) -> ui32
|
||||
}) {name = "Top"} : () -> ()
|
|
@ -1,4 +1,6 @@
|
|||
set(LIBS
|
||||
MLIRFIRRTL
|
||||
|
||||
MLIRParser
|
||||
MLIRSupport
|
||||
MLIRIR
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "spt/Dialect/FIRRTL/IR/Ops.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/Pass/PassManager.h"
|
||||
#include "mlir/Pass/PassRegistry.h"
|
||||
|
@ -16,6 +17,7 @@
|
|||
|
||||
using namespace llvm;
|
||||
using namespace mlir;
|
||||
using namespace spt;
|
||||
|
||||
static cl::opt<std::string>
|
||||
inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
|
||||
|
@ -50,6 +52,7 @@ int main(int argc, char **argv) {
|
|||
InitLLVM y(argc, argv);
|
||||
|
||||
registerDialect<StandardOpsDialect>();
|
||||
registerDialect<firrtl::FIRRTLDialect>();
|
||||
|
||||
// Register any pass manager command line options.
|
||||
registerPassManagerCLOptions();
|
||||
|
|
Loading…
Reference in New Issue