Jlm
Loading...
Searching...
No Matches
region.hpp
Go to the documentation of this file.
1/*
2 * Copyright 2010 2011 2012 Helge Bahmann <hcb@chaoticmind.net>
3 * Copyright 2011 2012 2013 2014 2015 2016 Nico Reißmann <nico.reissmann@gmail.com>
4 * See COPYING for terms of redistribution.
5 */
6
7#ifndef JLM_RVSDG_REGION_HPP
8#define JLM_RVSDG_REGION_HPP
9
10#include <jlm/rvsdg/node.hpp>
11#include <jlm/util/common.hpp>
13
14namespace jlm::util
15{
16class Annotation;
17class AnnotationMap;
18}
19
20namespace jlm::rvsdg
21{
22
23class Node;
24class SimpleNode;
25class SimpleOperation;
26class StructuralInput;
27class StructuralNode;
28class StructuralOutput;
29class SubstitutionMap;
30class RegionObserver;
31
109
197
213{
214 using RegionArgumentIterator = std::vector<RegionArgument *>::iterator;
215 using RegionArgumentConstIterator = std::vector<RegionArgument *>::const_iterator;
218
219 using RegionResultIterator = std::vector<RegionResult *>::iterator;
220 using RegionResultConstIterator = std::vector<RegionResult *>::const_iterator;
223
227
228 using TopNodeIterator = region_top_node_list::Iterator;
229 using TopNodeConstIterator = region_top_node_list::ConstIterator;
232
233 using NodeIterator = region_nodes_list::Iterator;
234 using NodeConstIterator = region_nodes_list::ConstIterator;
237
238 using BottomNodeIterator = region_bottom_node_list::Iterator;
239 using BottomNodeConstIterator = region_bottom_node_list::ConstIterator;
242
243public:
244 using Id = uint64_t;
245
247
251 Region(Graph * graph);
252
256 Region(rvsdg::StructuralNode * node, size_t index);
257
259
260 Region &
262
266 [[nodiscard]] Graph *
268 {
269 return graph_;
270 }
271
277 [[nodiscard]] Id
279 {
280 return id_;
281 }
282
290 [[nodiscard]] size_t
292 {
293 return depth_;
294 }
295
302 {
303 return node_;
304 }
305
309 [[nodiscard]] size_t
311 {
312 return index_;
313 }
314
320 {
321 return { arguments_.begin(), arguments_.end() };
322 }
323
329 {
330 return { arguments_.begin(), arguments_.end() };
331 }
332
338 {
339 return { results_.begin(), results_.end() };
340 }
341
347 {
348 return { results_.begin(), results_.end() };
349 }
350
357 {
358 return { topNodes_.begin(), topNodes_.end() };
359 }
360
367 {
368 return { topNodes_.begin(), topNodes_.end() };
369 }
370
376 {
377 return { nodes_.begin(), nodes_.end() };
378 }
379
385 {
386 return { nodes_.begin(), nodes_.end() };
387 }
388
395 {
396 return { bottomNodes_.begin(), bottomNodes_.end() };
397 }
398
405 {
406 return { bottomNodes_.begin(), bottomNodes_.end() };
407 }
408
414 [[nodiscard]] bool
416
426
439
448 size_t
449 RemoveArguments(const util::HashSet<size_t> & indices);
450
456 size_t
458
459 inline size_t
461 {
462 return arguments_.size();
463 }
464
465 inline RegionArgument *
466 argument(size_t index) const noexcept
467 {
469 return arguments_[index];
470 }
471
480 addResult(std::unique_ptr<RegionResult> result);
481
490 size_t
491 RemoveResults(const util::HashSet<size_t> & indices);
492
493 inline size_t
495 {
496 return results_.size();
497 }
498
500 result(size_t index) const noexcept
501 {
503 return results_[index];
504 }
505
509 [[nodiscard]] size_t
511 {
512 return numNodes_;
513 }
514
518 [[nodiscard]] size_t
520 {
521 return numTopNodes_;
522 }
523
527 [[nodiscard]] size_t
529 {
530 return numBottomNodes_;
531 }
532
538 void
540
551 void
553
558 void
559 prune(bool recursive);
560
566 void
567 view() const;
568
574 {
575 return nextNodeId_;
576 }
577
578private:
586 void
588
595 void
597
605 void
607
614 void
616
623 void
625
632 void
634
643 {
644 const auto nodeId = nextNodeId_;
645 nextNodeId_++;
646 return nodeId;
647 }
648
649 void
651
652 void
654
655 void
656 notifyInputCreate(Input * input);
657
658 void
660
661 void
662 notifyInputDestroy(Input * input);
663
664public:
676 template<class TOperation>
677 static bool
678 containsOperation(const Region & region, bool checkSubregions);
679
691 template<class TNodeType>
692 static bool
693 containsNodeType(const Region & region, bool checkSubregions);
694
703 [[nodiscard]] static size_t
704 NumRegions(const rvsdg::Region & region) noexcept;
705
714 [[nodiscard]] static bool
715 isAncestor(const rvsdg::Region & region, const rvsdg::Region & ancestor) noexcept;
716
741 [[nodiscard]] static std::string
742 ToTree(const rvsdg::Region & region, const util::AnnotationMap & annotationMap) noexcept;
743
764 [[nodiscard]] static std::string
765 ToTree(const rvsdg::Region & region) noexcept;
766
775 [[nodiscard]] static std::string
776 toJson(const Region & region, const util::AnnotationMap & annotationMap) noexcept;
777
784 [[nodiscard]] static std::string
785 toJson(const Region & region) noexcept;
786
787private:
788 static void
789 ToTree(
790 const rvsdg::Region & region,
792 size_t indentationDepth,
793 std::stringstream & stream) noexcept;
794
795 static void
796 toJson(
797 const Region & region,
799 std::stringstream & stream) noexcept;
800
801 static void
802 toJson(
805 std::stringstream & stream) noexcept;
806
807 [[nodiscard]] static std::string
809
810 [[nodiscard]] static std::string
812 const void * key,
816
817 [[nodiscard]] static std::string
818 ToString(
819 const std::vector<util::Annotation> & annotations,
822
823 [[nodiscard]] static std::string
825
829 Graph * const graph_;
833 const Id id_;
837 const size_t depth_;
838
846 const size_t index_;
847
852
853 // The region owns its results, arguments and nodes
854 std::vector<RegionResult *> results_;
855 std::vector<RegionArgument *> arguments_;
861 size_t numNodes_;
862
867 mutable RegionObserver * observers_ = nullptr;
868
869 friend class Node;
870 friend class RegionObserver;
871 friend class SimpleNode;
872 friend class StructuralNode;
873 friend class Input;
874 friend class Output;
875 friend class RegionResult;
876};
877
886{
887public:
888 virtual ~RegionObserver() noexcept;
889
890 explicit RegionObserver(const Region & region);
891
893
895 operator=(const RegionObserver &) = delete;
896
902 virtual void
903 onNodeCreate(Node * node) = 0;
904
910 virtual void
911 onNodeDestroy(Node * node) = 0;
912
918 virtual void
919 onInputCreate(Input * input) = 0;
920
927 virtual void
929
935 virtual void
936 onInputDestroy(Input * input) = 0;
937
938private:
941
942 friend class Region;
943};
944
949{
950public:
952
954 : RegionObserver(region)
955 {}
956
957 void
958 onInputDestroy(Input * input) override
959 {
960 destroyedInputIndices_.push_back(input->index());
961 }
962
963 const std::vector<size_t> &
968
969 void
970 onNodeCreate(Node * node) override
971 {
972 createNodes_.push_back(node->GetNodeId());
973 }
974
975 const std::vector<Node::Id> &
977 {
978 return createNodes_;
979 }
980
981 void
982 onNodeDestroy(Node * node) override
983 {
984 destroyedNodes_.push_back(node->GetNodeId());
985 }
986
987 const std::vector<Node::Id> &
989 {
990 return destroyedNodes_;
991 }
992
993 void
994 onInputCreate(Input * input) override
995 {
996 createdInputIndices_.push_back(input->index());
997 }
998
999 const std::vector<size_t> &
1004
1005 void
1006 onInputChange(Input * input, Output *, Output *) override
1007 {
1008 changedInputIndices_.push_back(input->index());
1009 }
1010
1011 const std::vector<size_t> &
1016
1017private:
1018 std::vector<Node::Id> createNodes_{};
1019 std::vector<Node::Id> destroyedNodes_{};
1020 std::vector<size_t> createdInputIndices_{};
1021 std::vector<size_t> changedInputIndices_{};
1022 std::vector<size_t> destroyedInputIndices_{};
1023};
1024
1031std::unordered_map<const Node *, size_t>
1032computeDepthMap(const Region & region);
1033
1034static inline void
1036{
1037 return node->region()->removeNode(node);
1038}
1039
1040size_t
1041nnodes(const rvsdg::Region * region) noexcept;
1042
1043size_t
1044nstructnodes(const rvsdg::Region * region) noexcept;
1045
1046size_t
1047nsimpnodes(const rvsdg::Region * region) noexcept;
1048
1049size_t
1050ninputs(const rvsdg::Region * region) noexcept;
1051
1073template<typename NodeType>
1074inline NodeType *
1076{
1077 auto region = TryGetOwnerRegion(input);
1078 if (region)
1079 {
1080 return dynamic_cast<NodeType *>(region->node());
1081 }
1082 else
1083 {
1084 return nullptr;
1085 }
1086}
1087
1109template<typename NodeType>
1110inline NodeType *
1112{
1113 auto region = TryGetOwnerRegion(output);
1114 if (region)
1115 {
1116 return dynamic_cast<NodeType *>(region->node());
1117 }
1118 else
1119 {
1120 return nullptr;
1121 }
1122}
1123
1143template<typename NodeType>
1144inline NodeType &
1146{
1147 auto node = TryGetRegionParentNode<NodeType>(input);
1148 if (!node)
1149 {
1150 throw std::logic_error(std::string("expected node of type ") + typeid(NodeType).name());
1151 }
1152 return *node;
1153}
1154
1174template<typename NodeType>
1175inline NodeType &
1177{
1178 auto node = TryGetRegionParentNode<NodeType>(output);
1179 if (!node)
1180 {
1181 throw std::logic_error(std::string("expected node of type ") + typeid(NodeType).name());
1182 }
1183 return *node;
1184}
1185
1186} // namespace
1187
1188#endif
size_t index() const noexcept
Definition node.hpp:52
Output * origin() const noexcept
Definition node.hpp:58
Region * region() const noexcept
Definition node.cpp:83
uint64_t Id
Definition node.hpp:583
Id GetNodeId() const noexcept
Definition node.hpp:600
rvsdg::Region * region() const noexcept
Definition node.hpp:761
rvsdg::Region * region() const noexcept
Definition node.cpp:151
const std::vector< Node::Id > & createdNodes() const noexcept
Definition region.hpp:976
std::vector< size_t > createdInputIndices_
Definition region.hpp:1020
const std::vector< size_t > & changedInputIndices() const noexcept
Definition region.hpp:1012
std::vector< size_t > changedInputIndices_
Definition region.hpp:1021
std::vector< Node::Id > destroyedNodes_
Definition region.hpp:1019
const std::vector< Node::Id > & destroyedNodes() const noexcept
Definition region.hpp:988
void onInputDestroy(Input *input) override
Definition region.hpp:958
std::vector< Node::Id > createNodes_
Definition region.hpp:1018
const std::vector< size_t > & destroyedInputIndices() const noexcept
Definition region.hpp:964
~RecordingObserver() noexcept override=default
std::vector< size_t > destroyedInputIndices_
Definition region.hpp:1022
const std::vector< size_t > & createdInputIndices() const noexcept
Definition region.hpp:1000
void onInputCreate(Input *input) override
Definition region.hpp:994
void onNodeCreate(Node *node) override
Definition region.hpp:970
void onNodeDestroy(Node *node) override
Definition region.hpp:982
void onInputChange(Input *input, Output *, Output *) override
Definition region.hpp:1006
Represents the argument of a region.
Definition region.hpp:41
util::IntrusiveListAnchor< RegionArgument > structural_input_anchor_
Definition region.hpp:42
std::string debug_string() const override
Definition region.cpp:51
virtual RegionArgument & Copy(Region &region, StructuralInput *input) const
Definition region.cpp:57
~RegionArgument() noexcept override
Definition region.cpp:23
StructuralInput * input_
Definition region.hpp:107
static RegionArgument & Create(rvsdg::Region &region, StructuralInput *input, std::shared_ptr< const rvsdg::Type > type)
Creates region entry argument.
Definition region.cpp:63
util::IntrusiveListAccessor< RegionArgument, &RegionArgument::structural_input_anchor_ > structural_input_accessor
Definition region.hpp:46
StructuralInput * input() const noexcept
Definition region.hpp:69
Proxy object to observe changes to a region.
Definition region.hpp:886
virtual void onInputChange(Input *input, Output *old_origin, Output *new_origin)=0
virtual ~RegionObserver() noexcept
Definition region.cpp:767
virtual void onNodeCreate(Node *node)=0
virtual void onNodeDestroy(Node *node)=0
virtual void onInputCreate(Input *input)=0
RegionObserver(const RegionObserver &)=delete
virtual void onInputDestroy(Input *input)=0
RegionObserver ** pprev_
Definition region.hpp:939
RegionObserver & operator=(const RegionObserver &)=delete
RegionObserver * next_
Definition region.hpp:940
Represents the result of a region.
Definition region.hpp:120
StructuralOutput * output() const noexcept
Definition region.hpp:149
StructuralOutput * output_
Definition region.hpp:195
~RegionResult() noexcept override
Definition region.cpp:71
util::IntrusiveListAccessor< RegionResult, &RegionResult::structural_output_anchor_ > structural_output_accessor
Definition region.hpp:125
virtual RegionResult & Copy(rvsdg::Output &origin, StructuralOutput *output) const
Definition region.cpp:106
util::IntrusiveListAnchor< RegionResult > structural_output_anchor_
Definition region.hpp:121
std::string debug_string() const override
Definition region.cpp:100
static RegionResult & Create(rvsdg::Region &region, rvsdg::Output &origin, StructuralOutput *output, std::shared_ptr< const rvsdg::Type > type)
Create region exit result.
Definition region.cpp:112
Represent acyclic RVSDG subgraphs.
Definition region.hpp:213
size_t RemoveResults(const util::HashSet< size_t > &indices)
Definition region.cpp:281
RegionArgument * argument(size_t index) const noexcept
Definition region.hpp:466
RegionArgument & addArgument(std::unique_ptr< RegionArgument > argument)
Definition region.cpp:179
util::IteratorRange< NodeIterator > NodeRange
Definition region.hpp:235
std::vector< RegionResult * >::const_iterator RegionResultConstIterator
Definition region.hpp:220
void notifyNodeDestroy(Node *node)
Definition region.cpp:420
RegionArgumentRange Arguments() noexcept
Definition region.hpp:319
Graph *const graph_
Definition region.hpp:829
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition region.cpp:317
Node::Id generateNodeId() noexcept
Definition region.hpp:642
Graph * graph() const noexcept
Definition region.hpp:267
NodeConstRange Nodes() const noexcept
Definition region.hpp:384
BottomNodeRange BottomNodes() noexcept
Definition region.hpp:394
BottomNodeConstRange BottomNodes() const noexcept
Definition region.hpp:404
util::IteratorRange< BottomNodeConstIterator > BottomNodeConstRange
Definition region.hpp:241
static std::string ToString(const std::vector< util::Annotation > &annotations, char annotationSeparator, char labelValueSeparator)
Definition region.cpp:724
util::IteratorRange< RegionArgumentConstIterator > RegionArgumentConstRange
Definition region.hpp:217
const size_t depth_
Definition region.hpp:837
size_t numNodes() const noexcept
Definition region.hpp:510
region_nodes_list nodes_
Definition region.hpp:860
void view() const
Definition region.cpp:345
util::IteratorRange< RegionArgumentIterator > RegionArgumentRange
Definition region.hpp:216
rvsdg::StructuralNode *const node_
Definition region.hpp:842
Node::Id getNextNodeId() const noexcept
Definition region.hpp:573
region_top_node_list::ConstIterator TopNodeConstIterator
Definition region.hpp:229
TopNodeConstRange TopNodes() const noexcept
Definition region.hpp:366
util::IteratorRange< NodeConstIterator > NodeConstRange
Definition region.hpp:236
static std::string toJson(const Region &region, const util::AnnotationMap &annotationMap) noexcept
Definition region.cpp:492
util::IteratorRange< TopNodeIterator > TopNodeRange
Definition region.hpp:230
static std::string ToTree(const rvsdg::Region &region, const util::AnnotationMap &annotationMap) noexcept
Definition region.cpp:650
void onNodeRemoved(Node &node)
Definition region.cpp:403
void onNodeAdded(Node &node)
Adds node to the list of nodes in the region.
Definition region.cpp:395
region_top_node_list::Iterator TopNodeIterator
Definition region.hpp:228
void notifyInputChange(Input *input, Output *old_origin, Output *new_origin)
Definition region.cpp:438
size_t numBottomNodes_
Definition region.hpp:859
util::IteratorRange< BottomNodeIterator > BottomNodeRange
Definition region.hpp:240
size_t nresults() const noexcept
Definition region.hpp:494
region_nodes_list::ConstIterator NodeConstIterator
Definition region.hpp:234
RegionObserver * observers_
Definition region.hpp:867
region_nodes_list::Iterator NodeIterator
Definition region.hpp:233
util::IteratorRange< TopNodeConstIterator > TopNodeConstRange
Definition region.hpp:231
std::vector< RegionResult * > results_
Definition region.hpp:854
RegionResult & addResult(std::unique_ptr< RegionResult > result)
Definition region.cpp:265
TopNodeRange TopNodes() noexcept
Definition region.hpp:356
Id getRegionId() const noexcept
Definition region.hpp:278
region_bottom_node_list::Iterator BottomNodeIterator
Definition region.hpp:238
std::vector< RegionArgument * >::const_iterator RegionArgumentConstIterator
Definition region.hpp:215
static bool containsNodeType(const Region &region, bool checkSubregions)
void prune(bool recursive)
Definition region.cpp:326
RegionResult * result(size_t index) const noexcept
Definition region.hpp:500
std::vector< RegionArgument * > arguments_
Definition region.hpp:855
void onBottomNodeRemoved(Node &node)
Definition region.cpp:387
size_t index() const noexcept
Definition region.hpp:310
static std::string GetAnnotationString(const void *key, const util::AnnotationMap &annotationMap, char annotationSeparator, char labelValueSeparator)
Definition region.cpp:710
static bool containsOperation(const Region &region, bool checkSubregions)
void notifyNodeCreate(Node *node)
Definition region.cpp:411
size_t numTopNodes() const noexcept
Definition region.hpp:519
util::IteratorRange< RegionResultIterator > RegionResultRange
Definition region.hpp:221
bool IsRootRegion() const noexcept
Definition region.cpp:173
static size_t NumRegions(const rvsdg::Region &region) noexcept
Definition region.cpp:456
region_bottom_node_list::ConstIterator BottomNodeConstIterator
Definition region.hpp:239
void onTopNodeRemoved(Node &node)
Definition region.cpp:370
std::vector< RegionArgument * >::iterator RegionArgumentIterator
Definition region.hpp:214
rvsdg::StructuralNode * node() const noexcept
Definition region.hpp:301
size_t numBottomNodes() const noexcept
Definition region.hpp:528
const size_t index_
Definition region.hpp:846
~Region() noexcept
Definition region.cpp:122
size_t RemoveArguments(const util::HashSet< size_t > &indices)
Definition region.cpp:213
void removeNode(Node *node)
Definition region.cpp:309
static bool isAncestor(const rvsdg::Region &region, const rvsdg::Region &ancestor) noexcept
Definition region.cpp:474
region_top_node_list topNodes_
Definition region.hpp:856
void onTopNodeAdded(Node &node)
Adds node to the top nodes of the region.
Definition region.cpp:361
region_bottom_node_list bottomNodes_
Definition region.hpp:858
std::vector< RegionResult * >::iterator RegionResultIterator
Definition region.hpp:219
NodeRange Nodes() noexcept
Definition region.hpp:375
void notifyInputDestroy(Input *input)
Definition region.cpp:447
RegionResultConstRange Results() const noexcept
Definition region.hpp:346
void notifyInputCreate(Input *input)
Definition region.cpp:429
RegionArgument & insertArgument(size_t index, std::unique_ptr< RegionArgument > argument)
Definition region.cpp:190
static std::string toJsonKeyValue(const util::Annotation &annotation) noexcept
Definition region.cpp:622
size_t narguments() const noexcept
Definition region.hpp:460
void onBottomNodeAdded(Node &node)
Adds node to the set of bottom nodes in the region.
Definition region.cpp:378
util::IteratorRange< RegionResultConstIterator > RegionResultConstRange
Definition region.hpp:222
Node::Id nextNodeId_
Definition region.hpp:851
size_t PruneArguments()
Definition region.cpp:241
size_t getDepth() const noexcept
Definition region.hpp:291
RegionResultRange Results() noexcept
Definition region.hpp:337
RegionArgumentConstRange Arguments() const noexcept
Definition region.hpp:328
Iterator end() noexcept
Iterator begin() noexcept
#define JLM_ASSERT(x)
Definition common.hpp:16
size_t nsimpnodes(const rvsdg::Region *region) noexcept
Definition region.cpp:841
size_t nstructnodes(const rvsdg::Region *region) noexcept
Definition region.cpp:824
NodeType * TryGetRegionParentNode(const rvsdg::Input &input) noexcept
Checks if this is a result of a region inside a node of specified type.
Definition region.hpp:1075
static void remove(Node *node)
Definition region.hpp:1035
std::unordered_map< const Node *, size_t > computeDepthMap(const Region &region)
Definition region.cpp:788
NodeType & AssertGetRegionParentNode(const rvsdg::Input &input)
Asserts that this is a result of a region inside a node of specified type.
Definition region.hpp:1145
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
Definition region.cpp:808
size_t ninputs(const rvsdg::Region *region) noexcept
Definition region.cpp:861
Region * TryGetOwnerRegion(const rvsdg::Input &input) noexcept
Definition node.hpp:1021
NodeType * TryGetOwnerNode(const rvsdg::Input &input) noexcept
Checks if this is an input to a node of specified type.
Definition node.hpp:872