CIRCT 20.0.0git
Loading...
Searching...
No Matches
DependenceIterator.h
Go to the documentation of this file.
1//===- DependenceIterator.h - Uniform handling of dependences ---*- 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 defines utilities to let algorithms iterate over different flavors
10// of dependences in a uniform way.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef CIRCT_SCHEDULING_DEPENDENCEITERATOR_H
15#define CIRCT_SCHEDULING_DEPENDENCEITERATOR_H
16
17#include "circt/Support/LLVM.h"
18
19#include "llvm/ADT/DenseMapInfo.h"
20#include "llvm/ADT/SetVector.h"
21#include "llvm/ADT/iterator.h"
22
23#include <optional>
24
25namespace circt {
26namespace scheduling {
27
28class Problem;
29
30namespace detail {
31
32/// A wrapper class to uniformly handle def-use and auxiliary dependence edges.
33/// Should be small enough (two pointers) to be passed around by value.
35public:
36 /// The "expanded" representation of a dependence, intended as the key for
37 /// comparisons and hashing.
38 using TupleRepr =
39 std::tuple<Operation *, Operation *, std::optional<unsigned>,
40 std::optional<unsigned>>;
41
42 /// Wrap a def-use dependence, which is uniquely identified in the SSA graph
43 /// by an `OpOperand`.
44 Dependence(OpOperand *defUseDep) : auxSrc(nullptr), defUse(defUseDep) {}
45 /// Wrap an auxiliary dependence, identified by the pair of its endpoints.
46 Dependence(std::pair<Operation *, Operation *> auxDep)
47 : auxSrc(std::get<0>(auxDep)), auxDst(std::get<1>(auxDep)) {}
48 /// Wrap an auxiliary dependence between \p from and \p to.
49 Dependence(Operation *from, Operation *to) : auxSrc(from), auxDst(to) {}
50 /// Construct an invalid dependence.
51 Dependence() : auxSrc(nullptr), auxDst(nullptr) {}
52
53 /// Return true if this is a valid auxiliary dependence.
54 bool isAuxiliary() const { return auxSrc && auxDst; }
55 /// Return true if this is a valid def-use dependence.
56 bool isDefUse() const { return !auxSrc && auxDst; }
57 /// Return true if this is an invalid dependence.
58 bool isInvalid() const { return !auxDst; }
59
60 /// Return the source of the dependence.
61 Operation *getSource() const;
62 /// Return the destination of the dependence.
63 Operation *getDestination() const;
64
65 /// Return the source operation's result number, if applicable.
66 std::optional<unsigned> getSourceIndex() const;
67 /// Return the destination operation's operand number, if applicable.
68 std::optional<unsigned> getDestinationIndex() const;
69
70 /// Return the tuple representation of this dependence.
71 TupleRepr getAsTuple() const;
72
73 bool operator==(const Dependence &other) const;
74
75private:
76 Operation *auxSrc;
77 union {
78 Operation *auxDst;
79 OpOperand *defUse;
80 };
81};
82
83/// An iterator to transparently surface an operation's def-use dependences from
84/// the SSA subgraph (induced by the registered operations), as well as
85/// auxiliary, operation-to-operation dependences explicitly provided by the
86/// client.
88 : public llvm::iterator_facade_base<DependenceIterator,
89 std::forward_iterator_tag, Dependence> {
90public:
91 /// Construct an iterator over the \p op's def-use dependences (i.e. result
92 /// values of other operations registered in the scheduling problem, which are
93 /// used by one of \p op's operands), and over auxiliary dependences (i.e.
94 /// from other operation to \p op).
95 DependenceIterator(Problem &problem, Operation *op, bool end = false);
96
97 bool operator==(const DependenceIterator &other) const {
98 return dep == other.dep;
99 }
100
101 const Dependence &operator*() const { return dep; }
102
105 return *this;
106 }
107
108private:
109 void findNextDependence();
110
112 Operation *op;
113
114 unsigned operandIdx;
115 unsigned auxPredIdx;
116 llvm::SmallSetVector<Operation *, 4> *auxPreds;
117
119};
120
121} // namespace detail
122} // namespace scheduling
123} // namespace circt
124
125namespace llvm {
126
128
129template <>
131 static inline Dependence getEmptyKey() {
133 }
138 static unsigned getHashValue(const Dependence &val) {
139 return llvm::hash_value(val.getAsTuple());
140 }
141 static bool isEqual(const Dependence &lhs, const Dependence &rhs) {
142 return lhs == rhs;
143 }
144};
145
146} // namespace llvm
147
148#endif // CIRCT_SCHEDULING_DEPENDENCEITERATOR_H
This class models the most basic scheduling problem.
Definition Problems.h:75
An iterator to transparently surface an operation's def-use dependences from the SSA subgraph (induce...
bool operator==(const DependenceIterator &other) const
llvm::SmallSetVector< Operation *, 4 > * auxPreds
A wrapper class to uniformly handle def-use and auxiliary dependence edges.
bool isInvalid() const
Return true if this is an invalid dependence.
std::tuple< Operation *, Operation *, std::optional< unsigned >, std::optional< unsigned > > TupleRepr
The "expanded" representation of a dependence, intended as the key for comparisons and hashing.
bool operator==(const Dependence &other) const
Definition Problems.cpp:472
std::optional< unsigned > getDestinationIndex() const
Return the destination operation's operand number, if applicable.
Definition Problems.cpp:461
std::optional< unsigned > getSourceIndex() const
Return the source operation's result number, if applicable.
Definition Problems.cpp:453
Operation * getDestination() const
Return the destination of the dependence.
Definition Problems.cpp:449
bool isAuxiliary() const
Return true if this is a valid auxiliary dependence.
TupleRepr getAsTuple() const
Return the tuple representation of this dependence.
Definition Problems.cpp:467
Dependence(std::pair< Operation *, Operation * > auxDep)
Wrap an auxiliary dependence, identified by the pair of its endpoints.
bool isDefUse() const
Return true if this is a valid def-use dependence.
Operation * getSource() const
Return the source of the dependence.
Definition Problems.cpp:445
Dependence()
Construct an invalid dependence.
Dependence(OpOperand *defUseDep)
Wrap a def-use dependence, which is uniquely identified in the SSA graph by an OpOperand.
Dependence(Operation *from, Operation *to)
Wrap an auxiliary dependence between from and to.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
static unsigned getHashValue(const Dependence &val)
static bool isEqual(const Dependence &lhs, const Dependence &rhs)