diff --git a/CODEOWNERS b/CODEOWNERS index bc7a5abab53f..88add5aeb979 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -50,8 +50,8 @@ lib/Target/ExportSMTLIB @maerhart # SV **/Dialect/SV @darthscsi -# Ibis -**/Dialect/Ibis @teqdruid @mortbopet @blakep-msft +# Kanagawa +**/Dialect/Kanagawa @teqdruid @mortbopet @blakep-msft ## Infra diff --git a/docs/Dialects/Ibis/_index.md b/docs/Dialects/Ibis/_index.md deleted file mode 100644 index 7fc34e70d055..000000000000 --- a/docs/Dialects/Ibis/_index.md +++ /dev/null @@ -1,3 +0,0 @@ -# 'ibis' Dialect - -[include "Dialects/Ibis.md"] diff --git a/docs/Dialects/Ibis/RationaleIbis.md b/docs/Dialects/Kanagawa/RationaleKanagawa.md similarity index 83% rename from docs/Dialects/Ibis/RationaleIbis.md rename to docs/Dialects/Kanagawa/RationaleKanagawa.md index c1e7a6606583..cec49b150271 100644 --- a/docs/Dialects/Ibis/RationaleIbis.md +++ b/docs/Dialects/Kanagawa/RationaleKanagawa.md @@ -1,13 +1,13 @@ -# `ibis` Dialect Rationale +# `kanagawa` Dialect Rationale ## Lowering flow 1. Containerization: At this level, one may have relative references to ports `get_port` accesses - to `!ibis.scoperef`s + to `!kanagawa.scoperef`s 2. Tunneling: - Relative `!ibis.scoperef` references are defined via `ibis.path` operations. - In this pass, we lower `ibis.path` operations by tunneling `portref`s through + Relative `!kanagawa.scoperef` references are defined via `kanagawa.path` operations. + In this pass, we lower `kanagawa.path` operations by tunneling `portref`s through the instance hierarchy, based on the `get_port` operations that were present in the various containers. After this, various `portref>` ports are present in the design, which represents the actual ports that are @@ -27,9 +27,9 @@ In cases where children drive parent ports, the prior case may create situations where a container drives its own input ports (and by extension, no other instantiating container is expected to drive that port of the instance, - if the IR is correct). We thus run `ibis-clean-selfdrivers` to replace these + if the IR is correct). We thus run `kanagawa-clean-selfdrivers` to replace these self-driven ports by the actual values that are being driven into them. 5. HW lowering: - At this point, there no longer exist any relative references in the Ibis IR, + At this point, there no longer exist any relative references in the Kanagawa IR, and all instantiations should (if the IR is correct) have all of their inputs driven. This means that we can now lower the IR to `hw.module`s. diff --git a/docs/Dialects/Kanagawa/_index.md b/docs/Dialects/Kanagawa/_index.md new file mode 100644 index 000000000000..9e72df73200d --- /dev/null +++ b/docs/Dialects/Kanagawa/_index.md @@ -0,0 +1,3 @@ +# 'kanagawa' Dialect + +[include "Dialects/Kanagawa.md"] diff --git a/docs/Passes.md b/docs/Passes.md index aa4b7b470ba8..138d93e58275 100644 --- a/docs/Passes.md +++ b/docs/Passes.md @@ -44,9 +44,9 @@ This document describes the available CIRCT passes and their contracts. [include "HWPasses.md"] -## Ibis Dialect Passes +## Kanagawa Dialect Passes -[include "IbisPasses.md"] +[include "KanagawaPasses.md"] ## LLHD Dialect Passes diff --git a/frontends/PyCDE/integration_test/test_software/ibis_demo.py b/frontends/PyCDE/integration_test/test_software/kanagawa_demo.py similarity index 100% rename from frontends/PyCDE/integration_test/test_software/ibis_demo.py rename to frontends/PyCDE/integration_test/test_software/kanagawa_demo.py diff --git a/include/circt/Dialect/CMakeLists.txt b/include/circt/Dialect/CMakeLists.txt index 798409471773..97241bc62b85 100644 --- a/include/circt/Dialect/CMakeLists.txt +++ b/include/circt/Dialect/CMakeLists.txt @@ -27,7 +27,7 @@ add_subdirectory(Moore) add_subdirectory(MSFT) add_subdirectory(OM) add_subdirectory(Pipeline) -add_subdirectory(Ibis) +add_subdirectory(Kanagawa) add_subdirectory(Seq) add_subdirectory(Sim) add_subdirectory(SMT) diff --git a/include/circt/Dialect/Ibis/CMakeLists.txt b/include/circt/Dialect/Ibis/CMakeLists.txt deleted file mode 100644 index cfce0427c66c..000000000000 --- a/include/circt/Dialect/Ibis/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -add_circt_dialect(Ibis ibis) -add_circt_dialect_doc(Ibis ibis) - -set(LLVM_TARGET_DEFINITIONS IbisPasses.td) -mlir_tablegen(IbisPasses.h.inc -gen-pass-decls) -add_public_tablegen_target(CIRCTIbisTransformsIncGen) -add_circt_doc(IbisPasses IbisPasses -gen-pass-doc) - -set(LLVM_TARGET_DEFINITIONS IbisInterfaces.td) -mlir_tablegen(IbisInterfaces.h.inc -gen-op-interface-decls) -mlir_tablegen(IbisInterfaces.cpp.inc -gen-op-interface-defs) -add_public_tablegen_target(MLIRIbisInterfacIbisncGen) -add_dependencies(circt-headers MLIRIbisInterfacIbisncGen) - -set(LLVM_TARGET_DEFINITIONS Ibis.td) -mlir_tablegen(IbisEnums.h.inc -gen-enum-decls) -mlir_tablegen(IbisEnums.cpp.inc -gen-enum-defs) -mlir_tablegen(IbisAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=ibis) -mlir_tablegen(IbisAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=ibis) -add_public_tablegen_target(MLIRIbisEnumsIncGen) -add_dependencies(circt-headers MLIRIbisEnumsIncGen) diff --git a/include/circt/Dialect/Ibis/IbisPassPipelines.h b/include/circt/Dialect/Ibis/IbisPassPipelines.h deleted file mode 100644 index 763de7c90073..000000000000 --- a/include/circt/Dialect/Ibis/IbisPassPipelines.h +++ /dev/null @@ -1,29 +0,0 @@ -//===- IbisPassPipelines.h - Ibis pass pipelines -----------------*- C++-*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#ifndef CIRCT_DIALECT_IBIS_IBISPASSPIPELINES_H -#define CIRCT_DIALECT_IBIS_IBISPASSPIPELINES_H - -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "mlir/Pass/PassManager.h" -#include -#include - -namespace circt { -namespace ibis { - -// Loads a pass pipeline to transform low-level Ibis constructs. -void loadIbisLowLevelPassPipeline(mlir::PassManager &pm); - -// Loads a pass pipeline to transform high-level Ibis constructs. -void loadIbisHighLevelPassPipeline(mlir::PassManager &pm); - -} // namespace ibis -} // namespace circt - -#endif // CIRCT_DIALECT_IBIS_IBISPASSPIPELINES_H diff --git a/include/circt/Dialect/Kanagawa/CMakeLists.txt b/include/circt/Dialect/Kanagawa/CMakeLists.txt new file mode 100644 index 000000000000..b5bd4f6f11fa --- /dev/null +++ b/include/circt/Dialect/Kanagawa/CMakeLists.txt @@ -0,0 +1,21 @@ +add_circt_dialect(Kanagawa kanagawa) +add_circt_dialect_doc(Kanagawa kanagawa) + +set(LLVM_TARGET_DEFINITIONS KanagawaPasses.td) +mlir_tablegen(KanagawaPasses.h.inc -gen-pass-decls) +add_public_tablegen_target(CIRCTKanagawaTransformsIncGen) +add_circt_doc(KanagawaPasses KanagawaPasses -gen-pass-doc) + +set(LLVM_TARGET_DEFINITIONS KanagawaInterfaces.td) +mlir_tablegen(KanagawaInterfaces.h.inc -gen-op-interface-decls) +mlir_tablegen(KanagawaInterfaces.cpp.inc -gen-op-interface-defs) +add_public_tablegen_target(MLIRKanagawaInterfacKanagawancGen) +add_dependencies(circt-headers MLIRKanagawaInterfacKanagawancGen) + +set(LLVM_TARGET_DEFINITIONS Kanagawa.td) +mlir_tablegen(KanagawaEnums.h.inc -gen-enum-decls) +mlir_tablegen(KanagawaEnums.cpp.inc -gen-enum-defs) +mlir_tablegen(KanagawaAttributes.h.inc -gen-attrdef-decls -attrdefs-dialect=kanagawa) +mlir_tablegen(KanagawaAttributes.cpp.inc -gen-attrdef-defs -attrdefs-dialect=kanagawa) +add_public_tablegen_target(MLIRKanagawaEnumsIncGen) +add_dependencies(circt-headers MLIRKanagawaEnumsIncGen) diff --git a/include/circt/Dialect/Ibis/Ibis.td b/include/circt/Dialect/Kanagawa/Kanagawa.td similarity index 56% rename from include/circt/Dialect/Ibis/Ibis.td rename to include/circt/Dialect/Kanagawa/Kanagawa.td index 89890e9eede1..6d900211f6a1 100644 --- a/include/circt/Dialect/Ibis/Ibis.td +++ b/include/circt/Dialect/Kanagawa/Kanagawa.td @@ -1,4 +1,4 @@ -//===- Ibis.td - Definition of Ibis dialect -------------------------------===// +//===- Kanagawa.td - Definition of Kanagawa dialect -----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_TD -#define CIRCT_DIALECT_IBIS_TD +#ifndef CIRCT_DIALECT_KANAGAWA_TD +#define CIRCT_DIALECT_KANAGAWA_TD include "mlir/IR/AttrTypeBase.td" include "mlir/IR/OpBase.td" include "mlir/Interfaces/FunctionInterfaces.td" -include "circt/Dialect/Ibis/IbisDialect.td" -include "circt/Dialect/Ibis/IbisTypes.td" -include "circt/Dialect/Ibis/IbisOps.td" +include "circt/Dialect/Kanagawa/KanagawaDialect.td" +include "circt/Dialect/Kanagawa/KanagawaTypes.td" +include "circt/Dialect/Kanagawa/KanagawaOps.td" -#endif // CIRCT_DIALECT_IBIS_TD +#endif // CIRCT_DIALECT_KANAGAWA_TD diff --git a/include/circt/Dialect/Ibis/IbisDialect.h b/include/circt/Dialect/Kanagawa/KanagawaDialect.h similarity index 53% rename from include/circt/Dialect/Ibis/IbisDialect.h rename to include/circt/Dialect/Kanagawa/KanagawaDialect.h index 36af99bcbc16..3b8560eed973 100644 --- a/include/circt/Dialect/Ibis/IbisDialect.h +++ b/include/circt/Dialect/Kanagawa/KanagawaDialect.h @@ -1,4 +1,4 @@ -//===- IbisDialect.h - Definition of Ibis dialect ----------------*- C++-*-===// +//===- KanagawaDialect.h - Definition of Kanagawa dialect -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISDIALECT_H -#define CIRCT_DIALECT_IBIS_IBISDIALECT_H +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWADIALECT_H +#define CIRCT_DIALECT_KANAGAWA_KANAGAWADIALECT_H #include "mlir/IR/Dialect.h" // Pull in the dialect definition. -#include "circt/Dialect/Ibis/IbisDialect.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h.inc" // Pull in all enum type definitions and utility function declarations. -#include "circt/Dialect/Ibis/IbisEnums.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaEnums.h.inc" #define GET_ATTRDEF_CLASSES -#include "circt/Dialect/Ibis/IbisAttributes.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaAttributes.h.inc" -#endif // CIRCT_DIALECT_IBIS_IBISDIALECT_H +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWADIALECT_H diff --git a/include/circt/Dialect/Ibis/IbisDialect.td b/include/circt/Dialect/Kanagawa/KanagawaDialect.td similarity index 56% rename from include/circt/Dialect/Ibis/IbisDialect.td rename to include/circt/Dialect/Kanagawa/KanagawaDialect.td index bf7e61d1cfe0..a3f0dbb23fea 100644 --- a/include/circt/Dialect/Ibis/IbisDialect.td +++ b/include/circt/Dialect/Kanagawa/KanagawaDialect.td @@ -1,4 +1,4 @@ -//===- IbisDialect.td - Ibis dialect definition ----------------*- tablegen -*-===// +//===- KanagawaDialect.td - Kanagawa dialect definition ----*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_DIALECT_TD -#define CIRCT_DIALECT_IBIS_DIALECT_TD +#ifndef CIRCT_DIALECT_KANAGAWA_DIALECT_TD +#define CIRCT_DIALECT_KANAGAWA_DIALECT_TD include "mlir/IR/OpBase.td" -def IbisDialect : Dialect { - let name = "ibis"; - let cppNamespace = "::circt::ibis"; +def KanagawaDialect : Dialect { + let name = "kanagawa"; + let cppNamespace = "::circt::kanagawa"; - let summary = "Types and operations for Ibis dialect"; + let summary = "Types and operations for Kanagawa dialect"; let description = [{ - The `ibis` dialect is intended to support porting and eventual open sourcing + The `kanagawa` dialect is intended to support porting and eventual open sourcing of an internal hardware development language. }]; let useDefaultTypePrinterParser = 1; @@ -27,8 +27,8 @@ def IbisDialect : Dialect { void registerAttributes(); }]; - // Needed for ibis.pipeline_header + // Needed for kanagawa.pipeline_header let dependentDialects = ["seq::SeqDialect", "hw::HWDialect"]; } -#endif // CIRCT_DIALECT_IBIS_DIALECT_TD +#endif // CIRCT_DIALECT_KANAGAWA_DIALECT_TD diff --git a/include/circt/Dialect/Ibis/IbisInterfaces.td b/include/circt/Dialect/Kanagawa/KanagawaInterfaces.td similarity index 84% rename from include/circt/Dialect/Ibis/IbisInterfaces.td rename to include/circt/Dialect/Kanagawa/KanagawaInterfaces.td index 0b6ac7adc6cb..2d24e68f9cdf 100644 --- a/include/circt/Dialect/Ibis/IbisInterfaces.td +++ b/include/circt/Dialect/Kanagawa/KanagawaInterfaces.td @@ -1,4 +1,4 @@ -//===- IbisInterfaces.td - Ibis Interfaces ---------------*- tablegen -*---===// +//===- KanagawaInterfaces.td - Kanagawa Interfaces -------*- tablegen -*---===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,12 +6,12 @@ // //===----------------------------------------------------------------------===// // -// This describes the interfaces in the Ibis dialect. +// This describes the interfaces in the Kanagawa dialect. // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_INTERFACES_TD -#define CIRCT_DIALECT_IBIS_INTERFACES_TD +#ifndef CIRCT_DIALECT_KANAGAWA_INTERFACES_TD +#define CIRCT_DIALECT_KANAGAWA_INTERFACES_TD include "circt/Dialect/HW/HWOpInterfaces.td" @@ -19,7 +19,7 @@ include "mlir/IR/OpBase.td" include "mlir/IR/SymbolInterfaces.td" def NamedInnerSymbol : OpInterface<"NamedInnerSymbolInterface", [InnerSymbol]> { - let cppNamespace = "circt::ibis"; + let cppNamespace = "circt::kanagawa"; let description = [{ An interface for operations which define inner symbols with an optional namehint. @@ -50,7 +50,7 @@ def NamedInnerSymbol : OpInterface<"NamedInnerSymbolInterface", [InnerSymbol]> { } def PortOpInterface : OpInterface<"PortOpInterface", [NamedInnerSymbol]> { - let cppNamespace = "circt::ibis"; + let cppNamespace = "circt::kanagawa"; let description = "An interface for operations which describe ports."; @@ -59,17 +59,17 @@ def PortOpInterface : OpInterface<"PortOpInterface", [NamedInnerSymbol]> { "Returns the data type of the port.", "mlir::Type", "getPortType">, InterfaceMethod< - "Returns the `!ibis.portref` value defined by the op", + "Returns the `!kanagawa.portref` value defined by the op", "mlir::TypedValue", "getPort" > ]; } def ScopeOpInterface : OpInterface<"ScopeOpInterface", [NamedInnerSymbol]> { - let cppNamespace = "circt::ibis"; + let cppNamespace = "circt::kanagawa"; let description = [{ - An interface for operations which define Ibis scopes, that can be referenced - by an `ibis.this` operation. + An interface for operations which define Kanagawa scopes, that can be referenced + by an `kanagawa.this` operation. }]; let verify = "return detail::verifyScopeOpInterface($_op);"; @@ -125,20 +125,20 @@ def ScopeOpInterface : OpInterface<"ScopeOpInterface", [NamedInnerSymbol]> { >, InterfaceMethod< "Lookup a port in the scope", - "ibis::PortOpInterface", "lookupPort", + "kanagawa::PortOpInterface", "lookupPort", (ins "llvm::StringRef":$portName), [{}], [{ - return dyn_cast_or_null(this->lookupInnerSym(portName)); + return dyn_cast_or_null(this->lookupInnerSym(portName)); }] > ]; } def BlockOpInterface : OpInterface<"BlockOpInterface"> { - let cppNamespace = "circt::ibis"; + let cppNamespace = "circt::kanagawa"; let description = [{ - An interface for Ibis block-like operations. + An interface for Kanagawa block-like operations. }]; let methods = [ @@ -150,11 +150,11 @@ def BlockOpInterface : OpInterface<"BlockOpInterface"> { } def MethodLikeOpInterface : OpInterface<"MethodLikeOpInterface"> { - let cppNamespace = "circt::ibis"; + let cppNamespace = "circt::kanagawa"; let description = [{ - An interface for Ibis operations that act like callable methods. + An interface for Kanagawa operations that act like callable methods. This partially implements similar functionality to the FunctionLike interface - which cannot be used for Ibis Methods due to Ibis methods defining InnerSym's + which cannot be used for Kanagawa Methods due to Kanagawa methods defining InnerSym's whereas the FunctionLike interface is built on the assumption of the function defining a Symbol (i.e. inherits from the Symbol interface). }]; @@ -199,4 +199,4 @@ def MethodLikeOpInterface : OpInterface<"MethodLikeOpInterface"> { }]; } -#endif // CIRCT_DIALECT_IBIS_INTERFACES_TD +#endif // CIRCT_DIALECT_KANAGAWA_INTERFACES_TD diff --git a/include/circt/Dialect/Ibis/IbisOps.h b/include/circt/Dialect/Kanagawa/KanagawaOps.h similarity index 61% rename from include/circt/Dialect/Ibis/IbisOps.h rename to include/circt/Dialect/Kanagawa/KanagawaOps.h index 09042776aaa5..0ec773fb96e4 100644 --- a/include/circt/Dialect/Ibis/IbisOps.h +++ b/include/circt/Dialect/Kanagawa/KanagawaOps.h @@ -1,4 +1,4 @@ -//===- IbisOps.h - Definition of Ibis dialect ops ----------------*- C++-*-===// +//===- KanagawaOps.h - Definition of Kanagawa dialect ops -------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISOPS_H -#define CIRCT_DIALECT_IBIS_IBISOPS_H +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_H +#define CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_H #include "circt/Dialect/DC/DCTypes.h" #include "circt/Dialect/HW/HWOpInterfaces.h" #include "circt/Dialect/Handshake/HandshakeInterfaces.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Dialect/Seq/SeqTypes.h" #include "circt/Support/InstanceGraphInterface.h" #include "circt/Support/LLVM.h" @@ -28,29 +28,30 @@ #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" namespace circt { -namespace ibis { +namespace kanagawa { class ContainerOp; class ThisOp; -// Symbol name for the ibis operator library to be used during scheduling. -static constexpr const char *kIbisOperatorLibName = "ibis_operator_library"; +// Symbol name for the kanagawa operator library to be used during scheduling. +static constexpr const char *kKanagawaOperatorLibName = + "kanagawa_operator_library"; namespace detail { // Verify that `op` conforms to the ScopeOpInterface. LogicalResult verifyScopeOpInterface(Operation *op); -// Returns the %this value of an ibis scope-defining operation. Implemented -// here to hide the dependence on `ibis.this`, which is not defined before the -// interface definition. +// Returns the %this value of an kanagawa scope-defining operation. Implemented +// here to hide the dependence on `kanagawa.this`, which is not defined before +// the interface definition. mlir::FailureOr> getThisFromScope(Operation *op); } // namespace detail -} // namespace ibis +} // namespace kanagawa } // namespace circt -#include "circt/Dialect/Ibis/IbisInterfaces.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaInterfaces.h.inc" #define GET_OP_CLASSES -#include "circt/Dialect/Ibis/Ibis.h.inc" +#include "circt/Dialect/Kanagawa/Kanagawa.h.inc" -#endif // CIRCT_DIALECT_IBIS_IBISOPS_H +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_H diff --git a/include/circt/Dialect/Ibis/IbisOps.td b/include/circt/Dialect/Kanagawa/KanagawaOps.td similarity index 80% rename from include/circt/Dialect/Ibis/IbisOps.td rename to include/circt/Dialect/Kanagawa/KanagawaOps.td index eb8cdbb0c6d4..ea5c9c4b1b91 100644 --- a/include/circt/Dialect/Ibis/IbisOps.td +++ b/include/circt/Dialect/Kanagawa/KanagawaOps.td @@ -1,4 +1,4 @@ -//===- IbisOps.td - Definition of Ibis dialect operations -----------------===// +//===- KanagawaOps.td - Definition of Kanagawa dialect operations ---------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISOPS_TD -#define CIRCT_DIALECT_IBIS_IBISOPS_TD +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_TD +#define CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_TD include "mlir/IR/OpAsmInterface.td" include "mlir/IR/RegionKindInterface.td" @@ -21,33 +21,33 @@ include "mlir/IR/BuiltinAttributeInterfaces.td" include "circt/Dialect/Handshake/HandshakeInterfaces.td" include "circt/Dialect/HW/HWAttributesNaming.td" include "circt/Dialect/HW/HWOpInterfaces.td" -include "circt/Dialect/Ibis/IbisInterfaces.td" -include "circt/Dialect/Ibis/IbisTypes.td" +include "circt/Dialect/Kanagawa/KanagawaInterfaces.td" +include "circt/Dialect/Kanagawa/KanagawaTypes.td" include "circt/Dialect/Handshake/HandshakeInterfaces.td" include "circt/Dialect/Seq/SeqTypes.td" include "circt/Support/InstanceGraphInterface.td" include "circt/Dialect/HW/HWTypes.td" -class IbisOp traits = []> : - Op; +class KanagawaOp traits = []> : + Op; def HasCustomSSAName : DeclareOpInterfaceMethods; -def ClassOp : IbisOp<"class", [ +def ClassOp : KanagawaOp<"class", [ IsolatedFromAbove, RegionKindInterface, SingleBlock, NoTerminator, ScopeOpInterface, InstanceGraphModuleOpInterface, HasParent<"DesignOp"> ] > { - let summary = "Ibis class"; + let summary = "Kanagawa class"; let description = [{ - Ibis has the notion of a class which can contain methods and member + Kanagawa has the notion of a class which can contain methods and member variables. - In the low-level Ibis representation, the ClassOp becomes a container for - `ibis.port`s, `ibis.container`s, and contain logic for member variables. + In the low-level Kanagawa representation, the ClassOp becomes a container for + `kanagawa.port`s, `kanagawa.container`s, and contain logic for member variables. }]; let arguments = (ins InnerSymAttr:$inner_sym, OptionalAttr:$name); @@ -69,7 +69,7 @@ def ClassOp : IbisOp<"class", [ }]; } -class InstanceOpBase : IbisOp : KanagawaOp, DeclareOpInterfaceMethods, InstanceGraphInstanceOpInterface, @@ -117,9 +117,9 @@ class InstanceOpBase : IbisOp { - let summary = "Ibis class instance"; + let summary = "Kanagawa class instance"; let description = [{ - Instantiates an Ibis class. + Instantiates an Kanagawa class. }]; let extraInstanceClassDeclaration = [{ @@ -141,12 +141,12 @@ def InstanceOp : InstanceOpBase<"instance"> { class MethodOpBase traits = []> : - IbisOp, // FunctionOpInterface @mortbopet: This is very much a function-like // operation, but FunctionOpInterface inherits from Symbol which is - // incompatible with the fact that ibis methods define inner symbols. + // incompatible with the fact that kanagawa methods define inner symbols. MethodLikeOpInterface, HasParent<"ClassOp">, ])> { @@ -178,9 +178,9 @@ def MethodOp : MethodOpBase<"method", [ DeclareOpInterfaceMethods ]> { - let summary = "Ibis method"; + let summary = "Kanagawa method"; let description = [{ - Ibis methods are a lot like software functions: a list of named arguments + Kanagawa methods are a lot like software functions: a list of named arguments and unnamed return values with imperative control flow. }]; @@ -188,14 +188,14 @@ def MethodOp : MethodOpBase<"method", [ } def DataflowMethodOp : MethodOpBase<"method.df", [ - SingleBlockImplicitTerminator<"ibis::ReturnOp">, + SingleBlockImplicitTerminator<"kanagawa::ReturnOp">, RegionKindInterface, FineGrainedDataflowRegionOpInterface ]> { - let summary = "Ibis dataflow method"; + let summary = "Kanagawa dataflow method"; let description = [{ - Ibis dataflow methods share the same interface as an `ibis.method` but + Kanagawa dataflow methods share the same interface as an `kanagawa.method` but without imperative CFG-based control flow. Instead, this method implements a graph region, and control flow is expected to be defined by dataflow operations. }]; @@ -207,10 +207,10 @@ def DataflowMethodOp : MethodOpBase<"method.df", [ }]; } -def ReturnOp : IbisOp<"return", [ +def ReturnOp : KanagawaOp<"return", [ Pure, ReturnLike, Terminator, ParentOneOf<["MethodOp", "DataflowMethodOp"]>]> { - let summary = "Ibis method terminator"; + let summary = "Kanagawa method terminator"; let arguments = (ins Variadic:$retValues); let assemblyFormat = "($retValues^)? attr-dict (`:` type($retValues)^)?"; @@ -221,7 +221,7 @@ def ReturnOp : IbisOp<"return", [ ]; } -class BlockLikeOp traits = []> : IbisOp traits = []> : KanagawaOp, AutomaticAllocationScope, BlockOpInterface])> { @@ -269,13 +269,13 @@ class HighLevelBlockLikeOp traits = []> : BlockLike } def StaticBlockOp : HighLevelBlockLikeOp<"sblock"> { - let summary = "Ibis block"; + let summary = "Kanagawa block"; let description = [{ - The `ibis.sblock` operation defines a block wherein a group of operations + The `kanagawa.sblock` operation defines a block wherein a group of operations are expected to be statically scheduleable. The operation is not isolated from above to facilitate ease of construction. However, once a program has been constructed and lowered to a sufficient - level, the user may run `--ibis-argify-blocks` to effectively isolate the + level, the user may run `--kanagawa-argify-blocks` to effectively isolate the block from above, by converting SSA values referenced through dominanes into arguments of the block @@ -287,9 +287,9 @@ def StaticBlockOp : HighLevelBlockLikeOp<"sblock"> { def IsolatedStaticBlockOp : HighLevelBlockLikeOp<"sblock.isolated", [ IsolatedFromAbove ]> { - let summary = "Ibis isolated block"; + let summary = "Kanagawa isolated block"; let description = [{ - The `ibis.sblock.isolated` operation is like an `ibis.sblock` operation + The `kanagawa.sblock.isolated` operation is like an `kanagawa.sblock` operation but with an IsolatedFromAbove condition, meaning that all arguments and results are passed through the block as arguments and results. }]; @@ -298,9 +298,9 @@ def IsolatedStaticBlockOp : HighLevelBlockLikeOp<"sblock.isolated", [ def DCBlockOp : BlockLikeOp<"sblock.dc", [ IsolatedFromAbove ]> { - let summary = "DC-interfaced Ibis block"; + let summary = "DC-interfaced Kanagawa block"; let description = [{ - The `ibis.sblock.dc` operation is like an `ibis.sblock` operation with + The `kanagawa.sblock.dc` operation is like an `kanagawa.sblock` operation with a few differences, being: 1. The operation is DC-interfaced, meaning that all arguments and results are dc-value typed. @@ -324,19 +324,19 @@ def DCBlockOp : BlockLikeOp<"sblock.dc", [ }]; } -def InlineStaticBlockBeginOp : IbisOp<"sblock.inline.begin", [ +def InlineStaticBlockBeginOp : KanagawaOp<"sblock.inline.begin", [ HasParent<"MethodOp"> ]> { - let summary = "Ibis inline static block begin marker"; + let summary = "Kanagawa inline static block begin marker"; let description = [{ - The `ibis.sblock.inline.begin` operation is a marker that indicates the + The `kanagawa.sblock.inline.begin` operation is a marker that indicates the begin of an inline static block. - The operation is used to maintain `ibis.sblocks` while in the Ibis inline + The operation is used to maintain `kanagawa.sblocks` while in the Kanagawa inline phase (to facilitate e.g. mem2reg). The operation: 1. denotes the begin of the sblock - 2. carries whatever attributes that the source `ibis.sblock` carried. + 2. carries whatever attributes that the source `kanagawa.sblock` carried. 3. is considered side-effectfull. }]; @@ -347,14 +347,14 @@ def InlineStaticBlockBeginOp : IbisOp<"sblock.inline.begin", [ }]; } -def InlineStaticBlockEndOp : IbisOp<"sblock.inline.end", [ +def InlineStaticBlockEndOp : KanagawaOp<"sblock.inline.end", [ HasParent<"MethodOp"> ]> { - let summary = "Ibis inline static block end marker"; + let summary = "Kanagawa inline static block end marker"; let description = [{ - The `ibis.sblock.inline.end` operation is a marker that indicates the + The `kanagawa.sblock.inline.end` operation is a marker that indicates the end of an inline static block. - The operation is used to maintain `ibis.sblocks` while in the Ibis inline + The operation is used to maintain `kanagawa.sblocks` while in the Kanagawa inline phase (to facilitate e.g. mem2reg). }]; @@ -366,10 +366,10 @@ def InlineStaticBlockEndOp : IbisOp<"sblock.inline.end", [ }]; } -def BlockReturnOp : IbisOp<"sblock.return", [ +def BlockReturnOp : KanagawaOp<"sblock.return", [ Pure, ReturnLike, Terminator, ParentOneOf<["StaticBlockOp", "IsolatedStaticBlockOp", "DCBlockOp"]>]> { - let summary = "Ibis static block terminator"; + let summary = "Kanagawa static block terminator"; let arguments = (ins Variadic:$retValues); let assemblyFormat = "($retValues^)? attr-dict (`:` type($retValues)^)?"; @@ -381,16 +381,16 @@ def BlockReturnOp : IbisOp<"sblock.return", [ } def MemRefTypeAttr : TypeAttrBase<"MemRefType", "any memref type">; -def VarOp : IbisOp<"var", [ +def VarOp : KanagawaOp<"var", [ DeclareOpInterfaceMethods ]> { - let summary = "Ibis variable definition"; + let summary = "Kanagawa variable definition"; let description = [{ - Defines an Ibis class member variable. The variable is typed with a + Defines an Kanagawa class member variable. The variable is typed with a `memref.memref` type, and may define either a singleton or uni-dimensional array of values. - `ibis.var` defines a symbol within the encompassing class scope which can - be dereferenced through a `!ibis.scoperef` value of the parent class. + `kanagawa.var` defines a symbol within the encompassing class scope which can + be dereferenced through a `!kanagawa.scoperef` value of the parent class. }]; let arguments = (ins InnerSymAttr:$inner_sym, MemRefTypeAttr:$type); @@ -404,11 +404,11 @@ def VarOp : IbisOp<"var", [ }]; } -def GetVarOp : IbisOp<"get_var", [ +def GetVarOp : KanagawaOp<"get_var", [ DeclareOpInterfaceMethods, HasCustomSSAName ]> { - let summary = "Dereferences an ibis member variable through a scoperef"; + let summary = "Dereferences an kanagawa member variable through a scoperef"; let arguments = (ins ScopeRefType:$instance, FlatSymbolRefAttr:$varName); let results = (outs AnyMemRef:$var); let assemblyFormat = [{ @@ -427,13 +427,13 @@ def GetVarOp : IbisOp<"get_var", [ }]; } -def CallOp : IbisOp<"call", [ +def CallOp : KanagawaOp<"call", [ DeclareOpInterfaceMethods, CallOpInterface ]> { - let summary = "Ibis method call"; + let summary = "Kanagawa method call"; let description = [{ - Dispatch a call to an Ibis method. + Dispatch a call to an Kanagawa method. }]; let arguments = (ins InnerRefAttr:$callee, Variadic:$operands); @@ -474,10 +474,10 @@ def CallOp : IbisOp<"call", [ def PathDirection : I32EnumAttr<"PathDirection", "path direction", [ I32EnumAttrCase<"Parent", 0, "parent">, I32EnumAttrCase<"Child", 1, "child">]> { - let cppNamespace = "::circt::ibis"; + let cppNamespace = "::circt::kanagawa"; } -def PathStepAttr : AttrDef { +def PathStepAttr : AttrDef { let description = "Used to describe a single step in a path"; let parameters = (ins "PathDirection":$direction, @@ -495,20 +495,20 @@ def PathStepAttr : AttrDef { def PathStepArrayAttr : TypedArrayAttrBase; -def PathOp : IbisOp<"path", [ +def PathOp : KanagawaOp<"path", [ DeclareOpInterfaceMethods, Pure, InferTypeOpInterface, HasCustomSSAName ]> { - let summary = "Ibis path"; + let summary = "Kanagawa path"; let description = [{ - The `ibis.path` operation describes an instance hierarchy path relative to + The `kanagawa.path` operation describes an instance hierarchy path relative to the current scope. The path is specified by a list of either parent or child identifiers (navigating up or down the hierarchy, respectively). - Scopes along the path are optionally typed, however, An `ibis.path` must - lways terminate in a fully typed specifier, i.e. never an `!ibis.scoperef<>`. + Scopes along the path are optionally typed, however, An `kanagawa.path` must + lways terminate in a fully typed specifier, i.e. never an `!kanagawa.scoperef<>`. - The operation returns a single `!ibis.scoperef`-typed value representing + The operation returns a single `!kanagawa.scoperef`-typed value representing the scope at the end of the path. }]; @@ -539,11 +539,11 @@ def PathOp : IbisOp<"path", [ let hasCanonicalizeMethod = 1; } -def ThisOp : IbisOp<"this", [ +def ThisOp : KanagawaOp<"this", [ DeclareOpInterfaceMethods, HasCustomSSAName ]> { - let summary = "Return a handle to the current scope `!ibis.scoperef`"; + let summary = "Return a handle to the current scope `!kanagawa.scoperef`"; let arguments = (ins InnerRefAttr:$scopeName); let results = (outs ScopeRefType:$thisRef); @@ -569,10 +569,10 @@ def ThisOp : IbisOp<"this", [ } // ===---------------------------------------------------------------------===// -// Low-level Ibis operations +// Low-level Kanagawa operations // ===---------------------------------------------------------------------===// -def DesignOp : IbisOp<"design", [ +def DesignOp : KanagawaOp<"design", [ Symbol, SingleBlock, InnerSymbolTable, @@ -580,7 +580,7 @@ def DesignOp : IbisOp<"design", [ NoRegionArguments, IsolatedFromAbove ]> { - let summary = "All Ibis containers must be inside this op"; + let summary = "All Kanagawa containers must be inside this op"; let arguments = (ins SymbolNameAttr:$sym_name); let regions = (region SizedRegion<1>:$body); @@ -590,7 +590,7 @@ def DesignOp : IbisOp<"design", [ }]; } -def ContainerOp : IbisOp<"container", [ +def ContainerOp : KanagawaOp<"container", [ SingleBlock, NoTerminator, NoRegionArguments, ScopeOpInterface, IsolatedFromAbove, @@ -599,9 +599,9 @@ def ContainerOp : IbisOp<"container", [ DeclareOpInterfaceMethods, ParentOneOf<["DesignOp", "ClassOp"]> ]> { - let summary = "Ibis container"; + let summary = "Kanagawa container"; let description = [{ - An ibis container describes a collection of logic nested within an Ibis class. + An kanagawa container describes a collection of logic nested within an Kanagawa class. }]; let arguments = (ins InnerSymAttr:$inner_sym, UnitAttr:$isTopLevel, OptionalAttr:$name); @@ -649,9 +649,9 @@ def ContainerOp : IbisOp<"container", [ } def ContainerInstanceOp : InstanceOpBase<"container.instance"> { - let summary = "Ibis container instance"; + let summary = "Kanagawa container instance"; let description = [{ - Instantiates an Ibis container. + Instantiates an Kanagawa container. }]; let extraInstanceClassDeclaration = [{ @@ -672,20 +672,20 @@ def ContainerInstanceOp : InstanceOpBase<"container.instance"> { }]; } -def GetPortOp : IbisOp<"get_port", [ +def GetPortOp : KanagawaOp<"get_port", [ Pure, DeclareOpInterfaceMethods, HasCustomSSAName ]> { - let summary = "Ibis get port"; + let summary = "Kanagawa get port"; let description = [{ - Given an Ibis class reference, returns a port of said class. The port + Given an Kanagawa class reference, returns a port of said class. The port is specified by the symbol name of the port in the referenced class. Importantly, the user must specify how they intend to use the op, by specifying the direction of the portref type that this op is generated with. - If the request port is to be read from, the type must be `!ibis.portref` - and if the port is to be written to, the type must be `!ibis.portref`. + If the request port is to be read from, the type must be `!kanagawa.portref` + and if the port is to be written to, the type must be `!kanagawa.portref`. This is to ensure that the usage is reflected in the get_port type which in turn is used by the tunneling passes to create the proper ports through the hierarchy. @@ -706,7 +706,7 @@ def GetPortOp : IbisOp<"get_port", [ let builders = [ OpBuilder<(ins "Value":$instance, "StringAttr":$portName, "Type":$innerPortType, - "ibis::Direction":$direction), [{ + "kanagawa::Direction":$direction), [{ build($_builder, $_state, $_builder.getType( innerPortType, direction), instance, portName ); @@ -716,7 +716,7 @@ def GetPortOp : IbisOp<"get_port", [ let hasCanonicalizeMethod = 1; let extraClassDeclaration = [{ // Returns the direction requested by this get_port op. - ibis::Direction getDirection() { + kanagawa::Direction getDirection() { return llvm::cast(getPort().getType()).getDirection(); } @@ -726,7 +726,7 @@ def GetPortOp : IbisOp<"get_port", [ } class PortLikeOp traits = []> : - IbisOp, InferTypeOpInterface, @@ -735,7 +735,7 @@ class PortLikeOp traits = []> : ])> { let description = [{ - An ibis port has an attached 'name' attribute. This is a name-hint used + An kanagawa port has an attached 'name' attribute. This is a name-hint used to generate the final port name. The port name and port symbol are not related, and all references to a port is done through the port symbol. }]; @@ -751,7 +751,7 @@ class PortLikeOp traits = []> : return getTypeAttr().getValue(); } - static ibis::Direction getPortDirection(); + static kanagawa::Direction getPortDirection(); /// Infer the return types of this operation. static LogicalResult inferReturnTypes(MLIRContext *context, @@ -787,27 +787,27 @@ class PortLikeOp traits = []> : } def InputPortOp : PortLikeOp<"port.input"> { - let summary = "Ibis input port"; + let summary = "Kanagawa input port"; let extraPortClassDefinition = [{ - ibis::Direction InputPortOp::getPortDirection() { - return ibis::Direction::Input; + kanagawa::Direction InputPortOp::getPortDirection() { + return kanagawa::Direction::Input; } }]; } def OutputPortOp : PortLikeOp<"port.output"> { - let summary = "Ibis output port"; + let summary = "Kanagawa output port"; let extraPortClassDefinition = [{ - ibis::Direction OutputPortOp::getPortDirection() { - return ibis::Direction::Output; + kanagawa::Direction OutputPortOp::getPortDirection() { + return kanagawa::Direction::Output; } }]; let hasCanonicalizeMethod = 1; } class WireLikeOp traits = []> : - IbisOp, HasCustomSSAName, @@ -819,7 +819,7 @@ class WireLikeOp traits = []> : return getPort().getType(); } - static ibis::Direction getPortDirection(); + static kanagawa::Direction getPortDirection(); }]; code extraWireClassDefinition = ?; @@ -833,7 +833,7 @@ class WireLikeOp traits = []> : class InnerTypeToPortrefTypeConstraint : TypesMatchWith<"the rhs type dictates the inner type of the rhs portref type", - lhs, rhs, "PortRefType::get($_ctxt, $_self, ibis::Direction::" # dir # ")">; + lhs, rhs, "PortRefType::get($_ctxt, $_self, kanagawa::Direction::" # dir # ")">; class PortRefToInnerTypeConstraint : TypesMatchWith<"the inner type of the lhs portref type dictates the rhs type", @@ -842,9 +842,9 @@ class PortRefToInnerTypeConstraint def InputWireOp : WireLikeOp<"wire.input", [ InnerTypeToPortrefTypeConstraint<"output", "port", "Input"> ]> { - let summary = "Ibis input wire"; + let summary = "Kanagawa input wire"; let description = [{ - An input wire defines an `ibis.portref` port alongside a value + An input wire defines an `kanagawa.portref` port alongside a value of type `T` which represents the value to-be-written to the wire. }]; @@ -855,8 +855,8 @@ def InputWireOp : WireLikeOp<"wire.input", [ }]; let extraWireClassDefinition = [{ - ibis::Direction $cppClass::getPortDirection() { - return ibis::Direction::Input; + kanagawa::Direction $cppClass::getPortDirection() { + return kanagawa::Direction::Input; } }]; @@ -864,7 +864,7 @@ def InputWireOp : WireLikeOp<"wire.input", [ OpBuilder<(ins "StringAttr":$inner_sym, "Type":$innerPortType, CArg<"mlir::StringAttr", "nullptr">:$name), [{ build($_builder, $_state, {$_builder.getType( - innerPortType, ibis::Direction::Input), innerPortType}, hw::InnerSymAttr::get(inner_sym), name); + innerPortType, kanagawa::Direction::Input), innerPortType}, hw::InnerSymAttr::get(inner_sym), name); }]> ]; @@ -874,9 +874,9 @@ def InputWireOp : WireLikeOp<"wire.input", [ def OutputWireOp : WireLikeOp<"wire.output", [ InnerTypeToPortrefTypeConstraint<"input", "port", "Output"> ]> { - let summary = "Ibis output wire"; + let summary = "Kanagawa output wire"; let description = [{ - An output wire defines an `ibis.portref` port that can be read. + An output wire defines an `kanagawa.portref` port that can be read. The operation takes an input value of type `T` which represents the value on the output portref. }]; @@ -888,20 +888,20 @@ def OutputWireOp : WireLikeOp<"wire.output", [ }]; let extraWireClassDefinition = [{ - ibis::Direction $cppClass::getPortDirection() { - return ibis::Direction::Output; + kanagawa::Direction $cppClass::getPortDirection() { + return kanagawa::Direction::Output; } }]; let hasCanonicalizeMethod = 1; } -def PortReadOp : IbisOp<"port.read", [ +def PortReadOp : KanagawaOp<"port.read", [ PortRefToInnerTypeConstraint<"port", "output">, Pure, HasCustomSSAName ]> { - let summary = "Ibis port read"; + let summary = "Kanagawa port read"; let description = [{ Read the value of a port reference. }]; @@ -913,10 +913,10 @@ def PortReadOp : IbisOp<"port.read", [ }]; } -def PortWriteOp : IbisOp<"port.write", [ +def PortWriteOp : KanagawaOp<"port.write", [ PortRefToInnerTypeConstraint<"port", "value"> ]> { - let summary = "Ibis port write"; + let summary = "Kanagawa port write"; let description = [{ Write a value to a port reference. }]; @@ -927,15 +927,15 @@ def PortWriteOp : IbisOp<"port.write", [ }]; } -def PipelineHeaderOp : IbisOp<"pipeline.header", [ +def PipelineHeaderOp : KanagawaOp<"pipeline.header", [ Pure ]> { - let summary = "Ibis pipeline header operation"; + let summary = "Kanagawa pipeline header operation"; let description = [{ This operation defines the hardware-like values used to drive a pipeline, such as clock and reset. This is an intermediate operation, meaning that it's strictly used to - facilitate progressive lowering of ibis static blocks to scheduled pipelines. + facilitate progressive lowering of kanagawa static blocks to scheduled pipelines. }]; let arguments = (ins); @@ -943,4 +943,4 @@ def PipelineHeaderOp : IbisOp<"pipeline.header", [ let assemblyFormat = "attr-dict"; } -#endif // CIRCT_DIALECT_IBIS_IBISOPS_TD +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWAOPS_TD diff --git a/include/circt/Dialect/Kanagawa/KanagawaPassPipelines.h b/include/circt/Dialect/Kanagawa/KanagawaPassPipelines.h new file mode 100644 index 000000000000..44169c5d41cc --- /dev/null +++ b/include/circt/Dialect/Kanagawa/KanagawaPassPipelines.h @@ -0,0 +1,29 @@ +//===- KanagawaPassPipelines.h - Kanagawa pass pipelines --------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSPIPELINES_H +#define CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSPIPELINES_H + +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "mlir/Pass/PassManager.h" +#include +#include + +namespace circt { +namespace kanagawa { + +// Loads a pass pipeline to transform low-level Kanagawa constructs. +void loadKanagawaLowLevelPassPipeline(mlir::PassManager &pm); + +// Loads a pass pipeline to transform high-level Kanagawa constructs. +void loadKanagawaHighLevelPassPipeline(mlir::PassManager &pm); + +} // namespace kanagawa +} // namespace circt + +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSPIPELINES_H diff --git a/include/circt/Dialect/Ibis/IbisPasses.h b/include/circt/Dialect/Kanagawa/KanagawaPasses.h similarity index 75% rename from include/circt/Dialect/Ibis/IbisPasses.h rename to include/circt/Dialect/Kanagawa/KanagawaPasses.h index 68315788d909..fe0271bbf6d9 100644 --- a/include/circt/Dialect/Ibis/IbisPasses.h +++ b/include/circt/Dialect/Kanagawa/KanagawaPasses.h @@ -1,4 +1,4 @@ -//===- Passes.h - Ibis pass entry points -------------------------*- C++-*-===// +//===- Passes.h - Kanagawa pass entry points --------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISPASSES_H -#define CIRCT_DIALECT_IBIS_IBISPASSES_H +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSES_H +#define CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSES_H #include "circt/Dialect/DC/DCDialect.h" #include "circt/Dialect/Pipeline/PipelineDialect.h" @@ -20,15 +20,15 @@ #include namespace circt { -namespace ibis { +namespace kanagawa { -#define GEN_PASS_DECL_IBISTUNNELING -#include "circt/Dialect/Ibis/IbisPasses.h.inc" +#define GEN_PASS_DECL_KANAGAWATUNNELING +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" std::unique_ptr createCallPrepPass(); std::unique_ptr createContainerizePass(); std::unique_ptr -createTunnelingPass(const IbisTunnelingOptions & = {}); +createTunnelingPass(const KanagawaTunnelingOptions & = {}); std::unique_ptr createPortrefLoweringPass(); std::unique_ptr createCleanSelfdriversPass(); std::unique_ptr createContainersToHWPass(); @@ -43,9 +43,9 @@ std::unique_ptr createAddOperatorLibraryPass(); /// Generate the code for registering passes. #define GEN_PASS_REGISTRATION -#include "circt/Dialect/Ibis/IbisPasses.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" -} // namespace ibis +} // namespace kanagawa } // namespace circt -#endif // CIRCT_DIALECT_IBIS_IBISPASSES_H +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWAPASSES_H diff --git a/include/circt/Dialect/Ibis/IbisPasses.td b/include/circt/Dialect/Kanagawa/KanagawaPasses.td similarity index 50% rename from include/circt/Dialect/Ibis/IbisPasses.td rename to include/circt/Dialect/Kanagawa/KanagawaPasses.td index 0dd2a3fdd972..bbbd24731596 100644 --- a/include/circt/Dialect/Ibis/IbisPasses.td +++ b/include/circt/Dialect/Kanagawa/KanagawaPasses.td @@ -1,4 +1,4 @@ -//===-- Passes.td - Ibis pass definition file --------------*- tablegen -*-===// +//===-- Passes.td - Kanagawa pass definition file ----------*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,34 +6,34 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_PASSES_TD -#define CIRCT_DIALECT_IBIS_PASSES_TD +#ifndef CIRCT_DIALECT_KANAGAWA_PASSES_TD +#define CIRCT_DIALECT_KANAGAWA_PASSES_TD include "mlir/Pass/PassBase.td" -def IbisCallPrep : Pass<"ibis-call-prep", "DesignOp"> { - let summary = "Convert ibis method calls to use `dc.value`"; +def KanagawaCallPrep : Pass<"kanagawa-call-prep", "DesignOp"> { + let summary = "Convert kanagawa method calls to use `dc.value`"; - let constructor = "::circt::ibis::createCallPrepPass()"; + let constructor = "::circt::kanagawa::createCallPrepPass()"; let dependentDialects = [ "::circt::hw::HWDialect"]; } -def IbisContainerize : Pass<"ibis-containerize", "DesignOp"> { - let summary = "Ibis containerization pass"; +def KanagawaContainerize : Pass<"kanagawa-containerize", "DesignOp"> { + let summary = "Kanagawa containerization pass"; let description = [{ - Convert Ibis classes to containers, and outlines containers inside classes. + Convert Kanagawa classes to containers, and outlines containers inside classes. }]; - let constructor = "::circt::ibis::createContainerizePass()"; + let constructor = "::circt::kanagawa::createContainerizePass()"; } -def IbisTunneling : Pass<"ibis-tunneling", "DesignOp"> { - let summary = "Ibis tunneling pass"; +def KanagawaTunneling : Pass<"kanagawa-tunneling", "DesignOp"> { + let summary = "Kanagawa tunneling pass"; let description = [{ Tunnels relative `get_port` ops through the module hierarchy, based on - `ibis.path` ops. The result of this pass is that various new in- and output - ports of `!ibis.portref<...>` type are created. + `kanagawa.path` ops. The result of this pass is that various new in- and output + ports of `!kanagawa.portref<...>` type are created. After this pass, `get_port` ops should only exist at the same scope of container instantiations. @@ -44,7 +44,7 @@ def IbisTunneling : Pass<"ibis-tunneling", "DesignOp"> { write accesses, and the suffixes must be different (in this case, the suffixes will be appended to the target port name, and thus de-alias the resulting ports). }]; - let constructor = "::circt::ibis::createTunnelingPass()"; + let constructor = "::circt::kanagawa::createTunnelingPass()"; let options = [ Option<"readSuffix", "read-suffix", "std::string", "\".rd\"", "Suffix to be used for the port when a port is tunneled for read access">, @@ -53,10 +53,10 @@ def IbisTunneling : Pass<"ibis-tunneling", "DesignOp"> { ]; } -def IbisPortrefLowering : Pass<"ibis-lower-portrefs", "::mlir::ModuleOp"> { - let summary = "Ibis portref lowering pass"; +def KanagawaPortrefLowering : Pass<"kanagawa-lower-portrefs", "::mlir::ModuleOp"> { + let summary = "Kanagawa portref lowering pass"; let description = [{ - Lower `ibis.portref>` to T (i.e. portref resolution). + Lower `kanagawa.portref>` to T (i.e. portref resolution). We do this by analyzing how a portref is used inside a container, and then creating an in- or output port based on that. @@ -75,48 +75,48 @@ def IbisPortrefLowering : Pass<"ibis-lower-portrefs", "::mlir::ModuleOp"> { the outside. A benefit of having portref lowering separate from portref tunneling is that - portref lowering can be done on an `ibis.container` granularity, allowing + portref lowering can be done on an `kanagawa.container` granularity, allowing for a bit of parallelism in the flow. }]; - let constructor = "::circt::ibis::createPortrefLoweringPass()"; + let constructor = "::circt::kanagawa::createPortrefLoweringPass()"; } -def IbisCleanSelfdrivers : Pass<"ibis-clean-selfdrivers", "DesignOp"> { - let summary = "Ibis clean selfdrivers pass"; +def KanagawaCleanSelfdrivers : Pass<"kanagawa-clean-selfdrivers", "DesignOp"> { + let summary = "Kanagawa clean selfdrivers pass"; let description = [{ - - Removes `ibis.port.input`s which are driven by operations within the same + - Removes `kanagawa.port.input`s which are driven by operations within the same container. - Removes reads of instance ports which are also written to within the same container. }]; - let constructor = "::circt::ibis::createCleanSelfdriversPass()"; + let constructor = "::circt::kanagawa::createCleanSelfdriversPass()"; let dependentDialects = ["::circt::hw::HWDialect"]; } -def IbisContainersToHW : Pass<"ibis-convert-containers-to-hw", "::mlir::ModuleOp"> { - let summary = "Ibis containers to hw conversion pass"; +def KanagawaContainersToHW : Pass<"kanagawa-convert-containers-to-hw", "::mlir::ModuleOp"> { + let summary = "Kanagawa containers to hw conversion pass"; let description = [{ - Converts `ibis.container` ops to `hw.module` ops. + Converts `kanagawa.container` ops to `hw.module` ops. }]; - let constructor = "::circt::ibis::createContainersToHWPass()"; + let constructor = "::circt::kanagawa::createContainersToHWPass()"; let dependentDialects = ["::circt::hw::HWDialect"]; } -def IbisArgifyBlocks : Pass<"ibis-argify-blocks"> { - let summary = "Add arguments to ibis blocks"; +def KanagawaArgifyBlocks : Pass<"kanagawa-argify-blocks"> { + let summary = "Add arguments to kanagawa blocks"; let description = [{ - Analyses `ibis.sblock` operations and converts any SSA value defined outside - the `ibis.sblock` to a block argument. As a result, `ibis.sblock.isolated` + Analyses `kanagawa.sblock` operations and converts any SSA value defined outside + the `kanagawa.sblock` to a block argument. As a result, `kanagawa.sblock.isolated` are produced. }]; - let constructor = "::circt::ibis::createArgifyBlocksPass()"; + let constructor = "::circt::kanagawa::createArgifyBlocksPass()"; } -def IbisReblock : Pass<"ibis-reblock", "ibis::MethodOp"> { - let summary = "Recreates `ibis.sblock` operations from a CFG"; +def KanagawaReblock : Pass<"kanagawa-reblock", "kanagawa::MethodOp"> { + let summary = "Recreates `kanagawa.sblock` operations from a CFG"; let description = [{ - Recreates `ibis.sblock` operations from a CFG. Any `ibis.block.attributes` + Recreates `kanagawa.sblock` operations from a CFG. Any `kanagawa.block.attributes` operations at the parent operation will be added to the resulting blocks. The IR is expected to be in maximal SSA form prior to this pass, given that @@ -124,7 +124,7 @@ def IbisReblock : Pass<"ibis-reblock", "ibis::MethodOp"> { values that are generated within the block. Maximum SSA form thus ensures that any value defined within the block is never used outside of the block. - It is expected that `ibis.call` operations have been isolated into + It is expected that `kanagawa.call` operations have been isolated into their own basic blocks before this pass is run. This implies that all operations within a block (except for the terminator operation) can be statically scheduled with each other. @@ -140,54 +140,54 @@ def IbisReblock : Pass<"ibis-reblock", "ibis::MethodOp"> { becomes ```mlir ^bb_foo(%arg0 : i32, %arg1 : i32): - %v_outer = ibis.sblock(%a0 : i32 = %arg0, %a1 : i32 = %arg1) -> (i32) { + %v_outer = kanagawa.sblock(%a0 : i32 = %arg0, %a1 : i32 = %arg1) -> (i32) { %res = arith.addi %arg0, %arg1 : i32 %v = ... - ibis.sblock.return %v : i32 + kanagawa.sblock.return %v : i32 } cf.br ^bb_bar(%v_outer : i32) ``` }]; - let constructor = "::circt::ibis::createReblockPass()"; + let constructor = "::circt::kanagawa::createReblockPass()"; } -def IbisInlineSBlocks : Pass<"ibis-inline-sblocks", "ibis::MethodOp"> { - let summary = "Inlines `ibis.sblock` operations as MLIR blocks"; +def KanagawaInlineSBlocks : Pass<"kanagawa-inline-sblocks", "kanagawa::MethodOp"> { + let summary = "Inlines `kanagawa.sblock` operations as MLIR blocks"; let description = [{ - Inlines `ibis.sblock` operations, by creating MLIR blocks and `cf` + Inlines `kanagawa.sblock` operations, by creating MLIR blocks and `cf` operations, while adding attributes to the parent operation about `sblock`-specific attributes. - The parent attributes are located under the `ibis.blockinfo` identifier as + The parent attributes are located under the `kanagawa.blockinfo` identifier as a dictionary attribute. Each entry in the dictionary consists of: - Key: an ID (numerical) string identifying the block. - Value: a dictionary of attributes. As a minimum this will contain a `loc`-keyed attribute specifying the location of the block. }]; - let constructor = "::circt::ibis::createInlineSBlocksPass()"; + let constructor = "::circt::kanagawa::createInlineSBlocksPass()"; let dependentDialects = ["::mlir::cf::ControlFlowDialect"]; } -def IbisConvertCFToHandshake : Pass<"ibis-convert-cf-to-handshake", "ibis::ClassOp"> { - let summary = "Converts an `ibis.method` to `ibis.method.df`"; +def KanagawaConvertCFToHandshake : Pass<"kanagawa-convert-cf-to-handshake", "kanagawa::ClassOp"> { + let summary = "Converts an `kanagawa.method` to `kanagawa.method.df`"; let description = [{ - Converts an `ibis.method` from using `cf` operations and MLIR blocks to - an `ibis.method.df` operation, using the `handshake` dialect to represent + Converts an `kanagawa.method` from using `cf` operations and MLIR blocks to + an `kanagawa.method.df` operation, using the `handshake` dialect to represent control flow through the `handshake` fine grained dataflow operations. }]; - let constructor = "::circt::ibis::createConvertCFToHandshakePass()"; + let constructor = "::circt::kanagawa::createConvertCFToHandshakePass()"; let dependentDialects = ["::circt::handshake::HandshakeDialect", "::mlir::cf::ControlFlowDialect"]; } -def IbisConvertHandshakeToDC : Pass<"ibis-convert-handshake-to-dc", "ibis::ClassOp"> { - let summary = "Converts an `ibis.method.df` to use DC"; +def KanagawaConvertHandshakeToDC : Pass<"kanagawa-convert-handshake-to-dc", "kanagawa::ClassOp"> { + let summary = "Converts an `kanagawa.method.df` to use DC"; let description = [{ - Converts an `ibis.method.df` from using `handshake` operations to + Converts an `kanagawa.method.df` from using `handshake` operations to `dc` operations. }]; - let constructor = "::circt::ibis::createConvertHandshakeToDCPass()"; + let constructor = "::circt::kanagawa::createConvertHandshakeToDCPass()"; let dependentDialects = [ "::circt::dc::DCDialect", "::circt::handshake::HandshakeDialect", @@ -195,31 +195,31 @@ def IbisConvertHandshakeToDC : Pass<"ibis-convert-handshake-to-dc", "ibis::Class ]; } -def IbisPrepareScheduling : Pass<"ibis-prepare-scheduling", "ibis::IsolatedStaticBlockOp"> { - let summary = "Prepare `ibis.sblock` operations for scheduling"; +def KanagawaPrepareScheduling : Pass<"kanagawa-prepare-scheduling", "kanagawa::IsolatedStaticBlockOp"> { + let summary = "Prepare `kanagawa.sblock` operations for scheduling"; let description = [{ - Prepares `ibis.sblock` operations for scheduling by: - - creating an `ibis.pipleine.header` operation - - moving operations of an `ibis.sblock` into a `pipeline.unscheduled` + Prepares `kanagawa.sblock` operations for scheduling by: + - creating an `kanagawa.pipleine.header` operation + - moving operations of an `kanagawa.sblock` into a `pipeline.unscheduled` operation, which is connected to the pipeline header. }]; - let constructor = "::circt::ibis::createPrepareSchedulingPass()"; + let constructor = "::circt::kanagawa::createPrepareSchedulingPass()"; let dependentDialects = ["::circt::pipeline::PipelineDialect"]; } -def IbisConvertMethodsToContainers : Pass<"ibis-convert-methods-to-containers", "ibis::ClassOp"> { - let summary = "Converts `ibis.method.df` to `ibis.container`s"; - let constructor = "::circt::ibis::createConvertMethodsToContainersPass()"; +def KanagawaConvertMethodsToContainers : Pass<"kanagawa-convert-methods-to-containers", "kanagawa::ClassOp"> { + let summary = "Converts `kanagawa.method.df` to `kanagawa.container`s"; + let constructor = "::circt::kanagawa::createConvertMethodsToContainersPass()"; } -def IbisAddOperatorLibrary : Pass<"ibis-add-operator-library", "::mlir::ModuleOp"> { - let summary = "Injects the Ibis operator library into the IR"; +def KanagawaAddOperatorLibrary : Pass<"kanagawa-add-operator-library", "::mlir::ModuleOp"> { + let summary = "Injects the Kanagawa operator library into the IR"; let description = [{ - Injects the Ibis operator library into the IR, which contains the - definitions of the Ibis operators. + Injects the Kanagawa operator library into the IR, which contains the + definitions of the Kanagawa operators. }]; - let constructor = "::circt::ibis::createAddOperatorLibraryPass()"; + let constructor = "::circt::kanagawa::createAddOperatorLibraryPass()"; let dependentDialects = ["::circt::ssp::SSPDialect"]; } -#endif // CIRCT_DIALECT_IBIS_PASSES_TD +#endif // CIRCT_DIALECT_KANAGAWA_PASSES_TD diff --git a/include/circt/Dialect/Ibis/IbisTypes.h b/include/circt/Dialect/Kanagawa/KanagawaTypes.h similarity index 54% rename from include/circt/Dialect/Ibis/IbisTypes.h rename to include/circt/Dialect/Kanagawa/KanagawaTypes.h index 83fd3d215e9a..b4e365b739c6 100644 --- a/include/circt/Dialect/Ibis/IbisTypes.h +++ b/include/circt/Dialect/Kanagawa/KanagawaTypes.h @@ -1,4 +1,4 @@ -//===- IbisTypes.h - Definition of Ibis dialect types ------------*- C++-*-===// +//===- KanagawaTypes.h - Definition of Kanagawa dialect types ---*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,24 +6,24 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISTYPES_H -#define CIRCT_DIALECT_IBIS_IBISTYPES_H +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_H +#define CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_H #include "circt/Dialect/HW/HWAttributes.h" -#include "circt/Dialect/Ibis/IbisDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" #include "circt/Support/LLVM.h" #include "mlir/IR/BuiltinAttributes.h" #include "mlir/IR/Types.h" namespace circt { -namespace ibis { -// Returns true if the given type is an opaque reference to an ibis class. +namespace kanagawa { +// Returns true if the given type is an opaque reference to an kanagawa class. bool isOpaqueScopeRefType(mlir::Type type); -} // namespace ibis +} // namespace kanagawa } // namespace circt #define GET_TYPEDEF_CLASSES -#include "circt/Dialect/Ibis/IbisTypes.h.inc" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h.inc" -#endif // CIRCT_DIALECT_IBIS_IBISTYPES_H +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_H diff --git a/include/circt/Dialect/Ibis/IbisTypes.td b/include/circt/Dialect/Kanagawa/KanagawaTypes.td similarity index 58% rename from include/circt/Dialect/Ibis/IbisTypes.td rename to include/circt/Dialect/Kanagawa/KanagawaTypes.td index 6c01c247aee1..c940c39555cf 100644 --- a/include/circt/Dialect/Ibis/IbisTypes.td +++ b/include/circt/Dialect/Kanagawa/KanagawaTypes.td @@ -1,4 +1,4 @@ -//===- IbisTypes.td - Definition of Ibis dialect types --------------------===// +//===- KanagawaTypes.td - Definition of Kanagawa dialect types ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,19 +6,19 @@ // //===----------------------------------------------------------------------===// -#ifndef CIRCT_DIALECT_IBIS_IBISTYPES_TD -#define CIRCT_DIALECT_IBIS_IBISTYPES_TD +#ifndef CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_TD +#define CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_TD -include "circt/Dialect/Ibis/IbisDialect.td" +include "circt/Dialect/Kanagawa/KanagawaDialect.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/EnumAttr.td" -class IbisTypeDef : TypeDef { } +class KanagawaTypeDef : TypeDef { } -def ScopeRefType : IbisTypeDef<"ScopeRef"> { +def ScopeRefType : KanagawaTypeDef<"ScopeRef"> { let mnemonic = "scoperef"; let description = [{ - A reference to an Ibis scope. May be either a reference to a specific + A reference to an Kanagawa scope. May be either a reference to a specific scope (given a `$scopeName` argument) or an opaque reference. }]; @@ -39,30 +39,30 @@ def ScopeRefType : IbisTypeDef<"ScopeRef"> { } def AnyScopeRefType : Type< - CPred<"llvm::isa($_self)">, + CPred<"llvm::isa($_self)">, "must be a !dc.classref type", - "ibis::ScopeRefType">{ + "kanagawa::ScopeRefType">{ } def OpaqueScopeRefType : Type< - CPred<"ibis::isOpaqueScopeRefType($_self)">, + CPred<"kanagawa::isOpaqueScopeRefType($_self)">, "must be a !dc.classref<> type">, - BuildableType<"$_builder.getType()"> { + BuildableType<"$_builder.getType()"> { } def Input : I32EnumAttrCase<"Input", 0, "in">; def Output : I32EnumAttrCase<"Output", 1, "out">; -def Direction : I32EnumAttr<"Direction", "Ibis port direction", +def Direction : I32EnumAttr<"Direction", "Kanagawa port direction", [Input, Output]> { - let cppNamespace = "::circt::ibis"; + let cppNamespace = "::circt::kanagawa"; } -def PortRefType : IbisTypeDef<"PortRef"> { +def PortRefType : KanagawaTypeDef<"PortRef"> { let mnemonic = "portref"; - let parameters = (ins "TypeAttr":$portTypeAttr, "ibis::Direction":$direction); + let parameters = (ins "TypeAttr":$portTypeAttr, "kanagawa::Direction":$direction); let assemblyFormat = "`<` $direction $portTypeAttr `>`"; let description = [{ - A reference to an Ibis port. + A reference to an Kanagawa port. }]; let extraClassDeclaration = [{ @@ -72,10 +72,10 @@ def PortRefType : IbisTypeDef<"PortRef"> { }]; let builders = [ - TypeBuilder<(ins "Type":$t, "ibis::Direction":$d), [{ + TypeBuilder<(ins "Type":$t, "kanagawa::Direction":$d), [{ return $_get($_ctxt, TypeAttr::get(t), d); }]> ]; } -#endif // CIRCT_DIALECT_IBIS_IBISTYPES_TD +#endif // CIRCT_DIALECT_KANAGAWA_KANAGAWATYPES_TD diff --git a/include/circt/InitAllDialects.h b/include/circt/InitAllDialects.h index 3212a01c154d..e443e74cc2fb 100644 --- a/include/circt/InitAllDialects.h +++ b/include/circt/InitAllDialects.h @@ -28,8 +28,8 @@ #include "circt/Dialect/HW/HWDialect.h" #include "circt/Dialect/HWArith/HWArithDialect.h" #include "circt/Dialect/Handshake/HandshakeDialect.h" -#include "circt/Dialect/Ibis/IbisDialect.h" #include "circt/Dialect/Interop/InteropDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" #include "circt/Dialect/LLHD/IR/LLHDDialect.h" #include "circt/Dialect/LTL/LTLDialect.h" #include "circt/Dialect/LoopSchedule/LoopScheduleDialect.h" @@ -67,7 +67,7 @@ inline void registerAllDialects(mlir::DialectRegistry ®istry) { hw::HWDialect, hwarith::HWArithDialect, interop::InteropDialect, - ibis::IbisDialect, + kanagawa::KanagawaDialect, llhd::LLHDDialect, loopschedule::LoopScheduleDialect, ltl::LTLDialect, diff --git a/include/circt/InitAllPasses.h b/include/circt/InitAllPasses.h index 36ae439f2970..48ed141491c8 100644 --- a/include/circt/InitAllPasses.h +++ b/include/circt/InitAllPasses.h @@ -26,7 +26,7 @@ #include "circt/Dialect/FSM/FSMPasses.h" #include "circt/Dialect/HW/HWPasses.h" #include "circt/Dialect/Handshake/HandshakePasses.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "circt/Dialect/LLHD/Transforms/Passes.h" #include "circt/Dialect/MSFT/MSFTPasses.h" #include "circt/Dialect/Moore/MoorePasses.h" @@ -72,7 +72,7 @@ inline void registerAllPasses() { seq::registerPasses(); sv::registerPasses(); handshake::registerPasses(); - ibis::registerPasses(); + kanagawa::registerPasses(); hw::registerPasses(); pipeline::registerPasses(); sim::registerPasses(); diff --git a/integration_test/CMakeLists.txt b/integration_test/CMakeLists.txt index 23894fd1ac8f..1c7aa16af4c5 100644 --- a/integration_test/CMakeLists.txt +++ b/integration_test/CMakeLists.txt @@ -14,7 +14,7 @@ set(CIRCT_INTEGRATION_TEST_DEPENDS circt-test-runner-sby firtool hlstool - ibistool + kanagawatool handshake-runner ) diff --git a/integration_test/Dialect/Ibis/end_to_end.mlir b/integration_test/Dialect/Ibis/end_to_end.mlir index 01033609731a..d2bcb818937a 100644 --- a/integration_test/Dialect/Ibis/end_to_end.mlir +++ b/integration_test/Dialect/Ibis/end_to_end.mlir @@ -1,51 +1,51 @@ // XFAIL: * // See https://github.com/llvm/circt/issues/6658 -// RUN: ibistool -lo %s +// RUN: kanagawatool -lo %s -ibis.design @foo { +kanagawa.design @foo { // A class hierarchy with a shared parent, and accessing between the children -ibis.class sym @C1 { - %this = ibis.this <@foo::@C1> - %out = ibis.port.output "out" sym @out : i32 +kanagawa.class sym @C1 { + %this = kanagawa.this <@foo::@C1> + %out = kanagawa.port.output "out" sym @out : i32 %c0 = hw.constant 42 : i32 - ibis.port.write %out, %c0 : !ibis.portref + kanagawa.port.write %out, %c0 : !kanagawa.portref } -ibis.class sym @C2 { - %this = ibis.this <@foo::@C2> +kanagawa.class sym @C2 { + %this = kanagawa.this <@foo::@C2> - %go_port = ibis.port.input "go" sym @go : i1 - %clk_port = ibis.port.input "clk" sym @clk : !seq.clock - %rst_port = ibis.port.input "rst" sym @rst : i1 - %done_port = ibis.port.output "done" sym @done : i1 - %out_port = ibis.port.output "out" sym @out : i32 + %go_port = kanagawa.port.input "go" sym @go : i1 + %clk_port = kanagawa.port.input "clk" sym @clk : !seq.clock + %rst_port = kanagawa.port.input "rst" sym @rst : i1 + %done_port = kanagawa.port.output "done" sym @done : i1 + %out_port = kanagawa.port.output "out" sym @out : i32 - ibis.container sym @MyMethod { - %t = ibis.this <@foo::@MyMethod> + kanagawa.container sym @MyMethod { + %t = kanagawa.this <@foo::@MyMethod> // Grab parent go, clk, reset inputs - note that the requested direction of // these are flipped wrt. the defined direction of the ports. The semantics // are now that get_port defines the intended usage of the port (in => i'll write to the port, out => i'll read from the port). - %parent = ibis.path [ - #ibis.step> + %parent = kanagawa.path [ + #kanagawa.step> ] - %go_ref = ibis.get_port %parent, @go : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %go = ibis.port.read %go_ref : !ibis.portref - %clk_ref = ibis.get_port %parent, @clk : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %clk = ibis.port.read %clk_ref : !ibis.portref - %rst_ref = ibis.get_port %parent, @rst : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %rst = ibis.port.read %rst_ref : !ibis.portref + %go_ref = kanagawa.get_port %parent, @go : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %go = kanagawa.port.read %go_ref : !kanagawa.portref + %clk_ref = kanagawa.get_port %parent, @clk : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %clk = kanagawa.port.read %clk_ref : !kanagawa.portref + %rst_ref = kanagawa.get_port %parent, @rst : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %rst = kanagawa.port.read %rst_ref : !kanagawa.portref // Grab sibling c1's output - %sibling = ibis.path [ - #ibis.step, - #ibis.step, - #ibis.step> + %sibling = kanagawa.path [ + #kanagawa.step, + #kanagawa.step, + #kanagawa.step> ] - %sibling_out_ref = ibis.get_port %sibling, @out : !ibis.scoperef<@foo::@C1> -> !ibis.portref - %sibling_out = ibis.port.read %sibling_out_ref : !ibis.portref + %sibling_out_ref = kanagawa.get_port %sibling, @out : !kanagawa.scoperef<@foo::@C1> -> !kanagawa.portref + %sibling_out = kanagawa.port.read %sibling_out_ref : !kanagawa.portref %res, %done = pipeline.scheduled(%a0 : i32 = %sibling_out) clock(%clk) reset(%rst) go(%go) entryEn(%s0_enable) -> (out : i32) { %0 = comb.mul %a0, %a0 : i32 @@ -61,45 +61,45 @@ ibis.class sym @C2 { } // Assign parent done port and output - %parent_done_ref = ibis.get_port %parent, @done : !ibis.scoperef<@foo::@C2> -> !ibis.portref - ibis.port.write %parent_done_ref, %done : !ibis.portref - %parent_out_ref = ibis.get_port %parent, @out : !ibis.scoperef<@foo::@C2> -> !ibis.portref - ibis.port.write %parent_out_ref, %res : !ibis.portref + %parent_done_ref = kanagawa.get_port %parent, @done : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + kanagawa.port.write %parent_done_ref, %done : !kanagawa.portref + %parent_out_ref = kanagawa.get_port %parent, @out : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + kanagawa.port.write %parent_out_ref, %res : !kanagawa.portref } } -ibis.class sym @Parent { - %this = ibis.this <@foo::@Parent> - %c1 = ibis.instance @c1, <@foo::@C1> - %c2 = ibis.instance @c2, <@foo::@C2> +kanagawa.class sym @Parent { + %this = kanagawa.this <@foo::@Parent> + %c1 = kanagawa.instance @c1, <@foo::@C1> + %c2 = kanagawa.instance @c2, <@foo::@C2> - %go = ibis.port.input "go" sym @go : i1 - %clk = ibis.port.input "clk" sym @clk : !seq.clock - %rst = ibis.port.input "rst" sym @rst : i1 + %go = kanagawa.port.input "go" sym @go : i1 + %clk = kanagawa.port.input "clk" sym @clk : !seq.clock + %rst = kanagawa.port.input "rst" sym @rst : i1 - %done = ibis.port.output "done" sym @done : i1 - %out = ibis.port.output "out" sym @out : i32 + %done = kanagawa.port.output "done" sym @done : i1 + %out = kanagawa.port.output "out" sym @out : i32 // Wire up to c2 - %go_ref = ibis.get_port %c2, @go : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %go_val = ibis.port.read %go : !ibis.portref - ibis.port.write %go_ref, %go_val : !ibis.portref + %go_ref = kanagawa.get_port %c2, @go : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %go_val = kanagawa.port.read %go : !kanagawa.portref + kanagawa.port.write %go_ref, %go_val : !kanagawa.portref - %clk_ref = ibis.get_port %c2, @clk : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %clk_val = ibis.port.read %clk : !ibis.portref - ibis.port.write %clk_ref, %clk_val : !ibis.portref + %clk_ref = kanagawa.get_port %c2, @clk : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %clk_val = kanagawa.port.read %clk : !kanagawa.portref + kanagawa.port.write %clk_ref, %clk_val : !kanagawa.portref - %rst_ref = ibis.get_port %c2, @rst : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %rst_val = ibis.port.read %rst : !ibis.portref - ibis.port.write %rst_ref, %rst_val : !ibis.portref + %rst_ref = kanagawa.get_port %c2, @rst : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %rst_val = kanagawa.port.read %rst : !kanagawa.portref + kanagawa.port.write %rst_ref, %rst_val : !kanagawa.portref - %done_ref = ibis.get_port %c2, @done : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %done_val = ibis.port.read %done_ref : !ibis.portref - ibis.port.write %done, %done_val : !ibis.portref + %done_ref = kanagawa.get_port %c2, @done : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %done_val = kanagawa.port.read %done_ref : !kanagawa.portref + kanagawa.port.write %done, %done_val : !kanagawa.portref - %out_ref = ibis.get_port %c2, @out : !ibis.scoperef<@foo::@C2> -> !ibis.portref - %out_val = ibis.port.read %out_ref : !ibis.portref - ibis.port.write %out, %out_val : !ibis.portref + %out_ref = kanagawa.get_port %c2, @out : !kanagawa.scoperef<@foo::@C2> -> !kanagawa.portref + %out_val = kanagawa.port.read %out_ref : !kanagawa.portref + kanagawa.port.write %out, %out_val : !kanagawa.portref } } diff --git a/integration_test/lit.cfg.py b/integration_test/lit.cfg.py index 022607617c81..371b3da3395f 100644 --- a/integration_test/lit.cfg.py +++ b/integration_test/lit.cfg.py @@ -79,7 +79,7 @@ ] tools = [ 'arcilator', 'circt-opt', 'circt-translate', 'firtool', 'circt-rtl-sim.py', - 'equiv-rtl.sh', 'handshake-runner', 'hlstool', 'ibistool', 'circt-lec', + 'equiv-rtl.sh', 'handshake-runner', 'hlstool', 'kanagawatool', 'circt-lec', 'circt-bmc', 'circt-test', 'circt-test-runner-sby.py' ] diff --git a/lib/Dialect/CMakeLists.txt b/lib/Dialect/CMakeLists.txt index eb30485abf79..9ebf9e4fa97b 100644 --- a/lib/Dialect/CMakeLists.txt +++ b/lib/Dialect/CMakeLists.txt @@ -22,7 +22,7 @@ add_subdirectory(FSM) add_subdirectory(Handshake) add_subdirectory(HW) add_subdirectory(HWArith) -add_subdirectory(Ibis) +add_subdirectory(Kanagawa) add_subdirectory(Interop) add_subdirectory(LLHD) add_subdirectory(LoopSchedule) diff --git a/lib/Dialect/Ibis/CMakeLists.txt b/lib/Dialect/Ibis/CMakeLists.txt deleted file mode 100644 index 9411bf68fa96..000000000000 --- a/lib/Dialect/Ibis/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ -add_circt_dialect_library(CIRCTIbis - IbisDialect.cpp - IbisOps.cpp - IbisTypes.cpp - - DEPENDS - MLIRIbisIncGen - - LINK_LIBS PUBLIC - MLIRIR - CIRCTHW - CIRCTDC - CIRCTSeq -) - -add_subdirectory(Transforms) diff --git a/lib/Dialect/Ibis/Transforms/CMakeLists.txt b/lib/Dialect/Ibis/Transforms/CMakeLists.txt deleted file mode 100644 index c54239552379..000000000000 --- a/lib/Dialect/Ibis/Transforms/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -add_circt_dialect_library(CIRCTIbisTransforms - IbisCallPrep.cpp - IbisContainerize.cpp - IbisTunneling.cpp - IbisPortrefLowering.cpp - IbisCleanSelfdrivers.cpp - IbisContainersToHW.cpp - IbisArgifyBlocksPass.cpp - IbisReblockPass.cpp - IbisInlineSBlocksPass.cpp - IbisConvertCFToHandshake.cpp - IbisPassPipelines.cpp - IbisPrepareScheduling.cpp - IbisConvertHandshakeToDC.cpp - IbisMethodsToContainers.cpp - IbisAddOperatorLibrary.cpp - - DEPENDS - CIRCTIbisTransformsIncGen - - LINK_LIBS PUBLIC - CIRCTDC - CIRCTHandshake - CIRCTPipelineOps - CIRCTCFToHandshake - CIRCTHandshakeToDC - CIRCTIbis - CIRCTSSP - CIRCTHW - CIRCTHWTransforms - CIRCTSupport - CIRCTTransforms - MLIRIR - MLIRPass - MLIRTransformUtils -) diff --git a/lib/Dialect/Kanagawa/CMakeLists.txt b/lib/Dialect/Kanagawa/CMakeLists.txt new file mode 100644 index 000000000000..3ea8eccdf6f6 --- /dev/null +++ b/lib/Dialect/Kanagawa/CMakeLists.txt @@ -0,0 +1,16 @@ +add_circt_dialect_library(CIRCTKanagawa + KanagawaDialect.cpp + KanagawaOps.cpp + KanagawaTypes.cpp + + DEPENDS + MLIRKanagawaIncGen + + LINK_LIBS PUBLIC + MLIRIR + CIRCTHW + CIRCTDC + CIRCTSeq +) + +add_subdirectory(Transforms) diff --git a/lib/Dialect/Ibis/IbisDialect.cpp b/lib/Dialect/Kanagawa/KanagawaDialect.cpp similarity index 55% rename from lib/Dialect/Ibis/IbisDialect.cpp rename to lib/Dialect/Kanagawa/KanagawaDialect.cpp index a12495805705..6e5602ae72c9 100644 --- a/lib/Dialect/Ibis/IbisDialect.cpp +++ b/lib/Dialect/Kanagawa/KanagawaDialect.cpp @@ -1,4 +1,4 @@ -//===- IbisDialect.cpp - Implementation of Ibis dialect -------------------===// +//===- KanagawaDialect.cpp - Implementation of Kanagawa dialect -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,37 +6,37 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" #include "mlir/IR/DialectImplementation.h" #include "llvm/ADT/TypeSwitch.h" using namespace circt; -using namespace ibis; +using namespace kanagawa; // Pull in the dialect definition. -#include "circt/Dialect/Ibis/IbisDialect.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaDialect.cpp.inc" -void IbisDialect::initialize() { +void KanagawaDialect::initialize() { registerTypes(); registerAttributes(); // Register operations. addOperations< #define GET_OP_LIST -#include "circt/Dialect/Ibis/Ibis.cpp.inc" +#include "circt/Dialect/Kanagawa/Kanagawa.cpp.inc" >(); } -void IbisDialect::registerAttributes() { +void KanagawaDialect::registerAttributes() { addAttributes< #define GET_ATTRDEF_LIST -#include "circt/Dialect/Ibis/IbisAttributes.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaAttributes.cpp.inc" >(); } // Provide implementations for the enums we use. -#include "circt/Dialect/Ibis/IbisEnums.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaEnums.cpp.inc" #define GET_ATTRDEF_CLASSES -#include "circt/Dialect/Ibis/IbisAttributes.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaAttributes.cpp.inc" diff --git a/lib/Dialect/Ibis/IbisOps.cpp b/lib/Dialect/Kanagawa/KanagawaOps.cpp similarity index 95% rename from lib/Dialect/Ibis/IbisOps.cpp rename to lib/Dialect/Kanagawa/KanagawaOps.cpp index 4cc64eff6f0e..8282d2c09de4 100644 --- a/lib/Dialect/Ibis/IbisOps.cpp +++ b/lib/Dialect/Kanagawa/KanagawaOps.cpp @@ -1,4 +1,4 @@ -//===- IbisOps.cpp - Implementation of Ibis dialect ops -------------------===// +//===- KanagawaOps.cpp - Implementation of Kanagawa dialect ops -----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" #include "circt/Dialect/DC/DCTypes.h" #include "circt/Support/ParsingUtils.h" @@ -19,7 +19,7 @@ using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; template ParseResult parseScopeRefFromName(OpAsmParser &parser, Type &scopeRefType, @@ -36,7 +36,7 @@ void printScopeRefFromName(OpAsmPrinter &p, Operation *op, Type type, // symbol. } -// Generates a name for Ibis values. +// Generates a name for Kanagawa values. // NOLINTBEGIN(misc-no-recursion) static llvm::raw_string_ostream &genValueName(llvm::raw_string_ostream &os, Value value) { @@ -72,7 +72,7 @@ static llvm::raw_string_ostream &genValueName(llvm::raw_string_ostream &os, } // NOLINTEND(misc-no-recursion) -// Generates a name for Ibis values, and returns a StringAttr. +// Generates a name for Kanagawa values, and returns a StringAttr. static StringAttr genValueNameAttr(Value v) { std::string s; llvm::raw_string_ostream os(s); @@ -85,19 +85,19 @@ static StringAttr genValueNameAttr(Value v) { //===----------------------------------------------------------------------===// FailureOr> -circt::ibis::detail::getThisFromScope(Operation *op) { +circt::kanagawa::detail::getThisFromScope(Operation *op) { auto scopeOp = cast(op); - auto thisOps = scopeOp.getBodyBlock()->getOps(); + auto thisOps = scopeOp.getBodyBlock()->getOps(); if (thisOps.empty()) - return op->emitOpError("must contain a 'ibis.this' operation"); + return op->emitOpError("must contain a 'kanagawa.this' operation"); if (std::next(thisOps.begin()) != thisOps.end()) - return op->emitOpError("must contain only one 'ibis.this' operation"); + return op->emitOpError("must contain only one 'kanagawa.this' operation"); return (*thisOps.begin()).getThisRef(); } -LogicalResult circt::ibis::detail::verifyScopeOpInterface(Operation *op) { +LogicalResult circt::kanagawa::detail::verifyScopeOpInterface(Operation *op) { if (failed(getThisFromScope(op))) return failure(); @@ -325,7 +325,7 @@ PortOpInterface GetPortOp::getPort(const hw::InnerRefNamespace &ns) { LogicalResult GetPortOp::canonicalize(GetPortOp op, PatternRewriter &rewriter) { // Canonicalize away get_port on %this in favor of using the port SSA value // directly. - // get_port(%this, @P) -> ibis.port.# + // get_port(%this, @P) -> kanagawa.port.# auto parentScope = dyn_cast(op->getParentOp()); if (parentScope) { auto scopeThis = parentScope.getThis(); @@ -425,15 +425,17 @@ LogicalResult PathStepAttr::verify(function_ref emitError, mlir::FlatSymbolRefAttr instance) { // 'parent' should never have an instance name specified. if (direction == PathDirection::Parent && instance) - return emitError() << "ibis.step 'parent' may not specify an instance name"; + return emitError() + << "kanagawa.step 'parent' may not specify an instance name"; if (direction == PathDirection::Child && !instance) - return emitError() << "ibis.step 'child' must specify an instance name"; + return emitError() << "kanagawa.step 'child' must specify an instance name"; // Only allow scoperefs auto scoperefType = llvm::dyn_cast(type); if (!scoperefType) - return emitError() << "ibis.step type must be an !ibis.scoperef type"; + return emitError() + << "kanagawa.step type must be an !kanagawa.scoperef type"; return success(); } @@ -441,7 +443,7 @@ LogicalResult PathStepAttr::verify(function_ref emitError, LogicalResult PathOp::verifyInnerRefs(hw::InnerRefNamespace &ns) { auto pathRange = getPathAsRange(); if (pathRange.empty()) - return emitOpError() << "ibis.path must have at least one step"; + return emitOpError() << "kanagawa.path must have at least one step"; // Verify that each referenced child symbol actually exists at the module // level. @@ -453,7 +455,7 @@ LogicalResult PathOp::verifyInnerRefs(hw::InnerRefNamespace &ns) { auto *targetScope = ns.lookupOp(scopeRefSym); if (!targetScope) - return emitOpError() << "ibis.step scoperef symbol '@" + return emitOpError() << "kanagawa.step scoperef symbol '@" << scopeRefSym.getName().getValue() << "' does not exist"; } @@ -462,15 +464,15 @@ LogicalResult PathOp::verifyInnerRefs(hw::InnerRefNamespace &ns) { PathStepAttr lastStep = *std::prev(getPathAsRange().end()); ScopeRefType lastStepType = cast(lastStep.getType()); if (!lastStepType.getScopeRef()) - return emitOpError() - << "last ibis.step in path must specify a symbol for the scoperef"; + return emitOpError() << "last kanagawa.step in path must specify a symbol " + "for the scoperef"; return success(); } LogicalResult PathOp::canonicalize(PathOp op, PatternRewriter &rewriter) { - // Canonicalize away ibis.path [ibis.child] to just referencing the instance - // in the current scope. + // Canonicalize away kanagawa.path [kanagawa.child] to just referencing the + // instance in the current scope. auto range = op.getPathAsRange(); size_t pathSize = std::distance(range.begin(), range.end()); PathStepAttr firstStep = *range.begin(); @@ -817,8 +819,8 @@ InlineStaticBlockEndOp InlineStaticBlockBeginOp::getEndOp() { // TableGen generated logic //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisInterfaces.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaInterfaces.cpp.inc" // Provide the autogenerated implementation guts for the Op classes. #define GET_OP_CLASSES -#include "circt/Dialect/Ibis/Ibis.cpp.inc" +#include "circt/Dialect/Kanagawa/Kanagawa.cpp.inc" diff --git a/lib/Dialect/Ibis/IbisTypes.cpp b/lib/Dialect/Kanagawa/KanagawaTypes.cpp similarity index 73% rename from lib/Dialect/Ibis/IbisTypes.cpp rename to lib/Dialect/Kanagawa/KanagawaTypes.cpp index e9e9a496fa8e..b88bff6a9892 100644 --- a/lib/Dialect/Ibis/IbisTypes.cpp +++ b/lib/Dialect/Kanagawa/KanagawaTypes.cpp @@ -1,4 +1,4 @@ -//===- IbisTypes.cpp - Implementation of Ibis dialect types ---------------===// +//===- KanagawaTypes.cpp - Implementation of Kanagawa dialect types -------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,18 +6,18 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisTypes.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" #include "mlir/IR/DialectImplementation.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/TypeSwitch.h" using namespace circt; -using namespace ibis; +using namespace kanagawa; -bool circt::ibis::isOpaqueScopeRefType(mlir::Type type) { +bool circt::kanagawa::isOpaqueScopeRefType(mlir::Type type) { auto scopeRef = dyn_cast(type); if (!scopeRef) return false; @@ -47,12 +47,12 @@ void ScopeRefType::print(AsmPrinter &p) const { } #define GET_TYPEDEF_CLASSES -#include "circt/Dialect/Ibis/IbisTypes.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaTypes.cpp.inc" -void IbisDialect::registerTypes() { +void KanagawaDialect::registerTypes() { // Register types. addTypes< #define GET_TYPEDEF_LIST -#include "circt/Dialect/Ibis/IbisTypes.cpp.inc" +#include "circt/Dialect/Kanagawa/KanagawaTypes.cpp.inc" >(); } diff --git a/lib/Dialect/Kanagawa/Transforms/CMakeLists.txt b/lib/Dialect/Kanagawa/Transforms/CMakeLists.txt new file mode 100644 index 000000000000..5d4e25de4f31 --- /dev/null +++ b/lib/Dialect/Kanagawa/Transforms/CMakeLists.txt @@ -0,0 +1,36 @@ +add_circt_dialect_library(CIRCTKanagawaTransforms + KanagawaCallPrep.cpp + KanagawaContainerize.cpp + KanagawaTunneling.cpp + KanagawaPortrefLowering.cpp + KanagawaCleanSelfdrivers.cpp + KanagawaContainersToHW.cpp + KanagawaArgifyBlocksPass.cpp + KanagawaReblockPass.cpp + KanagawaInlineSBlocksPass.cpp + KanagawaConvertCFToHandshake.cpp + KanagawaPassPipelines.cpp + KanagawaPrepareScheduling.cpp + KanagawaConvertHandshakeToDC.cpp + KanagawaMethodsToContainers.cpp + KanagawaAddOperatorLibrary.cpp + + DEPENDS + CIRCTKanagawaTransformsIncGen + + LINK_LIBS PUBLIC + CIRCTDC + CIRCTHandshake + CIRCTPipelineOps + CIRCTCFToHandshake + CIRCTHandshakeToDC + CIRCTKanagawa + CIRCTSSP + CIRCTHW + CIRCTHWTransforms + CIRCTSupport + CIRCTTransforms + MLIRIR + MLIRPass + MLIRTransformUtils +) diff --git a/lib/Dialect/Ibis/Transforms/IbisAddOperatorLibrary.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaAddOperatorLibrary.cpp similarity index 73% rename from lib/Dialect/Ibis/Transforms/IbisAddOperatorLibrary.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaAddOperatorLibrary.cpp index 4b96b9929dd4..88c330465696 100644 --- a/lib/Dialect/Ibis/Transforms/IbisAddOperatorLibrary.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaAddOperatorLibrary.cpp @@ -1,4 +1,4 @@ -//===- IbisAddOperatorLibraryPass.cpp -------------------------------------===// +//===- KanagawaAddOperatorLibraryPass.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" #include "circt/Dialect/Comb/CombOps.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Dialect/SSP/SSPOps.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" @@ -25,20 +25,20 @@ #include namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISADDOPERATORLIBRARY -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAADDOPERATORLIBRARY +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { struct AddOperatorLibraryPass - : public circt::ibis::impl::IbisAddOperatorLibraryBase< + : public circt::kanagawa::impl::KanagawaAddOperatorLibraryBase< AddOperatorLibraryPass> { void runOnOperation() override; }; @@ -58,7 +58,7 @@ void AddOperatorLibraryPass::runOnOperation() { auto b = ImplicitLocOpBuilder::atBlockBegin(getOperation().getLoc(), getOperation().getBody()); auto opLib = b.create(); - opLib.setSymNameAttr(b.getStringAttr(kIbisOperatorLibName)); + opLib.setSymNameAttr(b.getStringAttr(kKanagawaOperatorLibName)); b.setInsertionPointToStart(opLib.getBodyBlock()); // Provide definitions for some comb ops - just latency properties for now. @@ -84,6 +84,6 @@ void AddOperatorLibraryPass::runOnOperation() { addOperator(b, 1); } -std::unique_ptr circt::ibis::createAddOperatorLibraryPass() { +std::unique_ptr circt::kanagawa::createAddOperatorLibraryPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisArgifyBlocksPass.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaArgifyBlocksPass.cpp similarity index 81% rename from lib/Dialect/Ibis/Transforms/IbisArgifyBlocksPass.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaArgifyBlocksPass.cpp index 48f0a1537169..6c5cb750bc89 100644 --- a/lib/Dialect/Ibis/Transforms/IbisArgifyBlocksPass.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaArgifyBlocksPass.cpp @@ -1,4 +1,4 @@ -//===- IbisArgifyBlocksPass.cpp -------------------------------------------===// +//===- KanagawaArgifyBlocksPass.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,26 +6,26 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISARGIFYBLOCKS -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAARGIFYBLOCKS +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { @@ -84,7 +84,7 @@ struct BlockConversionPattern : public OpConversionPattern { }; struct ArgifyBlocksPass - : public circt::ibis::impl::IbisArgifyBlocksBase { + : public circt::kanagawa::impl::KanagawaArgifyBlocksBase { void runOnOperation() override; }; } // anonymous namespace @@ -93,7 +93,7 @@ void ArgifyBlocksPass::runOnOperation() { auto *ctx = &getContext(); ConversionTarget target(*ctx); target.addIllegalOp(); - target.addLegalDialect(); + target.addLegalDialect(); RewritePatternSet patterns(ctx); patterns.add(ctx); @@ -103,6 +103,6 @@ void ArgifyBlocksPass::runOnOperation() { signalPassFailure(); } -std::unique_ptr circt::ibis::createArgifyBlocksPass() { +std::unique_ptr circt::kanagawa::createArgifyBlocksPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisCallPrep.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaCallPrep.cpp similarity index 91% rename from lib/Dialect/Ibis/Transforms/IbisCallPrep.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaCallPrep.cpp index 69555f73db46..17ac6dcafbf4 100644 --- a/lib/Dialect/Ibis/Transforms/IbisCallPrep.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaCallPrep.cpp @@ -1,4 +1,4 @@ -//===- IbisCallPrep.cpp - Implementation of call prep lowering ------------===// +//===- KanagawaCallPrep.cpp - Implementation of call prep lowering --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Dialect/HW/ConversionPatterns.h" #include "circt/Dialect/HW/HWOps.h" @@ -23,14 +23,14 @@ #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCALLPREP -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACALLPREP +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; /// Build indexes to make lookups faster. Create the new argument types as well. struct CallPrepPrecomputed { @@ -131,7 +131,7 @@ void MergeCallArgs::rewrite(CallOp call, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const { auto loc = call.getLoc(); rewriter.setInsertionPoint(call); - auto method = call->getParentOfType(); + auto method = call->getParentOfType(); // Use the 'info' accelerator structures to find the argument type. auto argStructEntry = info.argTypes.find(call.getCalleeAttr()); @@ -208,7 +208,8 @@ void MergeMethodArgs::rewrite(MethodOp func, OpAdaptor adaptor, namespace { /// Run all the physical lowerings. -struct CallPrepPass : public circt::ibis::impl::IbisCallPrepBase { +struct CallPrepPass + : public circt::kanagawa::impl::KanagawaCallPrepBase { void runOnOperation() override; private: @@ -249,6 +250,6 @@ LogicalResult CallPrepPass::merge(const CallPrepPrecomputed &info) { return applyPartialConversion(getOperation(), target, std::move(patterns)); } -std::unique_ptr circt::ibis::createCallPrepPass() { +std::unique_ptr circt::kanagawa::createCallPrepPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisCleanSelfdrivers.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaCleanSelfdrivers.cpp similarity index 87% rename from lib/Dialect/Ibis/Transforms/IbisCleanSelfdrivers.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaCleanSelfdrivers.cpp index c2442151a064..1bc0aa1c1ffa 100644 --- a/lib/Dialect/Ibis/Transforms/IbisCleanSelfdrivers.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaCleanSelfdrivers.cpp @@ -1,4 +1,4 @@ -//===- IbisCleanSelfdrivers.cpp -------------------------------------------===// +//===- KanagawaCleanSelfdrivers.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,32 +6,32 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" #include "circt/Dialect/HW/HWOps.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Support/InstanceGraph.h" #include "llvm/Support/Debug.h" #include "mlir/Transforms/DialectConversion.h" #include "llvm/ADT/TypeSwitch.h" -#define DEBUG_TYPE "ibis-clean-selfdrivers" +#define DEBUG_TYPE "kanagawa-clean-selfdrivers" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCLEANSELFDRIVERS -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACLEANSELFDRIVERS +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; using namespace circt::igraph; // Returns true if the given input port is self-driven, i.e. there exists @@ -156,10 +156,10 @@ struct InputPortOpConversionPattern : public OpConversionPattern { for (auto reader : readers) rewriter.replaceOp(reader, wire); - // Since Ibis allows for input ports to be read from outside the container, - // we need to check the instance graph to see whether this is the case. - // If so, we need to add an output port to the container and connect it to - // the assigned value. + // Since Kanagawa allows for input ports to be read from outside the + // container, we need to check the instance graph to see whether this is the + // case. If so, we need to add an output port to the container and connect + // it to the assigned value. auto parentModuleOp = dyn_cast(op->getParentOp()); if (parentModuleOp) { InstanceGraphNode *node = ig.lookup(parentModuleOp); @@ -191,7 +191,8 @@ struct InputPortOpConversionPattern : public OpConversionPattern { }; struct CleanSelfdriversPass - : public circt::ibis::impl::IbisCleanSelfdriversBase { + : public circt::kanagawa::impl::KanagawaCleanSelfdriversBase< + CleanSelfdriversPass> { void runOnOperation() override; LogicalResult cleanInstanceSide(); @@ -210,7 +211,7 @@ LogicalResult CleanSelfdriversPass::cleanInstanceSide() { LogicalResult CleanSelfdriversPass::cleanContainerSide() { auto *ctx = &getContext(); ConversionTarget target(*ctx); - target.addLegalDialect(); + target.addLegalDialect(); target.addLegalOp(); target.addDynamicallyLegalOp( [](InputPortOp op) { return !isSelfDriven(op); }); @@ -231,6 +232,6 @@ void CleanSelfdriversPass::runOnOperation() { return signalPassFailure(); } -std::unique_ptr circt::ibis::createCleanSelfdriversPass() { +std::unique_ptr circt::kanagawa::createCleanSelfdriversPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisContainerize.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaContainerize.cpp similarity index 85% rename from lib/Dialect/Ibis/Transforms/IbisContainerize.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaContainerize.cpp index 589f38709cf6..4cd88db95619 100644 --- a/lib/Dialect/Ibis/Transforms/IbisContainerize.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaContainerize.cpp @@ -1,4 +1,4 @@ -//===- IbisContainerize.cpp - Implementation of containerizing ------------===// +//===- KanagawaContainerize.cpp - Implementation of containerizing --------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,28 +6,28 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Support/Namespace.h" #include "circt/Support/SymCache.h" #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCONTAINERIZE -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACONTAINERIZE +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { @@ -58,7 +58,7 @@ struct OutlineContainerPattern : public OpConversionPattern { rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {}); - // Rename the ibis.this operation to refer to the proper op. + // Rename the kanagawa.this operation to refer to the proper op. auto thisOp = cast(cast(*newContainer.getOperation()) .getThis() @@ -111,7 +111,7 @@ struct InstanceToContainerInstancePattern /// Run all the physical lowerings. struct ContainerizePass - : public circt::ibis::impl::IbisContainerizeBase { + : public circt::kanagawa::impl::KanagawaContainerizeBase { void runOnOperation() override; private: @@ -126,9 +126,9 @@ struct ContainerizePass LogicalResult ContainerizePass::outlineContainers() { auto *context = &getContext(); ConversionTarget target(*context); - target.addLegalDialect(); + target.addLegalDialect(); target.addDynamicallyLegalOp( - [&](auto *op) { return !isa(op->getParentOp()); }); + [&](auto *op) { return !isa(op->getParentOp()); }); RewritePatternSet patterns(context); // Setup a namespace to ensure that the new container names are unique. @@ -150,7 +150,7 @@ LogicalResult ContainerizePass::outlineContainers() { LogicalResult ContainerizePass::containerizeClasses() { auto *context = &getContext(); ConversionTarget target(*context); - target.addLegalDialect(); + target.addLegalDialect(); target.addIllegalOp(); RewritePatternSet patterns(context); patterns.insert( @@ -163,6 +163,6 @@ void ContainerizePass::runOnOperation() { signalPassFailure(); } -std::unique_ptr circt::ibis::createContainerizePass() { +std::unique_ptr circt::kanagawa::createContainerizePass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisContainersToHW.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaContainersToHW.cpp similarity index 88% rename from lib/Dialect/Ibis/Transforms/IbisContainersToHW.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaContainersToHW.cpp index 0e6c8ac6f7bd..bfbf1089bf7e 100644 --- a/lib/Dialect/Ibis/Transforms/IbisContainersToHW.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaContainersToHW.cpp @@ -1,4 +1,4 @@ -//===- IbisContainersToHW.cpp ---------------------------------------------===// +//===- KanagawaContainersToHW.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" #include "circt/Dialect/HW/HWOps.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Support/Namespace.h" #include "mlir/IR/OperationSupport.h" @@ -22,14 +22,14 @@ #include "llvm/ADT/TypeSwitch.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCONTAINERSTOHW -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACONTAINERSTOHW +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { @@ -152,7 +152,7 @@ struct ContainerOpConversionPattern : public OpConversionPattern { auto reader = dyn_cast(user); if (!reader) return rewriter.notifyMatchFailure( - user, "expected only ibis.port.read ops of the input port"); + user, "expected only kanagawa.port.read ops of the input port"); rewriter.replaceOp(reader, barg); } @@ -160,7 +160,7 @@ struct ContainerOpConversionPattern : public OpConversionPattern { rewriter.eraseOp(inputPort); } - // Adjust the hw.output op to use ibis.port.write values + // Adjust the hw.output op to use kanagawa.port.write values llvm::SmallVector outputValues; for (auto [idx, output] : llvm::enumerate(cpi.hwPorts->getOutputs())) { auto outputPort = cpi.opOutputs.at(output.name); @@ -169,7 +169,7 @@ struct ContainerOpConversionPattern : public OpConversionPattern { size_t nUsers = std::distance(users.begin(), users.end()); if (nUsers != 1) return outputPort->emitOpError() - << "expected exactly one ibis.port.write op of the output " + << "expected exactly one kanagawa.port.write op of the output " "port: " << output.name.str() << " found: " << nUsers; auto writer = cast(*users.begin()); @@ -232,7 +232,7 @@ struct ContainerInstanceOpConversionPattern auto getPort = dyn_cast(user); if (!getPort) return rewriter.notifyMatchFailure( - user, "expected only ibis.get_port op usage of the instance"); + user, "expected only kanagawa.get_port op usage of the instance"); for (auto *user : getPort->getUsers()) { auto res = @@ -244,7 +244,7 @@ struct ContainerInstanceOpConversionPattern read}); if (!inserted) return rewriter.notifyMatchFailure( - read, "expected only one ibis.port.read op of the " + read, "expected only one kanagawa.port.read op of the " "output port"); return success(); }) @@ -256,13 +256,14 @@ struct ContainerInstanceOpConversionPattern if (!inserted) return rewriter.notifyMatchFailure( write, - "expected only one ibis.port.write op of the input " + "expected only one kanagawa.port.write op of the input " "port"); return success(); }) .Default([&](auto op) { return rewriter.notifyMatchFailure( - op, "expected only ibis.port.read or ibis.port.write ops " + op, "expected only kanagawa.port.read or " + "kanagawa.port.write ops " "of the " "instance"); }); @@ -281,7 +282,8 @@ struct ContainerInstanceOpConversionPattern ers << "Error when lowering instance "; op.print(ers, mlir::OpPrintingFlags().printGenericOpForm()); - ers << "\nexpected exactly one ibis.port.write op of each input port. " + ers << "\nexpected exactly one kanagawa.port.write op of each input " + "port. " "Mising port assignments were:\n"; for (auto input : cpi.hwPorts->getInputs()) { if (inputWritesToUse.find(input.name) == inputWritesToUse.end()) @@ -345,7 +347,8 @@ struct ContainerInstanceOpConversionPattern }; // namespace struct ContainersToHWPass - : public circt::ibis::impl::IbisContainersToHWBase { + : public circt::kanagawa::impl::KanagawaContainersToHWBase< + ContainersToHWPass> { void runOnOperation() override; }; } // anonymous namespace @@ -369,18 +372,19 @@ void ContainersToHWPass::runOnOperation() { target.addIllegalOp(); target.markUnknownOpDynamicallyLegal([](Operation *) { return true; }); - // Remove the name of the ibis.design's from the namespace - The ibis.design - // op will be removed after this pass, and there may be ibis.component's - // inside the design that have the same name as the design; we want that - // name to persist, and not be falsely considered a duplicate. + // Remove the name of the kanagawa.design's from the namespace - The + // kanagawa.design op will be removed after this pass, and there may be + // kanagawa.component's inside the design that have the same name as the + // design; we want that name to persist, and not be falsely considered a + // duplicate. for (auto designOp : getOperation().getOps()) modNamespace.erase(designOp.getSymName()); // Parts of the conversion patterns will update operations in place, which in // turn requires the updated operations to be legalizeable. These in-place ops - // also include ibis ops that eventually will get replaced once all of the + // also include kanagawa ops that eventually will get replaced once all of the // patterns apply. - target.addLegalDialect(); + target.addLegalDialect(); RewritePatternSet patterns(ctx); patterns.add(ctx, modNamespace, portOrder, @@ -399,6 +403,6 @@ void ContainersToHWPass::runOnOperation() { design.erase(); } -std::unique_ptr circt::ibis::createContainersToHWPass() { +std::unique_ptr circt::kanagawa::createContainersToHWPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisConvertCFToHandshake.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaConvertCFToHandshake.cpp similarity index 75% rename from lib/Dialect/Ibis/Transforms/IbisConvertCFToHandshake.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaConvertCFToHandshake.cpp index 048becf76894..8ce9742a3332 100644 --- a/lib/Dialect/Ibis/Transforms/IbisConvertCFToHandshake.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaConvertCFToHandshake.cpp @@ -1,4 +1,4 @@ -//===- IbisConvertCFToHandshakePass.cpp -----------------------------------===// +//===- KanagawaConvertCFToHandshakePass.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Transforms/Passes.h" #include "mlir/Transforms/DialectConversion.h" @@ -21,20 +21,20 @@ #include "circt/Conversion/CFToHandshake.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCONVERTCFTOHANDSHAKE -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACONVERTCFTOHANDSHAKE +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { struct ConvertCFToHandshakePass - : public circt::ibis::impl::IbisConvertCFToHandshakeBase< + : public circt::kanagawa::impl::KanagawaConvertCFToHandshakeBase< ConvertCFToHandshakePass> { void runOnOperation() override; @@ -63,7 +63,7 @@ LogicalResult ConvertCFToHandshakePass::convertMethod(MethodOp method) { method.erase(); handshake::HandshakeLowering fol(dataflowMethodOp.getBody()); - if (failed(handshake::lowerRegion( + if (failed(handshake::lowerRegion( fol, /*sourceConstants*/ false, /*disableTaskPipelining*/ false, entryCtrl))) @@ -80,6 +80,6 @@ void ConvertCFToHandshakePass::runOnOperation() { } } -std::unique_ptr circt::ibis::createConvertCFToHandshakePass() { +std::unique_ptr circt::kanagawa::createConvertCFToHandshakePass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisConvertHandshakeToDC.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaConvertHandshakeToDC.cpp similarity index 72% rename from lib/Dialect/Ibis/Transforms/IbisConvertHandshakeToDC.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaConvertHandshakeToDC.cpp index dee332e3d53e..656840a3f2f9 100644 --- a/lib/Dialect/Ibis/Transforms/IbisConvertHandshakeToDC.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaConvertHandshakeToDC.cpp @@ -1,4 +1,4 @@ -//===- IbisConvertHandshakeToDCPass.cpp -----------------------------------===// +//===- KanagawaConvertHandshakeToDCPass.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" #include "circt/Dialect/DC/DCTypes.h" #include "circt/Dialect/HW/ConversionPatterns.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Transforms/Passes.h" #include "mlir/Transforms/DialectConversion.h" @@ -23,20 +23,20 @@ #include "circt/Conversion/HandshakeToDC.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCONVERTHANDSHAKETODC -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACONVERTHANDSHAKETODC +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { struct ConvertHandshakeToDCPass - : public circt::ibis::impl::IbisConvertHandshakeToDCBase< + : public circt::kanagawa::impl::KanagawaConvertHandshakeToDCBase< ConvertHandshakeToDCPass> { void runOnOperation() override; }; @@ -48,7 +48,7 @@ class ReturnOpConversion : public OpConversionPattern { LogicalResult matchAndRewrite(ReturnOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - rewriter.replaceOpWithNewOp(op, adaptor.getOperands()); + rewriter.replaceOpWithNewOp(op, adaptor.getOperands()); return success(); } }; @@ -86,22 +86,22 @@ static bool isDCTypedOp(Operation *op) { } void ConvertHandshakeToDCPass::runOnOperation() { - ibis::ClassOp classOp = getOperation(); + kanagawa::ClassOp classOp = getOperation(); auto targetModifier = [&](mlir::ConversionTarget &target) { - target.addDynamicallyLegalOp( - [](ibis::DataflowMethodOp op) { + target.addDynamicallyLegalOp( + [](kanagawa::DataflowMethodOp op) { auto methodLikeOp = cast(op.getOperation()); return llvm::all_of(methodLikeOp.getArgumentTypes(), isDCType) && llvm::all_of(methodLikeOp.getResultTypes(), isDCType); }); - target.addDynamicallyLegalOp(isDCTypedOp); - target.addLegalDialect(); - target.addIllegalOp(); + target.addDynamicallyLegalOp(isDCTypedOp); + target.addLegalDialect(); + target.addIllegalOp(); - // ibis.sblock.dc ops are recursively legal - we're only considering the + // kanagawa.sblock.dc ops are recursively legal - we're only considering the // DataflowMethodOp's region for conversion. - target.addLegalOp(); - target.markOpRecursivelyLegal(); + target.addLegalOp(); + target.markOpRecursivelyLegal(); }; auto patternBuilder = [&](TypeConverter &typeConverter, @@ -120,6 +120,6 @@ void ConvertHandshakeToDCPass::runOnOperation() { signalPassFailure(); } -std::unique_ptr circt::ibis::createConvertHandshakeToDCPass() { +std::unique_ptr circt::kanagawa::createConvertHandshakeToDCPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisInlineSBlocksPass.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaInlineSBlocksPass.cpp similarity index 58% rename from lib/Dialect/Ibis/Transforms/IbisInlineSBlocksPass.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaInlineSBlocksPass.cpp index 1adbcdc00776..dcec9fcb0752 100644 --- a/lib/Dialect/Ibis/Transforms/IbisInlineSBlocksPass.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaInlineSBlocksPass.cpp @@ -1,4 +1,4 @@ -//===- IbisInlineSBlocksPass.cpp ------------------------------------------===// +//===- KanagawaInlineSBlocksPass.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,14 +6,14 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" @@ -24,31 +24,33 @@ #include namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISINLINESBLOCKS -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAINLINESBLOCKS +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { struct InlineSBlocksPass - : public circt::ibis::impl::IbisInlineSBlocksBase { + : public circt::kanagawa::impl::KanagawaInlineSBlocksBase< + InlineSBlocksPass> { void runOnOperation() override; }; -class InlineSBlocksPattern : public OpConversionPattern { +class InlineSBlocksPattern + : public OpConversionPattern { public: - using OpConversionPattern::OpConversionPattern; + using OpConversionPattern::OpConversionPattern; using OpAdaptor = - typename OpConversionPattern::OpAdaptor; + typename OpConversionPattern::OpAdaptor; LogicalResult - matchAndRewrite(ibis::StaticBlockOp op, OpAdaptor adaptor, + matchAndRewrite(kanagawa::StaticBlockOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { Location loc = op.getLoc(); @@ -57,7 +59,8 @@ class InlineSBlocksPattern : public OpConversionPattern { if (hasAttributes) { // Start the inline block... - auto inlineStart = rewriter.create(loc); + auto inlineStart = + rewriter.create(loc); inlineStart->setAttrs(op->getAttrs()); } @@ -66,15 +69,15 @@ class InlineSBlocksPattern : public OpConversionPattern { BlockReturnOp ret = cast(sblockBody->getTerminator()); rewriter.inlineBlockBefore(sblockBody, op->getNextNode()); - // Replace the ibis.sblock return values with the values that were defined - // (returned from) within the sblock body, and erase the return op. + // Replace the kanagawa.sblock return values with the values that were + // defined (returned from) within the sblock body, and erase the return op. for (auto [res, val] : llvm::zip(op.getResults(), ret.getRetValues())) rewriter.replaceAllUsesWith(res, val); if (hasAttributes) { // Close the inline block rewriter.setInsertionPoint(ret); - rewriter.create(loc); + rewriter.create(loc); } rewriter.eraseOp(ret); @@ -88,9 +91,9 @@ class InlineSBlocksPattern : public OpConversionPattern { void InlineSBlocksPass::runOnOperation() { MethodOp parent = getOperation(); ConversionTarget target(getContext()); - target.addIllegalOp(); - // Mark everything but `ibis.sblock` as legal - we need a legalization pattern - // for any possible op that gets inlined from a block. + target.addIllegalOp(); + // Mark everything but `kanagawa.sblock` as legal - we need a legalization + // pattern for any possible op that gets inlined from a block. target.markUnknownOpDynamicallyLegal([](Operation *op) { return true; }); RewritePatternSet patterns(&getContext()); patterns.add(&getContext()); @@ -99,6 +102,6 @@ void InlineSBlocksPass::runOnOperation() { return signalPassFailure(); } -std::unique_ptr circt::ibis::createInlineSBlocksPass() { +std::unique_ptr circt::kanagawa::createInlineSBlocksPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisMethodsToContainers.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaMethodsToContainers.cpp similarity index 79% rename from lib/Dialect/Ibis/Transforms/IbisMethodsToContainers.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaMethodsToContainers.cpp index 13b0b08ad7cf..265570fa57e9 100644 --- a/lib/Dialect/Ibis/Transforms/IbisMethodsToContainers.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaMethodsToContainers.cpp @@ -1,4 +1,4 @@ -//===- IbisMethodsToContainers.cpp - Implementation of containerizing -----===// +//===- KanagawaMethodsToContainers.cpp - Implementation of containerizing -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,28 +6,28 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Support/Namespace.h" #include "circt/Support/SymCache.h" #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISCONVERTMETHODSTOCONTAINERS -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWACONVERTMETHODSTOCONTAINERS +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { @@ -76,7 +76,7 @@ struct DataflowMethodOpConversion }; struct MethodsToContainersPass - : public circt::ibis::impl::IbisConvertMethodsToContainersBase< + : public circt::kanagawa::impl::KanagawaConvertMethodsToContainersBase< MethodsToContainersPass> { void runOnOperation() override; }; @@ -85,7 +85,7 @@ struct MethodsToContainersPass void MethodsToContainersPass::runOnOperation() { auto *context = &getContext(); ConversionTarget target(*context); - target.addLegalDialect(); + target.addLegalDialect(); target.addIllegalOp(); target.addIllegalOp(); RewritePatternSet patterns(context); @@ -96,6 +96,6 @@ void MethodsToContainersPass::runOnOperation() { signalPassFailure(); } -std::unique_ptr circt::ibis::createConvertMethodsToContainersPass() { +std::unique_ptr circt::kanagawa::createConvertMethodsToContainersPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisPassPipelines.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaPassPipelines.cpp similarity index 69% rename from lib/Dialect/Ibis/Transforms/IbisPassPipelines.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaPassPipelines.cpp index c5e99b823156..c3560270bcd7 100644 --- a/lib/Dialect/Ibis/Transforms/IbisPassPipelines.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaPassPipelines.cpp @@ -1,4 +1,4 @@ -//===- IbisPassPipelines.cpp - Ibis pass pipelines ------------------------===// +//===- KanagawaPassPipelines.cpp - Kanagawa pass pipelines ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,16 +6,16 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisPassPipelines.h" +#include "circt/Dialect/Kanagawa/KanagawaPassPipelines.h" #include "circt/Dialect/HW/HWPasses.h" -#include "circt/Dialect/Ibis/IbisOps.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" #include "circt/Transforms/Passes.h" #include "mlir/Transforms/GreedyPatternRewriteDriver.h" #include "mlir/Transforms/Passes.h" using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; /// Create a simple canonicalizer pass. static std::unique_ptr createSimpleCanonicalizerPass() { @@ -25,12 +25,12 @@ static std::unique_ptr createSimpleCanonicalizerPass() { return mlir::createCanonicalizerPass(config); } -void circt::ibis::loadIbisLowLevelPassPipeline(mlir::PassManager &pm) { +void circt::kanagawa::loadKanagawaLowLevelPassPipeline(mlir::PassManager &pm) { // Inner ref: We create an inner ref verification pass to initially validate // the IR, as well as after all structure-changing passes. // In the future, could consider hiding this behind a flag to reduce overhead. pm.addPass(hw::createVerifyInnerRefNamespacePass()); - pm.nest().addPass(createContainerizePass()); + pm.nest().addPass(createContainerizePass()); pm.addPass(hw::createVerifyInnerRefNamespacePass()); // Pre-tunneling CSE pass. This ensures that duplicate get_port calls are @@ -38,7 +38,7 @@ void circt::ibis::loadIbisLowLevelPassPipeline(mlir::PassManager &pm) { // twice. pm.addPass(mlir::createCSEPass()); pm.nest().addPass( - createTunnelingPass(IbisTunnelingOptions{"", ""})); + createTunnelingPass(KanagawaTunnelingOptions{"", ""})); pm.addPass(hw::createVerifyInnerRefNamespacePass()); pm.addPass(createPortrefLoweringPass()); pm.addPass(createSimpleCanonicalizerPass()); @@ -47,11 +47,11 @@ void circt::ibis::loadIbisLowLevelPassPipeline(mlir::PassManager &pm) { pm.addPass(hw::createVerifyInnerRefNamespacePass()); } -void circt::ibis::loadIbisHighLevelPassPipeline(mlir::PassManager &pm) { - pm.nest() - .nest() - .nest() - .addPass(ibis::createInlineSBlocksPass()); +void circt::kanagawa::loadKanagawaHighLevelPassPipeline(mlir::PassManager &pm) { + pm.nest() + .nest() + .nest() + .addPass(kanagawa::createInlineSBlocksPass()); pm.addPass(mlir::createMem2Reg()); // TODO @mortbopet: Add a verification pass to ensure that there are no more @@ -62,11 +62,11 @@ void circt::ibis::loadIbisHighLevelPassPipeline(mlir::PassManager &pm) { // Now, perform SSA maximizations. pm.addPass(circt::createMaximizeSSAPass()); - // SSA maximal form achieved. Reconstruct the Ibis sblocks. - pm.nest() - .nest() - .nest() - .addPass(ibis::createReblockPass()); - pm.addPass(ibis::createArgifyBlocksPass()); + // SSA maximal form achieved. Reconstruct the Kanagawa sblocks. + pm.nest() + .nest() + .nest() + .addPass(kanagawa::createReblockPass()); + pm.addPass(kanagawa::createArgifyBlocksPass()); pm.addPass(createSimpleCanonicalizerPass()); } diff --git a/lib/Dialect/Ibis/Transforms/IbisPortrefLowering.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaPortrefLowering.cpp similarity index 84% rename from lib/Dialect/Ibis/Transforms/IbisPortrefLowering.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaPortrefLowering.cpp index 979cebddb138..2c416cd12557 100644 --- a/lib/Dialect/Ibis/Transforms/IbisPortrefLowering.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaPortrefLowering.cpp @@ -1,4 +1,4 @@ -//===- IbisPortrefLowering.cpp - Implementation of PortrefLowering --------===// +//===- KanagawaPortrefLowering.cpp - Implementation of PortrefLowering ----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,32 +6,32 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "mlir/IR/Builders.h" #include "mlir/Transforms/DialectConversion.h" #include "llvm/ADT/TypeSwitch.h" #include "llvm/Support/Debug.h" -#define DEBUG_TYPE "ibis-lower-portrefs" +#define DEBUG_TYPE "kanagawa-lower-portrefs" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISPORTREFLOWERING -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAPORTREFLOWERING +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { @@ -57,17 +57,19 @@ class InputPortConversionPattern : public OpConversionPattern { std::distance(portrefUsers.begin(), portrefUsers.end()); if (nPortrefUsers != 1) return rewriter.notifyMatchFailure( - op, "expected a single ibis.port.read as the only user of the input " - "port reference, but found multiple readers - please run CSE " - "prior to this pass"); + op, + "expected a single kanagawa.port.read as the only user of the input " + "port reference, but found multiple readers - please run CSE " + "prior to this pass"); // A single PortReadOp should be present, which unwraps the portref // into a portref. PortReadOp portUnwrapper = dyn_cast(*portrefUsers.begin()); if (!portUnwrapper) return rewriter.notifyMatchFailure( - op, "expected a single ibis.port.read as the only user of the input " - "port reference"); + op, + "expected a single kanagawa.port.read as the only user of the input " + "port reference"); // Replace the inner portref + port access with a "raw" port. OpBuilder::InsertionGuard g(rewriter); @@ -99,7 +101,7 @@ class InputPortConversionPattern : public OpConversionPattern { // See https://github.com/llvm/circt/issues/6795. portUnwrapper.getResult().replaceAllUsesWith(rawInput); - // Replace all ibis.port.read ops with a read of the new input. + // Replace all kanagawa.port.read ops with a read of the new input. for (auto *portUser : llvm::make_early_inc_range(portUnwrapper.getResult().getUsers())) { PortReadOp portReader = dyn_cast(portUser); @@ -138,7 +140,7 @@ class OutputPortConversionPattern : public OpConversionPattern { if (writeOp && writeOp.getPort() == op.getResult()) { if (portWrapper) return rewriter.notifyMatchFailure( - op, "expected a single ibis.port.write to wrap the output " + op, "expected a single kanagawa.port.write to wrap the output " "portref, but found multiple"); portWrapper = writeOp; break; @@ -147,7 +149,7 @@ class OutputPortConversionPattern : public OpConversionPattern { if (!portWrapper) return rewriter.notifyMatchFailure( - op, "expected an ibis.port.write to wrap the output portref"); + op, "expected an kanagawa.port.write to wrap the output portref"); OpBuilder::InsertionGuard g(rewriter); rewriter.setInsertionPoint(op); @@ -213,7 +215,7 @@ class GetPortConversionPattern : public OpConversionPattern { if (!getPortWrapper) return rewriter.notifyMatchFailure( - op, "expected an ibis.port.write to wrap the get_port result"); + op, "expected an kanagawa.port.write to wrap the get_port result"); wrapper = getPortWrapper; LLVM_DEBUG(llvm::dbgs() << "Found wrapper: " << *wrapper); if (innerDirection == Direction::Input) { @@ -247,25 +249,27 @@ class GetPortConversionPattern : public OpConversionPattern { if (!getPortUnwrapper) return rewriter.notifyMatchFailure( - op, "expected an ibis.port.read to unwrap the get_port result"); + op, "expected an kanagawa.port.read to unwrap the get_port result"); wrapper = getPortUnwrapper; LLVM_DEBUG(llvm::dbgs() << "Found unwrapper: " << *wrapper); if (innerDirection == Direction::Input) { // In this situation, we're retrieving an input port that is sent as an - // output of the container: %rr = ibis.get_port %c %c_in : - // !ibis.scoperef<...> -> !ibis.portref> + // output of the container: %rr = kanagawa.get_port %c %c_in : + // !kanagawa.scoperef<...> -> !kanagawa.portref> // // Thus we expect one of these cases: // (always). a read op which unwraps the portref> into // a portref - // %r = ibis.port.read %rr : !ibis.portref> + // %r = kanagawa.port.read %rr : !kanagawa.portref> // either: // 1. A write to %r which drives the target input port - // ibis.port.write %r, %someValue : !ibis.portref + // kanagawa.port.write %r, %someValue : !kanagawa.portref // 2. A write using %r which forwards the input port reference - // ibis.port.write %r_fw, %r : !ibis.portref> + // kanagawa.port.write %r_fw, %r : !kanagawa.portref> // PortWriteOp portDriver; PortWriteOp portForwardingDriver; @@ -278,16 +282,18 @@ class GetPortConversionPattern : public OpConversionPattern { if (isForwarding) { if (portForwardingDriver) return rewriter.notifyMatchFailure( - op, "expected a single ibis.port.write to use the unwrapped " - "get_port result, but found multiple"); + op, + "expected a single kanagawa.port.write to use the unwrapped " + "get_port result, but found multiple"); portForwardingDriver = writeOp; LLVM_DEBUG(llvm::dbgs() << "Found forwarding driver: " << *portForwardingDriver); } else { if (portDriver) return rewriter.notifyMatchFailure( - op, "expected a single ibis.port.write to use the unwrapped " - "get_port result, but found multiple"); + op, + "expected a single kanagawa.port.write to use the unwrapped " + "get_port result, but found multiple"); portDriver = writeOp; LLVM_DEBUG(llvm::dbgs() << "Found driver: " << *portDriver); } @@ -295,8 +301,9 @@ class GetPortConversionPattern : public OpConversionPattern { if (!portDriver && !portForwardingDriver) return rewriter.notifyMatchFailure( - op, "expected an ibis.port.write to drive the unwrapped get_port " - "result"); + op, + "expected an kanagawa.port.write to drive the unwrapped get_port " + "result"); Value portDriverValue; if (portForwardingDriver) { @@ -333,13 +340,15 @@ class GetPortConversionPattern : public OpConversionPattern { rewriter.create(op.getLoc(), rawPort, portDriverValue); } else { // In this situation, we're retrieving an output port that is sent as an - // output of the container: %rr = ibis.get_port %c %c_in : - // !ibis.scoperef<...> -> !ibis.portref> + // output of the container: %rr = kanagawa.get_port %c %c_in : + // !kanagawa.scoperef<...> -> !kanagawa.portref> // // Thus we expect two ops to be present: // 1. a read op which unwraps the portref> into a // portref - // %r = ibis.port.read %rr : !ibis.portref> + // %r = kanagawa.port.read %rr : !kanagawa.portref> // 2. one (or multiple, if not CSEd) // // We then replace the read op with the actual output port of the @@ -366,7 +375,8 @@ class GetPortConversionPattern : public OpConversionPattern { }; struct PortrefLoweringPass - : public circt::ibis::impl::IbisPortrefLoweringBase { + : public circt::kanagawa::impl::KanagawaPortrefLoweringBase< + PortrefLoweringPass> { void runOnOperation() override; }; @@ -376,7 +386,7 @@ void PortrefLoweringPass::runOnOperation() { auto *ctx = &getContext(); ConversionTarget target(*ctx); target.addIllegalOp(); - target.addLegalDialect(); + target.addLegalDialect(); // Ports are legal when they do not have portref types anymore. target.addDynamicallyLegalOp([&](auto op) { @@ -402,6 +412,6 @@ void PortrefLoweringPass::runOnOperation() { signalPassFailure(); } -std::unique_ptr circt::ibis::createPortrefLoweringPass() { +std::unique_ptr circt::kanagawa::createPortrefLoweringPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisPrepareScheduling.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaPrepareScheduling.cpp similarity index 85% rename from lib/Dialect/Ibis/Transforms/IbisPrepareScheduling.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaPrepareScheduling.cpp index 26a7876559ce..dd7eecaf46ba 100644 --- a/lib/Dialect/Ibis/Transforms/IbisPrepareScheduling.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaPrepareScheduling.cpp @@ -1,4 +1,4 @@ -//===- IbisPrepareScheduling.cpp - Prepares ibis static blocks for scheduling // +//===- KanagawaPrepareScheduling.cpp - Prepares static blocks for scheduling =// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,15 +6,15 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" #include "circt/Dialect/Comb/CombOps.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Dialect/Pipeline/PipelineOps.h" #include "circt/Dialect/SSP/SSPOps.h" @@ -23,19 +23,19 @@ #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISPREPARESCHEDULING -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAPREPARESCHEDULING +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { struct PrepareSchedulingPass - : public circt::ibis::impl::IbisPrepareSchedulingBase< + : public circt::kanagawa::impl::KanagawaPrepareSchedulingBase< PrepareSchedulingPass> { void runOnOperation() override; @@ -55,7 +55,7 @@ PrepareSchedulingPass::prepareSBlock(IsolatedStaticBlockOp sblock) { Location loc = sblock.getLoc(); Block *bodyBlock = sblock.getBodyBlock(); auto b = OpBuilder::atBlockBegin(bodyBlock); - auto ph = b.create(loc); + auto ph = b.create(loc); // Create a pipeline.unscheduled operation which returns the same types // as that returned by the sblock. @@ -127,7 +127,7 @@ LogicalResult PrepareSchedulingPass::attachOperatorTypes( // Attach the operator lib attribute pipeline->setAttr( "operator_lib", - FlatSymbolRefAttr::get(pipeline.getContext(), kIbisOperatorLibName)); + FlatSymbolRefAttr::get(pipeline.getContext(), kKanagawaOperatorLibName)); return success(); } @@ -138,6 +138,6 @@ void PrepareSchedulingPass::runOnOperation() { return signalPassFailure(); } -std::unique_ptr circt::ibis::createPrepareSchedulingPass() { +std::unique_ptr circt::kanagawa::createPrepareSchedulingPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisReblockPass.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaReblockPass.cpp similarity index 76% rename from lib/Dialect/Ibis/Transforms/IbisReblockPass.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaReblockPass.cpp index 1a81433295e8..9f9ac030d9f3 100644 --- a/lib/Dialect/Ibis/Transforms/IbisReblockPass.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaReblockPass.cpp @@ -1,4 +1,4 @@ -//===- IbisReblockPass.cpp ------------------------------------------------===// +//===- KanagawaReblockPass.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,34 +6,36 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "mlir/Pass/Pass.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Transforms/Passes.h" #include "mlir/Transforms/DialectConversion.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISREBLOCK -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWAREBLOCK +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace circt; -using namespace ibis; +using namespace kanagawa; namespace { -struct ReblockPass : public circt::ibis::impl::IbisReblockBase { +struct ReblockPass + : public circt::kanagawa::impl::KanagawaReblockBase { void runOnOperation() override; - // Transforms an `ibis.sblock.inline.begin/end` scope into an `ibis.sblock`. + // Transforms an `kanagawa.sblock.inline.begin/end` scope into an + // `kanagawa.sblock`. LogicalResult reblock(ArrayRef ops, Operation *blockTerminator); /// Track ops that should be erased. @@ -44,7 +46,7 @@ struct ReblockPass : public circt::ibis::impl::IbisReblockBase { // operations should be closed. static bool isSBlockTerminator(Operation *op) { return op->hasTrait() || - isa(op); + isa(op); } } // anonymous namespace @@ -76,7 +78,7 @@ LogicalResult ReblockPass::reblock(ArrayRef ops, // Determine which values we need to return from within the block scope. // This is done by collecting all values defined within the start/end scope, // and recording uses that exist outside of the scope. - ibis::InlineStaticBlockBeginOp blockBeginOp; + kanagawa::InlineStaticBlockBeginOp blockBeginOp; if (isa(blockTerminator)) { blockBeginOp = dyn_cast(ops.front()); assert(blockBeginOp && @@ -118,17 +120,17 @@ LogicalResult ReblockPass::reblock(ArrayRef ops, } auto b = OpBuilder(beginOp); - auto ibisBlock = + auto kanagawaBlock = b.create(beginOp->getLoc(), blockRetTypes, ValueRange{}); - // The new `ibis.sblock` should inherit the attributes of the block begin op, - // if provided. + // The new `kanagawa.sblock` should inherit the attributes of the block begin + // op, if provided. if (blockBeginOp) - ibisBlock->setAttrs(blockBeginOp->getAttrs()); + kanagawaBlock->setAttrs(blockBeginOp->getAttrs()); - // Move operations into the `ibis.sblock` op. + // Move operations into the `kanagawa.sblock` op. BlockReturnOp blockReturn = - cast(ibisBlock.getBodyBlock()->getTerminator()); + cast(kanagawaBlock.getBodyBlock()->getTerminator()); for (auto &op : llvm::make_early_inc_range(llvm::make_range(startIt, terminatorIt))) @@ -140,7 +142,7 @@ LogicalResult ReblockPass::reblock(ArrayRef ops, // Replace the uses of the returned values outside of the block with the // block return values. for (auto [blockRet, innerDefAndUses] : - llvm::zip(ibisBlock.getResults(), returnValueUses)) { + llvm::zip(kanagawaBlock.getResults(), returnValueUses)) { auto &uses = std::get<1>(innerDefAndUses); for (OpOperand *use : uses) use->set(blockRet); @@ -155,6 +157,6 @@ LogicalResult ReblockPass::reblock(ArrayRef ops, return success(); } -std::unique_ptr circt::ibis::createReblockPass() { +std::unique_ptr circt::kanagawa::createReblockPass() { return std::make_unique(); } diff --git a/lib/Dialect/Ibis/Transforms/IbisTunneling.cpp b/lib/Dialect/Kanagawa/Transforms/KanagawaTunneling.cpp similarity index 91% rename from lib/Dialect/Ibis/Transforms/IbisTunneling.cpp rename to lib/Dialect/Kanagawa/Transforms/KanagawaTunneling.cpp index badf8df2e9eb..690acf8529db 100644 --- a/lib/Dialect/Ibis/Transforms/IbisTunneling.cpp +++ b/lib/Dialect/Kanagawa/Transforms/KanagawaTunneling.cpp @@ -1,4 +1,4 @@ -//===- IbisTunneling.cpp - Implementation of tunneling --------------------===// +//===- KanagawaTunneling.cpp - Implementation of tunneling ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPasses.h" -#include "circt/Dialect/Ibis/IbisTypes.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaTypes.h" #include "circt/Support/InstanceGraph.h" #include "mlir/IR/Builders.h" @@ -18,15 +18,15 @@ #include "llvm/ADT/TypeSwitch.h" namespace circt { -namespace ibis { -#define GEN_PASS_DEF_IBISTUNNELING -#include "circt/Dialect/Ibis/IbisPasses.h.inc" -} // namespace ibis +namespace kanagawa { +#define GEN_PASS_DEF_KANAGAWATUNNELING +#include "circt/Dialect/Kanagawa/KanagawaPasses.h.inc" +} // namespace kanagawa } // namespace circt using namespace mlir; using namespace circt; -using namespace circt::ibis; +using namespace circt::kanagawa; using namespace circt::igraph; namespace { @@ -49,7 +49,7 @@ struct PortInfo { struct Tunneler { public: - Tunneler(const IbisTunnelingOptions &options, PathOp op, + Tunneler(const KanagawaTunnelingOptions &options, PathOp op, ConversionPatternRewriter &rewriter, InstanceGraph &ig); // A mapping between requested port names from a ScopeRef and the actual @@ -67,7 +67,7 @@ struct Tunneler { llvm::ArrayRef path, PortRefMapping &mapping); - // "Port forwarding" check - ibis.get_port specifies the intended + // "Port forwarding" check - kanagawa.get_port specifies the intended // direction which a port is accessed by from within the hierarchy. // If the intended direction is not the same as the actual port // direction, we need to insert a wire to flip the direction of the @@ -95,7 +95,7 @@ struct Tunneler { PathOp op; ConversionPatternRewriter &rewriter; InstanceGraph &ig; - const IbisTunnelingOptions &options; + const KanagawaTunnelingOptions &options; mlir::StringAttr pathName; llvm::SmallVector path; @@ -108,12 +108,12 @@ struct Tunneler { FlatSymbolRefAttr targetName; }; -Tunneler::Tunneler(const IbisTunnelingOptions &options, PathOp op, +Tunneler::Tunneler(const KanagawaTunnelingOptions &options, PathOp op, ConversionPatternRewriter &rewriter, InstanceGraph &ig) : op(op), rewriter(rewriter), ig(ig), options(options) { llvm::copy(op.getPathAsRange(), std::back_inserter(path)); assert(!path.empty() && - "empty paths should never occur - illegal for ibis.path ops"); + "empty paths should never occur - illegal for kanagawa.path ops"); target = path.back(); targetName = target.getChild(); } @@ -148,7 +148,7 @@ LogicalResult Tunneler::go() { auto getPortOp = dyn_cast(user); if (!getPortOp) return user->emitOpError() << "unknown user of a PathOp result - " - "tunneling only supports ibis.get_port"; + "tunneling only supports kanagawa.get_port"; portInfos.push_back( PortInfo{getPortOp.getPortSymbolAttr().getAttr(), getPortOp}); } @@ -210,7 +210,7 @@ Value Tunneler::portForwardIfNeeded(PortOpInterface actualPort, rewriter.setInsertionPointAfter(actualPort); // If the requested direction was an input, this means that someone tried - // to write to an output port. We need to insert an ibis.wire.input that + // to write to an output port. We need to insert an kanagawa.wire.input that // provides a writeable input port, and assign the wire output to the // output port. if (requestedDir == Direction::Input) { @@ -224,7 +224,7 @@ Value Tunneler::portForwardIfNeeded(PortOpInterface actualPort, } // If the requested direction was an output, this means that someone tried - // to read from an input port. We need to insert an ibis.wire.output that + // to read from an input port. We need to insert an kanagawa.wire.output that // provides a readable output port, and read the input port as the value // of the wire. Value inputValue = @@ -238,7 +238,8 @@ Value Tunneler::portForwardIfNeeded(PortOpInterface actualPort, } // Lookup an instance in the parent op. If the parent op is a symbol table, will -// use that - else, scan the ibis.container.instance operations in the parent. +// use that - else, scan the kanagawa.container.instance operations in the +// parent. static FailureOr locateInstanceIn(Operation *parentOp, FlatSymbolRefAttr name) { if (parentOp->hasTrait()) { @@ -393,7 +394,7 @@ LogicalResult Tunneler::tunnelUp(InstanceGraphNode *currentContainer, class TunnelingConversionPattern : public OpConversionPattern { public: TunnelingConversionPattern(MLIRContext *context, InstanceGraph &ig, - IbisTunnelingOptions options) + KanagawaTunnelingOptions options) : OpConversionPattern(context), ig(ig), options(std::move(options)) {} @@ -405,12 +406,12 @@ class TunnelingConversionPattern : public OpConversionPattern { protected: InstanceGraph &ig; - IbisTunnelingOptions options; + KanagawaTunnelingOptions options; }; struct TunnelingPass - : public circt::ibis::impl::IbisTunnelingBase { - using IbisTunnelingBase::IbisTunnelingBase; + : public circt::kanagawa::impl::KanagawaTunnelingBase { + using KanagawaTunnelingBase::KanagawaTunnelingBase; void runOnOperation() override; }; @@ -426,7 +427,7 @@ void TunnelingPass::runOnOperation() { RewritePatternSet patterns(ctx); patterns.add( - ctx, ig, IbisTunnelingOptions{readSuffix, writeSuffix}); + ctx, ig, KanagawaTunnelingOptions{readSuffix, writeSuffix}); if (failed( applyPartialConversion(getOperation(), target, std::move(patterns)))) @@ -434,6 +435,6 @@ void TunnelingPass::runOnOperation() { } std::unique_ptr -circt::ibis::createTunnelingPass(const IbisTunnelingOptions &options) { +circt::kanagawa::createTunnelingPass(const KanagawaTunnelingOptions &options) { return std::make_unique(options); } diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 3bc76409af63..a4eeda68788e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -33,7 +33,7 @@ set(CIRCT_TEST_DEPENDS handshake-runner firtool hlstool - ibistool + kanagawatool om-linker ) diff --git a/test/Dialect/Ibis/Transforms/argify_blocks.mlir b/test/Dialect/Ibis/Transforms/argify_blocks.mlir deleted file mode 100644 index e8440285bdc2..000000000000 --- a/test/Dialect/Ibis/Transforms/argify_blocks.mlir +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: circt-opt --ibis-argify-blocks %s | FileCheck %s - -// CHECK-LABEL: ibis.class sym @Argify { -// CHECK-NEXT: %this = ibis.this <@foo::@Argify> -// CHECK-NEXT: ibis.method @foo() -> () { -// CHECK-NEXT: %c32_i32 = hw.constant 32 : i32 -// CHECK-NEXT: %0:2 = ibis.sblock.isolated (%arg0 : i32 = %c32_i32) -> (i32, i32) { -// CHECK-NEXT: %c31_i32 = hw.constant 31 : i32 -// CHECK-NEXT: %1 = arith.addi %arg0, %c31_i32 : i32 -// CHECK-NEXT: ibis.sblock.return %1, %arg0 : i32, i32 -// CHECK-NEXT: } -// CHECK-NEXT: ibis.return -// CHECK-NEXT: } -// CHECK-NEXT: } - -ibis.design @foo { -ibis.class sym @Argify { - %this = ibis.this <@foo::@Argify> - - ibis.method @foo() { - %c32 = hw.constant 32 : i32 - %0:2 = ibis.sblock() -> (i32, i32) { - %c31 = hw.constant 31 : i32 - %res = arith.addi %c31, %c32 : i32 - ibis.sblock.return %res, %c32 : i32, i32 - } - ibis.return - } -} -} diff --git a/test/Dialect/Ibis/Transforms/clean_selfdrivers.mlir b/test/Dialect/Ibis/Transforms/clean_selfdrivers.mlir deleted file mode 100644 index caa2419d8d32..000000000000 --- a/test/Dialect/Ibis/Transforms/clean_selfdrivers.mlir +++ /dev/null @@ -1,85 +0,0 @@ -// RUN: circt-opt --allow-unregistered-dialect --split-input-file --ibis-clean-selfdrivers %s | FileCheck %s - -ibis.design @D { -// CHECK-LABEL: ibis.container sym @C { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C> -// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1 -// CHECK: %[[VAL_3:.*]] = ibis.port.output "out" sym @out : i1 -// CHECK: %[[VAL_2]] = hw.constant true -// CHECK: ibis.port.write %[[VAL_3]], %[[VAL_1]] : !ibis.portref -// CHECK: } -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 - %true = hw.constant 1 : i1 - ibis.port.write %in, %true : !ibis.portref - %v = ibis.port.read %in : !ibis.portref - ibis.port.write %out, %v : !ibis.portref -} - -} - -// ----- - -ibis.design @D { -// CHECK-LABEL: ibis.container sym @Selfdriver { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Selfdriver> -// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1 -// CHECK: %[[VAL_3:.*]] = ibis.port.output "myIn" sym @in : i1 -// CHECK: ibis.port.write %[[VAL_3]], %[[VAL_1]] : !ibis.portref -// CHECK: %[[VAL_2]] = hw.constant true -// CHECK: } - -// CHECK-LABEL: ibis.container sym @ParentReader { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentReader> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @selfdriver, <@D::@Selfdriver> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@Selfdriver> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref -// CHECK: } - -ibis.container sym @Selfdriver { - %this = ibis.this <@D::@Selfdriver> - %in = ibis.port.input "myIn" sym @in : i1 - %true = hw.constant 1 : i1 - ibis.port.write %in, %true : !ibis.portref -} - -ibis.container sym @ParentReader { - %this = ibis.this <@D::@ParentReader> - %selfdriver = ibis.container.instance @selfdriver, <@D::@Selfdriver> - %in_ref = ibis.get_port %selfdriver, @in : !ibis.scoperef<@D::@Selfdriver> -> !ibis.portref - %in = ibis.port.read %in_ref : !ibis.portref -} - -} - -// ----- - -ibis.design @D { - -ibis.container sym @Foo { - %this = ibis.this <@D::@Foo> - %in = ibis.port.input "in" sym @in : i1 -} - -// CHECK-LABEL: ibis.container sym @ParentReaderWriter { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentReaderWriter> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @f, <@D::@Foo> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@Foo> -> !ibis.portref -// CHECK: "foo.bar"(%[[VAL_3:.*]]) : (i1) -> () -// CHECK: %[[VAL_3]] = hw.constant true -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3]] : !ibis.portref -// CHECK: } -ibis.container sym @ParentReaderWriter { - %this = ibis.this <@D::@ParentReaderWriter> - %f = ibis.container.instance @f, <@D::@Foo> - %in_wr_ref = ibis.get_port %f, @in : !ibis.scoperef<@D::@Foo> -> !ibis.portref - %in_rd_ref = ibis.get_port %f, @in : !ibis.scoperef<@D::@Foo> -> !ibis.portref - %v = ibis.port.read %in_rd_ref : !ibis.portref - "foo.bar"(%v) : (i1) -> () - %true = hw.constant 1 : i1 - ibis.port.write %in_wr_ref, %true : !ibis.portref -} - -} diff --git a/test/Dialect/Ibis/Transforms/containerize.mlir b/test/Dialect/Ibis/Transforms/containerize.mlir deleted file mode 100644 index 7f13674e4ff1..000000000000 --- a/test/Dialect/Ibis/Transforms/containerize.mlir +++ /dev/null @@ -1,38 +0,0 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis-containerize))' %s | FileCheck %s - -ibis.design @foo { - -// CHECK-LABEL: ibis.container sym @A_B -// CHECK-LABEL: ibis.container "MyClassName" sym @MyClass -// CHECK-LABEL: ibis.container sym @A_B_0 -// CHECK-LABEL: ibis.container sym @A_C -// CHECK-LABEL: ibis.container sym @A { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@A> -// CHECK: ibis.port.input "A_in" sym @A_in : i1 -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @myClass, <@foo::@MyClass> -// CHECK: %[[VAL_2:.*]] = ibis.container.instance @A_B_0, <@foo::@A_B_0> -// CHECK: %[[VAL_3:.*]] = ibis.container.instance @A_C, <@foo::@A_C> - -// This container will alias with the @B inside @A, and thus checks the -// name uniquing logic. -ibis.container sym @A_B { - %this = ibis.this <@foo::@A_B> -} - -ibis.class "MyClassName" sym @MyClass { - %this = ibis.this <@foo::@MyClass> -} - -ibis.class sym @A { - %this = ibis.this <@foo::@A> - ibis.port.input "A_in" sym @A_in : i1 - %myClass = ibis.instance @myClass, <@foo::@MyClass> - ibis.container sym @B { - %B_this = ibis.this <@foo::@B> - } - ibis.container sym @C { - %C_this = ibis.this <@foo::@C> - } -} - -} diff --git a/test/Dialect/Ibis/Transforms/containers_to_hw.mlir b/test/Dialect/Ibis/Transforms/containers_to_hw.mlir deleted file mode 100644 index b77656b6023f..000000000000 --- a/test/Dialect/Ibis/Transforms/containers_to_hw.mlir +++ /dev/null @@ -1,178 +0,0 @@ -// RUN: circt-opt --split-input-file --ibis-convert-containers-to-hw %s | FileCheck %s - -ibis.design @D { - -// CHECK: hw.module @D_MyB(in %in_foo : i1 {inputAttr}, out out_foo : i1 {outputAttr}) { -// CHECK: hw.output %in_foo : i1 -// CHECK: } -// CHECK: hw.module @D_AccessSibling(in %p_b_out_foo : i1, out p_b_in_foo : i1) { -// CHECK: hw.output %p_b_out_foo : i1 -// CHECK: } -// CHECK: hw.module @Parent() { -// CHECK: %a.p_b_in_foo = hw.instance "a" @D_AccessSibling(p_b_out_foo: %b.out_foo: i1) -> (p_b_in_foo: i1) -// CHECK: %b.out_foo = hw.instance "b" @D_MyB(in_foo: %a.p_b_in_foo: i1) -> (out_foo: i1) -// CHECK: hw.output -// CHECK: } - -ibis.container "MyB" sym @B { - %this = ibis.this <@D::@B> - // Test different port names vs. symbol names - %in = ibis.port.input "in_foo" sym @in : i1 {"inputAttr"} - %out = ibis.port.output "out_foo" sym @out : i1 {"outputAttr"} - - // Loopback. - %v = ibis.port.read %in : !ibis.portref - ibis.port.write %out, %v : !ibis.portref -} - -ibis.container sym @AccessSibling { - %this = ibis.this <@D::@AccessSibling> - %p_b_out = ibis.port.input "p_b_out_foo" sym @p_b_out : i1 - %p_b_in = ibis.port.output "p_b_in_foo" sym @p_b_in : i1 - ibis.port.write %p_b_in, %p_b_out.val : !ibis.portref - %p_b_out.val = ibis.port.read %p_b_out : !ibis.portref -} -ibis.container sym @Parent top_level { - %this = ibis.this <@D::@Parent> - %a = ibis.container.instance @a, <@D::@AccessSibling> - %a.p_b_out.ref = ibis.get_port %a, @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref - %b.out.ref.val = ibis.port.read %b.out.ref : !ibis.portref - ibis.port.write %a.p_b_out.ref, %b.out.ref.val : !ibis.portref - %a.p_b_in.ref = ibis.get_port %a, @p_b_in : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref - %a.p_b_in.ref.val = ibis.port.read %a.p_b_in.ref : !ibis.portref - ibis.port.write %b.in.ref, %a.p_b_in.ref.val : !ibis.portref - %b = ibis.container.instance @b, <@D::@B> - %b.out.ref = ibis.get_port %b, @out : !ibis.scoperef<@D::@B> -> !ibis.portref - %b.in.ref = ibis.get_port %b, @in : !ibis.scoperef<@D::@B> -> !ibis.portref -} - -} - -// ----- - -// Test that we can instantiate and get ports of a container from a hw.module. - -ibis.design @D { - -// CHECK: hw.module @D_C(in %in_foo : i1, out out_foo : i1) { -// CHECK: hw.output %in_foo : i1 -// CHECK: } -// CHECK: hw.module @Top() { -// CHECK: %c.out_foo = hw.instance "c" @D_C(in_foo: %c.out_foo: i1) -> (out_foo: i1) -// CHECK: hw.output -// CHECK: } - -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in_foo" sym @in : i1 - %out = ibis.port.output "out_foo" sym @out : i1 - %v = ibis.port.read %in : !ibis.portref - ibis.port.write %out, %v : !ibis.portref -} - -} - -hw.module @Top() { - %c = ibis.container.instance @c, <@D::@C> - %in = ibis.get_port %c, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %out = ibis.get_port %c, @out : !ibis.scoperef<@D::@C> -> !ibis.portref - %v = ibis.port.read %out : !ibis.portref - ibis.port.write %in, %v : !ibis.portref -} - -// ----- - -// Test that we can also move non-ibis ops - -ibis.design @D { - -// CHECK-LABEL: hw.module @D_Inst(out out : i1) { -// CHECK: %[[VAL_0:.*]] = hw.constant true -// CHECK: hw.output %[[VAL_0]] : i1 -// CHECK: } - -// CHECK-LABEL: hw.module @D_Top() { -// CHECK: %[[VAL_0:.*]] = hw.instance "myInst" @D_Inst() -> (out: i1) -// CHECK: %[[VAL_1:.*]] = hw.constant true -// CHECK: %[[VAL_2:.*]] = comb.and bin %[[VAL_1]], %[[VAL_0]] : i1 -// CHECK: hw.output -// CHECK: } - -ibis.container sym @Inst { - %this = ibis.this <@D::@Inst> - %out = ibis.port.output "out" sym @out : i1 - %true = hw.constant 1 : i1 - ibis.port.write %out, %true : !ibis.portref -} -ibis.container sym @Top { - %this = ibis.this <@D::@Top> - %myInst = ibis.container.instance @myInst, <@D::@Inst> - %true = hw.constant 1 : i1 - %out.ref = ibis.get_port %myInst, @out : !ibis.scoperef<@D::@Inst> -> !ibis.portref - %out.v = ibis.port.read %out.ref : !ibis.portref - %blake = comb.and bin %true, %out.v : i1 -} - -} - -// ----- - -// Test that we can unique duplicate port names. - -ibis.design @D { - -// CHECK: hw.module @D_Top(in %clk : i1, in %clk_0 : i1, out out : i1, out out_0 : i1) { -// CHECK: hw.output %clk, %clk_0 : i1, i1 -ibis.container sym @Top { - %this = ibis.this <@D::@Top> - %clk1 = ibis.port.input "clk" sym @clk1 : i1 - %clk2 = ibis.port.input "clk" sym @clk2 : i1 - %out1 = ibis.port.output "out" sym @out1 : i1 - %out2 = ibis.port.output "out" sym @out2 : i1 - - %v1 = ibis.port.read %clk1 : !ibis.portref - %v2 = ibis.port.read %clk2 : !ibis.portref - ibis.port.write %out1, %v1 : !ibis.portref - ibis.port.write %out2, %v2 : !ibis.portref -} -} - -// ----- - -// Test that we can de-alias module names. - -// CHECK: hw.module @D_Foo_0() { -// CHECK: hw.output -// CHECK: } -// CHECK: hw.module @Foo_0() { -// CHECK: hw.output -// CHECK: } -// CHECK: hw.module.extern @D_Foo(in %theExternModule : i1) -// CHECK: hw.module.extern @Foo(in %theExternModule : i1) - -ibis.design @D { - -ibis.container "Foo" sym @A { - %this = ibis.this <@D::@A> -} - -ibis.container "Foo" sym @B top_level { - %this = ibis.this <@D::@B> -} -} - -hw.module.extern @D_Foo(in %theExternModule : i1) -hw.module.extern @Foo(in %theExternModule : i1) - -// ----- - -// Test that containers with names that alias with the design op are not -// de-aliased. - -// CHECK: hw.module @D - -ibis.design @D { - ibis.container "D" sym @D top_level { - %this = ibis.this <@D::@D> - } -} diff --git a/test/Dialect/Ibis/Transforms/handshake_to_dc.mlir b/test/Dialect/Ibis/Transforms/handshake_to_dc.mlir deleted file mode 100644 index ae3914a36b0c..000000000000 --- a/test/Dialect/Ibis/Transforms/handshake_to_dc.mlir +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis-convert-handshake-to-dc)))' %s | FileCheck %s - -// Actual handshake-to-dc conversion is tested in the respective pass tests. -// This file just tests the ibis-specific hooks. - -// CHECK-LABEL: ibis.class sym @ToDC { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToDC> -// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: !dc.value) -> !dc.value { -// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = dc.unpack %[[VAL_1]] : !dc.value -// CHECK: %[[VAL_4:.*]]:2 = dc.fork [2] %[[VAL_2]] -// CHECK: %[[VAL_5:.*]] = dc.pack %[[VAL_4]]#0, %[[VAL_3]] : i32 -// CHECK: %[[VAL_6:.*]] = dc.pack %[[VAL_4]]#1, %[[VAL_3]] : i32 -// CHECK: %[[VAL_7:.*]] = ibis.sblock.dc (%[[VAL_8:.*]] : !dc.value = %[[VAL_5]], %[[VAL_9:.*]] : !dc.value = %[[VAL_6]]) -> !dc.value { -// CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_8]], %[[VAL_9]] : i32 -// CHECK: ibis.sblock.return %[[VAL_10]] : i32 -// CHECK: } -// CHECK: ibis.return %[[VAL_7]] : !dc.value -// CHECK: } -// CHECK: } - -ibis.design @foo { -ibis.class sym @ToDC { - %this = ibis.this <@foo::@ToDC> - ibis.method.df @foo(%arg0: i32) -> (i32) { - %o0, %o1 = handshake.fork [2] %arg0 : i32 - %1 = ibis.sblock.isolated(%a0 : i32 = %o0, %a1 : i32 = %o1) -> i32 { - %res = arith.addi %a0, %a1 : i32 - ibis.sblock.return %res : i32 - } - ibis.return %1 : i32 - } -} -} diff --git a/test/Dialect/Ibis/Transforms/inline_sblocks.mlir b/test/Dialect/Ibis/Transforms/inline_sblocks.mlir deleted file mode 100644 index 574894e5fe17..000000000000 --- a/test/Dialect/Ibis/Transforms/inline_sblocks.mlir +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis.method(ibis-inline-sblocks))))' \ -// RUN: --allow-unregistered-dialect %s | FileCheck %s - -ibis.design @foo { - -// CHECK-LABEL: ibis.class sym @Inline1 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Inline1> -// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () { -// CHECK: ibis.sblock.inline.begin {maxThreads = 1 : i64} -// CHECK: %[[VAL_3:.*]] = "foo.op1"(%[[VAL_1]], %[[VAL_2]]) : (i32, i32) -> i32 -// CHECK: ibis.sblock.inline.end -// CHECK: ibis.return -// CHECK: } -// CHECK: } -ibis.class sym @Inline1 { - %this = ibis.this <@foo::@Inline1> - - ibis.method @foo(%a : i32, %b : i32) { - %0 = ibis.sblock() -> (i32) attributes {maxThreads = 1} { - %res = "foo.op1"(%a, %b) : (i32, i32) -> i32 - ibis.sblock.return %res : i32 - } - ibis.return - } -} - -// CHECK-LABEL: ibis.class sym @Inline2 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Inline2> -// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () { -// CHECK: "foo.unused1"() : () -> () -// CHECK: ibis.sblock.inline.begin {maxThreads = 1 : i64} -// CHECK: %[[VAL_3:.*]] = "foo.op1"(%[[VAL_1]], %[[VAL_2]]) : (i32, i32) -> i32 -// CHECK: ibis.sblock.inline.end -// CHECK: "foo.unused2"() : () -> () -// CHECK: cf.br ^bb1 -// CHECK: ^bb1: -// CHECK: "foo.unused3"() : () -> () -// CHECK: %[[VAL_4:.*]] = "foo.op2"(%[[VAL_3]], %[[VAL_1]]) : (i32, i32) -> i32 -// CHECK: "foo.unused4"() : () -> () -// CHECK: ibis.return -// CHECK: } -// CHECK: } -ibis.class sym @Inline2 { - %this = ibis.this <@foo::@Inline2> - ibis.method @foo(%a : i32, %b : i32) { - "foo.unused1"() : () -> () - %0 = ibis.sblock() -> (i32) attributes {maxThreads = 1} { - %res = "foo.op1"(%a, %b) : (i32, i32) -> i32 - ibis.sblock.return %res : i32 - } - "foo.unused2"() : () -> () - cf.br ^bb1 - ^bb1: - "foo.unused3"() : () -> () - %1 = ibis.sblock() -> (i32) { - %res = "foo.op2"(%0, %a) : (i32, i32) -> i32 - ibis.sblock.return %res : i32 - } - "foo.unused4"() : () -> () - ibis.return - } -} - -} diff --git a/test/Dialect/Ibis/Transforms/methods_to_containers.mlir b/test/Dialect/Ibis/Transforms/methods_to_containers.mlir deleted file mode 100644 index f2dde7df4767..000000000000 --- a/test/Dialect/Ibis/Transforms/methods_to_containers.mlir +++ /dev/null @@ -1,37 +0,0 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis-convert-methods-to-containers)))' %s | FileCheck %s - -// CHECK-LABEL: ibis.class sym @ToContainers { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToContainers> -// CHECK: ibis.container sym @foo { -// CHECK: %[[VAL_1:.*]] = ibis.this <@foo::@foo> -// CHECK: %[[VAL_2:.*]] = ibis.port.input "arg0" sym @arg0 : !dc.value -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref> -// CHECK: %[[VAL_4:.*]] = ibis.port.output "out0" sym @out0 : !dc.value -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_5:.*]] : !ibis.portref> -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = dc.unpack %[[VAL_3]] : !dc.value -// CHECK: %[[VAL_8:.*]]:2 = dc.fork [2] %[[VAL_6]] -// CHECK: %[[VAL_9:.*]] = dc.pack %[[VAL_8]]#0, %[[VAL_7]] : i32 -// CHECK: %[[VAL_10:.*]] = dc.pack %[[VAL_8]]#1, %[[VAL_7]] : i32 -// CHECK: %[[VAL_5]] = ibis.sblock.dc (%[[VAL_11:.*]] : !dc.value = %[[VAL_9]], %[[VAL_12:.*]] : !dc.value = %[[VAL_10]]) -> !dc.value { -// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 -// CHECK: ibis.sblock.return %[[VAL_13]] : i32 -// CHECK: } -// CHECK: } -// CHECK: } - -ibis.design @foo { -ibis.class sym @ToContainers { - %this = ibis.this <@foo::@ToContainers> - ibis.method.df @foo(%arg0: !dc.value) -> !dc.value { - %token, %output = dc.unpack %arg0 : !dc.value - %0:2 = dc.fork [2] %token - %1 = dc.pack %0#0, %output : i32 - %2 = dc.pack %0#1, %output : i32 - %3 = ibis.sblock.dc (%arg1 : !dc.value = %1, %arg2 : !dc.value = %2) -> !dc.value { - %4 = arith.addi %arg1, %arg2 : i32 - ibis.sblock.return %4 : i32 - } - ibis.return %3 : !dc.value - } -} -} diff --git a/test/Dialect/Ibis/Transforms/path_end_to_end.mlir b/test/Dialect/Ibis/Transforms/path_end_to_end.mlir deleted file mode 100644 index ad039c159c16..000000000000 --- a/test/Dialect/Ibis/Transforms/path_end_to_end.mlir +++ /dev/null @@ -1,73 +0,0 @@ -// The ultimate tunneling test - by having 3 intermediate levels for both up- -// and downwards tunneling, we are sure test all the possible combinations of -// tunneling. This is more of a sanity check that everything works as expected. - -// RUN: circt-opt --split-input-file --ibis-tunneling \ -// RUN: --ibis-lower-portrefs --ibis-clean-selfdrivers \ -// RUN: --ibis-convert-containers-to-hw - -ibis.design @foo { -ibis.container sym @D_up { - %this = ibis.this <@foo::@D_up> - %d = ibis.path [ - #ibis.step, - #ibis.step, - #ibis.step, - #ibis.step, - #ibis.step : !ibis.scoperef, - #ibis.step : !ibis.scoperef, - #ibis.step : !ibis.scoperef, - #ibis.step> : !ibis.scoperef<@D_down>] - // Write an input port - %clk_ref = ibis.get_port %d, @clk_in : !ibis.scoperef<@D_down> -> !ibis.portref - %clk = hw.constant 1 : i1 - ibis.port.write %clk_ref, %clk : !ibis.portref - - // Read an input port - %clk_ref_2 = ibis.get_port %d, @clk_in : !ibis.scoperef<@D_down> -> !ibis.portref - %clk_in_val = ibis.port.read %clk_ref_2 : !ibis.portref - - // Read an output port - %clk_out_ref = ibis.get_port %d, @clk_out : !ibis.scoperef<@D_down> -> !ibis.portref - %clk_out_val = ibis.port.read %clk_out_ref : !ibis.portref -} -ibis.container sym @C_up { - %this = ibis.this <@foo::@C_up> - %d = ibis.container.instance @d, @D_up -} -ibis.container sym @B_up { - %this = ibis.this <@foo::@B_up> - %c = ibis.container.instance @c, @C_up - -} - -ibis.container sym @A_up { - %this = ibis.this <@foo::@A_up> - %b = ibis.container.instance @b, @B_up -} - -ibis.container sym @Top { - %this = ibis.this <@foo::@Top> - %a_down = ibis.container.instance @a_down, @A_down - %a_up = ibis.container.instance @a_up, @A_up -} -ibis.container sym @A_down { - %this = ibis.this <@foo::@A_down> - %b = ibis.container.instance @b, @B_down -} -ibis.container sym @B_down { - %this = ibis.this <@foo::@B_down> - %c = ibis.container.instance @c, @C_down -} -ibis.container sym @C_down { - %this = ibis.this <@foo::@C_down> - %d = ibis.container.instance @d, @D_down -} -ibis.container sym @D_down { - %this = ibis.this <@foo::@D_down> - %clk = ibis.port.input "clk_in" sym @clk_in : i1 - %clk_out = ibis.port.output "clk_out" sym @clk_out : i1 - %clk.val = ibis.port.read %clk : !ibis.portref - ibis.port.write %clk_out, %clk.val : !ibis.portref -} -} diff --git a/test/Dialect/Ibis/Transforms/portref_lowering.mlir b/test/Dialect/Ibis/Transforms/portref_lowering.mlir deleted file mode 100644 index a7474d779cbd..000000000000 --- a/test/Dialect/Ibis/Transforms/portref_lowering.mlir +++ /dev/null @@ -1,260 +0,0 @@ -// RUN: circt-opt --split-input-file --ibis-lower-portrefs %s | FileCheck %s - -ibis.design @D { - -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// CHECK-LABEL: ibis.container sym @AccessSibling { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessSibling> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_b_out" sym @p_b_out : i1 -// CHECK: %[[VAL_2:.*]] = ibis.port.output "p_b_in" sym @p_b_in : i1 -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3:.*]] : !ibis.portref -// CHECK: %[[VAL_3]] = ibis.port.read %[[VAL_1]] : !ibis.portref -// CHECK: } -ibis.container sym @AccessSibling { - %this = ibis.this <@D::@AccessSibling> - %p_b_out = ibis.port.input "p_b_out" sym @p_b_out : !ibis.portref - %p_b_out_val = ibis.port.read %p_b_out : !ibis.portref> - %p_b_in = ibis.port.input "p_b_in" sym @p_b_in : !ibis.portref - %p_b_in_val = ibis.port.read %p_b_in : !ibis.portref> - - // Loopback to ensure that value replacement is performed. - %v = ibis.port.read %p_b_out_val : !ibis.portref - ibis.port.write %p_b_in_val, %v : !ibis.portref -} - -// CHECK-LABEL: ibis.container sym @Parent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @a, <@D::@AccessSibling> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_4:.*]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3]] : !ibis.portref -// CHECK: %[[VAL_5:.*]] = ibis.get_port %[[VAL_1]], @p_b_in : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref -// CHECK: %[[VAL_6:.*]] = ibis.port.read %[[VAL_5]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_7:.*]], %[[VAL_6]] : !ibis.portref -// CHECK: %[[VAL_8:.*]] = ibis.container.instance @b, <@D::@C> -// CHECK: %[[VAL_4]] = ibis.get_port %[[VAL_8]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_7]] = ibis.get_port %[[VAL_8]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: } -ibis.container sym @Parent { - %this = ibis.this <@D::@Parent> - %a = ibis.container.instance @a, <@D::@AccessSibling> - %a.p_b_out = ibis.get_port %a, @p_b_out : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref> - ibis.port.write %a.p_b_out, %b.out : !ibis.portref> - %a.p_b_in = ibis.get_port %a, @p_b_in : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref> - ibis.port.write %a.p_b_in, %b.in : !ibis.portref> - %b = ibis.container.instance @b, <@D::@C> - %b.out = ibis.get_port %b, @out : !ibis.scoperef<@D::@C> -> !ibis.portref - %b.in = ibis.get_port %b, @in : !ibis.scoperef<@D::@C> -> !ibis.portref -} - -} - -// ----- - -ibis.design @D { - - -// CHECK-LABEL: ibis.container sym @ParentPortAccess { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@ParentPortAccess> -// CHECK: %[[VAL_1:.*]] = ibis.port.output "p_in" sym @p_in : i1 -// CHECK: %[[VAL_2:.*]] = ibis.port.input "p_out" sym @p_out : i1 -// CHECK: } -ibis.container sym @ParentPortAccess { - %this = ibis.this <@D::@ParentPortAccess> - %p_in = ibis.port.input "p_in" sym @p_in : !ibis.portref - %p_in_val = ibis.port.read %p_in : !ibis.portref> - %p_out = ibis.port.input "p_out" sym @p_out : !ibis.portref - %p_out_val = ibis.port.read %p_out : !ibis.portref> -} - -// CHECK-LABEL: ibis.container sym @Parent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@D::@ParentPortAccess> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_in : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_4:.*]], %[[VAL_3]] : !ibis.portref -// CHECK: %[[VAL_5:.*]] = ibis.get_port %[[VAL_1]], @p_out : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref -// CHECK: %[[VAL_6:.*]] = ibis.port.read %[[VAL_7:.*]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_5]], %[[VAL_6]] : !ibis.portref -// CHECK: %[[VAL_4]] = ibis.port.input "in" sym @in : i1 -// CHECK: %[[VAL_7]] = ibis.port.output "out" sym @out : i1 -// CHECK: } -ibis.container sym @Parent { - %this = ibis.this <@D::@Parent> - %c = ibis.container.instance @c, <@D::@ParentPortAccess> - %c.p_in = ibis.get_port %c, @p_in : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref> - ibis.port.write %c.p_in, %in : !ibis.portref> - %c.p_out = ibis.get_port %c, @p_out : !ibis.scoperef<@D::@ParentPortAccess> -> !ibis.portref> - ibis.port.write %c.p_out, %out : !ibis.portref> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -} - -// ----- - -ibis.design @D { - - -// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child - -// CHECK-LABEL: ibis.container sym @C1 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C1> -// CHECK: %[[VAL_1:.*]] = ibis.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 -// CHECK: ibis.port.write %[[VAL_1]], %[[VAL_2:.*]] : !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 -// CHECK: %[[VAL_2]] = ibis.port.read %[[VAL_3]] : !ibis.portref -// CHECK: } -ibis.container sym @C1 { - %this = ibis.this <@D::@C1> - %parent_parent_c2_c3_in = ibis.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !ibis.portref - %parent_parent_c2_c3_out = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !ibis.portref - - // Assignment drivers - unwrap the ports and roundtrip read-write. - %parent_b_in_unwrapped = ibis.port.read %parent_parent_c2_c3_in : !ibis.portref> - %parent_b_out_unwrapped = ibis.port.read %parent_parent_c2_c3_out : !ibis.portref> - %parent_b_out_value = ibis.port.read %parent_b_out_unwrapped : !ibis.portref - ibis.port.write %parent_b_in_unwrapped, %parent_b_out_value : !ibis.portref -} - -// CHECK-LABEL: ibis.container sym @C2 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C2> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c3, <@D::@C> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.get_port %[[VAL_1]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 -// CHECK: %[[VAL_5:.*]] = ibis.port.read %[[VAL_4]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_5]] : !ibis.portref -// CHECK: %[[VAL_6:.*]] = ibis.port.output "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 -// CHECK: %[[VAL_7:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_6]], %[[VAL_7]] : !ibis.portref -// CHECK: } -ibis.container sym @C2 { - %this = ibis.this <@D::@C2> - %c3 = ibis.container.instance @c3, <@D::@C> - %c3.in = ibis.get_port %c3, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %c3.out = ibis.get_port %c3, @out : !ibis.scoperef<@D::@C> -> !ibis.portref - %parent_parent_c2_c3_in = ibis.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !ibis.portref - %parent_parent_c2_c3_out = ibis.port.output "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !ibis.portref - ibis.port.write %parent_parent_c2_c3_in, %c3.in : !ibis.portref> - ibis.port.write %parent_parent_c2_c3_out, %c3.out : !ibis.portref> -} -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// CHECK-LABEL: ibis.container sym @P1 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P1> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c1, <@D::@C1> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C1> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_out : !ibis.scoperef<@D::@C1> -> !ibis.portref -// CHECK: %[[VAL_5:.*]] = ibis.port.read %[[VAL_6:.*]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_5]] : !ibis.portref -// CHECK: %[[VAL_7:.*]] = ibis.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 -// CHECK: ibis.port.write %[[VAL_7]], %[[VAL_3]] : !ibis.portref -// CHECK: %[[VAL_6]] = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 -// CHECK: } -ibis.container sym @P1 { - %this = ibis.this <@D::@P1> - %c1 = ibis.container.instance @c1, <@D::@C1> - %c1.parent_parent_c2_c3_in = ibis.get_port %c1, @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C1> -> !ibis.portref> - ibis.port.write %c1.parent_parent_c2_c3_in, %0 : !ibis.portref> - %c1.parent_parent_c2_c3_out = ibis.get_port %c1, @parent_parent_c2_c3_out : !ibis.scoperef<@D::@C1> -> !ibis.portref> - ibis.port.write %c1.parent_parent_c2_c3_out, %1 : !ibis.portref> - %parent_parent_c2_c3_in = ibis.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !ibis.portref - %0 = ibis.port.read %parent_parent_c2_c3_in : !ibis.portref> - %parent_parent_c2_c3_out = ibis.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !ibis.portref - %1 = ibis.port.read %parent_parent_c2_c3_out : !ibis.portref> -} - -// CHECK-LABEL: ibis.container sym @P2 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P2> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @p1, <@D::@P1> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@P1> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.port.read %[[VAL_2]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_4:.*]], %[[VAL_3]] : !ibis.portref -// CHECK: %[[VAL_5:.*]] = ibis.get_port %[[VAL_1]], @parent_parent_c2_c3_out : !ibis.scoperef<@D::@P1> -> !ibis.portref -// CHECK: %[[VAL_6:.*]] = ibis.port.read %[[VAL_7:.*]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_5]], %[[VAL_6]] : !ibis.portref -// CHECK: %[[VAL_8:.*]] = ibis.container.instance @c2, <@D::@C2> -// CHECK: %[[VAL_7]] = ibis.get_port %[[VAL_8]], @parent_parent_c2_c3_out : !ibis.scoperef<@D::@C2> -> !ibis.portref -// CHECK: %[[VAL_4]] = ibis.port.input "parent_parent_c2_c3_in_fw" sym @parent_parent_c2_c3_in_fw : i1 -// CHECK: %[[VAL_9:.*]] = ibis.port.read %[[VAL_4]] : !ibis.portref -// CHECK: %[[VAL_10:.*]] = ibis.get_port %[[VAL_8]], @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C2> -> !ibis.portref -// CHECK: ibis.port.write %[[VAL_10]], %[[VAL_9]] : !ibis.portref -// CHECK: } -ibis.container sym @P2 { - %this = ibis.this <@D::@P2> - %p1 = ibis.container.instance @p1, <@D::@P1> - %p1.parent_parent_c2_c3_in = ibis.get_port %p1, @parent_parent_c2_c3_in : !ibis.scoperef<@D::@P1> -> !ibis.portref> - ibis.port.write %p1.parent_parent_c2_c3_in, %1 : !ibis.portref> - %p1.parent_parent_c2_c3_out = ibis.get_port %p1, @parent_parent_c2_c3_out : !ibis.scoperef<@D::@P1> -> !ibis.portref> - ibis.port.write %p1.parent_parent_c2_c3_out, %0 : !ibis.portref> - %c2 = ibis.container.instance @c2, <@D::@C2> - %c2.parent_parent_c2_c3_out = ibis.get_port %c2, @parent_parent_c2_c3_out : !ibis.scoperef<@D::@C2> -> !ibis.portref> - %0 = ibis.port.read %c2.parent_parent_c2_c3_out : !ibis.portref> - %c2.parent_parent_c2_c3_in = ibis.get_port %c2, @parent_parent_c2_c3_in : !ibis.scoperef<@D::@C2> -> !ibis.portref> - %1 = ibis.port.read %c2.parent_parent_c2_c3_in : !ibis.portref> -} - -} - -// ----- - -ibis.design @D { - - -// CHECK-LABEL: ibis.container sym @AccessParent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessParent> -// CHECK: %[[VAL_1:.*]] = ibis.port.output "p_out" sym @p_out : i1 -// CHECK: %[[VAL_2:.*]] = ibis.port.input "p_in" sym @p_in : i1 -// CHECK: } -ibis.container sym @AccessParent { - %this = ibis.this <@D::@AccessParent> - %p_out = ibis.port.input "p_out" sym @p_out : !ibis.portref - %p_out.val = ibis.port.read %p_out : !ibis.portref> - %p_in = ibis.port.input "p_in" sym @p_in : !ibis.portref - %p_in.val = ibis.port.read %p_in : !ibis.portref> -} - -// CHECK-LABEL: ibis.container sym @Parent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1 -// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.wire.output @in.rd, %[[VAL_2]] : i1 -// CHECK: %[[VAL_4:.*]] = ibis.port.output "out" sym @out : i1 -// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = ibis.wire.input @out.wr : i1 -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_6]] : !ibis.portref -// CHECK: %[[VAL_7:.*]] = ibis.container.instance @c, <@D::@AccessParent> -// CHECK: %[[VAL_8:.*]] = ibis.get_port %[[VAL_7]], @p_out : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref -// CHECK: %[[VAL_9:.*]] = ibis.port.read %[[VAL_8]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_5]], %[[VAL_9]] : !ibis.portref -// CHECK: %[[VAL_10:.*]] = ibis.get_port %[[VAL_7]], @p_in : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref -// CHECK: %[[VAL_11:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref -// CHECK: ibis.port.write %[[VAL_10]], %[[VAL_11]] : !ibis.portref -// CHECK: } -ibis.container sym @Parent { - %this = ibis.this <@D::@Parent> - %in = ibis.port.input "in" sym @in : i1 - %in.val = ibis.port.read %in : !ibis.portref - %in.rd = ibis.wire.output @in.rd, %in.val : i1 - %out = ibis.port.output "out" sym @out : i1 - %out.wr, %out.wr.out = ibis.wire.input @out.wr : i1 - ibis.port.write %out, %out.wr.out : !ibis.portref - %c = ibis.container.instance @c, <@D::@AccessParent> - %c.p_out.ref = ibis.get_port %c, @p_out : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref> - ibis.port.write %c.p_out.ref, %out.wr : !ibis.portref> - %c.p_in.ref = ibis.get_port %c, @p_in : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref> - ibis.port.write %c.p_in.ref, %in.rd : !ibis.portref> -} - -} diff --git a/test/Dialect/Ibis/Transforms/prepare_scheduling.mlir b/test/Dialect/Ibis/Transforms/prepare_scheduling.mlir deleted file mode 100644 index 23be180d1f6d..000000000000 --- a/test/Dialect/Ibis/Transforms/prepare_scheduling.mlir +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: circt-opt --pass-pipeline="builtin.module(ibis.design(ibis.class(ibis.method.df(ibis.sblock.isolated(ibis-prepare-scheduling)))))" \ -// RUN: --allow-unregistered-dialect %s | FileCheck %s - -// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> (i32, i32) { -// CHECK: %[[VAL_3:.*]]:2 = ibis.sblock.isolated (%[[VAL_4:.*]] : i32 = %[[VAL_1]], %[[VAL_5:.*]] : i32 = %[[VAL_2]]) -> (i32, i32) { -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]] = ibis.pipeline.header -// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]], %[[VAL_12:.*]] = pipeline.unscheduled(%[[VAL_13:.*]] : i32 = %[[VAL_4]], %[[VAL_14:.*]] : i32 = %[[VAL_5]]) stall(%[[VAL_9]]) clock(%[[VAL_6]]) reset(%[[VAL_7]]) go(%[[VAL_8]]) entryEn(%[[VAL_15:.*]]) {operator_lib = @ibis_operator_library} -> (out0 : i32, out1 : i32) { -// CHECK: %[[VAL_16:.*]] = "foo.op1"(%[[VAL_13]], %[[VAL_14]]) {ssp.operator_type = @foo.op1} : (i32, i32) -> i32 -// CHECK: pipeline.return %[[VAL_16]], %[[VAL_13]] : i32, i32 -// CHECK: } -// CHECK: ibis.sblock.return %[[VAL_17:.*]], %[[VAL_18:.*]] : i32, i32 -// CHECK: } - -ibis.design @foo { -ibis.class sym @PrepareScheduling { - %this = ibis.this <@foo::@PrepareScheduling> - // A test wherein the returned values are either a value generated by an - // operation in the pipeline, or a value that's passed through the pipeline. - // The resulting IR should have all values passing through the newly created - // pipeline. - ibis.method.df @foo(%a: i32, %b: i32) -> (i32, i32) { - %0, %1 = ibis.sblock.isolated (%arg0 : i32 = %a, %arg1 : i32 = %b) -> (i32, i32) { - %4 = "foo.op1"(%arg0, %arg1) : (i32, i32) -> i32 - ibis.sblock.return %4, %arg0 : i32, i32 - } - ibis.return %0, %1 : i32, i32 - } -} -} diff --git a/test/Dialect/Ibis/Transforms/reblock.mlir b/test/Dialect/Ibis/Transforms/reblock.mlir deleted file mode 100644 index 00cc8eaa30c9..000000000000 --- a/test/Dialect/Ibis/Transforms/reblock.mlir +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis.design(ibis.class(ibis.method(ibis-reblock))))' %s | FileCheck %s - -// CHECK-LABEL: ibis.class sym @Reblock { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@Reblock> -// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 { -// CHECK: %[[VAL_3:.*]] = ibis.sblock () -> i32 { -// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_1]], %[[VAL_2]] : i32 -// CHECK: ibis.sblock.return %[[VAL_4]] : i32 -// CHECK: } -// CHECK: %[[VAL_5:.*]] = ibis.sblock () -> i32 attributes {maxThreads = 2 : i64} { -// CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : i32 -// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : i32 -// CHECK: ibis.sblock.return %[[VAL_7]] : i32 -// CHECK: } -// CHECK: %[[VAL_8:.*]] = ibis.sblock () -> i32 { -// CHECK: %[[VAL_9:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : i32 -// CHECK: ibis.sblock.return %[[VAL_9]] : i32 -// CHECK: } -// CHECK: cf.br ^bb1(%[[VAL_8]] : i32) -// CHECK: ^bb1(%[[VAL_10:.*]]: i32): -// CHECK: %[[VAL_11:.*]] = ibis.sblock () -> i32 { -// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_10]], %[[VAL_8]] : i32 -// CHECK: ibis.sblock.return %[[VAL_12]] : i32 -// CHECK: } -// CHECK: ibis.return %[[VAL_11]] : i32 -// CHECK: } -// CHECK: } - -ibis.design @foo { -ibis.class sym @Reblock { - %this = ibis.this <@foo::@Reblock> - - ibis.method @foo(%arg0 : i32, %arg1 : i32) -> i32 { - %0 = arith.addi %arg0, %arg1 : i32 - ibis.sblock.inline.begin {maxThreads = 2} - %inner = arith.addi %0, %arg1 : i32 - %1 = arith.addi %inner, %arg1 : i32 - ibis.sblock.inline.end - %2 = arith.addi %1, %arg1 : i32 - // %0 is used within the same MLIR block but outside the scope. - cf.br ^bb1(%2 : i32) - ^bb1(%barg : i32): - %3 = arith.addi %barg, %2 : i32 - // %1 is used in a different MLIR block (dominated by the sblock parent block). - ibis.return %3 : i32 - } -} -} diff --git a/test/Dialect/Ibis/Transforms/scoperef_tunneling.mlir b/test/Dialect/Ibis/Transforms/scoperef_tunneling.mlir deleted file mode 100644 index 1191905b34cf..000000000000 --- a/test/Dialect/Ibis/Transforms/scoperef_tunneling.mlir +++ /dev/null @@ -1,314 +0,0 @@ -// RUN: circt-opt --split-input-file --ibis-tunneling %s | FileCheck %s - -ibis.design @D { - -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// CHECK-LABEL: ibis.container sym @AccessChild { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessChild> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@D::@C> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK-NEXT: } - -ibis.container sym @AccessChild { - %this = ibis.this <@D::@AccessChild> - %c = ibis.container.instance @c, <@D::@C> - %c_ref = ibis.path [ - #ibis.step> - ] - %c_in = ibis.get_port %c_ref, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %c_out = ibis.get_port %c_ref, @out : !ibis.scoperef<@D::@C> -> !ibis.portref -} - -} - -// ----- -// CHECK-LABEL: // ----- - -ibis.design @D { -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// CHECK-LABEL: ibis.container sym @AccessSibling { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessSibling> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "[[VAL_1]]" sym @[[VAL_1]] : !ibis.portref -// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref> -// CHECK: %[[VAL_3:.*]] = ibis.port.input "[[VAL_3]]" sym @[[VAL_3]] : !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref> -// CHECK: } -ibis.container sym @AccessSibling { - %this = ibis.this <@D::@AccessSibling> - %sibling = ibis.path [ - #ibis.step, - #ibis.step> - ] - %c_in = ibis.get_port %sibling, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %c_out = ibis.get_port %sibling, @out : !ibis.scoperef<@D::@C> -> !ibis.portref -} - -// CHECK-LABEL: ibis.container sym @Parent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @a, <@D::@AccessSibling> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_b_out.rd : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3:.*]] : !ibis.portref> -// CHECK: %[[VAL_4:.*]] = ibis.get_port %[[VAL_1]], @p_b_in.wr : !ibis.scoperef<@D::@AccessSibling> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_5:.*]] : !ibis.portref> -// CHECK: %[[VAL_6:.*]] = ibis.container.instance @b, <@D::@C> -// CHECK: %[[VAL_3]] = ibis.get_port %[[VAL_6]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_5]] = ibis.get_port %[[VAL_6]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: } -ibis.container sym @Parent { - %this = ibis.this <@D::@Parent> - %a = ibis.container.instance @a, <@D::@AccessSibling> - %b = ibis.container.instance @b, <@D::@C> -} - -} - -// ----- -// CHECK-LABEL: // ----- - -// "Full"/recursive case. -// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child - -ibis.design @D { -// CHECK-LABEL: ibis.container sym @C1 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C1> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !ibis.portref -// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref> -// CHECK: %[[VAL_3:.*]] = ibis.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref> -// CHECK: } -ibis.container sym @C1 { - %this = ibis.this <@D::@C1> - %c3 = ibis.path [ - #ibis.step, - #ibis.step, - #ibis.step, - #ibis.step> - ] - %c_in = ibis.get_port %c3, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %c_out = ibis.get_port %c3, @out : !ibis.scoperef<@D::@C> -> !ibis.portref -} - -// CHECK-LABEL: ibis.container sym @C2 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@C2> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c3, <@D::@C> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.get_port %[[VAL_1]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.port.output "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !ibis.portref -// CHECK: %[[VAL_5:.*]] = ibis.port.output "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !ibis.portref -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_2]] : !ibis.portref> -// CHECK: ibis.port.write %[[VAL_5]], %[[VAL_3]] : !ibis.portref> -// CHECK: } -ibis.container sym @C2 { - %this = ibis.this <@D::@C2> - %c3 = ibis.container.instance @c3, <@D::@C> -} - -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// CHECK-LABEL: ibis.container sym @P1 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P1> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c1, <@D::@C1> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@C1> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3:.*]] : !ibis.portref> -// CHECK: %[[VAL_4:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_in.wr : !ibis.scoperef<@D::@C1> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_5:.*]] : !ibis.portref> -// CHECK: %[[VAL_6:.*]] = ibis.port.input "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !ibis.portref -// CHECK: %[[VAL_3]] = ibis.port.read %[[VAL_6]] : !ibis.portref> -// CHECK: %[[VAL_7:.*]] = ibis.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !ibis.portref -// CHECK: %[[VAL_5]] = ibis.port.read %[[VAL_7]] : !ibis.portref> -// CHECK: } -ibis.container sym @P1 { - %this = ibis.this <@D::@P1> - %c1 = ibis.container.instance @c1, <@D::@C1> -} - -// CHECK-LABEL: ibis.container sym @P2 { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@P2> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @p1, <@D::@P1> -// CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@P1> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_2]], %[[VAL_3:.*]] : !ibis.portref> -// CHECK: %[[VAL_4:.*]] = ibis.get_port %[[VAL_1]], @p_p_c2_c3_in.wr : !ibis.scoperef<@D::@P1> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_5:.*]] : !ibis.portref> -// CHECK: %[[VAL_6:.*]] = ibis.container.instance @c2, <@D::@C2> -// CHECK: %[[VAL_7:.*]] = ibis.get_port %[[VAL_6]], @p_p_c2_c3_in.wr : !ibis.scoperef<@D::@C2> -> !ibis.portref> -// CHECK: %[[VAL_5]] = ibis.port.read %[[VAL_7]] : !ibis.portref> -// CHECK: %[[VAL_8:.*]] = ibis.get_port %[[VAL_6]], @p_p_c2_c3_out.rd : !ibis.scoperef<@D::@C2> -> !ibis.portref> -// CHECK: %[[VAL_3]] = ibis.port.read %[[VAL_8]] : !ibis.portref> -// CHECK: } -ibis.container sym @P2 { - %this = ibis.this <@D::@P2> - %p1 = ibis.container.instance @p1, <@D::@P1> - %c2 = ibis.container.instance @c2, <@D::@C2> -} - -} - -// ----- -// CHECK-LABEL: // ----- - -ibis.design @D { -// CHECK-LABEL: ibis.container sym @AccessParent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@AccessParent> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "p_out.wr" sym @p_out.wr : !ibis.portref -// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref> -// CHECK: %[[VAL_3:.*]] = ibis.port.input "p_in.rd" sym @p_in.rd : !ibis.portref -// CHECK: %[[VAL_4:.*]] = ibis.port.read %[[VAL_3]] : !ibis.portref> -// CHECK: } -ibis.container sym @AccessParent { - %this = ibis.this <@D::@AccessParent> - %p = ibis.path [ - #ibis.step> - ] - - // get_port states the intended usage of the port. Hence we should be able to - // request a parent input port as an output port (readable), and vice versa. - // This will insert wires in the target container to facilitate the direction - // flip. - %p_in_ref = ibis.get_port %p, @in : !ibis.scoperef<@D::@Parent> -> !ibis.portref - %p_out_ref = ibis.get_port %p, @out : !ibis.scoperef<@D::@Parent> -> !ibis.portref -} - -// CHECK-LABEL: ibis.container sym @Parent { -// CHECK: %[[VAL_0:.*]] = ibis.this <@D::@Parent> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1 -// CHECK: %[[VAL_2:.*]] = ibis.port.read %[[VAL_1]] : !ibis.portref -// CHECK: %[[VAL_3:.*]] = ibis.wire.output @in.rd, %[[VAL_2]] : i1 -// CHECK: %[[VAL_4:.*]] = ibis.port.output "out" sym @out : i1 -// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = ibis.wire.input @out.wr : i1 -// CHECK: ibis.port.write %[[VAL_4]], %[[VAL_6]] : !ibis.portref -// CHECK: %[[VAL_7:.*]] = ibis.container.instance @c, <@D::@AccessParent> -// CHECK: %[[VAL_8:.*]] = ibis.get_port %[[VAL_7]], @p_out.wr : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_8]], %[[VAL_5]] : !ibis.portref> -// CHECK: %[[VAL_9:.*]] = ibis.get_port %[[VAL_7]], @p_in.rd : !ibis.scoperef<@D::@AccessParent> -> !ibis.portref> -// CHECK: ibis.port.write %[[VAL_9]], %[[VAL_3]] : !ibis.portref> -// CHECK: } -ibis.container sym @Parent { - %this = ibis.this <@D::@Parent> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 - %c = ibis.container.instance @c, <@D::@AccessParent> -} - -} - -// ----- -// CHECK-LABEL: // ----- - -ibis.design @D { - -ibis.container sym @C { - %this = ibis.this <@D::@C> - %in = ibis.port.input "in" sym @in : i1 - %out = ibis.port.output "out" sym @out : i1 -} - -// TODO: support this case. Too hard to support now. Problem is that hw.module -// cannot live within an ibis.design, but we need to run this pass on the -// ibis.design op. I don't think it's critical that we support this case currently. - -// COM: CHECK-LABEL: hw.module @AccessChildFromHW() { -// COM: CHECK: %[[VAL_0:.*]] = ibis.container.instance @c, <@D::@C> -// COM: CHECK: %[[VAL_1:.*]] = ibis.get_port %[[VAL_0]], @out : !ibis.scoperef<@D::@C> -> !ibis.portref -// COM: CHECK: %[[VAL_2:.*]] = ibis.get_port %[[VAL_0]], @in : !ibis.scoperef<@D::@C> -> !ibis.portref -// COM: CHECK: hw.output -// COM: CHECK: } - -} - -hw.module @AccessChildFromHW() { - %c = ibis.container.instance @c, <@D::@C> - %c_ref = ibis.path [ - #ibis.step> - ] - %c_in = ibis.get_port %c_ref, @in : !ibis.scoperef<@D::@C> -> !ibis.portref - %c_out = ibis.get_port %c_ref, @out : !ibis.scoperef<@D::@C> -> !ibis.portref -} - - -// ----- -// CHECK-LABEL: // ----- - -ibis.design @D { -// The ultimate tunneling test - by having 3 intermediate levels for both up- -// and downwards tunneling, we are sure test all the possible combinations of -// tunneling. - -ibis.container sym @D_up { - %this = ibis.this <@D::@D_up> - %d = ibis.path [ - #ibis.step, - #ibis.step, - #ibis.step, - #ibis.step, - #ibis.step : !ibis.scoperef, - #ibis.step : !ibis.scoperef, - #ibis.step : !ibis.scoperef, - #ibis.step> : !ibis.scoperef<@D::@D_down>] - // Write an input port - %clk_ref = ibis.get_port %d, @clk_in : !ibis.scoperef<@D::@D_down> -> !ibis.portref - %clk = hw.constant 1 : i1 - ibis.port.write %clk_ref, %clk : !ibis.portref - - // Read an input port - %clk_ref_2 = ibis.get_port %d, @clk_in : !ibis.scoperef<@D::@D_down> -> !ibis.portref - %clk_in_val = ibis.port.read %clk_ref_2 : !ibis.portref - - // Read an output port - %clk_out_ref = ibis.get_port %d, @clk_out : !ibis.scoperef<@D::@D_down> -> !ibis.portref - %clk_out_val = ibis.port.read %clk_out_ref : !ibis.portref -} -ibis.container sym @C_up { - %this = ibis.this <@D::@C_up> - %d = ibis.container.instance @d, <@D::@D_up> -} -ibis.container sym @B_up { - %this = ibis.this <@D::@B_up> - %c = ibis.container.instance @c, <@D::@C_up> - -} - -ibis.container sym @A_up { - %this = ibis.this <@D::@A_up> - %b = ibis.container.instance @b, <@D::@B_up> -} - -ibis.container sym @Top { - %this = ibis.this <@D::@Top> - %a_down = ibis.container.instance @a_down, <@D::@A_down> - %a_up = ibis.container.instance @a_up, <@D::@A_up> -} -ibis.container sym @A_down { - %this = ibis.this <@D::@A_down> - %b = ibis.container.instance @b, <@D::@B_down> -} -ibis.container sym @B_down { - %this = ibis.this <@D::@B_down> - %c = ibis.container.instance @c, <@D::@C_down> -} -ibis.container sym @C_down { - %this = ibis.this <@D::@C_down> - %d = ibis.container.instance @d, <@D::@D_down> -} -ibis.container sym @D_down { - %this = ibis.this <@D::@D_down> - %clk = ibis.port.input "clk_in" sym @clk_in : i1 - %clk_out = ibis.port.output "clk_out" sym @clk_out : i1 - %clk.val = ibis.port.read %clk : !ibis.portref - ibis.port.write %clk_out, %clk.val : !ibis.portref -} -} diff --git a/test/Dialect/Ibis/Transforms/structure.mlir b/test/Dialect/Ibis/Transforms/structure.mlir deleted file mode 100644 index 134f7d6172f8..000000000000 --- a/test/Dialect/Ibis/Transforms/structure.mlir +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: circt-opt %s | circt-opt | FileCheck %s -// RUN: circt-opt %s --ibis-call-prep | circt-opt | FileCheck %s --check-prefix=PREP - - -// CHECK-LABEL: ibis.class sym @C { -// CHECK: ibis.method @getAndSet(%x: ui32) -> ui32 { -// CHECK: ibis.return %x : ui32 -// CHECK: ibis.method @returnNothingWithRet() -> () { -// CHECK: ibis.return - -// PREP-LABEL: ibis.class sym @C { -// PREP: ibis.method @getAndSet(%arg: !hw.struct) -> ui32 { -// PREP: %x = hw.struct_explode %arg : !hw.struct -// PREP: ibis.return %x : ui32 -// PREP: ibis.method @returnNothingWithRet(%arg: !hw.struct<>) -> () { -// PREP: hw.struct_explode %arg : !hw.struct<> -// PREP: ibis.return - -ibis.design @foo { -ibis.class sym @C { - %this = ibis.this <@foo::@C> - ibis.method @getAndSet(%x: ui32) -> ui32 { - ibis.return %x : ui32 - } - ibis.method @returnNothingWithRet() { - ibis.return - } -} - -// CHECK-LABEL: ibis.class sym @User { -// CHECK: [[c:%.+]] = ibis.instance @c, <@foo::@C> -// CHECK: ibis.method @getAndSetWrapper(%new_value: ui32) -> ui32 { -// CHECK: [[x:%.+]] = ibis.call <@foo::@getAndSet>(%new_value) : (ui32) -> ui32 -// CHECK: ibis.return [[x]] : ui32 -// CHECK: ibis.method @getAndSetDup(%new_value: ui32) -> ui32 { -// CHECK: [[x:%.+]] = ibis.call <@foo::@getAndSet>(%new_value) : (ui32) -> ui32 -// CHECK: ibis.return [[x]] : ui32 - - -// PREP-LABEL: ibis.class sym @User { -// PREP: [[c:%.+]] = ibis.instance @c, <@foo::@C> -// PREP: ibis.method @getAndSetWrapper(%arg: !hw.struct) -> ui32 { -// PREP: %new_value = hw.struct_explode %arg : !hw.struct -// PREP: [[STRUCT1:%.+]] = hw.struct_create (%new_value) {sv.namehint = "getAndSet_args_called_from_getAndSetWrapper"} : !hw.struct -// PREP: [[CALLRES1:%.+]] = ibis.call <@foo::@getAndSet>([[STRUCT1]]) : (!hw.struct) -> ui32 -// PREP: ibis.method @getAndSetDup(%arg: !hw.struct) -> ui32 { -// PREP: %new_value = hw.struct_explode %arg : !hw.struct -// PREP: [[STRUCT2:%.+]] = hw.struct_create (%new_value) {sv.namehint = "getAndSet_args_called_from_getAndSetDup"} : !hw.struct -// PREP: [[CALLRES2:%.+]] = ibis.call <@foo::@getAndSet>([[STRUCT2]]) : (!hw.struct) -> ui32 -// PREP: ibis.return [[CALLRES2]] : ui32 -ibis.class sym @User { - %this = ibis.this <@foo::@User> - ibis.instance @c, <@foo::@C> - ibis.method @getAndSetWrapper(%new_value: ui32) -> ui32 { - %x = ibis.call <@foo::@getAndSet>(%new_value): (ui32) -> ui32 - ibis.return %x : ui32 - } - - ibis.method @getAndSetDup(%new_value: ui32) -> ui32 { - %x = ibis.call <@foo::@getAndSet>(%new_value): (ui32) -> ui32 - ibis.return %x : ui32 - } -} -} diff --git a/test/Dialect/Ibis/Transforms/tunneling_errors.mlir b/test/Dialect/Ibis/Transforms/tunneling_errors.mlir deleted file mode 100644 index dd829a2f014e..000000000000 --- a/test/Dialect/Ibis/Transforms/tunneling_errors.mlir +++ /dev/null @@ -1,43 +0,0 @@ -// RUN: circt-opt --split-input-file --allow-unregistered-dialect --ibis-tunneling --verify-diagnostics %s - -ibis.design @foo { -ibis.container sym @Parent { - %this = ibis.this <@foo::@Parent> - %in = ibis.port.input "in" sym @in : i1 -} - -ibis.container sym @Orphan { - %this = ibis.this <@foo::@Orphan> - // expected-error @+2 {{'ibis.path' op cannot tunnel up from "Orphan" because it has no uses}} - // expected-error @+1 {{failed to legalize operation 'ibis.path' that was explicitly marked illegal}} - %parent = ibis.path [ - #ibis.step> - ] - - %p = ibis.get_port %parent, @in : !ibis.scoperef<@foo::@Parent> -> !ibis.portref -} -} -// ----- - -ibis.design @foo { -ibis.container sym @Parent { - %this = ibis.this <@foo::@Parent> - %mc = ibis.container.instance @mc, <@foo::@MissingChild> -} - -ibis.container sym @Child { - %this = ibis.this <@foo::@Child> - %in = ibis.port.input "in" sym @in : i1 -} - -ibis.container sym @MissingChild { - %this = ibis.this <@foo::@MissingChild> - // expected-error @+2 {{'ibis.path' op expected an instance named @c in @Parent but found none}} - // expected-error @+1 {{failed to legalize operation 'ibis.path' that was explicitly marked illegal}} - %parent = ibis.path [ - #ibis.step, - #ibis.step> - ] - %p = ibis.get_port %parent, @in : !ibis.scoperef<@foo::@Child> -> !ibis.portref -} -} diff --git a/test/Dialect/Ibis/canonicalization.mlir b/test/Dialect/Ibis/canonicalization.mlir deleted file mode 100644 index 5c553dd7ffd0..000000000000 --- a/test/Dialect/Ibis/canonicalization.mlir +++ /dev/null @@ -1,40 +0,0 @@ -// RUN: circt-opt --allow-unregistered-dialect --split-input-file --canonicalize --cse %s | FileCheck %s - -ibis.design @foo { - -// CHECK-LABEL: ibis.container sym @GetPortOnThis { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@GetPortOnThis> -// CHECK: %[[VAL_1:.*]] = ibis.port.input "in" sym @in : i1 -// CHECK: "foo.user"(%[[VAL_1]]) : (!ibis.portref) -> () -// CHECK: } -ibis.container sym @GetPortOnThis { - %this = ibis.this <@foo::@GetPortOnThis> - %p = ibis.port.input "in" sym @in : i1 - %p2 = ibis.get_port %this, @in : !ibis.scoperef<@foo::@GetPortOnThis> -> !ibis.portref - "foo.user"(%p2) : (!ibis.portref) -> () -} - -} - -// ----- - -ibis.design @foo { - -ibis.container sym @C { - %this = ibis.this <@foo::@C> -} - -// CHECK-LABEL: ibis.container sym @AccessChild { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@AccessChild> -// CHECK: %[[VAL_1:.*]] = ibis.container.instance @c, <@foo::@C -// CHECK: "foo.user"(%[[VAL_1]]) : (!ibis.scoperef<@foo::@C>) -> () -// CHECK: } -ibis.container sym @AccessChild { - %this = ibis.this <@foo::@AccessChild> - %c = ibis.container.instance @c, <@foo::@C> - %c_ref = ibis.path [ - #ibis.step> - ] - "foo.user"(%c_ref) : (!ibis.scoperef<@foo::@C>) -> () -} -} diff --git a/test/Dialect/Ibis/errors.mlir b/test/Dialect/Ibis/errors.mlir deleted file mode 100644 index d01a5ab1af4b..000000000000 --- a/test/Dialect/Ibis/errors.mlir +++ /dev/null @@ -1,96 +0,0 @@ -// RUN: circt-opt --split-input-file --verify-diagnostics %s - -ibis.design @foo { -ibis.class sym @C { - %this = ibis.this <@foo::@C> - ibis.method @typeMismatch1() -> (ui32, i32) { - // expected-error @+1 {{'ibis.return' op must have the same number of operands as the method has results}} - ibis.return - } -} -} - -// ----- -ibis.design @foo { -ibis.class sym @C { - %this = ibis.this <@foo::@C> - ibis.method @typeMismatch3() -> ui32 { - %c = hw.constant 1 : i8 - // expected-error @+1 {{'ibis.return' op operand type ('i8') must match function return type ('ui32')}} - ibis.return %c : i8 - } -} -} - -// ----- - -ibis.design @foo { -// expected-error @+1 {{'ibis.class' op must contain only one 'ibis.this' operation}} -ibis.class sym @MultipleThis { - %this = ibis.this <@foo::@MultipleThis> - %this2 = ibis.this <@foo::@MultipleThis> -} -} - -// ----- - -ibis.design @foo { -// expected-error @+1 {{'ibis.container' op must contain a 'ibis.this' operation}} -ibis.container sym @NoThis { -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PathStepParentWithInstanceName { - %this = ibis.this <@foo::@PathStepParentWithInstanceName> - // expected-error @+1 {{ibis.step 'parent' may not specify an instance name}} - %p = ibis.path [#ibis.step] -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PathStepInvalidType { - %this = ibis.this <@foo::@PathStepParentWithInstanceName> - // expected-error @+1 {{ibis.step type must be an !ibis.scoperef type}} - %p = ibis.path [#ibis.step] -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PathStepChildMissingSymbol { - %this = ibis.this <@foo::@PathStepNonExistingChild> - // expected-error @+1 {{ibis.step 'child' must specify an instance name}} - %p = ibis.path [#ibis.step>] -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @InvalidVar { - %this = ibis.this <@foo::@C> - // expected-error @+1 {{'ibis.var' op attribute 'type' failed to satisfy constraint: any memref type}} - ibis.var @var : i32 -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @InvalidReturn { - %this = ibis.this <@foo::@InvalidReturn> - ibis.method @foo() { - %c = hw.constant 1 : i32 - // expected-error @+1 {{'ibis.sblock.return' op number of operands must match number of block outputs}} - %ret = ibis.sblock() -> i32 { - } - ibis.return - } -} -} diff --git a/test/Dialect/Ibis/inner_ref_errors.mlir b/test/Dialect/Ibis/inner_ref_errors.mlir deleted file mode 100644 index 41e4341ba560..000000000000 --- a/test/Dialect/Ibis/inner_ref_errors.mlir +++ /dev/null @@ -1,74 +0,0 @@ -// RUN: circt-opt --hw-verify-irn --split-input-file --verify-diagnostics %s - -ibis.design @foo { -ibis.class sym @MissingPort { - %this = ibis.this <@foo::@MissingPort> - // expected-error @+1 {{'ibis.get_port' op port '@C_in' does not exist in @MissingPort}} - %c_in = ibis.get_port %this, @C_in : !ibis.scoperef<@foo::@MissingPort> -> !ibis.portref -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @InvalidGetVar2 { - %this = ibis.this <@foo::@InvalidGetVar2> - ibis.var @var : memref - ibis.method @foo() { - %parent = ibis.path [ - #ibis.step> - ] - // expected-error @+1 {{'ibis.get_var' op dereferenced type ('memref') must match variable type ('memref')}} - %var = ibis.get_var %parent, @var : !ibis.scoperef<@foo::@InvalidGetVar2> -> memref - ibis.return - } -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @InvalidGetVar { - %this = ibis.this <@foo::@InvalidGetVar> - ibis.var @var : memref - ibis.method @foo() { - %parent = ibis.path [ - #ibis.step> - ] - // expected-error @+1 {{'ibis.get_var' op result #0 must be memref of any type values, but got 'i32'}} - %var = ibis.get_var %parent, @var : !ibis.scoperef<@foo::@InvalidGetVar> -> i32 - ibis.return - } -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PortTypeMismatch { - %this = ibis.this <@foo::@PortTypeMismatch> - ibis.port.input "in" sym @in : i1 - // expected-error @+1 {{'ibis.get_port' op symbol '@in' refers to a port of type 'i1', but this op has type 'i2'}} - %c_in = ibis.get_port %this, @in : !ibis.scoperef<@foo::@PortTypeMismatch> -> !ibis.portref -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PathStepNonExistingChild { - %this = ibis.this <@foo::@PathStepNonExistingChild> - // expected-error @+1 {{'ibis.path' op ibis.step scoperef symbol '@A' does not exist}} - %p = ibis.path [#ibis.step>] -} -} - -// ----- - -ibis.design @foo { -ibis.class sym @PathStepNonExistingParent { - %this = ibis.this <@foo::@PathStepNonExistingParent> - // expected-error @+1 {{'ibis.path' op last ibis.step in path must specify a symbol for the scoperef}} - %p = ibis.path [#ibis.step] -} -} diff --git a/test/Dialect/Ibis/round-trip.mlir b/test/Dialect/Ibis/round-trip.mlir deleted file mode 100644 index a4e29478d831..000000000000 --- a/test/Dialect/Ibis/round-trip.mlir +++ /dev/null @@ -1,145 +0,0 @@ -// RUN: circt-opt %s | circt-opt | FileCheck %s - -ibis.design @foo { - -// CHECK-LABEL: ibis.class sym @HighLevel { -// CHECK-NEXT: %this = ibis.this <@foo::@HighLevel> -// CHECK-NEXT: ibis.var @single : memref -// CHECK-NEXT: ibis.var @array : memref<10xi32> -// CHECK-NEXT: ibis.method @foo() -> (i32, i32) { -// CHECK-NEXT: %parent = ibis.path [#ibis.step> : !ibis.scoperef<@foo::@HighLevel>] -// CHECK-NEXT: %single = ibis.get_var %parent, @single : !ibis.scoperef<@foo::@HighLevel> -> memref -// CHECK-NEXT: %array = ibis.get_var %parent, @array : !ibis.scoperef<@foo::@HighLevel> -> memref<10xi32> -// CHECK-NEXT: %alloca = memref.alloca() : memref -// CHECK-NEXT: %c32_i32 = hw.constant 32 : i32 -// CHECK-NEXT: %0:2 = ibis.sblock (%arg0 : i32 = %c32_i32) -> (i32, i32) attributes {schedule = 1 : i64} { -// CHECK-NEXT: %1 = memref.load %alloca[] : memref -// CHECK-NEXT: memref.store %arg0, %alloca[] : memref -// CHECK-NEXT: ibis.sblock.return %1, %1 : i32, i32 -// CHECK-NEXT: } -// CHECK-NEXT: ibis.return %0#0, %0#1 : i32, i32 -// CHECK-NEXT: } -// CHECK-NEXT: ibis.method.df @bar(%arg0: none) -> none { -// CHECK-NEXT: %0 = handshake.join %arg0 : none -// CHECK-NEXT: ibis.return %0 : none -// CHECK-NEXT: } -// CHECK-NEXT: } - - -ibis.class sym @HighLevel { - %this = ibis.this <@foo::@HighLevel> - ibis.var @single : memref - ibis.var @array : memref<10xi32> - - ibis.method @foo() -> (i32, i32) { - %parent = ibis.path [ - #ibis.step> - ] - %single = ibis.get_var %parent, @single : !ibis.scoperef<@foo::@HighLevel> -> memref - %array = ibis.get_var %parent, @array : !ibis.scoperef<@foo::@HighLevel> -> memref<10xi32> - %local = memref.alloca() : memref - %c32 = hw.constant 32 : i32 - %out1, %out2 = ibis.sblock(%arg : i32 = %c32) -> (i32, i32) attributes {schedule = 1} { - %v = memref.load %local[] : memref - memref.store %arg, %local[] : memref - ibis.sblock.return %v, %v : i32, i32 - } - ibis.return %out1, %out2 : i32, i32 - } - - ibis.method.df @bar(%arg0 : none) -> (none) { - %0 = handshake.join %arg0 : none - ibis.return %0 : none - } -} - - -// CHECK-LABEL: ibis.class sym @A { -// CHECK-NEXT: %this = ibis.this <@foo::@A> -// CHECK-NEXT: %in = ibis.port.input "in" sym @in : i1 -// CHECK-NEXT: %out = ibis.port.output "out" sym @out : i1 -// CHECK-NEXT: %AnonymousPort = ibis.port.input sym @AnonymousPort : i1 -// CHECK-NEXT: } - -// CHECK-LABEL: ibis.class sym @LowLevel { -// CHECK-NEXT: %this = ibis.this <@foo::@LowLevel> -// CHECK-NEXT: %LowLevel_in = ibis.port.input "LowLevel_in" sym @LowLevel_in : i1 -// CHECK-NEXT: %LowLevel_out = ibis.port.output "LowLevel_out" sym @LowLevel_out : i1 -// CHECK-NEXT: %in_wire, %in_wire.out = ibis.wire.input @in_wire : i1 -// CHECK-NEXT: %true = hw.constant true -// CHECK-NEXT: %out_wire = ibis.wire.output @out_wire, %true : i1 -// CHECK-NEXT: %a = ibis.instance @a, <@foo::@A> -// CHECK-NEXT: ibis.container sym @D { -// CHECK-NEXT: %this_0 = ibis.this <@foo::@D> -// CHECK-NEXT: %parent = ibis.path [#ibis.step> : !ibis.scoperef<@foo::@LowLevel>] -// CHECK-NEXT: %parent.LowLevel_in.ref = ibis.get_port %parent, @LowLevel_in : !ibis.scoperef<@foo::@LowLevel> -> !ibis.portref -// CHECK-NEXT: %parent.LowLevel_out.ref = ibis.get_port %parent, @LowLevel_out : !ibis.scoperef<@foo::@LowLevel> -> !ibis.portref -// CHECK-NEXT: %true_1 = hw.constant true -// CHECK-NEXT: ibis.port.write %parent.LowLevel_in.ref, %true_1 : !ibis.portref -// CHECK-NEXT: %parent.LowLevel_out.ref.val = ibis.port.read %parent.LowLevel_out.ref : !ibis.portref -// CHECK-NEXT: %parent.a = ibis.path [#ibis.step : !ibis.scoperef, #ibis.step> : !ibis.scoperef<@foo::@A>] -// CHECK-NEXT: %parent.a.in.ref = ibis.get_port %parent.a, @in : !ibis.scoperef<@foo::@A> -> !ibis.portref -// CHECK-NEXT: %parent.a.out.ref = ibis.get_port %parent.a, @out : !ibis.scoperef<@foo::@A> -> !ibis.portref -// CHECK-NEXT: ibis.port.write %parent.a.in.ref, %parent.LowLevel_out.ref.val : !ibis.portref -// CHECK-NEXT: %parent.a.out.ref.val = ibis.port.read %parent.a.out.ref : !ibis.portref -// CHECK-NEXT: hw.instance "foo" @externModule() -> () -// CHECK-NEXT: } - -// CHECK-NEXT: ibis.container "ThisName" sym @ThisSymbol { -// CHECK-NEXT: %this_0 = ibis.this <@foo::@ThisSymbol> -// CHECK-NEXT: } -// CHECK-NEXT: } - -ibis.class sym @A { - %this = ibis.this <@foo::@A> - ibis.port.input "in" sym @in : i1 - ibis.port.output "out" sym @out : i1 - ibis.port.input sym @AnonymousPort : i1 -} - -ibis.class sym @LowLevel { - %this = ibis.this <@foo::@LowLevel> - ibis.port.input "LowLevel_in" sym @LowLevel_in : i1 - ibis.port.output "LowLevel_out" sym @LowLevel_out : i1 - - %in_wire, %in_wire.val = ibis.wire.input @in_wire : i1 - %true = hw.constant 1 : i1 - %out_wire = ibis.wire.output @out_wire, %true : i1 - - // Instantiation - %a = ibis.instance @a, <@foo::@A> - - ibis.container sym @D { - %this_d = ibis.this <@foo::@D> - %parent_C = ibis.path [ - #ibis.step> - ] - // Test local read/writes - %LowLevel_in_p = ibis.get_port %parent_C, @LowLevel_in : !ibis.scoperef<@foo::@LowLevel> -> !ibis.portref - %LowLevel_out_p = ibis.get_port %parent_C, @LowLevel_out : !ibis.scoperef<@foo::@LowLevel> -> !ibis.portref - %t = hw.constant true - ibis.port.write %LowLevel_in_p, %t : !ibis.portref - %LowLevel_out = ibis.port.read %LowLevel_out_p : !ibis.portref - - // Test cross-container read/writes - %A.in_parent = ibis.path [ - #ibis.step, - #ibis.step> - ] - %A.in_p = ibis.get_port %A.in_parent, @in : !ibis.scoperef<@foo::@A> -> !ibis.portref - %A.out_p = ibis.get_port %A.in_parent, @out : !ibis.scoperef<@foo::@A> -> !ibis.portref - ibis.port.write %A.in_p, %LowLevel_out : !ibis.portref - %A.out = ibis.port.read %A.out_p : !ibis.portref - - // Test hw.instance ops inside a container (symbol table usage) - hw.instance "foo" @externModule() -> () - } - - ibis.container "ThisName" sym @ThisSymbol { - %this2 = ibis.this <@foo::@ThisSymbol> - } -} - -} - -hw.module.extern @externModule() diff --git a/test/Dialect/Kanagawa/Transforms/argify_blocks.mlir b/test/Dialect/Kanagawa/Transforms/argify_blocks.mlir new file mode 100644 index 000000000000..1791fd8750cd --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/argify_blocks.mlir @@ -0,0 +1,30 @@ +// RUN: circt-opt --kanagawa-argify-blocks %s | FileCheck %s + +// CHECK-LABEL: kanagawa.class sym @Argify { +// CHECK-NEXT: %this = kanagawa.this <@foo::@Argify> +// CHECK-NEXT: kanagawa.method @foo() -> () { +// CHECK-NEXT: %c32_i32 = hw.constant 32 : i32 +// CHECK-NEXT: %0:2 = kanagawa.sblock.isolated (%arg0 : i32 = %c32_i32) -> (i32, i32) { +// CHECK-NEXT: %c31_i32 = hw.constant 31 : i32 +// CHECK-NEXT: %1 = arith.addi %arg0, %c31_i32 : i32 +// CHECK-NEXT: kanagawa.sblock.return %1, %arg0 : i32, i32 +// CHECK-NEXT: } +// CHECK-NEXT: kanagawa.return +// CHECK-NEXT: } +// CHECK-NEXT: } + +kanagawa.design @foo { +kanagawa.class sym @Argify { + %this = kanagawa.this <@foo::@Argify> + + kanagawa.method @foo() { + %c32 = hw.constant 32 : i32 + %0:2 = kanagawa.sblock() -> (i32, i32) { + %c31 = hw.constant 31 : i32 + %res = arith.addi %c31, %c32 : i32 + kanagawa.sblock.return %res, %c32 : i32, i32 + } + kanagawa.return + } +} +} diff --git a/test/Dialect/Ibis/Transforms/cf_to_handshake.mlir b/test/Dialect/Kanagawa/Transforms/cf_to_handshake.mlir similarity index 62% rename from test/Dialect/Ibis/Transforms/cf_to_handshake.mlir rename to test/Dialect/Kanagawa/Transforms/cf_to_handshake.mlir index 07622731f088..2000fa48f482 100644 --- a/test/Dialect/Ibis/Transforms/cf_to_handshake.mlir +++ b/test/Dialect/Kanagawa/Transforms/cf_to_handshake.mlir @@ -1,16 +1,16 @@ -// RUN: circt-opt --pass-pipeline="builtin.module(ibis.design(ibis.class(ibis-convert-cf-to-handshake)))" \ +// RUN: circt-opt --pass-pipeline="builtin.module(kanagawa.design(kanagawa.class(kanagawa-convert-cf-to-handshake)))" \ // RUN: --allow-unregistered-dialect %s | FileCheck %s -// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: none) -> (i32, none) { +// CHECK: kanagawa.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: none) -> (i32, none) { // CHECK: %[[VAL_5:.*]] = handshake.merge %[[VAL_1]] : i32 // CHECK: %[[VAL_6:.*]] = handshake.merge %[[VAL_2]] : i32 // CHECK: %[[VAL_7:.*]] = handshake.merge %[[VAL_3]] : i1 // CHECK: %[[VAL_8:.*]] = handshake.buffer [2] fifo %[[VAL_7]] : i1 // CHECK: %[[VAL_9:.*]] = handshake.merge %[[VAL_4]] : none -// CHECK: %[[VAL_10:.*]] = ibis.sblock (%[[VAL_11:.*]] : i32 = %[[VAL_5]], %[[VAL_12:.*]] : i32 = %[[VAL_6]]) -> i32 attributes {maxThreads = 1 : i64} { +// CHECK: %[[VAL_10:.*]] = kanagawa.sblock (%[[VAL_11:.*]] : i32 = %[[VAL_5]], %[[VAL_12:.*]] : i32 = %[[VAL_6]]) -> i32 attributes {maxThreads = 1 : i64} { // CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 -// CHECK: ibis.sblock.return %[[VAL_13]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_13]] : i32 // CHECK: } // CHECK: %[[VAL_14:.*]], %[[VAL_15:.*]] = handshake.cond_br %[[VAL_7]], %[[VAL_5]] : i32 // CHECK: %[[VAL_16:.*]], %[[VAL_17:.*]] = handshake.cond_br %[[VAL_7]], %[[VAL_9]] : none @@ -18,53 +18,53 @@ // CHECK: %[[VAL_20:.*]] = handshake.merge %[[VAL_14]] : i32 // CHECK: %[[VAL_21:.*]] = handshake.merge %[[VAL_18]] : i32 // CHECK: %[[VAL_22:.*]], %[[VAL_23:.*]] = handshake.control_merge %[[VAL_16]] : none, index -// CHECK: %[[VAL_24:.*]] = ibis.sblock (%[[VAL_25:.*]] : i32 = %[[VAL_21]], %[[VAL_26:.*]] : i32 = %[[VAL_20]]) -> i32 { +// CHECK: %[[VAL_24:.*]] = kanagawa.sblock (%[[VAL_25:.*]] : i32 = %[[VAL_21]], %[[VAL_26:.*]] : i32 = %[[VAL_20]]) -> i32 { // CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_25]], %[[VAL_26]] : i32 -// CHECK: ibis.sblock.return %[[VAL_27]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_27]] : i32 // CHECK: } // CHECK: %[[VAL_28:.*]] = handshake.br %[[VAL_22]] : none // CHECK: %[[VAL_29:.*]] = handshake.br %[[VAL_24]] : i32 // CHECK: %[[VAL_30:.*]] = handshake.merge %[[VAL_15]] : i32 // CHECK: %[[VAL_31:.*]] = handshake.merge %[[VAL_19]] : i32 // CHECK: %[[VAL_32:.*]], %[[VAL_33:.*]] = handshake.control_merge %[[VAL_17]] : none, index -// CHECK: %[[VAL_34:.*]] = ibis.sblock (%[[VAL_35:.*]] : i32 = %[[VAL_31]], %[[VAL_36:.*]] : i32 = %[[VAL_30]]) -> i32 { +// CHECK: %[[VAL_34:.*]] = kanagawa.sblock (%[[VAL_35:.*]] : i32 = %[[VAL_31]], %[[VAL_36:.*]] : i32 = %[[VAL_30]]) -> i32 { // CHECK: %[[VAL_37:.*]] = "foo.op2"(%[[VAL_35]], %[[VAL_36]]) : (i32, i32) -> i32 -// CHECK: ibis.sblock.return %[[VAL_37]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_37]] : i32 // CHECK: } // CHECK: %[[VAL_38:.*]] = handshake.br %[[VAL_32]] : none // CHECK: %[[VAL_39:.*]] = handshake.br %[[VAL_34]] : i32 // CHECK: %[[VAL_40:.*]] = handshake.mux %[[VAL_41:.*]] {{\[}}%[[VAL_39]], %[[VAL_29]]] : index, i32 // CHECK: %[[VAL_42:.*]] = handshake.mux %[[VAL_8]] {{\[}}%[[VAL_38]], %[[VAL_28]]] : i1, none // CHECK: %[[VAL_41]] = arith.index_cast %[[VAL_8]] : i1 to index -// CHECK: ibis.return %[[VAL_40]], %[[VAL_42]] : i32, none +// CHECK: kanagawa.return %[[VAL_40]], %[[VAL_42]] : i32, none // CHECK: } -ibis.design @foo { -ibis.class sym @ToHandshake { - %this = ibis.this <@foo::@ToHandshake> - // Just a simple test demonstrating the intended mixing of `ibis.sblock`s and +kanagawa.design @foo { +kanagawa.class sym @ToHandshake { + %this = kanagawa.this <@foo::@ToHandshake> + // Just a simple test demonstrating the intended mixing of `kanagawa.sblock`s and // control flow operations. The meat of cf-to-handshake conversion is tested // in the handshake dialect tests. - ibis.method @foo(%a: i32, %b: i32, %cond : i1) -> i32 { - %0 = ibis.sblock (%arg0 : i32 = %a, %arg1 : i32 = %b) -> i32 attributes {maxThreads = 1 : i64} { + kanagawa.method @foo(%a: i32, %b: i32, %cond : i1) -> i32 { + %0 = kanagawa.sblock (%arg0 : i32 = %a, %arg1 : i32 = %b) -> i32 attributes {maxThreads = 1 : i64} { %4 = arith.addi %arg0, %arg1 : i32 - ibis.sblock.return %4 : i32 + kanagawa.sblock.return %4 : i32 } cf.cond_br %cond, ^bb1(%a, %0 : i32, i32), ^bb2(%a, %0 : i32, i32) ^bb1(%11: i32, %21: i32): // pred: ^bb0 - %31 = ibis.sblock (%arg0 : i32 = %21, %arg1 : i32 = %11) -> i32 { + %31 = kanagawa.sblock (%arg0 : i32 = %21, %arg1 : i32 = %11) -> i32 { %4 = arith.subi %arg0, %arg1 : i32 - ibis.sblock.return %4 : i32 + kanagawa.sblock.return %4 : i32 } cf.br ^bb4(%31 : i32) ^bb2(%12 : i32, %22 : i32): - %32 = ibis.sblock (%arg0 : i32 = %22, %arg1 : i32 = %12) -> i32 { + %32 = kanagawa.sblock (%arg0 : i32 = %22, %arg1 : i32 = %12) -> i32 { %4 = "foo.op2"(%arg0, %arg1) : (i32, i32) -> i32 - ibis.sblock.return %4 : i32 + kanagawa.sblock.return %4 : i32 } cf.br ^bb4(%32 : i32) ^bb4(%res : i32): - ibis.return %res : i32 + kanagawa.return %res : i32 } } } diff --git a/test/Dialect/Kanagawa/Transforms/clean_selfdrivers.mlir b/test/Dialect/Kanagawa/Transforms/clean_selfdrivers.mlir new file mode 100644 index 000000000000..beb7d12ab284 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/clean_selfdrivers.mlir @@ -0,0 +1,85 @@ +// RUN: circt-opt --allow-unregistered-dialect --split-input-file --kanagawa-clean-selfdrivers %s | FileCheck %s + +kanagawa.design @D { +// CHECK-LABEL: kanagawa.container sym @C { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@C> +// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1 +// CHECK: %[[VAL_3:.*]] = kanagawa.port.output "out" sym @out : i1 +// CHECK: %[[VAL_2]] = hw.constant true +// CHECK: kanagawa.port.write %[[VAL_3]], %[[VAL_1]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 + %true = hw.constant 1 : i1 + kanagawa.port.write %in, %true : !kanagawa.portref + %v = kanagawa.port.read %in : !kanagawa.portref + kanagawa.port.write %out, %v : !kanagawa.portref +} + +} + +// ----- + +kanagawa.design @D { +// CHECK-LABEL: kanagawa.container sym @Selfdriver { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Selfdriver> +// CHECK: %[[VAL_1:.*]] = hw.wire %[[VAL_2:.*]] : i1 +// CHECK: %[[VAL_3:.*]] = kanagawa.port.output "myIn" sym @in : i1 +// CHECK: kanagawa.port.write %[[VAL_3]], %[[VAL_1]] : !kanagawa.portref +// CHECK: %[[VAL_2]] = hw.constant true +// CHECK: } + +// CHECK-LABEL: kanagawa.container sym @ParentReader { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@ParentReader> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @selfdriver, <@D::@Selfdriver> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@Selfdriver> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref +// CHECK: } + +kanagawa.container sym @Selfdriver { + %this = kanagawa.this <@D::@Selfdriver> + %in = kanagawa.port.input "myIn" sym @in : i1 + %true = hw.constant 1 : i1 + kanagawa.port.write %in, %true : !kanagawa.portref +} + +kanagawa.container sym @ParentReader { + %this = kanagawa.this <@D::@ParentReader> + %selfdriver = kanagawa.container.instance @selfdriver, <@D::@Selfdriver> + %in_ref = kanagawa.get_port %selfdriver, @in : !kanagawa.scoperef<@D::@Selfdriver> -> !kanagawa.portref + %in = kanagawa.port.read %in_ref : !kanagawa.portref +} + +} + +// ----- + +kanagawa.design @D { + +kanagawa.container sym @Foo { + %this = kanagawa.this <@D::@Foo> + %in = kanagawa.port.input "in" sym @in : i1 +} + +// CHECK-LABEL: kanagawa.container sym @ParentReaderWriter { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@ParentReaderWriter> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @f, <@D::@Foo> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@Foo> -> !kanagawa.portref +// CHECK: "foo.bar"(%[[VAL_3:.*]]) : (i1) -> () +// CHECK: %[[VAL_3]] = hw.constant true +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @ParentReaderWriter { + %this = kanagawa.this <@D::@ParentReaderWriter> + %f = kanagawa.container.instance @f, <@D::@Foo> + %in_wr_ref = kanagawa.get_port %f, @in : !kanagawa.scoperef<@D::@Foo> -> !kanagawa.portref + %in_rd_ref = kanagawa.get_port %f, @in : !kanagawa.scoperef<@D::@Foo> -> !kanagawa.portref + %v = kanagawa.port.read %in_rd_ref : !kanagawa.portref + "foo.bar"(%v) : (i1) -> () + %true = hw.constant 1 : i1 + kanagawa.port.write %in_wr_ref, %true : !kanagawa.portref +} + +} diff --git a/test/Dialect/Kanagawa/Transforms/containerize.mlir b/test/Dialect/Kanagawa/Transforms/containerize.mlir new file mode 100644 index 000000000000..a3aec6cc4047 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/containerize.mlir @@ -0,0 +1,38 @@ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa.design(kanagawa-containerize))' %s | FileCheck %s + +kanagawa.design @foo { + +// CHECK-LABEL: kanagawa.container sym @A_B +// CHECK-LABEL: kanagawa.container "MyClassName" sym @MyClass +// CHECK-LABEL: kanagawa.container sym @A_B_0 +// CHECK-LABEL: kanagawa.container sym @A_C +// CHECK-LABEL: kanagawa.container sym @A { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@A> +// CHECK: kanagawa.port.input "A_in" sym @A_in : i1 +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @myClass, <@foo::@MyClass> +// CHECK: %[[VAL_2:.*]] = kanagawa.container.instance @A_B_0, <@foo::@A_B_0> +// CHECK: %[[VAL_3:.*]] = kanagawa.container.instance @A_C, <@foo::@A_C> + +// This container will alias with the @B inside @A, and thus checks the +// name uniquing logic. +kanagawa.container sym @A_B { + %this = kanagawa.this <@foo::@A_B> +} + +kanagawa.class "MyClassName" sym @MyClass { + %this = kanagawa.this <@foo::@MyClass> +} + +kanagawa.class sym @A { + %this = kanagawa.this <@foo::@A> + kanagawa.port.input "A_in" sym @A_in : i1 + %myClass = kanagawa.instance @myClass, <@foo::@MyClass> + kanagawa.container sym @B { + %B_this = kanagawa.this <@foo::@B> + } + kanagawa.container sym @C { + %C_this = kanagawa.this <@foo::@C> + } +} + +} diff --git a/test/Dialect/Kanagawa/Transforms/containers_to_hw.mlir b/test/Dialect/Kanagawa/Transforms/containers_to_hw.mlir new file mode 100644 index 000000000000..ba1284fb45f5 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/containers_to_hw.mlir @@ -0,0 +1,178 @@ +// RUN: circt-opt --split-input-file --kanagawa-convert-containers-to-hw %s | FileCheck %s + +kanagawa.design @D { + +// CHECK: hw.module @D_MyB(in %in_foo : i1 {inputAttr}, out out_foo : i1 {outputAttr}) { +// CHECK: hw.output %in_foo : i1 +// CHECK: } +// CHECK: hw.module @D_AccessSibling(in %p_b_out_foo : i1, out p_b_in_foo : i1) { +// CHECK: hw.output %p_b_out_foo : i1 +// CHECK: } +// CHECK: hw.module @Parent() { +// CHECK: %a.p_b_in_foo = hw.instance "a" @D_AccessSibling(p_b_out_foo: %b.out_foo: i1) -> (p_b_in_foo: i1) +// CHECK: %b.out_foo = hw.instance "b" @D_MyB(in_foo: %a.p_b_in_foo: i1) -> (out_foo: i1) +// CHECK: hw.output +// CHECK: } + +kanagawa.container "MyB" sym @B { + %this = kanagawa.this <@D::@B> + // Test different port names vs. symbol names + %in = kanagawa.port.input "in_foo" sym @in : i1 {"inputAttr"} + %out = kanagawa.port.output "out_foo" sym @out : i1 {"outputAttr"} + + // Loopback. + %v = kanagawa.port.read %in : !kanagawa.portref + kanagawa.port.write %out, %v : !kanagawa.portref +} + +kanagawa.container sym @AccessSibling { + %this = kanagawa.this <@D::@AccessSibling> + %p_b_out = kanagawa.port.input "p_b_out_foo" sym @p_b_out : i1 + %p_b_in = kanagawa.port.output "p_b_in_foo" sym @p_b_in : i1 + kanagawa.port.write %p_b_in, %p_b_out.val : !kanagawa.portref + %p_b_out.val = kanagawa.port.read %p_b_out : !kanagawa.portref +} +kanagawa.container sym @Parent top_level { + %this = kanagawa.this <@D::@Parent> + %a = kanagawa.container.instance @a, <@D::@AccessSibling> + %a.p_b_out.ref = kanagawa.get_port %a, @p_b_out : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref + %b.out.ref.val = kanagawa.port.read %b.out.ref : !kanagawa.portref + kanagawa.port.write %a.p_b_out.ref, %b.out.ref.val : !kanagawa.portref + %a.p_b_in.ref = kanagawa.get_port %a, @p_b_in : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref + %a.p_b_in.ref.val = kanagawa.port.read %a.p_b_in.ref : !kanagawa.portref + kanagawa.port.write %b.in.ref, %a.p_b_in.ref.val : !kanagawa.portref + %b = kanagawa.container.instance @b, <@D::@B> + %b.out.ref = kanagawa.get_port %b, @out : !kanagawa.scoperef<@D::@B> -> !kanagawa.portref + %b.in.ref = kanagawa.get_port %b, @in : !kanagawa.scoperef<@D::@B> -> !kanagawa.portref +} + +} + +// ----- + +// Test that we can instantiate and get ports of a container from a hw.module. + +kanagawa.design @D { + +// CHECK: hw.module @D_C(in %in_foo : i1, out out_foo : i1) { +// CHECK: hw.output %in_foo : i1 +// CHECK: } +// CHECK: hw.module @Top() { +// CHECK: %c.out_foo = hw.instance "c" @D_C(in_foo: %c.out_foo: i1) -> (out_foo: i1) +// CHECK: hw.output +// CHECK: } + +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in_foo" sym @in : i1 + %out = kanagawa.port.output "out_foo" sym @out : i1 + %v = kanagawa.port.read %in : !kanagawa.portref + kanagawa.port.write %out, %v : !kanagawa.portref +} + +} + +hw.module @Top() { + %c = kanagawa.container.instance @c, <@D::@C> + %in = kanagawa.get_port %c, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %out = kanagawa.get_port %c, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %v = kanagawa.port.read %out : !kanagawa.portref + kanagawa.port.write %in, %v : !kanagawa.portref +} + +// ----- + +// Test that we can also move non-kanagawa ops + +kanagawa.design @D { + +// CHECK-LABEL: hw.module @D_Inst(out out : i1) { +// CHECK: %[[VAL_0:.*]] = hw.constant true +// CHECK: hw.output %[[VAL_0]] : i1 +// CHECK: } + +// CHECK-LABEL: hw.module @D_Top() { +// CHECK: %[[VAL_0:.*]] = hw.instance "myInst" @D_Inst() -> (out: i1) +// CHECK: %[[VAL_1:.*]] = hw.constant true +// CHECK: %[[VAL_2:.*]] = comb.and bin %[[VAL_1]], %[[VAL_0]] : i1 +// CHECK: hw.output +// CHECK: } + +kanagawa.container sym @Inst { + %this = kanagawa.this <@D::@Inst> + %out = kanagawa.port.output "out" sym @out : i1 + %true = hw.constant 1 : i1 + kanagawa.port.write %out, %true : !kanagawa.portref +} +kanagawa.container sym @Top { + %this = kanagawa.this <@D::@Top> + %myInst = kanagawa.container.instance @myInst, <@D::@Inst> + %true = hw.constant 1 : i1 + %out.ref = kanagawa.get_port %myInst, @out : !kanagawa.scoperef<@D::@Inst> -> !kanagawa.portref + %out.v = kanagawa.port.read %out.ref : !kanagawa.portref + %blake = comb.and bin %true, %out.v : i1 +} + +} + +// ----- + +// Test that we can unique duplicate port names. + +kanagawa.design @D { + +// CHECK: hw.module @D_Top(in %clk : i1, in %clk_0 : i1, out out : i1, out out_0 : i1) { +// CHECK: hw.output %clk, %clk_0 : i1, i1 +kanagawa.container sym @Top { + %this = kanagawa.this <@D::@Top> + %clk1 = kanagawa.port.input "clk" sym @clk1 : i1 + %clk2 = kanagawa.port.input "clk" sym @clk2 : i1 + %out1 = kanagawa.port.output "out" sym @out1 : i1 + %out2 = kanagawa.port.output "out" sym @out2 : i1 + + %v1 = kanagawa.port.read %clk1 : !kanagawa.portref + %v2 = kanagawa.port.read %clk2 : !kanagawa.portref + kanagawa.port.write %out1, %v1 : !kanagawa.portref + kanagawa.port.write %out2, %v2 : !kanagawa.portref +} +} + +// ----- + +// Test that we can de-alias module names. + +// CHECK: hw.module @D_Foo_0() { +// CHECK: hw.output +// CHECK: } +// CHECK: hw.module @Foo_0() { +// CHECK: hw.output +// CHECK: } +// CHECK: hw.module.extern @D_Foo(in %theExternModule : i1) +// CHECK: hw.module.extern @Foo(in %theExternModule : i1) + +kanagawa.design @D { + +kanagawa.container "Foo" sym @A { + %this = kanagawa.this <@D::@A> +} + +kanagawa.container "Foo" sym @B top_level { + %this = kanagawa.this <@D::@B> +} +} + +hw.module.extern @D_Foo(in %theExternModule : i1) +hw.module.extern @Foo(in %theExternModule : i1) + +// ----- + +// Test that containers with names that alias with the design op are not +// de-aliased. + +// CHECK: hw.module @D + +kanagawa.design @D { + kanagawa.container "D" sym @D top_level { + %this = kanagawa.this <@D::@D> + } +} diff --git a/test/Dialect/Kanagawa/Transforms/handshake_to_dc.mlir b/test/Dialect/Kanagawa/Transforms/handshake_to_dc.mlir new file mode 100644 index 000000000000..5a5809e57224 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/handshake_to_dc.mlir @@ -0,0 +1,33 @@ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa.design(kanagawa.class(kanagawa-convert-handshake-to-dc)))' %s | FileCheck %s + +// Actual handshake-to-dc conversion is tested in the respective pass tests. +// This file just tests the kanagawa-specific hooks. + +// CHECK-LABEL: kanagawa.class sym @ToDC { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@ToDC> +// CHECK: kanagawa.method.df @foo(%[[VAL_1:.*]]: !dc.value) -> !dc.value { +// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = dc.unpack %[[VAL_1]] : !dc.value +// CHECK: %[[VAL_4:.*]]:2 = dc.fork [2] %[[VAL_2]] +// CHECK: %[[VAL_5:.*]] = dc.pack %[[VAL_4]]#0, %[[VAL_3]] : i32 +// CHECK: %[[VAL_6:.*]] = dc.pack %[[VAL_4]]#1, %[[VAL_3]] : i32 +// CHECK: %[[VAL_7:.*]] = kanagawa.sblock.dc (%[[VAL_8:.*]] : !dc.value = %[[VAL_5]], %[[VAL_9:.*]] : !dc.value = %[[VAL_6]]) -> !dc.value { +// CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_8]], %[[VAL_9]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_10]] : i32 +// CHECK: } +// CHECK: kanagawa.return %[[VAL_7]] : !dc.value +// CHECK: } +// CHECK: } + +kanagawa.design @foo { +kanagawa.class sym @ToDC { + %this = kanagawa.this <@foo::@ToDC> + kanagawa.method.df @foo(%arg0: i32) -> (i32) { + %o0, %o1 = handshake.fork [2] %arg0 : i32 + %1 = kanagawa.sblock.isolated(%a0 : i32 = %o0, %a1 : i32 = %o1) -> i32 { + %res = arith.addi %a0, %a1 : i32 + kanagawa.sblock.return %res : i32 + } + kanagawa.return %1 : i32 + } +} +} diff --git a/test/Dialect/Kanagawa/Transforms/inline_sblocks.mlir b/test/Dialect/Kanagawa/Transforms/inline_sblocks.mlir new file mode 100644 index 000000000000..c93ba606fd53 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/inline_sblocks.mlir @@ -0,0 +1,64 @@ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa.design(kanagawa.class(kanagawa.method(kanagawa-inline-sblocks))))' \ +// RUN: --allow-unregistered-dialect %s | FileCheck %s + +kanagawa.design @foo { + +// CHECK-LABEL: kanagawa.class sym @Inline1 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@Inline1> +// CHECK: kanagawa.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () { +// CHECK: kanagawa.sblock.inline.begin {maxThreads = 1 : i64} +// CHECK: %[[VAL_3:.*]] = "foo.op1"(%[[VAL_1]], %[[VAL_2]]) : (i32, i32) -> i32 +// CHECK: kanagawa.sblock.inline.end +// CHECK: kanagawa.return +// CHECK: } +// CHECK: } +kanagawa.class sym @Inline1 { + %this = kanagawa.this <@foo::@Inline1> + + kanagawa.method @foo(%a : i32, %b : i32) { + %0 = kanagawa.sblock() -> (i32) attributes {maxThreads = 1} { + %res = "foo.op1"(%a, %b) : (i32, i32) -> i32 + kanagawa.sblock.return %res : i32 + } + kanagawa.return + } +} + +// CHECK-LABEL: kanagawa.class sym @Inline2 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@Inline2> +// CHECK: kanagawa.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> () { +// CHECK: "foo.unused1"() : () -> () +// CHECK: kanagawa.sblock.inline.begin {maxThreads = 1 : i64} +// CHECK: %[[VAL_3:.*]] = "foo.op1"(%[[VAL_1]], %[[VAL_2]]) : (i32, i32) -> i32 +// CHECK: kanagawa.sblock.inline.end +// CHECK: "foo.unused2"() : () -> () +// CHECK: cf.br ^bb1 +// CHECK: ^bb1: +// CHECK: "foo.unused3"() : () -> () +// CHECK: %[[VAL_4:.*]] = "foo.op2"(%[[VAL_3]], %[[VAL_1]]) : (i32, i32) -> i32 +// CHECK: "foo.unused4"() : () -> () +// CHECK: kanagawa.return +// CHECK: } +// CHECK: } +kanagawa.class sym @Inline2 { + %this = kanagawa.this <@foo::@Inline2> + kanagawa.method @foo(%a : i32, %b : i32) { + "foo.unused1"() : () -> () + %0 = kanagawa.sblock() -> (i32) attributes {maxThreads = 1} { + %res = "foo.op1"(%a, %b) : (i32, i32) -> i32 + kanagawa.sblock.return %res : i32 + } + "foo.unused2"() : () -> () + cf.br ^bb1 + ^bb1: + "foo.unused3"() : () -> () + %1 = kanagawa.sblock() -> (i32) { + %res = "foo.op2"(%0, %a) : (i32, i32) -> i32 + kanagawa.sblock.return %res : i32 + } + "foo.unused4"() : () -> () + kanagawa.return + } +} + +} diff --git a/test/Dialect/Kanagawa/Transforms/methods_to_containers.mlir b/test/Dialect/Kanagawa/Transforms/methods_to_containers.mlir new file mode 100644 index 000000000000..8d3661286eda --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/methods_to_containers.mlir @@ -0,0 +1,37 @@ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa.design(kanagawa.class(kanagawa-convert-methods-to-containers)))' %s | FileCheck %s + +// CHECK-LABEL: kanagawa.class sym @ToContainers { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@ToContainers> +// CHECK: kanagawa.container sym @foo { +// CHECK: %[[VAL_1:.*]] = kanagawa.this <@foo::@foo> +// CHECK: %[[VAL_2:.*]] = kanagawa.port.input "arg0" sym @arg0 : !dc.value +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref> +// CHECK: %[[VAL_4:.*]] = kanagawa.port.output "out0" sym @out0 : !dc.value +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_5:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]] = dc.unpack %[[VAL_3]] : !dc.value +// CHECK: %[[VAL_8:.*]]:2 = dc.fork [2] %[[VAL_6]] +// CHECK: %[[VAL_9:.*]] = dc.pack %[[VAL_8]]#0, %[[VAL_7]] : i32 +// CHECK: %[[VAL_10:.*]] = dc.pack %[[VAL_8]]#1, %[[VAL_7]] : i32 +// CHECK: %[[VAL_5]] = kanagawa.sblock.dc (%[[VAL_11:.*]] : !dc.value = %[[VAL_9]], %[[VAL_12:.*]] : !dc.value = %[[VAL_10]]) -> !dc.value { +// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_13]] : i32 +// CHECK: } +// CHECK: } +// CHECK: } + +kanagawa.design @foo { +kanagawa.class sym @ToContainers { + %this = kanagawa.this <@foo::@ToContainers> + kanagawa.method.df @foo(%arg0: !dc.value) -> !dc.value { + %token, %output = dc.unpack %arg0 : !dc.value + %0:2 = dc.fork [2] %token + %1 = dc.pack %0#0, %output : i32 + %2 = dc.pack %0#1, %output : i32 + %3 = kanagawa.sblock.dc (%arg1 : !dc.value = %1, %arg2 : !dc.value = %2) -> !dc.value { + %4 = arith.addi %arg1, %arg2 : i32 + kanagawa.sblock.return %4 : i32 + } + kanagawa.return %3 : !dc.value + } +} +} diff --git a/test/Dialect/Kanagawa/Transforms/path_end_to_end.mlir b/test/Dialect/Kanagawa/Transforms/path_end_to_end.mlir new file mode 100644 index 000000000000..b2ba6fdecda2 --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/path_end_to_end.mlir @@ -0,0 +1,73 @@ +// The ultimate tunneling test - by having 3 intermediate levels for both up- +// and downwards tunneling, we are sure test all the possible combinations of +// tunneling. This is more of a sanity check that everything works as expected. + +// RUN: circt-opt --split-input-file --kanagawa-tunneling \ +// RUN: --kanagawa-lower-portrefs --kanagawa-clean-selfdrivers \ +// RUN: --kanagawa-convert-containers-to-hw + +kanagawa.design @foo { +kanagawa.container sym @D_up { + %this = kanagawa.this <@foo::@D_up> + %d = kanagawa.path [ + #kanagawa.step, + #kanagawa.step, + #kanagawa.step, + #kanagawa.step, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step> : !kanagawa.scoperef<@D_down>] + // Write an input port + %clk_ref = kanagawa.get_port %d, @clk_in : !kanagawa.scoperef<@D_down> -> !kanagawa.portref + %clk = hw.constant 1 : i1 + kanagawa.port.write %clk_ref, %clk : !kanagawa.portref + + // Read an input port + %clk_ref_2 = kanagawa.get_port %d, @clk_in : !kanagawa.scoperef<@D_down> -> !kanagawa.portref + %clk_in_val = kanagawa.port.read %clk_ref_2 : !kanagawa.portref + + // Read an output port + %clk_out_ref = kanagawa.get_port %d, @clk_out : !kanagawa.scoperef<@D_down> -> !kanagawa.portref + %clk_out_val = kanagawa.port.read %clk_out_ref : !kanagawa.portref +} +kanagawa.container sym @C_up { + %this = kanagawa.this <@foo::@C_up> + %d = kanagawa.container.instance @d, @D_up +} +kanagawa.container sym @B_up { + %this = kanagawa.this <@foo::@B_up> + %c = kanagawa.container.instance @c, @C_up + +} + +kanagawa.container sym @A_up { + %this = kanagawa.this <@foo::@A_up> + %b = kanagawa.container.instance @b, @B_up +} + +kanagawa.container sym @Top { + %this = kanagawa.this <@foo::@Top> + %a_down = kanagawa.container.instance @a_down, @A_down + %a_up = kanagawa.container.instance @a_up, @A_up +} +kanagawa.container sym @A_down { + %this = kanagawa.this <@foo::@A_down> + %b = kanagawa.container.instance @b, @B_down +} +kanagawa.container sym @B_down { + %this = kanagawa.this <@foo::@B_down> + %c = kanagawa.container.instance @c, @C_down +} +kanagawa.container sym @C_down { + %this = kanagawa.this <@foo::@C_down> + %d = kanagawa.container.instance @d, @D_down +} +kanagawa.container sym @D_down { + %this = kanagawa.this <@foo::@D_down> + %clk = kanagawa.port.input "clk_in" sym @clk_in : i1 + %clk_out = kanagawa.port.output "clk_out" sym @clk_out : i1 + %clk.val = kanagawa.port.read %clk : !kanagawa.portref + kanagawa.port.write %clk_out, %clk.val : !kanagawa.portref +} +} diff --git a/test/Dialect/Kanagawa/Transforms/portref_lowering.mlir b/test/Dialect/Kanagawa/Transforms/portref_lowering.mlir new file mode 100644 index 000000000000..fc4e5700bbeb --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/portref_lowering.mlir @@ -0,0 +1,260 @@ +// RUN: circt-opt --split-input-file --kanagawa-lower-portrefs %s | FileCheck %s + +kanagawa.design @D { + +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// CHECK-LABEL: kanagawa.container sym @AccessSibling { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@AccessSibling> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "p_b_out" sym @p_b_out : i1 +// CHECK: %[[VAL_2:.*]] = kanagawa.port.output "p_b_in" sym @p_b_in : i1 +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref +// CHECK: %[[VAL_3]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @AccessSibling { + %this = kanagawa.this <@D::@AccessSibling> + %p_b_out = kanagawa.port.input "p_b_out" sym @p_b_out : !kanagawa.portref + %p_b_out_val = kanagawa.port.read %p_b_out : !kanagawa.portref> + %p_b_in = kanagawa.port.input "p_b_in" sym @p_b_in : !kanagawa.portref + %p_b_in_val = kanagawa.port.read %p_b_in : !kanagawa.portref> + + // Loopback to ensure that value replacement is performed. + %v = kanagawa.port.read %p_b_out_val : !kanagawa.portref + kanagawa.port.write %p_b_in_val, %v : !kanagawa.portref +} + +// CHECK-LABEL: kanagawa.container sym @Parent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Parent> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @a, <@D::@AccessSibling> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @p_b_out : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_4:.*]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3]] : !kanagawa.portref +// CHECK: %[[VAL_5:.*]] = kanagawa.get_port %[[VAL_1]], @p_b_in : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref +// CHECK: %[[VAL_6:.*]] = kanagawa.port.read %[[VAL_5]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_7:.*]], %[[VAL_6]] : !kanagawa.portref +// CHECK: %[[VAL_8:.*]] = kanagawa.container.instance @b, <@D::@C> +// CHECK: %[[VAL_4]] = kanagawa.get_port %[[VAL_8]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_7]] = kanagawa.get_port %[[VAL_8]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: } +kanagawa.container sym @Parent { + %this = kanagawa.this <@D::@Parent> + %a = kanagawa.container.instance @a, <@D::@AccessSibling> + %a.p_b_out = kanagawa.get_port %a, @p_b_out : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref> + kanagawa.port.write %a.p_b_out, %b.out : !kanagawa.portref> + %a.p_b_in = kanagawa.get_port %a, @p_b_in : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref> + kanagawa.port.write %a.p_b_in, %b.in : !kanagawa.portref> + %b = kanagawa.container.instance @b, <@D::@C> + %b.out = kanagawa.get_port %b, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %b.in = kanagawa.get_port %b, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +} + +} + +// ----- + +kanagawa.design @D { + + +// CHECK-LABEL: kanagawa.container sym @ParentPortAccess { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@ParentPortAccess> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.output "p_in" sym @p_in : i1 +// CHECK: %[[VAL_2:.*]] = kanagawa.port.input "p_out" sym @p_out : i1 +// CHECK: } +kanagawa.container sym @ParentPortAccess { + %this = kanagawa.this <@D::@ParentPortAccess> + %p_in = kanagawa.port.input "p_in" sym @p_in : !kanagawa.portref + %p_in_val = kanagawa.port.read %p_in : !kanagawa.portref> + %p_out = kanagawa.port.input "p_out" sym @p_out : !kanagawa.portref + %p_out_val = kanagawa.port.read %p_out : !kanagawa.portref> +} + +// CHECK-LABEL: kanagawa.container sym @Parent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Parent> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c, <@D::@ParentPortAccess> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @p_in : !kanagawa.scoperef<@D::@ParentPortAccess> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_4:.*]], %[[VAL_3]] : !kanagawa.portref +// CHECK: %[[VAL_5:.*]] = kanagawa.get_port %[[VAL_1]], @p_out : !kanagawa.scoperef<@D::@ParentPortAccess> -> !kanagawa.portref +// CHECK: %[[VAL_6:.*]] = kanagawa.port.read %[[VAL_7:.*]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_5]], %[[VAL_6]] : !kanagawa.portref +// CHECK: %[[VAL_4]] = kanagawa.port.input "in" sym @in : i1 +// CHECK: %[[VAL_7]] = kanagawa.port.output "out" sym @out : i1 +// CHECK: } +kanagawa.container sym @Parent { + %this = kanagawa.this <@D::@Parent> + %c = kanagawa.container.instance @c, <@D::@ParentPortAccess> + %c.p_in = kanagawa.get_port %c, @p_in : !kanagawa.scoperef<@D::@ParentPortAccess> -> !kanagawa.portref> + kanagawa.port.write %c.p_in, %in : !kanagawa.portref> + %c.p_out = kanagawa.get_port %c, @p_out : !kanagawa.scoperef<@D::@ParentPortAccess> -> !kanagawa.portref> + kanagawa.port.write %c.p_out, %out : !kanagawa.portref> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +} + +// ----- + +kanagawa.design @D { + + +// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child + +// CHECK-LABEL: kanagawa.container sym @C1 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@C1> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 +// CHECK: kanagawa.port.write %[[VAL_1]], %[[VAL_2:.*]] : !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 +// CHECK: %[[VAL_2]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @C1 { + %this = kanagawa.this <@D::@C1> + %parent_parent_c2_c3_in = kanagawa.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !kanagawa.portref + %parent_parent_c2_c3_out = kanagawa.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !kanagawa.portref + + // Assignment drivers - unwrap the ports and roundtrip read-write. + %parent_b_in_unwrapped = kanagawa.port.read %parent_parent_c2_c3_in : !kanagawa.portref> + %parent_b_out_unwrapped = kanagawa.port.read %parent_parent_c2_c3_out : !kanagawa.portref> + %parent_b_out_value = kanagawa.port.read %parent_b_out_unwrapped : !kanagawa.portref + kanagawa.port.write %parent_b_in_unwrapped, %parent_b_out_value : !kanagawa.portref +} + +// CHECK-LABEL: kanagawa.container sym @C2 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@C2> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c3, <@D::@C> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 +// CHECK: %[[VAL_5:.*]] = kanagawa.port.read %[[VAL_4]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_5]] : !kanagawa.portref +// CHECK: %[[VAL_6:.*]] = kanagawa.port.output "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 +// CHECK: %[[VAL_7:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_6]], %[[VAL_7]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @C2 { + %this = kanagawa.this <@D::@C2> + %c3 = kanagawa.container.instance @c3, <@D::@C> + %c3.in = kanagawa.get_port %c3, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %c3.out = kanagawa.get_port %c3, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %parent_parent_c2_c3_in = kanagawa.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !kanagawa.portref + %parent_parent_c2_c3_out = kanagawa.port.output "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !kanagawa.portref + kanagawa.port.write %parent_parent_c2_c3_in, %c3.in : !kanagawa.portref> + kanagawa.port.write %parent_parent_c2_c3_out, %c3.out : !kanagawa.portref> +} +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// CHECK-LABEL: kanagawa.container sym @P1 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@P1> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c1, <@D::@C1> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.get_port %[[VAL_1]], @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref +// CHECK: %[[VAL_5:.*]] = kanagawa.port.read %[[VAL_6:.*]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_5]] : !kanagawa.portref +// CHECK: %[[VAL_7:.*]] = kanagawa.port.output "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : i1 +// CHECK: kanagawa.port.write %[[VAL_7]], %[[VAL_3]] : !kanagawa.portref +// CHECK: %[[VAL_6]] = kanagawa.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : i1 +// CHECK: } +kanagawa.container sym @P1 { + %this = kanagawa.this <@D::@P1> + %c1 = kanagawa.container.instance @c1, <@D::@C1> + %c1.parent_parent_c2_c3_in = kanagawa.get_port %c1, @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref> + kanagawa.port.write %c1.parent_parent_c2_c3_in, %0 : !kanagawa.portref> + %c1.parent_parent_c2_c3_out = kanagawa.get_port %c1, @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref> + kanagawa.port.write %c1.parent_parent_c2_c3_out, %1 : !kanagawa.portref> + %parent_parent_c2_c3_in = kanagawa.port.input "parent_parent_c2_c3_in" sym @parent_parent_c2_c3_in : !kanagawa.portref + %0 = kanagawa.port.read %parent_parent_c2_c3_in : !kanagawa.portref> + %parent_parent_c2_c3_out = kanagawa.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !kanagawa.portref + %1 = kanagawa.port.read %parent_parent_c2_c3_out : !kanagawa.portref> +} + +// CHECK-LABEL: kanagawa.container sym @P2 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@P2> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @p1, <@D::@P1> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_4:.*]], %[[VAL_3]] : !kanagawa.portref +// CHECK: %[[VAL_5:.*]] = kanagawa.get_port %[[VAL_1]], @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref +// CHECK: %[[VAL_6:.*]] = kanagawa.port.read %[[VAL_7:.*]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_5]], %[[VAL_6]] : !kanagawa.portref +// CHECK: %[[VAL_8:.*]] = kanagawa.container.instance @c2, <@D::@C2> +// CHECK: %[[VAL_7]] = kanagawa.get_port %[[VAL_8]], @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref +// CHECK: %[[VAL_4]] = kanagawa.port.input "parent_parent_c2_c3_in_fw" sym @parent_parent_c2_c3_in_fw : i1 +// CHECK: %[[VAL_9:.*]] = kanagawa.port.read %[[VAL_4]] : !kanagawa.portref +// CHECK: %[[VAL_10:.*]] = kanagawa.get_port %[[VAL_8]], @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_10]], %[[VAL_9]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @P2 { + %this = kanagawa.this <@D::@P2> + %p1 = kanagawa.container.instance @p1, <@D::@P1> + %p1.parent_parent_c2_c3_in = kanagawa.get_port %p1, @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref> + kanagawa.port.write %p1.parent_parent_c2_c3_in, %1 : !kanagawa.portref> + %p1.parent_parent_c2_c3_out = kanagawa.get_port %p1, @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref> + kanagawa.port.write %p1.parent_parent_c2_c3_out, %0 : !kanagawa.portref> + %c2 = kanagawa.container.instance @c2, <@D::@C2> + %c2.parent_parent_c2_c3_out = kanagawa.get_port %c2, @parent_parent_c2_c3_out : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref> + %0 = kanagawa.port.read %c2.parent_parent_c2_c3_out : !kanagawa.portref> + %c2.parent_parent_c2_c3_in = kanagawa.get_port %c2, @parent_parent_c2_c3_in : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref> + %1 = kanagawa.port.read %c2.parent_parent_c2_c3_in : !kanagawa.portref> +} + +} + +// ----- + +kanagawa.design @D { + + +// CHECK-LABEL: kanagawa.container sym @AccessParent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@AccessParent> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.output "p_out" sym @p_out : i1 +// CHECK: %[[VAL_2:.*]] = kanagawa.port.input "p_in" sym @p_in : i1 +// CHECK: } +kanagawa.container sym @AccessParent { + %this = kanagawa.this <@D::@AccessParent> + %p_out = kanagawa.port.input "p_out" sym @p_out : !kanagawa.portref + %p_out.val = kanagawa.port.read %p_out : !kanagawa.portref> + %p_in = kanagawa.port.input "p_in" sym @p_in : !kanagawa.portref + %p_in.val = kanagawa.port.read %p_in : !kanagawa.portref> +} + +// CHECK-LABEL: kanagawa.container sym @Parent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Parent> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "in" sym @in : i1 +// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.wire.output @in.rd, %[[VAL_2]] : i1 +// CHECK: %[[VAL_4:.*]] = kanagawa.port.output "out" sym @out : i1 +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = kanagawa.wire.input @out.wr : i1 +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_6]] : !kanagawa.portref +// CHECK: %[[VAL_7:.*]] = kanagawa.container.instance @c, <@D::@AccessParent> +// CHECK: %[[VAL_8:.*]] = kanagawa.get_port %[[VAL_7]], @p_out : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref +// CHECK: %[[VAL_9:.*]] = kanagawa.port.read %[[VAL_8]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_5]], %[[VAL_9]] : !kanagawa.portref +// CHECK: %[[VAL_10:.*]] = kanagawa.get_port %[[VAL_7]], @p_in : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref +// CHECK: %[[VAL_11:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_10]], %[[VAL_11]] : !kanagawa.portref +// CHECK: } +kanagawa.container sym @Parent { + %this = kanagawa.this <@D::@Parent> + %in = kanagawa.port.input "in" sym @in : i1 + %in.val = kanagawa.port.read %in : !kanagawa.portref + %in.rd = kanagawa.wire.output @in.rd, %in.val : i1 + %out = kanagawa.port.output "out" sym @out : i1 + %out.wr, %out.wr.out = kanagawa.wire.input @out.wr : i1 + kanagawa.port.write %out, %out.wr.out : !kanagawa.portref + %c = kanagawa.container.instance @c, <@D::@AccessParent> + %c.p_out.ref = kanagawa.get_port %c, @p_out : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref> + kanagawa.port.write %c.p_out.ref, %out.wr : !kanagawa.portref> + %c.p_in.ref = kanagawa.get_port %c, @p_in : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref> + kanagawa.port.write %c.p_in.ref, %in.rd : !kanagawa.portref> +} + +} diff --git a/test/Dialect/Kanagawa/Transforms/prepare_scheduling.mlir b/test/Dialect/Kanagawa/Transforms/prepare_scheduling.mlir new file mode 100644 index 000000000000..aa6f665ea43a --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/prepare_scheduling.mlir @@ -0,0 +1,29 @@ +// RUN: circt-opt --pass-pipeline="builtin.module(kanagawa.design(kanagawa.class(kanagawa.method.df(kanagawa.sblock.isolated(kanagawa-prepare-scheduling)))))" \ +// RUN: --allow-unregistered-dialect %s | FileCheck %s + +// CHECK: kanagawa.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> (i32, i32) { +// CHECK: %[[VAL_3:.*]]:2 = kanagawa.sblock.isolated (%[[VAL_4:.*]] : i32 = %[[VAL_1]], %[[VAL_5:.*]] : i32 = %[[VAL_2]]) -> (i32, i32) { +// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]] = kanagawa.pipeline.header +// CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]], %[[VAL_12:.*]] = pipeline.unscheduled(%[[VAL_13:.*]] : i32 = %[[VAL_4]], %[[VAL_14:.*]] : i32 = %[[VAL_5]]) stall(%[[VAL_9]]) clock(%[[VAL_6]]) reset(%[[VAL_7]]) go(%[[VAL_8]]) entryEn(%[[VAL_15:.*]]) {operator_lib = @kanagawa_operator_library} -> (out0 : i32, out1 : i32) { +// CHECK: %[[VAL_16:.*]] = "foo.op1"(%[[VAL_13]], %[[VAL_14]]) {ssp.operator_type = @foo.op1} : (i32, i32) -> i32 +// CHECK: pipeline.return %[[VAL_16]], %[[VAL_13]] : i32, i32 +// CHECK: } +// CHECK: kanagawa.sblock.return %[[VAL_17:.*]], %[[VAL_18:.*]] : i32, i32 +// CHECK: } + +kanagawa.design @foo { +kanagawa.class sym @PrepareScheduling { + %this = kanagawa.this <@foo::@PrepareScheduling> + // A test wherein the returned values are either a value generated by an + // operation in the pipeline, or a value that's passed through the pipeline. + // The resulting IR should have all values passing through the newly created + // pipeline. + kanagawa.method.df @foo(%a: i32, %b: i32) -> (i32, i32) { + %0, %1 = kanagawa.sblock.isolated (%arg0 : i32 = %a, %arg1 : i32 = %b) -> (i32, i32) { + %4 = "foo.op1"(%arg0, %arg1) : (i32, i32) -> i32 + kanagawa.sblock.return %4, %arg0 : i32, i32 + } + kanagawa.return %0, %1 : i32, i32 + } +} +} diff --git a/test/Dialect/Kanagawa/Transforms/reblock.mlir b/test/Dialect/Kanagawa/Transforms/reblock.mlir new file mode 100644 index 000000000000..75764a1d902d --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/reblock.mlir @@ -0,0 +1,48 @@ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa.design(kanagawa.class(kanagawa.method(kanagawa-reblock))))' %s | FileCheck %s + +// CHECK-LABEL: kanagawa.class sym @Reblock { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@Reblock> +// CHECK: kanagawa.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 { +// CHECK: %[[VAL_3:.*]] = kanagawa.sblock () -> i32 { +// CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_1]], %[[VAL_2]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_4]] : i32 +// CHECK: } +// CHECK: %[[VAL_5:.*]] = kanagawa.sblock () -> i32 attributes {maxThreads = 2 : i64} { +// CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : i32 +// CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_7]] : i32 +// CHECK: } +// CHECK: %[[VAL_8:.*]] = kanagawa.sblock () -> i32 { +// CHECK: %[[VAL_9:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_9]] : i32 +// CHECK: } +// CHECK: cf.br ^bb1(%[[VAL_8]] : i32) +// CHECK: ^bb1(%[[VAL_10:.*]]: i32): +// CHECK: %[[VAL_11:.*]] = kanagawa.sblock () -> i32 { +// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_10]], %[[VAL_8]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_12]] : i32 +// CHECK: } +// CHECK: kanagawa.return %[[VAL_11]] : i32 +// CHECK: } +// CHECK: } + +kanagawa.design @foo { +kanagawa.class sym @Reblock { + %this = kanagawa.this <@foo::@Reblock> + + kanagawa.method @foo(%arg0 : i32, %arg1 : i32) -> i32 { + %0 = arith.addi %arg0, %arg1 : i32 + kanagawa.sblock.inline.begin {maxThreads = 2} + %inner = arith.addi %0, %arg1 : i32 + %1 = arith.addi %inner, %arg1 : i32 + kanagawa.sblock.inline.end + %2 = arith.addi %1, %arg1 : i32 + // %0 is used within the same MLIR block but outside the scope. + cf.br ^bb1(%2 : i32) + ^bb1(%barg : i32): + %3 = arith.addi %barg, %2 : i32 + // %1 is used in a different MLIR block (dominated by the sblock parent block). + kanagawa.return %3 : i32 + } +} +} diff --git a/test/Dialect/Ibis/Transforms/schedule_pipeline.mlir b/test/Dialect/Kanagawa/Transforms/schedule_pipeline.mlir similarity index 69% rename from test/Dialect/Ibis/Transforms/schedule_pipeline.mlir rename to test/Dialect/Kanagawa/Transforms/schedule_pipeline.mlir index 44bf753d95cf..a84b3536ac97 100644 --- a/test/Dialect/Ibis/Transforms/schedule_pipeline.mlir +++ b/test/Dialect/Kanagawa/Transforms/schedule_pipeline.mlir @@ -1,7 +1,7 @@ -// RUN: circt-opt --pass-pipeline='builtin.module(ibis-add-operator-library, ibis.design(ibis.class(ibis.method.df(ibis.sblock.isolated(pipeline-schedule-linear)))))' %s | \ +// RUN: circt-opt --pass-pipeline='builtin.module(kanagawa-add-operator-library, kanagawa.design(kanagawa.class(kanagawa.method.df(kanagawa.sblock.isolated(pipeline-schedule-linear)))))' %s | \ // RUN: FileCheck %s -// CHECK-LABEL: ssp.library @ibis_operator_library { +// CHECK-LABEL: ssp.library @kanagawa_operator_library { // CHECK: operator_type @comb.add [latency<1>] // CHECK: operator_type @comb.sub [latency<1>] // CHECK: operator_type @comb.mul [latency<2>] @@ -16,11 +16,11 @@ // CHECK: operator_type @comb.shrs [latency<1>] // CHECK: } -// CHECK-LABEL: ibis.class sym @SchedulePipeline { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@SchedulePipeline> -// CHECK: ibis.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 { -// CHECK: %[[VAL_3:.*]] = ibis.sblock.isolated (%[[VAL_4:.*]] : i32 = %[[VAL_1]], %[[VAL_5:.*]] : i32 = %[[VAL_2]]) -> i32 { -// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]] = ibis.pipeline.header +// CHECK-LABEL: kanagawa.class sym @SchedulePipeline { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@SchedulePipeline> +// CHECK: kanagawa.method.df @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32) -> i32 { +// CHECK: %[[VAL_3:.*]] = kanagawa.sblock.isolated (%[[VAL_4:.*]] : i32 = %[[VAL_1]], %[[VAL_5:.*]] : i32 = %[[VAL_2]]) -> i32 { +// CHECK: %[[VAL_6:.*]], %[[VAL_7:.*]], %[[VAL_8:.*]], %[[VAL_9:.*]] = kanagawa.pipeline.header // CHECK: %[[VAL_10:.*]], %[[VAL_11:.*]] = pipeline.scheduled(%[[VAL_12:.*]] : i32 = %[[VAL_4]], %[[VAL_13:.*]] : i32 = %[[VAL_5]]) stall(%[[VAL_9]]) clock(%[[VAL_6]]) reset(%[[VAL_7]]) go(%[[VAL_8]]) entryEn(%[[VAL_14:.*]]) -> (out0 : i32) { // CHECK: %[[VAL_15:.*]] = comb.mul %[[VAL_12]], %[[VAL_13]] {ssp.operator_type = @comb.mul} : i32 // CHECK: pipeline.stage ^bb1 @@ -38,32 +38,32 @@ // CHECK: ^bb5(%[[VAL_23:.*]]: i1): // CHECK: pipeline.return %[[VAL_21]] : i32 // CHECK: } -// CHECK: ibis.sblock.return %[[VAL_24:.*]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_24:.*]] : i32 // CHECK: } -// CHECK: ibis.return %[[VAL_3]] : i32 +// CHECK: kanagawa.return %[[VAL_3]] : i32 // CHECK: } // CHECK: } -ibis.design @foo { -ibis.class sym @SchedulePipeline { - %this = ibis.this <@foo::@SchedulePipeline> +kanagawa.design @foo { +kanagawa.class sym @SchedulePipeline { + %this = kanagawa.this <@foo::@SchedulePipeline> // A test wherein the returned values are either a value generated by an // operation in the pipeline, or a value that's passed through the pipeline. // The resulting IR should have all values passing through the newly created // pipeline. - ibis.method.df @foo(%a: i32, %b: i32) -> (i32) { - %0 = ibis.sblock.isolated (%arg2 : i32 = %a, %arg3 : i32 = %b) -> i32 { - %clock, %reset, %go, %stall = ibis.pipeline.header - %out0, %done = pipeline.unscheduled(%in0 : i32 = %arg2, %in1 : i32 = %arg3) stall(%stall) clock(%clock) reset(%reset) go(%go) entryEn(%s0_enable) {operator_lib = @ibis_operator_library} -> (out0 : i32) { + kanagawa.method.df @foo(%a: i32, %b: i32) -> (i32) { + %0 = kanagawa.sblock.isolated (%arg2 : i32 = %a, %arg3 : i32 = %b) -> i32 { + %clock, %reset, %go, %stall = kanagawa.pipeline.header + %out0, %done = pipeline.unscheduled(%in0 : i32 = %arg2, %in1 : i32 = %arg3) stall(%stall) clock(%clock) reset(%reset) go(%go) entryEn(%s0_enable) {operator_lib = @kanagawa_operator_library} -> (out0 : i32) { %1 = comb.add %in0, %in1 {ssp.operator_type = @comb.add} : i32 %2 = comb.mul %in0, %in1 {ssp.operator_type = @comb.mul} : i32 %3 = comb.sub %1, %2 {ssp.operator_type = @comb.sub} : i32 %4 = comb.mul %3, %1 {ssp.operator_type = @comb.mul} : i32 pipeline.return %4 : i32 } - ibis.sblock.return %out0 : i32 + kanagawa.sblock.return %out0 : i32 } - ibis.return %0 : i32 + kanagawa.return %0 : i32 } } } diff --git a/test/Dialect/Kanagawa/Transforms/scoperef_tunneling.mlir b/test/Dialect/Kanagawa/Transforms/scoperef_tunneling.mlir new file mode 100644 index 000000000000..99d13094db0c --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/scoperef_tunneling.mlir @@ -0,0 +1,314 @@ +// RUN: circt-opt --split-input-file --kanagawa-tunneling %s | FileCheck %s + +kanagawa.design @D { + +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// CHECK-LABEL: kanagawa.container sym @AccessChild { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@AccessChild> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c, <@D::@C> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK-NEXT: } + +kanagawa.container sym @AccessChild { + %this = kanagawa.this <@D::@AccessChild> + %c = kanagawa.container.instance @c, <@D::@C> + %c_ref = kanagawa.path [ + #kanagawa.step> + ] + %c_in = kanagawa.get_port %c_ref, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %c_out = kanagawa.get_port %c_ref, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +} + +} + +// ----- +// CHECK-LABEL: // ----- + +kanagawa.design @D { +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// CHECK-LABEL: kanagawa.container sym @AccessSibling { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@AccessSibling> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "[[VAL_1]]" sym @[[VAL_1]] : !kanagawa.portref +// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref> +// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "[[VAL_3]]" sym @[[VAL_3]] : !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @AccessSibling { + %this = kanagawa.this <@D::@AccessSibling> + %sibling = kanagawa.path [ + #kanagawa.step, + #kanagawa.step> + ] + %c_in = kanagawa.get_port %sibling, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %c_out = kanagawa.get_port %sibling, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +} + +// CHECK-LABEL: kanagawa.container sym @Parent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Parent> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @a, <@D::@AccessSibling> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @p_b_out.rd : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_4:.*]] = kanagawa.get_port %[[VAL_1]], @p_b_in.wr : !kanagawa.scoperef<@D::@AccessSibling> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_5:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_6:.*]] = kanagawa.container.instance @b, <@D::@C> +// CHECK: %[[VAL_3]] = kanagawa.get_port %[[VAL_6]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_5]] = kanagawa.get_port %[[VAL_6]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: } +kanagawa.container sym @Parent { + %this = kanagawa.this <@D::@Parent> + %a = kanagawa.container.instance @a, <@D::@AccessSibling> + %b = kanagawa.container.instance @b, <@D::@C> +} + +} + +// ----- +// CHECK-LABEL: // ----- + +// "Full"/recursive case. +// C1 child -> P1 parent -> P2 parent -> C2 child -> C3 child + +kanagawa.design @D { +// CHECK-LABEL: kanagawa.container sym @C1 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@C1> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !kanagawa.portref +// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref> +// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @C1 { + %this = kanagawa.this <@D::@C1> + %c3 = kanagawa.path [ + #kanagawa.step, + #kanagawa.step, + #kanagawa.step, + #kanagawa.step> + ] + %c_in = kanagawa.get_port %c3, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %c_out = kanagawa.get_port %c3, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +} + +// CHECK-LABEL: kanagawa.container sym @C2 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@C2> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c3, <@D::@C> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.port.output "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !kanagawa.portref +// CHECK: %[[VAL_5:.*]] = kanagawa.port.output "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !kanagawa.portref +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_2]] : !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_5]], %[[VAL_3]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @C2 { + %this = kanagawa.this <@D::@C2> + %c3 = kanagawa.container.instance @c3, <@D::@C> +} + +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// CHECK-LABEL: kanagawa.container sym @P1 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@P1> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c1, <@D::@C1> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_4:.*]] = kanagawa.get_port %[[VAL_1]], @p_p_c2_c3_in.wr : !kanagawa.scoperef<@D::@C1> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_5:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_6:.*]] = kanagawa.port.input "p_p_c2_c3_out.rd" sym @p_p_c2_c3_out.rd : !kanagawa.portref +// CHECK: %[[VAL_3]] = kanagawa.port.read %[[VAL_6]] : !kanagawa.portref> +// CHECK: %[[VAL_7:.*]] = kanagawa.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !kanagawa.portref +// CHECK: %[[VAL_5]] = kanagawa.port.read %[[VAL_7]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @P1 { + %this = kanagawa.this <@D::@P1> + %c1 = kanagawa.container.instance @c1, <@D::@C1> +} + +// CHECK-LABEL: kanagawa.container sym @P2 { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@P2> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @p1, <@D::@P1> +// CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_1]], @p_p_c2_c3_out.rd : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_4:.*]] = kanagawa.get_port %[[VAL_1]], @p_p_c2_c3_in.wr : !kanagawa.scoperef<@D::@P1> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_5:.*]] : !kanagawa.portref> +// CHECK: %[[VAL_6:.*]] = kanagawa.container.instance @c2, <@D::@C2> +// CHECK: %[[VAL_7:.*]] = kanagawa.get_port %[[VAL_6]], @p_p_c2_c3_in.wr : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref> +// CHECK: %[[VAL_5]] = kanagawa.port.read %[[VAL_7]] : !kanagawa.portref> +// CHECK: %[[VAL_8:.*]] = kanagawa.get_port %[[VAL_6]], @p_p_c2_c3_out.rd : !kanagawa.scoperef<@D::@C2> -> !kanagawa.portref> +// CHECK: %[[VAL_3]] = kanagawa.port.read %[[VAL_8]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @P2 { + %this = kanagawa.this <@D::@P2> + %p1 = kanagawa.container.instance @p1, <@D::@P1> + %c2 = kanagawa.container.instance @c2, <@D::@C2> +} + +} + +// ----- +// CHECK-LABEL: // ----- + +kanagawa.design @D { +// CHECK-LABEL: kanagawa.container sym @AccessParent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@AccessParent> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "p_out.wr" sym @p_out.wr : !kanagawa.portref +// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref> +// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "p_in.rd" sym @p_in.rd : !kanagawa.portref +// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @AccessParent { + %this = kanagawa.this <@D::@AccessParent> + %p = kanagawa.path [ + #kanagawa.step> + ] + + // get_port states the intended usage of the port. Hence we should be able to + // request a parent input port as an output port (readable), and vice versa. + // This will insert wires in the target container to facilitate the direction + // flip. + %p_in_ref = kanagawa.get_port %p, @in : !kanagawa.scoperef<@D::@Parent> -> !kanagawa.portref + %p_out_ref = kanagawa.get_port %p, @out : !kanagawa.scoperef<@D::@Parent> -> !kanagawa.portref +} + +// CHECK-LABEL: kanagawa.container sym @Parent { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@D::@Parent> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "in" sym @in : i1 +// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref +// CHECK: %[[VAL_3:.*]] = kanagawa.wire.output @in.rd, %[[VAL_2]] : i1 +// CHECK: %[[VAL_4:.*]] = kanagawa.port.output "out" sym @out : i1 +// CHECK: %[[VAL_5:.*]], %[[VAL_6:.*]] = kanagawa.wire.input @out.wr : i1 +// CHECK: kanagawa.port.write %[[VAL_4]], %[[VAL_6]] : !kanagawa.portref +// CHECK: %[[VAL_7:.*]] = kanagawa.container.instance @c, <@D::@AccessParent> +// CHECK: %[[VAL_8:.*]] = kanagawa.get_port %[[VAL_7]], @p_out.wr : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_8]], %[[VAL_5]] : !kanagawa.portref> +// CHECK: %[[VAL_9:.*]] = kanagawa.get_port %[[VAL_7]], @p_in.rd : !kanagawa.scoperef<@D::@AccessParent> -> !kanagawa.portref> +// CHECK: kanagawa.port.write %[[VAL_9]], %[[VAL_3]] : !kanagawa.portref> +// CHECK: } +kanagawa.container sym @Parent { + %this = kanagawa.this <@D::@Parent> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 + %c = kanagawa.container.instance @c, <@D::@AccessParent> +} + +} + +// ----- +// CHECK-LABEL: // ----- + +kanagawa.design @D { + +kanagawa.container sym @C { + %this = kanagawa.this <@D::@C> + %in = kanagawa.port.input "in" sym @in : i1 + %out = kanagawa.port.output "out" sym @out : i1 +} + +// TODO: support this case. Too hard to support now. Problem is that hw.module +// cannot live within an kanagawa.design, but we need to run this pass on the +// kanagawa.design op. I don't think it's critical that we support this case currently. + +// COM: CHECK-LABEL: hw.module @AccessChildFromHW() { +// COM: CHECK: %[[VAL_0:.*]] = kanagawa.container.instance @c, <@D::@C> +// COM: CHECK: %[[VAL_1:.*]] = kanagawa.get_port %[[VAL_0]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// COM: CHECK: %[[VAL_2:.*]] = kanagawa.get_port %[[VAL_0]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +// COM: CHECK: hw.output +// COM: CHECK: } + +} + +hw.module @AccessChildFromHW() { + %c = kanagawa.container.instance @c, <@D::@C> + %c_ref = kanagawa.path [ + #kanagawa.step> + ] + %c_in = kanagawa.get_port %c_ref, @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref + %c_out = kanagawa.get_port %c_ref, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref +} + + +// ----- +// CHECK-LABEL: // ----- + +kanagawa.design @D { +// The ultimate tunneling test - by having 3 intermediate levels for both up- +// and downwards tunneling, we are sure test all the possible combinations of +// tunneling. + +kanagawa.container sym @D_up { + %this = kanagawa.this <@D::@D_up> + %d = kanagawa.path [ + #kanagawa.step, + #kanagawa.step, + #kanagawa.step, + #kanagawa.step, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step : !kanagawa.scoperef, + #kanagawa.step> : !kanagawa.scoperef<@D::@D_down>] + // Write an input port + %clk_ref = kanagawa.get_port %d, @clk_in : !kanagawa.scoperef<@D::@D_down> -> !kanagawa.portref + %clk = hw.constant 1 : i1 + kanagawa.port.write %clk_ref, %clk : !kanagawa.portref + + // Read an input port + %clk_ref_2 = kanagawa.get_port %d, @clk_in : !kanagawa.scoperef<@D::@D_down> -> !kanagawa.portref + %clk_in_val = kanagawa.port.read %clk_ref_2 : !kanagawa.portref + + // Read an output port + %clk_out_ref = kanagawa.get_port %d, @clk_out : !kanagawa.scoperef<@D::@D_down> -> !kanagawa.portref + %clk_out_val = kanagawa.port.read %clk_out_ref : !kanagawa.portref +} +kanagawa.container sym @C_up { + %this = kanagawa.this <@D::@C_up> + %d = kanagawa.container.instance @d, <@D::@D_up> +} +kanagawa.container sym @B_up { + %this = kanagawa.this <@D::@B_up> + %c = kanagawa.container.instance @c, <@D::@C_up> + +} + +kanagawa.container sym @A_up { + %this = kanagawa.this <@D::@A_up> + %b = kanagawa.container.instance @b, <@D::@B_up> +} + +kanagawa.container sym @Top { + %this = kanagawa.this <@D::@Top> + %a_down = kanagawa.container.instance @a_down, <@D::@A_down> + %a_up = kanagawa.container.instance @a_up, <@D::@A_up> +} +kanagawa.container sym @A_down { + %this = kanagawa.this <@D::@A_down> + %b = kanagawa.container.instance @b, <@D::@B_down> +} +kanagawa.container sym @B_down { + %this = kanagawa.this <@D::@B_down> + %c = kanagawa.container.instance @c, <@D::@C_down> +} +kanagawa.container sym @C_down { + %this = kanagawa.this <@D::@C_down> + %d = kanagawa.container.instance @d, <@D::@D_down> +} +kanagawa.container sym @D_down { + %this = kanagawa.this <@D::@D_down> + %clk = kanagawa.port.input "clk_in" sym @clk_in : i1 + %clk_out = kanagawa.port.output "clk_out" sym @clk_out : i1 + %clk.val = kanagawa.port.read %clk : !kanagawa.portref + kanagawa.port.write %clk_out, %clk.val : !kanagawa.portref +} +} diff --git a/test/Dialect/Kanagawa/Transforms/structure.mlir b/test/Dialect/Kanagawa/Transforms/structure.mlir new file mode 100644 index 000000000000..4c1134fe137b --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/structure.mlir @@ -0,0 +1,64 @@ +// RUN: circt-opt %s | circt-opt | FileCheck %s +// RUN: circt-opt %s --kanagawa-call-prep | circt-opt | FileCheck %s --check-prefix=PREP + + +// CHECK-LABEL: kanagawa.class sym @C { +// CHECK: kanagawa.method @getAndSet(%x: ui32) -> ui32 { +// CHECK: kanagawa.return %x : ui32 +// CHECK: kanagawa.method @returnNothingWithRet() -> () { +// CHECK: kanagawa.return + +// PREP-LABEL: kanagawa.class sym @C { +// PREP: kanagawa.method @getAndSet(%arg: !hw.struct) -> ui32 { +// PREP: %x = hw.struct_explode %arg : !hw.struct +// PREP: kanagawa.return %x : ui32 +// PREP: kanagawa.method @returnNothingWithRet(%arg: !hw.struct<>) -> () { +// PREP: hw.struct_explode %arg : !hw.struct<> +// PREP: kanagawa.return + +kanagawa.design @foo { +kanagawa.class sym @C { + %this = kanagawa.this <@foo::@C> + kanagawa.method @getAndSet(%x: ui32) -> ui32 { + kanagawa.return %x : ui32 + } + kanagawa.method @returnNothingWithRet() { + kanagawa.return + } +} + +// CHECK-LABEL: kanagawa.class sym @User { +// CHECK: [[c:%.+]] = kanagawa.instance @c, <@foo::@C> +// CHECK: kanagawa.method @getAndSetWrapper(%new_value: ui32) -> ui32 { +// CHECK: [[x:%.+]] = kanagawa.call <@foo::@getAndSet>(%new_value) : (ui32) -> ui32 +// CHECK: kanagawa.return [[x]] : ui32 +// CHECK: kanagawa.method @getAndSetDup(%new_value: ui32) -> ui32 { +// CHECK: [[x:%.+]] = kanagawa.call <@foo::@getAndSet>(%new_value) : (ui32) -> ui32 +// CHECK: kanagawa.return [[x]] : ui32 + + +// PREP-LABEL: kanagawa.class sym @User { +// PREP: [[c:%.+]] = kanagawa.instance @c, <@foo::@C> +// PREP: kanagawa.method @getAndSetWrapper(%arg: !hw.struct) -> ui32 { +// PREP: %new_value = hw.struct_explode %arg : !hw.struct +// PREP: [[STRUCT1:%.+]] = hw.struct_create (%new_value) {sv.namehint = "getAndSet_args_called_from_getAndSetWrapper"} : !hw.struct +// PREP: [[CALLRES1:%.+]] = kanagawa.call <@foo::@getAndSet>([[STRUCT1]]) : (!hw.struct) -> ui32 +// PREP: kanagawa.method @getAndSetDup(%arg: !hw.struct) -> ui32 { +// PREP: %new_value = hw.struct_explode %arg : !hw.struct +// PREP: [[STRUCT2:%.+]] = hw.struct_create (%new_value) {sv.namehint = "getAndSet_args_called_from_getAndSetDup"} : !hw.struct +// PREP: [[CALLRES2:%.+]] = kanagawa.call <@foo::@getAndSet>([[STRUCT2]]) : (!hw.struct) -> ui32 +// PREP: kanagawa.return [[CALLRES2]] : ui32 +kanagawa.class sym @User { + %this = kanagawa.this <@foo::@User> + kanagawa.instance @c, <@foo::@C> + kanagawa.method @getAndSetWrapper(%new_value: ui32) -> ui32 { + %x = kanagawa.call <@foo::@getAndSet>(%new_value): (ui32) -> ui32 + kanagawa.return %x : ui32 + } + + kanagawa.method @getAndSetDup(%new_value: ui32) -> ui32 { + %x = kanagawa.call <@foo::@getAndSet>(%new_value): (ui32) -> ui32 + kanagawa.return %x : ui32 + } +} +} diff --git a/test/Dialect/Kanagawa/Transforms/tunneling_errors.mlir b/test/Dialect/Kanagawa/Transforms/tunneling_errors.mlir new file mode 100644 index 000000000000..46ce494c4bdc --- /dev/null +++ b/test/Dialect/Kanagawa/Transforms/tunneling_errors.mlir @@ -0,0 +1,43 @@ +// RUN: circt-opt --split-input-file --allow-unregistered-dialect --kanagawa-tunneling --verify-diagnostics %s + +kanagawa.design @foo { +kanagawa.container sym @Parent { + %this = kanagawa.this <@foo::@Parent> + %in = kanagawa.port.input "in" sym @in : i1 +} + +kanagawa.container sym @Orphan { + %this = kanagawa.this <@foo::@Orphan> + // expected-error @+2 {{'kanagawa.path' op cannot tunnel up from "Orphan" because it has no uses}} + // expected-error @+1 {{failed to legalize operation 'kanagawa.path' that was explicitly marked illegal}} + %parent = kanagawa.path [ + #kanagawa.step> + ] + + %p = kanagawa.get_port %parent, @in : !kanagawa.scoperef<@foo::@Parent> -> !kanagawa.portref +} +} +// ----- + +kanagawa.design @foo { +kanagawa.container sym @Parent { + %this = kanagawa.this <@foo::@Parent> + %mc = kanagawa.container.instance @mc, <@foo::@MissingChild> +} + +kanagawa.container sym @Child { + %this = kanagawa.this <@foo::@Child> + %in = kanagawa.port.input "in" sym @in : i1 +} + +kanagawa.container sym @MissingChild { + %this = kanagawa.this <@foo::@MissingChild> + // expected-error @+2 {{'kanagawa.path' op expected an instance named @c in @Parent but found none}} + // expected-error @+1 {{failed to legalize operation 'kanagawa.path' that was explicitly marked illegal}} + %parent = kanagawa.path [ + #kanagawa.step, + #kanagawa.step> + ] + %p = kanagawa.get_port %parent, @in : !kanagawa.scoperef<@foo::@Child> -> !kanagawa.portref +} +} diff --git a/test/Dialect/Kanagawa/canonicalization.mlir b/test/Dialect/Kanagawa/canonicalization.mlir new file mode 100644 index 000000000000..291720c6a931 --- /dev/null +++ b/test/Dialect/Kanagawa/canonicalization.mlir @@ -0,0 +1,40 @@ +// RUN: circt-opt --allow-unregistered-dialect --split-input-file --canonicalize --cse %s | FileCheck %s + +kanagawa.design @foo { + +// CHECK-LABEL: kanagawa.container sym @GetPortOnThis { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@GetPortOnThis> +// CHECK: %[[VAL_1:.*]] = kanagawa.port.input "in" sym @in : i1 +// CHECK: "foo.user"(%[[VAL_1]]) : (!kanagawa.portref) -> () +// CHECK: } +kanagawa.container sym @GetPortOnThis { + %this = kanagawa.this <@foo::@GetPortOnThis> + %p = kanagawa.port.input "in" sym @in : i1 + %p2 = kanagawa.get_port %this, @in : !kanagawa.scoperef<@foo::@GetPortOnThis> -> !kanagawa.portref + "foo.user"(%p2) : (!kanagawa.portref) -> () +} + +} + +// ----- + +kanagawa.design @foo { + +kanagawa.container sym @C { + %this = kanagawa.this <@foo::@C> +} + +// CHECK-LABEL: kanagawa.container sym @AccessChild { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@AccessChild> +// CHECK: %[[VAL_1:.*]] = kanagawa.container.instance @c, <@foo::@C +// CHECK: "foo.user"(%[[VAL_1]]) : (!kanagawa.scoperef<@foo::@C>) -> () +// CHECK: } +kanagawa.container sym @AccessChild { + %this = kanagawa.this <@foo::@AccessChild> + %c = kanagawa.container.instance @c, <@foo::@C> + %c_ref = kanagawa.path [ + #kanagawa.step> + ] + "foo.user"(%c_ref) : (!kanagawa.scoperef<@foo::@C>) -> () +} +} diff --git a/test/Dialect/Kanagawa/errors.mlir b/test/Dialect/Kanagawa/errors.mlir new file mode 100644 index 000000000000..ab3b2c4ebee6 --- /dev/null +++ b/test/Dialect/Kanagawa/errors.mlir @@ -0,0 +1,96 @@ +// RUN: circt-opt --split-input-file --verify-diagnostics %s + +kanagawa.design @foo { +kanagawa.class sym @C { + %this = kanagawa.this <@foo::@C> + kanagawa.method @typeMismatch1() -> (ui32, i32) { + // expected-error @+1 {{'kanagawa.return' op must have the same number of operands as the method has results}} + kanagawa.return + } +} +} + +// ----- +kanagawa.design @foo { +kanagawa.class sym @C { + %this = kanagawa.this <@foo::@C> + kanagawa.method @typeMismatch3() -> ui32 { + %c = hw.constant 1 : i8 + // expected-error @+1 {{'kanagawa.return' op operand type ('i8') must match function return type ('ui32')}} + kanagawa.return %c : i8 + } +} +} + +// ----- + +kanagawa.design @foo { +// expected-error @+1 {{'kanagawa.class' op must contain only one 'kanagawa.this' operation}} +kanagawa.class sym @MultipleThis { + %this = kanagawa.this <@foo::@MultipleThis> + %this2 = kanagawa.this <@foo::@MultipleThis> +} +} + +// ----- + +kanagawa.design @foo { +// expected-error @+1 {{'kanagawa.container' op must contain a 'kanagawa.this' operation}} +kanagawa.container sym @NoThis { +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PathStepParentWithInstanceName { + %this = kanagawa.this <@foo::@PathStepParentWithInstanceName> + // expected-error @+1 {{kanagawa.step 'parent' may not specify an instance name}} + %p = kanagawa.path [#kanagawa.step] +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PathStepInvalidType { + %this = kanagawa.this <@foo::@PathStepParentWithInstanceName> + // expected-error @+1 {{kanagawa.step type must be an !kanagawa.scoperef type}} + %p = kanagawa.path [#kanagawa.step] +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PathStepChildMissingSymbol { + %this = kanagawa.this <@foo::@PathStepNonExistingChild> + // expected-error @+1 {{kanagawa.step 'child' must specify an instance name}} + %p = kanagawa.path [#kanagawa.step>] +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @InvalidVar { + %this = kanagawa.this <@foo::@C> + // expected-error @+1 {{'kanagawa.var' op attribute 'type' failed to satisfy constraint: any memref type}} + kanagawa.var @var : i32 +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @InvalidReturn { + %this = kanagawa.this <@foo::@InvalidReturn> + kanagawa.method @foo() { + %c = hw.constant 1 : i32 + // expected-error @+1 {{'kanagawa.sblock.return' op number of operands must match number of block outputs}} + %ret = kanagawa.sblock() -> i32 { + } + kanagawa.return + } +} +} diff --git a/test/Dialect/Kanagawa/inner_ref_errors.mlir b/test/Dialect/Kanagawa/inner_ref_errors.mlir new file mode 100644 index 000000000000..677e488d3511 --- /dev/null +++ b/test/Dialect/Kanagawa/inner_ref_errors.mlir @@ -0,0 +1,74 @@ +// RUN: circt-opt --hw-verify-irn --split-input-file --verify-diagnostics %s + +kanagawa.design @foo { +kanagawa.class sym @MissingPort { + %this = kanagawa.this <@foo::@MissingPort> + // expected-error @+1 {{'kanagawa.get_port' op port '@C_in' does not exist in @MissingPort}} + %c_in = kanagawa.get_port %this, @C_in : !kanagawa.scoperef<@foo::@MissingPort> -> !kanagawa.portref +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @InvalidGetVar2 { + %this = kanagawa.this <@foo::@InvalidGetVar2> + kanagawa.var @var : memref + kanagawa.method @foo() { + %parent = kanagawa.path [ + #kanagawa.step> + ] + // expected-error @+1 {{'kanagawa.get_var' op dereferenced type ('memref') must match variable type ('memref')}} + %var = kanagawa.get_var %parent, @var : !kanagawa.scoperef<@foo::@InvalidGetVar2> -> memref + kanagawa.return + } +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @InvalidGetVar { + %this = kanagawa.this <@foo::@InvalidGetVar> + kanagawa.var @var : memref + kanagawa.method @foo() { + %parent = kanagawa.path [ + #kanagawa.step> + ] + // expected-error @+1 {{'kanagawa.get_var' op result #0 must be memref of any type values, but got 'i32'}} + %var = kanagawa.get_var %parent, @var : !kanagawa.scoperef<@foo::@InvalidGetVar> -> i32 + kanagawa.return + } +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PortTypeMismatch { + %this = kanagawa.this <@foo::@PortTypeMismatch> + kanagawa.port.input "in" sym @in : i1 + // expected-error @+1 {{'kanagawa.get_port' op symbol '@in' refers to a port of type 'i1', but this op has type 'i2'}} + %c_in = kanagawa.get_port %this, @in : !kanagawa.scoperef<@foo::@PortTypeMismatch> -> !kanagawa.portref +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PathStepNonExistingChild { + %this = kanagawa.this <@foo::@PathStepNonExistingChild> + // expected-error @+1 {{'kanagawa.path' op kanagawa.step scoperef symbol '@A' does not exist}} + %p = kanagawa.path [#kanagawa.step>] +} +} + +// ----- + +kanagawa.design @foo { +kanagawa.class sym @PathStepNonExistingParent { + %this = kanagawa.this <@foo::@PathStepNonExistingParent> + // expected-error @+1 {{'kanagawa.path' op last kanagawa.step in path must specify a symbol for the scoperef}} + %p = kanagawa.path [#kanagawa.step] +} +} diff --git a/test/Dialect/Kanagawa/round-trip.mlir b/test/Dialect/Kanagawa/round-trip.mlir new file mode 100644 index 000000000000..701f17b0459f --- /dev/null +++ b/test/Dialect/Kanagawa/round-trip.mlir @@ -0,0 +1,145 @@ +// RUN: circt-opt %s | circt-opt | FileCheck %s + +kanagawa.design @foo { + +// CHECK-LABEL: kanagawa.class sym @HighLevel { +// CHECK-NEXT: %this = kanagawa.this <@foo::@HighLevel> +// CHECK-NEXT: kanagawa.var @single : memref +// CHECK-NEXT: kanagawa.var @array : memref<10xi32> +// CHECK-NEXT: kanagawa.method @foo() -> (i32, i32) { +// CHECK-NEXT: %parent = kanagawa.path [#kanagawa.step> : !kanagawa.scoperef<@foo::@HighLevel>] +// CHECK-NEXT: %single = kanagawa.get_var %parent, @single : !kanagawa.scoperef<@foo::@HighLevel> -> memref +// CHECK-NEXT: %array = kanagawa.get_var %parent, @array : !kanagawa.scoperef<@foo::@HighLevel> -> memref<10xi32> +// CHECK-NEXT: %alloca = memref.alloca() : memref +// CHECK-NEXT: %c32_i32 = hw.constant 32 : i32 +// CHECK-NEXT: %0:2 = kanagawa.sblock (%arg0 : i32 = %c32_i32) -> (i32, i32) attributes {schedule = 1 : i64} { +// CHECK-NEXT: %1 = memref.load %alloca[] : memref +// CHECK-NEXT: memref.store %arg0, %alloca[] : memref +// CHECK-NEXT: kanagawa.sblock.return %1, %1 : i32, i32 +// CHECK-NEXT: } +// CHECK-NEXT: kanagawa.return %0#0, %0#1 : i32, i32 +// CHECK-NEXT: } +// CHECK-NEXT: kanagawa.method.df @bar(%arg0: none) -> none { +// CHECK-NEXT: %0 = handshake.join %arg0 : none +// CHECK-NEXT: kanagawa.return %0 : none +// CHECK-NEXT: } +// CHECK-NEXT: } + + +kanagawa.class sym @HighLevel { + %this = kanagawa.this <@foo::@HighLevel> + kanagawa.var @single : memref + kanagawa.var @array : memref<10xi32> + + kanagawa.method @foo() -> (i32, i32) { + %parent = kanagawa.path [ + #kanagawa.step> + ] + %single = kanagawa.get_var %parent, @single : !kanagawa.scoperef<@foo::@HighLevel> -> memref + %array = kanagawa.get_var %parent, @array : !kanagawa.scoperef<@foo::@HighLevel> -> memref<10xi32> + %local = memref.alloca() : memref + %c32 = hw.constant 32 : i32 + %out1, %out2 = kanagawa.sblock(%arg : i32 = %c32) -> (i32, i32) attributes {schedule = 1} { + %v = memref.load %local[] : memref + memref.store %arg, %local[] : memref + kanagawa.sblock.return %v, %v : i32, i32 + } + kanagawa.return %out1, %out2 : i32, i32 + } + + kanagawa.method.df @bar(%arg0 : none) -> (none) { + %0 = handshake.join %arg0 : none + kanagawa.return %0 : none + } +} + + +// CHECK-LABEL: kanagawa.class sym @A { +// CHECK-NEXT: %this = kanagawa.this <@foo::@A> +// CHECK-NEXT: %in = kanagawa.port.input "in" sym @in : i1 +// CHECK-NEXT: %out = kanagawa.port.output "out" sym @out : i1 +// CHECK-NEXT: %AnonymousPort = kanagawa.port.input sym @AnonymousPort : i1 +// CHECK-NEXT: } + +// CHECK-LABEL: kanagawa.class sym @LowLevel { +// CHECK-NEXT: %this = kanagawa.this <@foo::@LowLevel> +// CHECK-NEXT: %LowLevel_in = kanagawa.port.input "LowLevel_in" sym @LowLevel_in : i1 +// CHECK-NEXT: %LowLevel_out = kanagawa.port.output "LowLevel_out" sym @LowLevel_out : i1 +// CHECK-NEXT: %in_wire, %in_wire.out = kanagawa.wire.input @in_wire : i1 +// CHECK-NEXT: %true = hw.constant true +// CHECK-NEXT: %out_wire = kanagawa.wire.output @out_wire, %true : i1 +// CHECK-NEXT: %a = kanagawa.instance @a, <@foo::@A> +// CHECK-NEXT: kanagawa.container sym @D { +// CHECK-NEXT: %this_0 = kanagawa.this <@foo::@D> +// CHECK-NEXT: %parent = kanagawa.path [#kanagawa.step> : !kanagawa.scoperef<@foo::@LowLevel>] +// CHECK-NEXT: %parent.LowLevel_in.ref = kanagawa.get_port %parent, @LowLevel_in : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref +// CHECK-NEXT: %parent.LowLevel_out.ref = kanagawa.get_port %parent, @LowLevel_out : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref +// CHECK-NEXT: %true_1 = hw.constant true +// CHECK-NEXT: kanagawa.port.write %parent.LowLevel_in.ref, %true_1 : !kanagawa.portref +// CHECK-NEXT: %parent.LowLevel_out.ref.val = kanagawa.port.read %parent.LowLevel_out.ref : !kanagawa.portref +// CHECK-NEXT: %parent.a = kanagawa.path [#kanagawa.step : !kanagawa.scoperef, #kanagawa.step> : !kanagawa.scoperef<@foo::@A>] +// CHECK-NEXT: %parent.a.in.ref = kanagawa.get_port %parent.a, @in : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref +// CHECK-NEXT: %parent.a.out.ref = kanagawa.get_port %parent.a, @out : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref +// CHECK-NEXT: kanagawa.port.write %parent.a.in.ref, %parent.LowLevel_out.ref.val : !kanagawa.portref +// CHECK-NEXT: %parent.a.out.ref.val = kanagawa.port.read %parent.a.out.ref : !kanagawa.portref +// CHECK-NEXT: hw.instance "foo" @externModule() -> () +// CHECK-NEXT: } + +// CHECK-NEXT: kanagawa.container "ThisName" sym @ThisSymbol { +// CHECK-NEXT: %this_0 = kanagawa.this <@foo::@ThisSymbol> +// CHECK-NEXT: } +// CHECK-NEXT: } + +kanagawa.class sym @A { + %this = kanagawa.this <@foo::@A> + kanagawa.port.input "in" sym @in : i1 + kanagawa.port.output "out" sym @out : i1 + kanagawa.port.input sym @AnonymousPort : i1 +} + +kanagawa.class sym @LowLevel { + %this = kanagawa.this <@foo::@LowLevel> + kanagawa.port.input "LowLevel_in" sym @LowLevel_in : i1 + kanagawa.port.output "LowLevel_out" sym @LowLevel_out : i1 + + %in_wire, %in_wire.val = kanagawa.wire.input @in_wire : i1 + %true = hw.constant 1 : i1 + %out_wire = kanagawa.wire.output @out_wire, %true : i1 + + // Instantiation + %a = kanagawa.instance @a, <@foo::@A> + + kanagawa.container sym @D { + %this_d = kanagawa.this <@foo::@D> + %parent_C = kanagawa.path [ + #kanagawa.step> + ] + // Test local read/writes + %LowLevel_in_p = kanagawa.get_port %parent_C, @LowLevel_in : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref + %LowLevel_out_p = kanagawa.get_port %parent_C, @LowLevel_out : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref + %t = hw.constant true + kanagawa.port.write %LowLevel_in_p, %t : !kanagawa.portref + %LowLevel_out = kanagawa.port.read %LowLevel_out_p : !kanagawa.portref + + // Test cross-container read/writes + %A.in_parent = kanagawa.path [ + #kanagawa.step, + #kanagawa.step> + ] + %A.in_p = kanagawa.get_port %A.in_parent, @in : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref + %A.out_p = kanagawa.get_port %A.in_parent, @out : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref + kanagawa.port.write %A.in_p, %LowLevel_out : !kanagawa.portref + %A.out = kanagawa.port.read %A.out_p : !kanagawa.portref + + // Test hw.instance ops inside a container (symbol table usage) + hw.instance "foo" @externModule() -> () + } + + kanagawa.container "ThisName" sym @ThisSymbol { + %this2 = kanagawa.this <@foo::@ThisSymbol> + } +} + +} + +hw.module.extern @externModule() diff --git a/test/circt-opt/commandline.mlir b/test/circt-opt/commandline.mlir index d9c79d7e1ce9..b3427d821189 100644 --- a/test/circt-opt/commandline.mlir +++ b/test/circt-opt/commandline.mlir @@ -21,8 +21,8 @@ // DIALECT-SAME: handshake // DIALECT-SAME: hw // DIALECT-SAME: hwarith -// DIALECT-SAME: ibis // DIALECT-SAME: interop +// DIALECT-SAME: kanagawa // DIALECT-SAME: llhd // DIALECT-SAME: llvm // DIALECT-SAME: memref diff --git a/test/ibistool/output_format.mlir b/test/ibistool/output_format.mlir deleted file mode 100644 index 4c48e3172b7a..000000000000 --- a/test/ibistool/output_format.mlir +++ /dev/null @@ -1,79 +0,0 @@ -// XFAIL: * -// See https://github.com/llvm/circt/issues/6658 -// RUN: ibistool %s --lo --post-ibis-ir | FileCheck %s --check-prefix=CHECK-POST-IBIS -// RUN: ibistool %s --lo --ir | FileCheck %s --check-prefix=CHECK-IR -// RUN: ibistool %s --lo --verilog | FileCheck %s --check-prefix=CHECK-VERILOG - -// CHECK-POST-IBIS-LABEL: hw.module @A_B( -// CHECK-POST-IBIS-SAME: in %[[VAL_0:.*]] : !seq.clock, in %[[VAL_1:.*]] : i1, out p_out : i1) { -// CHECK-POST-IBIS: %[[VAL_2:.*]] = seq.compreg %[[VAL_1]], %[[VAL_0]] : i1 -// CHECK-POST-IBIS: hw.output %[[VAL_2]] : i1 -// CHECK-POST-IBIS: } - -// CHECK-POST-IBIS-LABEL: hw.module @A( -// CHECK-POST-IBIS-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : !seq.clock, out out : i1) { -// CHECK-POST-IBIS: %[[VAL_2:.*]] = hw.instance "A_B" @A_B(p_clk: %[[VAL_1]]: !seq.clock, p_in: %[[VAL_0]]: i1) -> (p_out: i1) -// CHECK-POST-IBIS: hw.output %[[VAL_2]] : i1 -// CHECK-POST-IBIS: } - -// CHECK-IR-LABEL: hw.module @A_B( -// CHECK-IR-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : i1, out p_out : i1) { -// CHECK-IR: %[[VAL_2:.*]] = sv.reg : !hw.inout -// CHECK-IR: %[[VAL_3:.*]] = sv.read_inout %[[VAL_2]] : !hw.inout -// CHECK-IR: sv.alwaysff(posedge %[[VAL_0]]) { -// CHECK-IR: sv.passign %[[VAL_2]], %[[VAL_1]] : i1 -// CHECK-IR: } -// CHECK-IR: hw.output %[[VAL_3]] : i1 -// CHECK-IR: } - -// CHECK-IR-LABEL: hw.module @A( -// CHECK-IR-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : i1, out out : i1) { -// CHECK-IR: %[[VAL_2:.*]] = hw.instance "A_B" @A_B(p_clk: %[[VAL_1]]: i1, p_in: %[[VAL_0]]: i1) -> (p_out: i1) -// CHECK-IR: hw.output %[[VAL_2]] : i1 -// CHECK-IR: } - -// CHECK-VERILOG-LABEL: module A_B( -// CHECK-VERILOG: input p_clk, -// CHECK-VERILOG: p_in, -// CHECK-VERILOG: output p_out -// CHECK-VERILOG: ); -// CHECK-VERILOG: reg r; -// CHECK-VERILOG: always_ff @(posedge p_clk) -// CHECK-VERILOG: r <= p_in; -// CHECK-VERILOG: assign p_out = r; -// CHECK-VERILOG: endmodule - -// CHECK-VERILOG-LABEL: module A( -// CHECK-VERILOG: input in, -// CHECK-VERILOG: clk, -// CHECK-VERILOG: output out -// CHECK-VERILOG: ); -// CHECK-VERILOG: A_B A_B ( -// CHECK-VERILOG: .p_clk (clk), -// CHECK-VERILOG: .p_in (in), -// CHECK-VERILOG: .p_out (out) -// CHECK-VERILOG: ); -// CHECK-VERILOG: endmodule - -ibis.design @foo { -ibis.class sym @A { - %this = ibis.this @A - ibis.port.input "in" sym @in : i1 - ibis.port.output "out" sym @out : i1 - ibis.port.input "clk" sym @clk : !seq.clock - - ibis.container@B { - %B_this = ibis.this @B - %parent = ibis.path [ - #ibis.step> - ] - %a_in = ibis.get_port %parent, @in : !ibis.scoperef<@foo::@A> -> !ibis.portref - %a_clk = ibis.get_port %parent, @clk : !ibis.scoperef<@foo::@A> -> !ibis.portref - %a_out = ibis.get_port %parent, @out : !ibis.scoperef<@foo::@A> -> !ibis.portref - %in = ibis.port.read %a_in : !ibis.portref - %clk = ibis.port.read %a_clk : !ibis.portref - %r = seq.compreg %in, %clk: i1 - ibis.port.write %a_out, %r : !ibis.portref - } -} -} diff --git a/test/ibistool/high_level.mlir b/test/kanagawatool/high_level.mlir similarity index 66% rename from test/ibistool/high_level.mlir rename to test/kanagawatool/high_level.mlir index 5436152e03f4..07e2e191b82c 100644 --- a/test/ibistool/high_level.mlir +++ b/test/kanagawatool/high_level.mlir @@ -1,55 +1,55 @@ -// RUN: ibistool --hi --post-ibis-ir %s | FileCheck %s +// RUN: kanagawatool --hi --post-kanagawa-ir %s | FileCheck %s -// CHECK-LABEL: ibis.class sym @ToHandshake { -// CHECK: %[[VAL_0:.*]] = ibis.this <@foo::@ToHandshake> -// CHECK: ibis.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i1) -> i32 { -// CHECK: %[[VAL_4:.*]]:3 = ibis.sblock.isolated () -> (i32, i32, i32) { +// CHECK-LABEL: kanagawa.class sym @ToHandshake { +// CHECK: %[[VAL_0:.*]] = kanagawa.this <@foo::@ToHandshake> +// CHECK: kanagawa.method @foo(%[[VAL_1:.*]]: i32, %[[VAL_2:.*]]: i32, %[[VAL_3:.*]]: i1) -> i32 { +// CHECK: %[[VAL_4:.*]]:3 = kanagawa.sblock.isolated () -> (i32, i32, i32) { // CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 // CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 // CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32 -// CHECK: ibis.sblock.return %[[VAL_5]], %[[VAL_6]], %[[VAL_7]] : i32, i32, i32 +// CHECK: kanagawa.sblock.return %[[VAL_5]], %[[VAL_6]], %[[VAL_7]] : i32, i32, i32 // CHECK: } // CHECK: cf.br ^bb1(%[[VAL_1]], %[[VAL_8:.*]]#2, %[[VAL_2]], %[[VAL_8]]#0, %[[VAL_8]]#1, %[[VAL_8]]#2 : i32, i32, i32, i32, i32, i32) // CHECK: ^bb1(%[[VAL_9:.*]]: i32, %[[VAL_10:.*]]: i32, %[[VAL_11:.*]]: i32, %[[VAL_12:.*]]: i32, %[[VAL_13:.*]]: i32, %[[VAL_14:.*]]: i32): -// CHECK: %[[VAL_15:.*]] = ibis.sblock.isolated (%[[VAL_16:.*]] : i32 = %[[VAL_9]], %[[VAL_17:.*]] : i32 = %[[VAL_11]]) -> i1 { +// CHECK: %[[VAL_15:.*]] = kanagawa.sblock.isolated (%[[VAL_16:.*]] : i32 = %[[VAL_9]], %[[VAL_17:.*]] : i32 = %[[VAL_11]]) -> i1 { // CHECK: %[[VAL_18:.*]] = arith.cmpi slt, %[[VAL_16]], %[[VAL_17]] : i32 -// CHECK: ibis.sblock.return %[[VAL_18]] : i1 +// CHECK: kanagawa.sblock.return %[[VAL_18]] : i1 // CHECK: } // CHECK: cf.cond_br %[[VAL_15]], ^bb2(%[[VAL_11]], %[[VAL_12]], %[[VAL_13]], %[[VAL_14]], %[[VAL_9]], %[[VAL_10]] : i32, i32, i32, i32, i32, i32), ^bb6(%[[VAL_10]] : i32) // CHECK: ^bb2(%[[VAL_19:.*]]: i32, %[[VAL_20:.*]]: i32, %[[VAL_21:.*]]: i32, %[[VAL_22:.*]]: i32, %[[VAL_23:.*]]: i32, %[[VAL_24:.*]]: i32): -// CHECK: %[[VAL_25:.*]] = ibis.sblock.isolated (%[[VAL_26:.*]] : i32 = %[[VAL_24]], %[[VAL_27:.*]] : i32 = %[[VAL_20]], %[[VAL_28:.*]] : i32 = %[[VAL_22]]) -> i1 { +// CHECK: %[[VAL_25:.*]] = kanagawa.sblock.isolated (%[[VAL_26:.*]] : i32 = %[[VAL_24]], %[[VAL_27:.*]] : i32 = %[[VAL_20]], %[[VAL_28:.*]] : i32 = %[[VAL_22]]) -> i1 { // CHECK: %[[VAL_29:.*]] = arith.remsi %[[VAL_26]], %[[VAL_27]] : i32 // CHECK: %[[VAL_30:.*]] = arith.cmpi eq, %[[VAL_29]], %[[VAL_28]] : i32 -// CHECK: ibis.sblock.return %[[VAL_30]] : i1 +// CHECK: kanagawa.sblock.return %[[VAL_30]] : i1 // CHECK: } // CHECK: cf.cond_br %[[VAL_25]], ^bb3(%[[VAL_19]], %[[VAL_20]], %[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_24]] : i32, i32, i32, i32, i32, i32), ^bb4(%[[VAL_19]], %[[VAL_20]], %[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_24]] : i32, i32, i32, i32, i32, i32) // CHECK: ^bb3(%[[VAL_31:.*]]: i32, %[[VAL_32:.*]]: i32, %[[VAL_33:.*]]: i32, %[[VAL_34:.*]]: i32, %[[VAL_35:.*]]: i32, %[[VAL_36:.*]]: i32): -// CHECK: %[[VAL_37:.*]] = ibis.sblock.isolated (%[[VAL_38:.*]] : i32 = %[[VAL_36]], %[[VAL_39:.*]] : i32 = %[[VAL_35]]) -> i32 { +// CHECK: %[[VAL_37:.*]] = kanagawa.sblock.isolated (%[[VAL_38:.*]] : i32 = %[[VAL_36]], %[[VAL_39:.*]] : i32 = %[[VAL_35]]) -> i32 { // CHECK: %[[VAL_40:.*]] = arith.addi %[[VAL_38]], %[[VAL_39]] : i32 -// CHECK: ibis.sblock.return %[[VAL_40]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_40]] : i32 // CHECK: } // CHECK: cf.br ^bb5(%[[VAL_37]], %[[VAL_31]], %[[VAL_32]], %[[VAL_33]], %[[VAL_34]], %[[VAL_35]] : i32, i32, i32, i32, i32, i32) // CHECK: ^bb4(%[[VAL_41:.*]]: i32, %[[VAL_42:.*]]: i32, %[[VAL_43:.*]]: i32, %[[VAL_44:.*]]: i32, %[[VAL_45:.*]]: i32, %[[VAL_46:.*]]: i32): -// CHECK: %[[VAL_47:.*]] = ibis.sblock.isolated (%[[VAL_48:.*]] : i32 = %[[VAL_46]], %[[VAL_49:.*]] : i32 = %[[VAL_45]]) -> i32 { +// CHECK: %[[VAL_47:.*]] = kanagawa.sblock.isolated (%[[VAL_48:.*]] : i32 = %[[VAL_46]], %[[VAL_49:.*]] : i32 = %[[VAL_45]]) -> i32 { // CHECK: %[[VAL_50:.*]] = arith.subi %[[VAL_48]], %[[VAL_49]] : i32 -// CHECK: ibis.sblock.return %[[VAL_50]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_50]] : i32 // CHECK: } // CHECK: cf.br ^bb5(%[[VAL_47]], %[[VAL_41]], %[[VAL_42]], %[[VAL_43]], %[[VAL_44]], %[[VAL_45]] : i32, i32, i32, i32, i32, i32) // CHECK: ^bb5(%[[VAL_51:.*]]: i32, %[[VAL_52:.*]]: i32, %[[VAL_53:.*]]: i32, %[[VAL_54:.*]]: i32, %[[VAL_55:.*]]: i32, %[[VAL_56:.*]]: i32): -// CHECK: %[[VAL_57:.*]] = ibis.sblock.isolated (%[[VAL_58:.*]] : i32 = %[[VAL_56]], %[[VAL_59:.*]] : i32 = %[[VAL_54]]) -> i32 { +// CHECK: %[[VAL_57:.*]] = kanagawa.sblock.isolated (%[[VAL_58:.*]] : i32 = %[[VAL_56]], %[[VAL_59:.*]] : i32 = %[[VAL_54]]) -> i32 { // CHECK: %[[VAL_60:.*]] = arith.addi %[[VAL_58]], %[[VAL_59]] : i32 -// CHECK: ibis.sblock.return %[[VAL_60]] : i32 +// CHECK: kanagawa.sblock.return %[[VAL_60]] : i32 // CHECK: } // CHECK: cf.br ^bb1(%[[VAL_57]], %[[VAL_51]], %[[VAL_52]], %[[VAL_53]], %[[VAL_54]], %[[VAL_55]] : i32, i32, i32, i32, i32, i32) // CHECK: ^bb6(%[[VAL_61:.*]]: i32): -// CHECK: ibis.return %[[VAL_61]] : i32 +// CHECK: kanagawa.return %[[VAL_61]] : i32 // CHECK: } // CHECK: } -ibis.design @foo { -ibis.class sym @ToHandshake { - %this = ibis.this <@foo::@ToHandshake> - ibis.method @foo(%a: i32, %b: i32, %c: i1) -> i32 { +kanagawa.design @foo { +kanagawa.class sym @ToHandshake { + %this = kanagawa.this <@foo::@ToHandshake> + kanagawa.method @foo(%a: i32, %b: i32, %c: i1) -> i32 { %c2_i32 = arith.constant 2 : i32 %c1 = arith.constant 1 : i32 %c0_i32 = arith.constant 0 : i32 @@ -78,7 +78,7 @@ ibis.class sym @ToHandshake { cf.br ^bb1(%9 : i32) ^bb7: // pred: ^bb1 %10 = memref.load %alloca[] : memref - ibis.return %10 : i32 + kanagawa.return %10 : i32 } } } diff --git a/test/kanagawatool/output_format.mlir b/test/kanagawatool/output_format.mlir new file mode 100644 index 000000000000..0c52c2012cf3 --- /dev/null +++ b/test/kanagawatool/output_format.mlir @@ -0,0 +1,79 @@ +// XFAIL: * +// See https://github.com/llvm/circt/issues/6658 +// RUN: kanagawatool %s --lo --post-kanagawa-ir | FileCheck %s --check-prefix=CHECK-POST-KANAGAWA +// RUN: kanagawatool %s --lo --ir | FileCheck %s --check-prefix=CHECK-IR +// RUN: kanagawatool %s --lo --verilog | FileCheck %s --check-prefix=CHECK-VERILOG + +// CHECK-POST-KANAGAWA-LABEL: hw.module @A_B( +// CHECK-POST-KANAGAWA-SAME: in %[[VAL_0:.*]] : !seq.clock, in %[[VAL_1:.*]] : i1, out p_out : i1) { +// CHECK-POST-KANAGAWA: %[[VAL_2:.*]] = seq.compreg %[[VAL_1]], %[[VAL_0]] : i1 +// CHECK-POST-KANAGAWA: hw.output %[[VAL_2]] : i1 +// CHECK-POST-KANAGAWA: } + +// CHECK-POST-KANAGAWA-LABEL: hw.module @A( +// CHECK-POST-KANAGAWA-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : !seq.clock, out out : i1) { +// CHECK-POST-KANAGAWA: %[[VAL_2:.*]] = hw.instance "A_B" @A_B(p_clk: %[[VAL_1]]: !seq.clock, p_in: %[[VAL_0]]: i1) -> (p_out: i1) +// CHECK-POST-KANAGAWA: hw.output %[[VAL_2]] : i1 +// CHECK-POST-KANAGAWA: } + +// CHECK-IR-LABEL: hw.module @A_B( +// CHECK-IR-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : i1, out p_out : i1) { +// CHECK-IR: %[[VAL_2:.*]] = sv.reg : !hw.inout +// CHECK-IR: %[[VAL_3:.*]] = sv.read_inout %[[VAL_2]] : !hw.inout +// CHECK-IR: sv.alwaysff(posedge %[[VAL_0]]) { +// CHECK-IR: sv.passign %[[VAL_2]], %[[VAL_1]] : i1 +// CHECK-IR: } +// CHECK-IR: hw.output %[[VAL_3]] : i1 +// CHECK-IR: } + +// CHECK-IR-LABEL: hw.module @A( +// CHECK-IR-SAME: in %[[VAL_0:.*]] : i1, in %[[VAL_1:.*]] : i1, out out : i1) { +// CHECK-IR: %[[VAL_2:.*]] = hw.instance "A_B" @A_B(p_clk: %[[VAL_1]]: i1, p_in: %[[VAL_0]]: i1) -> (p_out: i1) +// CHECK-IR: hw.output %[[VAL_2]] : i1 +// CHECK-IR: } + +// CHECK-VERILOG-LABEL: module A_B( +// CHECK-VERILOG: input p_clk, +// CHECK-VERILOG: p_in, +// CHECK-VERILOG: output p_out +// CHECK-VERILOG: ); +// CHECK-VERILOG: reg r; +// CHECK-VERILOG: always_ff @(posedge p_clk) +// CHECK-VERILOG: r <= p_in; +// CHECK-VERILOG: assign p_out = r; +// CHECK-VERILOG: endmodule + +// CHECK-VERILOG-LABEL: module A( +// CHECK-VERILOG: input in, +// CHECK-VERILOG: clk, +// CHECK-VERILOG: output out +// CHECK-VERILOG: ); +// CHECK-VERILOG: A_B A_B ( +// CHECK-VERILOG: .p_clk (clk), +// CHECK-VERILOG: .p_in (in), +// CHECK-VERILOG: .p_out (out) +// CHECK-VERILOG: ); +// CHECK-VERILOG: endmodule + +kanagawa.design @foo { +kanagawa.class sym @A { + %this = kanagawa.this @A + kanagawa.port.input "in" sym @in : i1 + kanagawa.port.output "out" sym @out : i1 + kanagawa.port.input "clk" sym @clk : !seq.clock + + kanagawa.container@B { + %B_this = kanagawa.this @B + %parent = kanagawa.path [ + #kanagawa.step> + ] + %a_in = kanagawa.get_port %parent, @in : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref + %a_clk = kanagawa.get_port %parent, @clk : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref + %a_out = kanagawa.get_port %parent, @out : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref + %in = kanagawa.port.read %a_in : !kanagawa.portref + %clk = kanagawa.port.read %a_clk : !kanagawa.portref + %r = seq.compreg %in, %clk: i1 + kanagawa.port.write %a_out, %r : !kanagawa.portref + } +} +} diff --git a/test/lit.cfg.py b/test/lit.cfg.py index 911bff304966..80042d0221c1 100644 --- a/test/lit.cfg.py +++ b/test/lit.cfg.py @@ -61,7 +61,7 @@ 'arcilator', 'circt-as', 'circt-capi-ir-test', 'circt-capi-om-test', 'circt-capi-firrtl-test', 'circt-capi-firtool-test', 'circt-dis', 'circt-lec', 'circt-reduce', 'circt-synth', 'circt-test', 'circt-translate', - 'firtool', 'hlstool', 'om-linker', 'ibistool' + 'firtool', 'hlstool', 'om-linker', 'kanagawatool' ] if "CIRCT_OPT_CHECK_IR_ROUNDTRIP" in os.environ: diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index a91b167fa521..d44f094d22e4 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -14,7 +14,7 @@ add_subdirectory(circt-translate) add_subdirectory(firtool) add_subdirectory(handshake-runner) add_subdirectory(hlstool) -add_subdirectory(ibistool) +add_subdirectory(kanagawatool) add_subdirectory(om-linker) add_subdirectory(py-split-input-file) diff --git a/tools/ibistool/CMakeLists.txt b/tools/kanagawatool/CMakeLists.txt similarity index 79% rename from tools/ibistool/CMakeLists.txt rename to tools/kanagawatool/CMakeLists.txt index d43246aaddda..e149f07cb245 100644 --- a/tools/ibistool/CMakeLists.txt +++ b/tools/kanagawatool/CMakeLists.txt @@ -2,11 +2,11 @@ set(LLVM_LINK_COMPONENTS Support ) -add_circt_tool(ibistool - ibistool.cpp +add_circt_tool(kanagawatool + kanagawatool.cpp ) -llvm_update_compile_flags(ibistool) -target_link_libraries(ibistool +llvm_update_compile_flags(kanagawatool) +target_link_libraries(kanagawatool PRIVATE CIRCTExportChiselInterface @@ -22,8 +22,8 @@ target_link_libraries(ibistool CIRCTCFToHandshake CIRCTSV CIRCTSVTransforms - CIRCTIbis - CIRCTIbisTransforms + CIRCTKanagawa + CIRCTKanagawaTransforms CIRCTTransforms CIRCTPipelineOps CIRCTPipelineToHW diff --git a/tools/ibistool/ibistool.cpp b/tools/kanagawatool/kanagawatool.cpp similarity index 80% rename from tools/ibistool/ibistool.cpp rename to tools/kanagawatool/kanagawatool.cpp index 64f2e7696325..ed406de9cb5a 100644 --- a/tools/ibistool/ibistool.cpp +++ b/tools/kanagawatool/kanagawatool.cpp @@ -1,4 +1,5 @@ -//===- ibistool.cpp - The ibistool utility for working with the Ibis dialect =// +//===- kanagawatool.cpp - The kanagawatool utility for working with the Kanagawa +//dialect =// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,8 +7,8 @@ // //===----------------------------------------------------------------------===// // -// This file implements 'ibistool', which composes together a variety of -// CIRCT libraries that can be used to realise an Ibis-based lowering flow. +// This file implements 'kanagawatool', which composes together a variety of +// CIRCT libraries that can be used to realise an Kanagawa-based lowering flow. // //===----------------------------------------------------------------------===// @@ -44,10 +45,10 @@ #include "circt/Dialect/DC/DCPasses.h" #include "circt/Dialect/ESI/ESIDialect.h" #include "circt/Dialect/ESI/ESIPasses.h" -#include "circt/Dialect/Ibis/IbisDialect.h" -#include "circt/Dialect/Ibis/IbisOps.h" -#include "circt/Dialect/Ibis/IbisPassPipelines.h" -#include "circt/Dialect/Ibis/IbisPasses.h" +#include "circt/Dialect/Kanagawa/KanagawaDialect.h" +#include "circt/Dialect/Kanagawa/KanagawaOps.h" +#include "circt/Dialect/Kanagawa/KanagawaPassPipelines.h" +#include "circt/Dialect/Kanagawa/KanagawaPasses.h" #include "circt/Dialect/Pipeline/PipelineDialect.h" #include "circt/Dialect/Pipeline/PipelinePasses.h" #include "circt/Dialect/SV/SVDialect.h" @@ -62,13 +63,13 @@ using namespace llvm; using namespace mlir; using namespace circt; -using namespace ibis; +using namespace kanagawa; // -------------------------------------------------------------------------- // Tool options // -------------------------------------------------------------------------- -static cl::OptionCategory mainCategory("ibistool Options"); +static cl::OptionCategory mainCategory("kanagawatool Options"); static cl::opt inputFilename(cl::Positional, cl::desc(""), @@ -107,7 +108,7 @@ static cl::opt cl::cat(mainCategory)); enum OutputFormatKind { - OutputLoweredIbis, + OutputLoweredKanagawa, OutputIR, OutputVerilog, OutputSplitVerilog @@ -116,8 +117,8 @@ enum OutputFormatKind { static cl::opt outputFormat( cl::desc("Specify output format:"), cl::values( - clEnumValN(OutputLoweredIbis, "post-ibis-ir", - "Emit IR after Ibis constructs have been lowered away"), + clEnumValN(OutputLoweredKanagawa, "post-kanagawa-ir", + "Emit IR after Kanagawa constructs have been lowered away"), clEnumValN(OutputIR, "ir", "Emit pre-emission IR"), clEnumValN(OutputVerilog, "verilog", "Emit Verilog"), clEnumValN(OutputSplitVerilog, "split-verilog", @@ -130,12 +131,12 @@ static cl::opt cl::desc("Add tracing to an iverilog simulated module"), cl::init(false), cl::cat(mainCategory)); -enum FlowKind { HiIbis, LoIbis }; -static cl::opt - flowKind(cl::desc("Specify flow kind:"), - cl::values(clEnumValN(HiIbis, "hi", "High-level Ibis flow"), - clEnumValN(LoIbis, "lo", "Low-level Ibis flow")), - cl::Required, cl::cat(mainCategory)); +enum FlowKind { HiKanagawa, LoKanagawa }; +static cl::opt flowKind( + cl::desc("Specify flow kind:"), + cl::values(clEnumValN(HiKanagawa, "hi", "High-level Kanagawa flow"), + clEnumValN(LoKanagawa, "lo", "Low-level Kanagawa flow")), + cl::Required, cl::cat(mainCategory)); static LoweringOptionsOption loweringOptions(mainCategory); @@ -162,8 +163,8 @@ static void loadHandshakeTransformsPipeline(OpPassManager &pm) { pm.addPass(circt::createInsertMergeBlocksPass()); // Perform dataflow conversion - pm.nest().nest().addPass( - ibis::createConvertCFToHandshakePass()); + pm.nest().nest().addPass( + kanagawa::createConvertCFToHandshakePass()); // Canonicalize - necessary after handshake conversion to clean up a lot of // stuff e.g. simple branches. pm.addPass(createSimpleCanonicalizerPass()); @@ -172,11 +173,13 @@ static void loadHandshakeTransformsPipeline(OpPassManager &pm) { } static void loadDCTransformsPipeline(OpPassManager &pm) { - pm.nest().nest().addPass( - ibis::createConvertHandshakeToDCPass()); + pm.nest().nest().addPass( + kanagawa::createConvertHandshakeToDCPass()); pm.addPass(createSimpleCanonicalizerPass()); - pm.nest().nest().nest().addPass( - dc::createDCMaterializeForksSinksPass()); + pm.nest() + .nest() + .nest() + .addPass(dc::createDCMaterializeForksSinksPass()); // pm.nest().addPass(circt::createDCToHWPass()); } @@ -205,27 +208,27 @@ static void loadHWLoweringPipeline(OpPassManager &pm) { static void loadSchedulingPipeline(OpPassManager &pm) { // Inject operator library - pm.addPass(ibis::createAddOperatorLibraryPass()); + pm.addPass(kanagawa::createAddOperatorLibraryPass()); // Map any arith operators to comb - pm.nest() - .nest() - .nest() - .nest() + pm.nest() + .nest() + .nest() + .nest() .addPass(circt::createMapArithToCombPass()); // Prepare for scheduling - pm.nest() - .nest() - .nest() - .nest() - .addPass(ibis::createPrepareSchedulingPass()); + pm.nest() + .nest() + .nest() + .nest() + .addPass(kanagawa::createPrepareSchedulingPass()); // Schedule! - pm.nest() - .nest() - .nest() - .nest() + pm.nest() + .nest() + .nest() + .nest() .addPass(pipeline::createScheduleLinearPipelinePass()); } @@ -256,31 +259,31 @@ static void loadLowLevelPassPipeline( } } -static void loadIbisHiFlow( +static void loadKanagawaHiFlow( PassManager &pm, ModuleOp module, std::optional> &outputFile) { if (verbosePassExecutions) - llvm::errs() << "[ibistool] Will run high-level Ibis flow\n"; + llvm::errs() << "[kanagawatool] Will run high-level Kanagawa flow\n"; loadHighLevelControlflowTransformsPipeline(pm); - loadIbisHighLevelPassPipeline(pm); - if (outputFormat != OutputLoweredIbis) { + loadKanagawaHighLevelPassPipeline(pm); + if (outputFormat != OutputLoweredKanagawa) { loadHandshakeTransformsPipeline(pm); loadSchedulingPipeline(pm); loadDCTransformsPipeline(pm); - if (outputFormat != OutputLoweredIbis) + if (outputFormat != OutputLoweredKanagawa) loadLowLevelPassPipeline(pm, module, outputFile); } } -static void loadIbisLoFlow( +static void loadKanagawaLoFlow( PassManager &pm, ModuleOp module, std::optional> &outputFile) { if (verbosePassExecutions) - llvm::errs() << "[ibistool] Will run low-level Ibis flow\n"; - loadIbisLowLevelPassPipeline(pm); + llvm::errs() << "[kanagawatool] Will run low-level Kanagawa flow\n"; + loadKanagawaLowLevelPassPipeline(pm); - if (outputFormat != OutputLoweredIbis) + if (outputFormat != OutputLoweredKanagawa) loadLowLevelPassPipeline(pm, module, outputFile); } @@ -292,7 +295,7 @@ static LogicalResult processBuffer( mlir::OwningOpRef module; llvm::sys::TimePoint<> parseStartTime; if (verbosePassExecutions) { - llvm::errs() << "[ibistool] Running MLIR parser\n"; + llvm::errs() << "[kanagawatool] Running MLIR parser\n"; parseStartTime = llvm::sys::TimePoint<>::clock::now(); } auto parserTimer = ts.nest("MLIR Parser"); @@ -305,8 +308,8 @@ static LogicalResult processBuffer( auto elpased = std::chrono::duration( llvm::sys::TimePoint<>::clock::now() - parseStartTime) / std::chrono::seconds(1); - llvm::errs() << "[ibistool] -- Done in " << llvm::format("%.3f", elpased) - << " sec\n"; + llvm::errs() << "[kanagawatool] -- Done in " + << llvm::format("%.3f", elpased) << " sec\n"; } // Apply any pass manager command line options. @@ -317,10 +320,10 @@ static LogicalResult processBuffer( return failure(); pm.addPass(createSimpleCanonicalizerPass()); - if (flowKind == HiIbis) - loadIbisHiFlow(pm, module.get(), outputFile); - else if (flowKind == LoIbis) - loadIbisLoFlow(pm, module.get(), outputFile); + if (flowKind == HiKanagawa) + loadKanagawaHiFlow(pm, module.get(), outputFile); + else if (flowKind == LoKanagawa) + loadKanagawaLoFlow(pm, module.get(), outputFile); // Go execute! if (failed(pm.run(module.get()))) @@ -374,7 +377,7 @@ processInput(MLIRContext &context, TimingScope &ts, llvm::outs()); } -static LogicalResult executeIbistool(MLIRContext &context) { +static LogicalResult executeKanagawatool(MLIRContext &context) { if (allowUnregisteredDialects) context.allowUnregisteredDialects(); @@ -411,10 +414,11 @@ static LogicalResult executeIbistool(MLIRContext &context) { return success(); } -/// Main driver for ibistool command. This sets up LLVM and MLIR, and parses -/// command line options before passing off to 'executeIbistool'. This is set -/// up so we can `exit(0)` at the end of the program to avoid teardown of the -/// MLIRContext and modules inside of it (reducing compile time). +/// Main driver for kanagawatool command. This sets up LLVM and MLIR, and +/// parses command line options before passing off to 'executeKanagawatool'. +/// This is set up so we can `exit(0)` at the end of the program to avoid +/// teardown of the MLIRContext and modules inside of it (reducing compile +/// time). int main(int argc, char **argv) { InitLLVM y(argc, argv); @@ -433,7 +437,7 @@ int main(int argc, char **argv) { registerAsmPrinterCLOptions(); // Parse pass names in main to ensure static initialization completed. - cl::ParseCommandLineOptions(argc, argv, "CIRCT Ibis tool\n"); + cl::ParseCommandLineOptions(argc, argv, "CIRCT Kanagawa tool\n"); DialectRegistry registry; // Register MLIR dialects. @@ -450,13 +454,14 @@ int main(int argc, char **argv) { mlir::registerCanonicalizerPass(); // Register CIRCT dialects. - registry.insert(); + registry + .insert(); - // Do the guts of the ibistool process. + // Do the guts of the kanagawatool process. MLIRContext context(registry); - auto result = executeIbistool(context); + auto result = executeKanagawatool(context); // Use "exit" instead of return'ing to signal completion. This avoids // invoking the MLIRContext destructor, which spends a bunch of time