30template<
typename Traverser>
33template<
typename Traverser>
39template<
typename Traverser>
46template<
typename Traverser>
50 traverser_.onNodeDestroy(node);
53template<
typename Traverser>
57 traverser_.onInputCreate(input);
60template<
typename Traverser>
67template<
typename Traverser>
71 traverser_.onInputDestroy(input);
79 : observer_(*region, *
this),
80 nodeIdCutoff_(region->getNextNodeId())
82 for (
auto & node : region->TopNodes())
84 tracker_.checkNodeActivation(&node, node.ninputs());
87 for (
auto argument : region->Arguments())
89 for (
const auto &
user : argument->Users())
93 tracker_.incActivationCount(node, node->ninputs());
105 return tracker_.isNodeVisited(
pred);
112template<
bool IsConst>
116 tracker_.checkMarkNodeVisitedIfFrontier(&node);
117 for (
const auto & output : node.Outputs())
119 for (
const auto &
user : output.Users())
123 tracker_.incActivationCount(next, next->ninputs());
129template<
bool IsConst>
135 const auto node = tracker_.peek();
139 markAsVisited(*node);
142 if (node->GetNodeId() >= nodeIdCutoff_)
149template<
bool IsConst>
153 if (node->ninputs() == 0)
155 tracker_.checkNodeActivation(node, node->ninputs());
159 for (
const auto & input : node->Inputs())
161 if (isOutputActivated(*input.origin()))
163 tracker_.incActivationCount(node, node->ninputs());
171 tracker_.checkMarkNodeVisitedIfFrontier(node);
174template<
bool IsConst>
179 tracker_.removeNode(node);
182template<
bool IsConst>
190 if (isOutputActivated(*input->
origin()))
192 tracker_.incActivationCount(node, node->ninputs());
196 tracker_.checkNodeDeactivation(node, node->ninputs());
200template<
bool IsConst>
223 tracker_.incActivationCount(node, node->ninputs());
227 tracker_.decActivationCount(node, node->ninputs());
231template<
bool IsConst>
239 if (isOutputActivated(*input->
origin()))
243 tracker_.decActivationCount(node, 0);
248 tracker_.checkNodeActivation(node, node->ninputs() - 1);
252template<
bool IsConst>
257 : observer_(*region, *
this)
259 for (
auto & node : region->BottomNodes())
261 tracker_.checkNodeActivation(&node, node.numSuccessors());
264 for (
auto result : region->Results())
268 tracker_.incActivationCount(node, node->numSuccessors());
273template<
bool IsConst>
279 return tracker_.isNodeVisited(node);
286template<
bool IsConst>
290 tracker_.checkMarkNodeVisitedIfFrontier(&node);
291 for (
const auto & input : node.Inputs())
300template<
bool IsConst>
304 auto node = tracker_.peek();
308 markAsVisited(*node);
312template<
bool IsConst>
317 markAsVisited(*node);
320template<
bool IsConst>
326 if (!tracker_.isNodeVisited(node))
327 markAsVisited(*node);
329 for (
const auto & input : node->Inputs())
337 tracker_.decActivationCount(
pred, 0);
342template<
bool IsConst>
350 if (isInputActivated(*input))
352 tracker_.incActivationCount(node, node->numSuccessors());
356 tracker_.checkNodeDeactivation(node, node->numSuccessors());
360template<
bool IsConst>
390 tracker_.checkNodeDeactivation(
newNode,
newNode->numSuccessors());
395template<
bool IsConst>
403 if (isInputActivated(*input))
407 tracker_.decActivationCount(
pred, 0);
411 tracker_.checkNodeActivation(
pred,
pred->numSuccessors() - 1);
415template<
typename NodeType>
419 auto i = states_.find(node);
423template<
typename NodeType>
430 frontier_.push_back(node);
431 i->second.pos = std::prev(frontier_.end());
436template<
typename NodeType>
443 frontier_.erase(
i->second.pos);
444 i->second.pos = frontier_.end();
449template<
typename NodeType>
456 frontier_.erase(
i->second.pos);
457 i->second.pos = frontier_.end();
462template<
typename NodeType>
467 i->second.activationCount += 1;
471template<
typename NodeType>
476 i->second.activationCount -= 1;
480template<
typename NodeType>
484 if (
const auto it = states_.find(node);
it != states_.end())
487 frontier_.erase(
it->second.pos);
492template<
typename NodeType>
496 return frontier_.empty() ? nullptr : frontier_.front();
Proxy object to observe changes to a region.
virtual void onNodeCreate(Node *node)=0
Represent acyclic RVSDG subgraphs.
void onInputDestroy(Input *input)
std::conditional_t< IsConst, const Node, Node > NodeType
bool isInputActivated(const Input &input) const
void onNodeDestroy(NodeType *node)
void markAsVisited(NodeType &node)
void onInputCreate(Input *input)
void onNodeCreate(NodeType *node)
std::conditional_t< IsConst, const Region, Region > RegionType
~BottomUpTraverserGeneric() noexcept
void onInputChange(Input *input, Output *oldOrigin, Output *newOrigin)
void onNodeDestroy(Node *node) override
ForwardingObserver(const Region ®ion, Traverser &traverser)
~ForwardingObserver() noexcept override
void onInputCreate(Input *input) override
void onInputChange(Input *input, Output *oldOrigin, Output *newOrigin) override
void onNodeCreate(Node *node) override
void onInputDestroy(Input *input) override
bool isOutputActivated(const Output &output) const
void markAsVisited(NodeType &node)
void onInputDestroy(Input *input)
void onNodeCreate(NodeType *node)
void onInputChange(Input *in, Output *old_origin, Output *new_origin)
void onInputCreate(Input *input)
~TopDownTraverserGeneric() noexcept
void onNodeDestroy(NodeType *node)
std::conditional_t< IsConst, const Node, Node > NodeType
std::conditional_t< IsConst, const Region, Region > RegionType
void checkMarkNodeVisitedIfFrontier(NodeType *node)
Marks a node visited if it is currently ready for visiting.
bool isNodeVisited(NodeType *node) const
Determines whether node has been visited already.
void decActivationCount(NodeType *node, std::size_t threshold)
Decrements activation count; removes from frontier if threshold is no longer met.
void incActivationCount(NodeType *node, std::size_t threshold)
Increments activation count; adds to frontier if threshold is met.
void checkNodeActivation(NodeType *node, std::size_t threshold)
Checks activation count whether node is ready for visiting.
void checkNodeDeactivation(NodeType *node, std::size_t threshold)
Checks activation count whether node is no longer ready for visiting.
void removeNode(NodeType *node)
Removes any state associated with the given node.
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.