[Kanagawa] Remove `%this` (#8097)

`%this` and the `ThisOp` isn't being used in practice, and is now pure overhead. This PR removes the `ThisOp` operation and any associated capabilities. Most notably, this includes referencing ports of the current scope, within the current scope, through `get_port` on the `ThisOp`. This, again, is a redundant pattern, that anyways were being canonicalized away to just directly reference the port.

Co-authored-by: Morten Borup Petersen <mpetersen@microsoft.com>
This commit is contained in:
Morten Borup Petersen 2025-01-21 09:38:54 +01:00 committed by GitHub
parent 6cfac8cd37
commit 443f007a3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
30 changed files with 4 additions and 337 deletions

View File

@ -68,8 +68,7 @@ def PortOpInterface : OpInterface<"PortOpInterface", [NamedInnerSymbol]> {
def ScopeOpInterface : OpInterface<"ScopeOpInterface", [NamedInnerSymbol]> {
let cppNamespace = "circt::kanagawa";
let description = [{
An interface for operations which define Kanagawa scopes, that can be referenced
by an `kanagawa.this` operation.
An interface for operations which define Kanagawa scopes.
}];
let verify = "return detail::verifyScopeOpInterface($_op);";
@ -82,20 +81,6 @@ def ScopeOpInterface : OpInterface<"ScopeOpInterface", [NamedInnerSymbol]> {
return $_op.getBodyBlock();
}]
>,
InterfaceMethod<
"Returns `%this` of the scope",
"mlir::TypedValue<ScopeRefType>", "getThis",
(ins), [{
return *detail::getThisFromScope($_op);
}]
>,
InterfaceMethod<
"Returns the `ThisOp` of this scope",
"Operation*", "getThisOp",
(ins), [{
return cast<ScopeOpInterface>($_op.getOperation()).getThis().getDefiningOp();
}]
>,
InterfaceMethod<
"Returns the symbol name of the scope",
"mlir::StringAttr", "getScopeName",

View File

@ -30,7 +30,6 @@
namespace circt {
namespace kanagawa {
class ContainerOp;
class ThisOp;
// Symbol name for the kanagawa operator library to be used during scheduling.
static constexpr const char *kKanagawaOperatorLibName =
@ -40,11 +39,6 @@ namespace detail {
// Verify that `op` conforms to the ScopeOpInterface.
LogicalResult verifyScopeOpInterface(Operation *op);
// 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<mlir::TypedValue<ScopeRefType>> getThisFromScope(Operation *op);
} // namespace detail
} // namespace kanagawa
} // namespace circt

View File

@ -539,35 +539,6 @@ def PathOp : KanagawaOp<"path", [
let hasCanonicalizeMethod = 1;
}
def ThisOp : KanagawaOp<"this", [
DeclareOpInterfaceMethods<InnerRefUserOpInterface>,
HasCustomSSAName
]> {
let summary = "Return a handle to the current scope `!kanagawa.scoperef`";
let arguments = (ins InnerRefAttr:$scopeName);
let results = (outs ScopeRefType:$thisRef);
let assemblyFormat = [{
$scopeName attr-dict custom<ScopeRefFromName>(type($thisRef), ref($scopeName))
}];
let builders = [
OpBuilder<(ins "StringAttr":$moduleName, "hw::InnerSymAttr":$sym), [{
auto name = $_builder.getAttr<hw::InnerRefAttr>(
FlatSymbolRefAttr::get(moduleName), sym.getSymName());
build($_builder, $_state, $_builder.getType<ScopeRefType>(name), name);
}]>,
OpBuilder<(ins "hw::InnerRefAttr":$name), [{
build($_builder, $_state, $_builder.getType<ScopeRefType>(name), name);
}]>
];
let extraClassDeclaration = [{
/// Return the scope operation which this accelerator refers to
ScopeOpInterface getScope(const hw::InnerRefNamespace &symbolTable);
}];
}
// ===---------------------------------------------------------------------===//
// Low-level Kanagawa operations
// ===---------------------------------------------------------------------===//
@ -713,7 +684,6 @@ def GetPortOp : KanagawaOp<"get_port", [
}]>
];
let hasCanonicalizeMethod = 1;
let extraClassDeclaration = [{
// Returns the direction requested by this get_port op.
kanagawa::Direction getDirection() {

View File

@ -7,15 +7,12 @@ kanagawa.design @foo {
// A class hierarchy with a shared parent, and accessing between the children
kanagawa.class sym @C1 {
%this = kanagawa.this <@foo::@C1>
%out = kanagawa.port.output "out" sym @out : i32
%c0 = hw.constant 42 : i32
kanagawa.port.write %out, %c0 : !kanagawa.portref<out i32>
}
kanagawa.class sym @C2 {
%this = kanagawa.this <@foo::@C2>
%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
@ -23,8 +20,6 @@ kanagawa.class sym @C2 {
%out_port = kanagawa.port.output "out" sym @out : i32
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).
@ -69,7 +64,6 @@ kanagawa.class sym @C2 {
}
kanagawa.class sym @Parent {
%this = kanagawa.this <@foo::@Parent>
%c1 = kanagawa.instance @c1, <@foo::@C1>
%c2 = kanagawa.instance @c2, <@foo::@C2>

View File

@ -43,7 +43,6 @@ static llvm::raw_string_ostream &genValueName(llvm::raw_string_ostream &os,
auto *definingOp = value.getDefiningOp();
assert(definingOp && "scoperef should always be defined by some op");
llvm::TypeSwitch<Operation *, void>(definingOp)
.Case<ThisOp>([&](auto op) { os << "this"; })
.Case<InstanceOp, ContainerInstanceOp>(
[&](auto op) { os << op.getInstanceNameAttr().strref(); })
.Case<PortOpInterface>([&](auto op) { os << op.getNameHint(); })
@ -84,23 +83,7 @@ static StringAttr genValueNameAttr(Value v) {
// ScopeOpInterface
//===----------------------------------------------------------------------===//
FailureOr<mlir::TypedValue<ScopeRefType>>
circt::kanagawa::detail::getThisFromScope(Operation *op) {
auto scopeOp = cast<ScopeOpInterface>(op);
auto thisOps = scopeOp.getBodyBlock()->getOps<kanagawa::ThisOp>();
if (thisOps.empty())
return op->emitOpError("must contain a 'kanagawa.this' operation");
if (std::next(thisOps.begin()) != thisOps.end())
return op->emitOpError("must contain only one 'kanagawa.this' operation");
return (*thisOps.begin()).getThisRef();
}
LogicalResult circt::kanagawa::detail::verifyScopeOpInterface(Operation *op) {
if (failed(getThisFromScope(op)))
return failure();
if (!isa<hw::InnerSymbolOpInterface>(op))
return op->emitOpError("must implement 'InnerSymbolOpInterface'");
@ -322,46 +305,10 @@ PortOpInterface GetPortOp::getPort(const hw::InnerRefNamespace &ns) {
targetScope.lookupInnerSym(getPortSymbol()));
}
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) -> kanagawa.port.#
auto parentScope = dyn_cast<ScopeOpInterface>(op->getParentOp());
if (parentScope) {
auto scopeThis = parentScope.getThis();
if (op.getInstance() == scopeThis) {
auto definingPort = parentScope.lookupPort(op.getPortSymbol());
rewriter.replaceOp(op, {definingPort.getPort()});
return success();
}
}
return failure();
}
void GetPortOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getResult(), genValueNameAttr(getResult()));
}
//===----------------------------------------------------------------------===//
// ThisOp
//===----------------------------------------------------------------------===//
LogicalResult ThisOp::verifyInnerRefs(hw::InnerRefNamespace &ns) {
if (!getScope(ns))
return emitOpError() << "'" << getScopeName() << "' does not exist";
return success();
}
void ThisOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
setNameFn(getResult(), "this");
}
ScopeOpInterface ThisOp::getScope(const hw::InnerRefNamespace &ns) {
return ns.lookupOp<ScopeOpInterface>(getScopeNameAttr());
}
//===----------------------------------------------------------------------===//
// PortReadOp
//===----------------------------------------------------------------------===//

View File

@ -58,15 +58,6 @@ struct OutlineContainerPattern : public OpConversionPattern<ContainerOp> {
rewriter.mergeBlocks(op.getBodyBlock(), newContainer.getBodyBlock(), {});
// Rename the kanagawa.this operation to refer to the proper op.
auto thisOp =
cast<ThisOp>(cast<ScopeOpInterface>(*newContainer.getOperation())
.getThis()
.getDefiningOp());
rewriter.setInsertionPoint(thisOp);
rewriter.replaceOpWithNewOp<ThisOp>(thisOp, design.getSymNameAttr(),
newContainer.getInnerSymAttr());
// Create a container instance op in the parent class.
rewriter.setInsertionPoint(op);
rewriter.create<ContainerInstanceOp>(

View File

@ -193,19 +193,6 @@ struct ContainerOpConversionPattern : public OpConversionPattern<ContainerOp> {
ContainerHWModSymbolMap &modSymMap;
};
struct ThisOpConversionPattern : public OpConversionPattern<ThisOp> {
ThisOpConversionPattern(MLIRContext *ctx)
: OpConversionPattern<ThisOp>(ctx) {}
LogicalResult
matchAndRewrite(ThisOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
// TODO: remove this op from the dialect - not needed anymore.
rewriter.eraseOp(op);
return success();
}
};
struct ContainerInstanceOpConversionPattern
: public OpConversionPattern<ContainerInstanceOp> {
@ -369,7 +356,7 @@ void ContainersToHWPass::runOnOperation() {
modSymCache.addDefinitions(getOperation());
Namespace modNamespace;
modNamespace.add(modSymCache);
target.addIllegalOp<ContainerOp, ContainerInstanceOp, ThisOp>();
target.addIllegalOp<ContainerOp, ContainerInstanceOp>();
target.markUnknownOpDynamicallyLegal([](Operation *) { return true; });
// Remove the name of the kanagawa.design's from the namespace - The
@ -390,7 +377,6 @@ void ContainersToHWPass::runOnOperation() {
patterns.add<ContainerOpConversionPattern>(ctx, modNamespace, portOrder,
modSymMap);
patterns.add<ContainerInstanceOpConversionPattern>(ctx, portOrder, modSymMap);
patterns.add<ThisOpConversionPattern>(ctx);
if (failed(
applyPartialConversion(getOperation(), target, std::move(patterns))))

View File

@ -44,11 +44,6 @@ struct DataflowMethodOpConversion
op.getLoc(), op.getInnerSym(), /*isTopLevel=*/false);
rewriter.setInsertionPointToStart(newContainer.getBodyBlock());
// Create mandatory %this
// TODO @mortbopet: this will most likely already be present at the
// method.df level soon...
rewriter.create<ThisOp>(op.getLoc(), newContainer.getInnerRef());
// Create in- and output ports.
llvm::SmallVector<Value> argValues;
for (auto [arg, name] : llvm::zip_equal(

View File

@ -1,7 +1,6 @@
// 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) {
@ -15,7 +14,6 @@
kanagawa.design @foo {
kanagawa.class sym @Argify {
%this = kanagawa.this <@foo::@Argify>
kanagawa.method @foo() {
%c32 = hw.constant 32 : i32

View File

@ -41,7 +41,6 @@
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.

View File

@ -2,14 +2,12 @@
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<out i1>
// 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
@ -24,7 +22,6 @@ kanagawa.container sym @C {
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<out i1>
@ -32,21 +29,18 @@ kanagawa.design @D {
// 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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref<out i1>
// 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<in i1>
}
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<out i1>
%in = kanagawa.port.read %in_ref : !kanagawa.portref<out i1>
@ -59,12 +53,10 @@ kanagawa.container sym @ParentReader {
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<in i1>
// CHECK: "foo.bar"(%[[VAL_3:.*]]) : (i1) -> ()
@ -72,7 +64,6 @@ kanagawa.container sym @Foo {
// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3]] : !kanagawa.portref<in i1>
// 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 i1>
%in_rd_ref = kanagawa.get_port %f, @in : !kanagawa.scoperef<@D::@Foo> -> !kanagawa.portref<out i1>

View File

@ -7,7 +7,6 @@ kanagawa.design @foo {
// 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>
@ -16,22 +15,17 @@ kanagawa.design @foo {
// 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>
}
}

View File

@ -15,7 +15,6 @@ kanagawa.design @D {
// 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"}
@ -26,14 +25,12 @@ kanagawa.container "MyB" sym @B {
}
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<out i1>
%p_b_out.val = kanagawa.port.read %p_b_out : !kanagawa.portref<in i1>
}
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<in i1>
%b.out.ref.val = kanagawa.port.read %b.out.ref : !kanagawa.portref<out i1>
@ -63,7 +60,6 @@ kanagawa.design @D {
// 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<in i1>
@ -99,13 +95,11 @@ kanagawa.design @D {
// 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<out i1>
}
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 i1>
@ -124,7 +118,6 @@ 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
@ -153,11 +146,9 @@ kanagawa.container sym @Top {
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>
}
}
@ -173,6 +164,5 @@ hw.module.extern @Foo(in %theExternModule : i1)
kanagawa.design @D {
kanagawa.container "D" sym @D top_level {
%this = kanagawa.this <@D::@D>
}
}

View File

@ -4,7 +4,6 @@
// 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<i32>) -> !dc.value<i32> {
// CHECK: %[[VAL_2:.*]], %[[VAL_3:.*]] = dc.unpack %[[VAL_1]] : !dc.value<i32>
// CHECK: %[[VAL_4:.*]]:2 = dc.fork [2] %[[VAL_2]]
@ -20,7 +19,6 @@
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 {

View File

@ -4,7 +4,6 @@
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
@ -13,7 +12,6 @@ kanagawa.design @foo {
// 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} {
@ -25,7 +23,6 @@ kanagawa.class sym @Inline1 {
}
// 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}
@ -41,7 +38,6 @@ kanagawa.class sym @Inline1 {
// 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} {

View File

@ -1,9 +1,7 @@
// 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<i32>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref<in !dc.value<i32>>
// CHECK: %[[VAL_4:.*]] = kanagawa.port.output "out0" sym @out0 : !dc.value<i32>
@ -21,7 +19,6 @@
kanagawa.design @foo {
kanagawa.class sym @ToContainers {
%this = kanagawa.this <@foo::@ToContainers>
kanagawa.method.df @foo(%arg0: !dc.value<i32>) -> !dc.value<i32> {
%token, %output = dc.unpack %arg0 : !dc.value<i32>
%0:2 = dc.fork [2] %token

View File

@ -8,7 +8,6 @@
kanagawa.design @foo {
kanagawa.container sym @D_up {
%this = kanagawa.this <@foo::@D_up>
%d = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef>,
#kanagawa.step<parent : !kanagawa.scoperef>,
@ -32,39 +31,31 @@ kanagawa.container sym @D_up {
%clk_out_val = kanagawa.port.read %clk_out_ref : !kanagawa.portref<out i1>
}
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<in i1>

View File

@ -3,20 +3,17 @@
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<out i1>
// CHECK: %[[VAL_3]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref<in i1>
// 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<out i1>
%p_b_out_val = kanagawa.port.read %p_b_out : !kanagawa.portref<in !kanagawa.portref<out i1>>
%p_b_in = kanagawa.port.input "p_b_in" sym @p_b_in : !kanagawa.portref<in i1>
@ -28,7 +25,6 @@ kanagawa.container sym @AccessSibling {
}
// 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<in i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_4:.*]] : !kanagawa.portref<out i1>
@ -41,7 +37,6 @@ kanagawa.container sym @AccessSibling {
// CHECK: %[[VAL_7]] = kanagawa.get_port %[[VAL_8]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<in i1>
// 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<in !kanagawa.portref<out i1>>
kanagawa.port.write %a.p_b_out, %b.out : !kanagawa.portref<in !kanagawa.portref<out i1>>
@ -60,12 +55,10 @@ 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<in i1>
%p_in_val = kanagawa.port.read %p_in : !kanagawa.portref<in !kanagawa.portref<in i1>>
%p_out = kanagawa.port.input "p_out" sym @p_out : !kanagawa.portref<out i1>
@ -73,7 +66,6 @@ kanagawa.container sym @ParentPortAccess {
}
// 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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref<out i1>
@ -85,7 +77,6 @@ kanagawa.container sym @ParentPortAccess {
// 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<in !kanagawa.portref<in i1>>
kanagawa.port.write %c.p_in, %in : !kanagawa.portref<in !kanagawa.portref<in i1>>
@ -105,14 +96,12 @@ 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<out i1>
// 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<in i1>
// 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<in i1>
%parent_parent_c2_c3_out = kanagawa.port.input "parent_parent_c2_c3_out" sym @parent_parent_c2_c3_out : !kanagawa.portref<out i1>
@ -124,7 +113,6 @@ kanagawa.container sym @C1 {
}
// 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<in i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<out i1>
@ -136,7 +124,6 @@ kanagawa.container sym @C1 {
// CHECK: kanagawa.port.write %[[VAL_6]], %[[VAL_7]] : !kanagawa.portref<out i1>
// 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<in i1>
%c3.out = kanagawa.get_port %c3, @out : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<out i1>
@ -146,13 +133,11 @@ kanagawa.container sym @C2 {
kanagawa.port.write %parent_parent_c2_c3_out, %c3.out : !kanagawa.portref<out !kanagawa.portref<out i1>>
}
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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref<out i1>
@ -164,7 +149,6 @@ kanagawa.container sym @C {
// 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<in !kanagawa.portref<in i1>>
kanagawa.port.write %c1.parent_parent_c2_c3_in, %0 : !kanagawa.portref<in !kanagawa.portref<in i1>>
@ -177,7 +161,6 @@ kanagawa.container sym @P1 {
}
// 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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.read %[[VAL_2]] : !kanagawa.portref<out i1>
@ -193,7 +176,6 @@ kanagawa.container sym @P1 {
// CHECK: kanagawa.port.write %[[VAL_10]], %[[VAL_9]] : !kanagawa.portref<in i1>
// 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<in !kanagawa.portref<in i1>>
kanagawa.port.write %p1.parent_parent_c2_c3_in, %1 : !kanagawa.portref<in !kanagawa.portref<in i1>>
@ -214,12 +196,10 @@ 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<in i1>
%p_out.val = kanagawa.port.read %p_out : !kanagawa.portref<in !kanagawa.portref<in i1>>
%p_in = kanagawa.port.input "p_in" sym @p_in : !kanagawa.portref<out i1>
@ -227,7 +207,6 @@ kanagawa.container sym @AccessParent {
}
// 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<in i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.wire.output @in.rd, %[[VAL_2]] : i1
@ -243,7 +222,6 @@ kanagawa.container sym @AccessParent {
// CHECK: kanagawa.port.write %[[VAL_10]], %[[VAL_11]] : !kanagawa.portref<in i1>
// 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 i1>
%in.rd = kanagawa.wire.output @in.rd, %in.val : i1

View File

@ -13,7 +13,6 @@
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

View File

@ -1,7 +1,6 @@
// 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
@ -28,7 +27,6 @@
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

View File

@ -17,7 +17,6 @@
// CHECK: }
// 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
@ -46,7 +45,6 @@
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

View File

@ -3,20 +3,17 @@
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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<in i1>
// CHECK-NEXT: }
kanagawa.container sym @AccessChild {
%this = kanagawa.this <@D::@AccessChild>
%c = kanagawa.container.instance @c, <@D::@C>
%c_ref = kanagawa.path [
#kanagawa.step<child , @c : !kanagawa.scoperef<@D::@C>>
@ -32,20 +29,17 @@ kanagawa.container sym @AccessChild {
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<out i1>
// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "[[VAL_3]]" sym @[[VAL_3]] : !kanagawa.portref<in i1>
// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref<in !kanagawa.portref<in i1>>
// CHECK: }
kanagawa.container sym @AccessSibling {
%this = kanagawa.this <@D::@AccessSibling>
%sibling = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef>,
#kanagawa.step<child , @b : !kanagawa.scoperef<@D::@C>>
@ -55,7 +49,6 @@ kanagawa.container sym @AccessSibling {
}
// 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<in !kanagawa.portref<out i1>>
// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
@ -66,7 +59,6 @@ kanagawa.container sym @AccessSibling {
// CHECK: %[[VAL_5]] = kanagawa.get_port %[[VAL_6]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<in i1>
// CHECK: }
kanagawa.container sym @Parent {
%this = kanagawa.this <@D::@Parent>
%a = kanagawa.container.instance @a, <@D::@AccessSibling>
%b = kanagawa.container.instance @b, <@D::@C>
}
@ -81,14 +73,12 @@ kanagawa.container sym @Parent {
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<out i1>
// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "p_p_c2_c3_in.wr" sym @p_p_c2_c3_in.wr : !kanagawa.portref<in i1>
// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref<in !kanagawa.portref<in i1>>
// CHECK: }
kanagawa.container sym @C1 {
%this = kanagawa.this <@D::@C1>
%c3 = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef>,
#kanagawa.step<parent : !kanagawa.scoperef>,
@ -100,7 +90,6 @@ kanagawa.container sym @C1 {
}
// 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<out i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.get_port %[[VAL_1]], @in : !kanagawa.scoperef<@D::@C> -> !kanagawa.portref<in i1>
@ -110,18 +99,15 @@ kanagawa.container sym @C1 {
// CHECK: kanagawa.port.write %[[VAL_5]], %[[VAL_3]] : !kanagawa.portref<out !kanagawa.portref<in i1>>
// 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<in !kanagawa.portref<out i1>>
// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
@ -133,12 +119,10 @@ kanagawa.container sym @C {
// CHECK: %[[VAL_5]] = kanagawa.port.read %[[VAL_7]] : !kanagawa.portref<in !kanagawa.portref<in i1>>
// 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<in !kanagawa.portref<out i1>>
// CHECK: kanagawa.port.write %[[VAL_2]], %[[VAL_3:.*]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
@ -151,7 +135,6 @@ kanagawa.container sym @P1 {
// CHECK: %[[VAL_3]] = kanagawa.port.read %[[VAL_8]] : !kanagawa.portref<out !kanagawa.portref<out i1>>
// CHECK: }
kanagawa.container sym @P2 {
%this = kanagawa.this <@D::@P2>
%p1 = kanagawa.container.instance @p1, <@D::@P1>
%c2 = kanagawa.container.instance @c2, <@D::@C2>
}
@ -163,14 +146,12 @@ kanagawa.container sym @P2 {
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<in i1>
// CHECK: %[[VAL_2:.*]] = kanagawa.port.read %[[VAL_1]] : !kanagawa.portref<in !kanagawa.portref<in i1>>
// CHECK: %[[VAL_3:.*]] = kanagawa.port.input "p_in.rd" sym @p_in.rd : !kanagawa.portref<out i1>
// CHECK: %[[VAL_4:.*]] = kanagawa.port.read %[[VAL_3]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
// CHECK: }
kanagawa.container sym @AccessParent {
%this = kanagawa.this <@D::@AccessParent>
%p = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef<@D::@Parent>>
]
@ -184,7 +165,6 @@ kanagawa.container sym @AccessParent {
}
// 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<in i1>
// CHECK: %[[VAL_3:.*]] = kanagawa.wire.output @in.rd, %[[VAL_2]] : i1
@ -198,7 +178,6 @@ kanagawa.container sym @AccessParent {
// CHECK: kanagawa.port.write %[[VAL_9]], %[[VAL_3]] : !kanagawa.portref<in !kanagawa.portref<out i1>>
// 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>
@ -212,7 +191,6 @@ kanagawa.container sym @Parent {
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
}
@ -249,7 +227,6 @@ kanagawa.design @D {
// tunneling.
kanagawa.container sym @D_up {
%this = kanagawa.this <@D::@D_up>
%d = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef>,
#kanagawa.step<parent : !kanagawa.scoperef>,
@ -273,39 +250,31 @@ kanagawa.container sym @D_up {
%clk_out_val = kanagawa.port.read %clk_out_ref : !kanagawa.portref<out i1>
}
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<in i1>

View File

@ -18,7 +18,6 @@
kanagawa.design @foo {
kanagawa.class sym @C {
%this = kanagawa.this <@foo::@C>
kanagawa.method @getAndSet(%x: ui32) -> ui32 {
kanagawa.return %x : ui32
}
@ -49,7 +48,6 @@ kanagawa.class sym @C {
// PREP: [[CALLRES2:%.+]] = kanagawa.call <@foo::@getAndSet>([[STRUCT2]]) : (!hw.struct<x: ui32>) -> 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

View File

@ -2,12 +2,10 @@
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 [
@ -21,17 +19,14 @@ kanagawa.container sym @Orphan {
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 [

View File

@ -2,35 +2,14 @@
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<in i1>) -> ()
// 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<in i1>
"foo.user"(%p2) : (!kanagawa.portref<in i1>) -> ()
}
}
// -----
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<child , @c : !kanagawa.scoperef<@foo::@C>>

View File

@ -2,7 +2,6 @@
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
@ -13,7 +12,6 @@ kanagawa.class sym @C {
// -----
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')}}
@ -24,27 +22,8 @@ kanagawa.class sym @C {
// -----
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<parent , @a : !kanagawa.scoperef>]
}
@ -54,7 +33,6 @@ kanagawa.class sym @PathStepParentWithInstanceName {
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<parent : i1>]
}
@ -64,7 +42,6 @@ kanagawa.class sym @PathStepInvalidType {
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<child : !kanagawa.scoperef<@foo::@A>>]
}
@ -74,7 +51,6 @@ kanagawa.class sym @PathStepChildMissingSymbol {
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
}
@ -84,7 +60,6 @@ kanagawa.class sym @InvalidVar {
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}}

View File

@ -1,18 +1,7 @@
// 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<in i1>
}
}
// -----
kanagawa.design @foo {
kanagawa.class sym @InvalidGetVar2 {
%this = kanagawa.this <@foo::@InvalidGetVar2>
kanagawa.var @var : memref<i32>
kanagawa.method @foo() {
%parent = kanagawa.path [
@ -29,7 +18,6 @@ kanagawa.class sym @InvalidGetVar2 {
kanagawa.design @foo {
kanagawa.class sym @InvalidGetVar {
%this = kanagawa.this <@foo::@InvalidGetVar>
kanagawa.var @var : memref<i32>
kanagawa.method @foo() {
%parent = kanagawa.path [
@ -42,22 +30,11 @@ kanagawa.class sym @InvalidGetVar {
}
}
// -----
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<in i2>
}
}
// -----
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<child , @a : !kanagawa.scoperef<@foo::@A>>]
}
@ -67,7 +44,6 @@ kanagawa.class sym @PathStepNonExistingChild {
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<parent : !kanagawa.scoperef>]
}

View File

@ -3,7 +3,6 @@
kanagawa.design @foo {
// CHECK-LABEL: kanagawa.class sym @HighLevel {
// CHECK-NEXT: %this = kanagawa.this <@foo::@HighLevel>
// CHECK-NEXT: kanagawa.var @single : memref<i32>
// CHECK-NEXT: kanagawa.var @array : memref<10xi32>
// CHECK-NEXT: kanagawa.method @foo() -> (i32, i32) {
@ -27,7 +26,6 @@ kanagawa.design @foo {
kanagawa.class sym @HighLevel {
%this = kanagawa.this <@foo::@HighLevel>
kanagawa.var @single : memref<i32>
kanagawa.var @array : memref<10xi32>
@ -55,14 +53,12 @@ kanagawa.class sym @HighLevel {
// 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
@ -70,12 +66,11 @@ kanagawa.class sym @HighLevel {
// 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<parent : !kanagawa.scoperef<@foo::@LowLevel>> : !kanagawa.scoperef<@foo::@LowLevel>]
// CHECK-NEXT: %parent.LowLevel_in.ref = kanagawa.get_port %parent, @LowLevel_in : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref<in i1>
// CHECK-NEXT: %parent.LowLevel_out.ref = kanagawa.get_port %parent, @LowLevel_out : !kanagawa.scoperef<@foo::@LowLevel> -> !kanagawa.portref<out i1>
// CHECK-NEXT: %true_1 = hw.constant true
// CHECK-NEXT: kanagawa.port.write %parent.LowLevel_in.ref, %true_1 : !kanagawa.portref<in i1>
// CHECK-NEXT: %true_0 = hw.constant true
// CHECK-NEXT: kanagawa.port.write %parent.LowLevel_in.ref, %true_0 : !kanagawa.portref<in i1>
// CHECK-NEXT: %parent.LowLevel_out.ref.val = kanagawa.port.read %parent.LowLevel_out.ref : !kanagawa.portref<out i1>
// CHECK-NEXT: %parent.a = kanagawa.path [#kanagawa.step<parent : !kanagawa.scoperef> : !kanagawa.scoperef, #kanagawa.step<child, @a : !kanagawa.scoperef<@foo::@A>> : !kanagawa.scoperef<@foo::@A>]
// CHECK-NEXT: %parent.a.in.ref = kanagawa.get_port %parent.a, @in : !kanagawa.scoperef<@foo::@A> -> !kanagawa.portref<in i1>
@ -86,19 +81,16 @@ kanagawa.class sym @HighLevel {
// 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
@ -110,7 +102,6 @@ kanagawa.class sym @LowLevel {
%a = kanagawa.instance @a, <@foo::@A>
kanagawa.container sym @D {
%this_d = kanagawa.this <@foo::@D>
%parent_C = kanagawa.path [
#kanagawa.step<parent : !kanagawa.scoperef<@foo::@LowLevel>>
]
@ -136,7 +127,6 @@ kanagawa.class sym @LowLevel {
}
kanagawa.container "ThisName" sym @ThisSymbol {
%this2 = kanagawa.this <@foo::@ThisSymbol>
}
}

View File

@ -1,7 +1,6 @@
// RUN: kanagawatool --hi --post-kanagawa-ir %s | FileCheck %s
// 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
@ -48,7 +47,6 @@
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

View File

@ -57,13 +57,11 @@
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<parent : !kanagawa.scoperef<@foo::@A>>
]