Jlm
graph.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2010 2011 2012 2013 2014 2015 Helge Bahmann <hcb@chaoticmind.net>
3  * Copyright 2013 2014 2016 Nico Reißmann <nico.reissmann@gmail.com>
4  * See COPYING for terms of redistribution.
5  */
6 
7 #include <jlm/rvsdg/graph.hpp>
9 #include <jlm/util/strfmt.hpp>
10 
11 #include <algorithm>
12 
13 namespace jlm::rvsdg
14 {
15 
16 GraphImport::GraphImport(Graph & graph, std::shared_ptr<const rvsdg::Type> type, std::string name)
17  : RegionArgument(&graph.GetRootRegion(), nullptr, std::move(type)),
18  Name_(std::move(name))
19 {}
20 
21 std::string
23 {
24  return util::strfmt("import[", Name_, "]");
25 }
26 
29 {
30  // FIXME: A import should never be created on a region, but only on a graph. This interface is
31  // broken as it suggest to the user that it should be created on \p region.
32  return Create(*region.graph(), Type(), Name());
33 }
34 
36 GraphImport::Create(Graph & graph, std::shared_ptr<const rvsdg::Type> type, std::string name)
37 {
38  std::unique_ptr<GraphImport> graphImport(
39  new GraphImport(graph, std::move(type), std::move(name)));
40  return static_cast<GraphImport &>(graph.GetRootRegion().addArgument(std::move(graphImport)));
41 }
42 
43 GraphExport::GraphExport(rvsdg::Output & origin, std::string name)
44  : RegionResult(origin.region(), &origin, nullptr, origin.Type()),
45  Name_(std::move(name))
46 {}
47 
48 std::string
50 {
51  return util::strfmt("export[", Name_, "]");
52 }
53 
55 GraphExport::Copy(Output & origin, StructuralOutput * output) const
56 {
57  JLM_ASSERT(output == nullptr);
58  return Create(origin, Name());
59 }
60 
62 GraphExport::Create(Output & origin, std::string name)
63 {
64  if (!origin.region()->IsRootRegion())
65  throw std::logic_error("Cannot create a GraphExport on a non-root region.");
66 
67  std::unique_ptr<GraphExport> graphExport(new GraphExport(origin, std::move(name)));
68  return static_cast<GraphExport &>(graphExport->region()->addResult(std::move(graphExport)));
69 }
70 
71 Graph::~Graph() noexcept = default;
72 
74  : nextRegionId_(0),
75  RootRegion_(new Region(nullptr, this))
76 {}
77 
78 std::unique_ptr<Graph>
79 Graph::Copy() const
80 {
81  SubstitutionMap substitutionMap;
82  auto graph = std::make_unique<Graph>();
83 
84  // copy graph imports
85  for (auto import : GetRootRegion().Arguments())
86  {
87  auto & importCopy = import->Copy(graph->GetRootRegion(), nullptr);
88  substitutionMap.insert(import, &importCopy);
89  }
90 
91  // copy root region
92  GetRootRegion().copy(&graph->GetRootRegion(), substitutionMap);
93 
94  // copy graph exports
95  for (auto xport : GetRootRegion().Results())
96  {
97  auto & newOrigin = substitutionMap.lookup(*xport->origin());
98  xport->Copy(newOrigin, nullptr);
99  }
100 
101  return graph;
102 }
103 
104 std::vector<Node *>
106 {
107  auto IsOnlyExported = [](const rvsdg::Output & output)
108  {
109  auto IsRootRegionExport = [](const rvsdg::Input * input)
110  {
111  if (!input->region()->IsRootRegion())
112  {
113  return false;
114  }
115 
116  if (TryGetOwnerNode<Node>(*input))
117  {
118  return false;
119  }
120 
121  return true;
122  };
123 
124  for (auto & user : output.Users())
125  {
126  if (!IsRootRegionExport(&user))
127  {
128  return false;
129  }
130  }
131 
132  return true;
133  };
134 
135  auto & rootRegion = rvsdg.GetRootRegion();
136 
137  std::vector<Node *> nodes;
138  for (auto & bottomNode : rootRegion.BottomNodes())
139  {
140  nodes.push_back(&bottomNode);
141  }
142 
143  for (size_t n = 0; n < rootRegion.nresults(); n++)
144  {
145  auto output = rootRegion.result(n)->origin();
146  if (IsOnlyExported(*output))
147  {
148  nodes.push_back(rvsdg::TryGetOwnerNode<Node>(*output));
149  }
150  }
151 
152  return nodes;
153 }
154 
155 }
const std::string & Name() const noexcept
Definition: graph.hpp:53
std::string Name_
Definition: graph.hpp:68
std::string debug_string() const override
Definition: graph.cpp:49
static GraphExport & Create(Output &origin, std::string name)
Definition: graph.cpp:62
GraphExport & Copy(Output &origin, StructuralOutput *output) const override
Definition: graph.cpp:55
GraphExport(Output &origin, std::string name)
Definition: graph.cpp:43
GraphImport & Copy(Region &region, StructuralInput *input) const override
Definition: graph.cpp:28
static GraphImport & Create(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:36
std::string Name_
Definition: graph.hpp:40
const std::string & Name() const noexcept
Definition: graph.hpp:25
std::string debug_string() const override
Definition: graph.cpp:22
GraphImport(Graph &graph, std::shared_ptr< const rvsdg::Type > type, std::string name)
Definition: graph.cpp:16
static std::vector< Node * > ExtractTailNodes(const Graph &rvsdg)
Definition: graph.cpp:105
~Graph() noexcept
std::unique_ptr< Graph > Copy() const
Definition: graph.cpp:79
Region & GetRootRegion() const noexcept
Definition: graph.hpp:99
Output * origin() const noexcept
Definition: node.hpp:58
rvsdg::Region * region() const noexcept
Definition: node.cpp:151
Represents the argument of a region.
Definition: region.hpp:41
Represents the result of a region.
Definition: region.hpp:120
StructuralOutput * output() const noexcept
Definition: region.hpp:149
Represent acyclic RVSDG subgraphs.
Definition: region.hpp:213
RegionResult * result(size_t index) const noexcept
Definition: region.hpp:471
RegionArgument & addArgument(std::unique_ptr< RegionArgument > argument)
Definition: region.cpp:176
void copy(Region *target, SubstitutionMap &smap) const
Copy a region with substitutions.
Definition: region.cpp:314
Graph * graph() const noexcept
Definition: region.hpp:363
bool IsRootRegion() const noexcept
Definition: region.cpp:170
void insert(const Output *original, Output *substitute)
Output & lookup(const Output &original) const
#define JLM_ASSERT(x)
Definition: common.hpp:16
static std::string type(const Node *n)
Definition: view.cpp:255
static std::string strfmt(Args... args)
Definition: strfmt.hpp:35