From 4429fff2454de411982ddcc5141e0cd7b45cc55c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:01:40 +0200 Subject: [PATCH 001/187] result io name --- lib/Analysis/NameAnalysis.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index f014bac6f9..f122292e8a 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -96,9 +96,10 @@ static bool tryToGetBlockArgName(BlockArgument arg, StringRef parentOpName, /// handshake::NamedIOInterface interface or, failing that, is its index. static std::string getResultName(Operation *op, size_t resIdx) { std::string oprName; - if (auto namedIO = dyn_cast(op)) - return namedIO.getResultName(resIdx); - return std::to_string(resIdx); + auto namedIO = dyn_cast(op); + op->emitError("missing named io interface";) + assert(namedIO) + return namedIO.getResultName(resIdx); } /// Returns the name of an operand which is either provided by the From 130beba5b28600258dbf761fe325e77d767ba547 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:03:04 +0200 Subject: [PATCH 002/187] typo --- lib/Analysis/NameAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index f122292e8a..3a1ddd3d33 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -97,7 +97,7 @@ static bool tryToGetBlockArgName(BlockArgument arg, StringRef parentOpName, static std::string getResultName(Operation *op, size_t resIdx) { std::string oprName; auto namedIO = dyn_cast(op); - op->emitError("missing named io interface";) + op->emitError("missing named io interface"); assert(namedIO) return namedIO.getResultName(resIdx); } From 5924e83a2524ee3bc023e202761fbf7678883305 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:03:33 +0200 Subject: [PATCH 003/187] typo --- lib/Analysis/NameAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 3a1ddd3d33..0f7b61252e 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -98,7 +98,7 @@ static std::string getResultName(Operation *op, size_t resIdx) { std::string oprName; auto namedIO = dyn_cast(op); op->emitError("missing named io interface"); - assert(namedIO) + assert(namedIO); return namedIO.getResultName(resIdx); } From f57bed11e01422a681a6675a4ade946258629f13 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:11:29 +0200 Subject: [PATCH 004/187] remove default implementations --- .../Dialect/Handshake/HandshakeInterfaces.td | 51 ++----------------- 1 file changed, 4 insertions(+), 47 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index a2b4041346..f127808777 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -149,56 +149,13 @@ def NamedIOInterface : OpInterface<"NamedIOInterface"> { [{"Provides detailed names for the operands and results of an operation."}]; let methods = [ - StaticInterfaceMethod< - "Returns the default name of a specific operand.", - "std::string", "getDefaultOperandName", (ins "unsigned" : $idx), - "", - [{ - return "ins_" + std::to_string(idx); - }]>, - StaticInterfaceMethod< - "Returns the default name of a specific result.", - "std::string", "getDefaultResultName", (ins "unsigned" : $idx), - "", - [{ - return "outs_" + std::to_string(idx); - }]>, InterfaceMethod< "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - - // Operations which always have a single operand get a specific port - // name for it - if (concreteOp.template hasTrait()) { - assert(idx == 0 && "index too high"); - return "ins"; - } - - // Generic input name - assert(idx < concreteOp->getNumOperands() && "index too high"); - return getDefaultOperandName(idx); - }]>, + "std::string", "getOperandName", (ins "unsigned" : $idx)>, InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - - // Operations which always have a single result get a specific port - // name for it - if (concreteOp.template hasTrait()) { - assert(idx == 0 && "index too high"); - return "outs"; - } - - // Generic output name - assert(idx < concreteOp->getNumResults() && "index too high"); - return getDefaultResultName(idx); - }]> + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx) + > ]; } From b925da3344f72bf80be44020a365e2f0b6e88de8 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:14:52 +0200 Subject: [PATCH 005/187] remove default naming --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 115 +++++++++--------- 1 file changed, 60 insertions(+), 55 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 8bd260b861..9cc1d158fe 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -34,66 +34,71 @@ using namespace dynamatic::handshake; PortNamer::PortNamer(Operation *op) { assert(op && "cannot generate port names for null operation"); - if (auto namedOpInterface = dyn_cast(op)) - inferFromNamedOpInterface(namedOpInterface); - else if (auto funcOp = dyn_cast(op)) + if (auto funcOp = dyn_cast(op)){ inferFromFuncOp(funcOp); - else - inferDefault(op); -} + return; + } -void PortNamer::infer(Operation *op, IdxToStrF &inF, IdxToStrF &outF) { - for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) - inputs.push_back(inF(idx)); - for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) - outputs.push_back(outF(idx)); - - // The Handshake terminator forwards its non-memory inputs to its outputs, so - // it needs port names for them - if (handshake::EndOp endOp = dyn_cast(op)) { - handshake::FuncOp funcOp = endOp->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - size_t numResults = funcOp.getFunctionType().getNumResults(); - for (size_t idx = 0, e = numResults; idx < e; ++idx) - outputs.push_back(endOp.getDefaultResultName(idx)); + auto namedOpInterface = dyn_cast(op); + if (!namedOpInterface){ + op->emitError("all normal operations must specify port names"); + assert(false); } + inferFromNamedOpInterface(namedOpInterface); } -void PortNamer::inferDefault(Operation *op) { - llvm::TypeSwitch(op) - .Case([&](auto) { - infer( - op, [](unsigned idx) { return idx == 0 ? "lhs" : "rhs"; }, - [](unsigned idx) { return "result"; }); - }) - .Case( - [&](auto) { - infer( - op, [](unsigned idx) { return "ins"; }, - [](unsigned idx) { return "outs"; }); - }) - .Case([&](auto) { - infer( - op, - [](unsigned idx) { - if (idx == 0) - return "condition"; - if (idx == 1) - return "trueValue"; - return "falseValue"; - }, - [](unsigned idx) { return "result"; }); - }) - .Default([&](auto) { - infer( - op, [](unsigned idx) { return "in" + std::to_string(idx); }, - [](unsigned idx) { return "out" + std::to_string(idx); }); - }); -} +// void PortNamer::infer(Operation *op, IdxToStrF &inF, IdxToStrF &outF) { +// for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) +// inputs.push_back(inF(idx)); +// for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) +// outputs.push_back(outF(idx)); + +// // The Handshake terminator forwards its non-memory inputs to its outputs, so +// // it needs port names for them +// if (handshake::EndOp endOp = dyn_cast(op)) { +// handshake::FuncOp funcOp = endOp->getParentOfType(); +// assert(funcOp && "end must be child of handshake function"); +// size_t numResults = funcOp.getFunctionType().getNumResults(); +// for (size_t idx = 0, e = numResults; idx < e; ++idx) +// outputs.push_back(endOp.getDefaultResultName(idx)); +// } +// } + +// void PortNamer::inferDefault(Operation *op) { +// llvm::TypeSwitch(op) +// .Case([&](auto) { +// infer( +// op, [](unsigned idx) { return idx == 0 ? "lhs" : "rhs"; }, +// [](unsigned idx) { return "result"; }); +// }) +// .Case( +// [&](auto) { +// infer( +// op, [](unsigned idx) { return "ins"; }, +// [](unsigned idx) { return "outs"; }); +// }) +// .Case([&](auto) { +// infer( +// op, +// [](unsigned idx) { +// if (idx == 0) +// return "condition"; +// if (idx == 1) +// return "trueValue"; +// return "falseValue"; +// }, +// [](unsigned idx) { return "result"; }); +// }) +// .Default([&](auto) { +// infer( +// op, [](unsigned idx) { return "in" + std::to_string(idx); }, +// [](unsigned idx) { return "out" + std::to_string(idx); }); +// }); +// } void PortNamer::inferFromNamedOpInterface(handshake::NamedIOInterface namedIO) { auto inF = [&](unsigned idx) { return namedIO.getOperandName(idx); }; From f0253fc6f0cb5f478dc757b815b2016021232dfd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:20:09 +0200 Subject: [PATCH 006/187] remove default calls --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 9cc1d158fe..3ecdb370b8 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -123,7 +123,7 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { std::string handshake::MuxOp::getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : getDefaultOperandName(idx - 1); + return idx == 0 ? "index" : "ins_" + std::string(idx - 1); } std::string handshake::ControlMergeOp::getResultName(unsigned idx) { @@ -153,7 +153,7 @@ std::string handshake::EndOp::getOperandName(unsigned idx) { unsigned numResults = funcOp.getFunctionType().getNumResults(); if (idx < numResults) - return getDefaultOperandName(idx); + return "ins_" + std::to_string(idx); return "memDone_" + std::to_string(idx - numResults); } From b26a4718f35a9f8cfe60b7038d0613fb27617f76 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:27:24 +0200 Subject: [PATCH 007/187] typo --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 3ecdb370b8..c3c0acea99 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -123,7 +123,7 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { std::string handshake::MuxOp::getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : "ins_" + std::string(idx - 1); + return idx == 0 ? "index" : "ins_" + std::to_string(idx - 1); } std::string handshake::ControlMergeOp::getResultName(unsigned idx) { From 939573be1b6ec4ab2a18cdffddc2a8dac5e6a211 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:46:18 +0200 Subject: [PATCH 008/187] custom and simple --- .../Dialect/Handshake/HandshakeInterfaces.td | 33 ++++++++++++++++++- .../Dialect/Handshake/HandshakeOps.td | 10 +++--- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 10 ++++++ 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index f127808777..67b0d441b7 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -143,7 +143,7 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { ]; } -def NamedIOInterface : OpInterface<"NamedIOInterface"> { +def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = [{"Provides detailed names for the operands and results of an operation."}]; @@ -159,6 +159,37 @@ def NamedIOInterface : OpInterface<"NamedIOInterface"> { ]; } +def SimpleNamedIOInterface : OpInterface<"SimpleIOInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Provides detailed names for the operands and results of an operation."}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + + // Simple input name + assert(idx < concreteOp->getNumOperands() && "index too high"); + return simpleInputPortName(idx); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + + // Generic output name + assert(idx < concreteOp->getNumResults() && "index too high"); + return simpleOutputPortName(idx); + }]> + ]; +} + def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index a68af2eb0b..b47d382745 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -30,7 +30,6 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, - DeclareOpInterfaceMethods, DeclareOpInterfaceMethods]> { } @@ -323,9 +322,12 @@ def NDWireOp : Handshake_Op<"ndwire", [ }]; } -class Handshake_ForkOp traits = []> : +class Handshake_ForkOp traits = []> : Handshake_Op { let arguments = (ins HandshakeType:$operand); let results = (outs Variadic:$result); @@ -338,7 +340,7 @@ class Handshake_ForkOp traits = []> : }]> ]; - let assemblyFormat = [{ + let assemblyFormat = [{ custom($operand, attr-dict, type($operand), type($result)) }]; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index c3c0acea99..9ee231e8e1 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -368,4 +368,14 @@ TypedValue LSQOp::getCtrlEnd() { return cast>(getOperands().back()); } +namespace{ + std::string simpleInputPortName(int idx){ + return "ins_" + std::to_string(idx); + } + + std::string simpleOutputPortName(int idx){ + return "outs_" + std::to_string(idx); + } +} + #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" From da229b5dfdc036256f09179884827e30f944f412 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:50:21 +0200 Subject: [PATCH 009/187] methods to interface --- .../Dialect/Handshake/HandshakeOps.td | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index b47d382745..21e0cf2dcf 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -414,7 +414,7 @@ def MuxOp : Handshake_Op<"mux", [ // Interface declarations DeclareOpInterfaceMethods, DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "mux operation"; let description = [{ @@ -451,7 +451,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ AllExtraSignalsMatchWithVariadic<"dataOperands", ["result", "index"]>, // Interface declarations DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "control merge operation"; let description = [{ @@ -517,7 +517,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ IsIntSizedChannel<1, "conditionOperand">, DeclareOpInterfaceMethods, DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "conditional branch operation"; let description = [{ @@ -666,8 +666,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ IsSimpleHandshakeVariadic<"inputs">, IsSimpleHandshakeVariadic<"outputs">, DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "memory controller (dynamatic)"; let description = [{ @@ -746,8 +745,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ def LSQOp : Handshake_Op<"lsq", [ DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "load-store queue (dynamatic)"; let description = [{ @@ -849,7 +847,7 @@ class Handshake_MemPortOp< MemPortOpInterface, AllDataTypesMatch<["address", "addressResult"]>, AllDataTypesMatch<["data", "dataResult"]>, - DeclareOpInterfaceMethods, + CustomNamedIOInterface, IsIntChannel<"address">, IsIntChannel<"addressResult"> ] @@ -971,7 +969,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ //===----------------------------------------------------------------------===// def EndOp : Handshake_Op<"end", [ - DeclareOpInterfaceMethods, + CustomNamedIOInterface, Terminator ]> { let summary = "function endpoint (dynamatic)"; @@ -1014,7 +1012,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ IsIntSizedChannel<3, "SCCommitCtrl">, IsSimpleHandshake<"SCIsMisspec">, IsIntSizedChannel<1, "SCIsMisspec">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "Central control unit of the speculative circuit."; let description = [{ @@ -1098,7 +1096,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ HasValidSpecTag<"dataOut">, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<1, "ctrl">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "Saves data tokens that interact in the speculative region."; let description = [{ @@ -1144,7 +1142,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ LacksSpecTag<"dataOut">, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<1, "ctrl">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "Stall speculative data tokens until they are resolved."; let description = [{ @@ -1191,7 +1189,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ AllTypesMatch<["dataIn", "dataOut"]>, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<3, "ctrl">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "Lets all tokens pass and saves a copy of them."; let description = [{ @@ -1234,7 +1232,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ HasValidSpecTag<"dataOperand">, LacksSpecTag<"trueResult">, LacksSpecTag<"falseResult">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "speculating branch operation"; let description = [{ @@ -1280,7 +1278,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ AllExtraSignalsMatchExcept<"spec", ["dataIn", "dataOut"]>, LacksSpecTag<"dataIn">, HasValidSpecTag<"dataOut">, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = "Adds a non-speculative spec bit."; let description = [{ @@ -1321,7 +1319,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ SameOperandsAndResultType, - DeclareOpInterfaceMethods, + CustomNamedIOInterface, ]> { let summary = "sharing wrapper operation"; @@ -1502,7 +1500,7 @@ def UnbundleOp : Handshake_Op<"unbundle", [ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ SameOperandsAndResultType, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = [{ Rigidifies a channel to simplify the handshake logic. @@ -1534,7 +1532,7 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ def ValidMergerOp : Handshake_Op<"valid_merger",[ AllTypesMatch<["lhsIn", "lhs"]>, AllTypesMatch<["rhsIn", "rhs"]>, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let summary = [{ Merges the valid signals of two channels. From c0ce4dbb957c3ca6a9feafbeb82b380174938ef6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 12:52:04 +0200 Subject: [PATCH 010/187] arith ops fixed --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 3e853ea539..3b1ecccea5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -25,7 +25,7 @@ class Handshake_Arith_Op traits = []> : class Handshake_Arith_BinaryOp traits = []> : Handshake_Arith_Op, + CustomNamedIOInterface, ]> { let arguments = (ins ChannelType:$lhs, ChannelType:$rhs); let results = (outs ChannelType:$result); @@ -77,7 +77,7 @@ class Handshake_Arith_CompareOp traits = []> : AllExtraSignalsMatch<["lhs", "rhs", "result"]>, IsIntSizedChannel<1, "result">, DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods + CustomNamedIOInterface ]> { let results = (outs ChannelType:$result); @@ -235,7 +235,7 @@ def Handshake_CmpIOp : Handshake_Arith_CompareOp<"cmpi", [ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ AllExtraSignalsMatch<["ctrl", "result"]>, - DeclareOpInterfaceMethods, + CustomNamedIOInterface, DeclareOpInterfaceMethods ]> { let summary = "constant operation"; @@ -326,7 +326,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ AllTypesMatch<["trueValue", "falseValue", "result"]>, AllExtraSignalsMatch<["condition", "trueValue", "falseValue", "result"]>, IsIntSizedChannel<1, "condition">, - DeclareOpInterfaceMethods, + CustomNamedIOInterface ]> { let summary = "Select a value based on a 1-bit predicate."; From 4d860846e7de10c8e206ec1cf873bb24cba381a5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:02:20 +0200 Subject: [PATCH 011/187] move to header --- .../dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 11 +++++++++++ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 8 +------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index c8d488100c..ca38b45c13 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -77,6 +77,17 @@ class PortNamer { class ControlType; +namespace detail { + +inline std::string simpleInputPortName(unsigned idx) { + return "ins_" + std::to_string(idx); +} + +inline std::string simpleOutputPortName(unsigned idx) { + return "outs_" + std::to_string(idx); +} + +} // end namespace detail } // end namespace handshake } // end namespace dynamatic diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 9ee231e8e1..b22a839598 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -368,14 +368,8 @@ TypedValue LSQOp::getCtrlEnd() { return cast>(getOperands().back()); } -namespace{ - std::string simpleInputPortName(int idx){ - return "ins_" + std::to_string(idx); - } - std::string simpleOutputPortName(int idx){ - return "outs_" + std::to_string(idx); - } + } #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" From deaf39284b3b5daeb023b5b4ad26aec97918b9fa Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:11:01 +0200 Subject: [PATCH 012/187] change infer functions --- .../Dialect/Handshake/HandshakeInterfaces.h | 10 +- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 94 ++++++------------- 2 files changed, 30 insertions(+), 74 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index ca38b45c13..8fcc648468 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -56,15 +56,7 @@ class PortNamer { /// Maps the index of an input or output to its port name. using IdxToStrF = const std::function &; - /// Infers port names for the operation using the provided callbacks. - void infer(Operation *op, IdxToStrF &inF, IdxToStrF &outF); - - /// Infers default port names when nothing better can be achieved. - void inferDefault(Operation *op); - - /// Infers port names for an operation implementing the - /// `handshake::NamedIOInterface` interface. - void inferFromNamedOpInterface(NamedIOInterface namedIO); + void inferFromInterface(Operation *op); /// Infers port names for a Handshake function. void inferFromFuncOp(FuncOp funcOp); diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index b22a839598..8a4eb3c6e2 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -36,74 +36,41 @@ PortNamer::PortNamer(Operation *op) { assert(op && "cannot generate port names for null operation"); if (auto funcOp = dyn_cast(op)){ inferFromFuncOp(funcOp); - return; + } else { + inferFromInterface(op); } +} - auto namedOpInterface = dyn_cast(op); - if (!namedOpInterface){ +void PortNamer::inferFromInterface(Operation *op) { + auto customNamedOpInterface = dyn_cast(op); + auto simpleNamedOpInterface = dyn_cast(op); + + IdxToStrF inF, outF; + if(customNamedOpInterface){ + inF = [&](unsigned idx) { return customNamedOpInterface.getOperandName(idx); }; + outF = [&](unsigned idx) { return customNamedOpInterface.getResultName(idx); }; + } else if (simpleNamedOpInterface) { + inF = [&](unsigned idx) { return simpleNamedOpInterface.getOperandName(idx); }; + outF = [&](unsigned idx) { return simpleNamedOpInterface.getResultName(idx); }; + } else { op->emitError("all normal operations must specify port names"); assert(false); } - inferFromNamedOpInterface(namedOpInterface); -} -// void PortNamer::infer(Operation *op, IdxToStrF &inF, IdxToStrF &outF) { -// for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) -// inputs.push_back(inF(idx)); -// for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) -// outputs.push_back(outF(idx)); - -// // The Handshake terminator forwards its non-memory inputs to its outputs, so -// // it needs port names for them -// if (handshake::EndOp endOp = dyn_cast(op)) { -// handshake::FuncOp funcOp = endOp->getParentOfType(); -// assert(funcOp && "end must be child of handshake function"); -// size_t numResults = funcOp.getFunctionType().getNumResults(); -// for (size_t idx = 0, e = numResults; idx < e; ++idx) -// outputs.push_back(endOp.getDefaultResultName(idx)); -// } -// } - -// void PortNamer::inferDefault(Operation *op) { -// llvm::TypeSwitch(op) -// .Case([&](auto) { -// infer( -// op, [](unsigned idx) { return idx == 0 ? "lhs" : "rhs"; }, -// [](unsigned idx) { return "result"; }); -// }) -// .Case( -// [&](auto) { -// infer( -// op, [](unsigned idx) { return "ins"; }, -// [](unsigned idx) { return "outs"; }); -// }) -// .Case([&](auto) { -// infer( -// op, -// [](unsigned idx) { -// if (idx == 0) -// return "condition"; -// if (idx == 1) -// return "trueValue"; -// return "falseValue"; -// }, -// [](unsigned idx) { return "result"; }); -// }) -// .Default([&](auto) { -// infer( -// op, [](unsigned idx) { return "in" + std::to_string(idx); }, -// [](unsigned idx) { return "out" + std::to_string(idx); }); -// }); -// } - -void PortNamer::inferFromNamedOpInterface(handshake::NamedIOInterface namedIO) { - auto inF = [&](unsigned idx) { return namedIO.getOperandName(idx); }; - auto outF = [&](unsigned idx) { return namedIO.getResultName(idx); }; - infer(namedIO, inF, outF); + for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) + inputs.push_back(inF(idx)); + for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) + outputs.push_back(outF(idx)); + + // The Handshake terminator forwards its non-memory inputs to its outputs, so + // it needs port names for them + if (handshake::EndOp endOp = dyn_cast(op)) { + handshake::FuncOp funcOp = endOp->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + size_t numResults = funcOp.getFunctionType().getNumResults(); + for (size_t idx = 0, e = numResults; idx < e; ++idx) + outputs.push_back(endOp.getDefaultResultName(idx)); + } } void PortNamer::inferFromFuncOp(handshake::FuncOp funcOp) { @@ -369,7 +336,4 @@ TypedValue LSQOp::getCtrlEnd() { } - -} - #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" From b3fcd0afa7f6d3afffffa46ecc2fd5c61f3c6883 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:16:38 +0200 Subject: [PATCH 013/187] arith io interface --- .../Dialect/Handshake/HandshakeArithOps.td | 14 +---------- .../Dialect/Handshake/HandshakeInterfaces.td | 25 +++++++++++++++++++ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 20 +++++++++------ 3 files changed, 38 insertions(+), 21 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 3b1ecccea5..9fab264a53 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -25,24 +25,12 @@ class Handshake_Arith_Op traits = []> : class Handshake_Arith_BinaryOp traits = []> : Handshake_Arith_Op { let arguments = (ins ChannelType:$lhs, ChannelType:$rhs); let results = (outs ChannelType:$result); let assemblyFormat = "$lhs `,` $rhs attr-dict `:` type($result)"; - - let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { - assert(idx < 2 && "index too high"); - return (idx == 0) ? "lhs" : "rhs"; - } - - std::string $cppClass::getResultName(unsigned idx) { - assert(idx < 1 && "index too high"); - return "result"; - } - }]; } class Handshake_Arith_IntBinaryOp traits = []> : diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 67b0d441b7..d547f570bb 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -190,6 +190,31 @@ def SimpleNamedIOInterface : OpInterface<"SimpleIOInterface"> { ]; } +def ArithNamedIOInterface : OpInterface<"SimpleIOInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Provides detailed names for the operands and results of an operation."}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx), + "", + [{ + assert(idx < 2 && "index too high"); + return (idx == 0) ? "lhs" : "rhs"; + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx), + "", + [{ + assert(idx < 1 && "index too high"); + return "result"; + }]> + ]; +} + def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 8a4eb3c6e2..580ef8bb5e 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -42,16 +42,20 @@ PortNamer::PortNamer(Operation *op) { } void PortNamer::inferFromInterface(Operation *op) { - auto customNamedOpInterface = dyn_cast(op); - auto simpleNamedOpInterface = dyn_cast(op); + + + IdxToStrF inF, outF; - if(customNamedOpInterface){ - inF = [&](unsigned idx) { return customNamedOpInterface.getOperandName(idx); }; - outF = [&](unsigned idx) { return customNamedOpInterface.getResultName(idx); }; - } else if (simpleNamedOpInterface) { - inF = [&](unsigned idx) { return simpleNamedOpInterface.getOperandName(idx); }; - outF = [&](unsigned idx) { return simpleNamedOpInterface.getResultName(idx); }; + if(auto nameInterface = dyn_cast(op)){ + inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; + outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; + } else if (auto nameInterface = dyn_cast(op)) { + inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; + outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; + } else if (auto nameInterface = dyn_cast(op)) { + inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; + outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; } else { op->emitError("all normal operations must specify port names"); assert(false); From 0cca80f64cb752e979b7b9e0f0d59270d2e06361 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:20:49 +0200 Subject: [PATCH 014/187] individual arith interfaces --- .../Dialect/Handshake/HandshakeArithOps.td | 121 +++++++++++++----- 1 file changed, 87 insertions(+), 34 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 9fab264a53..234d497431 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -24,8 +24,7 @@ class Handshake_Arith_Op traits = []> : class Handshake_Arith_BinaryOp traits = []> : Handshake_Arith_Op { let arguments = (ins ChannelType:$lhs, ChannelType:$rhs); let results = (outs ChannelType:$result); @@ -144,16 +143,23 @@ class Handshake_Arith_FToICastOp traits = []> : def Handshake_AddFOp : Handshake_Arith_FloatBinaryOp<"addf", [ Commutative, FPUImplInterface, - InternalDelayInterface + InternalDelayInterface, + ArithNamedIOInterface ]> { let summary = "Floating-point addition."; } -def Handshake_AddIOp : Handshake_Arith_IntBinaryOp<"addi", [Commutative]> { +def Handshake_AddIOp : Handshake_Arith_IntBinaryOp<"addi", [ + Commutative, + ArithNamedIOInterface +]> { let summary = "Integer addition."; } -def Handshake_AndIOp : Handshake_Arith_IntBinaryOp<"andi", [Commutative]> { +def Handshake_AndIOp : Handshake_Arith_IntBinaryOp<"andi", [ + Commutative, + ArithNamedIOInterface +]> { let summary = "Bitwise conjunction."; } @@ -185,11 +191,12 @@ def Handshake_CmpFOp : Handshake_Arith_CompareOp<"cmpf", [ IsFloatChannel<"lhs">, IsFloatChannel<"rhs">, FPUImplInterface, - InternalDelayInterface + InternalDelayInterface, + ArithNamedIOInterface ]> { let summary = "Floating-point comparison."; - - let arguments = (ins Handshake_CmpFPredicateAttr:$predicate, + + let arguments = (ins Handshake_CmpFPredicateAttr:$predicate, ChannelType:$lhs, ChannelType:$rhs); } @@ -213,7 +220,8 @@ def Handshake_CmpIPredicateAttr : I64EnumAttr< def Handshake_CmpIOp : Handshake_Arith_CompareOp<"cmpi", [ IsIntChannel<"lhs">, - IsIntChannel<"rhs"> + IsIntChannel<"rhs">, + ArithNamedIOInterface ]> { let summary = "Integer comparison."; @@ -252,40 +260,53 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ def Handshake_DivFOp : Handshake_Arith_FloatBinaryOp<"divf", [ FPUImplInterface, - InternalDelayInterface + InternalDelayInterface, + ArithNamedIOInterface ]> { let summary = "Floating-point division."; } -def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi"> { +def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi"[ + ArithNamedIOInterface +]> { let summary = "Signed integer remainder."; } -def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi"> { +def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi"[ + ArithNamedIOInterface +]> { let summary = "Signed integer division."; } -def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui"> { +def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui"[ + ArithNamedIOInterface +]> { let summary = "Unsigned integer division."; } -def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi"> { +def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi"[ + ArithNamedIOInterface +]> { let summary = "Integer unsigned width extension."; let hasCanonicalizer = 1; } -def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"> { +def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"[ + ArithNamedIOInterface +]> { let summary = "Integer signed width extension."; } def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [ - Commutative + Commutative, + ArithNamedIOInterface ]> { let summary = "Floating-point maximum."; } def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [ - Commutative + Commutative, + ArithNamedIOInterface ]> { let summary = "Floating-point minimum."; } @@ -293,20 +314,28 @@ def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [ def Handshake_MulFOp : Handshake_Arith_FloatBinaryOp<"mulf", [ Commutative, FPUImplInterface, - InternalDelayInterface + InternalDelayInterface, + ArithNamedIOInterface ]> { let summary = "Floating-point multiplication."; } -def Handshake_MulIOp : Handshake_Arith_IntBinaryOp<"muli", [Commutative]> { +def Handshake_MulIOp : Handshake_Arith_IntBinaryOp<"muli", [ + Commutative, + ArithNamedIOInterface]> { let summary = "Integer multiplication."; } -def Handshake_NegFOp : Handshake_Arith_FloatUnaryOp<"negf"> { +def Handshake_NegFOp : Handshake_Arith_FloatUnaryOp<"negf", [ + SimpleNamedIOInterface +]> { let summary = "Floating-point sign negation."; } -def Handshake_OrIOp : Handshake_Arith_IntBinaryOp<"ori", [Commutative]> { +def Handshake_OrIOp : Handshake_Arith_IntBinaryOp<"ori", [ + Commutative, + ArithNamedIOInterface +]> { let summary = "Bitwise union."; } @@ -317,7 +346,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ CustomNamedIOInterface ]> { let summary = "Select a value based on a 1-bit predicate."; - + let arguments = (ins ChannelType:$condition, ChannelType:$trueValue, ChannelType:$falseValue); let results = (outs ChannelType:$result); @@ -328,59 +357,83 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ }]; } -def Handshake_ShLIOp : Handshake_Arith_IntBinaryOp<"shli"> { +def Handshake_ShLIOp : Handshake_Arith_IntBinaryOp<"shli", [ + ArithNamedIOInterface +]> { let summary = "Logical left shift."; } -def Handshake_ShRSIOp : Handshake_Arith_IntBinaryOp<"shrsi"> { +def Handshake_ShRSIOp : Handshake_Arith_IntBinaryOp<"shrsi", [ + ArithNamedIOInterface +]> { let summary = "Arithmetic right shift."; } -def Handshake_ShRUIOp : Handshake_Arith_IntBinaryOp<"shrui"> { +def Handshake_ShRUIOp : Handshake_Arith_IntBinaryOp<"shrui", [ + ArithNamedIOInterface +]> { let summary = "Logical right shift."; } def Handshake_SubFOp : Handshake_Arith_FloatBinaryOp<"subf", [ FPUImplInterface, - InternalDelayInterface + InternalDelayInterface, + ArithNamedIOInterface ]> { let summary = "Floating-point subtraction."; } -def Handshake_SubIOp : Handshake_Arith_IntBinaryOp<"subi"> { +def Handshake_SubIOp : Handshake_Arith_IntBinaryOp<"subi", [ + ArithNamedIOInterface +]> { let summary = "Integer subtraction."; } -def Handshake_TruncIOp : Handshake_Arith_IToICastOp<"trunci"> { +def Handshake_TruncIOp : Handshake_Arith_IToICastOp<"trunci", [ + SimpleNamedIOInterface +]> { let summary = "Integer truncation."; let hasCanonicalizer = 1; } -def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf"> { +def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf", [ + SimpleNamedIOInterface +]> { let summary = "Floating-point truncation."; // TODO: add canonicalizer let hasVerifier = 1; } -def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [Commutative]> { +def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [ + Commutative, + ArithNamedIOInterface +]> { let summary = "Bitwise exclusive union."; } -def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp"> { +def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp", [ + SimpleNamedIOInterface +]> { let summary = "Converts a signed integer to float."; } -def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi"> { +def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi", [ + SimpleNamedIOInterface +]> { let summary = "Converts a float to signed integer."; } -def Handshake_ExtFOp : Handshake_Arith_FToFCastOp<"extf"> { +def Handshake_ExtFOp : Handshake_Arith_FToFCastOp<"extf", [ + SimpleNamedIOInterface +]> { let summary = "Floating point extension."; // TODO: add canonicalizer let hasVerifier = 1; } -def Handshake_AbsFOp : Handshake_Arith_FToFCastOp<"absf"> { +def Handshake_AbsFOp : Handshake_Arith_FToFCastOp<"absf", [ + SimpleNamedIOInterface +]> { let summary = "floating point absolute-value operation"; // TODO: add folder } From 2db35bc9a1b4e2b0f8e0d9f194b06b54e5569db1 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:21:27 +0200 Subject: [PATCH 015/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 234d497431..bc1e136965 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -266,7 +266,7 @@ def Handshake_DivFOp : Handshake_Arith_FloatBinaryOp<"divf", [ let summary = "Floating-point division."; } -def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi"[ +def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ ArithNamedIOInterface ]> { let summary = "Signed integer remainder."; From 180565438da73a6766be1ee72ccebd8683e20346 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:22:06 +0200 Subject: [PATCH 016/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index bc1e136965..f72b14346d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -272,26 +272,26 @@ def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ let summary = "Signed integer remainder."; } -def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi"[ +def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi", [ ArithNamedIOInterface ]> { let summary = "Signed integer division."; } -def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui"[ +def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ ArithNamedIOInterface ]> { let summary = "Unsigned integer division."; } -def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi"[ +def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi", [ ArithNamedIOInterface ]> { let summary = "Integer unsigned width extension."; let hasCanonicalizer = 1; } -def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui"[ +def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui", [ ArithNamedIOInterface ]> { let summary = "Integer signed width extension."; From 1524c23dca4fb23b12d844337f7d0aaba7049ea5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:24:03 +0200 Subject: [PATCH 017/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index d547f570bb..9400663dcb 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -190,7 +190,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleIOInterface"> { ]; } -def ArithNamedIOInterface : OpInterface<"SimpleIOInterface"> { +def ArithNamedIOInterface : OpInterface<"ArithNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = [{"Provides detailed names for the operands and results of an operation."}]; From 01870a19f18918c58bbaf285481730173aa1928f Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:34:08 +0200 Subject: [PATCH 018/187] fix mux names --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 13 +++++++++++++ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 8 -------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 21e0cf2dcf..8c71ec4545 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -440,6 +440,19 @@ def MuxOp : Handshake_Op<"mux", [ Variadic:$dataOperands); let results = (outs HandshakeType:$result); + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + return idx == 0 ? "index" : simpleInputPortName(idx - 1); + } + + std::string getResultName(unsigned idx) { + return simpleOutputPortName(idx); + } + }]; + + + let hasCustomAssemblyFormat = 1; let hasVerifier = 1; } diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 580ef8bb5e..7c1b85d5f9 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -42,10 +42,6 @@ PortNamer::PortNamer(Operation *op) { } void PortNamer::inferFromInterface(Operation *op) { - - - - IdxToStrF inF, outF; if(auto nameInterface = dyn_cast(op)){ inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; @@ -92,10 +88,6 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { return name.str() + "_" + std::to_string(idx); } -std::string handshake::MuxOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : "ins_" + std::to_string(idx - 1); -} std::string handshake::ControlMergeOp::getResultName(unsigned idx) { assert(idx < getNumResults() && "index too high"); From 00723290e1c44d0c4017e3f35aecb0ec548da962 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 13:35:16 +0200 Subject: [PATCH 019/187] namespace --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 8c71ec4545..6d38c48bd8 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -443,11 +443,11 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : simpleInputPortName(idx - 1); + return idx == 0 ? "index" : detail::simpleInputPortName(idx - 1); } std::string getResultName(unsigned idx) { - return simpleOutputPortName(idx); + return detail::simpleOutputPortName(idx); } }]; From 1c824e7e4a385220886b08d877a7b5afb96d029f Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 14:19:25 +0200 Subject: [PATCH 020/187] up to memory controller --- .../Dialect/Handshake/HandshakeOps.td | 118 +++++++++++++++--- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 52 -------- 2 files changed, 98 insertions(+), 72 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 6d38c48bd8..82cd929444 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -447,6 +447,7 @@ def MuxOp : Handshake_Op<"mux", [ } std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); return detail::simpleOutputPortName(idx); } }]; @@ -476,32 +477,46 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ Example: ``` - %res, %idx = control_merge %a, %b, %c : + %res, %idx = control_merge %a, %b, %c : !handshake.channel, !handshake.channel ``` }]; let arguments = (ins Variadic:$dataOperands); let results = (outs HandshakeType:$result, ChannelType:$index); - + let builders = [OpBuilder< (ins "ValueRange":$operands), [{ assert(!operands.empty() && "cmerge needs at least one operand"); $_state.addOperands(operands); - + // Optimize the size of the index result based on the number of operands auto dataType = ::dynamatic::handshake::getOptimizedIndexValType( $_builder, operands.size()); auto idxType = ::dynamatic::handshake::ChannelType::get(dataType); $_state.addTypes({operands[0].getType(), idxType}); }]>]; - + + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + return detail::simpleInputPortName(idx); + } + + std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); + return idx == 0 ? "outs" : "index"; + } + }]; + let hasCustomAssemblyFormat = 1; let hasVerifier = 1; } def BranchOp : Handshake_Op<"br", [ - Pure, SameOperandsAndResultType + Pure, + SameOperandsAndResultType, + SimpleNamedIOInterface ]> { let summary = "branch operation"; let description = [{ @@ -518,7 +533,7 @@ def BranchOp : Handshake_Op<"br", [ }]; let arguments = (ins HandshakeType:$operand); let results = (outs HandshakeType:$result); - + let assemblyFormat = [{ $operand attr-dict `:` custom(type($result)) }]; @@ -550,7 +565,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ HandshakeType:$dataOperand); let results = (outs HandshakeType:$trueResult, HandshakeType:$falseResult); - + let assemblyFormat = [{ $conditionOperand `,` $dataOperand attr-dict `:` type($conditionOperand) `,` custom(type($dataOperand)) @@ -558,10 +573,22 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ let extraClassDeclaration = [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; + + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + return idx == 0 ? "condition" : "data"; + } + + std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); + return idx == ConditionalBranchOp::trueIndex ? "trueOut" : "falseOut"; + } }]; } -def SinkOp : Handshake_Op<"sink"> { +def SinkOp : Handshake_Op<"sink", [ + SimpleNamedIOInterface +]> { let summary = "sink operation"; let description = [{ The sink operation discards any data that arrives at its @@ -573,14 +600,17 @@ def SinkOp : Handshake_Op<"sink"> { sink %data : !handshake.channel ``` }]; - + let arguments = (ins HandshakeType:$operand); let assemblyFormat = [{ $operand attr-dict `:` custom(type($operand)) }]; } -def SourceOp : Handshake_Op<"source", [Pure]> { +def SourceOp : Handshake_Op<"source", [ + Pure, + SimpleNamedIOInterface + ]> { let summary = "source operation"; let description = [{ The source operation represents a continuous control-only-token source. The @@ -608,7 +638,8 @@ def SourceOp : Handshake_Op<"source", [Pure]> { def JoinOp : Handshake_Op<"join", [ SameOperandsAndResultType, - DeclareOpInterfaceMethods + DeclareOpInterfaceMethods, + SimpleNamedIOInterface ]> { let summary = "join operation"; let description = [{ @@ -630,11 +661,12 @@ def JoinOp : Handshake_Op<"join", [ // TODO: Split the input into two parts and explicitly mark the forwarded input, // once the backend supports variadic channels with zero or one item correctly. def BlockerOp : Handshake_Op<"blocker", [ - SameOperandsAndResultType + SameOperandsAndResultType, + SimpleNamedIOInterface ]> { let summary = "blocker operation"; let description = [{ - A data synchronizer. Blocks handshakes until all inputs are valid, + A data synchronizer. Blocks handshakes until all inputs are valid, then forwards the first input. Example: @@ -649,7 +681,11 @@ def BlockerOp : Handshake_Op<"blocker", [ let assemblyFormat = "$data attr-dict `:` type($result)"; } -def NotOp : Handshake_Op<"not", [Pure, SameOperandsAndResultType]> { +def NotOp : Handshake_Op<"not", [ + Pure, + SameOperandsAndResultType, + SimpleNamedIOInterface +]> { let summary = "Logical negation"; let description = [{ Bitwise logical negation. @@ -683,8 +719,8 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ ]> { let summary = "memory controller (dynamatic)"; let description = [{ - Each `MemoryControllerOp` represents an interface to an externally defined - unidimensional memory (i.e., it interfaces a memref input to a Handshake + Each `MemoryControllerOp` represents an interface to an externally defined + unidimensional memory (i.e., it interfaces a memref input to a Handshake function). It receives control signals from each basic block containing store operations referencing the wrapped memref; the formers are fed to the operation through constants indicating the number of stores the basic block @@ -697,7 +733,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ Additionally, the `connectedBlocks` attribute contains the ordered list of basic blocks (referenced by their unique IDs) that communicate with the controller. Every load/store operation is required to be tagged with the ID - of a basic block present in this list. + of a basic block present in this list. Optionally, a memory controller may act as a middle-person between an LSQ and the external memory. @@ -705,7 +741,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ The order of memory inputs is 1. For each basic block: a. If there is at least one store in the block, a control signal fed - through a constant indicating the number of store operations in the + through a constant indicating the number of store operations in the block. b. Load/Store access requests from within the block, in program order. 2. If an LSQ references the same memory region: @@ -714,7 +750,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ signals described above. b. A single address operand for load accesses coming through the LSQ and a single pair of address/data operands for store accesses coming - through the LSQ. + through the LSQ. The order of memory outputs is 1. Load results, in program order (i.e., in load accesses order). @@ -731,8 +767,50 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ let builders = [OpBuilder<(ins "Value":$memRef, "Value":$memStart, "ValueRange":$inputs, "Value":$ctrlEnd, - "ArrayRef":$blocks, + "ArrayRef":$blocks, "unsigned":$numLoads)>]; + + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + + if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + MCPorts mcPorts = getPorts(); + if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to an LSQ + assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + if (lsqPort.getLoadAddrInputIndex() == idx) + return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); + if (lsqPort.getStoreAddrInputIndex() == idx) + return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); + assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); + return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); + } + + std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); + + if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + MCPorts mcPorts = getPorts(); + if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to an LSQ + assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); + return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); + } + }]; let hasVerifier = 1; // Dispatch SimpleControl signals to custom print and parse diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 7c1b85d5f9..75300d2e48 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -89,20 +89,6 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { } -std::string handshake::ControlMergeOp::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - return idx == 0 ? "outs" : "index"; -} - -std::string handshake::ConditionalBranchOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "condition" : "data"; -} - -std::string handshake::ConditionalBranchOp::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - return idx == ConditionalBranchOp::trueIndex ? "trueOut" : "falseOut"; -} std::string handshake::ConstantOp::getOperandName(unsigned idx) { assert(idx == 0 && "index too high"); @@ -203,45 +189,7 @@ static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { return ""; } -std::string handshake::MemoryControllerOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - - if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - MCPorts mcPorts = getPorts(); - if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to an LSQ - assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - if (lsqPort.getLoadAddrInputIndex() == idx) - return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); - if (lsqPort.getStoreAddrInputIndex() == idx) - return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); - assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); - return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); -} - -std::string handshake::MemoryControllerOp::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - MCPorts mcPorts = getPorts(); - if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to an LSQ - assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); - return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); -} std::string handshake::LSQOp::getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); From 9bdf571845e4cb114a474475df66725272e19130 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 14:22:47 +0200 Subject: [PATCH 021/187] remove some num results --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 82cd929444..bcb6ef1804 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -447,7 +447,7 @@ def MuxOp : Handshake_Op<"mux", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < 1 && "index too high"); return detail::simpleOutputPortName(idx); } }]; @@ -504,7 +504,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < 2 && "index too high"); return idx == 0 ? "outs" : "index"; } }]; @@ -580,7 +580,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < 2 && "index too high"); return idx == ConditionalBranchOp::trueIndex ? "trueOut" : "falseOut"; } }]; @@ -1346,7 +1346,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ let arguments = (ins HandshakeType:$tagFromOperand, HandshakeType:$dataOperand); let results = (outs HandshakeType:$trueResult, HandshakeType:$falseResult); let assemblyFormat = [{ - `[` $tagFromOperand `]` $dataOperand attr-dict `:` + `[` $tagFromOperand `]` $dataOperand attr-dict `:` type($tagFromOperand) `,` type($dataOperand) `,` type($trueResult) `,` type($falseResult) }]; @@ -1358,7 +1358,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ } std::string $cppClass::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < 2 && "index too high"); return idx == 0 ? "trueOut" : "falseOut"; } }]; From 89b9cf6fb14f9b130a15e86f7f665af692417572 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 14:23:27 +0200 Subject: [PATCH 022/187] remove nameiointerface --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 8fcc648468..cec918b997 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -32,7 +32,6 @@ namespace dynamatic { namespace handshake { -class NamedIOInterface; class FuncOp; /// Provides an opaque interface for generating the port names of an operation; From c3c2ca73dd3af8b01d81c65dd72721ff0e0472fa Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 14:24:32 +0200 Subject: [PATCH 023/187] simple port name for end --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 75300d2e48..40968efeb1 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -69,7 +69,7 @@ void PortNamer::inferFromInterface(Operation *op) { assert(funcOp && "end must be child of handshake function"); size_t numResults = funcOp.getFunctionType().getNumResults(); for (size_t idx = 0, e = numResults; idx < e; ++idx) - outputs.push_back(endOp.getDefaultResultName(idx)); + outputs.push_back(detail::simpleOutputPortName(idx)); } } From 57c7638ffe31b0dc8f6e5d693fab01c6a4ee327e Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 14:35:39 +0200 Subject: [PATCH 024/187] more functions into tablegen --- .../Dialect/Handshake/HandshakeArithOps.td | 27 +++ .../Dialect/Handshake/HandshakeOps.td | 163 +++++++++++++----- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 86 --------- 3 files changed, 147 insertions(+), 129 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index f72b14346d..03ac752fc6 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -252,6 +252,19 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ let arguments = (ins TypedAttrInterface:$value, ControlType:$ctrl); let results = (outs ChannelType:$result); + + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < 1 && "index too high"); + return "ctrl"; + } + + std::string getResultName(unsigned idx) { + assert(idx < 1 && "index too high"); + return idx == 0 ? "outs" : "index"; + } + }]; + // The type of the control also needs to be specified in the IR. // It may have extra bits, which could affect the result's type and token. let assemblyFormat = "$ctrl attr-dict `:` type($ctrl) `,` type($result)"; @@ -351,6 +364,20 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ ChannelType:$falseValue); let results = (outs ChannelType:$result); + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + if (idx == 0) + return "condition"; + return (idx == 1) ? "trueValue" : "falseValue"; + } + + std::string getResultName(unsigned idx) { + assert(idx < 1 && "index too high"); + return "result"; + } + }]; + let assemblyFormat = [{ $condition `[` $trueValue `,` $falseValue `]` attr-dict `:` type($condition) `,` type($result) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index bcb6ef1804..d70a83318a 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -880,15 +880,15 @@ def LSQOp : Handshake_Op<"lsq", [ accesses going to the external memory through the MC. 3. Control signal indicating completion. }]; - + let arguments = (ins Variadic:$inputs, I32ArrayAttr:$groupSizes); let results = (outs Variadic:$outputs); let builders = [ - OpBuilder<(ins "Value":$memref, "Value":$memStart, "ValueRange":$inputs, + OpBuilder<(ins "Value":$memref, "Value":$memStart, "ValueRange":$inputs, "Value":$ctrlEnd, "ArrayRef":$groupSizes, "unsigned":$numLoads)>, - OpBuilder<(ins "::dynamatic::handshake::MemoryControllerOp":$mcOp, - "ValueRange":$inputs, "ArrayRef":$groupSizes, + OpBuilder<(ins "::dynamatic::handshake::MemoryControllerOp":$mcOp, + "ValueRange":$inputs, "ArrayRef":$groupSizes, "unsigned":$numLoads)>, ]; let hasVerifier = 1; @@ -904,10 +904,10 @@ def LSQOp : Handshake_Op<"lsq", [ } /// Returns a convenient data-structure to go over the controls and memory - /// accesses that are connected to the LSQ. + /// accesses that are connected to the LSQ. dynamatic::LSQPorts getPorts(); - - /// Determines whether the LSQ is connected to an MC. + + /// Determines whether the LSQ is connected to an MC. bool isConnectedToMC() { return !isa(getInputs().front().getType()); } @@ -925,6 +925,46 @@ def LSQOp : Handshake_Op<"lsq", [ /// materialized when called. The returned values are guaranteed to be in /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); + + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + + if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && + "unknown LSQ/MC operand"); + return "ldDataFromMC"; + } + + std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); + + if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + MCLoadStorePort mcPort = lsqPorts.getMCPort(); + if (mcPort.getLoadAddrOutputIndex() == idx) + return "ldAddrToMC"; + if (mcPort.getStoreAddrOutputIndex() == idx) + return "stAddrToMC"; + assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); + return "stDataToMC"; + } }]; } @@ -966,7 +1006,8 @@ def LoadOp : Handshake_MemPortOp<"load", [ AllExtraSignalsMatch<["address", "dataResult"]>, // In LoadOp, addressResult and data are connected to a memory controller. IsSimpleHandshake<"addressResult">, - IsSimpleHandshake<"data"> + IsSimpleHandshake<"data">, + CustomNamedIOInterface ], [ // TODO: Please add comments on why this builder is necessary OpBuilder<(ins "MemRefType":$memrefType, "Value":$address), [{ @@ -1004,12 +1045,12 @@ def LoadOp : Handshake_MemPortOp<"load", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getNumResults() && "index too high"); return (idx == 0) ? "addrOut" : "dataOut"; } @@ -1020,7 +1061,8 @@ def StoreOp : Handshake_MemPortOp<"store", [ AllExtraSignalsMatch<["address", "data"]>, // In StoreOp, addressResult and dataResult are connected to a memory controller. IsSimpleHandshake<"addressResult">, - IsSimpleHandshake<"dataResult"> + IsSimpleHandshake<"dataResult">, + CustomNamedIOInterface ], []> { let summary = "store operation for memory controller (MC)"; let description = [{ @@ -1045,11 +1087,11 @@ def StoreOp : Handshake_MemPortOp<"store", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned int idx) { + std::string getOperandName(unsigned int idx) { return (idx == 0) ? "addrIn" : "dataIn"; } - std::string $cppClass::getResultName(unsigned int idx) { + std::string getResultName(unsigned int idx) { return (idx == 0) ? "addrOut" : "dataToMem"; } }]; @@ -1077,6 +1119,23 @@ def EndOp : Handshake_Op<"end", [ let arguments = (ins Variadic:$inputs); + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + + unsigned numResults = funcOp.getFunctionType().getNumResults(); + if (idx < numResults) + return "ins_" + std::to_string(idx); + return "memDone_" + std::to_string(idx - numResults); + } + + std::string getResultName(unsigned idx) { + assert(false && "index too high"); + } + }]; + let assemblyFormat = [{ attr-dict ($inputs^ `:` custom(type($inputs)))? }]; @@ -1155,12 +1214,12 @@ def SpeculatorOp : Handshake_Op<"speculator", [ }]>]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "ins" : "trigger"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getNumResults() && "index too high"); switch (idx) { case 0: @@ -1214,12 +1273,12 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } @@ -1262,12 +1321,12 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } @@ -1304,12 +1363,12 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } @@ -1352,12 +1411,12 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < 2 && "index too high"); return idx == 0 ? "trueOut" : "falseOut"; } @@ -1392,12 +1451,12 @@ def NonSpecOp : Handshake_Op<"non_spec", [ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return "dataIn"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); return "dataOut"; } @@ -1409,15 +1468,15 @@ def NonSpecOp : Handshake_Op<"non_spec", [ //===----------------------------------------------------------------------===// def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ - SameOperandsAndResultType, + SameOperandsAndResultType, CustomNamedIOInterface, ]> { let summary = "sharing wrapper operation"; let description = [{ - The sharing_wrapper operation represents the selecting & distributing logic + The sharing_wrapper operation represents the selecting & distributing logic that manages access to a shared unit. - + The sharing wrapper interfaces with the shared unit and the rest of the circuit. @@ -1427,18 +1486,18 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ operation that share the unit. - $numSharedOperands: the number of operands of the shared unit. - $latency: the execution latency of the shared unit. - + The convention for the input operands: - the first "numSharedOperands * len(credits)" operands are the operands from the circuit - the last operand is the result computed by the shared unit - + The convention for the output results: - the first "len(credits)" results are results dispatched to the rest of the circuit - the last "numSharedOperands" result is the selected operands that will be delivered to the shared unit. - + Future improvement: - Add the number of operations that share the unit (now it is assumed to be the size of the DenseI64ArrayAttr credits). @@ -1455,6 +1514,24 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); + let extraClassDefinition = [{ + std::string getOperandName(unsigned idx) { + assert(idx < getNumOperands() && "index too high"); + if (idx < getNumSharedOperands() * getNumSharedOperations()) { + return "op" + std::to_string(idx / getNumSharedOperands()) + "in" + + std::to_string(idx % getNumSharedOperands()); + } + return "fromSharedUnitOut0"; + } + + std::string getResultName(unsigned idx) { + assert(idx < getNumResults() && "index too high"); + if (idx < getNumSharedOperations()) + return "op" + std::to_string(idx) + "out0"; + return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); + } + }]; + let assemblyFormat = [{ `[` $dataOperands `]` `,` `[` $sharedOpResult `]` attr-dict `:` functional-type(operands, results) @@ -1476,7 +1553,7 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> { that combining individual signals into a `handshake::ChannelType` is a two-step process. 1. First, bundle a `i1` value, which produces a `!handshake.control` and - `i1` (representing the upstream ready signal) as results. + `i1` (representing the upstream ready signal) as results. 2. Then, bundle the `!handshake.control` along with a value representing the data signal (of a compatible signal type e.g., `i32`), which produces a `!handshake.channel`. @@ -1486,12 +1563,12 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> { ```mlir // Bundling into a channel with a downstream extra signal %channel = bundle %ctrl, %data, %extra : _ to - + // ----- - + // Bundling into a channel with an upstream extra signal %channel, %extra = bundle %ctrl, %data : _ to - + // ----- // Bundling into a control-only channel @@ -1523,7 +1600,7 @@ def BundleOp : Handshake_Op<"bundle", [Pure]> { > ]; - let hasCustomAssemblyFormat = 1; + let hasCustomAssemblyFormat = 1; let hasVerifier = 1; } @@ -1544,16 +1621,16 @@ def UnbundleOp : Handshake_Op<"unbundle", [ "downstream bundle"). 2. Then, unbundle the `!handshake.control` along with an `i1` value representing the ready signal, which produces an `i1` result representing - the valid signal. + the valid signal. Example: ```mlir // Unbundling a channel with a downstream extra signal %ctrl, %data, %extra = unbundle %channel : to _ - + // ----- - + // Unbundling a channel with an upstream extra signal %ctrl, %data = unbundle %channel [%extra] : to _ @@ -1609,11 +1686,11 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx = 0) { + std::string getOperandName(unsigned idx = 0) { return "ins"; } - std::string $cppClass::getResultName(unsigned idx = 0) { + std::string getResultName(unsigned idx = 0) { return "outs"; } }]; @@ -1642,12 +1719,12 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ }]; let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; } - std::string $cppClass::getResultName(unsigned idx) { + std::string getResultName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return (idx == 0) ? "lhs_outs" : "rhs_outs"; } diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 40968efeb1..e0e2dd38c0 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -88,36 +88,6 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { return name.str() + "_" + std::to_string(idx); } - - -std::string handshake::ConstantOp::getOperandName(unsigned idx) { - assert(idx == 0 && "index too high"); - return "ctrl"; -} - -std::string handshake::EndOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - - unsigned numResults = funcOp.getFunctionType().getNumResults(); - if (idx < numResults) - return "ins_" + std::to_string(idx); - return "memDone_" + std::to_string(idx - numResults); -} - -std::string handshake::SelectOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - if (idx == 0) - return "condition"; - return (idx == 1) ? "trueValue" : "falseValue"; -} - -std::string handshake::SelectOp::getResultName(unsigned idx) { - assert(idx == 0 && "index too high"); - return "result"; -} - /// Load/Store base signal names common to all memory interfaces static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), @@ -191,62 +161,6 @@ static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { -std::string handshake::LSQOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - - if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && - "unknown LSQ/MC operand"); - return "ldDataFromMC"; -} - -std::string handshake::LSQOp::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - - if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - MCLoadStorePort mcPort = lsqPorts.getMCPort(); - if (mcPort.getLoadAddrOutputIndex() == idx) - return "ldAddrToMC"; - if (mcPort.getStoreAddrOutputIndex() == idx) - return "stAddrToMC"; - assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); - return "stDataToMC"; -} - -std::string handshake::SharingWrapperOp::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - if (idx < getNumSharedOperands() * getNumSharedOperations()) { - return "op" + std::to_string(idx / getNumSharedOperands()) + "in" + - std::to_string(idx % getNumSharedOperands()); - } - return "fromSharedUnitOut0"; -} - -std::string handshake::SharingWrapperOp::getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - if (idx < getNumSharedOperations()) - return "op" + std::to_string(idx) + "out0"; - return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); -} - //===----------------------------------------------------------------------===// // MemoryOpInterface //===----------------------------------------------------------------------===// From 4ef039b21dabafecbd52dee785b41c1a16a5a65e Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:45:48 +0200 Subject: [PATCH 025/187] move common funcs into header --- .../Dialect/Handshake/HandshakeInterfaces.h | 71 ++++++++++++++++++ .../Dialect/Handshake/HandshakeOps.td | 2 +- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 72 ------------------- 3 files changed, 72 insertions(+), 73 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index cec918b997..fa1ddcde77 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -78,6 +78,77 @@ inline std::string simpleOutputPortName(unsigned idx) { return "outs_" + std::to_string(idx); } +/// Load/Store base signal names common to all memory interfaces +static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), + MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), + LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); + +inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { + if (!memOp.isMasterInterface()) + return ""; + switch (idx) { + case 0: + return MEMREF; + case 1: + return MEM_START; + default: + return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; + } +} + +static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { + if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) + return MEM_END; + return ""; +} + +/// Common operand naming logic for memory controllers and LSQs. +inline static std::string getMemOperandName(const FuncMemoryPorts &ports, + unsigned idx) { + // Iterate through all memory ports to find out the type of the operand + unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + if (blockPorts.hasControl()) { + if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) + return getArrayElemName(CTRL, ctrlIdx); + ++ctrlIdx; + } + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getAddrInputIndex() == idx) + return getArrayElemName(LD_ADDR, loadIdx); + ++loadIdx; + } else { + std::optional storePort = cast(accessPort); + if (storePort->getAddrInputIndex() == idx) + return getArrayElemName(ST_ADDR, storeIdx); + if (storePort->getDataInputIndex() == idx) + return getArrayElemName(ST_DATA, storeIdx); + ++storeIdx; + } + } + } + + return ""; +} + +/// Common result naming logic for memory controllers and LSQs. +inline static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { + // Iterate through all memory ports to find out the type of the + // operand + unsigned loadIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getDataOutputIndex() == idx) + return getArrayElemName(LD_DATA, loadIdx); + ++loadIdx; + } + } + } + return ""; +} + } // end namespace detail } // end namespace handshake } // end namespace dynamatic diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d70a83318a..a2fc98b56d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -877,7 +877,7 @@ def LSQOp : Handshake_Op<"lsq", [ 1. Load results, in program order (i.e., in load accesses order). 2. If an MC references the same memory region, a single address operand for load accesses and a single pair of address/data operands for store - accesses going to the external memory through the MC. + accesses going to the external memory through the MC. 3. Control signal indicating completion. }]; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index e0e2dd38c0..c5458ff7fb 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -88,78 +88,6 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { return name.str() + "_" + std::to_string(idx); } -/// Load/Store base signal names common to all memory interfaces -static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), - MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), - LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); - -static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { - if (!memOp.isMasterInterface()) - return ""; - switch (idx) { - case 0: - return MEMREF; - case 1: - return MEM_START; - default: - return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; - } -} - -static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { - if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) - return MEM_END; - return ""; -} - -/// Common operand naming logic for memory controllers and LSQs. -static std::string getMemOperandName(const FuncMemoryPorts &ports, - unsigned idx) { - // Iterate through all memory ports to find out the type of the operand - unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - if (blockPorts.hasControl()) { - if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) - return getArrayElemName(CTRL, ctrlIdx); - ++ctrlIdx; - } - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getAddrInputIndex() == idx) - return getArrayElemName(LD_ADDR, loadIdx); - ++loadIdx; - } else { - std::optional storePort = cast(accessPort); - if (storePort->getAddrInputIndex() == idx) - return getArrayElemName(ST_ADDR, storeIdx); - if (storePort->getDataInputIndex() == idx) - return getArrayElemName(ST_DATA, storeIdx); - ++storeIdx; - } - } - } - - return ""; -} - -/// Common result naming logic for memory controllers and LSQs. -static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { - // Iterate through all memory ports to find out the type of the - // operand - unsigned loadIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getDataOutputIndex() == idx) - return getArrayElemName(LD_DATA, loadIdx); - ++loadIdx; - } - } - } - return ""; -} - - //===----------------------------------------------------------------------===// // MemoryOpInterface From bd73f815857d72c77889dd384147c150a52444ce Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:46:14 +0200 Subject: [PATCH 026/187] move out of detail --- .../Dialect/Handshake/HandshakeInterfaces.h | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index fa1ddcde77..35c87676b9 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -68,16 +68,6 @@ class PortNamer { class ControlType; -namespace detail { - -inline std::string simpleInputPortName(unsigned idx) { - return "ins_" + std::to_string(idx); -} - -inline std::string simpleOutputPortName(unsigned idx) { - return "outs_" + std::to_string(idx); -} - /// Load/Store base signal names common to all memory interfaces static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), @@ -149,6 +139,16 @@ inline static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) return ""; } +namespace detail { + +inline std::string simpleInputPortName(unsigned idx) { + return "ins_" + std::to_string(idx); +} + +inline std::string simpleOutputPortName(unsigned idx) { + return "outs_" + std::to_string(idx); +} + } // end namespace detail } // end namespace handshake } // end namespace dynamatic From 58baf07b84cee14308e5e53c797d39cd54311a1c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:48:09 +0200 Subject: [PATCH 027/187] move autogenerated? --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 35c87676b9..6763b70e09 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -29,6 +29,8 @@ #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" +#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h.inc" + namespace dynamatic { namespace handshake { @@ -153,6 +155,4 @@ inline std::string simpleOutputPortName(unsigned idx) { } // end namespace handshake } // end namespace dynamatic -#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h.inc" - #endif // DYNAMATIC_DIALECT_HANDSHAKE_HANDSHAKE_INTERFACES_H From 3a560616049a483e928ae1687d99f138078e6d41 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:49:41 +0200 Subject: [PATCH 028/187] forward declaration --- .../dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 6763b70e09..0aa643ce15 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -29,8 +29,6 @@ #include "mlir/Interfaces/InferTypeOpInterface.h" #include "mlir/Interfaces/SideEffectInterfaces.h" -#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h.inc" - namespace dynamatic { namespace handshake { @@ -70,6 +68,11 @@ class PortNamer { class ControlType; +class MemoryOpInterface; +class FuncMemoryPorts; +class GroupMemoryPorts; +class LoadPort; + /// Load/Store base signal names common to all memory interfaces static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), @@ -155,4 +158,6 @@ inline std::string simpleOutputPortName(unsigned idx) { } // end namespace handshake } // end namespace dynamatic +#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h.inc" + #endif // DYNAMATIC_DIALECT_HANDSHAKE_HANDSHAKE_INTERFACES_H From e22ff8733ff8f35d386e75882db542fa1b96fe58 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:54:44 +0200 Subject: [PATCH 029/187] move into ops h --- .../Dialect/Handshake/HandshakeInterfaces.h | 76 ------------------- .../Dialect/Handshake/HandshakeOps.h | 72 ++++++++++++++++++ 2 files changed, 72 insertions(+), 76 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 0aa643ce15..cec918b997 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -68,82 +68,6 @@ class PortNamer { class ControlType; -class MemoryOpInterface; -class FuncMemoryPorts; -class GroupMemoryPorts; -class LoadPort; - -/// Load/Store base signal names common to all memory interfaces -static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), - MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), - LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); - -inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { - if (!memOp.isMasterInterface()) - return ""; - switch (idx) { - case 0: - return MEMREF; - case 1: - return MEM_START; - default: - return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; - } -} - -static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { - if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) - return MEM_END; - return ""; -} - -/// Common operand naming logic for memory controllers and LSQs. -inline static std::string getMemOperandName(const FuncMemoryPorts &ports, - unsigned idx) { - // Iterate through all memory ports to find out the type of the operand - unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - if (blockPorts.hasControl()) { - if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) - return getArrayElemName(CTRL, ctrlIdx); - ++ctrlIdx; - } - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getAddrInputIndex() == idx) - return getArrayElemName(LD_ADDR, loadIdx); - ++loadIdx; - } else { - std::optional storePort = cast(accessPort); - if (storePort->getAddrInputIndex() == idx) - return getArrayElemName(ST_ADDR, storeIdx); - if (storePort->getDataInputIndex() == idx) - return getArrayElemName(ST_DATA, storeIdx); - ++storeIdx; - } - } - } - - return ""; -} - -/// Common result naming logic for memory controllers and LSQs. -inline static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { - // Iterate through all memory ports to find out the type of the - // operand - unsigned loadIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getDataOutputIndex() == idx) - return getArrayElemName(LD_DATA, loadIdx); - ++loadIdx; - } - } - } - return ""; -} - namespace detail { inline std::string simpleInputPortName(unsigned idx) { diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index cd16366c41..71a3a9258b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -576,6 +576,78 @@ FuncMemoryPorts getMemoryPorts(dynamatic::handshake::MemoryOpInterface memOp); /// giving up. Returns `nullptr` if no memory interface could be found. handshake::MemoryOpInterface findMemInterface(Value val); + +/// Load/Store base signal names common to all memory interfaces +static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), + MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), + LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); + +inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { + if (!memOp.isMasterInterface()) + return ""; + switch (idx) { + case 0: + return MEMREF; + case 1: + return MEM_START; + default: + return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; + } +} + +static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { + if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) + return MEM_END; + return ""; +} + +/// Common operand naming logic for memory controllers and LSQs. +inline static std::string getMemOperandName(const FuncMemoryPorts &ports, + unsigned idx) { + // Iterate through all memory ports to find out the type of the operand + unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + if (blockPorts.hasControl()) { + if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) + return getArrayElemName(CTRL, ctrlIdx); + ++ctrlIdx; + } + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getAddrInputIndex() == idx) + return getArrayElemName(LD_ADDR, loadIdx); + ++loadIdx; + } else { + std::optional storePort = cast(accessPort); + if (storePort->getAddrInputIndex() == idx) + return getArrayElemName(ST_ADDR, storeIdx); + if (storePort->getDataInputIndex() == idx) + return getArrayElemName(ST_DATA, storeIdx); + ++storeIdx; + } + } + } + + return ""; +} + +/// Common result naming logic for memory controllers and LSQs. +inline static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { + // Iterate through all memory ports to find out the type of the + // operand + unsigned loadIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getDataOutputIndex() == idx) + return getArrayElemName(LD_DATA, loadIdx); + ++loadIdx; + } + } + } + return ""; +} + } // namespace dynamatic // Structs to enable LLVM-style RTTI for the memory port hierarchy. From 75ff38d2d16140b83d5edc75813506b647e1c3d5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 15:59:16 +0200 Subject: [PATCH 030/187] mem interface in hs --- include/dynamatic/Dialect/Handshake/HandshakeOps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 71a3a9258b..8ba20d87df 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -582,7 +582,7 @@ static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); -inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { +inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, unsigned idx) { if (!memOp.isMasterInterface()) return ""; switch (idx) { @@ -595,7 +595,7 @@ inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) } } -static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { +static StringRef getIfControlRes(handshake::MemoryOpInterface memOp, unsigned idx) { if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) return MEM_END; return ""; From 8e8e2893e1cadb25d5eeed9fa875bb5f02536e9d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:00:57 +0200 Subject: [PATCH 031/187] remove body of end op get operands --- .../Dialect/Handshake/HandshakeOps.td | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index a2fc98b56d..5329c757ab 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1120,16 +1120,18 @@ def EndOp : Handshake_Op<"end", [ let arguments = (ins Variadic:$inputs); let extraClassDeclaration = [{ - std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - - unsigned numResults = funcOp.getFunctionType().getNumResults(); - if (idx < numResults) - return "ins_" + std::to_string(idx); - return "memDone_" + std::to_string(idx - numResults); - } + std::string getOperandName(unsigned idx); + + // { + // assert(idx < getNumOperands() && "index too high"); + // handshake::FuncOp funcOp = (*this)->getParentOfType(); + // assert(funcOp && "end must be child of handshake function"); + + // unsigned numResults = funcOp.getFunctionType().getNumResults(); + // if (idx < numResults) + // return "ins_" + std::to_string(idx); + // return "memDone_" + std::to_string(idx - numResults); + // } std::string getResultName(unsigned idx) { assert(false && "index too high"); From 389668aa5a01b093b31c3708f75ec22c706d444a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:04:16 +0200 Subject: [PATCH 032/187] get array --- include/dynamatic/Dialect/Handshake/HandshakeOps.h | 4 ++++ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 9 --------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 8ba20d87df..e36e68e7ea 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -582,6 +582,10 @@ static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); +static inline std::string getArrayElemName(const Twine &name, unsigned idx) { + return name.str() + "_" + std::to_string(idx); +} + inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, unsigned idx) { if (!memOp.isMasterInterface()) return ""; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index c5458ff7fb..37f2a043e0 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -80,15 +80,6 @@ void PortNamer::inferFromFuncOp(handshake::FuncOp funcOp) { [](Attribute res) { return cast(res).str(); }); } -//===----------------------------------------------------------------------===// -// NamedIOInterface (getOperandName/getResultName) -//===----------------------------------------------------------------------===// - -static inline std::string getArrayElemName(const Twine &name, unsigned idx) { - return name.str() + "_" + std::to_string(idx); -} - - //===----------------------------------------------------------------------===// // MemoryOpInterface //===----------------------------------------------------------------------===// From d42e4a003464892c98ed2c000d2ecfde046272da Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:09:20 +0200 Subject: [PATCH 033/187] remove namedio from name analysis --- lib/Analysis/NameAnalysis.cpp | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 0f7b61252e..0299c04525 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -95,20 +95,33 @@ static bool tryToGetBlockArgName(BlockArgument arg, StringRef parentOpName, /// Returns the name of a result which is either provided by the /// handshake::NamedIOInterface interface or, failing that, is its index. static std::string getResultName(Operation *op, size_t resIdx) { - std::string oprName; - auto namedIO = dyn_cast(op); - op->emitError("missing named io interface"); - assert(namedIO); - return namedIO.getResultName(resIdx); + + if(auto nameInterface = dyn_cast(op)){ + return nameInterface.getResultName(idx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(idx); + }; + + op->emitError("all operations must specify result names"); + assert(0); } /// Returns the name of an operand which is either provided by the /// handshake::NamedIOInterface interface or, failing that, is its index. static std::string getOperandName(Operation *op, size_t oprdIdx) { - std::string oprName; - if (auto namedIO = dyn_cast(op)) - return namedIO.getOperandName(oprdIdx); - return std::to_string(oprdIdx); + + if(auto nameInterface = dyn_cast(op)){ + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getOperandName(idx); + }; + + op->emitError("all operations must specify operand names"); + assert(0); } StringRef NameAnalysis::getName(Operation *op) { From 3cbbda0ea7650d1c4b4b1e0fd02d9f7dd3598586 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:10:23 +0200 Subject: [PATCH 034/187] typo --- lib/Analysis/NameAnalysis.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 0299c04525..437e74d592 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -97,11 +97,11 @@ static bool tryToGetBlockArgName(BlockArgument arg, StringRef parentOpName, static std::string getResultName(Operation *op, size_t resIdx) { if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getResultName(idx); + return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(idx); + return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(idx); + return nameInterface.getResultName(resIdx); }; op->emitError("all operations must specify result names"); @@ -113,11 +113,11 @@ static std::string getResultName(Operation *op, size_t resIdx) { static std::string getOperandName(Operation *op, size_t oprdIdx) { if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getOperandName(idx); + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(idx); + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(idx); + return nameInterface.getOperandName(oprdIdx); }; op->emitError("all operations must specify operand names"); From d913d1af454c70aed53309ed345b18e0854bb58d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:19:17 +0200 Subject: [PATCH 035/187] typo --- .../Dialect/Handshake/HandshakeInterfaces.h | 11 --- .../Dialect/Handshake/HandshakeOps.h | 76 ------------------ .../Dialect/Handshake/HandshakeOps.td | 12 +-- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 7 ++ lib/Dialect/Handshake/HandshakeOps.cpp | 80 +++++++++++++++++++ 5 files changed, 94 insertions(+), 92 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index cec918b997..a632978068 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -68,17 +68,6 @@ class PortNamer { class ControlType; -namespace detail { - -inline std::string simpleInputPortName(unsigned idx) { - return "ins_" + std::to_string(idx); -} - -inline std::string simpleOutputPortName(unsigned idx) { - return "outs_" + std::to_string(idx); -} - -} // end namespace detail } // end namespace handshake } // end namespace dynamatic diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index e36e68e7ea..cd16366c41 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -576,82 +576,6 @@ FuncMemoryPorts getMemoryPorts(dynamatic::handshake::MemoryOpInterface memOp); /// giving up. Returns `nullptr` if no memory interface could be found. handshake::MemoryOpInterface findMemInterface(Value val); - -/// Load/Store base signal names common to all memory interfaces -static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), - MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), - LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); - -static inline std::string getArrayElemName(const Twine &name, unsigned idx) { - return name.str() + "_" + std::to_string(idx); -} - -inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, unsigned idx) { - if (!memOp.isMasterInterface()) - return ""; - switch (idx) { - case 0: - return MEMREF; - case 1: - return MEM_START; - default: - return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; - } -} - -static StringRef getIfControlRes(handshake::MemoryOpInterface memOp, unsigned idx) { - if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) - return MEM_END; - return ""; -} - -/// Common operand naming logic for memory controllers and LSQs. -inline static std::string getMemOperandName(const FuncMemoryPorts &ports, - unsigned idx) { - // Iterate through all memory ports to find out the type of the operand - unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - if (blockPorts.hasControl()) { - if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) - return getArrayElemName(CTRL, ctrlIdx); - ++ctrlIdx; - } - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getAddrInputIndex() == idx) - return getArrayElemName(LD_ADDR, loadIdx); - ++loadIdx; - } else { - std::optional storePort = cast(accessPort); - if (storePort->getAddrInputIndex() == idx) - return getArrayElemName(ST_ADDR, storeIdx); - if (storePort->getDataInputIndex() == idx) - return getArrayElemName(ST_DATA, storeIdx); - ++storeIdx; - } - } - } - - return ""; -} - -/// Common result naming logic for memory controllers and LSQs. -inline static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { - // Iterate through all memory ports to find out the type of the - // operand - unsigned loadIdx = 0; - for (const GroupMemoryPorts &blockPorts : ports.groups) { - for (const MemoryPort &accessPort : blockPorts.accessPorts) { - if (std::optional loadPort = dyn_cast(accessPort)) { - if (loadPort->getDataOutputIndex() == idx) - return getArrayElemName(LD_DATA, loadIdx); - ++loadIdx; - } - } - } - return ""; -} - } // namespace dynamatic // Structs to enable LLVM-style RTTI for the memory port hierarchy. diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 5329c757ab..63c7e0d214 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -443,12 +443,12 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : detail::simpleInputPortName(idx - 1); + return idx == 0 ? "index" : simpleInputPortName(idx - 1); } std::string getResultName(unsigned idx) { assert(idx < 1 && "index too high"); - return detail::simpleOutputPortName(idx); + return simpleOutputPortName(idx); } }]; @@ -497,10 +497,10 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let extraClassDeclaration = [{ + let extraClassDefinition = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return detail::simpleInputPortName(idx); + return simpleInputPortName(idx); } std::string getResultName(unsigned idx) { @@ -573,7 +573,9 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ let extraClassDeclaration = [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; + }]; + let extraClassDefinition = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "condition" : "data"; @@ -770,7 +772,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ "ArrayRef":$blocks, "unsigned":$numLoads)>]; - let extraClassDeclaration = [{ + let extraClassDefinition = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 37f2a043e0..3d6d585592 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -112,5 +112,12 @@ TypedValue LSQOp::getCtrlEnd() { return cast>(getOperands().back()); } +std::string simpleInputPortName(unsigned idx) { + return "ins_" + std::to_string(idx); +} + +std::string simpleOutputPortName(unsigned idx) { + return "outs_" + std::to_string(idx); +} #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index c0e5facdeb..45bba6a1ec 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1980,5 +1980,85 @@ LogicalResult TruncFOp::verify() { return verifyTruncOp(*this); } //===----------------------------------------------------------------------===// LogicalResult ExtFOp::verify() { return verifyExtOp(*this); } + +//===----------------------------------------------------------------------===// +// Memory Controller GetOperandName and GetResultName Utilities +//===----------------------------------------------------------------------===// + +/// Load/Store base signal names common to all memory interfaces +static constexpr llvm::StringLiteral MEMREF("memref"), MEM_START("memStart"), + MEM_END("memEnd"), CTRL_END("ctrlEnd"), CTRL("ctrl"), LD_ADDR("ldAddr"), + LD_DATA("ldData"), ST_ADDR("stAddr"), ST_DATA("stData"); + +static inline std::string getArrayElemName(const Twine &name, unsigned idx) { + return name.str() + "_" + std::to_string(idx); +} + +inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, unsigned idx) { + if (!memOp.isMasterInterface()) + return ""; + switch (idx) { + case 0: + return MEMREF; + case 1: + return MEM_START; + default: + return idx == memOp->getNumOperands() - 1 ? CTRL_END : ""; + } +} + +static StringRef getIfControlRes(handshake::MemoryOpInterface memOp, unsigned idx) { + if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) + return MEM_END; + return ""; +} + +/// Common operand naming logic for memory controllers and LSQs. +inline static std::string getMemOperandName(const FuncMemoryPorts &ports, + unsigned idx) { + // Iterate through all memory ports to find out the type of the operand + unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + if (blockPorts.hasControl()) { + if (idx == blockPorts.ctrlPort->getCtrlInputIndex()) + return getArrayElemName(CTRL, ctrlIdx); + ++ctrlIdx; + } + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getAddrInputIndex() == idx) + return getArrayElemName(LD_ADDR, loadIdx); + ++loadIdx; + } else { + std::optional storePort = cast(accessPort); + if (storePort->getAddrInputIndex() == idx) + return getArrayElemName(ST_ADDR, storeIdx); + if (storePort->getDataInputIndex() == idx) + return getArrayElemName(ST_DATA, storeIdx); + ++storeIdx; + } + } + } + + return ""; +} + +/// Common result naming logic for memory controllers and LSQs. +static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { + // Iterate through all memory ports to find out the type of the + // operand + unsigned loadIdx = 0; + for (const GroupMemoryPorts &blockPorts : ports.groups) { + for (const MemoryPort &accessPort : blockPorts.accessPorts) { + if (std::optional loadPort = dyn_cast(accessPort)) { + if (loadPort->getDataOutputIndex() == idx) + return getArrayElemName(LD_DATA, loadIdx); + ++loadIdx; + } + } + } + return ""; +} + #define GET_OP_CLASSES #include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" \ No newline at end of file From 9c394cbf62fc1860131d483de209791612d3d100 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:23:27 +0200 Subject: [PATCH 036/187] try declaration? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- lib/Dialect/Handshake/HandshakeOps.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 63c7e0d214..d1001ecd9c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1414,7 +1414,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ type($trueResult) `,` type($falseResult) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 45bba6a1ec..4b41c24580 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1994,7 +1994,7 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { return name.str() + "_" + std::to_string(idx); } -inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, unsigned idx) { +inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { if (!memOp.isMasterInterface()) return ""; switch (idx) { @@ -2007,7 +2007,7 @@ inline static StringRef getIfControlOprd(handshake::MemoryOpInterface memOp, uns } } -static StringRef getIfControlRes(handshake::MemoryOpInterface memOp, unsigned idx) { +static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { if (memOp.isMasterInterface() && idx == memOp->getNumResults() - 1) return MEM_END; return ""; From 7b951d6855fc8d4974b509fff16ab8634ce469ab Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:24:40 +0200 Subject: [PATCH 037/187] move back into header --- .../dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 11 +++++++++++ include/dynamatic/Dialect/Handshake/HandshakeOps.td | 6 +++--- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 7 ------- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index a632978068..cec918b997 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -68,6 +68,17 @@ class PortNamer { class ControlType; +namespace detail { + +inline std::string simpleInputPortName(unsigned idx) { + return "ins_" + std::to_string(idx); +} + +inline std::string simpleOutputPortName(unsigned idx) { + return "outs_" + std::to_string(idx); +} + +} // end namespace detail } // end namespace handshake } // end namespace dynamatic diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d1001ecd9c..702ff23672 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -443,12 +443,12 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return idx == 0 ? "index" : simpleInputPortName(idx - 1); + return idx == 0 ? "index" : detail::simpleInputPortName(idx - 1); } std::string getResultName(unsigned idx) { assert(idx < 1 && "index too high"); - return simpleOutputPortName(idx); + return detail::simpleOutputPortName(idx); } }]; @@ -500,7 +500,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ let extraClassDefinition = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); - return simpleInputPortName(idx); + return detail::simpleInputPortName(idx); } std::string getResultName(unsigned idx) { diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 3d6d585592..37f2a043e0 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -112,12 +112,5 @@ TypedValue LSQOp::getCtrlEnd() { return cast>(getOperands().back()); } -std::string simpleInputPortName(unsigned idx) { - return "ins_" + std::to_string(idx); -} - -std::string simpleOutputPortName(unsigned idx) { - return "outs_" + std::to_string(idx); -} #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" From 098ddb432f77f3c5d1f6c87be2fc6f3ccf60eae6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:27:11 +0200 Subject: [PATCH 038/187] remove lsq temporarily --- .../Dialect/Handshake/HandshakeOps.td | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 702ff23672..d7426207f8 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -928,45 +928,46 @@ def LSQOp : Handshake_Op<"lsq", [ /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); - std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + // std::string getOperandName(unsigned idx) { - if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - return name.str(); + // assert(idx < getNumOperands() && "index too high"); - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) - return name; + // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + // return name.str(); - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && - "unknown LSQ/MC operand"); - return "ldDataFromMC"; - } + // // Try to get the operand name from the regular ports + // LSQPorts lsqPorts = getPorts(); + // if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) + // return name; - std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); - - if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) - return name; + // // Get the operand name from a port to a memory controller + // assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + // assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && + // "unknown LSQ/MC operand"); + // return "ldDataFromMC"; + // } - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - MCLoadStorePort mcPort = lsqPorts.getMCPort(); - if (mcPort.getLoadAddrOutputIndex() == idx) - return "ldAddrToMC"; - if (mcPort.getStoreAddrOutputIndex() == idx) - return "stAddrToMC"; - assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); - return "stDataToMC"; - } + // std::string getResultName(unsigned idx) { + // assert(idx < getNumResults() && "index too high"); + + // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + // return name.str(); + + // // Try to get the operand name from the regular ports + // LSQPorts lsqPorts = getPorts(); + // if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) + // return name; + + // // Get the operand name from a port to a memory controller + // assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + // MCLoadStorePort mcPort = lsqPorts.getMCPort(); + // if (mcPort.getLoadAddrOutputIndex() == idx) + // return "ldAddrToMC"; + // if (mcPort.getStoreAddrOutputIndex() == idx) + // return "stAddrToMC"; + // assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); + // return "stDataToMC"; + // } }]; } From c125231caa06a395dd1dff1911b9c90bacfd313b Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:28:24 +0200 Subject: [PATCH 039/187] interfaces for name analysis --- lib/Analysis/NameAnalysis.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 437e74d592..40905ed31f 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -12,6 +12,7 @@ #include "dynamatic/Analysis/NameAnalysis.h" #include "dynamatic/Dialect/Handshake/HandshakeOps.h" +#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h" #include "dynamatic/Support/LLVM.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Attributes.h" From 30a842ae2e62fd135f23b48f453e4c6757e7a64c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:29:50 +0200 Subject: [PATCH 040/187] fix name --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 2 +- lib/Analysis/NameAnalysis.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 9400663dcb..b63b8a0700 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -159,7 +159,7 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } -def SimpleNamedIOInterface : OpInterface<"SimpleIOInterface"> { +def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = [{"Provides detailed names for the operands and results of an operation."}]; diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 40905ed31f..437e74d592 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -12,7 +12,6 @@ #include "dynamatic/Analysis/NameAnalysis.h" #include "dynamatic/Dialect/Handshake/HandshakeOps.h" -#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h" #include "dynamatic/Support/LLVM.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/IR/Attributes.h" From d73592032ce22d98dcb567f5c91185fcd1db5f5a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:36:03 +0200 Subject: [PATCH 041/187] more into header files --- .../Dialect/Handshake/HandshakeOps.td | 104 +++++++++--------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d7426207f8..8b873dc81d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -497,7 +497,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return detail::simpleInputPortName(idx); @@ -575,7 +575,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ enum { trueIndex = 0, falseIndex = 1 }; }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "condition" : "data"; @@ -772,45 +772,45 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ "ArrayRef":$blocks, "unsigned":$numLoads)>]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + // assert(idx < getNumOperands() && "index too high"); - if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - MCPorts mcPorts = getPorts(); - if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to an LSQ - assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - if (lsqPort.getLoadAddrInputIndex() == idx) - return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); - if (lsqPort.getStoreAddrInputIndex() == idx) - return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); - assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); - return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); - } + // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + // return name.str(); - std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + // // Try to get the operand name from the regular ports + // MCPorts mcPorts = getPorts(); + // if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) + // return name; + + // // Get the operand name from a port to an LSQ + // assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + // LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + // if (lsqPort.getLoadAddrInputIndex() == idx) + // return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); + // if (lsqPort.getStoreAddrInputIndex() == idx) + // return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); + // assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); + // return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); + // } + + // std::string getResultName(unsigned idx) { + // assert(idx < getNumResults() && "index too high"); - if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - return name.str(); + // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + // return name.str(); - // Try to get the operand name from the regular ports - MCPorts mcPorts = getPorts(); - if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) - return name; + // // Try to get the operand name from the regular ports + // MCPorts mcPorts = getPorts(); + // if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) + // return name; - // Get the operand name from a port to an LSQ - assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); - return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); + // // Get the operand name from a port to an LSQ + // assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + // LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + // assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); + // return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); } }]; let hasVerifier = 1; @@ -1047,7 +1047,7 @@ def LoadOp : Handshake_MemPortOp<"load", [ ``` }]; - let extraClassDefinition = [{ + let extraClassDeclaration= [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; @@ -1089,7 +1089,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned int idx) { return (idx == 0) ? "addrIn" : "dataIn"; } @@ -1218,7 +1218,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ wideControlType, ctrlType}); }]>]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "ins" : "trigger"; @@ -1277,7 +1277,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; @@ -1325,7 +1325,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; @@ -1367,14 +1367,14 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($ctrl) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + assert(idx < getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + assert(idx < getNumResults() && "index too high"); return "outs"; } }]; @@ -1455,14 +1455,14 @@ def NonSpecOp : Handshake_Op<"non_spec", [ $dataIn attr-dict `:` type($dataIn) `to` type($dataOut) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + assert(idx < getNumOperands() && "index too high"); return "dataIn"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + assert(idx < getNumResults() && "index too high"); return "dataOut"; } }]; @@ -1519,7 +1519,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); if (idx < getNumSharedOperands() * getNumSharedOperations()) { @@ -1690,12 +1690,14 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - let extraClassDefinition = [{ - std::string getOperandName(unsigned idx = 0) { + let extraClassDeclaration = [{ + std::string getOperandName(unsigned idx){ + assert(idx < 1 && "index too high"); return "ins"; } - std::string getResultName(unsigned idx = 0) { + std::string getResultName(unsigned idx) { + assert(idx < 1 && "index too high"); return "outs"; } }]; @@ -1723,7 +1725,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ $lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn)) }]; - let extraClassDefinition = [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; From 9b7919104478b93108ad06ba831f49247880828b Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:38:01 +0200 Subject: [PATCH 042/187] num operands on operation? --- .../Dialect/Handshake/HandshakeOps.td | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 8b873dc81d..a05361cb83 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -442,7 +442,7 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "index" : detail::simpleInputPortName(idx - 1); } @@ -499,7 +499,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return detail::simpleInputPortName(idx); } @@ -577,7 +577,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "condition" : "data"; } @@ -774,7 +774,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - // assert(idx < getNumOperands() && "index too high"); + // assert(idx < getOperation()->getNumOperands() && "index too high"); // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) // return name.str(); @@ -930,7 +930,7 @@ def LSQOp : Handshake_Op<"lsq", [ // std::string getOperandName(unsigned idx) { - // assert(idx < getNumOperands() && "index too high"); + // assert(idx < getOperation()->getNumOperands() && "index too high"); // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) // return name.str(); @@ -1049,7 +1049,7 @@ def LoadOp : Handshake_MemPortOp<"load", [ let extraClassDeclaration= [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; } @@ -1126,7 +1126,7 @@ def EndOp : Handshake_Op<"end", [ std::string getOperandName(unsigned idx); // { - // assert(idx < getNumOperands() && "index too high"); + // assert(idx < getOperation()->getNumOperands() && "index too high"); // handshake::FuncOp funcOp = (*this)->getParentOfType(); // assert(funcOp && "end must be child of handshake function"); @@ -1220,7 +1220,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "trigger"; } @@ -1369,7 +1369,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } @@ -1417,7 +1417,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; } @@ -1457,7 +1457,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return "dataIn"; } @@ -1521,7 +1521,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); if (idx < getNumSharedOperands() * getNumSharedOperations()) { return "op" + std::to_string(idx / getNumSharedOperands()) + "in" + std::to_string(idx % getNumSharedOperands()); @@ -1727,12 +1727,12 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; } std::string getResultName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "lhs_outs" : "rhs_outs"; } }]; From 894643d2a9c31cf633031ce7d3a5e545dab6232c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:39:10 +0200 Subject: [PATCH 043/187] results from get operation --- .../dynamatic/Dialect/Handshake/HandshakeOps.td | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index a05361cb83..3424967f1d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -796,7 +796,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ // } // std::string getResultName(unsigned idx) { - // assert(idx < getNumResults() && "index too high"); + // assert(idx < getOperation()->getNumResults() && "index too high"); // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) // return name.str(); @@ -948,7 +948,7 @@ def LSQOp : Handshake_Op<"lsq", [ // } // std::string getResultName(unsigned idx) { - // assert(idx < getNumResults() && "index too high"); + // assert(idx < getOperation()->getNumResults() && "index too high"); // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) // return name.str(); @@ -1054,7 +1054,7 @@ def LoadOp : Handshake_MemPortOp<"load", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < getOperation()->getNumResults() && "index too high"); return (idx == 0) ? "addrOut" : "dataOut"; } }]; @@ -1225,7 +1225,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < getOperation()->getNumResults() && "index too high"); switch (idx) { case 0: return "outs"; @@ -1374,7 +1374,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } }]; @@ -1462,7 +1462,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < getOperation()->getNumResults() && "index too high"); return "dataOut"; } }]; @@ -1530,7 +1530,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ } std::string getResultName(unsigned idx) { - assert(idx < getNumResults() && "index too high"); + assert(idx < getOperation()->getNumResults() && "index too high"); if (idx < getNumSharedOperations()) return "op" + std::to_string(idx) + "out0"; return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); From 42b659880f989db7b4bc120d5ea68ec9a6b8a039 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Thu, 31 Jul 2025 16:40:17 +0200 Subject: [PATCH 044/187] merge declarations cond br --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 3424967f1d..bceaf0ba87 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -570,12 +570,11 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ $conditionOperand `,` $dataOperand attr-dict `:` type($conditionOperand) `,` custom(type($dataOperand)) }]; + let extraClassDeclaration = [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; - }]; - let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "condition" : "data"; @@ -583,7 +582,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ std::string getResultName(unsigned idx) { assert(idx < 2 && "index too high"); - return idx == ConditionalBranchOp::trueIndex ? "trueOut" : "falseOut"; + return idx == trueIndex ? "trueOut" : "falseOut"; } }]; } From 5491bb1fdd5ebe8d327a957915726aae2f48b918 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:08:52 +0200 Subject: [PATCH 045/187] remove polygeist path --- tools/dynamatic/dynamatic.cpp | 56 +++--------------------------- tools/dynamatic/scripts/compile.sh | 17 +++++---- 2 files changed, 12 insertions(+), 61 deletions(-) diff --git a/tools/dynamatic/dynamatic.cpp b/tools/dynamatic/dynamatic.cpp index 9f2021eb7b..783f488586 100644 --- a/tools/dynamatic/dynamatic.cpp +++ b/tools/dynamatic/dynamatic.cpp @@ -90,7 +90,6 @@ namespace { struct FrontendState { std::string cwd; std::string dynamaticPath; - std::string polygeistPath; std::string vivadoPath = "/tools/Xilinx/Vivado/2019.1/"; std::string fpUnitsGenerator = "flopoco"; // By default, the clock period is 4 ns @@ -221,17 +220,6 @@ class SetDynamaticPath : public Command { CommandResult execute(CommandArguments &args) override; }; -class SetPolygeistPath : public Command { -public: - SetPolygeistPath(FrontendState &state) - : Command("set-polygeist-path", - "Sets the path to Polygeist installation directory", state) { - addPositionalArg({"path", "path to Polygeist installation directory"}); - } - - CommandResult execute(CommandArguments &args) override; -}; - class SetVivadoPath : public Command { public: SetVivadoPath(FrontendState &state) @@ -530,16 +518,9 @@ CommandResult SetDynamaticPath::execute(CommandArguments &args) { if (StringRef(dynamaticPath).ends_with(sep)) dynamaticPath = dynamaticPath.substr(0, dynamaticPath.size() - 1); - // Check whether the path makes sense - if (!fs::exists(dynamaticPath + sep + "polygeist")) { - llvm::outs() << ERR << "'" << dynamaticPath - << "' doesn't seem to point to Dynamatic, expected to " - "find, for example, a directory named 'polygeist' there.\n"; - return CommandResult::FAIL; - } - if (!fs::exists(dynamaticPath + sep + "bin")) { + if (!fs::exists(dynamaticPath + sep + "bin" + sep + "dynamatic")) { llvm::outs() << ERR - << "No 'bin' directory in provided path, Dynamatic doesn't " + << "No 'dynamatic' executable found in bin/, Dynamatic doesn't " "seem to have been built.\n"; return CommandResult::FAIL; } @@ -548,32 +529,6 @@ CommandResult SetDynamaticPath::execute(CommandArguments &args) { return CommandResult::SUCCESS; } -CommandResult SetPolygeistPath::execute(CommandArguments &args) { - // Remove the separator at the end of the path if there is one - StringRef sep = sys::path::get_separator(); - std::string polygeistPath = args.positionals.front().str(); - if (StringRef(polygeistPath).ends_with(sep)) - polygeistPath = polygeistPath.substr(0, polygeistPath.size() - 1); - - // Check whether the path makes sense - if (!fs::exists(polygeistPath + sep + "llvm-project/")) { - llvm::outs() - << ERR << "'" << polygeistPath - << "' doesn't seem to point to Polygeist, expected to " - "find, for example, a directory named 'llvm-project/' there.\n"; - return CommandResult::FAIL; - } - if (!fs::exists(polygeistPath + sep + "build/bin/")) { - llvm::outs() << ERR - << "No 'bin' directory in provided path, Polygeist doesn't " - "seem to have been built.\n"; - return CommandResult::FAIL; - } - - state.polygeistPath = state.makeAbsolutePath(polygeistPath); - return CommandResult::SUCCESS; -} - CommandResult SetVivadoPath::execute(CommandArguments &args) { // Remove the separator at the end of the path if there is one StringRef sep = sys::path::get_separator(); @@ -658,12 +613,10 @@ CommandResult Compile::execute(CommandArguments &args) { std::string sharing = args.flags.contains(SHARING) ? "1" : "0"; std::string rigidification = args.flags.contains(RIGIDIFICATION) ? "1" : "0"; std::string disableLSQ = args.flags.contains(DISABLE_LSQ) ? "1" : "0"; - state.polygeistPath = state.polygeistPath.empty() - ? state.dynamaticPath + getSeparator() + "polygeist" - : state.polygeistPath; + return execCmd(script, state.dynamaticPath, state.getKernelDir(), state.getOutputDir(), state.getKernelName(), buffers, - floatToString(state.targetCP, 3), state.polygeistPath, sharing, + floatToString(state.targetCP, 3), sharing, state.fpUnitsGenerator, rigidification, disableLSQ, fastTokenDelivery); } @@ -787,7 +740,6 @@ int main(int argc, char **argv) { FrontendState state(cwd.str()); FrontendCommands commands; commands.add(state); - commands.add(state); commands.add(state); commands.add(state); commands.add(state); diff --git a/tools/dynamatic/scripts/compile.sh b/tools/dynamatic/scripts/compile.sh index 63b509e104..637657a6ae 100755 --- a/tools/dynamatic/scripts/compile.sh +++ b/tools/dynamatic/scripts/compile.sh @@ -13,15 +13,14 @@ OUTPUT_DIR=$3 KERNEL_NAME=$4 BUFFER_ALGORITHM=$5 TARGET_CP=$6 -POLYGEIST_PATH=$7 -USE_SHARING=$8 -FPUNITS_GEN=$9 -USE_RIGIDIFICATION=${10} -DISABLE_LSQ=${11} -FAST_TOKEN_DELIVERY=${12} - -POLYGEIST_CLANG_BIN="$POLYGEIST_PATH/build/bin/cgeist" -CLANGXX_BIN="$POLYGEIST_PATH/llvm-project/build/bin/clang++" +USE_SHARING=$7 +FPUNITS_GEN=$8 +USE_RIGIDIFICATION=${9} +DISABLE_LSQ=${10} +FAST_TOKEN_DELIVERY=${11} + +POLYGEIST_CLANG_BIN="$DYNAMATIC_DIR/build/bin/cgeist" +CLANGXX_BIN="$DYNAMATIC_DIR/bin/clang++" DYNAMATIC_OPT_BIN="$DYNAMATIC_DIR/bin/dynamatic-opt" DYNAMATIC_PROFILER_BIN="$DYNAMATIC_DIR/bin/exp-frequency-profiler" DYNAMATIC_EXPORT_DOT_BIN="$DYNAMATIC_DIR/bin/export-dot" From 8282ba3dcfd9e2a08d578899c026ab61b2c4d83c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:13:00 +0200 Subject: [PATCH 046/187] typo --- tools/dynamatic/scripts/compile.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dynamatic/scripts/compile.sh b/tools/dynamatic/scripts/compile.sh index 637657a6ae..f26dd9fac8 100755 --- a/tools/dynamatic/scripts/compile.sh +++ b/tools/dynamatic/scripts/compile.sh @@ -19,7 +19,7 @@ USE_RIGIDIFICATION=${9} DISABLE_LSQ=${10} FAST_TOKEN_DELIVERY=${11} -POLYGEIST_CLANG_BIN="$DYNAMATIC_DIR/build/bin/cgeist" +POLYGEIST_CLANG_BIN="$DYNAMATIC_DIR/bin/cgeist" CLANGXX_BIN="$DYNAMATIC_DIR/bin/clang++" DYNAMATIC_OPT_BIN="$DYNAMATIC_DIR/bin/dynamatic-opt" DYNAMATIC_PROFILER_BIN="$DYNAMATIC_DIR/bin/exp-frequency-profiler" From 4bfed54aa5c5ec8157aa60c0a21f4f6587eadc0e Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:36:04 +0200 Subject: [PATCH 047/187] fix includes --- build.sh | 12 ++++++++++++ tools/dynamatic/scripts/compile.sh | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index acd8ccf475..0c6d4bf022 100755 --- a/build.sh +++ b/build.sh @@ -93,6 +93,13 @@ create_generator_symlink() { ln -f --symbolic ../../$src $dst } +create_include_symlink() { + local src=$1 + local dst="include/polygeist" + echo "$dst -> $src" + ln -f --symbolic ../../$src $dst +} + # Determine whether cmake should be re-configured by looking for a # CMakeCache.txt file in the current working directory. @@ -424,6 +431,11 @@ create_generator_symlink build/bin/rtl-text-generator create_generator_symlink build/bin/rtl-constant-generator-verilog create_generator_symlink build/bin/exp-sharing-wrapper-generator create_generator_symlink "$LSQ_GEN_PATH/$LSQ_GEN_JAR" + +# Create symbolic links to polygeist headers (standard c library for clang) +create_include_symlink "$POLYGEIST_DIR"/llvm-project/clang/lib/Headers + + if [[ $GODOT_PATH != "" ]]; then create_symlink ../visual-dataflow/bin/visual-dataflow fi diff --git a/tools/dynamatic/scripts/compile.sh b/tools/dynamatic/scripts/compile.sh index f26dd9fac8..7db8dbf001 100755 --- a/tools/dynamatic/scripts/compile.sh +++ b/tools/dynamatic/scripts/compile.sh @@ -97,7 +97,7 @@ rm -rf "$COMP_DIR" && mkdir -p "$COMP_DIR" # source -> affine level "$POLYGEIST_CLANG_BIN" "$SRC_DIR/$KERNEL_NAME.c" --function="$KERNEL_NAME" \ - -I "$POLYGEIST_PATH/llvm-project/clang/lib/Headers" \ + -I "$DYNAMATIC_DIR/include/polygeist" \ -I "$DYNAMATIC_DIR/include" \ -S -O3 --memref-fullrank --raise-scf-to-affine \ > "$F_AFFINE" From b7193016cbc9de7fae71343def1f9f2e313b3628 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:44:50 +0200 Subject: [PATCH 048/187] fixes --- build.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 0c6d4bf022..4339670efb 100755 --- a/build.sh +++ b/build.sh @@ -97,10 +97,9 @@ create_include_symlink() { local src=$1 local dst="include/polygeist" echo "$dst -> $src" - ln -f --symbolic ../../$src $dst + ln -fnsv "$src" "$dst" } - # Determine whether cmake should be re-configured by looking for a # CMakeCache.txt file in the current working directory. should_run_cmake() { From 1ab9e5e3b1f7a2363ca8c9062ab3ab7fd09f3b7b Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:48:39 +0200 Subject: [PATCH 049/187] clang format --- tools/dynamatic/dynamatic.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/dynamatic/dynamatic.cpp b/tools/dynamatic/dynamatic.cpp index 783f488586..06d4c75695 100644 --- a/tools/dynamatic/dynamatic.cpp +++ b/tools/dynamatic/dynamatic.cpp @@ -519,9 +519,10 @@ CommandResult SetDynamaticPath::execute(CommandArguments &args) { dynamaticPath = dynamaticPath.substr(0, dynamaticPath.size() - 1); if (!fs::exists(dynamaticPath + sep + "bin" + sep + "dynamatic")) { - llvm::outs() << ERR - << "No 'dynamatic' executable found in bin/, Dynamatic doesn't " - "seem to have been built.\n"; + llvm::outs() + << ERR + << "No 'dynamatic' executable found in bin/, Dynamatic doesn't " + "seem to have been built.\n"; return CommandResult::FAIL; } @@ -614,11 +615,10 @@ CommandResult Compile::execute(CommandArguments &args) { std::string rigidification = args.flags.contains(RIGIDIFICATION) ? "1" : "0"; std::string disableLSQ = args.flags.contains(DISABLE_LSQ) ? "1" : "0"; - return execCmd(script, state.dynamaticPath, state.getKernelDir(), - state.getOutputDir(), state.getKernelName(), buffers, - floatToString(state.targetCP, 3), sharing, - state.fpUnitsGenerator, rigidification, disableLSQ, - fastTokenDelivery); + return execCmd( + script, state.dynamaticPath, state.getKernelDir(), state.getOutputDir(), + state.getKernelName(), buffers, floatToString(state.targetCP, 3), sharing, + state.fpUnitsGenerator, rigidification, disableLSQ, fastTokenDelivery); } CommandResult WriteHDL::execute(CommandArguments &args) { From f6eed098453a3a5ed2059a46779463aee79a59e8 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 15:56:31 +0200 Subject: [PATCH 050/187] move into build include --- build.sh | 2 +- tools/dynamatic/scripts/compile.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 4339670efb..8d0ea2180b 100755 --- a/build.sh +++ b/build.sh @@ -95,7 +95,7 @@ create_generator_symlink() { create_include_symlink() { local src=$1 - local dst="include/polygeist" + local dst="build/include/polygeist" echo "$dst -> $src" ln -fnsv "$src" "$dst" } diff --git a/tools/dynamatic/scripts/compile.sh b/tools/dynamatic/scripts/compile.sh index 7db8dbf001..b2d383d11b 100755 --- a/tools/dynamatic/scripts/compile.sh +++ b/tools/dynamatic/scripts/compile.sh @@ -97,7 +97,7 @@ rm -rf "$COMP_DIR" && mkdir -p "$COMP_DIR" # source -> affine level "$POLYGEIST_CLANG_BIN" "$SRC_DIR/$KERNEL_NAME.c" --function="$KERNEL_NAME" \ - -I "$DYNAMATIC_DIR/include/polygeist" \ + -I "$DYNAMATIC_DIR/build/include/polygeist" \ -I "$DYNAMATIC_DIR/include" \ -S -O3 --memref-fullrank --raise-scf-to-affine \ > "$F_AFFINE" From 58ffe7e0113075f8d9889335d20ae101f6d85cab Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 16:02:35 +0200 Subject: [PATCH 051/187] clean up link creation --- build.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 8d0ea2180b..f270b5f01b 100755 --- a/build.sh +++ b/build.sh @@ -97,7 +97,8 @@ create_include_symlink() { local src=$1 local dst="build/include/polygeist" echo "$dst -> $src" - ln -fnsv "$src" "$dst" + rm -rf "$dst" + ln -f --symbolic "$src" "$dst" } # Determine whether cmake should be re-configured by looking for a From 3accda344449e1a51860ae58057a153da86cfda9 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 22 Aug 2025 16:04:04 +0200 Subject: [PATCH 052/187] remove remove --- build.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/build.sh b/build.sh index f270b5f01b..3f25046e17 100755 --- a/build.sh +++ b/build.sh @@ -97,7 +97,6 @@ create_include_symlink() { local src=$1 local dst="build/include/polygeist" echo "$dst -> $src" - rm -rf "$dst" ln -f --symbolic "$src" "$dst" } From 33aa07bff72043e6b3f3d6c7b943701b2c8bb256 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:13:40 +0200 Subject: [PATCH 053/187] move naming into interfaces cpp --- .../Dialect/Handshake/HandshakeInterfaces.h | 7 -- lib/Analysis/NameAnalysis.cpp | 32 ------ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 100 +++++++++++------- 3 files changed, 61 insertions(+), 78 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index cec918b997..932a226393 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -52,13 +52,6 @@ class PortNamer { StringRef getOutputName(unsigned idx) const { return outputs[idx]; } private: - /// Maps the index of an input or output to its port name. - using IdxToStrF = const std::function &; - - void inferFromInterface(Operation *op); - - /// Infers port names for a Handshake function. - void inferFromFuncOp(FuncOp funcOp); /// List of input port names. SmallVector inputs; diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 437e74d592..f47a4f9ecc 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -92,38 +92,6 @@ static bool tryToGetBlockArgName(BlockArgument arg, StringRef parentOpName, }); } -/// Returns the name of a result which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getResultName(Operation *op, size_t resIdx) { - - if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - }; - - op->emitError("all operations must specify result names"); - assert(0); -} - -/// Returns the name of an operand which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getOperandName(Operation *op, size_t oprdIdx) { - - if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); - }; - - op->emitError("all operations must specify operand names"); - assert(0); -} - StringRef NameAnalysis::getName(Operation *op) { assert(namesValid && "analysis invariant is broken"); // If the operation already has a name or is intrinsically named , do nothing diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 37f2a043e0..a85e9e7988 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -28,56 +28,78 @@ using namespace mlir; using namespace dynamatic; using namespace dynamatic::handshake; + //===----------------------------------------------------------------------===// -// PortNameGenerator (uses NamedIOInterface) +// Operand and Result Names //===----------------------------------------------------------------------===// -PortNamer::PortNamer(Operation *op) { - assert(op && "cannot generate port names for null operation"); - if (auto funcOp = dyn_cast(op)){ - inferFromFuncOp(funcOp); - } else { - inferFromInterface(op); - } + +/// Returns the name of a result which is either provided by the +/// handshake::NamedIOInterface interface or, failing that, is its index. +static std::string getResultName(Operation *op, size_t resIdx) { + + if(auto nameInterface = dyn_cast(op)){ + return nameInterface.getResultName(resIdx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + }; + + op->emitError("all operations must specify result names"); + assert(0); } -void PortNamer::inferFromInterface(Operation *op) { - IdxToStrF inF, outF; +/// Returns the name of an operand which is either provided by the +/// handshake::NamedIOInterface interface or, failing that, is its index. +static std::string getOperandName(Operation *op, size_t oprdIdx) { + if(auto nameInterface = dyn_cast(op)){ - inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; - outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; - outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - inF = [&](unsigned idx) { return nameInterface.getOperandName(idx); }; - outF = [&](unsigned idx) { return nameInterface.getResultName(idx); }; - } else { - op->emitError("all normal operations must specify port names"); - assert(false); - } + return nameInterface.getOperandName(oprdIdx); + }; - for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) - inputs.push_back(inF(idx)); - for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) - outputs.push_back(outF(idx)); - - // The Handshake terminator forwards its non-memory inputs to its outputs, so - // it needs port names for them - if (handshake::EndOp endOp = dyn_cast(op)) { - handshake::FuncOp funcOp = endOp->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - size_t numResults = funcOp.getFunctionType().getNumResults(); - for (size_t idx = 0, e = numResults; idx < e; ++idx) - outputs.push_back(detail::simpleOutputPortName(idx)); - } + op->emitError("all operations must specify operand names"); + assert(0); } -void PortNamer::inferFromFuncOp(handshake::FuncOp funcOp) { - llvm::transform(funcOp.getArgNames(), std::back_inserter(inputs), - [](Attribute arg) { return cast(arg).str(); }); - llvm::transform(funcOp.getResNames(), std::back_inserter(outputs), - [](Attribute res) { return cast(res).str(); }); + +//===----------------------------------------------------------------------===// +// Operand and Result Names to Port Names +//===----------------------------------------------------------------------===// + +PortNamer::PortNamer(Operation *op) { + assert(op && "cannot generate port names for null operation"); + + // special case: input and output port names + // are actually stored in dictionary attributes + if (auto funcOp = dyn_cast(op)){ + llvm::transform(funcOp.getArgNames(), std::back_inserter(inputs), + [](Attribute arg) { return cast(arg).str(); }); + llvm::transform(funcOp.getResNames(), std::back_inserter(outputs), + [](Attribute res) { return cast(res).str(); }); + } else { + // all other operations must direclty provide names for their + // inputs and outputs + + for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) + inputs.push_back(getOperandName(op, idx)); + for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) + outputs.push_back(getResultName(op, idx)); + + // The Handshake terminator forwards its non-memory inputs to its outputs, so + // it needs port names for them + if (handshake::EndOp endOp = dyn_cast(op)) { + handshake::FuncOp funcOp = endOp->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + size_t numResults = funcOp.getFunctionType().getNumResults(); + for (size_t idx = 0; idx < numResults; ++idx) + outputs.push_back(detail::simpleOutputPortName(idx)); + } + } } //===----------------------------------------------------------------------===// From 9eb399f052bd11349d6366d8bb43da3691787e35 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:17:29 +0200 Subject: [PATCH 054/187] add to header --- .../Dialect/Handshake/HandshakeInterfaces.h | 4 +++ lib/Analysis/NameAnalysis.cpp | 1 + lib/Dialect/Handshake/HandshakeInterfaces.cpp | 33 ++++++++++--------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 932a226393..3277246110 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -34,6 +34,10 @@ namespace handshake { class FuncOp; +static std::string getOperandName(Operation *op, size_t oprdIdx); + +static std::string getResultName(Operation *op, size_t resIdx); + /// Provides an opaque interface for generating the port names of an operation; /// handshake operations generate names by the `handshake::NamedIOInterface`; /// other operations, such as arithmetic ones, are assigned default names. diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index f47a4f9ecc..839c2fed23 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "dynamatic/Analysis/NameAnalysis.h" +#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h" #include "dynamatic/Dialect/Handshake/HandshakeOps.h" #include "dynamatic/Support/LLVM.h" #include "mlir/Dialect/Func/IR/FuncOps.h" diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index a85e9e7988..221166263e 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -28,44 +28,47 @@ using namespace mlir; using namespace dynamatic; using namespace dynamatic::handshake; +namespace dynamatic { +namespace handshake { //===----------------------------------------------------------------------===// // Operand and Result Names //===----------------------------------------------------------------------===// - -/// Returns the name of a result which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getResultName(Operation *op, size_t resIdx) { +/// Returns the name of an operand which is either provided by the +/// handshake::NamedIOInterface interface or, failing that, is its index. +static std::string getOperandName(Operation *op, size_t oprdIdx) { if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getResultName(resIdx); + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); + return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); + return nameInterface.getOperandName(oprdIdx); }; - op->emitError("all operations must specify result names"); + op->emitError("all operations must specify operand names"); assert(0); } -/// Returns the name of an operand which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getOperandName(Operation *op, size_t oprdIdx) { +/// Returns the name of a result which is either provided by the +/// handshake::NamedIOInterface interface or, failing that, is its index. +static std::string getResultName(Operation *op, size_t resIdx) { if(auto nameInterface = dyn_cast(op)){ - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getResultName(resIdx); }; - op->emitError("all operations must specify operand names"); + op->emitError("all operations must specify result names"); assert(0); } +} +} //===----------------------------------------------------------------------===// // Operand and Result Names to Port Names From 77003abaa4a8894d6ff258a4b8d3ec3151be4130 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:22:30 +0200 Subject: [PATCH 055/187] remove compare funcs --- .../dynamatic/Dialect/Handshake/HandshakeArithOps.td | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 03ac752fc6..5cf0a6041b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -69,18 +69,6 @@ class Handshake_Arith_CompareOp traits = []> : let results = (outs ChannelType:$result); let assemblyFormat = "$predicate `,` $lhs `,` $rhs attr-dict `:` type($lhs)"; - - let extraClassDefinition = [{ - std::string $cppClass::getOperandName(unsigned idx) { - assert(idx < getNumOperands() && "index too high"); - return (idx == 0) ? "lhs" : "rhs"; - } - - std::string $cppClass::getResultName(unsigned idx) { - assert(idx < 1 && "index too high"); - return "result"; - } - }]; } class Handshake_Arith_IToICastOp traits = []> : From 79b72d9a2c16176ed9ad329cb47a124baee35c01 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:35:29 +0200 Subject: [PATCH 056/187] handshake --- .../Dialect/Handshake/HandshakeArithOps.td | 2 +- .../Dialect/Handshake/HandshakeOps.td | 68 +++++++++---------- lib/Analysis/NameAnalysis.cpp | 1 + 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 5cf0a6041b..764e2bd342 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -249,7 +249,7 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ std::string getResultName(unsigned idx) { assert(idx < 1 && "index too high"); - return idx == 0 ? "outs" : "index"; + return detail::simpleOutputPortName(idx); } }]; diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index bceaf0ba87..4f8104090b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -927,46 +927,46 @@ def LSQOp : Handshake_Op<"lsq", [ /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); - // std::string getOperandName(unsigned idx) { + std::string getOperandName(unsigned idx) { - // assert(idx < getOperation()->getNumOperands() && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); - // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - // return name.str(); + if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + return name.str(); - // // Try to get the operand name from the regular ports - // LSQPorts lsqPorts = getPorts(); - // if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) - // return name; - - // // Get the operand name from a port to a memory controller - // assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - // assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && - // "unknown LSQ/MC operand"); - // return "ldDataFromMC"; - // } + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) + return name; - // std::string getResultName(unsigned idx) { - // assert(idx < getOperation()->getNumResults() && "index too high"); - - // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - // return name.str(); + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && + "unknown LSQ/MC operand"); + return "ldDataFromMC"; + } - // // Try to get the operand name from the regular ports - // LSQPorts lsqPorts = getPorts(); - // if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) - // return name; + std::string getResultName(unsigned idx) { + assert(idx < getOperation()->getNumResults() && "index too high"); - // // Get the operand name from a port to a memory controller - // assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - // MCLoadStorePort mcPort = lsqPorts.getMCPort(); - // if (mcPort.getLoadAddrOutputIndex() == idx) - // return "ldAddrToMC"; - // if (mcPort.getStoreAddrOutputIndex() == idx) - // return "stAddrToMC"; - // assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); - // return "stDataToMC"; - // } + if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + MCLoadStorePort mcPort = lsqPorts.getMCPort(); + if (mcPort.getLoadAddrOutputIndex() == idx) + return "ldAddrToMC"; + if (mcPort.getStoreAddrOutputIndex() == idx) + return "stAddrToMC"; + assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); + return "stDataToMC"; + } }]; } diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 839c2fed23..2c0936a9f4 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -27,6 +27,7 @@ using namespace mlir; using namespace dynamatic; +using namespace handshake; /// Shortcut to get the name attribute of an operation. inline static mlir::StringAttr getNameAttr(Operation *op) { From bad71a599472b5def75c18016416d95af8aaede1 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:47:09 +0200 Subject: [PATCH 057/187] lsq naming --- .../Dialect/Handshake/HandshakeOps.td | 46 ++----------------- lib/Dialect/Handshake/HandshakeOps.cpp | 41 +++++++++++++++++ 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 4f8104090b..8f34bcf2be 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -907,7 +907,7 @@ def LSQOp : Handshake_Op<"lsq", [ /// Returns a convenient data-structure to go over the controls and memory /// accesses that are connected to the LSQ. dynamatic::LSQPorts getPorts(); - + /// Determines whether the LSQ is connected to an MC. bool isConnectedToMC() { return !isa(getInputs().front().getType()); @@ -927,47 +927,9 @@ def LSQOp : Handshake_Op<"lsq", [ /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); - std::string getOperandName(unsigned idx) { - - assert(idx < getOperation()->getNumOperands() && "index too high"); - - if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && - "unknown LSQ/MC operand"); - return "ldDataFromMC"; - } - - std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); - - if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - return name.str(); - - // Try to get the operand name from the regular ports - LSQPorts lsqPorts = getPorts(); - if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) - return name; - - // Get the operand name from a port to a memory controller - assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); - MCLoadStorePort mcPort = lsqPorts.getMCPort(); - if (mcPort.getLoadAddrOutputIndex() == idx) - return "ldAddrToMC"; - if (mcPort.getStoreAddrOutputIndex() == idx) - return "stAddrToMC"; - assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); - return "stDataToMC"; - } - }]; + std::string getOperandName(unsigned idx); + std::string getResultName(unsigned idx); + }] } //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 4b41c24580..2db9296ff1 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2060,5 +2060,46 @@ static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { return ""; } +std::string LSQOp::getOperandName(unsigned idx) { + + assert(idx < getOperation()->getNumOperands() && "index too high"); + + if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemOperandName(lsqPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && + "unknown LSQ/MC operand"); + return "ldDataFromMC"; +} + +std::string LSQOp::getResultName(unsigned idx) { + assert(idx < getOperation()->getNumResults() && "index too high"); + + if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + LSQPorts lsqPorts = getPorts(); + if (std::string name = getMemResultName(lsqPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to a memory controller + assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); + MCLoadStorePort mcPort = lsqPorts.getMCPort(); + if (mcPort.getLoadAddrOutputIndex() == idx) + return "ldAddrToMC"; + if (mcPort.getStoreAddrOutputIndex() == idx) + return "stAddrToMC"; + assert(mcPort.getStoreDataOutputIndex() == idx && "unknown LSQ/MC result"); + return "stDataToMC"; +} + #define GET_OP_CLASSES #include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" \ No newline at end of file From c1b92b38e4d42cec252dc1b4b4ee4aaf88d728bf Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:47:36 +0200 Subject: [PATCH 058/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 8f34bcf2be..0e66d56b69 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -929,7 +929,7 @@ def LSQOp : Handshake_Op<"lsq", [ std::string getOperandName(unsigned idx); std::string getResultName(unsigned idx); - }] + }]; } //===----------------------------------------------------------------------===// From e8efda1a199494617159b05cd524316245084692 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:50:05 +0200 Subject: [PATCH 059/187] mem controller op --- .../Dialect/Handshake/HandshakeOps.td | 41 +------------------ lib/Dialect/Handshake/HandshakeOps.cpp | 40 ++++++++++++++++++ 2 files changed, 42 insertions(+), 39 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 0e66d56b69..3a1196ac6c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -772,45 +772,8 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ "unsigned":$numLoads)>]; let extraClassDeclaration = [{ - std::string getOperandName(unsigned idx) { - // assert(idx < getOperation()->getNumOperands() && "index too high"); - - // if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) - // return name.str(); - - // // Try to get the operand name from the regular ports - // MCPorts mcPorts = getPorts(); - // if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) - // return name; - - // // Get the operand name from a port to an LSQ - // assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - // LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - // if (lsqPort.getLoadAddrInputIndex() == idx) - // return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); - // if (lsqPort.getStoreAddrInputIndex() == idx) - // return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); - // assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); - // return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); - // } - - // std::string getResultName(unsigned idx) { - // assert(idx < getOperation()->getNumResults() && "index too high"); - - // if (StringRef name = getIfControlRes(*this, idx); !name.empty()) - // return name.str(); - - // // Try to get the operand name from the regular ports - // MCPorts mcPorts = getPorts(); - // if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) - // return name; - - // // Get the operand name from a port to an LSQ - // assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); - // LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); - // assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); - // return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); - } + std::string getOperandName(unsigned idx); + std::string getResultName(unsigned idx); }]; let hasVerifier = 1; diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 2db9296ff1..5a41160dae 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2101,5 +2101,45 @@ std::string LSQOp::getResultName(unsigned idx) { return "stDataToMC"; } +std::string MemoryControllerOp::getOperandName(unsigned idx) { + assert(idx < getOperation()->getNumOperands() && "index too high"); + + if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + MCPorts mcPorts = getPorts(); + if (std::string name = getMemOperandName(mcPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to an LSQ + assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + if (lsqPort.getLoadAddrInputIndex() == idx) + return getArrayElemName(LD_ADDR, mcPorts.getNumPorts()); + if (lsqPort.getStoreAddrInputIndex() == idx) + return getArrayElemName(ST_ADDR, mcPorts.getNumPorts()); + assert(lsqPort.getStoreDataInputIndex() == idx && "unknown MC/LSQ operand"); + return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); +} + +std::string MemoryControllerOp::getResultName(unsigned idx) { + assert(idx < getOperation()->getNumResults() && "index too high"); + + if (StringRef name = getIfControlRes(*this, idx); !name.empty()) + return name.str(); + + // Try to get the operand name from the regular ports + MCPorts mcPorts = getPorts(); + if (std::string name = getMemResultName(mcPorts, idx); !name.empty()) + return name; + + // Get the operand name from a port to an LSQ + assert(mcPorts.connectsToLSQ() && "expected MC to connect to LSQ"); + LSQLoadStorePort lsqPort = mcPorts.getLSQPort(); + assert(lsqPort.getLoadDataOutputIndex() == idx && "unknown MC/LSQ result"); + return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); +} + #define GET_OP_CLASSES #include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" \ No newline at end of file From eebc5c97af116c109da94d085cf0116e4aa320ac Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:51:12 +0200 Subject: [PATCH 060/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 3a1196ac6c..bdfb4696cc 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -771,10 +771,6 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ "ArrayRef":$blocks, "unsigned":$numLoads)>]; - let extraClassDeclaration = [{ - std::string getOperandName(unsigned idx); - std::string getResultName(unsigned idx); - }]; let hasVerifier = 1; // Dispatch SimpleControl signals to custom print and parse @@ -795,6 +791,9 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ /// Returns a convenient data-structure to go over the controls and memory /// accesses that are connected to the memory controller. dynamatic::MCPorts getPorts(); + + std::string getOperandName(unsigned idx); + std::string getResultName(unsigned idx); }]; } From 0537c821cf69624406354ce594df5ffb14f3e44c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:53:37 +0200 Subject: [PATCH 061/187] endop --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 11 ----------- lib/Dialect/Handshake/HandshakeOps.cpp | 11 +++++++++++ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index bdfb4696cc..0c42ddc64c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1048,17 +1048,6 @@ def EndOp : Handshake_Op<"end", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx); - // { - // assert(idx < getOperation()->getNumOperands() && "index too high"); - // handshake::FuncOp funcOp = (*this)->getParentOfType(); - // assert(funcOp && "end must be child of handshake function"); - - // unsigned numResults = funcOp.getFunctionType().getNumResults(); - // if (idx < numResults) - // return "ins_" + std::to_string(idx); - // return "memDone_" + std::to_string(idx - numResults); - // } - std::string getResultName(unsigned idx) { assert(false && "index too high"); } diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 5a41160dae..eb2e580f8b 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1548,6 +1548,17 @@ LogicalResult EndOp::verify() { return success(); } +std::string EndOp::getOperandName(unsigned idx){ + assert(idx < getOperation()->getNumOperands() && "index too high"); + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + + unsigned numResults = funcOp.getFunctionType().getNumResults(); + if (idx < numResults) + return "ins_" + std::to_string(idx); + return "memDone_" + std::to_string(idx - numResults); +} + //===----------------------------------------------------------------------===// // BundleOp //===----------------------------------------------------------------------===// From 52a64a45cdc368b5953325b9ece33cbf2f388aaa Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 09:57:46 +0200 Subject: [PATCH 062/187] non static --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 4 ++-- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 3277246110..a7148bea58 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -34,9 +34,9 @@ namespace handshake { class FuncOp; -static std::string getOperandName(Operation *op, size_t oprdIdx); +std::string getOperandName(Operation *op, size_t oprdIdx); -static std::string getResultName(Operation *op, size_t resIdx); +std::string getResultName(Operation *op, size_t resIdx); /// Provides an opaque interface for generating the port names of an operation; /// handshake operations generate names by the `handshake::NamedIOInterface`; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 221166263e..9c2a181a35 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -37,7 +37,7 @@ namespace handshake { /// Returns the name of an operand which is either provided by the /// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getOperandName(Operation *op, size_t oprdIdx) { +std::string getOperandName(Operation *op, size_t oprdIdx) { if(auto nameInterface = dyn_cast(op)){ return nameInterface.getOperandName(oprdIdx); @@ -53,7 +53,7 @@ static std::string getOperandName(Operation *op, size_t oprdIdx) { /// Returns the name of a result which is either provided by the /// handshake::NamedIOInterface interface or, failing that, is its index. -static std::string getResultName(Operation *op, size_t resIdx) { +std::string getResultName(Operation *op, size_t resIdx) { if(auto nameInterface = dyn_cast(op)){ return nameInterface.getResultName(resIdx); From eaf7892b9b50111f7242c72978ce38dec778867d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:09:59 +0200 Subject: [PATCH 063/187] add simple naming? --- .../Dialect/Handshake/HandshakeOps.td | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 0c42ddc64c..eeec186b6d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -42,7 +42,8 @@ def FuncOp : Op { let summary = "Handshake dialect function."; let description = [{ @@ -136,7 +137,8 @@ def FuncOp : Op + DeclareOpInterfaceMethods, + SimpleNamedIOInterface ]> { let summary = "module instantiate operation"; let description = [{ @@ -214,7 +216,9 @@ def InstanceOp : Handshake_Op<"instance", [ } def BufferOp : Handshake_Op<"buffer", [ - HasClock, SameOperandsAndResultType + HasClock, + SameOperandsAndResultType, + SimpleNamedIOInterface ]> { let summary = "buffer operation"; let description = [{ @@ -285,7 +289,9 @@ def BufferOp : Handshake_Op<"buffer", [ } def InitOp : Handshake_Op<"init", [ - HasClock, SameOperandsAndResultType + HasClock, + SameOperandsAndResultType, + SimpleNamedIOInterface ]> { let summary = "init operation"; let description = [{ @@ -307,7 +313,9 @@ def InitOp : Handshake_Op<"init", [ } def NDWireOp : Handshake_Op<"ndwire", [ - HasClock, SameOperandsAndResultType + HasClock, + SameOperandsAndResultType, + SimpleNamedIOInterface ]> { let summary = "non-deterministic wire operation"; let description = [{ @@ -383,7 +391,8 @@ def MergeOp : Handshake_Op<"merge", [ // require that the data types match. SameOperandsAndResultType, VariadicHasElement<"dataOperands">, - DeclareOpInterfaceMethods + DeclareOpInterfaceMethods, + SimpleNamedIOInterface ]> { let summary = "merge operation"; let description = [{ From 3af244719e557adaca2fe96286784ecc6514b274 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:22:40 +0200 Subject: [PATCH 064/187] 2d --- .../Dialect/Handshake/HandshakeInterfaces.td | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index b63b8a0700..a726e512b3 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -174,6 +174,13 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { // Simple input name assert(idx < concreteOp->getNumOperands() && "index too high"); + + // TODO: Remove 2D output packing + // but for now this is needed + if(concreteOp->getNumOperands() == 1){ + return "ins"; + } + return simpleInputPortName(idx); }]>, InterfaceMethod< @@ -185,6 +192,12 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { // Generic output name assert(idx < concreteOp->getNumResults() && "index too high"); + + // TODO: Remove 2D output packing + // but for now this is needed + if(concreteOp->getNumResults() == 1){ + return "outs"; + } return simpleOutputPortName(idx); }]> ]; From 5102c61e8603ef9287c273999f4461d51291eeb6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:23:57 +0200 Subject: [PATCH 065/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index a726e512b3..c7333532bc 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -175,7 +175,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { // Simple input name assert(idx < concreteOp->getNumOperands() && "index too high"); - // TODO: Remove 2D output packing + // TODO: Remove 2D I/O packing // but for now this is needed if(concreteOp->getNumOperands() == 1){ return "ins"; @@ -193,7 +193,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { // Generic output name assert(idx < concreteOp->getNumResults() && "index too high"); - // TODO: Remove 2D output packing + // TODO: Remove 2D I/O packing // but for now this is needed if(concreteOp->getNumResults() == 1){ return "outs"; From af393b3e7684e32e5f5038673e6d0d4db28963cd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:31:19 +0200 Subject: [PATCH 066/187] move into function --- .../Dialect/Handshake/HandshakeArithOps.td | 3 +-- .../Dialect/Handshake/HandshakeInterfaces.h | 20 ++++++++++++++++-- .../Dialect/Handshake/HandshakeInterfaces.td | 21 ++----------------- .../Dialect/Handshake/HandshakeOps.td | 9 +++----- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 764e2bd342..0ffbdd82c4 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -248,8 +248,7 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ } std::string getResultName(unsigned idx) { - assert(idx < 1 && "index too high"); - return detail::simpleOutputPortName(idx); + return detail::simpleResultName(idx, 1); } }]; diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index a7148bea58..f2235b7158 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -67,11 +67,27 @@ class ControlType; namespace detail { -inline std::string simpleInputPortName(unsigned idx) { +inline std::string simpleOperandName(unsigned idx, unsigned numOperands) { + assert(idx < numOperands && "index too high"); + + // TODO: Remove 2D I/O packing + // but for now this is needed + if(numOperands == 1){ + return "ins"; + } + return "ins_" + std::to_string(idx); } -inline std::string simpleOutputPortName(unsigned idx) { +inline std::string simpleResultsName(unsigned idx, unsigned numResults) { + assert(idx < numResults && "index too high"); + + // TODO: Remove 2D I/O packing + // but for now this is needed + if(numResults == 1){ + return "outs"; + } + return "outs_" + std::to_string(idx); } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index c7333532bc..2608a6795a 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -172,16 +172,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - // Simple input name - assert(idx < concreteOp->getNumOperands() && "index too high"); - - // TODO: Remove 2D I/O packing - // but for now this is needed - if(concreteOp->getNumOperands() == 1){ - return "ins"; - } - - return simpleInputPortName(idx); + return simpleOperandName(idx, concreteOp->getNumOperands()); }]>, InterfaceMethod< "Returns the name of a specific result.", @@ -190,15 +181,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - // Generic output name - assert(idx < concreteOp->getNumResults() && "index too high"); - - // TODO: Remove 2D I/O packing - // but for now this is needed - if(concreteOp->getNumResults() == 1){ - return "outs"; - } - return simpleOutputPortName(idx); + return simpleResultName(idx, concreteOp->getNumResults); }]> ]; } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index eeec186b6d..d916db363b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -451,13 +451,11 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); - return idx == 0 ? "index" : detail::simpleInputPortName(idx - 1); + return idx == 0 ? "index" : detail::simpleOperandName(idx - 1, getOperation()->getNumOperands() - 1); } std::string getResultName(unsigned idx) { - assert(idx < 1 && "index too high"); - return detail::simpleOutputPortName(idx); + return detail::simpleResultName(idx, 1); } }]; @@ -508,8 +506,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); - return detail::simpleInputPortName(idx); + return detail::simpleOperandName(idx, getOperation()->getNumOperands()); } std::string getResultName(unsigned idx) { From 6a40f7f112d3ea413c4248fbb8f0195baa3c6139 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:31:53 +0200 Subject: [PATCH 067/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index f2235b7158..da92db512e 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -79,7 +79,7 @@ inline std::string simpleOperandName(unsigned idx, unsigned numOperands) { return "ins_" + std::to_string(idx); } -inline std::string simpleResultsName(unsigned idx, unsigned numResults) { +inline std::string simpleResultName(unsigned idx, unsigned numResults) { assert(idx < numResults && "index too high"); // TODO: Remove 2D I/O packing From aba1aec3dcd61957464444af6e15ad15186e1194 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:32:42 +0200 Subject: [PATCH 068/187] endop --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 9c2a181a35..ddd58eb50f 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -100,7 +100,7 @@ PortNamer::PortNamer(Operation *op) { assert(funcOp && "end must be child of handshake function"); size_t numResults = funcOp.getFunctionType().getNumResults(); for (size_t idx = 0; idx < numResults; ++idx) - outputs.push_back(detail::simpleOutputPortName(idx)); + outputs.push_back(detail::simpleResultName(idx, numResults)); } } } From a697a2d54a63e2f6be979d1442a1f0683ba5eb02 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:33:40 +0200 Subject: [PATCH 069/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 2 +- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 2608a6795a..79d68b91be 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -181,7 +181,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - return simpleResultName(idx, concreteOp->getNumResults); + return simpleResultName(idx, concreteOp->getNumResults()); }]> ]; } diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index ddd58eb50f..cf5bdae347 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -85,7 +85,7 @@ PortNamer::PortNamer(Operation *op) { llvm::transform(funcOp.getResNames(), std::back_inserter(outputs), [](Attribute res) { return cast(res).str(); }); } else { - // all other operations must direclty provide names for their + // all other operations must directly provide names for their // inputs and outputs for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) From 9e3cc5f899d415b2bb326639b641cc34ce7a72c3 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:37:11 +0200 Subject: [PATCH 070/187] fix ext --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 0ffbdd82c4..3b8109cfa6 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -285,14 +285,14 @@ def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ } def Handshake_ExtSIOp : Handshake_Arith_IToICastOp<"extsi", [ - ArithNamedIOInterface + SimpleNamedIOInterface ]> { let summary = "Integer unsigned width extension."; let hasCanonicalizer = 1; } def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui", [ - ArithNamedIOInterface + SimpleNamedIOInterface ]> { let summary = "Integer signed width extension."; } From 28a5a7d59cdae6ae59973ce7746a637a79218d4f Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 10:51:12 +0200 Subject: [PATCH 071/187] format --- .../Dialect/Handshake/HandshakeInterfaces.h | 4 +-- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 28 +++++++++++-------- lib/Dialect/Handshake/HandshakeOps.cpp | 9 +++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index da92db512e..8095055026 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -72,7 +72,7 @@ inline std::string simpleOperandName(unsigned idx, unsigned numOperands) { // TODO: Remove 2D I/O packing // but for now this is needed - if(numOperands == 1){ + if (numOperands == 1){ return "ins"; } @@ -84,7 +84,7 @@ inline std::string simpleResultName(unsigned idx, unsigned numResults) { // TODO: Remove 2D I/O packing // but for now this is needed - if(numResults == 1){ + if (numResults == 1){ return "outs"; } diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index cf5bdae347..abf9e692f5 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -39,15 +39,17 @@ namespace handshake { /// handshake::NamedIOInterface interface or, failing that, is its index. std::string getOperandName(Operation *op, size_t oprdIdx) { - if(auto nameInterface = dyn_cast(op)){ + if (auto nameInterface = dyn_cast(op)){ return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = dyn_cast(op)) { + } else if (auto nameInterface = + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = dyn_cast(op)) { + } else if (auto nameInterface = + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); - }; + } - op->emitError("all operations must specify operand names"); + op->emitError() << "must specify operation names, op: " << *op; assert(0); } @@ -55,20 +57,23 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { /// handshake::NamedIOInterface interface or, failing that, is its index. std::string getResultName(Operation *op, size_t resIdx) { - if(auto nameInterface = dyn_cast(op)){ + if (auto nameInterface = dyn_cast(op)){ return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { + } else if (auto nameInterface = + dyn_cast(op)) { return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { + } else if (auto nameInterface = + dyn_cast(op)) { return nameInterface.getResultName(resIdx); - }; + } op->emitError("all operations must specify result names"); assert(0); } -} -} +} // namespace handshake +} // namespace dynamatic + //===----------------------------------------------------------------------===// // Operand and Result Names to Port Names @@ -137,5 +142,4 @@ TypedValue LSQOp::getCtrlEnd() { return cast>(getOperands().back()); } - #include "dynamatic/Dialect/Handshake/HandshakeInterfaces.cpp.inc" diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index eb2e580f8b..b0878044f5 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1548,7 +1548,7 @@ LogicalResult EndOp::verify() { return success(); } -std::string EndOp::getOperandName(unsigned idx){ +std::string EndOp::getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); handshake::FuncOp funcOp = (*this)->getParentOfType(); assert(funcOp && "end must be child of handshake function"); @@ -2005,7 +2005,8 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { return name.str() + "_" + std::to_string(idx); } -inline static StringRef getIfControlOprd(MemoryOpInterface memOp, unsigned idx) { +inline static StringRef getIfControlOprd(MemoryOpInterface memOp, + unsigned idx) { if (!memOp.isMasterInterface()) return ""; switch (idx) { @@ -2026,7 +2027,7 @@ static StringRef getIfControlRes(MemoryOpInterface memOp, unsigned idx) { /// Common operand naming logic for memory controllers and LSQs. inline static std::string getMemOperandName(const FuncMemoryPorts &ports, - unsigned idx) { + unsigned idx) { // Iterate through all memory ports to find out the type of the operand unsigned ctrlIdx = 0, loadIdx = 0, storeIdx = 0; for (const GroupMemoryPorts &blockPorts : ports.groups) { @@ -2086,7 +2087,7 @@ std::string LSQOp::getOperandName(unsigned idx) { // Get the operand name from a port to a memory controller assert(lsqPorts.connectsToMC() && "expected LSQ to connect to MC"); assert(lsqPorts.getMCPort().getLoadDataInputIndex() == idx && - "unknown LSQ/MC operand"); + "unknown LSQ/MC operand"); return "ldDataFromMC"; } From cfd61fc9a03670be61211bc75f544290eb3fd051 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 11:35:14 +0200 Subject: [PATCH 072/187] format --- .../Dialect/Handshake/HandshakeInterfaces.h | 4 ++-- .../Dialect/Handshake/HandshakeOps.td | 9 +++++---- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 19 +++++++++---------- lib/Dialect/Handshake/HandshakeOps.cpp | 3 +-- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 8095055026..702df97d26 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -72,7 +72,7 @@ inline std::string simpleOperandName(unsigned idx, unsigned numOperands) { // TODO: Remove 2D I/O packing // but for now this is needed - if (numOperands == 1){ + if (numOperands == 1) { return "ins"; } @@ -84,7 +84,7 @@ inline std::string simpleResultName(unsigned idx, unsigned numResults) { // TODO: Remove 2D I/O packing // but for now this is needed - if (numResults == 1){ + if (numResults == 1) { return "outs"; } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d916db363b..8254495389 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -582,7 +582,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ enum { trueIndex = 0, falseIndex = 1 }; std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + assert(idx < 2 && "index too high"); return idx == 0 ? "condition" : "data"; } @@ -910,7 +910,6 @@ class Handshake_MemPortOp< MemPortOpInterface, AllDataTypesMatch<["address", "addressResult"]>, AllDataTypesMatch<["data", "dataResult"]>, - CustomNamedIOInterface, IsIntChannel<"address">, IsIntChannel<"addressResult"> ] @@ -978,12 +977,12 @@ def LoadOp : Handshake_MemPortOp<"load", [ let extraClassDeclaration= [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + assert(idx < 2 && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + assert(idx < 2 && "index too high"); return (idx == 0) ? "addrOut" : "dataOut"; } }]; @@ -1020,10 +1019,12 @@ def StoreOp : Handshake_MemPortOp<"store", [ let extraClassDeclaration = [{ std::string getOperandName(unsigned int idx) { + assert(idx < 2 && "index too high"); return (idx == 0) ? "addrIn" : "dataIn"; } std::string getResultName(unsigned int idx) { + assert(idx < 2 && "index too high"); return (idx == 0) ? "addrOut" : "dataToMem"; } }]; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index abf9e692f5..4ff3f514c9 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -39,13 +39,13 @@ namespace handshake { /// handshake::NamedIOInterface interface or, failing that, is its index. std::string getOperandName(Operation *op, size_t oprdIdx) { - if (auto nameInterface = dyn_cast(op)){ + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } @@ -57,13 +57,13 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { /// handshake::NamedIOInterface interface or, failing that, is its index. std::string getResultName(Operation *op, size_t resIdx) { - if (auto nameInterface = dyn_cast(op)){ + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getResultName(resIdx); } @@ -74,7 +74,6 @@ std::string getResultName(Operation *op, size_t resIdx) { } // namespace handshake } // namespace dynamatic - //===----------------------------------------------------------------------===// // Operand and Result Names to Port Names //===----------------------------------------------------------------------===// @@ -84,7 +83,7 @@ PortNamer::PortNamer(Operation *op) { // special case: input and output port names // are actually stored in dictionary attributes - if (auto funcOp = dyn_cast(op)){ + if (auto funcOp = dyn_cast(op)) { llvm::transform(funcOp.getArgNames(), std::back_inserter(inputs), [](Attribute arg) { return cast(arg).str(); }); llvm::transform(funcOp.getResNames(), std::back_inserter(outputs), @@ -98,8 +97,8 @@ PortNamer::PortNamer(Operation *op) { for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) outputs.push_back(getResultName(op, idx)); - // The Handshake terminator forwards its non-memory inputs to its outputs, so - // it needs port names for them + // The Handshake terminator forwards its non-memory inputs to its outputs, + // so it needs port names for them if (handshake::EndOp endOp = dyn_cast(op)) { handshake::FuncOp funcOp = endOp->getParentOfType(); assert(funcOp && "end must be child of handshake function"); diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index b0878044f5..950323d75b 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1991,7 +1991,6 @@ LogicalResult TruncFOp::verify() { return verifyTruncOp(*this); } //===----------------------------------------------------------------------===// LogicalResult ExtFOp::verify() { return verifyExtOp(*this); } - //===----------------------------------------------------------------------===// // Memory Controller GetOperandName and GetResultName Utilities //===----------------------------------------------------------------------===// @@ -2006,7 +2005,7 @@ static inline std::string getArrayElemName(const Twine &name, unsigned idx) { } inline static StringRef getIfControlOprd(MemoryOpInterface memOp, - unsigned idx) { + unsigned idx) { if (!memOp.isMasterInterface()) return ""; switch (idx) { From b362a8f576e7e540f31bf41eeb1ec85636ec641d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:51:29 +0200 Subject: [PATCH 073/187] try new interfaces --- .../Dialect/Handshake/HandshakeInterfaces.td | 80 +++++++++++++++++ .../Dialect/Handshake/HandshakeOps.td | 27 ++++-- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 88 +++++++++++++------ lib/Dialect/Handshake/HandshakeOps.cpp | 41 +++++++-- 4 files changed, 197 insertions(+), 39 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 79d68b91be..4d8d26ec3d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -211,6 +211,86 @@ def ArithNamedIOInterface : OpInterface<"ArithNamedIOInterface"> { ]; } +def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"The operands of this operation correspond directly to its input RTL ports."}]; + let methods = [ + InterfaceMethod< + "Returns the number of RTL ports.", + "unsigned", "getNumInputPorts", (ins), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return concreteOp->getNumOperands(); + }]>, + InterfaceMethod< + "Returns the name of a specific input port.", + "std::string", "getInputPortName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return getOperandName(idx, concreteOp->->getNumOperands()); + }]> + ]; +} + +def CustomRTLInputPortsInterface : OpInterface<"CustomRTLInputPortsInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"The input RTL ports of this operation do not correspond to its operands"}]; + + let methods = [ + InterfaceMethod< + "Returns the number of RTL ports.", + "unsigned", "getNumInputPorts", (ins)>, + InterfaceMethod< + "Returns the name of a specific input port.", + "std::string", "getInputPortName", (ins "unsigned" : $idx) + > + ]; +} + +def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"The results of this operation correspond directly to its output RTL ports."}]; + let methods = [ + InterfaceMethod< + "Returns the number of RTL ports.", + "unsigned", "getNumOutputPorts", (ins), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return concreteOp->getNumResults(); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getOutputPortName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return getResultName(idx, concreteOp->->getNumResults()); + }]> + ]; +} + +def CustomRTLOutputPortsInterface : OpInterface<"CustomRTLOutputPortsInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"The output RTL ports of this operation do not correspond to its results"}]; + + let methods = [ + InterfaceMethod< + "Returns the number of output RTL ports.", + "unsigned", "getNumOutputPorts", (ins)>, + InterfaceMethod< + "Returns the name of a specific output port.", + "std::string", "getOutputPortName", (ins "unsigned" : $idx) + > + ]; +} + def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 8254495389..9662527a52 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -30,7 +30,10 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, - DeclareOpInterfaceMethods]> { + DeclareOpInterfaceMethods, + InputRTLPortsAreOperandsInterface, + OutputRTLPortsAreResultsInterface + ]> { } // This is almost exactly like a standard FuncOp, except that it has some @@ -43,7 +46,9 @@ def FuncOp : Op { let summary = "Handshake dialect function."; let description = [{ @@ -1034,9 +1039,15 @@ def StoreOp : Handshake_MemPortOp<"store", [ // Terminator //===----------------------------------------------------------------------===// -def EndOp : Handshake_Op<"end", [ +// Not a handshake op, as its RTL ports do not correspond to +// its operands and results +def EndOp : Op, + DeclareOpInterfaceMethods, CustomNamedIOInterface, - Terminator + InputRTLPortsAreOperandsInterface, + CustomRTLOutputPortsInterface ]> { let summary = "function endpoint (dynamatic)"; let description = [{ @@ -1053,11 +1064,17 @@ def EndOp : Handshake_Op<"end", [ let arguments = (ins Variadic:$inputs); let extraClassDeclaration = [{ - std::string getOperandName(unsigned idx); + std::string getOperandName(unsigned idx){ + return detail::simpleOperandName(idx, getOperation()->getNumOperands()); + } std::string getResultName(unsigned idx) { assert(false && "index too high"); } + + unsigned getNumOutputPorts(); + + std::string getOutputPortName(unsigned idx); }]; let assemblyFormat = [{ diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 4ff3f514c9..678dee9c71 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -49,7 +49,7 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { return nameInterface.getOperandName(oprdIdx); } - op->emitError() << "must specify operation names, op: " << *op; + op->emitError() << "must specify operand names, op: " << *op; assert(0); } @@ -67,10 +67,63 @@ std::string getResultName(Operation *op, size_t resIdx) { return nameInterface.getResultName(resIdx); } - op->emitError("all operations must specify result names"); + op->emitError() << "must specify result names, op: " << *op; assert(0); } +unsigned getNumInputPorts(Operation *op) { + if(auto operandPortsInterface = + dyn_cast(op)){ + return operandPortsInterface.getNumInputPorts(); + } else if (auto customPortsInterface = + dyn_cast(op)){ + return customPortsInterface.getNumInputPorts(); + } + + op->emitError("All operations must specify input ports"); + assert(0); +} + +std::string getInputPortName(Operation *op, size_t portIdx) { + if(auto operandPortsInterface = + dyn_cast(op)){ + return operandPortsInterface.getInputPortName(portIdx); + } else if (auto customPortsInterface = + dyn_cast(op)){ + return customPortsInterface.getInputPortName(portIdx); + } + + op->emitError("All operations must specify input ports"); + assert(0); +} + +unsigned getNumOutputPorts(Operation *op) { + if(auto resultsPortsInterface = + dyn_cast(op)){ + return resultsPortsInterface.getNumOutputPorts(); + } else if (auto customPortsInterface = + dyn_cast(op)){ + return customPortsInterface.getNumInputPorts(); + } + + op->emitError("All operations must specify output ports"); + assert(0); +} + +std::string getOutputPortName(Operation *op, size_t portIdx) { + if(auto resultsPortsInterface = + dyn_cast(op)){ + return resultsPortsInterface.getOutputPortName(portIdx); + } else if (auto customPortsInterface = + dyn_cast(op)){ + return customPortsInterface.getOutputPortName(portIdx); + } + + op->emitError("All operations must specify output ports"); + assert(0); +} + + } // namespace handshake } // namespace dynamatic @@ -81,31 +134,12 @@ std::string getResultName(Operation *op, size_t resIdx) { PortNamer::PortNamer(Operation *op) { assert(op && "cannot generate port names for null operation"); - // special case: input and output port names - // are actually stored in dictionary attributes - if (auto funcOp = dyn_cast(op)) { - llvm::transform(funcOp.getArgNames(), std::back_inserter(inputs), - [](Attribute arg) { return cast(arg).str(); }); - llvm::transform(funcOp.getResNames(), std::back_inserter(outputs), - [](Attribute res) { return cast(res).str(); }); - } else { - // all other operations must directly provide names for their - // inputs and outputs - - for (size_t idx = 0, e = op->getNumOperands(); idx < e; ++idx) - inputs.push_back(getOperandName(op, idx)); - for (size_t idx = 0, e = op->getNumResults(); idx < e; ++idx) - outputs.push_back(getResultName(op, idx)); - - // The Handshake terminator forwards its non-memory inputs to its outputs, - // so it needs port names for them - if (handshake::EndOp endOp = dyn_cast(op)) { - handshake::FuncOp funcOp = endOp->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - size_t numResults = funcOp.getFunctionType().getNumResults(); - for (size_t idx = 0; idx < numResults; ++idx) - outputs.push_back(detail::simpleResultName(idx, numResults)); - } + for (size_t idx = 0, e = getNumInputPorts(op); idx < e; ++idx){ + inputs.push_back(getInputPortName(op, idx)); + } + + for (size_t idx = 0, e = getNumOutputPorts(op); idx < e; ++idx){ + outputs.push_back(getOutputPortName(op, idx)); } } diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 950323d75b..20e277e2bc 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -545,6 +545,31 @@ void FuncOp::print(OpAsmPrinter &p) { getArgAttrsAttrName(), getResAttrsAttrName()); } +unsigned FuncOp::getNumInputPorts(){ + if (auto names = getArgNames()) { + return names.size(); + } + return 0 +} + +std::string FuncOp::getInputPortName(unsigned idx){ + assert(idx < getNumInputPorts() && "index too high"); + return getArgName(idx) +} + +unsigned FuncOp::getNumOutputPorts(){ + if (auto names = getResNames()) { + return names.size(); + } + return 0 +} + +std::string FuncOp::getOutputPortName(unsigned idx){ + assert(idx < getNumOutputPorts() && "index too high"); + return getResName(idx) +} + + bool ConditionalBranchOp::isControl() { return isControlCheckTypeAndOperand(getDataOperand().getType(), getDataOperand()); @@ -1548,17 +1573,19 @@ LogicalResult EndOp::verify() { return success(); } -std::string EndOp::getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); +unsigned EndOp::getNumOutputPorts(){ handshake::FuncOp funcOp = (*this)->getParentOfType(); assert(funcOp && "end must be child of handshake function"); + return funcOp.getFunctionType().getNumResults(); +} - unsigned numResults = funcOp.getFunctionType().getNumResults(); - if (idx < numResults) - return "ins_" + std::to_string(idx); - return "memDone_" + std::to_string(idx - numResults); +std::string EndOp::getOutputPortName(unsigned idx){ + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + return funcOp.getOutputPortName(idx); } + //===----------------------------------------------------------------------===// // BundleOp //===----------------------------------------------------------------------===// @@ -2153,4 +2180,4 @@ std::string MemoryControllerOp::getResultName(unsigned idx) { } #define GET_OP_CLASSES -#include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" \ No newline at end of file +#include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" From 879f4f6d9e5e644c29e1b7fe6575ff46f94b542a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:52:13 +0200 Subject: [PATCH 074/187] end simple --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 9662527a52..6a067b6527 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1045,7 +1045,7 @@ def EndOp : Op, DeclareOpInterfaceMethods, - CustomNamedIOInterface, + SimpleNamedIOInterface, InputRTLPortsAreOperandsInterface, CustomRTLOutputPortsInterface ]> { @@ -1064,14 +1064,6 @@ def EndOp : Op:$inputs); let extraClassDeclaration = [{ - std::string getOperandName(unsigned idx){ - return detail::simpleOperandName(idx, getOperation()->getNumOperands()); - } - - std::string getResultName(unsigned idx) { - assert(false && "index too high"); - } - unsigned getNumOutputPorts(); std::string getOutputPortName(unsigned idx); From 1b5c9061d2d12fea98f986e086c52ba3c388576c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:53:36 +0200 Subject: [PATCH 075/187] typo --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 4d8d26ec3d..90e277e7d5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -230,7 +230,7 @@ def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getOperandName(idx, concreteOp->->getNumOperands()); + return getOperandName(idx, concreteOp->getNumOperands()); }]> ]; } @@ -270,7 +270,7 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getResultName(idx, concreteOp->->getNumResults()); + return getResultName(idx, concreteOp->getNumResults()); }]> ]; } From 53c581bf77b4d74360cda598d9f39a817b4c851c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:54:32 +0200 Subject: [PATCH 076/187] semicolon --- lib/Dialect/Handshake/HandshakeOps.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 20e277e2bc..cdb1372b84 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -554,7 +554,7 @@ unsigned FuncOp::getNumInputPorts(){ std::string FuncOp::getInputPortName(unsigned idx){ assert(idx < getNumInputPorts() && "index too high"); - return getArgName(idx) + return getArgName(idx); } unsigned FuncOp::getNumOutputPorts(){ @@ -566,7 +566,7 @@ unsigned FuncOp::getNumOutputPorts(){ std::string FuncOp::getOutputPortName(unsigned idx){ assert(idx < getNumOutputPorts() && "index too high"); - return getResName(idx) + return getResName(idx); } From 3c23a89fd770a9d2e80bebc60244c13735d05b11 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:56:00 +0200 Subject: [PATCH 077/187] typo --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 678dee9c71..63b82d065d 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -102,7 +102,7 @@ unsigned getNumOutputPorts(Operation *op) { dyn_cast(op)){ return resultsPortsInterface.getNumOutputPorts(); } else if (auto customPortsInterface = - dyn_cast(op)){ + dyn_cast(op)){ return customPortsInterface.getNumInputPorts(); } From 651c465127fc6b363055929dbcac343eac00d38c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:56:34 +0200 Subject: [PATCH 078/187] typo --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 63b82d065d..f657b2c9e4 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -103,7 +103,7 @@ unsigned getNumOutputPorts(Operation *op) { return resultsPortsInterface.getNumOutputPorts(); } else if (auto customPortsInterface = dyn_cast(op)){ - return customPortsInterface.getNumInputPorts(); + return customPortsInterface.getNumOutputPorts(); } op->emitError("All operations must specify output ports"); From 25af5d53c59b3b612412648a8d3110a6b2db84f5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 13:59:13 +0200 Subject: [PATCH 079/187] func op header --- .../Dialect/Handshake/HandshakeOps.td | 33 +++++++++++++++++++ lib/Dialect/Handshake/HandshakeOps.cpp | 24 -------------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 6a067b6527..db889c3ef1 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -132,6 +132,39 @@ def FuncOp : Op Date: Sat, 23 Aug 2025 13:59:50 +0200 Subject: [PATCH 080/187] semicolon --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index db889c3ef1..bcb5cc27ab 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -141,7 +141,7 @@ def FuncOp : Op Date: Sat, 23 Aug 2025 14:01:14 +0200 Subject: [PATCH 081/187] str copy? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index bcb5cc27ab..39024275db 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -146,7 +146,7 @@ def FuncOp : Op Date: Sat, 23 Aug 2025 14:01:46 +0200 Subject: [PATCH 082/187] namespace --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 39024275db..9b43077b57 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -137,14 +137,14 @@ def FuncOp : Op Date: Sat, 23 Aug 2025 14:04:07 +0200 Subject: [PATCH 083/187] fix call --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 90e277e7d5..97daba48f6 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -230,7 +230,7 @@ def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getOperandName(idx, concreteOp->getNumOperands()); + return getOperandName(op, idx); }]> ]; } @@ -270,7 +270,7 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getResultName(idx, concreteOp->getNumResults()); + return getResultName(op, idx); }]> ]; } From 324afc0515efabeb6762c3842df708a5843ad6c8 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Sat, 23 Aug 2025 14:04:52 +0200 Subject: [PATCH 084/187] concrete op --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 97daba48f6..94041a3ad9 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -230,7 +230,7 @@ def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getOperandName(op, idx); + return getOperandName(concreteOp, idx); }]> ]; } @@ -270,7 +270,7 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt "", [{ ConcreteOp concreteOp = mlir::cast($_op); - return getResultName(op, idx); + return getResultName(concreteOp, idx); }]> ]; } From fcde84a7ab10958359525fb872bedd9f8e98cf72 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 13:44:23 +0200 Subject: [PATCH 085/187] commenting, check funcop? --- .../Dialect/Handshake/HandshakeArithOps.td | 40 +++++----- .../Dialect/Handshake/HandshakeInterfaces.td | 74 ++++++++++++++----- .../Dialect/Handshake/HandshakeOps.td | 17 ++++- 3 files changed, 92 insertions(+), 39 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 846c87c857..21c0f46c9b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -132,21 +132,21 @@ def Handshake_AddFOp : Handshake_Arith_FloatBinaryOp<"addf", [ Commutative, FPUImplInterface, InternalDelayInterface, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point addition."; } def Handshake_AddIOp : Handshake_Arith_IntBinaryOp<"addi", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Integer addition."; } def Handshake_AndIOp : Handshake_Arith_IntBinaryOp<"andi", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Bitwise conjunction."; } @@ -180,7 +180,7 @@ def Handshake_CmpFOp : Handshake_Arith_CompareOp<"cmpf", [ IsFloatChannel<"rhs">, FPUImplInterface, InternalDelayInterface, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point comparison."; @@ -209,7 +209,7 @@ def Handshake_CmpIPredicateAttr : I64EnumAttr< def Handshake_CmpIOp : Handshake_Arith_CompareOp<"cmpi", [ IsIntChannel<"lhs">, IsIntChannel<"rhs">, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Integer comparison."; @@ -261,25 +261,25 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ def Handshake_DivFOp : Handshake_Arith_FloatBinaryOp<"divf", [ FPUImplInterface, InternalDelayInterface, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point division."; } def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Signed integer remainder."; } def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Signed integer division."; } def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Unsigned integer division."; } @@ -311,14 +311,14 @@ def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui", [ def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point maximum."; } def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point minimum."; } @@ -327,14 +327,14 @@ def Handshake_MulFOp : Handshake_Arith_FloatBinaryOp<"mulf", [ Commutative, FPUImplInterface, InternalDelayInterface, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point multiplication."; } def Handshake_MulIOp : Handshake_Arith_IntBinaryOp<"muli", [ Commutative, - ArithNamedIOInterface]> { + BinaryArithNamedIOInterface]> { let summary = "Integer multiplication."; } @@ -346,7 +346,7 @@ def Handshake_NegFOp : Handshake_Arith_FloatUnaryOp<"negf", [ def Handshake_OrIOp : Handshake_Arith_IntBinaryOp<"ori", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Bitwise union."; } @@ -384,19 +384,19 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ } def Handshake_ShLIOp : Handshake_Arith_IntBinaryOp<"shli", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Logical left shift."; } def Handshake_ShRSIOp : Handshake_Arith_IntBinaryOp<"shrsi", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Arithmetic right shift."; } def Handshake_ShRUIOp : Handshake_Arith_IntBinaryOp<"shrui", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Logical right shift."; } @@ -404,13 +404,13 @@ def Handshake_ShRUIOp : Handshake_Arith_IntBinaryOp<"shrui", [ def Handshake_SubFOp : Handshake_Arith_FloatBinaryOp<"subf", [ FPUImplInterface, InternalDelayInterface, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Floating-point subtraction."; } def Handshake_SubIOp : Handshake_Arith_IntBinaryOp<"subi", [ - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Integer subtraction."; } @@ -432,7 +432,7 @@ def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf", [ def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [ Commutative, - ArithNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Bitwise exclusive union."; } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 94041a3ad9..1dfc21ba59 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -143,26 +143,43 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { ]; } -def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"Provides detailed names for the operands and results of an operation."}]; - - let methods = [ - InterfaceMethod< - "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx)>, - InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx) - > - ]; -} +//===----------------------------------------------------------------------===// +// IO Naming Interfaces +//===----------------------------------------------------------------------===// +// +// To generate the netlist, we need to know the names of +// the operands (inputs) and results (output) +// for each operation. +// +// These are already named inside of the Tablegen, +// but this does not generate any way to access the names as strings +// only using the names to generate functions. +// +// There are 3 interfaces: simple, binary arith, custom +// For an operation which uses the simple interface: +// The operand names are 'ins_n', where n is the index of the operand +// the result names are 'outs_n' where n is the idnex of the result +// +// If there is only 1 operand or 1 result, the name is 'ins' or 'outs', +// respectively. +// +// To use binary arith, the operation must have 2 operands and 1 result +// They will be named 'lhs', 'rhs', and 'result'. +// +// If the custom interface is used, the name uses a fully custom function +// If the naming is easy to do, +// the function definition can be added to the operation declaration in tablegen +// +// If it is hard, +// the function declaration can be added to the operation declaration in tablegen +// and the definition can be written in HandshakeOps.cpp +// +//===----------------------------------------------------------------------===// def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = - [{"Provides detailed names for the operands and results of an operation."}]; + [{"Used by operations whose operands and results are named 'ins" and 'outs'."}]; let methods = [ InterfaceMethod< @@ -186,10 +203,10 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { ]; } -def ArithNamedIOInterface : OpInterface<"ArithNamedIOInterface"> { +def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = - [{"Provides detailed names for the operands and results of an operation."}]; + [{"Used by operations whose operands are named 'lhs' and 'rhs', and result is named 'result'."}]; let methods = [ InterfaceMethod< @@ -211,6 +228,27 @@ def ArithNamedIOInterface : OpInterface<"ArithNamedIOInterface"> { ]; } +def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Used by operations with unique names for their operands and results. T"}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx)>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx) + > + ]; +} + +//===----------------------------------------------------------------------===// +// Number of RTL Ports +//===----------------------------------------------------------------------===// + + def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 4dbd81bd2f..cc25c3fd8e 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -32,6 +32,9 @@ class Handshake_Op traits = []> : Op, DeclareOpInterfaceMethods, + // To inherit from HandshakeOp, + // an operations connections must match its + // RTL connections InputRTLPortsAreOperandsInterface, OutputRTLPortsAreResultsInterface ]> { @@ -40,6 +43,7 @@ class Handshake_Op traits = []> // This is almost exactly like a standard FuncOp, except that it has some // extra verification conditions. In particular, each Value must // only have a single use. Also, it defines a Dominance-Free Scope + def FuncOp : Op { @@ -137,6 +141,11 @@ def FuncOp : Op, + // the RTL ports of a FuncOp have simple names SimpleNamedIOInterface ]> { let summary = "module instantiate operation"; From 4e1fced377dd188bd3c021734a127fc453555405 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 13:45:14 +0200 Subject: [PATCH 086/187] commenting, check funcop? --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index f657b2c9e4..2a38dd4b66 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -45,7 +45,7 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } @@ -63,7 +63,7 @@ std::string getResultName(Operation *op, size_t resIdx) { dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getResultName(resIdx); } From 60825b3a3741d36bbf5c23bd75988596ab553792 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:14:12 +0200 Subject: [PATCH 087/187] commenting, check end op? --- .../Dialect/Handshake/HandshakeOps.td | 81 +++++++++++++++++-- lib/Dialect/Handshake/HandshakeOps.cpp | 22 ++--- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index cc25c3fd8e..413633ba23 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -51,7 +51,7 @@ def FuncOp : Op { @@ -191,8 +191,6 @@ def InstanceOp : Handshake_Op<"instance", [ CallOpInterface, HasClock, DeclareOpInterfaceMethods, - // the RTL ports of a FuncOp have simple names - SimpleNamedIOInterface ]> { let summary = "module instantiate operation"; let description = [{ @@ -272,6 +270,7 @@ def InstanceOp : Handshake_Op<"instance", [ def BufferOp : Handshake_Op<"buffer", [ HasClock, SameOperandsAndResultType, + // The IOs of a BufferOp have simple names SimpleNamedIOInterface ]> { let summary = "buffer operation"; @@ -345,6 +344,7 @@ def BufferOp : Handshake_Op<"buffer", [ def InitOp : Handshake_Op<"init", [ HasClock, SameOperandsAndResultType, + // The IOs of an InitOp have simple names SimpleNamedIOInterface ]> { let summary = "init operation"; @@ -369,6 +369,7 @@ def InitOp : Handshake_Op<"init", [ def NDWireOp : Handshake_Op<"ndwire", [ HasClock, SameOperandsAndResultType, + // The IOs of a NDWire have simple names SimpleNamedIOInterface ]> { let summary = "non-deterministic wire operation"; @@ -389,6 +390,7 @@ class Handshake_ForkOp traits = []> : Pure, HasClock, SameOperandsAndResultType, + // The IOs of a ForkOp have simple names SimpleNamedIOInterface ]> { let arguments = (ins HandshakeType:$operand); @@ -446,6 +448,7 @@ def MergeOp : Handshake_Op<"merge", [ SameOperandsAndResultType, VariadicHasElement<"dataOperands">, DeclareOpInterfaceMethods, + // The IOs of a MergeOp have simple names SimpleNamedIOInterface ]> { let summary = "merge operation"; @@ -477,6 +480,9 @@ def MuxOp : Handshake_Op<"mux", [ // Interface declarations DeclareOpInterfaceMethods, DeclareOpInterfaceMethods, + // The IOs of a MuxOp have custom names, + // defined here in the Tablegen + // as part of the MuxOp declaration CustomNamedIOInterface ]> { let summary = "mux operation"; @@ -504,10 +510,13 @@ def MuxOp : Handshake_Op<"mux", [ let results = (outs HandshakeType:$result); let extraClassDeclaration = [{ + /// Operand 0 is named "index" + /// Operands 1 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { return idx == 0 ? "index" : detail::simpleOperandName(idx - 1, getOperation()->getNumOperands() - 1); } + /// Result 0 is named "outs" std::string getResultName(unsigned idx) { return detail::simpleResultName(idx, 1); } @@ -526,6 +535,9 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ AllExtraSignalsMatchWithVariadic<"dataOperands", ["result", "index"]>, // Interface declarations DeclareOpInterfaceMethods, + // The IOs of a CMergeOP have custom names, + // defined here in the Tablegen + // as part of the CMergeOP declaration CustomNamedIOInterface ]> { let summary = "control merge operation"; @@ -559,10 +571,13 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ }]>]; let extraClassDeclaration = [{ + /// Operands 0 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); } + /// Result 0 is named outs + /// Result 1 is named index std::string getResultName(unsigned idx) { assert(idx < 2 && "index too high"); return idx == 0 ? "outs" : "index"; @@ -576,6 +591,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ def BranchOp : Handshake_Op<"br", [ Pure, SameOperandsAndResultType, + // The IOs of a BranchOp have simple names SimpleNamedIOInterface ]> { let summary = "branch operation"; @@ -605,6 +621,9 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ IsIntSizedChannel<1, "conditionOperand">, DeclareOpInterfaceMethods, DeclareOpInterfaceMethods, + // The IOs of a ConditionalBranch have custom names, + // defined here in the Tablegen + // as part of the ConditionalBranch declaration CustomNamedIOInterface ]> { let summary = "conditional branch operation"; @@ -635,11 +654,15 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; + /// Operand 0 is named condition + /// Operand 1 is named data std::string getOperandName(unsigned idx) { assert(idx < 2 && "index too high"); return idx == 0 ? "condition" : "data"; } + /// Operand 0 is named trueOut + /// Operand 1 is named falseOut std::string getResultName(unsigned idx) { assert(idx < 2 && "index too high"); return idx == trueIndex ? "trueOut" : "falseOut"; @@ -648,6 +671,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ } def SinkOp : Handshake_Op<"sink", [ + // The IOs of a SinkOp have simple names SimpleNamedIOInterface ]> { let summary = "sink operation"; @@ -670,8 +694,9 @@ def SinkOp : Handshake_Op<"sink", [ def SourceOp : Handshake_Op<"source", [ Pure, + // The IOs of a SourceOp have simple names SimpleNamedIOInterface - ]> { +]> { let summary = "source operation"; let description = [{ The source operation represents a continuous control-only-token source. The @@ -700,6 +725,7 @@ def SourceOp : Handshake_Op<"source", [ def JoinOp : Handshake_Op<"join", [ SameOperandsAndResultType, DeclareOpInterfaceMethods, + // The IOs of a JoinOp have simple names SimpleNamedIOInterface ]> { let summary = "join operation"; @@ -723,6 +749,7 @@ def JoinOp : Handshake_Op<"join", [ // once the backend supports variadic channels with zero or one item correctly. def BlockerOp : Handshake_Op<"blocker", [ SameOperandsAndResultType, + // The IOs of a BlockerOp have simple names SimpleNamedIOInterface ]> { let summary = "blocker operation"; @@ -745,6 +772,7 @@ def BlockerOp : Handshake_Op<"blocker", [ def NotOp : Handshake_Op<"not", [ Pure, SameOperandsAndResultType, + // The IOs of a NotOp have simple names SimpleNamedIOInterface ]> { let summary = "Logical negation"; @@ -776,6 +804,9 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ IsSimpleHandshakeVariadic<"inputs">, IsSimpleHandshakeVariadic<"outputs">, DeclareOpInterfaceMethods, + // The IOs of a MemoryControllerOp have custom names, + // As they are complex, they are declared here, + // but defined in HandshakeOps.cpp CustomNamedIOInterface ]> { let summary = "memory controller (dynamatic)"; @@ -859,6 +890,9 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ def LSQOp : Handshake_Op<"lsq", [ DeclareOpInterfaceMethods, + // The IOs of a MemoryControllerOp have custom names, + // As they are complex, they are declared here, + // but defined in HandshakeOps.cpp CustomNamedIOInterface ]> { let summary = "load-store queue (dynamatic)"; @@ -992,6 +1026,9 @@ def LoadOp : Handshake_MemPortOp<"load", [ // In LoadOp, addressResult and data are connected to a memory controller. IsSimpleHandshake<"addressResult">, IsSimpleHandshake<"data">, + // The IOs of a LoadOp have custom names, + // defined here in the Tablegen + // as part of the LoadOp declaration CustomNamedIOInterface ], [ // TODO: Please add comments on why this builder is necessary @@ -1030,11 +1067,15 @@ def LoadOp : Handshake_MemPortOp<"load", [ }]; let extraClassDeclaration= [{ + /// Operand 0 is named addrIn + /// Operand 1 is named dataFromMem std::string getOperandName(unsigned idx) { assert(idx < 2 && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; } + /// Result 0 is named addrOut + /// Result 1 is named dataOut std::string getResultName(unsigned idx) { assert(idx < 2 && "index too high"); return (idx == 0) ? "addrOut" : "dataOut"; @@ -1047,6 +1088,9 @@ def StoreOp : Handshake_MemPortOp<"store", [ // In StoreOp, addressResult and dataResult are connected to a memory controller. IsSimpleHandshake<"addressResult">, IsSimpleHandshake<"dataResult">, + // The IOs of a StoreOp have custom names, + // defined here in the Tablegen + // as part of the StoreOp declaration CustomNamedIOInterface ], []> { let summary = "store operation for memory controller (MC)"; @@ -1072,11 +1116,15 @@ def StoreOp : Handshake_MemPortOp<"store", [ }]; let extraClassDeclaration = [{ + /// Operand 0 is named addrIn + /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { assert(idx < 2 && "index too high"); return (idx == 0) ? "addrIn" : "dataIn"; } + /// Result 0 is named addrOut + /// Result 1 is named dataToMem std::string getResultName(unsigned int idx) { assert(idx < 2 && "index too high"); return (idx == 0) ? "addrOut" : "dataToMem"; @@ -1143,8 +1191,14 @@ def EndOp : Op, DeclareOpInterfaceMethods, + // The IOs of a EndOp have simple names SimpleNamedIOInterface, + // The RTL input ports correspond to the IR InputRTLPortsAreOperandsInterface, + // The RTL output ports do not + // As they are actually based on the function results + // And so are defined here in the tablegen + // as part of the EndOp declaration CustomRTLOutputPortsInterface ]> { let summary = "function endpoint (dynamatic)"; @@ -1162,9 +1216,24 @@ def EndOp : Op:$inputs); let extraClassDeclaration = [{ - unsigned getNumOutputPorts(); + // unsigned getNumOutputPorts(); + + // std::string getOutputPortName(unsigned idx); + + /// Output ports of EndOp are function results + unsigned EndOp::getNumOutputPorts(){ + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + return funcOp.getNumOutputPorts(); + } + + /// Output ports of EndOp are function results + std::string EndOp::getOutputPortName(unsigned idx){ + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + return funcOp.getOutputPortName(idx); + } - std::string getOutputPortName(unsigned idx); }]; let assemblyFormat = [{ diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 764cb7da83..56e187157f 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1549,17 +1549,17 @@ LogicalResult EndOp::verify() { return success(); } -unsigned EndOp::getNumOutputPorts(){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getFunctionType().getNumResults(); -} - -std::string EndOp::getOutputPortName(unsigned idx){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getOutputPortName(idx); -} +// unsigned EndOp::getNumOutputPorts(){ +// handshake::FuncOp funcOp = (*this)->getParentOfType(); +// assert(funcOp && "end must be child of handshake function"); +// return funcOp.getNumOutputPorts(); +// } + +// std::string EndOp::getOutputPortName(unsigned idx){ +// handshake::FuncOp funcOp = (*this)->getParentOfType(); +// assert(funcOp && "end must be child of handshake function"); +// return funcOp.getOutputPortName(idx); +// } //===----------------------------------------------------------------------===// From 382f494ad7b399bc35d25409ed597eb064eebec6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:20:40 +0200 Subject: [PATCH 088/187] commenting, check end op? --- .../Dialect/Handshake/HandshakeOps.td | 28 ++++++------------- lib/Dialect/Handshake/HandshakeOps.cpp | 22 +++++++-------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 413633ba23..7adf996328 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1195,10 +1195,13 @@ def EndOp : Op { let summary = "function endpoint (dynamatic)"; @@ -1216,24 +1219,11 @@ def EndOp : Op:$inputs); let extraClassDeclaration = [{ - // unsigned getNumOutputPorts(); - - // std::string getOutputPortName(unsigned idx); - /// Output ports of EndOp are function results - unsigned EndOp::getNumOutputPorts(){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getNumOutputPorts(); - } + unsigned getNumOutputPorts(); /// Output ports of EndOp are function results - std::string EndOp::getOutputPortName(unsigned idx){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getOutputPortName(idx); - } - + std::string getOutputPortName(unsigned idx); }]; let assemblyFormat = [{ diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 56e187157f..e25c620d0e 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1549,17 +1549,17 @@ LogicalResult EndOp::verify() { return success(); } -// unsigned EndOp::getNumOutputPorts(){ -// handshake::FuncOp funcOp = (*this)->getParentOfType(); -// assert(funcOp && "end must be child of handshake function"); -// return funcOp.getNumOutputPorts(); -// } - -// std::string EndOp::getOutputPortName(unsigned idx){ -// handshake::FuncOp funcOp = (*this)->getParentOfType(); -// assert(funcOp && "end must be child of handshake function"); -// return funcOp.getOutputPortName(idx); -// } +unsigned EndOp::getNumOutputPorts(){ + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + return funcOp.getNumOutputPorts(); +} + +std::string EndOp::getOutputPortName(unsigned idx){ + handshake::FuncOp funcOp = (*this)->getParentOfType(); + assert(funcOp && "end must be child of handshake function"); + return funcOp.getOutputPortName(idx); +} //===----------------------------------------------------------------------===// From 0d5894d807e743dade465a344914e881f3f0b7de Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:29:30 +0200 Subject: [PATCH 089/187] commenting, validate? --- .../Dialect/Handshake/HandshakeOps.td | 57 +++++++++++++++---- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 7adf996328..7919a10307 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -38,6 +38,16 @@ class Handshake_Op traits = []> InputRTLPortsAreOperandsInterface, OutputRTLPortsAreResultsInterface ]> { + let extraClassDeclaration = [{ + void validateOperandIdx(unsigned idx){ + assert(idx < getOperation()->getNumOperands() && "index too high"); + } + + void validateResultIdx(unsigned idx){ + assert(idx < getOperation()->getNumResults() && "index too high"); + } + }]; + } // This is almost exactly like a standard FuncOp, except that it has some @@ -657,14 +667,14 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ /// Operand 0 is named condition /// Operand 1 is named data std::string getOperandName(unsigned idx) { - assert(idx < 2 && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "condition" : "data"; } /// Operand 0 is named trueOut /// Operand 1 is named falseOut std::string getResultName(unsigned idx) { - assert(idx < 2 && "index too high"); + validateResultIdx(idx); return idx == trueIndex ? "trueOut" : "falseOut"; } }]; @@ -1070,14 +1080,14 @@ def LoadOp : Handshake_MemPortOp<"load", [ /// Operand 0 is named addrIn /// Operand 1 is named dataFromMem std::string getOperandName(unsigned idx) { - assert(idx < 2 && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "addrIn" : "dataFromMem"; } /// Result 0 is named addrOut /// Result 1 is named dataOut std::string getResultName(unsigned idx) { - assert(idx < 2 && "index too high"); + validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataOut"; } }]; @@ -1119,14 +1129,14 @@ def StoreOp : Handshake_MemPortOp<"store", [ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { - assert(idx < 2 && "index too high"); + assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "addrIn" : "dataIn"; } /// Result 0 is named addrOut /// Result 1 is named dataToMem std::string getResultName(unsigned int idx) { - assert(idx < 2 && "index too high"); + validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataToMem"; } }]; @@ -1252,6 +1262,9 @@ def SpeculatorOp : Handshake_Op<"speculator", [ IsIntSizedChannel<3, "SCCommitCtrl">, IsSimpleHandshake<"SCIsMisspec">, IsIntSizedChannel<1, "SCIsMisspec">, + // The IOs of the SpeculatorOp have custom names + // defined here in the Tablegen + // as part of the SpeculatorOp declaration CustomNamedIOInterface ]> { let summary = "Central control unit of the speculative circuit."; @@ -1304,13 +1317,21 @@ def SpeculatorOp : Handshake_Op<"speculator", [ }]>]; let extraClassDeclaration = [{ + /// Operand 0 is named ins + /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "trigger"; } + /// Result 0 is named outs + /// Result 1 is named ctrl_save + /// Result 2 is named ctrl_commit + /// Result 3 is named ctrl_sc_save + /// Result 4 is named ctrl_sc_commit + /// Result 5 is named ctrl_sc_branch std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); switch (idx) { case 0: return "outs"; @@ -1336,6 +1357,9 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ HasValidSpecTag<"dataOut">, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<1, "ctrl">, + // The IOs of a SpecSaveOp have custom names, + // defined here in the Tablegen + // as part of the SpecSaveOp declaration CustomNamedIOInterface ]> { let summary = "Saves data tokens that interact in the speculative region."; @@ -1363,13 +1387,16 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ }]; let extraClassDeclaration = [{ + /// Operand 0 is named ins + /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } + /// Result 0 is named outs std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1382,6 +1409,9 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ LacksSpecTag<"dataOut">, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<1, "ctrl">, + // The IOs of a SpecCommitOp have custom names, + // defined here in the Tablegen + // as part of the SpecCommitOp declaration CustomNamedIOInterface ]> { let summary = "Stall speculative data tokens until they are resolved."; @@ -1411,13 +1441,16 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ }]; let extraClassDeclaration = [{ + /// Operand 0 is named ins + /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } + /// Result 0 is named result std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1459,7 +1492,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1547,7 +1580,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "dataOut"; } }]; @@ -1615,7 +1648,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); if (idx < getNumSharedOperations()) return "op" + std::to_string(idx) + "out0"; return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); From 665430784a68dfb914be55eaf944157d16504436 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:33:07 +0200 Subject: [PATCH 090/187] commenting, inherit? --- .../Dialect/Handshake/HandshakeOps.td | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 7919a10307..3087bc1dd5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -240,7 +240,7 @@ def InstanceOp : Handshake_Op<"instance", [ operands); }]>]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ FunctionType getModuleType(); /// Get the argument operands to the called function. @@ -296,7 +296,7 @@ def BufferOp : Handshake_Op<"buffer", [ let results = (outs HandshakeType:$result); - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ // can a data token bypass the buffer bool isBypassDV(){ switch (getBufferType()) { @@ -366,7 +366,7 @@ def InitOp : Handshake_Op<"init", [ let arguments = (ins HandshakeType:$operand); let results = (outs HandshakeType:$result); - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ static constexpr ::llvm::StringLiteral INIT_TOKEN_ATTR_NAME = "INIT_TOKEN", TIMING_ATTR_NAME = "TIMING"; }]; @@ -519,7 +519,7 @@ def MuxOp : Handshake_Op<"mux", [ Variadic:$dataOperands); let results = (outs HandshakeType:$result); - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { @@ -580,7 +580,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operands 0 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); @@ -660,7 +660,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ `:` type($conditionOperand) `,` custom(type($dataOperand)) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; @@ -880,7 +880,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ attr-dict `:` custom(type($memStart)) custom(type($memEnd)) custom(type($ctrlEnd)) functional-type($inputs, $outputs) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Returns the list of basic block IDs the MC is connected to. mlir::SmallVector getMCBlocks() { mlir::SmallVector blocks; @@ -961,7 +961,7 @@ def LSQOp : Handshake_Op<"lsq", [ let hasVerifier = 1; let hasCustomAssemblyFormat = 1; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Returns the list of sizes of all LSQ groups. mlir::SmallVector getLSQGroupSizes() { mlir::SmallVector sizes; @@ -1125,7 +1125,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { @@ -1228,7 +1228,7 @@ def EndOp : Op:$inputs); - let extraClassDeclaration = [{ + let ExtraClassDeclaration = [{ /// Output ports of EndOp are function results unsigned getNumOutputPorts(); @@ -1316,7 +1316,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ wideControlType, ctrlType}); }]>]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { @@ -1386,7 +1386,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1440,7 +1440,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1485,7 +1485,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; @@ -1533,7 +1533,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ type($trueResult) `,` type($falseResult) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; @@ -1573,7 +1573,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ $dataIn attr-dict `:` type($dataIn) `to` type($dataOut) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return "dataIn"; @@ -1637,7 +1637,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); if (idx < getNumSharedOperands() * getNumSharedOperations()) { @@ -1808,7 +1808,7 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx){ assert(idx < 1 && "index too high"); return "ins"; @@ -1843,7 +1843,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ $lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn)) }]; - let extraClassDeclaration = [{ + let ExtraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; From 8a3dd965f27edbbd11c6d0cc6fba6a011f411a4c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:34:28 +0200 Subject: [PATCH 091/187] commenting, inherit? --- .../Dialect/Handshake/HandshakeOps.td | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 3087bc1dd5..d6fc6a1693 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -240,7 +240,7 @@ def InstanceOp : Handshake_Op<"instance", [ operands); }]>]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ FunctionType getModuleType(); /// Get the argument operands to the called function. @@ -296,7 +296,7 @@ def BufferOp : Handshake_Op<"buffer", [ let results = (outs HandshakeType:$result); - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ // can a data token bypass the buffer bool isBypassDV(){ switch (getBufferType()) { @@ -366,7 +366,7 @@ def InitOp : Handshake_Op<"init", [ let arguments = (ins HandshakeType:$operand); let results = (outs HandshakeType:$result); - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ static constexpr ::llvm::StringLiteral INIT_TOKEN_ATTR_NAME = "INIT_TOKEN", TIMING_ATTR_NAME = "TIMING"; }]; @@ -519,7 +519,7 @@ def MuxOp : Handshake_Op<"mux", [ Variadic:$dataOperands); let results = (outs HandshakeType:$result); - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { @@ -580,7 +580,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operands 0 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); @@ -660,7 +660,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ `:` type($conditionOperand) `,` custom(type($dataOperand)) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; @@ -880,7 +880,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ attr-dict `:` custom(type($memStart)) custom(type($memEnd)) custom(type($ctrlEnd)) functional-type($inputs, $outputs) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Returns the list of basic block IDs the MC is connected to. mlir::SmallVector getMCBlocks() { mlir::SmallVector blocks; @@ -961,7 +961,7 @@ def LSQOp : Handshake_Op<"lsq", [ let hasVerifier = 1; let hasCustomAssemblyFormat = 1; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Returns the list of sizes of all LSQ groups. mlir::SmallVector getLSQGroupSizes() { mlir::SmallVector sizes; @@ -1125,7 +1125,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { @@ -1228,7 +1228,7 @@ def EndOp : Op:$inputs); - let ExtraClassDeclaration = [{ + let extraClassDeclaration = [{ /// Output ports of EndOp are function results unsigned getNumOutputPorts(); @@ -1316,7 +1316,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ wideControlType, ctrlType}); }]>]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { @@ -1386,7 +1386,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1440,7 +1440,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1485,7 +1485,7 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($ctrl) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; @@ -1533,7 +1533,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ type($trueResult) `,` type($falseResult) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; @@ -1573,7 +1573,7 @@ def NonSpecOp : Handshake_Op<"non_spec", [ $dataIn attr-dict `:` type($dataIn) `to` type($dataOut) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return "dataIn"; @@ -1637,7 +1637,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); if (idx < getNumSharedOperands() * getNumSharedOperations()) { @@ -1808,7 +1808,7 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx){ assert(idx < 1 && "index too high"); return "ins"; @@ -1843,7 +1843,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ $lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn)) }]; - let ExtraClassDeclaration += [{ + let extraClassDeclaration += [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; From e5513205aaf6b631a55ac13d1b35731905db2221 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:35:46 +0200 Subject: [PATCH 092/187] commenting, inherit? --- .../Dialect/Handshake/HandshakeOps.td | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d6fc6a1693..6ce69e4d22 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -240,7 +240,7 @@ def InstanceOp : Handshake_Op<"instance", [ operands); }]>]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ FunctionType getModuleType(); /// Get the argument operands to the called function. @@ -296,7 +296,7 @@ def BufferOp : Handshake_Op<"buffer", [ let results = (outs HandshakeType:$result); - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ // can a data token bypass the buffer bool isBypassDV(){ switch (getBufferType()) { @@ -366,7 +366,7 @@ def InitOp : Handshake_Op<"init", [ let arguments = (ins HandshakeType:$operand); let results = (outs HandshakeType:$result); - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ static constexpr ::llvm::StringLiteral INIT_TOKEN_ATTR_NAME = "INIT_TOKEN", TIMING_ATTR_NAME = "TIMING"; }]; @@ -519,7 +519,7 @@ def MuxOp : Handshake_Op<"mux", [ Variadic:$dataOperands); let results = (outs HandshakeType:$result); - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { @@ -580,7 +580,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operands 0 to N are named "ins_0" to "ins_" std::string getOperandName(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); @@ -660,7 +660,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ `:` type($conditionOperand) `,` custom(type($dataOperand)) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; @@ -674,7 +674,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ /// Operand 0 is named trueOut /// Operand 1 is named falseOut std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); return idx == trueIndex ? "trueOut" : "falseOut"; } }]; @@ -880,7 +880,7 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ attr-dict `:` custom(type($memStart)) custom(type($memEnd)) custom(type($ctrlEnd)) functional-type($inputs, $outputs) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Returns the list of basic block IDs the MC is connected to. mlir::SmallVector getMCBlocks() { mlir::SmallVector blocks; @@ -961,7 +961,7 @@ def LSQOp : Handshake_Op<"lsq", [ let hasVerifier = 1; let hasCustomAssemblyFormat = 1; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Returns the list of sizes of all LSQ groups. mlir::SmallVector getLSQGroupSizes() { mlir::SmallVector sizes; @@ -1087,7 +1087,7 @@ def LoadOp : Handshake_MemPortOp<"load", [ /// Result 0 is named addrOut /// Result 1 is named dataOut std::string getResultName(unsigned idx) { - validateResultIdx(idx); + validateResultIdx(idx) return (idx == 0) ? "addrOut" : "dataOut"; } }]; @@ -1125,7 +1125,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { @@ -1136,10 +1136,10 @@ def StoreOp : Handshake_MemPortOp<"store", [ /// Result 0 is named addrOut /// Result 1 is named dataToMem std::string getResultName(unsigned int idx) { - validateResultIdx(idx); + validateResultIdx(idx) return (idx == 0) ? "addrOut" : "dataToMem"; } - }]; + }] # extraClassDeclaration; } //===----------------------------------------------------------------------===// @@ -1316,7 +1316,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ wideControlType, ctrlType}); }]>]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { @@ -1331,7 +1331,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ /// Result 4 is named ctrl_sc_commit /// Result 5 is named ctrl_sc_branch std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); switch (idx) { case 0: return "outs"; @@ -1386,7 +1386,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1396,7 +1396,7 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ /// Result 0 is named outs std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } }]; @@ -1440,7 +1440,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1450,7 +1450,7 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ /// Result 0 is named result std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } }]; @@ -1485,14 +1485,14 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($ctrl) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "ins" : "ctrl"; } std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); return "outs"; } }]; @@ -1533,7 +1533,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ type($trueResult) `,` type($falseResult) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return idx == 0 ? "spec_tag_data" : "data"; @@ -1573,14 +1573,14 @@ def NonSpecOp : Handshake_Op<"non_spec", [ $dataIn attr-dict `:` type($dataIn) `to` type($dataOut) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return "dataIn"; } std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); return "dataOut"; } }]; @@ -1637,7 +1637,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); if (idx < getNumSharedOperands() * getNumSharedOperations()) { @@ -1648,7 +1648,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ } std::string getResultName(unsigned idx) { - validateResultIdx(idx); + assert(idx < getOperation()->getNumResults() && "index too high"); if (idx < getNumSharedOperations()) return "op" + std::to_string(idx) + "out0"; return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); @@ -1808,7 +1808,7 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx){ assert(idx < 1 && "index too high"); return "ins"; @@ -1843,7 +1843,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ $lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn)) }]; - let extraClassDeclaration += [{ + let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); return (idx == 0) ? "lhs_ins" : "rhs_ins"; From c35de58a7965299f90efc99abc41f65432aa01ff Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:41:58 +0200 Subject: [PATCH 093/187] commenting, inherit? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 6ce69e4d22..c502bdbe7e 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -38,7 +38,8 @@ class Handshake_Op traits = []> InputRTLPortsAreOperandsInterface, OutputRTLPortsAreResultsInterface ]> { - let extraClassDeclaration = [{ + // Shared functions to include in child classes + let validateIO = [{ void validateOperandIdx(unsigned idx){ assert(idx < getOperation()->getNumOperands() && "index too high"); } @@ -1125,7 +1126,8 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - let extraClassDeclaration = [{ + // include validateIO functions + let extraClassDeclaration = validateIO # [{ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { @@ -1139,7 +1141,7 @@ def StoreOp : Handshake_MemPortOp<"store", [ validateResultIdx(idx) return (idx == 0) ? "addrOut" : "dataToMem"; } - }] # extraClassDeclaration; + }]; } //===----------------------------------------------------------------------===// From 1b218b0e46604998a59f62fabaffe2e1e6e1f775 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:42:32 +0200 Subject: [PATCH 094/187] commenting, inherit? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index c502bdbe7e..c4060aafd8 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -39,7 +39,7 @@ class Handshake_Op traits = []> OutputRTLPortsAreResultsInterface ]> { // Shared functions to include in child classes - let validateIO = [{ + string validateIO = [{ void validateOperandIdx(unsigned idx){ assert(idx < getOperation()->getNumOperands() && "index too high"); } From ae77057d72d6ab55900507de3aed684ab940da7a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:52:44 +0200 Subject: [PATCH 095/187] commenting, inherit? --- .../Dialect/Handshake/HandshakeOps.td | 87 +++++++++++-------- 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index c4060aafd8..3e27e4c587 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -40,11 +40,11 @@ class Handshake_Op traits = []> ]> { // Shared functions to include in child classes string validateIO = [{ - void validateOperandIdx(unsigned idx){ + void validateOperandIdx(unsigned int idx){ assert(idx < getOperation()->getNumOperands() && "index too high"); } - void validateResultIdx(unsigned idx){ + void validateResultIdx(unsigned int idx){ assert(idx < getOperation()->getNumResults() && "index too high"); } }]; @@ -523,11 +523,13 @@ def MuxOp : Handshake_Op<"mux", [ let extraClassDeclaration = [{ /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" + /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { return idx == 0 ? "index" : detail::simpleOperandName(idx - 1, getOperation()->getNumOperands() - 1); } /// Result 0 is named "outs" + /// simpleResultName handles validation std::string getResultName(unsigned idx) { return detail::simpleResultName(idx, 1); } @@ -581,8 +583,10 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ $_state.addTypes({operands[0].getType(), idxType}); }]>]; - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ /// Operands 0 to N are named "ins_0" to "ins_" + /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); } @@ -590,7 +594,7 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ /// Result 0 is named outs /// Result 1 is named index std::string getResultName(unsigned idx) { - assert(idx < 2 && "index too high"); + validateResultIdx(idx); return idx == 0 ? "outs" : "index"; } }]; @@ -1077,18 +1081,19 @@ def LoadOp : Handshake_MemPortOp<"load", [ ``` }]; - let extraClassDeclaration= [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ /// Operand 0 is named addrIn /// Operand 1 is named dataFromMem std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return (idx == 0) ? "addrIn" : "dataFromMem"; } /// Result 0 is named addrOut /// Result 1 is named dataOut std::string getResultName(unsigned idx) { - validateResultIdx(idx) + validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataOut"; } }]; @@ -1126,19 +1131,19 @@ def StoreOp : Handshake_MemPortOp<"store", [ ``` }]; - // include validateIO functions + // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return (idx == 0) ? "addrIn" : "dataIn"; } /// Result 0 is named addrOut /// Result 1 is named dataToMem std::string getResultName(unsigned int idx) { - validateResultIdx(idx) + validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataToMem"; } }]; @@ -1318,11 +1323,12 @@ def SpeculatorOp : Handshake_Op<"speculator", [ wideControlType, ctrlType}); }]>]; + // include validateIO functions from handshake op let extraClassDeclaration = [{ /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "ins" : "trigger"; } @@ -1333,7 +1339,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ /// Result 4 is named ctrl_sc_commit /// Result 5 is named ctrl_sc_branch std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); switch (idx) { case 0: return "outs"; @@ -1388,17 +1394,18 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } /// Result 0 is named outs std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1442,17 +1449,17 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($dataOut) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + let extraClassDeclaration = validateIO # [{ /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } /// Result 0 is named result std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1487,14 +1494,15 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ `[` $ctrl `]` $dataIn attr-dict `:` type($dataIn) `,` type($ctrl) }]; - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1535,14 +1543,16 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ type($trueResult) `,` type($falseResult) }]; + + // include validateIO functions from handshake op let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "spec_tag_data" : "data"; } std::string getResultName(unsigned idx) { - assert(idx < 2 && "index too high"); + validateResultIdx(idx); return idx == 0 ? "trueOut" : "falseOut"; } }]; @@ -1575,14 +1585,16 @@ def NonSpecOp : Handshake_Op<"non_spec", [ $dataIn attr-dict `:` type($dataIn) `to` type($dataOut) }]; - let extraClassDeclaration = [{ + + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return "dataIn"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return "dataOut"; } }]; @@ -1639,9 +1651,10 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ ConfinedAttr]>:$latency); let results = (outs Variadic : $dataOut); - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); if (idx < getNumSharedOperands() * getNumSharedOperations()) { return "op" + std::to_string(idx / getNumSharedOperands()) + "in" + std::to_string(idx % getNumSharedOperands()); @@ -1650,7 +1663,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); if (idx < getNumSharedOperations()) return "op" + std::to_string(idx) + "out0"; return "toSharedUnitIn" + std::to_string(idx - getNumSharedOperations()); @@ -1810,14 +1823,15 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx){ - assert(idx < 1 && "index too high"); + validateOperandIdx(idx); return "ins"; } std::string getResultName(unsigned idx) { - assert(idx < 1 && "index too high"); + validateResultIdx(idx); return "outs"; } }]; @@ -1845,15 +1859,16 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ $lhsIn `,` $rhsIn attr-dict `:` custom(type($lhsIn)) `,` custom(type($rhsIn)) }]; + // include validateIO functions from handshake op let extraClassDeclaration = [{ std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); - return (idx == 0) ? "lhs_ins" : "rhs_ins"; + validateOperandIdx(idx); + return (idx == 0) ? "lhs_ins" : "rhs_ins"; } std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); - return (idx == 0) ? "lhs_outs" : "rhs_outs"; + validateResultIdx(idx); + return (idx == 0) ? "lhs_outs" : "rhs_outs"; } }]; From 2ab2594a2505fc11b3ea9fce25396fe20cfa61a0 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:53:30 +0200 Subject: [PATCH 096/187] commenting, inherit? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 3e27e4c587..befb2fb806 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1860,7 +1860,7 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ }]; // include validateIO functions from handshake op - let extraClassDeclaration = [{ + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return (idx == 0) ? "lhs_ins" : "rhs_ins"; From 23ce952e4e2cdaf2566e365e2010eadf41307986 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:54:52 +0200 Subject: [PATCH 097/187] inherit fixes --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index befb2fb806..d792419eb4 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1545,7 +1545,7 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ // include validateIO functions from handshake op - let extraClassDeclaration = [{ + let extraClassDeclaration = validateIO # [{ std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "spec_tag_data" : "data"; From 41d16de0879fdb84c0b52f5abbd518c9f64510b5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 15:55:32 +0200 Subject: [PATCH 098/187] inherit fixes --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d792419eb4..4709a759bc 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1324,7 +1324,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ }]>]; // include validateIO functions from handshake op - let extraClassDeclaration = [{ + let extraClassDeclaration = validateIO # [{ /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { From 7fc4cdbd62ed26dc2e00db687606cbbb2846a97e Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:13:56 +0200 Subject: [PATCH 099/187] remove port namer --- .../Dialect/Handshake/HandshakeInterfaces.h | 32 ++----- .../Dialect/Handshake/HandshakeInterfaces.td | 90 ++++++++++--------- .../Dialect/Handshake/HandshakeOps.td | 19 ++-- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 27 +----- 4 files changed, 75 insertions(+), 93 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 702df97d26..dec2a94c97 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -34,34 +34,20 @@ namespace handshake { class FuncOp; +/// Returns the name of an operand +/// based on which interface the operation implements std::string getOperandName(Operation *op, size_t oprdIdx); -std::string getResultName(Operation *op, size_t resIdx); - -/// Provides an opaque interface for generating the port names of an operation; -/// handshake operations generate names by the `handshake::NamedIOInterface`; -/// other operations, such as arithmetic ones, are assigned default names. -class PortNamer { -public: - /// Does nothing; no port name will be generated. - PortNamer() = default; - - /// Derives port names for the operation on object creation. - PortNamer(Operation *op); - /// Returs the port name of the input at the specified index. - StringRef getInputName(unsigned idx) const { return inputs[idx]; } - - /// Returs the port name of the output at the specified index. - StringRef getOutputName(unsigned idx) const { return outputs[idx]; } +/// Returns the name of a result +/// based on which interface the operation implements +std::string getResultName(Operation *op, size_t resIdx); -private: +unsigned getNumInputPorts(Operation *op); +std::string getInputPortName(Operation *op, size_t portIdx); - /// List of input port names. - SmallVector inputs; - /// List of output port names. - SmallVector outputs; -}; +unsigned getNumOutputPorts(Operation *op); +std::string getOutputPortName(Operation *op, size_t portIdx); class ControlType; diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 1dfc21ba59..572939e10f 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -148,7 +148,7 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { //===----------------------------------------------------------------------===// // // To generate the netlist, we need to know the names of -// the operands (inputs) and results (output) +// the operands (inputs) and results (outputs) // for each operation. // // These are already named inside of the Tablegen, @@ -231,12 +231,12 @@ def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = - [{"Used by operations with unique names for their operands and results. T"}]; + [{"Used by operations with unique names for their operands and results."}]; let methods = [ InterfaceMethod< - "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx)>, + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx)>, InterfaceMethod< "Returns the name of a specific result.", "std::string", "getResultName", (ins "unsigned" : $idx) @@ -247,30 +247,33 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { //===----------------------------------------------------------------------===// // Number of RTL Ports //===----------------------------------------------------------------------===// - +// Operations may have more ports than operands and results +// For example, the EndOp and FuncOp both have +// the function results as additional ports +//===----------------------------------------------------------------------===// def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = - [{"The operands of this operation correspond directly to its input RTL ports."}]; + [{"The operands of this operation correspond directly to its input RTL ports."}]; let methods = [ - InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumInputPorts", (ins), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return concreteOp->getNumOperands(); - }]>, - InterfaceMethod< - "Returns the name of a specific input port.", - "std::string", "getInputPortName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return getOperandName(concreteOp, idx); - }]> - ]; + InterfaceMethod< + "Returns the number of RTL ports.", + "unsigned", "getNumInputPorts", (ins), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return concreteOp->getNumOperands(); + }]>, + InterfaceMethod< + "Returns the name of a specific input port.", + "std::string", "getInputPortName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return getOperandName(concreteOp, idx); + }]> + ]; } def CustomRTLInputPortsInterface : OpInterface<"CustomRTLInputPortsInterface"> { @@ -280,8 +283,8 @@ def CustomRTLInputPortsInterface : OpInterface<"CustomRTLInputPortsInterface"> { let methods = [ InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumInputPorts", (ins)>, + "Returns the number of RTL ports.", + "unsigned", "getNumInputPorts", (ins)>, InterfaceMethod< "Returns the name of a specific input port.", "std::string", "getInputPortName", (ins "unsigned" : $idx) @@ -294,23 +297,23 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt let description = [{"The results of this operation correspond directly to its output RTL ports."}]; let methods = [ - InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumOutputPorts", (ins), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return concreteOp->getNumResults(); - }]>, - InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getOutputPortName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return getResultName(concreteOp, idx); - }]> - ]; + InterfaceMethod< + "Returns the number of RTL ports.", + "unsigned", "getNumOutputPorts", (ins), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return concreteOp->getNumResults(); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getOutputPortName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + return getResultName(concreteOp, idx); + }]> + ]; } def CustomRTLOutputPortsInterface : OpInterface<"CustomRTLOutputPortsInterface"> { @@ -329,6 +332,9 @@ def CustomRTLOutputPortsInterface : OpInterface<"CustomRTLOutputPortsInterface"> ]; } +//===----------------------------------------------------------------------===// + + def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 4709a759bc..aa2a349954 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -54,7 +54,6 @@ class Handshake_Op traits = []> // This is almost exactly like a standard FuncOp, except that it has some // extra verification conditions. In particular, each Value must // only have a single use. Also, it defines a Dominance-Free Scope - def FuncOp : Op, + DeclareOpInterfaceMethods ]> { let summary = "module instantiate operation"; let description = [{ @@ -665,21 +664,22 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ `:` type($conditionOperand) `,` custom(type($dataOperand)) }]; - let extraClassDeclaration = [{ + // include validateIO functions from handshake op + let extraClassDeclaration = validateIO [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; /// Operand 0 is named condition /// Operand 1 is named data std::string getOperandName(unsigned idx) { - assert(idx < getOperation()->getNumOperands() && "index too high"); + validateOperandIdx(idx); return idx == 0 ? "condition" : "data"; } /// Operand 0 is named trueOut /// Operand 1 is named falseOut std::string getResultName(unsigned idx) { - assert(idx < getOperation()->getNumResults() && "index too high"); + validateResultIdx(idx); return idx == trueIndex ? "trueOut" : "falseOut"; } }]; @@ -898,8 +898,13 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ /// accesses that are connected to the memory controller. dynamatic::MCPorts getPorts(); + + //------------------------------------------- + // Custom IO Naming: + std::string getOperandName(unsigned idx); std::string getResultName(unsigned idx); + //------------------------------------------- }]; } @@ -998,8 +1003,12 @@ def LSQOp : Handshake_Op<"lsq", [ /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); + //------------------------------------------- + // Custom IO Naming: + std::string getOperandName(unsigned idx); std::string getResultName(unsigned idx); + //------------------------------------------- }]; } diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 2a38dd4b66..948699f38d 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -35,8 +35,6 @@ namespace handshake { // Operand and Result Names //===----------------------------------------------------------------------===// -/// Returns the name of an operand which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. std::string getOperandName(Operation *op, size_t oprdIdx) { if (auto nameInterface = dyn_cast(op)) { @@ -53,19 +51,17 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { assert(0); } -/// Returns the name of a result which is either provided by the -/// handshake::NamedIOInterface interface or, failing that, is its index. std::string getResultName(Operation *op, size_t resIdx) { - if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); - } + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + } op->emitError() << "must specify result names, op: " << *op; assert(0); @@ -127,21 +123,6 @@ std::string getOutputPortName(Operation *op, size_t portIdx) { } // namespace handshake } // namespace dynamatic -//===----------------------------------------------------------------------===// -// Operand and Result Names to Port Names -//===----------------------------------------------------------------------===// - -PortNamer::PortNamer(Operation *op) { - assert(op && "cannot generate port names for null operation"); - - for (size_t idx = 0, e = getNumInputPorts(op); idx < e; ++idx){ - inputs.push_back(getInputPortName(op, idx)); - } - - for (size_t idx = 0, e = getNumOutputPorts(op); idx < e; ++idx){ - outputs.push_back(getOutputPortName(op, idx)); - } -} //===----------------------------------------------------------------------===// // MemoryOpInterface From fe6e660b05bab105b8092c591b7ca0b76749ad56 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:14:32 +0200 Subject: [PATCH 100/187] remove port namer --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index aa2a349954..935698e73c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -665,7 +665,7 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ }]; // include validateIO functions from handshake op - let extraClassDeclaration = validateIO [{ + let extraClassDeclaration = validateIO # [{ // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; From 0370d0a178c88c29127900b21b3f2fb4110ab29d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:19:36 +0200 Subject: [PATCH 101/187] remove port namer --- experimental/lib/Support/FormalProperty.cpp | 14 ++++------- .../Dialect/Handshake/HandshakeInterfaces.h | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 388d4e3b35..2ce99d7ef4 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -128,9 +128,6 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, Operation *ownerOp = res.getOwner(); Operation *userOp = *res.getUsers().begin(); - handshake::PortNamer ownerNamer(ownerOp); - handshake::PortNamer userNamer(userOp); - unsigned long operandIndex = userOp->getNumOperands(); for (auto [j, arg] : llvm::enumerate(userOp->getOperands())) { if (arg == res) { @@ -144,9 +141,8 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; - ownerChannel.channelName = - ownerNamer.getOutputName(res.getResultNumber()).str(); - userChannel.channelName = userNamer.getInputName(operandIndex).str(); + ownerChannel.channelName = getOutputPortName(ownerOp, res.getResultNumber()); + userChannel.channelName = getInputPortName(userOp, operandIndex); } llvm::json::Value AbsenceOfBackpressure::extraInfoToJSON() const { @@ -184,18 +180,16 @@ ValidEquivalence::ValidEquivalence(unsigned long id, TAG tag, : FormalProperty(id, tag, TYPE::VEQ) { Operation *op1 = res1.getOwner(); unsigned int i = res1.getResultNumber(); - handshake::PortNamer namer1(op1); Operation *op2 = res2.getOwner(); unsigned int j = res2.getResultNumber(); - handshake::PortNamer namer2(op2); ownerChannel.operationName = getUniqueName(op1).str(); targetChannel.operationName = getUniqueName(op2).str(); ownerChannel.channelIndex = i; targetChannel.channelIndex = j; - ownerChannel.channelName = namer1.getOutputName(i).str(); - targetChannel.channelName = namer2.getOutputName(j).str(); + ownerChannel.channelName = getOutputPortName(op1, i); + targetChannel.channelName = getOutputPortName(op2, j); } llvm::json::Value ValidEquivalence::extraInfoToJSON() const { diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index dec2a94c97..6866c3ecb6 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -49,6 +49,30 @@ std::string getInputPortName(Operation *op, size_t portIdx); unsigned getNumOutputPorts(Operation *op); std::string getOutputPortName(Operation *op, size_t portIdx); +/// Provides an opaque interface for generating the port names of an operation; + +// class PortNamer { +// public: +// /// Does nothing; no port name will be generated. +// PortNamer() = default; + +// /// Derives port names for the operation on object creation. +// PortNamer(Operation *op); + +// /// Returs the port name of the input at the specified index. +// StringRef getInputName(unsigned idx) const { return inputs[idx]; } + +// /// Returs the port name of the output at the specified index. +// StringRef getOutputName(unsigned idx) const { return outputs[idx]; } + +// private: + +// /// List of input port names. +// SmallVector inputs; +// /// List of output port names. +// SmallVector outputs; +// }; + class ControlType; namespace detail { From 0a0dff66a15772bad0289da50013de0681577b96 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:20:21 +0200 Subject: [PATCH 102/187] remove port namer --- experimental/lib/Support/FormalProperty.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 2ce99d7ef4..e5c7d665d1 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -20,6 +20,8 @@ namespace dynamatic { +using handshake; + std::optional FormalProperty::typeFromStr(const std::string &s) { From d75b2a5ee34ce4b5ce83caacacd96b9a2554eac2 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:21:56 +0200 Subject: [PATCH 103/187] remove port namer --- experimental/lib/Support/FormalProperty.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index e5c7d665d1..3cdbe23e80 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -20,7 +20,7 @@ namespace dynamatic { -using handshake; +using namespace handshake; std::optional FormalProperty::typeFromStr(const std::string &s) { From d2a455122115085de93e618c76fa68d7429c57e7 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:26:56 +0200 Subject: [PATCH 104/187] remove port namer --- .../HandshakeToHW/HandshakeToHW.cpp | 39 ++++++++----------- 1 file changed, 17 insertions(+), 22 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 030fa1410b..ec96b55202 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -167,9 +167,7 @@ struct MemLoweringState { /// Cache memory port information before modifying the interface, which can /// make them impossible to query. FuncMemoryPorts ports; - /// Generates and stores the interface's port names before starting the - /// conversion, when those are still queryable. - handshake::PortNamer portNames; + /// Backedges to the containing module's `hw::OutputOp` operation, which /// must be set, in order, with the memory interface's results that connect /// to the top-level module IO. @@ -186,7 +184,7 @@ struct MemLoweringState { /// Needed because we use the class as a value type in a map, which needs to /// be default-constructible. - MemLoweringState() : ports(nullptr), portNames(nullptr) { + MemLoweringState() : ports(nullptr), { llvm_unreachable("object should never be default-constructed"); } @@ -194,7 +192,7 @@ struct MemLoweringState { MemLoweringState(handshake::MemoryOpInterface memOp, const Twine &name) : name(name.str()), dataType(lowerType(memOp.getMemRefType().getElementType())), - ports(getMemoryPorts(memOp)), portNames(memOp) { + ports(getMemoryPorts(memOp)) { assert(dataType && "unsupported memory element type"); }; @@ -221,20 +219,18 @@ struct InternalMemLoweringState { handshake::MemoryOpInterface memInterface; FuncMemoryPorts ports; - handshake::PortNamer portNames; /// Needed because we use the class as a value type in a map, which needs to /// be default-constructible. InternalMemLoweringState() - : ramOp(nullptr), memInterface(nullptr), ports(nullptr), - portNames(nullptr) { + : ramOp(nullptr), memInterface(nullptr), ports(nullptr) { llvm_unreachable("object should never be default-constructed"); } InternalMemLoweringState(handshake::RAMOp ramOp, handshake::MemoryOpInterface memInterface) : ramOp(ramOp), memInterface(memInterface), - ports(getMemoryPorts(memInterface)), portNames(memInterface) {}; + ports(getMemoryPorts(memInterface)) {}; }; /// Summarizes information to convert a Handshake function into a @@ -1141,11 +1137,12 @@ static void addMemIO(ModuleBuilder &modBuilder, handshake::FuncOp funcOp, hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, ModuleLoweringState &state) { ModuleBuilder modBuilder(funcOp.getContext()); - handshake::PortNamer portNames(funcOp); // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(portNames.getOutputName(idx), lowerType(res)); + modBuilder.addOutput(handshake::getOutputPortName(funcOp, idx), lowerType(res)); + + // Add all function inputs to the module, expanding memory references into a // set of individual ports for loads and stores @@ -1155,7 +1152,7 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, if (TypedValue memref = dyn_cast>(arg)) addMemIO(modBuilder, funcOp, memref, argName, state); else - modBuilder.addInput(portNames.getInputName(idx), lowerType(type)); + modBuilder.addInput(handshake::getInputPortName(funcOp, idx), lowerType(type)); } modBuilder.addClkAndRst(); @@ -1307,11 +1304,10 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( StringAttr name = rewriter.getStringAttr(funcOp.getName()); ModuleBuilder modBuilder(funcOp.getContext()); - handshake::PortNamer portNames(funcOp); // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(portNames.getOutputName(idx), lowerType(res)); + modBuilder.addOutput(handshake::getOutputPortName(funcOp, idx), lowerType(res)); // Add all function inputs to the module for (auto [idx, type] : llvm::enumerate(funcOp.getArgumentTypes())) { @@ -1320,7 +1316,7 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( << "Memory interfaces are not supported for external " "functions"; } - modBuilder.addInput(portNames.getInputName(idx), lowerType(type)); + modBuilder.addInput(handshake::getInputPortName(funcOp, idx), lowerType(type)); } modBuilder.addClkAndRst(); @@ -1397,14 +1393,14 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - converter.addInput(memState.portNames.getInputName(idx), oprd); + converter.addInput(handshake::getInputPortName(memOp, idx), oprd); } converter.addClkAndRst(parentModOp); // The HW instance will be connected to the top-level module through a // number of output ports, add those last after the regular interface ports for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - converter.addOutput(memState.portNames.getOutputName(idx), + converter.addOutput(handshake::getOutputPortName(funcOp, idx), lowerType(res.getType())); } auto outputModPorts = memState.getMemOutputPorts(parentModOp); @@ -1526,12 +1522,12 @@ LogicalResult ConvertMemInterfaceForInternalArray::matchAndRewrite( // type. for (auto [i, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - memInterfaceConverter.addInput(memState.portNames.getInputName(i), oprd); + memInterfaceConverter.addInput(handshake::getInputPortName(memOp, i), oprd); } memInterfaceConverter.addClkAndRst(parentModOp); for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - memInterfaceConverter.addOutput(memState.portNames.getOutputName(idx), + memInterfaceConverter.addOutput(handshake::getOutputPortName(memOp, idx), lowerType(res.getType())); } @@ -1579,16 +1575,15 @@ template LogicalResult ConvertToHWInstance::matchAndRewrite( T op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const { HWConverter converter(this->getContext()); - handshake::PortNamer portNames(op); // Add all operation operands to the inputs for (auto [idx, oprd] : llvm::enumerate(adaptor.getOperands())) - converter.addInput(portNames.getInputName(idx), oprd); + converter.addInput(handshake::getInputPortName(op, idx), oprd); converter.addClkAndRst(((Operation *)op)->getParentOfType()); // Add all operation results to the outputs for (auto [idx, type] : llvm::enumerate(op->getResultTypes())) - converter.addOutput(portNames.getOutputName(idx), lowerType(type)); + converter.addOutput(handshake::getOutputPortName(op, idx), lowerType(type)); hw::InstanceOp instOp = converter.convertToInstance(op, rewriter); return instOp ? success() : failure(); From ac34325e3b40d1890c6a1ac89efe8123117f1bd1 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 16:28:02 +0200 Subject: [PATCH 105/187] remove port namer --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index ec96b55202..f1f26b7d82 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -184,7 +184,7 @@ struct MemLoweringState { /// Needed because we use the class as a value type in a map, which needs to /// be default-constructible. - MemLoweringState() : ports(nullptr), { + MemLoweringState() : ports(nullptr) { llvm_unreachable("object should never be default-constructed"); } @@ -1400,7 +1400,7 @@ LogicalResult ConvertMemInterface::matchAndRewrite( // The HW instance will be connected to the top-level module through a // number of output ports, add those last after the regular interface ports for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - converter.addOutput(handshake::getOutputPortName(funcOp, idx), + converter.addOutput(handshake::getOutputPortName(memOp, idx), lowerType(res.getType())); } auto outputModPorts = memState.getMemOutputPorts(parentModOp); From 0f1f74eb6f4d9e601ac0e30845872cc1a3fbb34f Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:12:46 +0200 Subject: [PATCH 106/187] remove port namer --- .../Dialect/Handshake/HandshakeInterfaces.h | 29 +++---------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 6866c3ecb6..2ab0b86506 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -43,35 +43,14 @@ std::string getOperandName(Operation *op, size_t oprdIdx); /// based on which interface the operation implements std::string getResultName(Operation *op, size_t resIdx); -unsigned getNumInputPorts(Operation *op); +/// Returns the name of a input RTL port +/// based on which interface the operation implements std::string getInputPortName(Operation *op, size_t portIdx); -unsigned getNumOutputPorts(Operation *op); +/// Returns the name of an output RTL port +/// based on which interface the operation implements std::string getOutputPortName(Operation *op, size_t portIdx); -/// Provides an opaque interface for generating the port names of an operation; - -// class PortNamer { -// public: -// /// Does nothing; no port name will be generated. -// PortNamer() = default; - -// /// Derives port names for the operation on object creation. -// PortNamer(Operation *op); - -// /// Returs the port name of the input at the specified index. -// StringRef getInputName(unsigned idx) const { return inputs[idx]; } - -// /// Returs the port name of the output at the specified index. -// StringRef getOutputName(unsigned idx) const { return outputs[idx]; } - -// private: - -// /// List of input port names. -// SmallVector inputs; -// /// List of output port names. -// SmallVector outputs; -// }; class ControlType; From e59c39c650729e8bc8bfd57604b83ee6267f2356 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:19:29 +0200 Subject: [PATCH 107/187] comments --- .../Dialect/Handshake/HandshakeOps.td | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 935698e73c..ac6326e3de 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1480,6 +1480,9 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ AllTypesMatch<["dataIn", "dataOut"]>, IsSimpleHandshake<"ctrl">, IsIntSizedChannel<3, "ctrl">, + // The IOs of a SpecSaveCommitOp have custom names, + // defined here in the Tablegen + // as part of the SpecCommitOp declaration CustomNamedIOInterface ]> { let summary = "Lets all tokens pass and saves a copy of them."; @@ -1505,11 +1508,15 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + + /// Operand 0 is named ins + /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } + /// Result 0 is named result std::string getResultName(unsigned idx) { validateResultIdx(idx); return "outs"; @@ -1524,6 +1531,9 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ HasValidSpecTag<"dataOperand">, LacksSpecTag<"trueResult">, LacksSpecTag<"falseResult">, + // The IOs of a SpeculatingBranchOp have custom names, + // defined here in the Tablegen + // as part of the SpeculatingBranchOp declaration CustomNamedIOInterface ]> { let summary = "speculating branch operation"; @@ -1555,11 +1565,15 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + /// Operand 0 is named spec_tag_data + /// Operand 1 is named data std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "spec_tag_data" : "data"; } + /// Result 0 is named trueOut + /// Result 1 is named falseOut std::string getResultName(unsigned idx) { validateResultIdx(idx); return idx == 0 ? "trueOut" : "falseOut"; @@ -1572,6 +1586,9 @@ def NonSpecOp : Handshake_Op<"non_spec", [ AllExtraSignalsMatchExcept<"spec", ["dataIn", "dataOut"]>, LacksSpecTag<"dataIn">, HasValidSpecTag<"dataOut">, + // The IOs of a NonSpecOp have custom names, + // defined here in the Tablegen + // as part of the NonSpecOp declaration CustomNamedIOInterface ]> { let summary = "Adds a non-speculative spec bit."; @@ -1597,11 +1614,13 @@ def NonSpecOp : Handshake_Op<"non_spec", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + /// Operand 0 is named dataIn std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return "dataIn"; } + /// Result 0 is named dataOut std::string getResultName(unsigned idx) { validateResultIdx(idx); return "dataOut"; @@ -1615,6 +1634,9 @@ def NonSpecOp : Handshake_Op<"non_spec", [ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ SameOperandsAndResultType, + // The IOs of a SharingWrapperOp have custom names, + // defined here in the Tablegen + // as part of the SharingWrapperOp declaration CustomNamedIOInterface, ]> { @@ -1662,6 +1684,8 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + /// The first set of operands are named op__in_ + /// The last operand is named fromSharedUnitOut0 std::string getOperandName(unsigned idx) { validateOperandIdx(idx); if (idx < getNumSharedOperands() * getNumSharedOperations()) { @@ -1671,6 +1695,8 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ return "fromSharedUnitOut0"; } + /// The first set of results are named op__out_0 + /// The last set of results are named toSharedUnitIn_ std::string getResultName(unsigned idx) { validateResultIdx(idx); if (idx < getNumSharedOperations()) @@ -1815,7 +1841,8 @@ def UnbundleOp : Handshake_Op<"unbundle", [ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ SameOperandsAndResultType, - CustomNamedIOInterface + // The IOs of a ReadyRemoverOp have simple names + SimpleNamedIOInterface ]> { let summary = [{ Rigidifies a channel to simplify the handshake logic. @@ -1832,24 +1859,14 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ $channelIn attr-dict `:` custom(type($channelIn)) }]; - // include validateIO functions from handshake op - let extraClassDeclaration = validateIO # [{ - std::string getOperandName(unsigned idx){ - validateOperandIdx(idx); - return "ins"; - } - - std::string getResultName(unsigned idx) { - validateResultIdx(idx); - return "outs"; - } - }]; - } def ValidMergerOp : Handshake_Op<"valid_merger",[ AllTypesMatch<["lhsIn", "lhs"]>, AllTypesMatch<["rhsIn", "rhs"]>, + // The IOs of a ValidMergerOp have custom names, + // defined here in the Tablegen + // as part of the ValidMergerOp declaration CustomNamedIOInterface ]> { let summary = [{ @@ -1870,11 +1887,15 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + /// Operand 0 is named lhs_ins + /// Operand 1 is named rhs_ins std::string getOperandName(unsigned idx) { validateOperandIdx(idx); return (idx == 0) ? "lhs_ins" : "rhs_ins"; } + /// Result 0 is named lhs_outs + /// Result 1 is named rhs_outs std::string getResultName(unsigned idx) { validateResultIdx(idx); return (idx == 0) ? "lhs_outs" : "rhs_outs"; From d50a1b4d848c1fb674a937081823153eea19c983 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:23:11 +0200 Subject: [PATCH 108/187] need num ports? --- .../Dialect/Handshake/HandshakeInterfaces.td | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 572939e10f..6dfc98ef97 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -257,14 +257,14 @@ def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInt let description = [{"The operands of this operation correspond directly to its input RTL ports."}]; let methods = [ - InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumInputPorts", (ins), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return concreteOp->getNumOperands(); - }]>, + // InterfaceMethod< + // "Returns the number of RTL ports.", + // "unsigned", "getNumInputPorts", (ins), + // "", + // [{ + // ConcreteOp concreteOp = mlir::cast($_op); + // return concreteOp->getNumOperands(); + // }]>, InterfaceMethod< "Returns the name of a specific input port.", "std::string", "getInputPortName", (ins "unsigned" : $idx), @@ -297,14 +297,14 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt let description = [{"The results of this operation correspond directly to its output RTL ports."}]; let methods = [ - InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumOutputPorts", (ins), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return concreteOp->getNumResults(); - }]>, + // InterfaceMethod< + // "Returns the number of RTL ports.", + // "unsigned", "getNumOutputPorts", (ins), + // "", + // [{ + // ConcreteOp concreteOp = mlir::cast($_op); + // return concreteOp->getNumResults(); + // }]>, InterfaceMethod< "Returns the name of a specific result.", "std::string", "getOutputPortName", (ins "unsigned" : $idx), From 63958ab8eaf3868c434a85da06628378cfef95fc Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:24:10 +0200 Subject: [PATCH 109/187] need num ports? --- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 948699f38d..9010d19055 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -67,18 +67,18 @@ std::string getResultName(Operation *op, size_t resIdx) { assert(0); } -unsigned getNumInputPorts(Operation *op) { - if(auto operandPortsInterface = - dyn_cast(op)){ - return operandPortsInterface.getNumInputPorts(); - } else if (auto customPortsInterface = - dyn_cast(op)){ - return customPortsInterface.getNumInputPorts(); - } - - op->emitError("All operations must specify input ports"); - assert(0); -} +// unsigned getNumInputPorts(Operation *op) { +// if(auto operandPortsInterface = +// dyn_cast(op)){ +// return operandPortsInterface.getNumInputPorts(); +// } else if (auto customPortsInterface = +// dyn_cast(op)){ +// return customPortsInterface.getNumInputPorts(); +// } + +// op->emitError("All operations must specify input ports"); +// assert(0); +// } std::string getInputPortName(Operation *op, size_t portIdx) { if(auto operandPortsInterface = @@ -93,18 +93,18 @@ std::string getInputPortName(Operation *op, size_t portIdx) { assert(0); } -unsigned getNumOutputPorts(Operation *op) { - if(auto resultsPortsInterface = - dyn_cast(op)){ - return resultsPortsInterface.getNumOutputPorts(); - } else if (auto customPortsInterface = - dyn_cast(op)){ - return customPortsInterface.getNumOutputPorts(); - } - - op->emitError("All operations must specify output ports"); - assert(0); -} +// unsigned getNumOutputPorts(Operation *op) { +// if(auto resultsPortsInterface = +// dyn_cast(op)){ +// return resultsPortsInterface.getNumOutputPorts(); +// } else if (auto customPortsInterface = +// dyn_cast(op)){ +// return customPortsInterface.getNumOutputPorts(); +// } + +// op->emitError("All operations must specify output ports"); +// assert(0); +// } std::string getOutputPortName(Operation *op, size_t portIdx) { if(auto resultsPortsInterface = From 52368362f4d4756ce0b5cd4aa748310a0375b19a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:28:34 +0200 Subject: [PATCH 110/187] need num ports? --- .../Dialect/Handshake/HandshakeInterfaces.h | 1 - .../Dialect/Handshake/HandshakeInterfaces.td | 22 ---------------- .../Dialect/Handshake/HandshakeOps.td | 5 +--- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 26 ------------------- lib/Dialect/Handshake/HandshakeOps.cpp | 6 ----- 5 files changed, 1 insertion(+), 59 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 2ab0b86506..3faad81aed 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -38,7 +38,6 @@ class FuncOp; /// based on which interface the operation implements std::string getOperandName(Operation *op, size_t oprdIdx); - /// Returns the name of a result /// based on which interface the operation implements std::string getResultName(Operation *op, size_t resIdx); diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 6dfc98ef97..689996fbf5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -257,14 +257,6 @@ def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInt let description = [{"The operands of this operation correspond directly to its input RTL ports."}]; let methods = [ - // InterfaceMethod< - // "Returns the number of RTL ports.", - // "unsigned", "getNumInputPorts", (ins), - // "", - // [{ - // ConcreteOp concreteOp = mlir::cast($_op); - // return concreteOp->getNumOperands(); - // }]>, InterfaceMethod< "Returns the name of a specific input port.", "std::string", "getInputPortName", (ins "unsigned" : $idx), @@ -282,9 +274,6 @@ def CustomRTLInputPortsInterface : OpInterface<"CustomRTLInputPortsInterface"> { [{"The input RTL ports of this operation do not correspond to its operands"}]; let methods = [ - InterfaceMethod< - "Returns the number of RTL ports.", - "unsigned", "getNumInputPorts", (ins)>, InterfaceMethod< "Returns the name of a specific input port.", "std::string", "getInputPortName", (ins "unsigned" : $idx) @@ -297,14 +286,6 @@ def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInt let description = [{"The results of this operation correspond directly to its output RTL ports."}]; let methods = [ - // InterfaceMethod< - // "Returns the number of RTL ports.", - // "unsigned", "getNumOutputPorts", (ins), - // "", - // [{ - // ConcreteOp concreteOp = mlir::cast($_op); - // return concreteOp->getNumResults(); - // }]>, InterfaceMethod< "Returns the name of a specific result.", "std::string", "getOutputPortName", (ins "unsigned" : $idx), @@ -322,9 +303,6 @@ def CustomRTLOutputPortsInterface : OpInterface<"CustomRTLOutputPortsInterface"> [{"The output RTL ports of this operation do not correspond to its results"}]; let methods = [ - InterfaceMethod< - "Returns the number of output RTL ports.", - "unsigned", "getNumOutputPorts", (ins)>, InterfaceMethod< "Returns the name of a specific output port.", "std::string", "getOutputPortName", (ins "unsigned" : $idx) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index ac6326e3de..2df41b26e2 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -179,7 +179,7 @@ def FuncOp : Op:$inputs); let extraClassDeclaration = [{ - /// Output ports of EndOp are function results - unsigned getNumOutputPorts(); - /// Output ports of EndOp are function results std::string getOutputPortName(unsigned idx); }]; diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 9010d19055..209259bc78 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -67,19 +67,6 @@ std::string getResultName(Operation *op, size_t resIdx) { assert(0); } -// unsigned getNumInputPorts(Operation *op) { -// if(auto operandPortsInterface = -// dyn_cast(op)){ -// return operandPortsInterface.getNumInputPorts(); -// } else if (auto customPortsInterface = -// dyn_cast(op)){ -// return customPortsInterface.getNumInputPorts(); -// } - -// op->emitError("All operations must specify input ports"); -// assert(0); -// } - std::string getInputPortName(Operation *op, size_t portIdx) { if(auto operandPortsInterface = dyn_cast(op)){ @@ -93,19 +80,6 @@ std::string getInputPortName(Operation *op, size_t portIdx) { assert(0); } -// unsigned getNumOutputPorts(Operation *op) { -// if(auto resultsPortsInterface = -// dyn_cast(op)){ -// return resultsPortsInterface.getNumOutputPorts(); -// } else if (auto customPortsInterface = -// dyn_cast(op)){ -// return customPortsInterface.getNumOutputPorts(); -// } - -// op->emitError("All operations must specify output ports"); -// assert(0); -// } - std::string getOutputPortName(Operation *op, size_t portIdx) { if(auto resultsPortsInterface = dyn_cast(op)){ diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index e25c620d0e..6fdc4abd6c 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1549,12 +1549,6 @@ LogicalResult EndOp::verify() { return success(); } -unsigned EndOp::getNumOutputPorts(){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getNumOutputPorts(); -} - std::string EndOp::getOutputPortName(unsigned idx){ handshake::FuncOp funcOp = (*this)->getParentOfType(); assert(funcOp && "end must be child of handshake function"); From 00c887fad351d0d6b25e429cd578b4286365b192 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:30:46 +0200 Subject: [PATCH 111/187] need num ports? --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 2df41b26e2..21eedbcf13 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1228,7 +1228,8 @@ def EndOp : Op { let summary = "function endpoint (dynamatic)"; let description = [{ @@ -1244,10 +1245,10 @@ def EndOp : Op:$inputs); - let extraClassDeclaration = [{ - /// Output ports of EndOp are function results - std::string getOutputPortName(unsigned idx); - }]; + // let extraClassDeclaration = [{ + // /// Output ports of EndOp are function results + // std::string getOutputPortName(unsigned idx); + // }]; let assemblyFormat = [{ attr-dict ($inputs^ `:` custom(type($inputs)))? From 043761e4c8c139a457935fe8c2d75a9b28f53ced Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:31:12 +0200 Subject: [PATCH 112/187] need num ports? --- lib/Dialect/Handshake/HandshakeOps.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 6fdc4abd6c..dba0e1815d 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1549,11 +1549,11 @@ LogicalResult EndOp::verify() { return success(); } -std::string EndOp::getOutputPortName(unsigned idx){ - handshake::FuncOp funcOp = (*this)->getParentOfType(); - assert(funcOp && "end must be child of handshake function"); - return funcOp.getOutputPortName(idx); -} +// std::string EndOp::getOutputPortName(unsigned idx){ +// handshake::FuncOp funcOp = (*this)->getParentOfType(); +// assert(funcOp && "end must be child of handshake function"); +// return funcOp.getOutputPortName(idx); +// } //===----------------------------------------------------------------------===// From 8dd2a0e193bc69151dea8e3eb5157ff6f5bba13a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:47:25 +0200 Subject: [PATCH 113/187] no port names --- .../Dialect/Handshake/HandshakeInterfaces.h | 9 -- .../Dialect/Handshake/HandshakeOps.td | 95 ++++++++----------- .../HandshakeToHW/HandshakeToHW.cpp | 27 +++--- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 26 ----- lib/Dialect/Handshake/HandshakeOps.cpp | 6 -- 5 files changed, 55 insertions(+), 108 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 3faad81aed..72210e3a41 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -42,15 +42,6 @@ std::string getOperandName(Operation *op, size_t oprdIdx); /// based on which interface the operation implements std::string getResultName(Operation *op, size_t resIdx); -/// Returns the name of a input RTL port -/// based on which interface the operation implements -std::string getInputPortName(Operation *op, size_t portIdx); - -/// Returns the name of an output RTL port -/// based on which interface the operation implements -std::string getOutputPortName(Operation *op, size_t portIdx); - - class ControlType; namespace detail { diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 21eedbcf13..ee8935b21d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -32,12 +32,7 @@ class Handshake_Op traits = []> : Op, DeclareOpInterfaceMethods, - // To inherit from HandshakeOp, - // an operations connections must match its - // RTL connections - InputRTLPortsAreOperandsInterface, - OutputRTLPortsAreResultsInterface - ]> { +]> { // Shared functions to include in child classes string validateIO = [{ void validateOperandIdx(unsigned int idx){ @@ -61,9 +56,7 @@ def FuncOp : Op { let summary = "Handshake dialect function."; let description = [{ @@ -148,14 +141,14 @@ def FuncOp : Op" + /// simpleOperandName handles validation + std::string getOperandName(unsigned idx) { + assert(idx < getNumInputPorts() && "index too high"); return getResName(idx).str(); } + + /// Result 0 is named outs + /// Result 1 is named index + std::string getResultName(unsigned idx) { + validateResultIdx(idx); + return idx == 0 ? "outs" : "index"; + } }]; let hasVerifier = 1; @@ -1211,25 +1218,10 @@ def RAMOp : Handshake_Op<"ram", []> { // Terminator //===----------------------------------------------------------------------===// -// Not a handshake op, as its RTL ports do not correspond to -// its operands and results -def EndOp : Op, - DeclareOpInterfaceMethods, - // The IOs of a EndOp have simple names - SimpleNamedIOInterface, - // The RTL input ports correspond to the IR - InputRTLPortsAreOperandsInterface, - // The RTL output ports do not correspond to the IR - // As they are actually the function results - // Although they could normally be in the class declaration - // The header file is organized alphabetically - // with EndOp before FuncOp - // and so the the RTL output port functions are defined in - // HandshakeOps.cpp - // CustomRTLOutputPortsInterface - OutputRTLPortsAreResultsInterface + // The IOs of an EndOp have simple names + SimpleNamedIOInterface ]> { let summary = "function endpoint (dynamatic)"; let description = [{ @@ -1245,11 +1237,6 @@ def EndOp : Op:$inputs); - // let extraClassDeclaration = [{ - // /// Output ports of EndOp are function results - // std::string getOutputPortName(unsigned idx); - // }]; - let assemblyFormat = [{ attr-dict ($inputs^ `:` custom(type($inputs)))? }]; diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index f1f26b7d82..44b0048fa9 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1139,9 +1139,10 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, ModuleBuilder modBuilder(funcOp.getContext()); // Add all function outputs to the module - for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(handshake::getOutputPortName(funcOp, idx), lowerType(res)); - + for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())){ + StringAttr resName = funcOp.getResName(idx); + modBuilder.addOutput(resName, lowerType(res)); + } // Add all function inputs to the module, expanding memory references into a @@ -1152,7 +1153,7 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, if (TypedValue memref = dyn_cast>(arg)) addMemIO(modBuilder, funcOp, memref, argName, state); else - modBuilder.addInput(handshake::getInputPortName(funcOp, idx), lowerType(type)); + modBuilder.addInput(argName, lowerType(type)); } modBuilder.addClkAndRst(); @@ -1307,7 +1308,7 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(handshake::getOutputPortName(funcOp, idx), lowerType(res)); + modBuilder.addOutput(funcOp.getResName(idx), lowerType(res)); // Add all function inputs to the module for (auto [idx, type] : llvm::enumerate(funcOp.getArgumentTypes())) { @@ -1316,7 +1317,7 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( << "Memory interfaces are not supported for external " "functions"; } - modBuilder.addInput(handshake::getInputPortName(funcOp, idx), lowerType(type)); + modBuilder.addInput(funcOp.getArgName(idx), lowerType(type)); } modBuilder.addClkAndRst(); @@ -1393,15 +1394,15 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - converter.addInput(handshake::getInputPortName(memOp, idx), oprd); + converter.addInput(handshake::getOperandName(memOp, idx), oprd); } converter.addClkAndRst(parentModOp); // The HW instance will be connected to the top-level module through a // number of output ports, add those last after the regular interface ports for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - converter.addOutput(handshake::getOutputPortName(memOp, idx), - lowerType(res.getType())); + converter.addOutput(handshake::getResultName(memOp, idx), + lowerType(res.getType()));; } auto outputModPorts = memState.getMemOutputPorts(parentModOp); for (const hw::ModulePort &outputPort : outputModPorts) @@ -1522,12 +1523,12 @@ LogicalResult ConvertMemInterfaceForInternalArray::matchAndRewrite( // type. for (auto [i, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - memInterfaceConverter.addInput(handshake::getInputPortName(memOp, i), oprd); + memInterfaceConverter.addInput(handshake::getOperandName(memOp, i), oprd); } memInterfaceConverter.addClkAndRst(parentModOp); for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - memInterfaceConverter.addOutput(handshake::getOutputPortName(memOp, idx), + memInterfaceConverter.addOutput(handshake::getResultName(memOp, idx), lowerType(res.getType())); } @@ -1578,12 +1579,12 @@ LogicalResult ConvertToHWInstance::matchAndRewrite( // Add all operation operands to the inputs for (auto [idx, oprd] : llvm::enumerate(adaptor.getOperands())) - converter.addInput(handshake::getInputPortName(op, idx), oprd); + converter.addInput(handshake::getOperandName(op, idx), oprd); converter.addClkAndRst(((Operation *)op)->getParentOfType()); // Add all operation results to the outputs for (auto [idx, type] : llvm::enumerate(op->getResultTypes())) - converter.addOutput(handshake::getOutputPortName(op, idx), lowerType(type)); + converter.addOutput(handshake::getResultsName(op, idx), lowerType(type)); hw::InstanceOp instOp = converter.convertToInstance(op, rewriter); return instOp ? success() : failure(); diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 209259bc78..ad7f9bfc50 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -67,32 +67,6 @@ std::string getResultName(Operation *op, size_t resIdx) { assert(0); } -std::string getInputPortName(Operation *op, size_t portIdx) { - if(auto operandPortsInterface = - dyn_cast(op)){ - return operandPortsInterface.getInputPortName(portIdx); - } else if (auto customPortsInterface = - dyn_cast(op)){ - return customPortsInterface.getInputPortName(portIdx); - } - - op->emitError("All operations must specify input ports"); - assert(0); -} - -std::string getOutputPortName(Operation *op, size_t portIdx) { - if(auto resultsPortsInterface = - dyn_cast(op)){ - return resultsPortsInterface.getOutputPortName(portIdx); - } else if (auto customPortsInterface = - dyn_cast(op)){ - return customPortsInterface.getOutputPortName(portIdx); - } - - op->emitError("All operations must specify output ports"); - assert(0); -} - } // namespace handshake } // namespace dynamatic diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index dba0e1815d..257e506c45 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1549,12 +1549,6 @@ LogicalResult EndOp::verify() { return success(); } -// std::string EndOp::getOutputPortName(unsigned idx){ -// handshake::FuncOp funcOp = (*this)->getParentOfType(); -// assert(funcOp && "end must be child of handshake function"); -// return funcOp.getOutputPortName(idx); -// } - //===----------------------------------------------------------------------===// // BundleOp From 158a8d7356e3103438be49a2a328a248dab05a61 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:49:38 +0200 Subject: [PATCH 114/187] no port names --- .../Dialect/Handshake/HandshakeOps.td | 41 +++---------------- 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index ee8935b21d..c88a61eadf 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -141,49 +141,19 @@ def FuncOp : Op" /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { @@ -191,11 +161,10 @@ def FuncOp : Op Date: Tue, 14 Oct 2025 17:50:46 +0200 Subject: [PATCH 115/187] no port names --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index c88a61eadf..9d898933c2 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -146,6 +146,7 @@ def FuncOp : Op" /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { From 47a8ba2fb03b23177a7ee7abc594bcb0712afcb3 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:51:57 +0200 Subject: [PATCH 116/187] no port names --- experimental/lib/Support/FormalProperty.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 3cdbe23e80..69f50c50bc 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -143,8 +143,8 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; - ownerChannel.channelName = getOutputPortName(ownerOp, res.getResultNumber()); - userChannel.channelName = getInputPortName(userOp, operandIndex); + ownerChannel.channelName = getResultName(ownerOp, res.getResultNumber()); + userChannel.channelName = getOperandName(userOp, operandIndex); } llvm::json::Value AbsenceOfBackpressure::extraInfoToJSON() const { @@ -190,8 +190,8 @@ ValidEquivalence::ValidEquivalence(unsigned long id, TAG tag, targetChannel.operationName = getUniqueName(op2).str(); ownerChannel.channelIndex = i; targetChannel.channelIndex = j; - ownerChannel.channelName = getOutputPortName(op1, i); - targetChannel.channelName = getOutputPortName(op2, j); + ownerChannel.channelName = getResultName(op1, i); + targetChannel.channelName = getResultName(op2, j); } llvm::json::Value ValidEquivalence::extraInfoToJSON() const { From 7119bfe11960f4bee181f54ce718d8172b8dd66d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:53:30 +0200 Subject: [PATCH 117/187] no port names --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 44b0048fa9..2cf45420c4 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1141,7 +1141,7 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())){ StringAttr resName = funcOp.getResName(idx); - modBuilder.addOutput(resName, lowerType(res)); + modBuilder.addOutput(resName.getValue(), lowerType(res)); } @@ -1153,7 +1153,7 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, if (TypedValue memref = dyn_cast>(arg)) addMemIO(modBuilder, funcOp, memref, argName, state); else - modBuilder.addInput(argName, lowerType(type)); + modBuilder.addInput(argName.getValue(), lowerType(type)); } modBuilder.addClkAndRst(); @@ -1308,7 +1308,7 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(funcOp.getResName(idx), lowerType(res)); + modBuilder.addOutput(funcOp.getResName(idx).getValue(), lowerType(res)); // Add all function inputs to the module for (auto [idx, type] : llvm::enumerate(funcOp.getArgumentTypes())) { @@ -1317,7 +1317,7 @@ LogicalResult ConvertExternalFunc::matchAndRewrite( << "Memory interfaces are not supported for external " "functions"; } - modBuilder.addInput(funcOp.getArgName(idx), lowerType(type)); + modBuilder.addInput(funcOp.getArgName(idx).getValue(), lowerType(type)); } modBuilder.addClkAndRst(); From 663b6403fad528049e6dfea23fd782be9dda1610 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:54:11 +0200 Subject: [PATCH 118/187] no port names --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 2cf45420c4..db50a15b1a 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1584,7 +1584,7 @@ LogicalResult ConvertToHWInstance::matchAndRewrite( // Add all operation results to the outputs for (auto [idx, type] : llvm::enumerate(op->getResultTypes())) - converter.addOutput(handshake::getResultsName(op, idx), lowerType(type)); + converter.addOutput(handshake::getResultName(op, idx), lowerType(type)); hw::InstanceOp instOp = converter.convertToInstance(op, rewriter); return instOp ? success() : failure(); From 26e6517ca82ca4fbf6c5a513829db8df0fe8fb97 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:55:25 +0200 Subject: [PATCH 119/187] no port names --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index db50a15b1a..92229ed878 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1139,10 +1139,9 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, ModuleBuilder modBuilder(funcOp.getContext()); // Add all function outputs to the module - for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())){ - StringAttr resName = funcOp.getResName(idx); - modBuilder.addOutput(resName.getValue(), lowerType(res)); - } + for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) + modBuilder.addOutput(funcOp.getResName(idx);.getValue(), lowerType(res)); + // Add all function inputs to the module, expanding memory references into a From 72b7a811e96e96394036c90e2dc99dcb60952233 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:56:12 +0200 Subject: [PATCH 120/187] no port names --- experimental/lib/Support/FormalProperty.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 69f50c50bc..aaadc7d5e7 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -20,8 +20,6 @@ namespace dynamatic { -using namespace handshake; - std::optional FormalProperty::typeFromStr(const std::string &s) { @@ -143,8 +141,8 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; - ownerChannel.channelName = getResultName(ownerOp, res.getResultNumber()); - userChannel.channelName = getOperandName(userOp, operandIndex); + ownerChannel.channelName = handshake::getResultName(ownerOp, res.getResultNumber()); + userChannel.channelName = handshake::getOperandName(userOp, operandIndex); } llvm::json::Value AbsenceOfBackpressure::extraInfoToJSON() const { @@ -190,8 +188,8 @@ ValidEquivalence::ValidEquivalence(unsigned long id, TAG tag, targetChannel.operationName = getUniqueName(op2).str(); ownerChannel.channelIndex = i; targetChannel.channelIndex = j; - ownerChannel.channelName = getResultName(op1, i); - targetChannel.channelName = getResultName(op2, j); + ownerChannel.channelName = handshake::getResultName(op1, i); + targetChannel.channelName = handshake::getResultName(op2, j); } llvm::json::Value ValidEquivalence::extraInfoToJSON() const { From f5c16ac9cd3ef36277d3e05cf821a384b6350007 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 17:58:06 +0200 Subject: [PATCH 121/187] small fixes --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 92229ed878..ceeecde63e 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1140,7 +1140,7 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) - modBuilder.addOutput(funcOp.getResName(idx);.getValue(), lowerType(res)); + modBuilder.addOutput(funcOp.getResName(idx).getValue(), lowerType(res)); From c2ea688c691174500db148350bf15e7809780b1c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:00:13 +0200 Subject: [PATCH 122/187] small fixes --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 9d898933c2..c74145bd71 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -257,7 +257,6 @@ def InstanceOp : Handshake_Op<"instance", [ def BufferOp : Handshake_Op<"buffer", [ HasClock, SameOperandsAndResultType, - // The IOs of a BufferOp have simple names SimpleNamedIOInterface ]> { let summary = "buffer operation"; @@ -356,7 +355,6 @@ def InitOp : Handshake_Op<"init", [ def NDWireOp : Handshake_Op<"ndwire", [ HasClock, SameOperandsAndResultType, - // The IOs of a NDWire have simple names SimpleNamedIOInterface ]> { let summary = "non-deterministic wire operation"; @@ -377,7 +375,6 @@ class Handshake_ForkOp traits = []> : Pure, HasClock, SameOperandsAndResultType, - // The IOs of a ForkOp have simple names SimpleNamedIOInterface ]> { let arguments = (ins HandshakeType:$operand); @@ -435,7 +432,6 @@ def MergeOp : Handshake_Op<"merge", [ SameOperandsAndResultType, VariadicHasElement<"dataOperands">, DeclareOpInterfaceMethods, - // The IOs of a MergeOp have simple names SimpleNamedIOInterface ]> { let summary = "merge operation"; @@ -582,7 +578,6 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ def BranchOp : Handshake_Op<"br", [ Pure, SameOperandsAndResultType, - // The IOs of a BranchOp have simple names SimpleNamedIOInterface ]> { let summary = "branch operation"; @@ -663,7 +658,6 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ } def SinkOp : Handshake_Op<"sink", [ - // The IOs of a SinkOp have simple names SimpleNamedIOInterface ]> { let summary = "sink operation"; @@ -686,7 +680,6 @@ def SinkOp : Handshake_Op<"sink", [ def SourceOp : Handshake_Op<"source", [ Pure, - // The IOs of a SourceOp have simple names SimpleNamedIOInterface ]> { let summary = "source operation"; @@ -717,7 +710,6 @@ def SourceOp : Handshake_Op<"source", [ def JoinOp : Handshake_Op<"join", [ SameOperandsAndResultType, DeclareOpInterfaceMethods, - // The IOs of a JoinOp have simple names SimpleNamedIOInterface ]> { let summary = "join operation"; @@ -741,7 +733,6 @@ def JoinOp : Handshake_Op<"join", [ // once the backend supports variadic channels with zero or one item correctly. def BlockerOp : Handshake_Op<"blocker", [ SameOperandsAndResultType, - // The IOs of a BlockerOp have simple names SimpleNamedIOInterface ]> { let summary = "blocker operation"; @@ -764,7 +755,6 @@ def BlockerOp : Handshake_Op<"blocker", [ def NotOp : Handshake_Op<"not", [ Pure, SameOperandsAndResultType, - // The IOs of a NotOp have simple names SimpleNamedIOInterface ]> { let summary = "Logical negation"; @@ -1796,7 +1786,6 @@ def UnbundleOp : Handshake_Op<"unbundle", [ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ SameOperandsAndResultType, - // The IOs of a ReadyRemoverOp have simple names SimpleNamedIOInterface ]> { let summary = [{ From 4125ee012b96ecbe44769a48decc4fefb3db58dd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:01:40 +0200 Subject: [PATCH 123/187] small fixes --- .../Dialect/Handshake/HandshakeOps.td | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index c74145bd71..9cec8f3748 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -141,30 +141,30 @@ def FuncOp : Op" /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { - assert(idx < getNumInputPorts() && "index too high"); + assert(idx < getArgNames().size() && "index too high"); return getResName(idx).str(); } std::string getResultName(unsigned idx) { - assert(idx < getNumOutputPorts() && "index too high"); + assert(idx < getResNames().size() && "index too high"); return getResName(idx).str(); } }]; From 9edf40f569ee86884f1d1374f888460b044dc031 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:02:25 +0200 Subject: [PATCH 124/187] small fixes --- .../Dialect/Handshake/HandshakeInterfaces.td | 69 ------------------- 1 file changed, 69 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 689996fbf5..57af4bb246 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -244,75 +244,6 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } -//===----------------------------------------------------------------------===// -// Number of RTL Ports -//===----------------------------------------------------------------------===// -// Operations may have more ports than operands and results -// For example, the EndOp and FuncOp both have -// the function results as additional ports -//===----------------------------------------------------------------------===// - -def InputRTLPortsAreOperandsInterface : OpInterface<"InputRTLPortsAreOperandsInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"The operands of this operation correspond directly to its input RTL ports."}]; - let methods = [ - InterfaceMethod< - "Returns the name of a specific input port.", - "std::string", "getInputPortName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return getOperandName(concreteOp, idx); - }]> - ]; -} - -def CustomRTLInputPortsInterface : OpInterface<"CustomRTLInputPortsInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"The input RTL ports of this operation do not correspond to its operands"}]; - - let methods = [ - InterfaceMethod< - "Returns the name of a specific input port.", - "std::string", "getInputPortName", (ins "unsigned" : $idx) - > - ]; -} - -def OutputRTLPortsAreResultsInterface : OpInterface<"OutputRTLPortsAreResultsInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"The results of this operation correspond directly to its output RTL ports."}]; - let methods = [ - InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getOutputPortName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - return getResultName(concreteOp, idx); - }]> - ]; -} - -def CustomRTLOutputPortsInterface : OpInterface<"CustomRTLOutputPortsInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"The output RTL ports of this operation do not correspond to its results"}]; - - let methods = [ - InterfaceMethod< - "Returns the name of a specific output port.", - "std::string", "getOutputPortName", (ins "unsigned" : $idx) - > - ]; -} - -//===----------------------------------------------------------------------===// - - def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = From e9beac0cd0807cf97a14dc1d3f10e1efad6ee1b6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:03:02 +0200 Subject: [PATCH 125/187] small fixes --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 57af4bb246..84f350d211 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -244,6 +244,8 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } +//===----------------------------------------------------------------------===// + def ControlInterface : OpInterface<"ControlInterface"> { let cppNamespace = "::dynamatic::handshake"; let description = From f4adfe1ed6f4e21c6359339604329f0b9de9ffca Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:08:45 +0200 Subject: [PATCH 126/187] small fixes --- .../Dialect/Handshake/HandshakeInterfaces.h | 8 ---- .../Dialect/Handshake/HandshakeOps.h | 8 ++++ lib/Dialect/Handshake/HandshakeInterfaces.cpp | 43 ------------------- lib/Dialect/Handshake/HandshakeOps.cpp | 37 ++++++++++++++++ 4 files changed, 45 insertions(+), 51 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h index 72210e3a41..5cddc48b84 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.h @@ -34,14 +34,6 @@ namespace handshake { class FuncOp; -/// Returns the name of an operand -/// based on which interface the operation implements -std::string getOperandName(Operation *op, size_t oprdIdx); - -/// Returns the name of a result -/// based on which interface the operation implements -std::string getResultName(Operation *op, size_t resIdx); - class ControlType; namespace detail { diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 849b63a89b..95f2b270d6 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -42,6 +42,14 @@ class StoreOp; class MemoryControllerOp; class LSQOp; +/// Returns the name of an operand +/// based on which interface the operation implements +std::string getOperandName(Operation *op, size_t oprdIdx); + +/// Returns the name of a result +/// based on which interface the operation implements +std::string getResultName(Operation *op, size_t resIdx); + } // end namespace handshake } // end namespace dynamatic diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index ad7f9bfc50..06e3d3047e 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -28,49 +28,6 @@ using namespace mlir; using namespace dynamatic; using namespace dynamatic::handshake; -namespace dynamatic { -namespace handshake { - -//===----------------------------------------------------------------------===// -// Operand and Result Names -//===----------------------------------------------------------------------===// - -std::string getOperandName(Operation *op, size_t oprdIdx) { - - if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); - } - - op->emitError() << "must specify operand names, op: " << *op; - assert(0); -} - -std::string getResultName(Operation *op, size_t resIdx) { - - if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); - } - - op->emitError() << "must specify result names, op: " << *op; - assert(0); -} - - -} // namespace handshake -} // namespace dynamatic - //===----------------------------------------------------------------------===// // MemoryOpInterface diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 257e506c45..68fe2232ce 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2143,5 +2143,42 @@ std::string MemoryControllerOp::getResultName(unsigned idx) { return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); } +//===----------------------------------------------------------------------===// +// Operand and Result Names +//===----------------------------------------------------------------------===// + +std::string getOperandName(Operation *op, size_t oprdIdx) { + + if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getOperandName(oprdIdx); + } else if (auto nameInterface = + dyn_cast(op)) { + return nameInterface.getOperandName(oprdIdx); + } else if (auto nameInterface = + dyn_cast(op)) { + return nameInterface.getOperandName(oprdIdx); + } + + op->emitError() << "must specify operand names, op: " << *op; + assert(0); +} + +std::string getResultName(Operation *op, size_t resIdx) { + + if (auto nameInterface = + dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + } else if (auto nameInterface = + dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + } else if (auto nameInterface = dyn_cast(op)) { + return nameInterface.getResultName(resIdx); + } + + op->emitError() << "must specify result names, op: " << *op; + assert(0); +} + + #define GET_OP_CLASSES #include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" From 511aab73849da852ca5a2377e5fe1e145a704a33 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:09:23 +0200 Subject: [PATCH 127/187] small fixes --- experimental/lib/Support/FormalProperty.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index aaadc7d5e7..96b9f83b48 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -11,7 +11,7 @@ //===----------------------------------------------------------------------===// #include "experimental/Support/FormalProperty.h" #include "dynamatic/Analysis/NameAnalysis.h" -#include "dynamatic/Dialect/Handshake/HandshakeInterfaces.h" +#include "dynamatic/Dialect/Handshake/HandshakeOps.h" #include "dynamatic/Support/JSON/JSON.h" #include "llvm/Support/JSON.h" #include From 4b812103452391851ab9f89216811927f28a5ca2 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Tue, 14 Oct 2025 18:11:41 +0200 Subject: [PATCH 128/187] small fixes --- lib/Dialect/Handshake/HandshakeOps.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 68fe2232ce..5638e338d1 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2143,10 +2143,14 @@ std::string MemoryControllerOp::getResultName(unsigned idx) { return getArrayElemName(LD_DATA, mcPorts.getNumPorts()); } +namespace dynamatic { +namespace handshake { + //===----------------------------------------------------------------------===// // Operand and Result Names //===----------------------------------------------------------------------===// + std::string getOperandName(Operation *op, size_t oprdIdx) { if (auto nameInterface = dyn_cast(op)) { @@ -2179,6 +2183,8 @@ std::string getResultName(Operation *op, size_t resIdx) { assert(0); } +} // end namespace handshake +} // end namespace dynamatic #define GET_OP_CLASSES #include "dynamatic/Dialect/Handshake/Handshake.cpp.inc" From df47dc97f08376914ad3983ed579f16ecbb7aabd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 16:14:16 +0200 Subject: [PATCH 129/187] clang format --- experimental/lib/Support/FormalProperty.cpp | 3 ++- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 6 ++---- lib/Dialect/Handshake/HandshakeInterfaces.cpp | 1 - lib/Dialect/Handshake/HandshakeOps.cpp | 11 ++++------- 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 96b9f83b48..2f22d9276b 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -141,7 +141,8 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; - ownerChannel.channelName = handshake::getResultName(ownerOp, res.getResultNumber()); + ownerChannel.channelName = + handshake::getResultName(ownerOp, res.getResultNumber()); userChannel.channelName = handshake::getOperandName(userOp, operandIndex); } diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index ceeecde63e..02aad46ccb 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1141,8 +1141,6 @@ hw::ModulePortInfo getFuncPortInfo(handshake::FuncOp funcOp, // Add all function outputs to the module for (auto [idx, res] : llvm::enumerate(funcOp.getResultTypes())) modBuilder.addOutput(funcOp.getResName(idx).getValue(), lowerType(res)); - - // Add all function inputs to the module, expanding memory references into a // set of individual ports for loads and stores @@ -1400,8 +1398,8 @@ LogicalResult ConvertMemInterface::matchAndRewrite( // The HW instance will be connected to the top-level module through a // number of output ports, add those last after the regular interface ports for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - converter.addOutput(handshake::getResultName(memOp, idx), - lowerType(res.getType()));; + converter.addOutput(handshake::getResultName(memOp, idx), + lowerType(res.getType())); } auto outputModPorts = memState.getMemOutputPorts(parentModOp); for (const hw::ModulePort &outputPort : outputModPorts) diff --git a/lib/Dialect/Handshake/HandshakeInterfaces.cpp b/lib/Dialect/Handshake/HandshakeInterfaces.cpp index 06e3d3047e..b6615dbda2 100644 --- a/lib/Dialect/Handshake/HandshakeInterfaces.cpp +++ b/lib/Dialect/Handshake/HandshakeInterfaces.cpp @@ -28,7 +28,6 @@ using namespace mlir; using namespace dynamatic; using namespace dynamatic::handshake; - //===----------------------------------------------------------------------===// // MemoryOpInterface //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 5638e338d1..0acb8055eb 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -545,7 +545,6 @@ void FuncOp::print(OpAsmPrinter &p) { getArgAttrsAttrName(), getResAttrsAttrName()); } - bool ConditionalBranchOp::isControl() { return isControlCheckTypeAndOperand(getDataOperand().getType(), getDataOperand()); @@ -1549,7 +1548,6 @@ LogicalResult EndOp::verify() { return success(); } - //===----------------------------------------------------------------------===// // BundleOp //===----------------------------------------------------------------------===// @@ -2150,7 +2148,6 @@ namespace handshake { // Operand and Result Names //===----------------------------------------------------------------------===// - std::string getOperandName(Operation *op, size_t oprdIdx) { if (auto nameInterface = dyn_cast(op)) { @@ -2169,15 +2166,15 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { std::string getResultName(Operation *op, size_t resIdx) { - if (auto nameInterface = - dyn_cast(op)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); - } else if (auto nameInterface = dyn_cast(op)) { + } else if (auto nameInterface = + dyn_cast(op)) { return nameInterface.getResultName(resIdx); - } + } op->emitError() << "must specify result names, op: " << *op; assert(0); From 38d75f57722f644af5a3c4bd4dd489b71d4b054a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:03:16 +0200 Subject: [PATCH 130/187] format --- lib/Dialect/Handshake/HandshakeOps.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 1e069d45b1..c6f5ee332d 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -1964,7 +1964,6 @@ LogicalResult TruncIOp::verify() { return success(); } - //===----------------------------------------------------------------------===// // Memory Controller GetOperandName and GetResultName Utilities //===----------------------------------------------------------------------===// From e9d0bdd64f72500751c2e08240df129030c63b0a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:13:20 +0200 Subject: [PATCH 131/187] better comments --- .../Dialect/Handshake/HandshakeArithOps.td | 28 +++++- .../Dialect/Handshake/HandshakeOps.td | 91 ++++++++++++++----- 2 files changed, 93 insertions(+), 26 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index cb68ae4eaa..7611e70f39 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -63,8 +63,7 @@ class Handshake_Arith_CompareOp traits = []> : AllTypesMatch<["lhs", "rhs"]>, AllExtraSignalsMatch<["lhs", "rhs", "result"]>, IsIntSizedChannel<1, "result">, - DeclareOpInterfaceMethods, - CustomNamedIOInterface + DeclareOpInterfaceMethods ]> { let results = (outs ChannelType:$result); @@ -219,8 +218,11 @@ def Handshake_CmpIOp : Handshake_Arith_CompareOp<"cmpi", [ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ AllExtraSignalsMatch<["ctrl", "result"]>, - CustomNamedIOInterface, - DeclareOpInterfaceMethods + DeclareOpInterfaceMethods, + // The IOs of a Handshake_ConstantOp have custom names, + // defined here in the Tablegen + // as part of the Handshake_ConstantOp declaration + CustomNamedIOInterface ]> { let summary = "constant operation"; let description = [{ @@ -242,11 +244,18 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ let extraClassDeclaration = [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + + // Operand 0 is named ctrl std::string getOperandName(unsigned idx) { assert(idx < 1 && "index too high"); return "ctrl"; } + // Result 0 is named outs + // detail::simpleResultName handles idx validation std::string getResultName(unsigned idx) { return detail::simpleResultName(idx, 1); } @@ -385,6 +394,9 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ AllTypesMatch<["trueValue", "falseValue", "result"]>, AllExtraSignalsMatch<["condition", "trueValue", "falseValue", "result"]>, IsIntSizedChannel<1, "condition">, + // The IOs of a Handshake_SelectOp have custom names, + // defined here in the Tablegen + // as part of the Handshake_SelectOp declaration CustomNamedIOInterface ]> { let summary = "Select a value based on a 1-bit predicate."; @@ -394,6 +406,13 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ let results = (outs ChannelType:$result); let extraClassDeclaration = [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + + // Operand 0 is named condition + // Operand 1 is named trueValue + // Operand 2 is named falseValue std::string getOperandName(unsigned idx) { assert(idx < getNumOperands() && "index too high"); if (idx == 0) @@ -401,6 +420,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ return (idx == 1) ? "trueValue" : "falseValue"; } + // Result 0 is named result std::string getResultName(unsigned idx) { assert(idx < 1 && "index too high"); return "result"; diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 60d93938a6..fd56853c05 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -35,6 +35,10 @@ class Handshake_Op traits = []> ]> { // Shared functions to include in child classes string validateIO = [{ + //===------------------------------------------------------------------===// + // Helper Methods for CustomNamedIOInterface + //===------------------------------------------------------------------===// + void validateOperandIdx(unsigned int idx){ assert(idx < getOperation()->getNumOperands() && "index too high"); } @@ -56,6 +60,9 @@ def FuncOp : Op { let summary = "Handshake dialect function."; @@ -141,28 +148,17 @@ def FuncOp : Op" - /// simpleOperandName handles validation + /// Function operand names are function argument names std::string getOperandName(unsigned idx) { assert(idx < getArgNames().size() && "index too high"); return getResName(idx).str(); } - + /// Function result names are function result names std::string getResultName(unsigned idx) { assert(idx < getResNames().size() && "index too high"); return getResName(idx).str(); @@ -493,6 +489,10 @@ def MuxOp : Handshake_Op<"mux", [ let results = (outs HandshakeType:$result); let extraClassDeclaration = [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" /// simpleOperandName handles validation @@ -557,6 +557,10 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operands 0 to N are named "ins_0" to "ins_" /// simpleOperandName handles validation std::string getOperandName(unsigned idx) { @@ -638,6 +642,10 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + // These are the indices into the dests list. enum { trueIndex = 0, falseIndex = 1 }; @@ -866,12 +874,12 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ dynamatic::MCPorts getPorts(); - //------------------------------------------- - // Custom IO Naming: + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// std::string getOperandName(unsigned idx); std::string getResultName(unsigned idx); - //------------------------------------------- }]; } @@ -970,12 +978,12 @@ def LSQOp : Handshake_Op<"lsq", [ /// the same order as the control operation's results. SmallVector getControlPaths(Operation *ctrlOp); - //------------------------------------------- - // Custom IO Naming: + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// std::string getOperandName(unsigned idx); std::string getResultName(unsigned idx); - //------------------------------------------- }]; } @@ -1059,6 +1067,10 @@ def LoadOp : Handshake_MemPortOp<"load", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named addrIn /// Operand 1 is named dataFromMem std::string getOperandName(unsigned idx) { @@ -1109,6 +1121,10 @@ def StoreOp : Handshake_MemPortOp<"store", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named addrIn /// Operand 1 is named dataIn std::string getOperandName(unsigned int idx) { @@ -1279,6 +1295,10 @@ def SpeculatorOp : Handshake_Op<"speculator", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named ins /// Operand 1 is named trigger std::string getOperandName(unsigned idx) { @@ -1350,6 +1370,10 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1404,6 +1428,10 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ }]; let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named ins /// Operand 1 is named ctrl std::string getOperandName(unsigned idx) { @@ -1453,6 +1481,9 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// /// Operand 0 is named ins /// Operand 1 is named ctrl @@ -1510,6 +1541,10 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named spec_tag_data /// Operand 1 is named data std::string getOperandName(unsigned idx) { @@ -1559,6 +1594,10 @@ def NonSpecOp : Handshake_Op<"non_spec", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named dataIn std::string getOperandName(unsigned idx) { validateOperandIdx(idx); @@ -1629,6 +1668,10 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// The first set of operands are named op__in_ /// The last operand is named fromSharedUnitOut0 std::string getOperandName(unsigned idx) { @@ -1831,6 +1874,10 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ // include validateIO functions from handshake op let extraClassDeclaration = validateIO # [{ + //===------------------------------------------------------------------===// + // CustomNamedIOInterface Methods + //===------------------------------------------------------------------===// + /// Operand 0 is named lhs_ins /// Operand 1 is named rhs_ins std::string getOperandName(unsigned idx) { From e94e231151bf064a7a19823b87ec1f1b56716978 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:15:10 +0200 Subject: [PATCH 132/187] syntax --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 7611e70f39..df2988bba0 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -287,7 +287,7 @@ def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi", [ } def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ - BinaryArithNamedIOInterface + BinaryArithNamedIOInterface, IsIntSizedChannel<32, "lhs">, IsIntSizedChannel<32, "rhs">, IsIntSizedChannel<32, "result">, From f72f97badaab4932ce23c382ebfb319735b8ce20 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:17:02 +0200 Subject: [PATCH 133/187] format --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index a5d3de8060..6050a26a24 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -219,7 +219,6 @@ struct InternalMemLoweringState { handshake::MemoryOpInterface memInterface; FuncMemoryPorts ports; - /// Needed because we use the class as a value type in a map, which needs to /// be default-constructible. InternalMemLoweringState() From 217ea1650e5545f189f559836550f14da4bb4bf9 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:27:52 +0200 Subject: [PATCH 134/187] remove duplicate --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 6 ------ 1 file changed, 6 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index df2988bba0..1cae3c8fee 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -296,12 +296,6 @@ def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ let summary = "Signed integer remainder."; } -def Handshake_DivSIOp : Handshake_Arith_IntBinaryOp<"divsi", [ - BinaryArithNamedIOInterface -]> { - let summary = "Signed integer division."; -} - def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ BinaryArithNamedIOInterface IsIntSizedChannel<32, "lhs">, From 37c0cd05d8a36240fc4c8a768d503c84e1414302 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:29:58 +0200 Subject: [PATCH 135/187] fix interface --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 1cae3c8fee..e5a8e0a2a4 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -308,13 +308,13 @@ def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ } def Handshake_MaxSIOp : Handshake_Arith_IntBinaryOp<"maxsi", [ - SimpleNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Outputs the maximum between two input signed integers"; } def Handshake_MaxUIOp : Handshake_Arith_IntBinaryOp<"maxui", [ - SimpleNamedIOInterface + BinaryArithNamedIOInterface ]> { let summary = "Outputs the maximum between two input unsigned integers"; } From d5c042d5a0e8aebc4cf3710c0cd6f2e090804e0a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Fri, 17 Oct 2025 17:44:36 +0200 Subject: [PATCH 136/187] fix comments --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index fd56853c05..0de7af0230 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -326,7 +326,6 @@ def BufferOp : Handshake_Op<"buffer", [ def InitOp : Handshake_Op<"init", [ HasClock, SameOperandsAndResultType, - // The IOs of an InitOp have simple names SimpleNamedIOInterface ]> { let summary = "init operation"; @@ -1196,7 +1195,6 @@ def RAMOp : Handshake_Op<"ram", []> { def EndOp : Handshake_Op<"end", [ Terminator, - // The IOs of an EndOp have simple names SimpleNamedIOInterface ]> { let summary = "function endpoint (dynamatic)"; From b88194621c2a7358675c40ae02fc0c2391f7eb99 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:31:57 +0200 Subject: [PATCH 137/187] try base interface --- .../Dialect/Handshake/HandshakeInterfaces.td | 59 +++++++++++++++++++ .../Dialect/Handshake/HandshakeOps.td | 21 +------ .../HandshakeToHW/HandshakeToHW.cpp | 6 ++ 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index d6d2d40567..b6f77094d5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -143,6 +143,65 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { ]; } +//===----------------------------------------------------------------------===// +// Handshake Base Interface +//===----------------------------------------------------------------------===// +// +// The MLIR Operation inheritance hierarchy does not allow a shared base +// class to place shared functionality into. +// +// Instead we use this interface, present on every handshake operation +// to implement any functionality present on every handshake op +// +//===----------------------------------------------------------------------===// + +def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Base interface for shared functionality of all handshake operations."}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } + + $_op->emitError() << "must specify operand names, op: " << *$_op; + assert(0); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx), + "", + [{ + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } + + $_op->emitError() << "must specify result names, op: " << *$_op; + assert(0); + }]> + ]; +} + //===----------------------------------------------------------------------===// // IO Naming Interfaces //===----------------------------------------------------------------------===// diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 0de7af0230..40509de248 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -31,6 +31,7 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, + HandshakeBaseInterface, DeclareOpInterfaceMethods, ]> { // Shared functions to include in child classes @@ -60,10 +61,6 @@ def FuncOp : Op { let summary = "Handshake dialect function."; let description = [{ @@ -147,22 +144,6 @@ def FuncOp : Op(oprd.getType())) + if(auto handshakeOp = llvm::dyn_cast(memOp)){ + converter.addInput(handshakeOp.getOperandName(idx), oprd); + } else{ + memOp->emitError() << "must implement HandshakeBaseInterface, op: " << *memOp; + llvm::reportFatalInternalError("Missing HandshakeBaseInterface") + } converter.addInput(handshake::getOperandName(memOp, idx), oprd); } converter.addClkAndRst(parentModOp); From 172a4cfc956fda3fea864bdca6bce2b1767cfe22 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:33:48 +0200 Subject: [PATCH 138/187] try base interface --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index e5a8e0a2a4..b226f119f9 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -334,7 +334,7 @@ def Handshake_ExtUIOp : Handshake_Arith_IToICastOp<"extui", [ def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [ Commutative, - BinaryArithNamedIOInterface + BinaryArithNamedIOInterface, IsFloatSizedChannel<32, "lhs">, IsFloatSizedChannel<32, "rhs">, IsFloatSizedChannel<32, "result">, @@ -345,7 +345,7 @@ def Handshake_MaximumFOp : Handshake_Arith_FloatBinaryOp<"maximumf", [ def Handshake_MinimumFOp : Handshake_Arith_FloatBinaryOp< "minimumf", [ Commutative, - BinaryArithNamedIOInterface + BinaryArithNamedIOInterface, IsFloatSizedChannel<32, "lhs">, IsFloatSizedChannel<32, "rhs">, IsFloatSizedChannel<32, "result">, @@ -484,7 +484,6 @@ def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [ def Handshake_UIToFPOp : Handshake_Arith_IToFCastOp<"uitofp", [ SimpleNamedIOInterface - IsIntSizedChannel<32, "in">, IsFloatSizedChannel<32, "out"> ]> { let summary = "Converts a unsigned integer to float."; From 481a433494400c12842e53e747e4d719494eafa4 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:34:27 +0200 Subject: [PATCH 139/187] try base interface --- include/dynamatic/Dialect/Handshake/HandshakeArithOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index b226f119f9..fdbfda44f1 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -297,7 +297,7 @@ def Handshake_RemSIOp : Handshake_Arith_IntBinaryOp<"remsi", [ } def Handshake_DivUIOp : Handshake_Arith_IntBinaryOp<"divui", [ - BinaryArithNamedIOInterface + BinaryArithNamedIOInterface, IsIntSizedChannel<32, "lhs">, IsIntSizedChannel<32, "rhs">, IsIntSizedChannel<32, "result">, From 9f4406610fca7c054081e7b8fd7d936812bf5239 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:34:56 +0200 Subject: [PATCH 140/187] try base interface --- .../dynamatic/Dialect/Handshake/HandshakeArithOps.td | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index fdbfda44f1..66998b645b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -467,7 +467,7 @@ def Handshake_TruncIOp : Handshake_Arith_IToICastOp<"trunci", [ } def Handshake_TruncFOp : Handshake_Arith_FToFCastOp<"truncf", [ - SimpleNamedIOInterface + SimpleNamedIOInterface, IsFloatSizedChannel<64, "in">, IsFloatSizedChannel<32, "out"> ]>{ @@ -483,14 +483,14 @@ def Handshake_XOrIOp : Handshake_Arith_IntBinaryOp<"xori", [ } def Handshake_UIToFPOp : Handshake_Arith_IToFCastOp<"uitofp", [ - SimpleNamedIOInterface + SimpleNamedIOInterface, IsFloatSizedChannel<32, "out"> ]> { let summary = "Converts a unsigned integer to float."; } def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp", [ - SimpleNamedIOInterface + SimpleNamedIOInterface, IsIntSizedChannel<32, "in">, IsFloatSizedChannel<32, "out"> ]> { @@ -498,7 +498,7 @@ def Handshake_SIToFPOp : Handshake_Arith_IToFCastOp<"sitofp", [ } def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi", [ - SimpleNamedIOInterface + SimpleNamedIOInterface, IsFloatSizedChannel<32, "in">, IsIntSizedChannel<32, "out">, LatencyInterface @@ -507,7 +507,7 @@ def Handshake_FPToSIOp : Handshake_Arith_FToICastOp<"fptosi", [ } def Handshake_ExtFOp : Handshake_Arith_FToFCastOp<"extf", [ - SimpleNamedIOInterface + SimpleNamedIOInterface, IsFloatSizedChannel<32, "in">, IsFloatSizedChannel<64, "out"> ]>{ From 0a622ce90b0b61d32001bb085059cc1e80fcc260 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:38:38 +0200 Subject: [PATCH 141/187] try different order --- .../Dialect/Handshake/HandshakeInterfaces.td | 118 +++++++++--------- 1 file changed, 60 insertions(+), 58 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index b6f77094d5..e9f298b9e5 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -143,64 +143,6 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { ]; } -//===----------------------------------------------------------------------===// -// Handshake Base Interface -//===----------------------------------------------------------------------===// -// -// The MLIR Operation inheritance hierarchy does not allow a shared base -// class to place shared functionality into. -// -// Instead we use this interface, present on every handshake operation -// to implement any functionality present on every handshake op -// -//===----------------------------------------------------------------------===// - -def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"Base interface for shared functionality of all handshake operations."}]; - - let methods = [ - InterfaceMethod< - "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - - if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } - - $_op->emitError() << "must specify operand names, op: " << *$_op; - assert(0); - }]>, - InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx), - "", - [{ - if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } - - $_op->emitError() << "must specify result names, op: " << *$_op; - assert(0); - }]> - ]; -} //===----------------------------------------------------------------------===// // IO Naming Interfaces @@ -303,6 +245,66 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } +//===----------------------------------------------------------------------===// +// Handshake Base Interface +//===----------------------------------------------------------------------===// +// +// The MLIR Operation inheritance hierarchy does not allow a shared base +// class to place shared functionality into. +// +// Instead we use this interface, present on every handshake operation +// to implement any functionality present on every handshake op +// +//===----------------------------------------------------------------------===// + +def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Base interface for shared functionality of all handshake operations."}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } + + $_op->emitError() << "must specify operand names, op: " << *$_op; + assert(0); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx), + "", + [{ + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } + + $_op->emitError() << "must specify result names, op: " << *$_op; + assert(0); + }]> + ]; +} + + //===----------------------------------------------------------------------===// def ControlInterface : OpInterface<"ControlInterface"> { From 85c482c334c108a0deb3423ea3898c8012748950 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:39:21 +0200 Subject: [PATCH 142/187] try different order --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 40509de248..96468f08ef 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -31,7 +31,6 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, - HandshakeBaseInterface, DeclareOpInterfaceMethods, ]> { // Shared functions to include in child classes From aac755244495827b2e6bdcd20ec876c5885d4783 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:40:52 +0200 Subject: [PATCH 143/187] comment out --- .../Dialect/Handshake/HandshakeInterfaces.td | 116 +++++++++--------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index e9f298b9e5..2a3b50d838 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -245,64 +245,64 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } -//===----------------------------------------------------------------------===// -// Handshake Base Interface -//===----------------------------------------------------------------------===// -// -// The MLIR Operation inheritance hierarchy does not allow a shared base -// class to place shared functionality into. -// -// Instead we use this interface, present on every handshake operation -// to implement any functionality present on every handshake op -// -//===----------------------------------------------------------------------===// - -def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { - let cppNamespace = "::dynamatic::handshake"; - let description = - [{"Base interface for shared functionality of all handshake operations."}]; - - let methods = [ - InterfaceMethod< - "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx), - "", - [{ - ConcreteOp concreteOp = mlir::cast($_op); - - if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getOperandName(idx); - } - - $_op->emitError() << "must specify operand names, op: " << *$_op; - assert(0); - }]>, - InterfaceMethod< - "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx), - "", - [{ - if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } else if (auto nameInterface = - dyn_cast($_op)) { - return nameInterface.getResultName(idx); - } - - $_op->emitError() << "must specify result names, op: " << *$_op; - assert(0); - }]> - ]; -} +// //===----------------------------------------------------------------------===// +// // Handshake Base Interface +// //===----------------------------------------------------------------------===// +// // +// // The MLIR Operation inheritance hierarchy does not allow a shared base +// // class to place shared functionality into. +// // +// // Instead we use this interface, present on every handshake operation +// // to implement any functionality present on every handshake op +// // +// //===----------------------------------------------------------------------===// + +// def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { +// let cppNamespace = "::dynamatic::handshake"; +// let description = +// [{"Base interface for shared functionality of all handshake operations."}]; + +// let methods = [ +// InterfaceMethod< +// "Returns the name of a specific operand.", +// "std::string", "getOperandName", (ins "unsigned" : $idx), +// "", +// [{ +// ConcreteOp concreteOp = mlir::cast($_op); + +// if (auto nameInterface = dyn_cast($_op)) { +// return nameInterface.getOperandName(idx); +// } else if (auto nameInterface = +// dyn_cast($_op)) { +// return nameInterface.getOperandName(idx); +// } else if (auto nameInterface = +// dyn_cast($_op)) { +// return nameInterface.getOperandName(idx); +// } + +// $_op->emitError() << "must specify operand names, op: " << *$_op; +// assert(0); +// }]>, +// InterfaceMethod< +// "Returns the name of a specific result.", +// "std::string", "getResultName", (ins "unsigned" : $idx), +// "", +// [{ +// if (auto nameInterface = dyn_cast($_op)) { +// return nameInterface.getResultName(idx); +// } else if (auto nameInterface = +// dyn_cast($_op)) { +// return nameInterface.getResultName(idx); +// } else if (auto nameInterface = +// dyn_cast($_op)) { +// return nameInterface.getResultName(idx); +// } + +// $_op->emitError() << "must specify result names, op: " << *$_op; +// assert(0); +// }]> +// ]; +// } //===----------------------------------------------------------------------===// From 79c7306b317db0293e4ffd0115a6dfcbe4d24764 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:42:16 +0200 Subject: [PATCH 144/187] fix bug --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 96468f08ef..b69b5c32cf 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -1827,8 +1827,8 @@ def ReadyRemoverOp : Handshake_Op<"ready_remover",[ } def ValidMergerOp : Handshake_Op<"valid_merger",[ - AllTypesMatch<["lhsIn", "lhs"]>, - AllTypesMatch<["rhsIn", "rhs"]>, + AllTypesMatch<["lhsIn", "lhsOut"]>, + AllTypesMatch<["rhsIn", "rhsOut"]>, // The IOs of a ValidMergerOp have custom names, // defined here in the Tablegen // as part of the ValidMergerOp declaration From c781876793e0994ede415269ba69f58ea2d14d3d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:43:39 +0200 Subject: [PATCH 145/187] add back --- .../Dialect/Handshake/HandshakeInterfaces.td | 116 +++++++++--------- .../Dialect/Handshake/HandshakeOps.td | 1 + 2 files changed, 59 insertions(+), 58 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 2a3b50d838..3848ac6623 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -245,64 +245,64 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { ]; } -// //===----------------------------------------------------------------------===// -// // Handshake Base Interface -// //===----------------------------------------------------------------------===// -// // -// // The MLIR Operation inheritance hierarchy does not allow a shared base -// // class to place shared functionality into. -// // -// // Instead we use this interface, present on every handshake operation -// // to implement any functionality present on every handshake op -// // -// //===----------------------------------------------------------------------===// - -// def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { -// let cppNamespace = "::dynamatic::handshake"; -// let description = -// [{"Base interface for shared functionality of all handshake operations."}]; - -// let methods = [ -// InterfaceMethod< -// "Returns the name of a specific operand.", -// "std::string", "getOperandName", (ins "unsigned" : $idx), -// "", -// [{ -// ConcreteOp concreteOp = mlir::cast($_op); - -// if (auto nameInterface = dyn_cast($_op)) { -// return nameInterface.getOperandName(idx); -// } else if (auto nameInterface = -// dyn_cast($_op)) { -// return nameInterface.getOperandName(idx); -// } else if (auto nameInterface = -// dyn_cast($_op)) { -// return nameInterface.getOperandName(idx); -// } - -// $_op->emitError() << "must specify operand names, op: " << *$_op; -// assert(0); -// }]>, -// InterfaceMethod< -// "Returns the name of a specific result.", -// "std::string", "getResultName", (ins "unsigned" : $idx), -// "", -// [{ -// if (auto nameInterface = dyn_cast($_op)) { -// return nameInterface.getResultName(idx); -// } else if (auto nameInterface = -// dyn_cast($_op)) { -// return nameInterface.getResultName(idx); -// } else if (auto nameInterface = -// dyn_cast($_op)) { -// return nameInterface.getResultName(idx); -// } - -// $_op->emitError() << "must specify result names, op: " << *$_op; -// assert(0); -// }]> -// ]; -// } +//===----------------------------------------------------------------------===// +// Handshake Base Interface +//===----------------------------------------------------------------------===// +// +// The MLIR Operation inheritance hierarchy does not allow a shared base +// class to place shared functionality into. +// +// Instead we use this interface, present on every handshake operation, +// to implement shared functionality +// +//===----------------------------------------------------------------------===// + +def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { + let cppNamespace = "::dynamatic::handshake"; + let description = + [{"Base interface for shared functionality of all handshake operations."}]; + + let methods = [ + InterfaceMethod< + "Returns the name of a specific operand.", + "std::string", "getOperandName", (ins "unsigned" : $idx), + "", + [{ + ConcreteOp concreteOp = mlir::cast($_op); + + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getOperandName(idx); + } + + $_op->emitError() << "must specify operand names, op: " << *$_op; + assert(0); + }]>, + InterfaceMethod< + "Returns the name of a specific result.", + "std::string", "getResultName", (ins "unsigned" : $idx), + "", + [{ + if (auto nameInterface = dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } else if (auto nameInterface = + dyn_cast($_op)) { + return nameInterface.getResultName(idx); + } + + $_op->emitError() << "must specify result names, op: " << *$_op; + assert(0); + }]> + ]; +} //===----------------------------------------------------------------------===// diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index b69b5c32cf..ba1e60797c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -31,6 +31,7 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, + HandshakeBaseInterface, DeclareOpInterfaceMethods, ]> { // Shared functions to include in child classes From 892730947eae5f94cd22e122cad1a858c68b0c24 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:47:58 +0200 Subject: [PATCH 146/187] export dot --- tools/export-dot/export-dot.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index c70fb6bc4e..a2298267bc 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -276,13 +276,6 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { mlir::DenseMap bbSubgraphs; DOTGraph::Subgraph *root = &builder.getRoot(); - // Collect port names for all operations and the top-level function - using PortNames = mlir::DenseMap; - PortNames portNames; - portNames.try_emplace(funcOp, funcOp); - for (Operation &op : funcOp.getOps()) - portNames.try_emplace(&op, &op); - auto addNode = [&](Operation *op, DOTGraph::Subgraph &subgraph) -> LogicalResult { // The node's DOT "mlir_op" attribute @@ -335,11 +328,11 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { Operation *srcOp = res.getDefiningOp(); srcNodeName = getUniqueName(srcOp).str(); srcIdx = res.getResultNumber(); - srcPortName = portNames.at(srcOp).getOutputName(srcIdx); + srcPortName = handshake::getResultName(srcIdx); } else { Operation *parentOp = val.getParentBlock()->getParentOp(); srcIdx = cast(val).getArgNumber(); - srcNodeName = srcPortName = portNames.at(parentOp).getInputName(srcIdx); + srcNodeName = srcPortName = handshake::getOperandName(parentOp, srcIdx); } // Determine the edge's destination @@ -348,11 +341,11 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { if (isa(dstOp)) { Operation *parentOp = dstOp->getParentOp(); dstIdx = oprd.getOperandNumber(); - dstNodeName = dstPortName = portNames.at(parentOp).getOutputName(dstIdx); + dstNodeName = dstPortName = handshake::getResultName(dstIdx); } else { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); - dstPortName = portNames.at(dstOp).getInputName(dstIdx); + dstPortName = handshake::getOperandName(dstOp, dstIdx) } DOTGraph::Edge &edge = builder.addEdge(srcNodeName, dstNodeName, subgraph); @@ -377,7 +370,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { continue; // Create a node for the argument - StringRef argName = portNames.at(funcOp).getInputName(idx); + StringRef argName = funcOp.getArgName(idx); DOTGraph::Node *node = builder.addNode(argName, *root); if (!node) return funcOp.emitError() << "failed to create node for argument " << idx; @@ -394,7 +387,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { // Create nodes for all function results ValueRange results = funcOp.getBodyBlock()->getTerminator()->getOperands(); for (const auto &[idx, res] : llvm::enumerate(results)) { - StringRef resName = portNames.at(funcOp).getOutputName(idx); + StringRef resName = funcOp.getResultName(idx); DOTGraph::Node *node = builder.addNode(resName, *root); if (!node) return funcOp.emitError() << "failed to create node for argument " << idx; From 5023e631a5a0dd62a9f4c0418a33ce62d5dce2a6 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:49:35 +0200 Subject: [PATCH 147/187] log 2 csv --- tools/backend/log2csv/log2csv.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/backend/log2csv/log2csv.cpp b/tools/backend/log2csv/log2csv.cpp index 07f5bd2c2a..c26851c6f8 100644 --- a/tools/backend/log2csv/log2csv.cpp +++ b/tools/backend/log2csv/log2csv.cpp @@ -250,16 +250,14 @@ static LogicalResult mapSignalsToValues(mlir::ModuleOp modOp, } // First associate names to all function arguments - handshake::PortNamer argNameGen(funcOp); for (auto [idx, arg] : llvm::enumerate(funcOp.getArguments())) - ports.insert({argNameGen.getInputName(idx), arg}); + ports.insert({funcOp.getArgName(idx), arg}); // Then associate names to each operation's results for (Operation &op : funcOp.getOps()) { - handshake::PortNamer resNameGen(&op); for (auto [idx, res] : llvm::enumerate(op.getResults())) { std::string signalName = - getUniqueName(&op).str() + "_" + resNameGen.getOutputName(idx).str(); + getUniqueName(&op).str() + "_" + funcOp.getResultName(idx).str(); ports.insert({signalName, res}); } } From 3feaeb159a2cb2f9f82271d89fe6c7a24027a1be Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 11:50:28 +0200 Subject: [PATCH 148/187] syntax --- tools/backend/log2csv/log2csv.cpp | 2 +- tools/export-dot/export-dot.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/backend/log2csv/log2csv.cpp b/tools/backend/log2csv/log2csv.cpp index c26851c6f8..8183f7d18e 100644 --- a/tools/backend/log2csv/log2csv.cpp +++ b/tools/backend/log2csv/log2csv.cpp @@ -257,7 +257,7 @@ static LogicalResult mapSignalsToValues(mlir::ModuleOp modOp, for (Operation &op : funcOp.getOps()) { for (auto [idx, res] : llvm::enumerate(op.getResults())) { std::string signalName = - getUniqueName(&op).str() + "_" + funcOp.getResultName(idx).str(); + getUniqueName(&op).str() + "_" + funcOp.getResName(idx).str(); ports.insert({signalName, res}); } } diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index a2298267bc..e2b43bb6e6 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -345,7 +345,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { } else { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); - dstPortName = handshake::getOperandName(dstOp, dstIdx) + dstPortName = handshake::getOperandName(dstOp, dstIdx); } DOTGraph::Edge &edge = builder.addEdge(srcNodeName, dstNodeName, subgraph); @@ -387,7 +387,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { // Create nodes for all function results ValueRange results = funcOp.getBodyBlock()->getTerminator()->getOperands(); for (const auto &[idx, res] : llvm::enumerate(results)) { - StringRef resName = funcOp.getResultName(idx); + StringRef resName = funcOp.getResName(idx); DOTGraph::Node *node = builder.addNode(resName, *root); if (!node) return funcOp.emitError() << "failed to create node for argument " << idx; From 353e0a842a39a55a7ab3f98f584bde6cd50900d3 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:01:06 +0200 Subject: [PATCH 149/187] detail --- .../Dialect/Handshake/HandshakeInterfaces.td | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 3848ac6623..a64c069e0a 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -178,7 +178,7 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { //===----------------------------------------------------------------------===// def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake"; + let cppNamespace = "::dynamatic::handshake::detail"; let description = [{"Used by operations whose operands and results are named 'ins" and 'outs'."}]; @@ -205,7 +205,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { } def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake"; + let cppNamespace = "::dynamatic::handshake::detail"; let description = [{"Used by operations whose operands are named 'lhs' and 'rhs', and result is named 'result'."}]; @@ -230,7 +230,7 @@ def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { } def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake"; + let cppNamespace = "::dynamatic::handshake::detail"; let description = [{"Used by operations with unique names for their operands and results."}]; @@ -270,13 +270,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast($_op)) { return nameInterface.getOperandName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getOperandName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getOperandName(idx); } From c32ba800c07134ef6eaa461955e4b3a762e8afb8 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:02:16 +0200 Subject: [PATCH 150/187] detail --- lib/Dialect/Handshake/HandshakeOps.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index c6f5ee332d..312c66b20b 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2134,13 +2134,13 @@ namespace handshake { std::string getOperandName(Operation *op, size_t oprdIdx) { - if (auto nameInterface = dyn_cast(op)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } From 515e14a6ba41efd9ff8149daaba52f1e73c85b80 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:03:40 +0200 Subject: [PATCH 151/187] detail --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index a64c069e0a..9ffa2a5124 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -288,13 +288,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast($_op)) { return nameInterface.getResultName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getResultName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getResultName(idx); } From 34d59d2456790b47f7c682d849ea9c4676005f60 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:07:44 +0200 Subject: [PATCH 152/187] detail --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 9ffa2a5124..3ffe6eb81c 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -178,7 +178,7 @@ def MemPortOpInterface : OpInterface<"MemPortOpInterface"> { //===----------------------------------------------------------------------===// def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake::detail"; + let cppNamespace = "::dynamatic::handshake::detail::io"; let description = [{"Used by operations whose operands and results are named 'ins" and 'outs'."}]; @@ -205,7 +205,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { } def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake::detail"; + let cppNamespace = "::dynamatic::handshake::detail::io"; let description = [{"Used by operations whose operands are named 'lhs' and 'rhs', and result is named 'result'."}]; @@ -230,7 +230,7 @@ def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { } def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { - let cppNamespace = "::dynamatic::handshake::detail"; + let cppNamespace = "::dynamatic::handshake::detail::io"; let description = [{"Used by operations with unique names for their operands and results."}]; From d54c540a913b81c0cbe3d1d6e6b4a408d8b9fed3 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:08:58 +0200 Subject: [PATCH 153/187] detail --- .../Dialect/Handshake/HandshakeInterfaces.td | 12 ++++++------ lib/Dialect/Handshake/HandshakeOps.cpp | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 3ffe6eb81c..8ce3fda493 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -270,13 +270,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast($_op)) { return nameInterface.getOperandName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getOperandName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getOperandName(idx); } @@ -288,13 +288,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast($_op)) { return nameInterface.getResultName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getResultName(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast($_op)) { return nameInterface.getResultName(idx); } diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 312c66b20b..8aeb63f3cd 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2134,13 +2134,13 @@ namespace handshake { std::string getOperandName(Operation *op, size_t oprdIdx) { - if (auto nameInterface = dyn_cast(op)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getOperandName(oprdIdx); } @@ -2150,13 +2150,13 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { std::string getResultName(Operation *op, size_t resIdx) { - if (auto nameInterface = dyn_cast(op)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getResultName(resIdx); } else if (auto nameInterface = - dyn_cast(op)) { + dyn_cast(op)) { return nameInterface.getResultName(resIdx); } From 245f3f82018899bbf3bb83bfd6f5a49224555baa Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:12:09 +0200 Subject: [PATCH 154/187] detail --- .../Dialect/Handshake/HandshakeArithOps.td | 8 +-- .../Dialect/Handshake/HandshakeInterfaces.td | 12 ++-- .../Dialect/Handshake/HandshakeOps.td | 64 +++++++++---------- lib/Dialect/Handshake/HandshakeOps.cpp | 12 ++-- 4 files changed, 48 insertions(+), 48 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td index 66998b645b..e35223da31 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeArithOps.td @@ -249,14 +249,14 @@ def Handshake_ConstantOp : Handshake_Arith_Op<"constant", [ //===------------------------------------------------------------------===// // Operand 0 is named ctrl - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { assert(idx < 1 && "index too high"); return "ctrl"; } // Result 0 is named outs // detail::simpleResultName handles idx validation - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { return detail::simpleResultName(idx, 1); } }]; @@ -407,7 +407,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ // Operand 0 is named condition // Operand 1 is named trueValue // Operand 2 is named falseValue - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { assert(idx < getNumOperands() && "index too high"); if (idx == 0) return "condition"; @@ -415,7 +415,7 @@ def Handshake_SelectOp : Handshake_Arith_Op<"select", [ } // Result 0 is named result - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { assert(idx < 1 && "index too high"); return "result"; } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 8ce3fda493..25fb515720 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -185,7 +185,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { let methods = [ InterfaceMethod< "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx), + "std::string", "getOperandNameImpl", (ins "unsigned" : $idx), "", [{ ConcreteOp concreteOp = mlir::cast($_op); @@ -194,7 +194,7 @@ def SimpleNamedIOInterface : OpInterface<"SimpleNamedIOInterface"> { }]>, InterfaceMethod< "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx), + "std::string", "getResultNameImpl", (ins "unsigned" : $idx), "", [{ ConcreteOp concreteOp = mlir::cast($_op); @@ -212,7 +212,7 @@ def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { let methods = [ InterfaceMethod< "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx), + "std::string", "getOperandNameImpl", (ins "unsigned" : $idx), "", [{ assert(idx < 2 && "index too high"); @@ -220,7 +220,7 @@ def BinaryArithNamedIOInterface : OpInterface<"BinaryArithNamedIOInterface"> { }]>, InterfaceMethod< "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx), + "std::string", "getResultNameImpl", (ins "unsigned" : $idx), "", [{ assert(idx < 1 && "index too high"); @@ -237,10 +237,10 @@ def CustomNamedIOInterface : OpInterface<"CustomNamedIOInterface"> { let methods = [ InterfaceMethod< "Returns the name of a specific operand.", - "std::string", "getOperandName", (ins "unsigned" : $idx)>, + "std::string", "getOperandNameImpl", (ins "unsigned" : $idx)>, InterfaceMethod< "Returns the name of a specific result.", - "std::string", "getResultName", (ins "unsigned" : $idx) + "std::string", "getResultNameImpl", (ins "unsigned" : $idx) > ]; } diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index ba1e60797c..08912b6097 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -40,11 +40,11 @@ class Handshake_Op traits = []> // Helper Methods for CustomNamedIOInterface //===------------------------------------------------------------------===// - void validateOperandIdx(unsigned int idx){ + void validateOperandIdx(unsigned idx){ assert(idx < getOperation()->getNumOperands() && "index too high"); } - void validateResultIdx(unsigned int idx){ + void validateResultIdx(unsigned idx){ assert(idx < getOperation()->getNumResults() && "index too high"); } }]; @@ -476,13 +476,13 @@ def MuxOp : Handshake_Op<"mux", [ /// Operand 0 is named "index" /// Operands 1 to N are named "ins_0" to "ins_" /// simpleOperandName handles validation - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { return idx == 0 ? "index" : detail::simpleOperandName(idx - 1, getOperation()->getNumOperands() - 1); } /// Result 0 is named "outs" /// simpleResultName handles validation - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { return detail::simpleResultName(idx, 1); } }]; @@ -543,13 +543,13 @@ def ControlMergeOp : Handshake_Op<"control_merge", [ /// Operands 0 to N are named "ins_0" to "ins_" /// simpleOperandName handles validation - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { return detail::simpleOperandName(idx, getOperation()->getNumOperands()); } /// Result 0 is named outs /// Result 1 is named index - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return idx == 0 ? "outs" : "index"; } @@ -631,14 +631,14 @@ def ConditionalBranchOp : Handshake_Op<"cond_br", [ /// Operand 0 is named condition /// Operand 1 is named data - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "condition" : "data"; } /// Operand 0 is named trueOut /// Operand 1 is named falseOut - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return idx == trueIndex ? "trueOut" : "falseOut"; } @@ -858,8 +858,8 @@ def MemoryControllerOp : Handshake_Op<"mem_controller", [ // CustomNamedIOInterface Methods //===------------------------------------------------------------------===// - std::string getOperandName(unsigned idx); - std::string getResultName(unsigned idx); + std::string getOperandNameImpl(unsigned idx); + std::string getResultNameImpl(unsigned idx); }]; } @@ -962,8 +962,8 @@ def LSQOp : Handshake_Op<"lsq", [ // CustomNamedIOInterface Methods //===------------------------------------------------------------------===// - std::string getOperandName(unsigned idx); - std::string getResultName(unsigned idx); + std::string getOperandNameImpl(unsigned idx); + std::string getResultNameImpl(unsigned idx); }]; } @@ -1053,14 +1053,14 @@ def LoadOp : Handshake_MemPortOp<"load", [ /// Operand 0 is named addrIn /// Operand 1 is named dataFromMem - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return (idx == 0) ? "addrIn" : "dataFromMem"; } /// Result 0 is named addrOut /// Result 1 is named dataOut - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataOut"; } @@ -1107,14 +1107,14 @@ def StoreOp : Handshake_MemPortOp<"store", [ /// Operand 0 is named addrIn /// Operand 1 is named dataIn - std::string getOperandName(unsigned int idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return (idx == 0) ? "addrIn" : "dataIn"; } /// Result 0 is named addrOut /// Result 1 is named dataToMem - std::string getResultName(unsigned int idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return (idx == 0) ? "addrOut" : "dataToMem"; } @@ -1280,7 +1280,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ /// Operand 0 is named ins /// Operand 1 is named trigger - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "ins" : "trigger"; } @@ -1291,7 +1291,7 @@ def SpeculatorOp : Handshake_Op<"speculator", [ /// Result 3 is named ctrl_sc_save /// Result 4 is named ctrl_sc_commit /// Result 5 is named ctrl_sc_branch - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); switch (idx) { case 0: @@ -1355,13 +1355,13 @@ def SpecSaveOp : Handshake_Op<"spec_save", [ /// Operand 0 is named ins /// Operand 1 is named ctrl - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } /// Result 0 is named outs - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return "outs"; } @@ -1413,13 +1413,13 @@ def SpecCommitOp : Handshake_Op<"spec_commit", [ /// Operand 0 is named ins /// Operand 1 is named ctrl - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } /// Result 0 is named result - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return "outs"; } @@ -1466,13 +1466,13 @@ def SpecSaveCommitOp : Handshake_Op<"spec_save_commit", [ /// Operand 0 is named ins /// Operand 1 is named ctrl - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "ins" : "ctrl"; } /// Result 0 is named result - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return "outs"; } @@ -1526,14 +1526,14 @@ def SpeculatingBranchOp : Handshake_Op<"speculating_branch", [ /// Operand 0 is named spec_tag_data /// Operand 1 is named data - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return idx == 0 ? "spec_tag_data" : "data"; } /// Result 0 is named trueOut /// Result 1 is named falseOut - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return idx == 0 ? "trueOut" : "falseOut"; } @@ -1578,13 +1578,13 @@ def NonSpecOp : Handshake_Op<"non_spec", [ //===------------------------------------------------------------------===// /// Operand 0 is named dataIn - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return "dataIn"; } /// Result 0 is named dataOut - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return "dataOut"; } @@ -1653,7 +1653,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ /// The first set of operands are named op__in_ /// The last operand is named fromSharedUnitOut0 - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); if (idx < getNumSharedOperands() * getNumSharedOperations()) { return "op" + std::to_string(idx / getNumSharedOperands()) + "in" + @@ -1664,7 +1664,7 @@ def SharingWrapperOp : Handshake_Op<"sharing_wrapper", [ /// The first set of results are named op__out_0 /// The last set of results are named toSharedUnitIn_ - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); if (idx < getNumSharedOperations()) return "op" + std::to_string(idx) + "out0"; @@ -1859,14 +1859,14 @@ def ValidMergerOp : Handshake_Op<"valid_merger",[ /// Operand 0 is named lhs_ins /// Operand 1 is named rhs_ins - std::string getOperandName(unsigned idx) { + std::string getOperandNameImpl(unsigned idx) { validateOperandIdx(idx); return (idx == 0) ? "lhs_ins" : "rhs_ins"; } /// Result 0 is named lhs_outs /// Result 1 is named rhs_outs - std::string getResultName(unsigned idx) { + std::string getResultNameImpl(unsigned idx) { validateResultIdx(idx); return (idx == 0) ? "lhs_outs" : "rhs_outs"; } diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 8aeb63f3cd..0a9656b28c 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2135,13 +2135,13 @@ namespace handshake { std::string getOperandName(Operation *op, size_t oprdIdx) { if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getOperandNameImpl(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getOperandNameImpl(oprdIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandName(oprdIdx); + return nameInterface.getOperandNameImpl(oprdIdx); } op->emitError() << "must specify operand names, op: " << *op; @@ -2151,13 +2151,13 @@ std::string getOperandName(Operation *op, size_t oprdIdx) { std::string getResultName(Operation *op, size_t resIdx) { if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); + return nameInterface.getResultNameImpl(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); + return nameInterface.getResultNameImpl(resIdx); } else if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultName(resIdx); + return nameInterface.getResultNameImpl(resIdx); } op->emitError() << "must specify result names, op: " << *op; From 7c0c3f42765cc766883d33d537e2d439b1fa75db Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:13:01 +0200 Subject: [PATCH 155/187] detail --- .../Dialect/Handshake/HandshakeInterfaces.td | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 25fb515720..2b0c22c3ea 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -271,13 +271,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { ConcreteOp concreteOp = mlir::cast($_op); if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getOperandName(idx); + return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getOperandName(idx); + return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getOperandName(idx); + return nameInterface.getOperandNameImpl(idx); } $_op->emitError() << "must specify operand names, op: " << *$_op; @@ -289,13 +289,13 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "", [{ if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getResultName(idx); + return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getResultName(idx); + return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = dyn_cast($_op)) { - return nameInterface.getResultName(idx); + return nameInterface.getResultNameImpl(idx); } $_op->emitError() << "must specify result names, op: " << *$_op; From 53206904de48b9b1635258f609cef3e54fcbac7c Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:15:06 +0200 Subject: [PATCH 156/187] detail --- tools/export-dot/export-dot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index e2b43bb6e6..aae3609913 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -328,7 +328,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { Operation *srcOp = res.getDefiningOp(); srcNodeName = getUniqueName(srcOp).str(); srcIdx = res.getResultNumber(); - srcPortName = handshake::getResultName(srcIdx); + srcPortName = handshake::getResultName(srcOp, srcIdx); } else { Operation *parentOp = val.getParentBlock()->getParentOp(); srcIdx = cast(val).getArgNumber(); @@ -341,7 +341,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { if (isa(dstOp)) { Operation *parentOp = dstOp->getParentOp(); dstIdx = oprd.getOperandNumber(); - dstNodeName = dstPortName = handshake::getResultName(dstIdx); + dstNodeName = dstPortName = handshake::getResultName(dstOp, dstIdx); } else { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); From 5d239a12154477111e520b77b9f97a58fb8a2d28 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:17:24 +0200 Subject: [PATCH 157/187] detail --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- tools/export-dot/export-dot.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 2fac10e397..30c304ac81 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1402,7 +1402,7 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(handshakeOp.getOperandName(idx), oprd); } else{ memOp->emitError() << "must implement HandshakeBaseInterface, op: " << *memOp; - llvm::reportFatalInternalError("Missing HandshakeBaseInterface") + llvm::reportFatalError("Missing HandshakeBaseInterface"); } converter.addInput(handshake::getOperandName(memOp, idx), oprd); } diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index aae3609913..17f54adcd9 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -341,7 +341,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { if (isa(dstOp)) { Operation *parentOp = dstOp->getParentOp(); dstIdx = oprd.getOperandNumber(); - dstNodeName = dstPortName = handshake::getResultName(dstOp, dstIdx); + dstNodeName = dstPortName = handshake::getResultName(parentOp, dstIdx); } else { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); From 60b2381bcba6c3d185aa5e3f8c9be85437e9f0fb Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:18:41 +0200 Subject: [PATCH 158/187] detail --- lib/Dialect/Handshake/HandshakeOps.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 0a9656b28c..90a2ea4494 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2063,7 +2063,7 @@ std::string LSQOp::getOperandName(unsigned idx) { return "ldDataFromMC"; } -std::string LSQOp::getResultName(unsigned idx) { +std::string LSQOp::getResultNameImpl(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); if (StringRef name = getIfControlRes(*this, idx); !name.empty()) @@ -2107,7 +2107,7 @@ std::string MemoryControllerOp::getOperandName(unsigned idx) { return getArrayElemName(ST_DATA, mcPorts.getNumPorts()); } -std::string MemoryControllerOp::getResultName(unsigned idx) { +std::string MemoryControllerOp::getResultNameImpl(unsigned idx) { assert(idx < getOperation()->getNumResults() && "index too high"); if (StringRef name = getIfControlRes(*this, idx); !name.empty()) From 796fae470f2b2f23e374f4dbd3577e5b069109f5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:21:36 +0200 Subject: [PATCH 159/187] detail --- .../Dialect/Handshake/HandshakeInterfaces.td | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 2b0c22c3ea..04f439708b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -270,17 +270,17 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { [{ ConcreteOp concreteOp = mlir::cast($_op); - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast(concreteOp)) { return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast(concreteOp)) { return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast(concreteOp)) { return nameInterface.getOperandNameImpl(idx); } - $_op->emitError() << "must specify operand names, op: " << *$_op; + concreteOp->emitError() << "must specify operand names, op: " << *concreteOp; assert(0); }]>, InterfaceMethod< @@ -288,17 +288,17 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ - if (auto nameInterface = dyn_cast($_op)) { + if (auto nameInterface = dyn_cast(concreteOp)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast(concreteOp)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = - dyn_cast($_op)) { + dyn_cast(concreteOp)) { return nameInterface.getResultNameImpl(idx); } - $_op->emitError() << "must specify result names, op: " << *$_op; + concreteOp->emitError() << "must specify result names, op: " << *concreteOp; assert(0); }]> ]; From ee6016d972b434cbc24f304b0365537c61133f0d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:22:11 +0200 Subject: [PATCH 160/187] detail --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 04f439708b..8031a80d8d 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -288,6 +288,8 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ + ConcreteOp concreteOp = mlir::cast($_op); + if (auto nameInterface = dyn_cast(concreteOp)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = From 5a14db838efc3b858ca4c118dce2e28b5a8cc229 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:23:07 +0200 Subject: [PATCH 161/187] failure --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 30c304ac81..e754ce7dfb 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1402,7 +1402,7 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(handshakeOp.getOperandName(idx), oprd); } else{ memOp->emitError() << "must implement HandshakeBaseInterface, op: " << *memOp; - llvm::reportFatalError("Missing HandshakeBaseInterface"); + return failure(); } converter.addInput(handshake::getOperandName(memOp, idx), oprd); } From 544247c5345e4717b76e448e367a1237471265e4 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:23:53 +0200 Subject: [PATCH 162/187] failure --- lib/Dialect/Handshake/HandshakeOps.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 90a2ea4494..18c702ac4b 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2044,7 +2044,7 @@ static std::string getMemResultName(FuncMemoryPorts &ports, unsigned idx) { return ""; } -std::string LSQOp::getOperandName(unsigned idx) { +std::string LSQOp::getOperandNameImpl(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); @@ -2085,7 +2085,7 @@ std::string LSQOp::getResultNameImpl(unsigned idx) { return "stDataToMC"; } -std::string MemoryControllerOp::getOperandName(unsigned idx) { +std::string MemoryControllerOp::getOperandNameImpl(unsigned idx) { assert(idx < getOperation()->getNumOperands() && "index too high"); if (StringRef name = getIfControlOprd(*this, idx); !name.empty()) From 12e5f9c3be91145d28e8bd84883c8c7aa18720b1 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:27:45 +0200 Subject: [PATCH 163/187] const --- .../Dialect/Handshake/HandshakeInterfaces.td | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 8031a80d8d..65abce26c2 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -268,19 +268,19 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getOperandName", (ins "unsigned" : $idx), "", [{ - ConcreteOp concreteOp = mlir::cast($_op); + auto *op = const_cast($_op); - if (auto nameInterface = dyn_cast(concreteOp)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = - dyn_cast(concreteOp)) { + dyn_cast(op)) { return nameInterface.getOperandNameImpl(idx); } else if (auto nameInterface = - dyn_cast(concreteOp)) { + dyn_cast(op)) { return nameInterface.getOperandNameImpl(idx); } - concreteOp->emitError() << "must specify operand names, op: " << *concreteOp; + op->emitError() << "must specify operand names, op: " << *op; assert(0); }]>, InterfaceMethod< @@ -288,19 +288,19 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ - ConcreteOp concreteOp = mlir::cast($_op); + auto *op = const_cast($_op); - if (auto nameInterface = dyn_cast(concreteOp)) { + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = - dyn_cast(concreteOp)) { + dyn_cast(op)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = - dyn_cast(concreteOp)) { + dyn_cast(op)) { return nameInterface.getResultNameImpl(idx); } - concreteOp->emitError() << "must specify result names, op: " << *concreteOp; + op->emitError() << "must specify result names, op: " << *op; assert(0); }]> ]; From 0032e12a115b408cbb47ccf0f7e02b214d2c11c5 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:28:58 +0200 Subject: [PATCH 164/187] const --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 65abce26c2..22b5a84933 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -268,7 +268,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getOperandName", (ins "unsigned" : $idx), "", [{ - auto *op = const_cast($_op); + auto *op = const_cast($_op.getOperation()); if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandNameImpl(idx); @@ -288,8 +288,8 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "std::string", "getResultName", (ins "unsigned" : $idx), "", [{ - auto *op = const_cast($_op); - + auto *op = const_cast($_op.getOperation()); + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = From a9a659efa97a5ef25817bba7e7fdce4309aa0ac1 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:31:36 +0200 Subject: [PATCH 165/187] const --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index e754ce7dfb..44a9f10325 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1398,7 +1398,7 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - if(auto handshakeOp = llvm::dyn_cast(memOp)){ + if(auto handshakeOp = llvm::dyn_cast(memOp.getOperation())){ converter.addInput(handshakeOp.getOperandName(idx), oprd); } else{ memOp->emitError() << "must implement HandshakeBaseInterface, op: " << *memOp; From ecbb01bc9e878afa35046e1074db4bded67bc690 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:37:50 +0200 Subject: [PATCH 166/187] wrapper --- include/dynamatic/Dialect/Handshake/HandshakeOps.h | 2 ++ lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 9 ++------- lib/Dialect/Handshake/HandshakeOps.cpp | 8 ++++++++ 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 95f2b270d6..4272f8d5d1 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -50,6 +50,8 @@ std::string getOperandName(Operation *op, size_t oprdIdx); /// based on which interface the operation implements std::string getResultName(Operation *op, size_t resIdx); +HandshakeBaseInterface getHandshakeBase(Operation * op); + } // end namespace handshake } // end namespace dynamatic diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 44a9f10325..6cb6129a5e 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1398,13 +1398,8 @@ LogicalResult ConvertMemInterface::matchAndRewrite( converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - if(auto handshakeOp = llvm::dyn_cast(memOp.getOperation())){ - converter.addInput(handshakeOp.getOperandName(idx), oprd); - } else{ - memOp->emitError() << "must implement HandshakeBaseInterface, op: " << *memOp; - return failure(); - } - converter.addInput(handshake::getOperandName(memOp, idx), oprd); + auto handshakeOp = handshake::getHandshakeBase(memOp); + converter.addInput(handshakeOp.getOperandName(idx), oprd); } converter.addClkAndRst(parentModOp); diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 18c702ac4b..4418245871 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2132,6 +2132,14 @@ namespace handshake { // Operand and Result Names //===----------------------------------------------------------------------===// +handshake::HandshakeBaseInterface getHandshakeBase(Operation * op){ + if(auto handshakeBase = llvm::dyn_cast(op)){ + return handshakeBase; + } + op->emitError() << "must implement HandshakeBaseInterface, op: " << *op; + llvm::report_fatal_error("Missing HandshakeBaseInterface"); +} + std::string getOperandName(Operation *op, size_t oprdIdx) { if (auto nameInterface = dyn_cast(op)) { From 0e3dff5bb3c31cd35315a56adc464ee95080da71 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:39:02 +0200 Subject: [PATCH 167/187] wrapper --- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 6cb6129a5e..97f4c9b286 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1397,9 +1397,10 @@ LogicalResult ConvertMemInterface::matchAndRewrite( for (auto [port, arg] : llvm::zip_equal(inputModPorts, memArgs)) converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { - if (!isa(oprd.getType())) + if (!isa(oprd.getType())){ auto handshakeOp = handshake::getHandshakeBase(memOp); converter.addInput(handshakeOp.getOperandName(idx), oprd); + } } converter.addClkAndRst(parentModOp); From da6761f08b2997dcb2c2635652ae00652e3fa8dd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:41:35 +0200 Subject: [PATCH 168/187] wrapper --- .../HandshakeToHW/HandshakeToHW.cpp | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 97f4c9b286..02cfff5cea 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1407,7 +1407,9 @@ LogicalResult ConvertMemInterface::matchAndRewrite( // The HW instance will be connected to the top-level module through a // number of output ports, add those last after the regular interface ports for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - converter.addOutput(handshake::getResultName(memOp, idx), + auto handshakeOp = handshake::getHandshakeBase(memOp); + + converter.addOutput(handshakeOp.getResultName(idx), lowerType(res.getType())); } auto outputModPorts = memState.getMemOutputPorts(parentModOp); @@ -1524,17 +1526,17 @@ LogicalResult ConvertMemInterfaceForInternalArray::matchAndRewrite( memInterfaceConverter.addInput("loadData", bramInstanceOp.getResult(0)); } - // Add the ports from handshake op (here we use the port namer to name the - // ports that are directly converted from handshake op), except for the memref - // type. + // Add the ports from handshake op for (auto [i, oprd] : llvm::enumerate(operands)) { if (!isa(oprd.getType())) - memInterfaceConverter.addInput(handshake::getOperandName(memOp, i), oprd); + auto handshakeOp = handshake::getHandshakeBase(memOp); + memInterfaceConverter.addInput(handshakeOp.getOperandName(i), oprd); } memInterfaceConverter.addClkAndRst(parentModOp); for (auto [idx, res] : llvm::enumerate(memOp->getResults())) { - memInterfaceConverter.addOutput(handshake::getResultName(memOp, idx), + auto handshakeOp = handshake::getHandshakeBase(memOp); + memInterfaceConverter.addOutput(handshakeOp.getResultName(idx), lowerType(res.getType())); } @@ -1584,14 +1586,18 @@ LogicalResult ConvertToHWInstance::matchAndRewrite( HWConverter converter(this->getContext()); // Add all operation operands to the inputs - for (auto [idx, oprd] : llvm::enumerate(adaptor.getOperands())) - converter.addInput(handshake::getOperandName(op, idx), oprd); + for (auto [idx, oprd] : llvm::enumerate(adaptor.getOperands())){ + auto handshakeOp = handshake::getHandshakeBase(op); + converter.addInput(handshakeOp.getOperandName(idx), oprd); + } converter.addClkAndRst(((Operation *)op)->getParentOfType()); // Add all operation results to the outputs - for (auto [idx, type] : llvm::enumerate(op->getResultTypes())) - converter.addOutput(handshake::getResultName(op, idx), lowerType(type)); + for (auto [idx, type] : llvm::enumerate(op->getResultTypes())){ + auto handshakeOp = handshake::getHandshakeBase(op); + converter.addOutput(handshakeOp.getResultName(idx), lowerType(type)); + } hw::InstanceOp instOp = converter.convertToInstance(op, rewriter); return instOp ? success() : failure(); } From 65ebc90ca587dd3ab7bb5cb588ae847044270100 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:46:14 +0200 Subject: [PATCH 169/187] format --- include/dynamatic/Dialect/Handshake/HandshakeOps.h | 2 +- lib/Conversion/HandshakeToHW/HandshakeToHW.cpp | 7 ++++--- lib/Dialect/Handshake/HandshakeOps.cpp | 6 +++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 4272f8d5d1..01d7a6a70b 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -50,7 +50,7 @@ std::string getOperandName(Operation *op, size_t oprdIdx); /// based on which interface the operation implements std::string getResultName(Operation *op, size_t resIdx); -HandshakeBaseInterface getHandshakeBase(Operation * op); +HandshakeBaseInterface getHandshakeBase(Operation *op); } // end namespace handshake } // end namespace dynamatic diff --git a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp index 02cfff5cea..e30e798378 100644 --- a/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp +++ b/lib/Conversion/HandshakeToHW/HandshakeToHW.cpp @@ -1397,7 +1397,7 @@ LogicalResult ConvertMemInterface::matchAndRewrite( for (auto [port, arg] : llvm::zip_equal(inputModPorts, memArgs)) converter.addInput(removePortNamePrefix(port), arg); for (auto [idx, oprd] : llvm::enumerate(operands)) { - if (!isa(oprd.getType())){ + if (!isa(oprd.getType())) { auto handshakeOp = handshake::getHandshakeBase(memOp); converter.addInput(handshakeOp.getOperandName(idx), oprd); } @@ -1526,11 +1526,12 @@ LogicalResult ConvertMemInterfaceForInternalArray::matchAndRewrite( memInterfaceConverter.addInput("loadData", bramInstanceOp.getResult(0)); } - // Add the ports from handshake op + // Add the ports from handshake op for (auto [i, oprd] : llvm::enumerate(operands)) { - if (!isa(oprd.getType())) + if (!isa(oprd.getType())){ auto handshakeOp = handshake::getHandshakeBase(memOp); memInterfaceConverter.addInput(handshakeOp.getOperandName(i), oprd); + } } memInterfaceConverter.addClkAndRst(parentModOp); diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 4418245871..82247f98f2 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2132,8 +2132,9 @@ namespace handshake { // Operand and Result Names //===----------------------------------------------------------------------===// -handshake::HandshakeBaseInterface getHandshakeBase(Operation * op){ - if(auto handshakeBase = llvm::dyn_cast(op)){ +handshake::HandshakeBaseInterface getHandshakeBase(Operation *op) { + if(auto handshakeBase = + llvm::dyn_cast(op)) { return handshakeBase; } op->emitError() << "must implement HandshakeBaseInterface, op: " << *op; @@ -2141,7 +2142,6 @@ handshake::HandshakeBaseInterface getHandshakeBase(Operation * op){ } std::string getOperandName(Operation *op, size_t oprdIdx) { - if (auto nameInterface = dyn_cast(op)) { return nameInterface.getOperandNameImpl(oprdIdx); } else if (auto nameInterface = From 363090d6c775e47efa382d84df90604dcea0b661 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 12:49:44 +0200 Subject: [PATCH 170/187] format --- .../dynamatic/Dialect/Handshake/HandshakeOps.td | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 08912b6097..6da3a9fcff 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -61,6 +61,9 @@ def FuncOp : Op { let summary = "Handshake dialect function."; let description = [{ @@ -144,6 +147,18 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 12:50:18 +0200 Subject: [PATCH 171/187] syntax --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 6da3a9fcff..d049b34493 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -152,7 +152,7 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 12:51:43 +0200 Subject: [PATCH 172/187] syntax --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index d049b34493..3b29b28461 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -153,11 +153,11 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 12:52:28 +0200 Subject: [PATCH 173/187] syntax --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 3b29b28461..6a6b052a68 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -153,11 +153,11 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 12:52:49 +0200 Subject: [PATCH 174/187] syntax --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 6a6b052a68..15be9d4581 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -153,7 +153,7 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 13:00:30 +0200 Subject: [PATCH 175/187] safety --- .../Dialect/Handshake/HandshakeOps.td | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 15be9d4581..91ae6527b0 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -41,11 +41,13 @@ class Handshake_Op traits = []> //===------------------------------------------------------------------===// void validateOperandIdx(unsigned idx){ - assert(idx < getOperation()->getNumOperands() && "index too high"); + if (idx >= getOperation()->getNumOperands()) + llvm::report_fatal_error("operand index too high"); } void validateResultIdx(unsigned idx){ - assert(idx < getOperation()->getNumResults() && "index too high"); + if (idx >= getOperation()->getNumResults()) + llvm::report_fatal_error("result index too high"); } }]; @@ -61,8 +63,9 @@ def FuncOp : Op { let summary = "Handshake dialect function."; @@ -114,12 +117,18 @@ def FuncOp : Op(); + auto names = getArgNames(); + if (idx >= names.size()) + llvm::report_fatal_error("argument index too high"); + return names[idx].cast(); } /// Returns the result name at the given index. StringAttr getResName(unsigned idx) { - return getResNames()[idx].cast(); + auto names = getResNames(); + if (idx >= names.size()) + llvm::report_fatal_error("result index too high"); + return names[idx].cast(); } /// Hook for FunctionOpInterface, called after verifying that the 'type' @@ -149,7 +158,7 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 13:01:41 +0200 Subject: [PATCH 176/187] failure test --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 1 - 1 file changed, 1 deletion(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 91ae6527b0..89a37375e8 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -31,7 +31,6 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, - HandshakeBaseInterface, DeclareOpInterfaceMethods, ]> { // Shared functions to include in child classes From 60548e3f5ff00deea1f5e2dc1c521160b032eb4d Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:02:55 +0200 Subject: [PATCH 177/187] remove free functions --- .../Dialect/Handshake/HandshakeOps.td | 1 + lib/Dialect/Handshake/HandshakeOps.cpp | 31 ------------------- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 89a37375e8..91ae6527b0 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -31,6 +31,7 @@ include "dynamatic/Dialect/Handshake/HandshakeTypes.td" class Handshake_Op traits = []> : Op, + HandshakeBaseInterface, DeclareOpInterfaceMethods, ]> { // Shared functions to include in child classes diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index 82247f98f2..ee53cb05b1 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2141,37 +2141,6 @@ handshake::HandshakeBaseInterface getHandshakeBase(Operation *op) { llvm::report_fatal_error("Missing HandshakeBaseInterface"); } -std::string getOperandName(Operation *op, size_t oprdIdx) { - if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getOperandNameImpl(oprdIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getOperandNameImpl(oprdIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getOperandNameImpl(oprdIdx); - } - - op->emitError() << "must specify operand names, op: " << *op; - assert(0); -} - -std::string getResultName(Operation *op, size_t resIdx) { - - if (auto nameInterface = dyn_cast(op)) { - return nameInterface.getResultNameImpl(resIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getResultNameImpl(resIdx); - } else if (auto nameInterface = - dyn_cast(op)) { - return nameInterface.getResultNameImpl(resIdx); - } - - op->emitError() << "must specify result names, op: " << *op; - assert(0); -} - } // end namespace handshake } // end namespace dynamatic From 6776ce312a44def7c2770cc8be73b7c8e6ec7a27 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:03:25 +0200 Subject: [PATCH 178/187] remove free functions --- include/dynamatic/Dialect/Handshake/HandshakeOps.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.h b/include/dynamatic/Dialect/Handshake/HandshakeOps.h index 01d7a6a70b..e1d97431ef 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.h +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.h @@ -42,14 +42,6 @@ class StoreOp; class MemoryControllerOp; class LSQOp; -/// Returns the name of an operand -/// based on which interface the operation implements -std::string getOperandName(Operation *op, size_t oprdIdx); - -/// Returns the name of a result -/// based on which interface the operation implements -std::string getResultName(Operation *op, size_t resIdx); - HandshakeBaseInterface getHandshakeBase(Operation *op); } // end namespace handshake From 0d141b475bd751db4bc487406c1bfa51cc38a2dc Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:37:43 +0200 Subject: [PATCH 179/187] remove free functions --- .../Dialect/Handshake/HandshakeInterfaces.td | 6 +++--- lib/Analysis/NameAnalysis.cpp | 12 ++++++++---- tools/export-dot/export-dot.cpp | 12 ++++++++---- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 22b5a84933..4dac6fd5fb 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -281,7 +281,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { } op->emitError() << "must specify operand names, op: " << *op; - assert(0); + llvm::raise_fatal_error("All operation must specify IO names"); }]>, InterfaceMethod< "Returns the name of a specific result.", @@ -289,7 +289,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { "", [{ auto *op = const_cast($_op.getOperation()); - + if (auto nameInterface = dyn_cast(op)) { return nameInterface.getResultNameImpl(idx); } else if (auto nameInterface = @@ -301,7 +301,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { } op->emitError() << "must specify result names, op: " << *op; - assert(0); + llvm::raise_fatal_error("All operation must specify IO names"); }]> ]; } diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 2c0936a9f4..7926658861 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -119,7 +119,8 @@ std::string NameAnalysis::getName(OpOperand &oprd) { Value val = oprd.get(); if (Operation *defOp = val.getDefiningOp()) { defName = getName(defOp); - resName = getResultName(defOp, cast(val).getResultNumber()); + auto handshakeOp = getHandshakeBase(defOp); + resName = handshakeOp.getResultName(cast(val).getResultNumber()); } else { getBlockArgName(cast(val), defName, resName); } @@ -128,7 +129,8 @@ std::string NameAnalysis::getName(OpOperand &oprd) { std::string userName, oprName; Operation *userOp = oprd.getOwner(); userName = getName(userOp); - oprName = getOperandName(userOp, oprd.getOperandNumber()); + auto handshakeOp = getHandshakeBase(userOp) + oprName = handshakeOp.getOperandName(oprd.getOperandNumber()); return defName + "_" + resName + "_" + oprName + "_" + userName; } @@ -294,7 +296,8 @@ std::string dynamatic::getUniqueName(OpOperand &oprd) { if (Operation *defOp = val.getDefiningOp()) { if (mlir::StringAttr attr = getNameAttr(defOp)) { defName = attr.str(); - resName = getResultName(defOp, cast(val).getResultNumber()); + auto handshakeOp = getHandshakeBase(defOp); + resName = handshakeOp.getResultName(cast(val).getResultNumber()); } else { return ""; } @@ -310,7 +313,8 @@ std::string dynamatic::getUniqueName(OpOperand &oprd) { Operation *userOp = oprd.getOwner(); if (mlir::StringAttr attr = getNameAttr(userOp)) { userName = attr.str(); - oprName = getOperandName(userOp, oprd.getOperandNumber()); + auto handshakeOp = getHandshakeBase(userOp); + oprName = handshakeOp.getOperandName(oprd.getOperandNumber()); } else { return ""; } diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index 17f54adcd9..5669ae7499 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -328,11 +328,13 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { Operation *srcOp = res.getDefiningOp(); srcNodeName = getUniqueName(srcOp).str(); srcIdx = res.getResultNumber(); - srcPortName = handshake::getResultName(srcOp, srcIdx); + auto handshakeOp = getHandshakeBase(srcOp) + srcPortName = handshakeOp.getResultName(srcIdx); } else { Operation *parentOp = val.getParentBlock()->getParentOp(); srcIdx = cast(val).getArgNumber(); - srcNodeName = srcPortName = handshake::getOperandName(parentOp, srcIdx); + auto handshakeOp = getHandshakeBase(parentOp) + srcNodeName = srcPortName = handshakeOp.getOperandName(srcIdx); } // Determine the edge's destination @@ -341,11 +343,13 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { if (isa(dstOp)) { Operation *parentOp = dstOp->getParentOp(); dstIdx = oprd.getOperandNumber(); - dstNodeName = dstPortName = handshake::getResultName(parentOp, dstIdx); + auto handshakeOp = getHandshakeBase(parentOp); + dstNodeName = dstPortName = handshakeOp.getResultName(dstIdx); } else { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); - dstPortName = handshake::getOperandName(dstOp, dstIdx); + auto handshakeOp = getHandshakeBase(dstOp); + dstPortName = handshakeOp.getOperandName(dstOp, dstIdx); } DOTGraph::Edge &edge = builder.addEdge(srcNodeName, dstNodeName, subgraph); From 3636a6e5d720e94021bbbf28c4c4f4a386bfe97e Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:38:30 +0200 Subject: [PATCH 180/187] remove free functions --- include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td index 4dac6fd5fb..131ca38856 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeInterfaces.td @@ -281,7 +281,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { } op->emitError() << "must specify operand names, op: " << *op; - llvm::raise_fatal_error("All operation must specify IO names"); + llvm::report_fatal_error("All operation must specify IO names"); }]>, InterfaceMethod< "Returns the name of a specific result.", @@ -301,7 +301,7 @@ def HandshakeBaseInterface : OpInterface<"HandshakeBaseInterface"> { } op->emitError() << "must specify result names, op: " << *op; - llvm::raise_fatal_error("All operation must specify IO names"); + llvm::report_fatal_error("All operation must specify IO names"); }]> ]; } From 674ff06924cf0f9fbeeb0de6d938df0c67d46f44 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:40:52 +0200 Subject: [PATCH 181/187] remove free functions --- experimental/lib/Support/FormalProperty.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 2f22d9276b..9a5d68b456 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -141,9 +141,11 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; + auto handshakeOwnerOp = handshake::getHandshakeBase(ownerOp) ownerChannel.channelName = - handshake::getResultName(ownerOp, res.getResultNumber()); - userChannel.channelName = handshake::getOperandName(userOp, operandIndex); + handshakeOwnerOp.getResultName(res.getResultNumber()); + auto handshakeUserOp = handshake::getHandshakeBase(userOp); + userChannel.channelName = handshakeUserOp.getOperandName(operandIndex); } llvm::json::Value AbsenceOfBackpressure::extraInfoToJSON() const { @@ -189,8 +191,10 @@ ValidEquivalence::ValidEquivalence(unsigned long id, TAG tag, targetChannel.operationName = getUniqueName(op2).str(); ownerChannel.channelIndex = i; targetChannel.channelIndex = j; - ownerChannel.channelName = handshake::getResultName(op1, i); - targetChannel.channelName = handshake::getResultName(op2, j); + auto handshakeOp1 = handshake::getHandshakeBase(op1); + auto handshakeOp2 = handshake::getHandshakeBase(op2); + ownerChannel.channelName = handshakeOp1.getResultName(i); + targetChannel.channelName = handshakeOp2.getResultName(j); } llvm::json::Value ValidEquivalence::extraInfoToJSON() const { From 08e667ae30b3800303f38964d8d5f2b75a0d76db Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:42:28 +0200 Subject: [PATCH 182/187] remove free functions --- tools/export-dot/export-dot.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index 5669ae7499..85bbb24a79 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -328,12 +328,12 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { Operation *srcOp = res.getDefiningOp(); srcNodeName = getUniqueName(srcOp).str(); srcIdx = res.getResultNumber(); - auto handshakeOp = getHandshakeBase(srcOp) + auto handshakeOp = getHandshakeBase(srcOp); srcPortName = handshakeOp.getResultName(srcIdx); } else { Operation *parentOp = val.getParentBlock()->getParentOp(); srcIdx = cast(val).getArgNumber(); - auto handshakeOp = getHandshakeBase(parentOp) + auto handshakeOp = getHandshakeBase(parentOp); srcNodeName = srcPortName = handshakeOp.getOperandName(srcIdx); } From 77ef0462d0561af81d5e339b5d14a31365f238fd Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:42:49 +0200 Subject: [PATCH 183/187] remove free functions --- tools/export-dot/export-dot.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/export-dot/export-dot.cpp b/tools/export-dot/export-dot.cpp index 85bbb24a79..939739b7b9 100644 --- a/tools/export-dot/export-dot.cpp +++ b/tools/export-dot/export-dot.cpp @@ -349,7 +349,7 @@ static LogicalResult getDOTGraph(handshake::FuncOp funcOp, DOTGraph &graph) { dstNodeName = getUniqueName(dstOp).str(); dstIdx = oprd.getOperandNumber(); auto handshakeOp = getHandshakeBase(dstOp); - dstPortName = handshakeOp.getOperandName(dstOp, dstIdx); + dstPortName = handshakeOp.getOperandName(dstIdx); } DOTGraph::Edge &edge = builder.addEdge(srcNodeName, dstNodeName, subgraph); From 05f8adf91a664519d343c16b2b8ca7a8724d5a85 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:43:16 +0200 Subject: [PATCH 184/187] remove free functions --- experimental/lib/Support/FormalProperty.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/lib/Support/FormalProperty.cpp b/experimental/lib/Support/FormalProperty.cpp index 9a5d68b456..160bb41b35 100644 --- a/experimental/lib/Support/FormalProperty.cpp +++ b/experimental/lib/Support/FormalProperty.cpp @@ -141,7 +141,7 @@ AbsenceOfBackpressure::AbsenceOfBackpressure(unsigned long id, TAG tag, userChannel.operationName = getUniqueName(userOp).str(); ownerChannel.channelIndex = res.getResultNumber(); userChannel.channelIndex = operandIndex; - auto handshakeOwnerOp = handshake::getHandshakeBase(ownerOp) + auto handshakeOwnerOp = handshake::getHandshakeBase(ownerOp); ownerChannel.channelName = handshakeOwnerOp.getResultName(res.getResultNumber()); auto handshakeUserOp = handshake::getHandshakeBase(userOp); From 8f6d196699e87f6978e65d7749038d63967bfc9a Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:43:55 +0200 Subject: [PATCH 185/187] remove free functions --- lib/Analysis/NameAnalysis.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Analysis/NameAnalysis.cpp b/lib/Analysis/NameAnalysis.cpp index 7926658861..38b25872ab 100644 --- a/lib/Analysis/NameAnalysis.cpp +++ b/lib/Analysis/NameAnalysis.cpp @@ -129,7 +129,7 @@ std::string NameAnalysis::getName(OpOperand &oprd) { std::string userName, oprName; Operation *userOp = oprd.getOwner(); userName = getName(userOp); - auto handshakeOp = getHandshakeBase(userOp) + auto handshakeOp = getHandshakeBase(userOp); oprName = handshakeOp.getOperandName(oprd.getOperandNumber()); return defName + "_" + resName + "_" + oprName + "_" + userName; } From e41811d13de941407d622a8f0e288c52505bde20 Mon Sep 17 00:00:00 2001 From: Emmet Murphy Date: Wed, 22 Oct 2025 13:45:05 +0200 Subject: [PATCH 186/187] remove free functions --- include/dynamatic/Dialect/Handshake/HandshakeOps.td | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dynamatic/Dialect/Handshake/HandshakeOps.td b/include/dynamatic/Dialect/Handshake/HandshakeOps.td index 91ae6527b0..fc4a98444e 100644 --- a/include/dynamatic/Dialect/Handshake/HandshakeOps.td +++ b/include/dynamatic/Dialect/Handshake/HandshakeOps.td @@ -63,6 +63,7 @@ def FuncOp : Op Date: Wed, 22 Oct 2025 14:01:22 +0200 Subject: [PATCH 187/187] format --- lib/Dialect/Handshake/HandshakeOps.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/Handshake/HandshakeOps.cpp b/lib/Dialect/Handshake/HandshakeOps.cpp index ee53cb05b1..b0f4a0bd3c 100644 --- a/lib/Dialect/Handshake/HandshakeOps.cpp +++ b/lib/Dialect/Handshake/HandshakeOps.cpp @@ -2133,7 +2133,7 @@ namespace handshake { //===----------------------------------------------------------------------===// handshake::HandshakeBaseInterface getHandshakeBase(Operation *op) { - if(auto handshakeBase = + if (auto handshakeBase = llvm::dyn_cast(op)) { return handshakeBase; }