31 std::shared_ptr<const rvsdg::Type> type)
32 :
Output(region, std::move(type)),
38 throw util::Error(
"Argument cannot be added to input.");
65 std::shared_ptr<const rvsdg::Type> type)
80 std::shared_ptr<const rvsdg::Type> type)
81 :
Input(*region, *origin, std::move(type)),
87 throw util::Error(
"Result cannot be added to output.");
115 std::shared_ptr<const rvsdg::Type> type)
124 for (
size_t n = 0; n <
nresults(); n++)
143 head->
next_ =
nullptr;
148 : id_(graph->generateRegionId()),
159 : id_(node->graph()->generateRegionId()),
161 graph_(node->graph()),
179 throw util::Error(
"Appending argument to wrong region.");
190 throw util::Error(
"Inserting argument to wrong region.");
193 throw util::Error(
"Inserting argument after end of region.");
216 size_t numLiveArguments = 0;
217 size_t numRemovedArguments = 0;
224 numRemovedArguments++;
234 return numRemovedArguments;
240 size_t numLiveArguments = 0;
241 size_t numRemovedArguments = 0;
248 numRemovedArguments++;
258 return numRemovedArguments;
264 const auto resultPtr =
result.release();
266 if (resultPtr->region() !=
this)
267 throw util::Error(
"Appending result to wrong region.");
283 size_t numLiveResults = 0;
284 size_t numRemovedResults = 0;
285 for (
size_t n = 0; n <
nresults(); n++)
302 return numRemovedResults;
335 for (
size_t n = 0; n < snode->nsubregions(); n++)
336 snode->subregion(n)->prune(recursive);
351 std::ofstream outputFile(outputFilePath.
to_str());
412 observer->onNodeCreate(
node);
421 observer->onNodeDestroy(
node);
430 observer->onInputCreate(input);
439 observer->onInputChange(input, old_origin, new_origin);
448 observer->onInputDestroy(input);
455 size_t numRegions = 1;
456 for (
auto & node : region.Nodes())
460 for (
size_t n = 0; n < structuralNode->nsubregions(); n++)
462 numRegions += NumRegions(*structuralNode->subregion(n));
473 auto current = ®ion;
475 while (!current->IsRootRegion())
477 current = current->node()->region();
479 if (current == &ancestor)
489 std::stringstream stream{};
490 toJson(region, annotationMap, stream);
497 std::stringstream stream{};
499 toJson(region, annotationMap, stream);
507 std::stringstream & stream) noexcept
511 if (annotationMap.HasAnnotations(®ion))
514 for (
auto & annotation : annotationMap.GetAnnotations(®ion))
521 stream << toJsonKeyValue(annotation);
525 std::vector<const StructuralNode *> structuralNodes;
526 for (
auto & node : region.Nodes())
528 if (
const auto structuralNode =
dynamic_cast<const StructuralNode *
>(&node))
530 structuralNodes.push_back(structuralNode);
534 if (!structuralNodes.empty())
536 if (annotationMap.HasAnnotations(®ion))
539 bool firstNode =
true;
540 stream <<
"\"StructuralNodes\":[";
541 for (
const auto & structuralNode : structuralNodes)
548 toJson(*structuralNode, annotationMap, stream);
559 std::stringstream & stream) noexcept
562 stream <<
"\"DebugString\":\"" << structuralNode.DebugString() <<
"\"";
563 if (annotationMap.HasAnnotations(&structuralNode))
568 for (
auto & annotation : annotationMap.GetAnnotations(&structuralNode))
575 stream << toJsonKeyValue(annotation);
580 if (structuralNode.nsubregions() != 0)
582 bool firstSubregion =
true;
583 stream <<
"\"Subregions\":[";
584 for (
auto & subregion : structuralNode.Subregions())
587 firstSubregion =
false;
591 toJson(subregion, annotationMap, stream);
602 if (annotation.HasValueType<std::string>())
604 value =
util::strfmt(
"\"", annotation.Value<std::string>(),
"\"");
606 else if (annotation.HasValueType<int64_t>())
610 else if (annotation.HasValueType<uint64_t>())
614 else if (annotation.HasValueType<
double>())
623 return util::strfmt(
"\"", annotation.Label(),
"\":", value);
629 std::stringstream stream;
630 ToTree(region, annotationMap, 0, stream);
637 std::stringstream stream;
639 ToTree(region, annotationMap, 0, stream);
647 size_t indentationDepth,
648 std::stringstream & stream) noexcept
650 static const char indentationChar =
'-';
651 static const char annotationSeparator =
' ';
652 static const char labelValueSeparator =
':';
655 auto indentationString = std::string(indentationDepth, indentationChar);
657 region.IsRootRegion() ?
"RootRegion" :
util::strfmt(
"Region[", region.index(),
"]");
658 auto regionAnnotationString =
659 GetAnnotationString(®ion, annotationMap, annotationSeparator, labelValueSeparator);
661 stream << indentationString << regionString << regionAnnotationString <<
'\n';
665 indentationString = std::string(indentationDepth, indentationChar);
666 for (
auto & node : region.Nodes())
670 auto nodeString = structuralNode->DebugString();
671 auto annotationString = GetAnnotationString(
675 labelValueSeparator);
676 stream << indentationString << nodeString << annotationString <<
'\n';
678 for (
size_t n = 0; n < structuralNode->nsubregions(); n++)
680 ToTree(*structuralNode->subregion(n), annotationMap, indentationDepth + 1, stream);
690 char annotationSeparator,
691 char labelValueSeparator)
697 return ToString(annotations, annotationSeparator, labelValueSeparator);
702 const std::vector<util::Annotation> & annotations,
703 char annotationSeparator,
704 char labelValueSeparator)
706 std::stringstream stream;
707 for (
auto & annotation : annotations)
709 auto annotationString =
ToString(annotation, labelValueSeparator);
710 stream << annotationSeparator << annotationString;
722 value = annotation.
Value<std::string>();
764 std::unordered_map<const Node *, size_t>
767 std::unordered_map<const Node *, size_t> depthMap;
771 for (
auto & input : node->Inputs())
773 if (
const auto owner = TryGetOwnerNode<Node>(*input.origin()))
775 depth = std::max(depth, depthMap[owner] + 1);
778 depthMap[node] = depth;
787 size_t n = region->numNodes();
788 for (
const auto & node : region->Nodes())
792 for (
size_t r = 0; r < snode->nsubregions(); r++)
793 n +=
nnodes(snode->subregion(r));
804 for (
const auto & node : region->Nodes())
808 for (
size_t r = 0; r < snode->nsubregions(); r++)
821 for (
const auto & node : region->Nodes())
825 for (
size_t r = 0; r < snode->nsubregions(); r++)
840 size_t n = region->nresults();
841 for (
const auto & node : region->Nodes())
845 for (
size_t r = 0; r < snode->nsubregions(); r++)
846 n +=
ninputs(snode->subregion(r));
util::graph::Graph & WriteGraph(util::graph::Writer &writer, const Region ®ion)
Region & GetRootRegion() const noexcept
bool IsDead() const noexcept
Determines whether the node is dead.
rvsdg::Region * region() const noexcept
size_t ninputs() const noexcept
virtual Node * copy(rvsdg::Region *region, const std::vector< jlm::rvsdg::Output * > &operands) const
rvsdg::Region * region() const noexcept
const std::shared_ptr< const rvsdg::Type > & Type() const noexcept
size_t index() const noexcept
bool IsDead() const noexcept
Represents the argument of a region.
RegionArgument(rvsdg::Region *region, StructuralInput *input, std::shared_ptr< const rvsdg::Type > type)
std::string debug_string() const override
virtual RegionArgument & Copy(Region ®ion, StructuralInput *input) const
StructuralInput * input() const noexcept
~RegionArgument() noexcept override
static RegionArgument & Create(rvsdg::Region ®ion, StructuralInput *input, std::shared_ptr< const rvsdg::Type > type)
Creates region entry argument.
Proxy object to observe changes to a region.
virtual ~RegionObserver() noexcept
RegionObserver(const Region ®ion)
Represents the result of a region.
RegionResult(rvsdg::Region *region, rvsdg::Output *origin, StructuralOutput *output, std::shared_ptr< const rvsdg::Type > type)
StructuralOutput * output() const noexcept
~RegionResult() noexcept override
virtual RegionResult & Copy(rvsdg::Output &origin, StructuralOutput *output) const
std::string debug_string() const override
static RegionResult & Create(rvsdg::Region ®ion, rvsdg::Output &origin, StructuralOutput *output, std::shared_ptr< const rvsdg::Type > type)
Create region exit result.
Represent acyclic RVSDG subgraphs.
RegionResult * result(size_t index) const noexcept
size_t RemoveResults(const util::HashSet< size_t > &indices)
RegionArgument & addArgument(std::unique_ptr< RegionArgument > argument)
void notifyNodeDestroy(Node *node)
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
static std::string ToString(const std::vector< util::Annotation > &annotations, char annotationSeparator, char labelValueSeparator)
size_t numNodes() const noexcept
static std::string toJson(const Region ®ion, const util::AnnotationMap &annotationMap) noexcept
static std::string ToTree(const rvsdg::Region ®ion, const util::AnnotationMap &annotationMap) noexcept
void onNodeRemoved(Node &node)
rvsdg::StructuralNode * node() const noexcept
void onNodeAdded(Node &node)
Adds node to the list of nodes in the region.
Graph * graph() const noexcept
void notifyInputChange(Input *input, Output *old_origin, Output *new_origin)
size_t nresults() const noexcept
RegionObserver * observers_
std::vector< RegionResult * > results_
RegionResult & addResult(std::unique_ptr< RegionResult > result)
void prune(bool recursive)
std::vector< RegionArgument * > arguments_
void onBottomNodeRemoved(Node &node)
size_t index() const noexcept
static std::string GetAnnotationString(const void *key, const util::AnnotationMap &annotationMap, char annotationSeparator, char labelValueSeparator)
RegionArgument * argument(size_t index) const noexcept
void notifyNodeCreate(Node *node)
size_t numTopNodes() const noexcept
bool IsRootRegion() const noexcept
static size_t NumRegions(const rvsdg::Region ®ion) noexcept
void onTopNodeRemoved(Node &node)
size_t numBottomNodes() const noexcept
size_t RemoveArguments(const util::HashSet< size_t > &indices)
void removeNode(Node *node)
static bool isAncestor(const rvsdg::Region ®ion, const rvsdg::Region &ancestor) noexcept
Region(rvsdg::Region *parent, Graph *graph)
region_top_node_list topNodes_
void onTopNodeAdded(Node &node)
Adds node to the top nodes of the region.
region_bottom_node_list bottomNodes_
NodeRange Nodes() noexcept
void notifyInputDestroy(Input *input)
void notifyInputCreate(Input *input)
RegionArgument & insertArgument(size_t index, std::unique_ptr< RegionArgument > argument)
static std::string toJsonKeyValue(const util::Annotation &annotation) noexcept
size_t narguments() const noexcept
void onBottomNodeAdded(Node &node)
Adds node to the set of bottom nodes in the region.
StructuralNode * node() const noexcept
const std::vector< Annotation > & GetAnnotations(const void *key) const noexcept
bool HasAnnotations(const void *key) const noexcept
bool HasValueType() const noexcept
const TValue & Value() const
const std::string_view & Label() const noexcept
static FilePath createUniqueFileName(const FilePath &directory, const std::string &fileNamePrefix, const std::string &fileNameSuffix)
Generates a unique file in a given directory with a prefix and suffix.
static FilePath TempDirectoryPath()
const std::string & to_str() const noexcept
bool insert(ItemType item)
bool Contains(const ItemType &item) const noexcept
bool IsEmpty() const noexcept
void erase(ElementType *element) noexcept
ElementType * first() const noexcept
void push_back(ElementType *element) noexcept
void outputAllGraphs(std::ostream &out, OutputFormat format)
#define JLM_UNREACHABLE(msg)
size_t nsimpnodes(const rvsdg::Region *region) noexcept
size_t nstructnodes(const rvsdg::Region *region) noexcept
std::unordered_map< const Node *, size_t > computeDepthMap(const Region ®ion)
detail::TopDownTraverserGeneric< true > TopDownConstTraverser
Traverser for visiting every node in a const region in a top down order.
size_t nnodes(const jlm::rvsdg::Region *region) noexcept
size_t ninputs(const rvsdg::Region *region) noexcept
std::string getDotViewer()
static std::string strfmt(Args... args)
int executeProgramAndWait(const std::string &programName, const std::vector< std::string > &programArguments)