Jlm
ipgraph.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2013 2014 2015 Nico Reißmann <nico.reissmann@gmail.com>
3  * See COPYING for terms of redistribution.
4  */
5 
7 
8 #include <algorithm>
9 
10 /* Tarjan's SCC algorithm */
11 
12 static void
15  std::unordered_map<const jlm::llvm::InterProceduralGraphNode *, std::pair<size_t, size_t>> &
16  map,
17  std::vector<const jlm::llvm::InterProceduralGraphNode *> & node_stack,
18  size_t & index,
19  std::vector<std::unordered_set<const jlm::llvm::InterProceduralGraphNode *>> & sccs)
20 {
21  map.emplace(node, std::make_pair(index, index));
22  node_stack.push_back(node);
23  index++;
24 
25  for (auto callee : *node)
26  {
27  if (map.find(callee) == map.end())
28  {
29  /* successor has not been visited yet; recurse on it */
30  strongconnect(callee, map, node_stack, index, sccs);
31  map[node].second = std::min(map[node].second, map[callee].second);
32  }
33  else if (std::find(node_stack.begin(), node_stack.end(), callee) != node_stack.end())
34  {
35  /* successor is in stack and hence in the current SCC */
36  map[node].second = std::min(map[node].second, map[callee].first);
37  }
38  }
39 
40  if (map[node].second == map[node].first)
41  {
42  std::unordered_set<const jlm::llvm::InterProceduralGraphNode *> scc;
43  const jlm::llvm::InterProceduralGraphNode * w = nullptr;
44  do
45  {
46  w = node_stack.back();
47  node_stack.pop_back();
48  scc.insert(w);
49  } while (w != node);
50 
51  sccs.push_back(scc);
52  }
53 }
54 
55 namespace jlm::llvm
56 {
57 
58 void
59 InterProceduralGraph::add_node(std::unique_ptr<InterProceduralGraphNode> node)
60 {
61  nodes_.push_back(std::move(node));
62 }
63 
64 std::vector<std::unordered_set<const InterProceduralGraphNode *>>
66 {
67  std::vector<std::unordered_set<const InterProceduralGraphNode *>> sccs;
68 
69  std::unordered_map<const InterProceduralGraphNode *, std::pair<size_t, size_t>> map;
70  std::vector<const InterProceduralGraphNode *> node_stack;
71  size_t index = 0;
72 
73  for (auto & node : *this)
74  {
75  if (map.find(&node) == map.end())
76  strongconnect(&node, map, node_stack, index, sccs);
77  }
78 
79  return sccs;
80 }
81 
83 InterProceduralGraph::find(const std::string & name) const noexcept
84 {
85  for (auto & node : nodes_)
86  {
87  if (node->name() == name)
88  return node.get();
89  }
90 
91  return nullptr;
92 }
93 
95 
96 FunctionNode::~FunctionNode() noexcept = default;
97 
98 const std::string &
99 FunctionNode::name() const noexcept
100 {
101  return name_;
102 }
103 
104 const jlm::rvsdg::Type &
105 FunctionNode::type() const noexcept
106 {
107  return *FunctionType_;
108 }
109 
110 std::shared_ptr<const jlm::rvsdg::Type>
112 {
113  return FunctionType_;
114 }
115 
116 const llvm::Linkage &
117 FunctionNode::linkage() const noexcept
118 {
119  return linkage_;
120 }
121 
122 bool
123 FunctionNode::hasBody() const noexcept
124 {
125  return cfg() != nullptr;
126 }
127 
128 void
129 FunctionNode::add_cfg(std::unique_ptr<ControlFlowGraph> cfg)
130 {
131  if (cfg->fcttype() != fcttype())
132  throw util::Error("CFG does not match the function node's type.");
133 
134  cfg_ = std::move(cfg);
135 }
136 
137 FunctionVariable::~FunctionVariable() noexcept = default;
138 
139 DataNode::~DataNode() noexcept = default;
140 
141 const std::string &
142 DataNode::name() const noexcept
143 {
144  return name_;
145 }
146 
147 const PointerType &
148 DataNode::type() const noexcept
149 {
150  static PointerType pointerType;
151  return pointerType;
152 }
153 
154 std::shared_ptr<const rvsdg::Type>
156 {
157  return PointerType::Create();
158 }
159 
160 const llvm::Linkage &
161 DataNode::linkage() const noexcept
162 {
163  return linkage_;
164 }
165 
166 bool
167 DataNode::hasBody() const noexcept
168 {
169  return initialization() != nullptr;
170 }
171 
172 }
rvsdg::FunctionType fcttype() const
Definition: cfg.hpp:252
llvm::Linkage linkage_
Definition: ipgraph.hpp:404
std::shared_ptr< const jlm::rvsdg::Type > Type() const override
Definition: ipgraph.cpp:155
const llvm::Linkage & linkage() const noexcept override
Definition: ipgraph.cpp:161
const DataNodeInit * initialization() const noexcept
Definition: ipgraph.hpp:367
const PointerType & type() const noexcept override
Definition: ipgraph.cpp:148
bool hasBody() const noexcept override
Definition: ipgraph.cpp:167
const jlm::rvsdg::Type & type() const noexcept override
Definition: ipgraph.cpp:105
const rvsdg::FunctionType & fcttype() const noexcept
Definition: ipgraph.hpp:175
std::shared_ptr< const rvsdg::FunctionType > FunctionType_
Definition: ipgraph.hpp:234
void add_cfg(std::unique_ptr< ControlFlowGraph > cfg)
Adds cfg to the function node. If the function node already has a CFG, then it is replaced with cfg.
Definition: ipgraph.cpp:129
std::unique_ptr< ControlFlowGraph > cfg_
Definition: ipgraph.hpp:238
llvm::Linkage linkage_
Definition: ipgraph.hpp:236
bool hasBody() const noexcept override
Definition: ipgraph.cpp:123
const llvm::Linkage & linkage() const noexcept override
Definition: ipgraph.cpp:117
llvm::ControlFlowGraph * cfg() const noexcept
Definition: ipgraph.hpp:163
std::shared_ptr< const jlm::rvsdg::Type > Type() const override
Definition: ipgraph.cpp:111
~FunctionVariable() noexcept override
virtual ~InterProceduralGraphNode() noexcept
std::vector< std::unordered_set< const InterProceduralGraphNode * > > find_sccs() const
Definition: ipgraph.cpp:65
const InterProceduralGraphNode * find(const std::string &name) const noexcept
Definition: ipgraph.cpp:83
std::vector< std::unique_ptr< InterProceduralGraphNode > > nodes_
Definition: ipgraph.hpp:71
void add_node(std::unique_ptr< InterProceduralGraphNode > node)
Definition: ipgraph.cpp:59
PointerType class.
Definition: types.hpp:25
static std::shared_ptr< const PointerType > Create()
Definition: types.cpp:45
static void strongconnect(const jlm::llvm::InterProceduralGraphNode *node, std::unordered_map< const jlm::llvm::InterProceduralGraphNode *, std::pair< size_t, size_t >> &map, std::vector< const jlm::llvm::InterProceduralGraphNode * > &node_stack, size_t &index, std::vector< std::unordered_set< const jlm::llvm::InterProceduralGraphNode * >> &sccs)
Definition: ipgraph.cpp:13
Global memory state passed between functions.
static void strongconnect(ControlFlowGraphNode *node, ControlFlowGraphNode *exit, std::unordered_map< ControlFlowGraphNode *, std::pair< size_t, size_t >> &map, std::vector< ControlFlowGraphNode * > &node_stack, size_t &index, std::vector< StronglyConnectedComponent > &sccs)