Loading [MathJax]/extensions/tex2jax.js
CIRCT 21.0.0git
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Utilities.h
Go to the documentation of this file.
1//===- Utilities.h - SSP <-> circt::scheduling infra conversion -*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides utilities for the conversion between SSP IR and the
10// extensible problem model in the scheduling infrastructure.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CIRCT_DIALECT_SSP_SSPUTILITIES_H
15#define CIRCT_DIALECT_SSP_SSPUTILITIES_H
16
21
22#include "mlir/IR/ImplicitLocOpBuilder.h"
23#include "mlir/IR/SymbolTable.h"
24
25#include "llvm/ADT/DenseMap.h"
26#include "llvm/ADT/TypeSwitch.h"
27
28#include <functional>
29
30namespace circt {
31namespace ssp {
32
36
37//===----------------------------------------------------------------------===//
38// ssp.InstanceOp -> circt::scheduling::Problem (or subclasses)
39//===----------------------------------------------------------------------===//
40
41template <typename ProblemT>
42void loadOperationProperties(ProblemT &, Operation *, ArrayAttr) {}
43template <typename ProblemT, typename OperationPropertyT,
44 typename... OperationPropertyTs>
45void loadOperationProperties(ProblemT &prob, Operation *op, ArrayAttr props) {
46 if (!props)
47 return;
48 for (auto prop : props) {
49 TypeSwitch<Attribute>(prop)
50 .Case<OperationPropertyT, OperationPropertyTs...>(
51 [&](auto p) { p.setInProblem(prob, op); });
52 }
53}
54
55template <typename ProblemT>
56void loadOperatorTypeProperties(ProblemT &, OperatorType, ArrayAttr) {}
57template <typename ProblemT, typename OperatorTypePropertyT,
58 typename... OperatorTypePropertyTs>
60 ArrayAttr props) {
61 if (!props)
62 return;
63 for (auto prop : props) {
64 TypeSwitch<Attribute>(prop)
65 .Case<OperatorTypePropertyT, OperatorTypePropertyTs...>(
66 [&](auto p) { p.setInProblem(prob, opr); });
67 }
68}
69
70template <typename ProblemT>
71void loadResourceTypeProperties(ProblemT &, ResourceType, ArrayAttr) {}
72template <typename ProblemT, typename ResourceTypePropertyT,
73 typename... ResourceTypePropertyTs>
74void loadResourceTypeProperties(ProblemT &prob, ResourceType rsrc,
75 ArrayAttr props) {
76 if (!props)
77 return;
78 for (auto prop : props) {
79 TypeSwitch<Attribute>(prop)
80 .Case<ResourceTypePropertyT, ResourceTypePropertyTs...>(
81 [&](auto p) { p.setInProblem(prob, rsrc); });
82 }
83}
84
85template <typename ProblemT>
86void loadDependenceProperties(ProblemT &, Dependence, ArrayAttr) {}
87template <typename ProblemT, typename DependencePropertyT,
88 typename... DependencePropertyTs>
89void loadDependenceProperties(ProblemT &prob, Dependence dep, ArrayAttr props) {
90 if (!props)
91 return;
92 for (auto prop : props) {
93 TypeSwitch<Attribute>(prop)
94 .Case<DependencePropertyT, DependencePropertyTs...>(
95 [&](auto p) { p.setInProblem(prob, dep); });
96 }
97}
98
99template <typename ProblemT>
100void loadInstanceProperties(ProblemT &, ArrayAttr) {}
101template <typename ProblemT, typename InstancePropertyT,
102 typename... InstancePropertyTs>
103void loadInstanceProperties(ProblemT &prob, ArrayAttr props) {
104 if (!props)
105 return;
106 for (auto prop : props) {
107 TypeSwitch<Attribute>(prop).Case<InstancePropertyT, InstancePropertyTs...>(
108 [&](auto p) { p.setInProblem(prob); });
109 }
110}
111
112/// Load the operator type represented by \p oprOp into \p prob under a unique
113/// name informed by \p oprIds, and attempt to set its properties from the
114/// given attribute classes. The registered name is returned. The template
115/// instantiation fails if properties are incompatible with \p ProblemT.
116template <typename ProblemT, typename... OperatorTypePropertyTs>
117typename ProblemT::OperatorType loadOperatorType(
118 ProblemT &prob, OperatorTypeOp oprOp,
120 OperatorType opr = oprOp.getNameAttr();
121 unsigned &id = oprIds[opr];
122 if (id > 0)
123 opr = StringAttr::get(oprOp.getContext(),
124 opr.getValue() + Twine('_') + Twine(id));
125 ++id;
126 assert(!prob.hasOperatorType(opr));
127 prob.insertOperatorType(opr);
128 loadOperatorTypeProperties<ProblemT, OperatorTypePropertyTs...>(
129 prob, opr, oprOp.getSspPropertiesAttr());
130 return opr;
131}
132
133/// Load the resource type represented by \p rsrcOp into \p prob under a unique
134/// name informed by \p rsrcIds, and attempt to set its properties from the
135/// given attribute classes. The registered name is returned. The template
136/// instantiation fails if properties are incompatible with \p ProblemT.
137template <typename ProblemT, typename... ResourceTypePropertyTs>
138typename ProblemT::ResourceType loadResourceType(
139 ProblemT &prob, ResourceTypeOp rsrcOp,
141 ResourceType rsrc = rsrcOp.getNameAttr();
142 unsigned &id = rsrcIds[rsrc];
143 if (id > 0)
144 rsrc = StringAttr::get(rsrcOp.getContext(),
145 rsrc.getValue() + Twine('_') + Twine(id));
146 ++id;
147 assert(!prob.hasResourceType(rsrc));
148 prob.insertResourceType(rsrc);
149 loadResourceTypeProperties<ProblemT, ResourceTypePropertyTs...>(
150 prob, rsrc, rsrcOp.getSspPropertiesAttr());
151 return rsrc;
152}
153
154/// Construct an instance of \p ProblemT from \p instOp, and attempt to set
155/// properties from the given attribute classes. The attribute tuples are used
156/// solely for grouping/inferring the template parameter packs. The tuple
157/// elements may therefore be unitialized objects. The template instantiation
158/// fails if properties are incompatible with \p ProblemT.
159///
160/// Operations may link to operator types in other libraries, but the origin of
161/// an operator type will not be preserved in the problem instance. As this
162/// could lead to conflicts, operator types will be automatically renamed in the
163/// returned instance.
164///
165/// Example: To load an instance of the `circt::scheduling::CyclicProblem` with
166/// all its input and solution properties, call this as follows:
167///
168/// ```
169/// loadProblem<CyclicProblem>(instOp,
170/// std::make_tuple(LinkedOperatorTypeAttr(), StartTimeAttr()),
171/// std::make_tuple(LatencyAttr()),
172/// std::make_tuple(DistanceAttr()),
173/// std::make_tuple(InitiationIntervalAttr()));
174/// ```
175template <typename ProblemT, typename... OperationPropertyTs,
176 typename... OperatorTypePropertyTs,
177 typename... ResourceTypePropertyTs, typename... DependencePropertyTs,
178 typename... InstancePropertyTs>
179ProblemT loadProblem(InstanceOp instOp,
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);
186
187 loadInstanceProperties<ProblemT, InstancePropertyTs...>(
188 prob, instOp.getSspPropertiesAttr());
189 if (auto instName = instOp.getSymNameAttr())
190 prob.setInstanceName(instName);
191
192 // Use IDs to disambiguate operator types with the same name defined in
193 // different libraries.
195 // Map `OperatorTypeOp`s to their (possibly uniqued) name in the problem
196 // instance.
198
199 // Register all operator types in the instance's library.
200 auto libraryOp = instOp.getOperatorLibrary();
201 libraryOp.walk([&](OperatorTypeOp oprOp) {
202 operatorTypes[oprOp] =
203 loadOperatorType<ProblemT, OperatorTypePropertyTs...>(prob, oprOp,
204 operatorTypeIds);
205 });
206 if (auto libName = libraryOp.getSymNameAttr())
207 prob.setLibraryName(libName);
208
209 // Use IDs to disambiguate resource types with the same name defined in
210 // different resource libraries.
212 // Map `ResourceTypeOp`s to their (possibly uniqued) name in the problem
213 // instance.
215
216 // Register all resource types in the instance's resource library.
217 auto rsrcLibraryOp = instOp.getResourceLibrary();
218 rsrcLibraryOp.walk([&](ResourceTypeOp rsrcOp) {
219 resourceTypes[rsrcOp] =
220 loadResourceType<ProblemT, ResourceTypePropertyTs...>(prob, rsrcOp,
221 resourceTypeIds);
222 });
223
224 if (auto rsrcLibName = rsrcLibraryOp.getSymNameAttr())
225 prob.setRsrcLibraryName(rsrcLibName);
226
227 // Register all operations first, in order to retain their original order.
228 auto graphOp = instOp.getDependenceGraph();
229 graphOp.walk([&](OperationOp opOp) {
230 prob.insertOperation(opOp);
231 loadOperationProperties<ProblemT, OperationPropertyTs...>(
232 prob, opOp, opOp.getSspPropertiesAttr());
233 if (auto opName = opOp.getSymNameAttr())
234 prob.setOperationName(opOp, opName);
235
236 // Nothing else to check if no linked operator type is set for `opOp`,
237 // because the operation doesn't carry a `LinkedOperatorTypeAttr`, or that
238 // class is not part of the `OperationPropertyTs` to load.
239 if (!prob.getLinkedOperatorType(opOp).has_value())
240 return;
241
242 // Otherwise, inspect the corresponding attribute to make sure the operator
243 // type is available.
244 SymbolRefAttr oprRef = opOp.getLinkedOperatorTypeAttr().getValue();
245
246 Operation *oprOp;
247 // 1) Look in the instance's library.
248 oprOp = SymbolTable::lookupSymbolIn(libraryOp, oprRef);
249 // 2) Try to resolve a nested reference to the instance's library.
250 if (!oprOp)
251 oprOp = SymbolTable::lookupSymbolIn(instOp, oprRef);
252 // 3) Look outside of the instance.
253 if (!oprOp)
254 oprOp =
255 SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(), oprRef);
256
257 assert(oprOp && isa<OperatorTypeOp>(oprOp)); // checked by verifier
258
259 // Load the operator type from `oprOp` if needed.
260 auto &opr = operatorTypes[oprOp];
261 if (!opr.getAttr())
262 opr = loadOperatorType<ProblemT, OperatorTypePropertyTs...>(
263 prob, cast<OperatorTypeOp>(oprOp), operatorTypeIds);
264
265 // Update `opOp`'s property (may be a no-op if `opr` wasn't renamed).
266 prob.setLinkedOperatorType(opOp, opr);
267
268 // Nothing else to check if no linked resource type is set for `opOp`,
269 // because the operation doesn't carry a `LinkedResourceTypeAttr`, or that
270 // class is not part of the `OperationPropertyTs` to load.
271 if (!prob.getLinkedResourceTypes(opOp).has_value())
272 return;
273
274 // Otherwise, inspect the corresponding attribute to make sure the resource
275 // type is available.
276 SmallVector<ResourceType> loadedRsrcs;
277 for (auto attr : opOp.getLinkedResourceTypesAttr().getValue()) {
278 SymbolRefAttr rsrcRef = dyn_cast<SymbolRefAttr>(attr);
279 assert(rsrcRef &&
280 "expected SymbolRefAttr inside LinkedResourceTypesAttr");
281
282 Operation *rsrcOp;
283 // 1) Look in the instance's resource library.
284 rsrcOp = SymbolTable::lookupSymbolIn(rsrcLibraryOp, rsrcRef);
285 // 2) Try to resolve a nested reference to the instance's resource
286 // library.
287 if (!rsrcOp)
288 rsrcOp = SymbolTable::lookupSymbolIn(instOp, rsrcRef);
289 // 3) Look outside of the instance.
290 if (!rsrcOp)
291 rsrcOp = SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(),
292 rsrcRef);
293
294 assert(rsrcOp && isa<ResourceTypeOp>(rsrcOp)); // checked by verifier
295
296 // Load the resource type from `rsrcOp` if needed.
297 auto &rsrc = resourceTypes[rsrcOp];
298 if (!rsrc.getAttr())
299 rsrc = loadResourceType<ProblemT, ResourceTypePropertyTs...>(
300 prob, cast<ResourceTypeOp>(rsrcOp), resourceTypeIds);
301
302 loadedRsrcs.push_back(rsrc);
303 }
304
305 // Update `opOp`'s property (may be a no-op if `rsrc` wasn't renamed).
306 prob.setLinkedResourceTypes(opOp, loadedRsrcs);
307 });
308
309 // Then walk them again, and load auxiliary dependences as well as any
310 // dependence properties.
311 graphOp.walk([&](OperationOp opOp) {
312 ArrayAttr depsAttr = opOp.getDependencesAttr();
313 if (!depsAttr)
314 return;
315
316 for (auto depAttr : depsAttr.getAsRange<DependenceAttr>()) {
317 Dependence dep;
318 if (FlatSymbolRefAttr sourceRef = depAttr.getSourceRef()) {
319 Operation *sourceOp = SymbolTable::lookupSymbolIn(graphOp, sourceRef);
320 assert(sourceOp);
321 dep = Dependence(sourceOp, opOp);
322 LogicalResult res = prob.insertDependence(dep);
323 assert(succeeded(res));
324 (void)res;
325 } else
326 dep = Dependence(&opOp->getOpOperand(depAttr.getOperandIdx()));
327
328 loadDependenceProperties<ProblemT, DependencePropertyTs...>(
329 prob, dep, depAttr.getProperties());
330 }
331 });
332
333 return prob;
334}
335
336//===----------------------------------------------------------------------===//
337// circt::scheduling::Problem (or subclasses) -> ssp.InstanceOp
338//===----------------------------------------------------------------------===//
339
340template <typename ProblemT, typename... OperationPropertyTs>
341ArrayAttr saveOperationProperties(ProblemT &prob, Operation *op,
342 ImplicitLocOpBuilder &b) {
343 SmallVector<Attribute> props;
344 Attribute prop;
345 // Fold expression: Expands to a `getFromProblem` and a conditional
346 // `push_back` call for each of the `OperationPropertyTs`.
347 ((prop = OperationPropertyTs::getFromProblem(prob, op, b.getContext()),
348 prop ? props.push_back(prop) : (void)prop),
349 ...);
350 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
351}
352
353template <typename ProblemT, typename... OperatorTypePropertyTs>
354ArrayAttr saveOperatorTypeProperties(ProblemT &prob, OperatorType opr,
355 ImplicitLocOpBuilder &b) {
356 SmallVector<Attribute> props;
357 Attribute prop;
358 // Fold expression: Expands to a `getFromProblem` and a conditional
359 // `push_back` call for each of the `OperatorTypePropertyTs`.
360 ((prop = OperatorTypePropertyTs::getFromProblem(prob, opr, b.getContext()),
361 prop ? props.push_back(prop) : (void)prop),
362 ...);
363 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
364}
365
366template <typename ProblemT, typename... ResourceTypePropertyTs>
367ArrayAttr saveResourceTypeProperties(ProblemT &prob, ResourceType rsrc,
368 ImplicitLocOpBuilder &b) {
369 SmallVector<Attribute> props;
370 Attribute prop;
371 // Fold expression: Expands to a `getFromProblem` and a conditional
372 // `push_back` call for each of the `ResourceTypePropertyTs`.
373 ((prop = ResourceTypePropertyTs::getFromProblem(prob, rsrc, b.getContext()),
374 prop ? props.push_back(prop) : (void)prop),
375 ...);
376 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
377}
378
379template <typename ProblemT, typename... DependencePropertyTs>
380ArrayAttr saveDependenceProperties(ProblemT &prob, Dependence dep,
381 ImplicitLocOpBuilder &b) {
382 SmallVector<Attribute> props;
383 Attribute prop;
384 // Fold expression: Expands to a `getFromProblem` and a conditional
385 // `push_back` call for each of the `DependencePropertyTs`.
386 ((prop = DependencePropertyTs::getFromProblem(prob, dep, b.getContext()),
387 prop ? props.push_back(prop) : (void)prop),
388 ...);
389 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
390}
391
392template <typename ProblemT, typename... InstancePropertyTs>
393ArrayAttr saveInstanceProperties(ProblemT &prob, ImplicitLocOpBuilder &b) {
394 SmallVector<Attribute> props;
395 Attribute prop;
396 // Fold expression: Expands to a `getFromProblem` and a conditional
397 // `push_back` call for each of the `InstancePropertyTs`.
398 ((prop = InstancePropertyTs::getFromProblem(prob, b.getContext()),
399 prop ? props.push_back(prop) : (void)prop),
400 ...);
401 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
402}
403
404/// Construct an `InstanceOp` from a given \p ProblemT instance, and
405/// create/attach attributes of the given classes for the corresponding
406/// properties on the scheduling problem. The returned `InstanceOp` uses the
407/// given \p instanceName and \p problemName. `OperationOp`s are created
408/// unnamed, unless they represent the source operation in an auxiliary
409/// dependence, or the \p operationNameFn callback returns a non-null
410/// `StringAttr` with the desired name. The attribute tuples are used
411/// solely for grouping/inferring the template parameter packs. The tuple
412/// elements may therefore be unitialized objects. The template instantiation
413/// fails if properties are incompatible with \p ProblemT.
414///
415/// Example: To save an instance of the `circt::scheduling::CyclicProblem` with
416/// all its input and solution properties, and reyling on default operation
417/// names, call this as follows:
418///
419/// ```
420/// saveProblem<CyclicProblem>(prob,
421/// std::make_tuple(LinkedOperatorTypeAttr(), StartTimeAttr()),
422/// std::make_tuple(LatencyAttr()),
423/// std::make_tuple(DistanceAttr()),
424/// std::make_tuple(InitiationIntervalAttr()),
425/// builder);
426/// ```
427template <typename ProblemT, typename... OperationPropertyTs,
428 typename... OperatorTypePropertyTs,
429 typename... ResourceTypePropertyTs, typename... DependencePropertyTs,
430 typename... InstancePropertyTs>
431InstanceOp
432saveProblem(ProblemT &prob, std::tuple<OperationPropertyTs...> opProps,
433 std::tuple<OperatorTypePropertyTs...> oprProps,
434 std::tuple<ResourceTypePropertyTs...> rsrcProps,
435 std::tuple<DependencePropertyTs...> depProps,
436 std::tuple<InstancePropertyTs...> instProps, OpBuilder &builder) {
437 ImplicitLocOpBuilder b(builder.getUnknownLoc(), builder);
438
439 // Set up instance.
440 auto instOp = b.create<InstanceOp>(
441 builder.getStringAttr(ProblemT::name),
442 saveInstanceProperties<ProblemT, InstancePropertyTs...>(prob, b));
443 if (auto instName = prob.getInstanceName())
444 instOp.setSymNameAttr(instName);
445
446 // Emit operator types.
447 b.setInsertionPointToEnd(instOp.getBodyBlock());
448 auto libraryOp = b.create<OperatorLibraryOp>();
449 if (auto libName = prob.getLibraryName())
450 libraryOp.setSymNameAttr(libName);
451 b.setInsertionPointToStart(libraryOp.getBodyBlock());
452
453 for (auto opr : prob.getOperatorTypes())
454 b.create<OperatorTypeOp>(
455 opr.getAttr(),
456 saveOperatorTypeProperties<ProblemT, OperatorTypePropertyTs...>(
457 prob, opr, b));
458
459 // Emit resource types.
460 b.setInsertionPointToEnd(instOp.getBodyBlock());
461 auto rsrcLibraryOp = b.create<ResourceLibraryOp>();
462 if (auto rsrcLibName = prob.getRsrcLibraryName())
463 rsrcLibraryOp.setSymNameAttr(rsrcLibName);
464 b.setInsertionPointToStart(rsrcLibraryOp.getBodyBlock());
465
466 for (auto rsrc : prob.getResourceTypes())
467 b.create<ResourceTypeOp>(
468 rsrc.getAttr(),
469 saveResourceTypeProperties<ProblemT, ResourceTypePropertyTs...>(
470 prob, rsrc, b));
471
472 // Determine which operations act as source ops for auxiliary dependences, and
473 // therefore need a name. Also, honor names provided by the client.
474 DenseMap<Operation *, StringAttr> opNames;
475 for (auto *op : prob.getOperations()) {
476 if (auto opName = prob.getOperationName(op))
477 opNames[op] = opName;
478
479 for (auto &dep : prob.getDependences(op)) {
480 Operation *src = dep.getSource();
481 if (!dep.isAuxiliary() || opNames.count(src))
482 continue;
483 if (auto srcOpName = prob.getOperationName(src)) {
484 opNames[src] = srcOpName;
485 continue;
486 }
487 opNames[src] = b.getStringAttr(Twine("Op") + Twine(opNames.size()));
488 }
489 }
490
491 // Construct operations and model their dependences.
492 b.setInsertionPointToEnd(instOp.getBodyBlock());
493 auto graphOp = b.create<DependenceGraphOp>();
494 b.setInsertionPointToStart(graphOp.getBodyBlock());
495
496 BackedgeBuilder backedgeBuilder(b, b.getLoc());
497 ValueMapper v(&backedgeBuilder);
498 for (auto *op : prob.getOperations()) {
499 // Construct the `dependences attribute`. It contains `DependenceAttr` for
500 // def-use deps _with_ properties, and all aux deps.
501 ArrayAttr dependences;
502 SmallVector<Attribute> depAttrs;
503 unsigned auxOperandIdx = op->getNumOperands();
504 for (auto &dep : prob.getDependences(op)) {
505 ArrayAttr depProps =
506 saveDependenceProperties<ProblemT, DependencePropertyTs...>(prob, dep,
507 b);
508 if (dep.isDefUse() && depProps) {
509 auto depAttr = b.getAttr<DependenceAttr>(*dep.getDestinationIndex(),
510 FlatSymbolRefAttr(), depProps);
511 depAttrs.push_back(depAttr);
512 continue;
513 }
514
515 if (!dep.isAuxiliary())
516 continue;
517
518 auto sourceOpName = opNames.lookup(dep.getSource());
519 assert(sourceOpName);
520 auto sourceRef = b.getAttr<FlatSymbolRefAttr>(sourceOpName);
521 auto depAttr =
522 b.getAttr<DependenceAttr>(auxOperandIdx, sourceRef, depProps);
523 depAttrs.push_back(depAttr);
524 ++auxOperandIdx;
525 }
526 if (!depAttrs.empty())
527 dependences = b.getArrayAttr(depAttrs);
528
529 // Delegate to helper to construct the `properties` attribute.
530 ArrayAttr properties =
531 saveOperationProperties<ProblemT, OperationPropertyTs...>(prob, op, b);
532
533 // Finally, create the `OperationOp` and inform the value mapper.
534 // NB: sym_name, dependences and properties are optional attributes, so
535 // passing potentially unitialized String/ArrayAttrs is intentional here.
536 auto opOp =
537 b.create<OperationOp>(op->getNumResults(), v.get(op->getOperands()),
538 opNames.lookup(op), dependences, properties);
539 v.set(op->getResults(), opOp->getResults());
540 }
541
542 return instOp;
543}
544
545/// Dummy struct to query a problem's default properties (i.e. all input and
546/// solution properties). Specializations shall provide the following
547/// definitions:
548///
549/// ```
550/// static constexpr auto operationProperties = std::make_tuple(...);
551/// static constexpr auto operatorTypeProperties = std::make_tuple(...);
552/// static constexpr auto dependenceProperties = std::make_tuple(...);
553/// static constexpr auto instanceProperties = std::make_tuple(...);
554/// ```
555template <typename ProblemT>
556struct Default {};
557
558/// Construct an instance of \p ProblemT from \p instOp, and attempt to set all
559/// of the problem class' properties.
560///
561/// Relies on the specialization of template `circt::ssp::Default` for \p
562/// ProblemT.
563template <typename ProblemT>
571
572/// Construct an `InstanceOp` from a given \p ProblemT instance, and
573/// create/attach attributes for all of the problem class' properties.
574///
575/// Relies on the specialization of template `circt::ssp::Default` for \p
576/// ProblemT.
577template <typename ProblemT>
585
586//===----------------------------------------------------------------------===//
587// Default property tuples for the built-in problems
588//===----------------------------------------------------------------------===//
589
590template <>
591struct Default<scheduling::Problem> {
592 static constexpr auto operationProperties = std::make_tuple(
593 LinkedOperatorTypeAttr(), LinkedResourceTypesAttr(), StartTimeAttr());
594 static constexpr auto operatorTypeProperties = std::make_tuple(LatencyAttr());
595 static constexpr auto resourceTypeProperties = std::make_tuple();
596 static constexpr auto dependenceProperties = std::make_tuple();
597 static constexpr auto instanceProperties = std::make_tuple();
598};
599
600template <>
601struct Default<scheduling::CyclicProblem> {
602 static constexpr auto operationProperties =
604 static constexpr auto operatorTypeProperties =
606 static constexpr auto resourceTypeProperties =
608 static constexpr auto dependenceProperties =
610 std::make_tuple(DistanceAttr()));
611 static constexpr auto instanceProperties =
613 std::make_tuple(InitiationIntervalAttr()));
614};
615
616template <>
617struct Default<scheduling::ChainingProblem> {
618 static constexpr auto operationProperties =
620 std::make_tuple(StartTimeInCycleAttr()));
621 static constexpr auto operatorTypeProperties =
623 std::make_tuple(IncomingDelayAttr(), OutgoingDelayAttr()));
624 static constexpr auto resourceTypeProperties =
626 static constexpr auto dependenceProperties =
628 static constexpr auto instanceProperties =
630};
631
632template <>
633struct Default<scheduling::SharedOperatorsProblem> {
634 static constexpr auto operationProperties =
636 static constexpr auto operatorTypeProperties =
638 static constexpr auto resourceTypeProperties = std::make_tuple(LimitAttr());
639 static constexpr auto dependenceProperties =
641 static constexpr auto instanceProperties =
643};
644
645template <>
646struct Default<scheduling::ModuloProblem> {
647 static constexpr auto operationProperties =
649 static constexpr auto operatorTypeProperties =
651 static constexpr auto resourceTypeProperties =
653 static constexpr auto dependenceProperties =
655 static constexpr auto instanceProperties =
657};
658
659template <>
660struct Default<scheduling::ChainingCyclicProblem> {
661 static constexpr auto operationProperties =
663 static constexpr auto operatorTypeProperties =
665 static constexpr auto resourceTypeProperties =
667 static constexpr auto dependenceProperties =
669 static constexpr auto instanceProperties =
671};
672
673} // namespace ssp
674} // namespace circt
675
676#endif // CIRCT_DIALECT_SSP_SSPUTILITIES_H
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...
Definition ValueMapper.h:35
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.
Definition Problems.h:95
A wrapper class to uniformly handle def-use and auxiliary dependence edges.
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...
Definition Utilities.h:432
scheduling::Problem::Dependence Dependence
Definition Utilities.h:35
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...
Definition Utilities.h:179
void loadInstanceProperties(ProblemT &, ArrayAttr)
Definition Utilities.h:100
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,...
Definition Utilities.h:138
void loadOperationProperties(ProblemT &, Operation *, ArrayAttr)
Definition Utilities.h:42
ArrayAttr saveDependenceProperties(ProblemT &prob, Dependence dep, ImplicitLocOpBuilder &b)
Definition Utilities.h:380
void loadOperatorTypeProperties(ProblemT &, OperatorType, ArrayAttr)
Definition Utilities.h:56
ArrayAttr saveOperatorTypeProperties(ProblemT &prob, OperatorType opr, ImplicitLocOpBuilder &b)
Definition Utilities.h:354
void loadDependenceProperties(ProblemT &, Dependence, ArrayAttr)
Definition Utilities.h:86
ArrayAttr saveInstanceProperties(ProblemT &prob, ImplicitLocOpBuilder &b)
Definition Utilities.h:393
void loadResourceTypeProperties(ProblemT &, ResourceType, ArrayAttr)
Definition Utilities.h:71
ArrayAttr saveOperationProperties(ProblemT &prob, Operation *op, ImplicitLocOpBuilder &b)
Definition Utilities.h:341
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,...
Definition Utilities.h:117
ArrayAttr saveResourceTypeProperties(ProblemT &prob, ResourceType rsrc, ImplicitLocOpBuilder &b)
Definition Utilities.h:367
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Operator types are distinguished by name (chosen by the client).
Definition Problems.h:98
mlir::StringRef getValue() const
Definition Problems.h:110
Resource types are distinguished by name (chosen by the client).
Definition Problems.h:120
mlir::StringRef getValue() const
Definition Problems.h:132
Dummy struct to query a problem's default properties (i.e.
Definition Utilities.h:556