CIRCT 24.0.0git
Loading...
Searching...
No Matches
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 // Build ad-hoc symbol table to resolve auxiliary dependences.
229
230 // Register all operations first, in order to retain their original order.
231 auto graphOp = instOp.getDependenceGraph();
232 graphOp.walk([&](OperationOp opOp) {
233 prob.insertOperation(opOp);
234 loadOperationProperties<ProblemT, OperationPropertyTs...>(
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");
240 }
241
242 // Nothing else to check if no linked operator type is set for `opOp`,
243 // because the operation doesn't carry a `LinkedOperatorTypeAttr`, or that
244 // class is not part of the `OperationPropertyTs` to load.
245 if (!prob.getLinkedOperatorType(opOp).has_value())
246 return;
247
248 // Otherwise, inspect the corresponding attribute to make sure the operator
249 // type is available.
250 SymbolRefAttr oprRef = opOp.getLinkedOperatorTypeAttr().getValue();
251
252 Operation *oprOp;
253 // 1) Look in the instance's library.
254 oprOp = SymbolTable::lookupSymbolIn(libraryOp, oprRef);
255 // 2) Try to resolve a nested reference to the instance's library.
256 if (!oprOp)
257 oprOp = SymbolTable::lookupSymbolIn(instOp, oprRef);
258 // 3) Look outside of the instance.
259 if (!oprOp)
260 oprOp =
261 SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(), oprRef);
262
263 assert(oprOp && isa<OperatorTypeOp>(oprOp)); // checked by verifier
264
265 // Load the operator type from `oprOp` if needed.
266 auto &opr = operatorTypes[oprOp];
267 if (!opr.getAttr())
268 opr = loadOperatorType<ProblemT, OperatorTypePropertyTs...>(
269 prob, cast<OperatorTypeOp>(oprOp), operatorTypeIds);
270
271 // Update `opOp`'s property (may be a no-op if `opr` wasn't renamed).
272 prob.setLinkedOperatorType(opOp, opr);
273
274 // Nothing else to check if no linked resource type is set for `opOp`,
275 // because the operation doesn't carry a `LinkedResourceTypeAttr`, or that
276 // class is not part of the `OperationPropertyTs` to load.
277 if (!prob.getLinkedResourceTypes(opOp).has_value())
278 return;
279
280 // Otherwise, inspect the corresponding attribute to make sure the resource
281 // type is available.
282 SmallVector<ResourceType> loadedRsrcs;
283 for (auto attr : opOp.getLinkedResourceTypesAttr().getValue()) {
284 SymbolRefAttr rsrcRef = dyn_cast<SymbolRefAttr>(attr);
285 assert(rsrcRef &&
286 "expected SymbolRefAttr inside LinkedResourceTypesAttr");
287
288 Operation *rsrcOp;
289 // 1) Look in the instance's resource library.
290 rsrcOp = SymbolTable::lookupSymbolIn(rsrcLibraryOp, rsrcRef);
291 // 2) Try to resolve a nested reference to the instance's resource
292 // library.
293 if (!rsrcOp)
294 rsrcOp = SymbolTable::lookupSymbolIn(instOp, rsrcRef);
295 // 3) Look outside of the instance.
296 if (!rsrcOp)
297 rsrcOp = SymbolTable::lookupNearestSymbolFrom(instOp->getParentOp(),
298 rsrcRef);
299
300 assert(rsrcOp && isa<ResourceTypeOp>(rsrcOp)); // checked by verifier
301
302 // Load the resource type from `rsrcOp` if needed.
303 auto &rsrc = resourceTypes[rsrcOp];
304 if (!rsrc.getAttr())
305 rsrc = loadResourceType<ProblemT, ResourceTypePropertyTs...>(
306 prob, cast<ResourceTypeOp>(rsrcOp), resourceTypeIds);
307
308 loadedRsrcs.push_back(rsrc);
309 }
310
311 // Update `opOp`'s property (may be a no-op if `rsrc` wasn't renamed).
312 prob.setLinkedResourceTypes(opOp, loadedRsrcs);
313 });
314
315 // Then walk them again, and load auxiliary dependences as well as any
316 // dependence properties.
317 graphOp.walk([&](OperationOp opOp) {
318 ArrayAttr depsAttr = opOp.getDependencesAttr();
319 if (!depsAttr)
320 return;
321
322 for (auto depAttr : depsAttr.getAsRange<DependenceAttr>()) {
323 Dependence dep;
324 if (StringAttr sourceRef = depAttr.getSourceRef()) {
325 OperationOp sourceOp = namedOps.lookup(sourceRef);
326 assert(sourceOp);
327 dep = Dependence(sourceOp, opOp);
328 LogicalResult res = prob.insertDependence(dep);
329 assert(succeeded(res));
330 (void)res;
331 } else
332 dep = Dependence(&opOp->getOpOperand(depAttr.getOperandIdx()));
333
334 loadDependenceProperties<ProblemT, DependencePropertyTs...>(
335 prob, dep, depAttr.getProperties());
336 }
337 });
338
339 return prob;
340}
341
342//===----------------------------------------------------------------------===//
343// circt::scheduling::Problem (or subclasses) -> ssp.InstanceOp
344//===----------------------------------------------------------------------===//
345
346template <typename ProblemT, typename... OperationPropertyTs>
347ArrayAttr saveOperationProperties(ProblemT &prob, Operation *op,
348 ImplicitLocOpBuilder &b) {
349 SmallVector<Attribute> props;
350 Attribute prop;
351 // Fold expression: Expands to a `getFromProblem` and a conditional
352 // `push_back` call for each of the `OperationPropertyTs`.
353 ((prop = OperationPropertyTs::getFromProblem(prob, op, b.getContext()),
354 prop ? props.push_back(prop) : (void)prop),
355 ...);
356 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
357}
358
359template <typename ProblemT, typename... OperatorTypePropertyTs>
360ArrayAttr saveOperatorTypeProperties(ProblemT &prob, OperatorType opr,
361 ImplicitLocOpBuilder &b) {
362 SmallVector<Attribute> props;
363 Attribute prop;
364 // Fold expression: Expands to a `getFromProblem` and a conditional
365 // `push_back` call for each of the `OperatorTypePropertyTs`.
366 ((prop = OperatorTypePropertyTs::getFromProblem(prob, opr, b.getContext()),
367 prop ? props.push_back(prop) : (void)prop),
368 ...);
369 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
370}
371
372template <typename ProblemT, typename... ResourceTypePropertyTs>
373ArrayAttr saveResourceTypeProperties(ProblemT &prob, ResourceType rsrc,
374 ImplicitLocOpBuilder &b) {
375 SmallVector<Attribute> props;
376 Attribute prop;
377 // Fold expression: Expands to a `getFromProblem` and a conditional
378 // `push_back` call for each of the `ResourceTypePropertyTs`.
379 ((prop = ResourceTypePropertyTs::getFromProblem(prob, rsrc, b.getContext()),
380 prop ? props.push_back(prop) : (void)prop),
381 ...);
382 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
383}
384
385template <typename ProblemT, typename... DependencePropertyTs>
386ArrayAttr saveDependenceProperties(ProblemT &prob, Dependence dep,
387 ImplicitLocOpBuilder &b) {
388 SmallVector<Attribute> props;
389 Attribute prop;
390 // Fold expression: Expands to a `getFromProblem` and a conditional
391 // `push_back` call for each of the `DependencePropertyTs`.
392 ((prop = DependencePropertyTs::getFromProblem(prob, dep, b.getContext()),
393 prop ? props.push_back(prop) : (void)prop),
394 ...);
395 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
396}
397
398template <typename ProblemT, typename... InstancePropertyTs>
399ArrayAttr saveInstanceProperties(ProblemT &prob, ImplicitLocOpBuilder &b) {
400 SmallVector<Attribute> props;
401 Attribute prop;
402 // Fold expression: Expands to a `getFromProblem` and a conditional
403 // `push_back` call for each of the `InstancePropertyTs`.
404 ((prop = InstancePropertyTs::getFromProblem(prob, b.getContext()),
405 prop ? props.push_back(prop) : (void)prop),
406 ...);
407 return props.empty() ? ArrayAttr() : b.getArrayAttr(props);
408}
409
410/// Construct an `InstanceOp` from a given \p ProblemT instance, and
411/// create/attach attributes of the given classes for the corresponding
412/// properties on the scheduling problem. The returned `InstanceOp` uses the
413/// given \p instanceName and \p problemName. `OperationOp`s are created
414/// unnamed, unless they represent the source operation in an auxiliary
415/// dependence, or the \p operationNameFn callback returns a non-null
416/// `StringAttr` with the desired name. The attribute tuples are used
417/// solely for grouping/inferring the template parameter packs. The tuple
418/// elements may therefore be unitialized objects. The template instantiation
419/// fails if properties are incompatible with \p ProblemT.
420///
421/// Example: To save an instance of the `circt::scheduling::CyclicProblem` with
422/// all its input and solution properties, and reyling on default operation
423/// names, call this as follows:
424///
425/// ```
426/// saveProblem<CyclicProblem>(prob,
427/// std::make_tuple(LinkedOperatorTypeAttr(), StartTimeAttr()),
428/// std::make_tuple(LatencyAttr()),
429/// std::make_tuple(DistanceAttr()),
430/// std::make_tuple(InitiationIntervalAttr()),
431/// builder);
432/// ```
433template <typename ProblemT, typename... OperationPropertyTs,
434 typename... OperatorTypePropertyTs,
435 typename... ResourceTypePropertyTs, typename... DependencePropertyTs,
436 typename... InstancePropertyTs>
437InstanceOp
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);
444
445 // Set up instance.
446 auto instOp = InstanceOp::create(
447 b, builder.getStringAttr(ProblemT::name),
448 saveInstanceProperties<ProblemT, InstancePropertyTs...>(prob, b));
449 if (auto instName = prob.getInstanceName())
450 instOp.setSymNameAttr(instName);
451
452 // Emit operator types.
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());
458
459 for (auto opr : prob.getOperatorTypes())
460 OperatorTypeOp::create(
461 b, opr.getAttr(), /*sym_visibility=*/{},
462 saveOperatorTypeProperties<ProblemT, OperatorTypePropertyTs...>(
463 prob, opr, b));
464
465 // Emit resource types.
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());
471
472 for (auto rsrc : prob.getResourceTypes())
473 ResourceTypeOp::create(
474 b, rsrc.getAttr(), /*sym_visibility=*/{},
475 saveResourceTypeProperties<ProblemT, ResourceTypePropertyTs...>(
476 prob, rsrc, b));
477
478 // Determine which operations act as source ops for auxiliary dependences, and
479 // therefore need a name. Also, honor names provided by the client.
480 DenseMap<Operation *, StringAttr> opNames;
481 for (auto *op : prob.getOperations()) {
482 if (auto opName = prob.getOperationName(op))
483 opNames[op] = opName;
484
485 for (auto &dep : prob.getDependences(op)) {
486 Operation *src = dep.getSource();
487 if (!dep.isAuxiliary() || opNames.count(src))
488 continue;
489 if (auto srcOpName = prob.getOperationName(src)) {
490 opNames[src] = srcOpName;
491 continue;
492 }
493 opNames[src] = b.getStringAttr(Twine("Op") + Twine(opNames.size()));
494 }
495 }
496
497 // Construct operations and model their dependences.
498 b.setInsertionPointToEnd(instOp.getBodyBlock());
499 auto graphOp = DependenceGraphOp::create(b);
500 b.setInsertionPointToStart(graphOp.getBodyBlock());
501
502 BackedgeBuilder backedgeBuilder(b, b.getLoc());
503 ValueMapper v(&backedgeBuilder);
504 for (auto *op : prob.getOperations()) {
505 // Construct the `dependences attribute`. It contains `DependenceAttr` for
506 // def-use deps _with_ properties, and all aux deps.
507 ArrayAttr dependences;
508 SmallVector<Attribute> depAttrs;
509 unsigned auxOperandIdx = op->getNumOperands();
510 for (auto &dep : prob.getDependences(op)) {
511 ArrayAttr depProps =
512 saveDependenceProperties<ProblemT, DependencePropertyTs...>(prob, dep,
513 b);
514 if (dep.isDefUse() && depProps) {
515 auto depAttr = b.getAttr<DependenceAttr>(*dep.getDestinationIndex(),
516 StringAttr(), depProps);
517 depAttrs.push_back(depAttr);
518 continue;
519 }
520
521 if (!dep.isAuxiliary())
522 continue;
523
524 auto sourceRef = opNames.lookup(dep.getSource());
525 assert(sourceRef);
526 auto depAttr =
527 b.getAttr<DependenceAttr>(auxOperandIdx, sourceRef, depProps);
528 depAttrs.push_back(depAttr);
529 ++auxOperandIdx;
530 }
531 if (!depAttrs.empty())
532 dependences = b.getArrayAttr(depAttrs);
533
534 // Delegate to helper to construct the `properties` attribute.
535 ArrayAttr properties =
536 saveOperationProperties<ProblemT, OperationPropertyTs...>(prob, op, b);
537
538 // Finally, create the `OperationOp` and inform the value mapper.
539 // NB: sym_name, dependences and properties are optional attributes, so
540 // passing potentially unitialized String/ArrayAttrs is intentional here.
541 auto opOp =
542 OperationOp::create(b, op->getNumResults(), v.get(op->getOperands()),
543 opNames.lookup(op), dependences, properties);
544 v.set(op->getResults(), opOp->getResults());
545 }
546
547 return instOp;
548}
549
550/// Dummy struct to query a problem's default properties (i.e. all input and
551/// solution properties). Specializations shall provide the following
552/// definitions:
553///
554/// ```
555/// static constexpr auto operationProperties = std::make_tuple(...);
556/// static constexpr auto operatorTypeProperties = std::make_tuple(...);
557/// static constexpr auto dependenceProperties = std::make_tuple(...);
558/// static constexpr auto instanceProperties = std::make_tuple(...);
559/// ```
560template <typename ProblemT>
561struct Default {};
562
563/// Construct an instance of \p ProblemT from \p instOp, and attempt to set all
564/// of the problem class' properties.
565///
566/// Relies on the specialization of template `circt::ssp::Default` for \p
567/// ProblemT.
568template <typename ProblemT>
576
577/// Construct an `InstanceOp` from a given \p ProblemT instance, and
578/// create/attach attributes for all of the problem class' properties.
579///
580/// Relies on the specialization of template `circt::ssp::Default` for \p
581/// ProblemT.
582template <typename ProblemT>
590
591//===----------------------------------------------------------------------===//
592// Default property tuples for the built-in problems
593//===----------------------------------------------------------------------===//
594
595template <>
596struct Default<scheduling::Problem> {
597 static constexpr auto operationProperties = std::make_tuple(
598 LinkedOperatorTypeAttr(), LinkedResourceTypesAttr(), StartTimeAttr());
599 static constexpr auto operatorTypeProperties = std::make_tuple(LatencyAttr());
600 static constexpr auto resourceTypeProperties = std::make_tuple();
601 static constexpr auto dependenceProperties = std::make_tuple();
602 static constexpr auto instanceProperties = std::make_tuple();
603};
604
605template <>
606struct Default<scheduling::CyclicProblem> {
607 static constexpr auto operationProperties =
609 static constexpr auto operatorTypeProperties =
611 static constexpr auto resourceTypeProperties =
613 static constexpr auto dependenceProperties =
615 std::make_tuple(DistanceAttr()));
616 static constexpr auto instanceProperties =
618 std::make_tuple(InitiationIntervalAttr()));
619};
620
621template <>
622struct Default<scheduling::ChainingProblem> {
623 static constexpr auto operationProperties =
625 std::make_tuple(StartTimeInCycleAttr()));
626 static constexpr auto operatorTypeProperties =
628 std::make_tuple(IncomingDelayAttr(), OutgoingDelayAttr()));
629 static constexpr auto resourceTypeProperties =
631 static constexpr auto dependenceProperties =
633 static constexpr auto instanceProperties =
635};
636
637template <>
638struct Default<scheduling::SharedOperatorsProblem> {
639 static constexpr auto operationProperties =
641 static constexpr auto operatorTypeProperties =
643 static constexpr auto resourceTypeProperties = std::make_tuple(LimitAttr());
644 static constexpr auto dependenceProperties =
646 static constexpr auto instanceProperties =
648};
649
650template <>
651struct Default<scheduling::ModuloProblem> {
652 static constexpr auto operationProperties =
654 static constexpr auto operatorTypeProperties =
656 static constexpr auto resourceTypeProperties =
658 static constexpr auto dependenceProperties =
660 static constexpr auto instanceProperties =
662};
663
664template <>
665struct Default<scheduling::ChainingCyclicProblem> {
666 static constexpr auto operationProperties =
668 static constexpr auto operatorTypeProperties =
670 static constexpr auto resourceTypeProperties =
672 static constexpr auto dependenceProperties =
674 static constexpr auto instanceProperties =
676};
677
678} // namespace ssp
679} // namespace circt
680
681#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:438
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:386
void loadOperatorTypeProperties(ProblemT &, OperatorType, ArrayAttr)
Definition Utilities.h:56
ArrayAttr saveOperatorTypeProperties(ProblemT &prob, OperatorType opr, ImplicitLocOpBuilder &b)
Definition Utilities.h:360
void loadDependenceProperties(ProblemT &, Dependence, ArrayAttr)
Definition Utilities.h:86
ArrayAttr saveInstanceProperties(ProblemT &prob, ImplicitLocOpBuilder &b)
Definition Utilities.h:399
void loadResourceTypeProperties(ProblemT &, ResourceType, ArrayAttr)
Definition Utilities.h:71
ArrayAttr saveOperationProperties(ProblemT &prob, Operation *op, ImplicitLocOpBuilder &b)
Definition Utilities.h:347
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:373
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:561