14#ifndef CIRCT_DIALECT_SSP_SSPUTILITIES_H
15#define CIRCT_DIALECT_SSP_SSPUTILITIES_H
22#include "mlir/IR/ImplicitLocOpBuilder.h"
23#include "mlir/IR/SymbolTable.h"
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/TypeSwitch.h"
41template <
typename ProblemT>
43template <
typename ProblemT,
typename OperationPropertyT,
44 typename... OperationPropertyTs>
48 for (
auto prop : props) {
49 TypeSwitch<Attribute>(prop)
50 .Case<OperationPropertyT, OperationPropertyTs...>(
51 [&](
auto p) { p.setInProblem(prob, op); });
55template <
typename ProblemT>
57template <
typename ProblemT,
typename OperatorTypePropertyT,
58 typename... OperatorTypePropertyTs>
63 for (
auto prop : props) {
64 TypeSwitch<Attribute>(prop)
65 .Case<OperatorTypePropertyT, OperatorTypePropertyTs...>(
66 [&](
auto p) { p.setInProblem(prob, opr); });
70template <
typename ProblemT>
72template <
typename ProblemT,
typename ResourceTypePropertyT,
73 typename... ResourceTypePropertyTs>
78 for (
auto prop : props) {
79 TypeSwitch<Attribute>(prop)
80 .Case<ResourceTypePropertyT, ResourceTypePropertyTs...>(
81 [&](
auto p) { p.setInProblem(prob, rsrc); });
85template <
typename ProblemT>
87template <
typename ProblemT,
typename DependencePropertyT,
88 typename... DependencePropertyTs>
92 for (
auto prop : props) {
93 TypeSwitch<Attribute>(prop)
94 .Case<DependencePropertyT, DependencePropertyTs...>(
95 [&](
auto p) { p.setInProblem(prob, dep); });
99template <
typename ProblemT>
101template <
typename ProblemT,
typename InstancePropertyT,
102 typename... InstancePropertyTs>
106 for (
auto prop : props) {
107 TypeSwitch<Attribute>(prop).Case<InstancePropertyT, InstancePropertyTs...>(
108 [&](
auto p) { p.setInProblem(prob); });
116template <
typename ProblemT,
typename... OperatorTypePropertyTs>
118 ProblemT &prob, OperatorTypeOp oprOp,
121 unsigned &
id = oprIds[opr];
123 opr = StringAttr::get(oprOp.getContext(),
124 opr.
getValue() + Twine(
'_') + Twine(
id));
126 assert(!prob.hasOperatorType(opr));
127 prob.insertOperatorType(opr);
129 prob, opr, oprOp.getSspPropertiesAttr());
137template <
typename ProblemT,
typename... ResourceTypePropertyTs>
139 ProblemT &prob, ResourceTypeOp rsrcOp,
142 unsigned &
id = rsrcIds[rsrc];
144 rsrc = StringAttr::get(rsrcOp.getContext(),
145 rsrc.
getValue() + Twine(
'_') + Twine(
id));
147 assert(!prob.hasResourceType(rsrc));
148 prob.insertResourceType(rsrc);
150 prob, rsrc, rsrcOp.getSspPropertiesAttr());
175template <
typename ProblemT,
typename... OperationPropertyTs,
176 typename... OperatorTypePropertyTs,
177 typename... ResourceTypePropertyTs,
typename... DependencePropertyTs,
178 typename... InstancePropertyTs>
180 std::tuple<OperationPropertyTs...> opProps,
181 std::tuple<OperatorTypePropertyTs...> oprProps,
182 std::tuple<ResourceTypePropertyTs...> rsrcProps,
183 std::tuple<DependencePropertyTs...> depProps,
184 std::tuple<InstancePropertyTs...> instProps) {
185 ProblemT prob(instOp);
188 prob, instOp.getSspPropertiesAttr());
189 if (
auto instName = instOp.getSymNameAttr())
190 prob.setInstanceName(instName);
200 auto libraryOp = instOp.getOperatorLibrary();
201 libraryOp.walk([&](OperatorTypeOp oprOp) {
202 operatorTypes[oprOp] =
206 if (
auto libName = libraryOp.getSymNameAttr())
207 prob.setLibraryName(libName);
217 auto rsrcLibraryOp = instOp.getResourceLibrary();
218 rsrcLibraryOp.walk([&](ResourceTypeOp rsrcOp) {
219 resourceTypes[rsrcOp] =
224 if (
auto rsrcLibName = rsrcLibraryOp.getSymNameAttr())
225 prob.setRsrcLibraryName(rsrcLibName);
231 auto graphOp = instOp.getDependenceGraph();
232 graphOp.walk([&](OperationOp opOp) {
233 prob.insertOperation(opOp);
235 prob, opOp, opOp.getSspPropertiesAttr());
236 if (StringAttr opName = opOp.getNameAttr()) {
237 prob.setOperationName(opOp, opName);
238 [[maybe_unused]]
auto [it, ins] = namedOps.try_emplace(opName, opOp);
239 assert(ins &&
"Non-unique operation name detected");
245 if (!prob.getLinkedOperatorType(opOp).has_value())
250 SymbolRefAttr oprRef = opOp.getLinkedOperatorTypeAttr().getValue();
254 oprOp = SymbolTable::lookupSymbolIn(libraryOp, oprRef);
257 oprOp = SymbolTable::lookupSymbolIn(instOp, oprRef);
261 SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(), oprRef);
263 assert(oprOp && isa<OperatorTypeOp>(oprOp));
266 auto &opr = operatorTypes[oprOp];
269 prob, cast<OperatorTypeOp>(oprOp), operatorTypeIds);
272 prob.setLinkedOperatorType(opOp, opr);
277 if (!prob.getLinkedResourceTypes(opOp).has_value())
282 SmallVector<ResourceType> loadedRsrcs;
283 for (
auto attr : opOp.getLinkedResourceTypesAttr().getValue()) {
284 SymbolRefAttr rsrcRef = dyn_cast<SymbolRefAttr>(attr);
286 "expected SymbolRefAttr inside LinkedResourceTypesAttr");
290 rsrcOp = SymbolTable::lookupSymbolIn(rsrcLibraryOp, rsrcRef);
294 rsrcOp = SymbolTable::lookupSymbolIn(instOp, rsrcRef);
297 rsrcOp = SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(),
300 assert(rsrcOp && isa<ResourceTypeOp>(rsrcOp));
303 auto &rsrc = resourceTypes[rsrcOp];
306 prob, cast<ResourceTypeOp>(rsrcOp), resourceTypeIds);
308 loadedRsrcs.push_back(rsrc);
312 prob.setLinkedResourceTypes(opOp, loadedRsrcs);
317 graphOp.walk([&](OperationOp opOp) {
318 ArrayAttr depsAttr = opOp.getDependencesAttr();
322 for (
auto depAttr : depsAttr.getAsRange<DependenceAttr>()) {
324 if (StringAttr sourceRef = depAttr.getSourceRef()) {
325 OperationOp sourceOp = namedOps.lookup(sourceRef);
328 LogicalResult res = prob.insertDependence(dep);
332 dep =
Dependence(&opOp->getOpOperand(depAttr.getOperandIdx()));
335 prob, dep, depAttr.getProperties());
346template <
typename ProblemT,
typename... OperationPropertyTs>
348 ImplicitLocOpBuilder &b) {
349 SmallVector<Attribute> props;
353 ((prop = OperationPropertyTs::getFromProblem(prob, op, b.getContext()),
354 prop ? props.push_back(prop) : (void)prop),
356 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
359template <
typename ProblemT,
typename... OperatorTypePropertyTs>
361 ImplicitLocOpBuilder &b) {
362 SmallVector<Attribute> props;
366 ((prop = OperatorTypePropertyTs::getFromProblem(prob, opr, b.getContext()),
367 prop ? props.push_back(prop) : (void)prop),
369 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
372template <
typename ProblemT,
typename... ResourceTypePropertyTs>
374 ImplicitLocOpBuilder &b) {
375 SmallVector<Attribute> props;
379 ((prop = ResourceTypePropertyTs::getFromProblem(prob, rsrc, b.getContext()),
380 prop ? props.push_back(prop) : (void)prop),
382 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
385template <
typename ProblemT,
typename... DependencePropertyTs>
387 ImplicitLocOpBuilder &b) {
388 SmallVector<Attribute> props;
392 ((prop = DependencePropertyTs::getFromProblem(prob, dep, b.getContext()),
393 prop ? props.push_back(prop) : (void)prop),
395 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
398template <
typename ProblemT,
typename... InstancePropertyTs>
400 SmallVector<Attribute> props;
404 ((prop = InstancePropertyTs::getFromProblem(prob, b.getContext()),
405 prop ? props.push_back(prop) : (void)prop),
407 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
433template <
typename ProblemT,
typename... OperationPropertyTs,
434 typename... OperatorTypePropertyTs,
435 typename... ResourceTypePropertyTs,
typename... DependencePropertyTs,
436 typename... InstancePropertyTs>
438saveProblem(ProblemT &prob, std::tuple<OperationPropertyTs...> opProps,
439 std::tuple<OperatorTypePropertyTs...> oprProps,
440 std::tuple<ResourceTypePropertyTs...> rsrcProps,
441 std::tuple<DependencePropertyTs...> depProps,
442 std::tuple<InstancePropertyTs...> instProps, OpBuilder &builder) {
443 ImplicitLocOpBuilder b(builder.getUnknownLoc(), builder);
446 auto instOp = InstanceOp::create(
447 b, builder.getStringAttr(ProblemT::name),
449 if (
auto instName = prob.getInstanceName())
450 instOp.setSymNameAttr(instName);
453 b.setInsertionPointToEnd(instOp.getBodyBlock());
454 auto libraryOp = OperatorLibraryOp::create(b);
455 if (
auto libName = prob.getLibraryName())
456 libraryOp.setSymNameAttr(libName);
457 b.setInsertionPointToStart(libraryOp.getBodyBlock());
459 for (
auto opr : prob.getOperatorTypes())
460 OperatorTypeOp::create(
461 b, opr.getAttr(), {},
466 b.setInsertionPointToEnd(instOp.getBodyBlock());
467 auto rsrcLibraryOp = ResourceLibraryOp::create(b);
468 if (
auto rsrcLibName = prob.getRsrcLibraryName())
469 rsrcLibraryOp.setSymNameAttr(rsrcLibName);
470 b.setInsertionPointToStart(rsrcLibraryOp.getBodyBlock());
472 for (
auto rsrc : prob.getResourceTypes())
473 ResourceTypeOp::create(
474 b, rsrc.getAttr(), {},
480 DenseMap<Operation *, StringAttr> opNames;
481 for (
auto *op : prob.getOperations()) {
482 if (
auto opName = prob.getOperationName(op))
483 opNames[op] = opName;
485 for (
auto &dep : prob.getDependences(op)) {
486 Operation *src = dep.getSource();
487 if (!dep.isAuxiliary() || opNames.count(src))
489 if (
auto srcOpName = prob.getOperationName(src)) {
490 opNames[src] = srcOpName;
493 opNames[src] = b.getStringAttr(Twine(
"Op") + Twine(opNames.size()));
498 b.setInsertionPointToEnd(instOp.getBodyBlock());
499 auto graphOp = DependenceGraphOp::create(b);
500 b.setInsertionPointToStart(graphOp.getBodyBlock());
504 for (
auto *op : prob.getOperations()) {
507 ArrayAttr dependences;
508 SmallVector<Attribute> depAttrs;
509 unsigned auxOperandIdx = op->getNumOperands();
510 for (
auto &dep : prob.getDependences(op)) {
514 if (dep.isDefUse() && depProps) {
515 auto depAttr = b.getAttr<DependenceAttr>(*dep.getDestinationIndex(),
516 StringAttr(), depProps);
517 depAttrs.push_back(depAttr);
521 if (!dep.isAuxiliary())
524 auto sourceRef = opNames.lookup(dep.getSource());
527 b.getAttr<DependenceAttr>(auxOperandIdx, sourceRef, depProps);
528 depAttrs.push_back(depAttr);
531 if (!depAttrs.empty())
532 dependences = b.getArrayAttr(depAttrs);
535 ArrayAttr properties =
542 OperationOp::create(b, op->getNumResults(), v.
get(op->getOperands()),
543 opNames.lookup(op), dependences, properties);
544 v.
set(op->getResults(), opOp->getResults());
560template <
typename ProblemT>
568template <
typename ProblemT>
582template <
typename ProblemT>
598 LinkedOperatorTypeAttr(), LinkedResourceTypesAttr(), StartTimeAttr());
615 std::make_tuple(DistanceAttr()));
618 std::make_tuple(InitiationIntervalAttr()));
625 std::make_tuple(StartTimeInCycleAttr()));
628 std::make_tuple(IncomingDelayAttr(), OutgoingDelayAttr()));
assert(baseType &&"element must be base type")
Instantiate one of these and use it to build typed backedges.
The ValueMapper class facilitates the definition and connection of SSA def-use chains between two loc...
void set(mlir::Value from, mlir::Value to, bool replace=false)
mlir::Value get(mlir::Value from, TypeTransformer typeTransformer=ValueMapper::identity)
detail::Dependence Dependence
A thin wrapper to allow a uniform handling of def-use and auxiliary dependences.
InstanceOp saveProblem(ProblemT &prob, std::tuple< OperationPropertyTs... > opProps, std::tuple< OperatorTypePropertyTs... > oprProps, std::tuple< ResourceTypePropertyTs... > rsrcProps, std::tuple< DependencePropertyTs... > depProps, std::tuple< InstancePropertyTs... > instProps, OpBuilder &builder)
Construct an InstanceOp from a given ProblemT instance, and create/attach attributes of the given cla...
ProblemT loadProblem(InstanceOp instOp, std::tuple< OperationPropertyTs... > opProps, std::tuple< OperatorTypePropertyTs... > oprProps, std::tuple< ResourceTypePropertyTs... > rsrcProps, std::tuple< DependencePropertyTs... > depProps, std::tuple< InstancePropertyTs... > instProps)
Construct an instance of ProblemT from instOp, and attempt to set properties from the given attribute...
void loadInstanceProperties(ProblemT &, ArrayAttr)
ProblemT::ResourceType loadResourceType(ProblemT &prob, ResourceTypeOp rsrcOp, SmallDenseMap< typename ProblemT::ResourceType, unsigned > &rsrcIds)
Load the resource type represented by rsrcOp into prob under a unique name informed by rsrcIds,...
void loadOperationProperties(ProblemT &, Operation *, ArrayAttr)
scheduling::Problem::Dependence Dependence
scheduling::Problem::ResourceType ResourceType
ArrayAttr saveDependenceProperties(ProblemT &prob, Dependence dep, ImplicitLocOpBuilder &b)
void loadOperatorTypeProperties(ProblemT &, OperatorType, ArrayAttr)
ArrayAttr saveOperatorTypeProperties(ProblemT &prob, OperatorType opr, ImplicitLocOpBuilder &b)
void loadDependenceProperties(ProblemT &, Dependence, ArrayAttr)
scheduling::Problem::OperatorType OperatorType
ArrayAttr saveInstanceProperties(ProblemT &prob, ImplicitLocOpBuilder &b)
void loadResourceTypeProperties(ProblemT &, ResourceType, ArrayAttr)
ArrayAttr saveOperationProperties(ProblemT &prob, Operation *op, ImplicitLocOpBuilder &b)
ProblemT::OperatorType loadOperatorType(ProblemT &prob, OperatorTypeOp oprOp, SmallDenseMap< typename ProblemT::OperatorType, unsigned > &oprIds)
Load the operator type represented by oprOp into prob under a unique name informed by oprIds,...
ArrayAttr saveResourceTypeProperties(ProblemT &prob, ResourceType rsrc, ImplicitLocOpBuilder &b)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Operator types are distinguished by name (chosen by the client).
mlir::StringRef getValue() const
Resource types are distinguished by name (chosen by the client).
mlir::StringRef getValue() const
static constexpr auto dependenceProperties
static constexpr auto operationProperties
static constexpr auto instanceProperties
static constexpr auto operatorTypeProperties
static constexpr auto resourceTypeProperties
static constexpr auto resourceTypeProperties
static constexpr auto operatorTypeProperties
static constexpr auto operationProperties
static constexpr auto instanceProperties
static constexpr auto dependenceProperties
static constexpr auto instanceProperties
static constexpr auto resourceTypeProperties
static constexpr auto dependenceProperties
static constexpr auto operatorTypeProperties
static constexpr auto operationProperties
static constexpr auto instanceProperties
static constexpr auto operatorTypeProperties
static constexpr auto dependenceProperties
static constexpr auto resourceTypeProperties
static constexpr auto operationProperties
static constexpr auto operatorTypeProperties
static constexpr auto instanceProperties
static constexpr auto operationProperties
static constexpr auto resourceTypeProperties
static constexpr auto dependenceProperties
static constexpr auto dependenceProperties
static constexpr auto operationProperties
static constexpr auto operatorTypeProperties
static constexpr auto resourceTypeProperties
static constexpr auto instanceProperties
Dummy struct to query a problem's default properties (i.e.