PandA-2024.02
op_graph.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "op_graph.hpp"
45 
46 #include "Parameter.hpp"
47 #include "behavioral_helper.hpp"
49 #include "exceptions.hpp" // for THROW_ASSERT, THROW...
50 #include "tree_manager.hpp"
51 #include "tree_node.hpp"
52 #include "tree_reindex.hpp"
53 #include <boost/tuple/tuple.hpp> // for tie
54 #include <filesystem> // for create_directories
55 #include <fstream>
56 #include <utility> // for pair
57 
59 
60 OpEdgeInfo::OpEdgeInfo() = default;
61 
62 OpEdgeInfo::~OpEdgeInfo() = default;
63 
65 {
66  if(labels.find(FLG_SELECTOR) == labels.end())
67  {
68  return false;
69  }
70  return labels.find(FLG_SELECTOR)->second.find(T_COND) != labels.find(FLG_SELECTOR)->second.end();
71 }
72 
74 {
75  if(labels.find(FLG_SELECTOR) == labels.end())
76  {
77  return false;
78  }
79  return labels.find(FLG_SELECTOR)->second.find(F_COND) != labels.find(FLG_SELECTOR)->second.end();
80 }
81 
82 OpNodeInfo::OpNodeInfo() : node(tree_nodeRef()), bb_index(0), cer(0)
83 {
84  Initialize();
85 }
86 
88 {
114 }
115 
116 OpNodeInfo::~OpNodeInfo() = default;
117 
119  const FunctionBehavior_VariableAccessType access_type) const
120 {
121  return variables.find(variable_type)->second.find(access_type)->second;
122 }
123 
124 const std::string OpNodeInfo::GetOperation() const
125 {
126  if(vertex_name == ENTRY)
127  {
128  return ENTRY;
129  }
130  if(vertex_name == EXIT)
131  {
132  return EXIT;
133  }
134  if(vertex_name.find("_#empty_") != std::string::npos)
135  {
136  return NOP;
137  }
138  THROW_ASSERT(node, "");
139  THROW_ASSERT(GetPointer<const gimple_node>(GET_NODE(node)),
140  "Node is not a gimple_node but a " + GET_NODE(node)->get_kind_text());
141  return GetPointer<const gimple_node>(GET_NODE(node))->operation;
142 }
143 
144 unsigned int OpNodeInfo::GetNodeId() const
145 {
146  if(node)
147  {
148  return node->index;
149  }
150  else if(vertex_name == ENTRY)
151  {
152  return ENTRY_ID;
153  }
154  else if(vertex_name == EXIT)
155  {
156  return EXIT_ID;
157  }
158  THROW_UNREACHABLE("");
159  return 0;
160 }
161 
162 void PrintVariablesList(std::ostream& stream, const std::string& name, const CustomSet<unsigned int> variables,
163  const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
164 {
165  if(variables.size())
166  {
167  stream << name << ":" << (dotty_format ? "\\n" : "\n");
168  }
169 
170  for(const auto& variable : variables)
171  {
172  stream << behavioral_helper->PrintVariable(variable) << "(" << variable << ")" << (dotty_format ? "\\n" : "\n");
173  }
174 }
175 
176 void PrintMemoriesList(std::ostream& stream, const std::string& name, const CustomSet<MemoryAddress> variables,
177  const BehavioralHelperConstRef, const bool dotty_format)
178 {
179  if(variables.size())
180  {
181  stream << name << ":" << (dotty_format ? "\\n" : "\n");
182  }
183  for(const auto& variable : variables)
184  {
185  stream << from_strongtype_cast<int>(variable) << (dotty_format ? "\\n" : "\n");
186  }
187 }
188 
189 void PrintVariablesLists(std::ostream& stream, const std::string& name,
191  const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
192 {
193  for(const auto& local_variables : variables)
194  {
195  if(local_variables.second.size())
196  {
197  stream << name << ":" << (dotty_format ? "\\n" : "\n");
198  PrintVariablesList(stream, "USES", variables.find(FunctionBehavior_VariableAccessType::USE)->second,
199  behavioral_helper, dotty_format);
200  PrintVariablesList(stream, "DEFS", variables.find(FunctionBehavior_VariableAccessType::DEFINITION)->second,
201  behavioral_helper, dotty_format);
202  PrintVariablesList(stream, "OVERS", variables.find(FunctionBehavior_VariableAccessType::OVER)->second,
203  behavioral_helper, dotty_format);
204  PrintVariablesList(stream, "ADDR", variables.find(FunctionBehavior_VariableAccessType::ADDRESS)->second,
205  behavioral_helper, dotty_format);
206  break;
207  }
208  }
209 }
210 
211 void PrintMemoriesLists(std::ostream& stream, const std::string& name,
213  const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
214 {
215  for(const auto& local_variables : variables)
216  {
217  if(local_variables.second.size())
218  {
219  stream << name << ":" << (dotty_format ? "\\n" : "\n");
220  PrintMemoriesList(stream, "USES", variables.find(FunctionBehavior_VariableAccessType::USE)->second,
221  behavioral_helper, dotty_format);
222  PrintMemoriesList(stream, "DEFS", variables.find(FunctionBehavior_VariableAccessType::DEFINITION)->second,
223  behavioral_helper, dotty_format);
224  PrintMemoriesList(stream, "OVERS", variables.find(FunctionBehavior_VariableAccessType::OVER)->second,
225  behavioral_helper, dotty_format);
226  break;
227  }
228  }
229 }
230 
231 void OpNodeInfo::Print(std::ostream& stream, const BehavioralHelperConstRef behavioral_helper, bool dotty_format) const
232 {
233  PrintVariablesList(stream, "source code variables", cited_variables, behavioral_helper, dotty_format);
235  behavioral_helper, dotty_format);
237  behavioral_helper, dotty_format);
239  behavioral_helper, dotty_format);
240 }
241 
243  : entry_vertex(NULL_VERTEX), exit_vertex(NULL_VERTEX), BH(_BH)
244 {
245 }
246 
247 OpGraphInfo::~OpGraphInfo() = default;
248 
250  : graphs_collection(RefcountCast<GraphInfo>(_info), _parameters),
251  operations(OpGraphConstRef(new OpGraph(OpGraphsCollectionRef(this, null_deleter()), 0)))
252 {
253 }
254 
256 
258 {
259  return operations;
260 }
261 
262 void OpGraphsCollection::RemoveVertex(boost::graph_traits<boost_graphs_collection>::vertex_descriptor v)
263 {
264  operations.erase(v);
266 }
267 
268 boost::graph_traits<boost_graphs_collection>::vertex_descriptor OpGraphsCollection::AddVertex(const NodeInfoRef info)
269 {
270  const auto new_vertex = graphs_collection::AddVertex(info);
271  operations.insert(new_vertex);
272  return new_vertex;
273 }
274 
276 {
277  operations.clear();
278  graphs_collection::clear();
279 }
280 
281 #if HAVE_UNORDERED
283 {
284 }
285 
287 {
288 }
289 
290 #else
291 OpVertexSorter::OpVertexSorter(const OpGraphConstRef _op_graph) : op_graph(_op_graph)
292 {
293 }
294 
295 bool OpVertexSorter::operator()(const vertex x, const vertex y) const
296 {
297  return GET_NAME(op_graph, x) < GET_NAME(op_graph, y);
298 }
299 
301 {
302 }
303 
304 OpEdgeSorter::OpEdgeSorter(const OpGraphConstRef _op_graph) : op_graph(_op_graph)
305 {
306 }
307 
309 {
310  if(x != y)
311  {
312  return GET_NAME(op_graph, boost::source(x, *op_graph)) < GET_NAME(op_graph, boost::source(y, *op_graph));
313  }
315 }
316 
318 {
319 }
320 #endif
321 
322 OpGraph::OpGraph(OpGraphsCollectionRef _op_graphs_collection, int _selector)
323  : graph(_op_graphs_collection.get(), _selector)
324 {
325 }
326 
327 OpGraph::OpGraph(const OpGraphsCollectionRef _op_graphs_collection, int _selector,
328  const CustomUnorderedSet<boost::graph_traits<OpGraphsCollection>::vertex_descriptor>& _sub)
329  : graph(_op_graphs_collection.get(), _selector, _sub)
330 {
331 }
332 
333 OpGraph::~OpGraph() = default;
334 
335 void OpGraph::WriteDot(const std::string& file_name, const int detail_level) const
336 {
337  const BehavioralHelperConstRef helper = CGetOpGraphInfo()->BH;
338  std::string output_directory =
339  collection->parameters->getOption<std::string>(OPT_dot_directory) + "/" + helper->get_function_name() + "/";
340  if(!std::filesystem::exists(output_directory))
341  {
342  std::filesystem::create_directories(output_directory);
343  }
344  const std::string full_name = output_directory + file_name;
345  const VertexWriterConstRef op_label_writer(new OpWriter(this, detail_level));
346  const EdgeWriterConstRef op_edge_property_writer(new OpEdgeWriter(this));
347  InternalWriteDot<const OpWriter, const OpEdgeWriter>(full_name, op_label_writer, op_edge_property_writer);
348 }
349 
351 {
352  null_deleter null;
353  OpGraphConstRef thisRef(this, null);
355  OpVertexSet::const_iterator vertIter, vertIterEnd;
356  for(vertIter = toCheck.begin(), vertIterEnd = toCheck.end(); vertIter != vertIterEnd; ++vertIter)
357  {
358  InEdgeIterator inE, inEEnd;
359  for(boost::tie(inE, inEEnd) = boost::in_edges(*vertIter, *this); inE != inEEnd; inE++)
360  {
361  int origEdgeType = GetSelector(*inE);
362  if((edgeType & origEdgeType) != 0)
363  {
364  const vertex src = boost::source(*inE, *this);
365  if(retVal.find(src) == retVal.end())
366  {
367  retVal.insert(std::pair<vertex, OpVertexSet>(src, OpVertexSet(thisRef)));
368  }
369  retVal.find(src)->second.insert(*vertIter);
370  }
371  }
372  }
373  return retVal;
374 }
375 
377 {
378  const auto ret_value = dynamic_cast<OpGraphsCollection*>(collection)->CGetOperations();
379  return ret_value;
380 }
381 
382 #if HAVE_UNORDERED
383 boost::iterator_range<InEdgeIterator> OpGraph::CGetInEdges(const vertex v) const
384 {
385  return boost::make_iterator_range(boost::in_edges(v, *this));
386 }
387 #else
389 {
390  OpEdgeSet ret_value(OpGraphConstRef(this, null_deleter()));
391  OpVertexSorter op_vertex_sorter(OpGraphConstRef(this, null_deleter()));
392  InEdgeIterator ie, ie_end;
393  for(boost::tie(ie, ie_end) = boost::in_edges(v, *this); ie != ie_end; ie++)
394  {
395  ret_value.insert(*ie);
396  }
397  return ret_value;
398 }
399 #endif
400 
401 #if HAVE_UNORDERED
402 boost::iterator_range<OutEdgeIterator> OpGraph::CGetOutEdges(const vertex v) const
403 {
404  return boost::make_iterator_range(boost::out_edges(v, *this));
405 }
406 #else
408 {
409  OpEdgeSet ret_value(OpGraphConstRef(this, null_deleter()));
410  OpVertexSorter op_vertex_sorter(OpGraphConstRef(this, null_deleter()));
411  OutEdgeIterator oe, oe_end;
412  for(boost::tie(oe, oe_end) = boost::out_edges(v, *this); oe != oe_end; oe++)
413  {
414  ret_value.insert(*oe);
415  }
416  return ret_value;
417 }
418 #endif
419 
420 #if HAVE_HLS_BUILT
421 void OpGraph::WriteDot(const std::string& file_name, const hlsConstRef HLS,
422  const CustomSet<unsigned int> critical_paths) const
423 {
424  const BehavioralHelperConstRef helper = CGetOpGraphInfo()->BH;
425  std::string output_directory =
426  collection->parameters->getOption<std::string>(OPT_dot_directory) + "/" + helper->get_function_name() + "/";
427  if(!std::filesystem::exists(output_directory))
428  {
429  std::filesystem::create_directories(output_directory);
430  }
431  const std::string full_name = output_directory + file_name;
432  const VertexWriterConstRef op_label_writer(new TimedOpWriter(this, HLS, critical_paths));
433  const EdgeWriterConstRef op_edge_property_writer(new TimedOpEdgeWriter(this, HLS, critical_paths));
434  InternalWriteDot<const TimedOpWriter, const TimedOpEdgeWriter>(full_name, op_label_writer, op_edge_property_writer);
435 }
436 #endif
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
#define FLG_SELECTOR
Flow edge selector.
Definition: op_graph.hpp:515
OpEdgeSet CGetInEdges(const vertex v) const
Return the edge ingoing in a vertex.
Definition: op_graph.cpp:388
#define EXIT
Definition: global.h:46
std::string vertex_name
Definition of the node name property.
CustomMap< FunctionBehavior_VariableType, CustomMap< FunctionBehavior_VariableAccessType, CustomSet< unsigned int > > > variables
set of scalar ssa accessed in this node
Definition: op_graph.hpp:370
~OpNodeInfo() override
Destructor.
int GetSelector() const
Return the selector of this graph.
Definition: graph.hpp:922
OpGraphConstRef op_graph
The operation graph to which vertices belong Note: this should be const, but can not because of assig...
Definition: op_graph.hpp:684
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
Definition: graph.hpp:1312
const ParameterConstRef parameters
Set of input parameters.
Definition: graph.hpp:291
~OpGraphsCollection() override
Destructor.
Base class storing user data information to the whole graph.
Definition: graph_info.hpp:60
OpGraphsCollection(const OpGraphInfoRef info, const ParameterConstRef parameters)
Empty Constructror.
Definition: op_graph.cpp:249
string target
Definition: lenet_tvm.py:16
std::string get_function_name() const
Return the name of the function.
Edge writer for operation graph.
boost::graph_traits< boost_graphs_collection >::vertex_descriptor AddVertex(const NodeInfoRef info) override
Add a vertex to this graph with a property.
Definition: op_graph.cpp:268
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
CustomUnorderedMap< vertex, OpVertexSet > GetSrcVertices(const OpVertexSet &toCheck, int edgeType) const
Given a set of vertices, this function computes the edges which have the target in the set and the so...
Definition: op_graph.cpp:350
CustomOrderedMap< T, U > CustomMap
Definition: custom_map.hpp:167
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
Definition: graph.hpp:1310
exceptions managed by PandA
const OpVertexSet CGetOperations() const
Return the vertices belonging to the graph.
Definition: op_graph.cpp:376
FunctionBehavior_VariableType
The possible type of a variable.
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
~OpEdgeInfo() override
Destructor.
refcount< const OpGraph > OpGraphConstRef
Definition: op_graph.hpp:923
void RemoveVertex(boost::graph_traits< boost_graphs_collection >::vertex_descriptor v) override
Remove a vertex from this graph.
Definition: op_graph.cpp:262
void PrintVariablesList(std::ostream &stream, const std::string &name, const CustomSet< unsigned int > variables, const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
Definition: op_graph.cpp:162
A set of operation vertices.
Definition: op_graph.hpp:654
OpGraphConstRef op_graph
The operation graph to which vertices belong Note: this should be const, but can not because of assig...
Definition: op_graph.hpp:633
bool FlgEdgeT() const
Function returning true when the edge is a then flow edge.
Definition: op_graph.cpp:64
unsigned int GetNodeId() const
Return the node id of the operation associated with the vertex.
Definition: op_graph.cpp:144
void WriteDot(const std::string &file_name, const int detail_level=0) const
Writes this graph in dot format.
Definition: op_graph.cpp:335
OpGraph(const OpGraphsCollectionRef _op_graphs_collection, int selector)
Standard constructor.
Definition: op_graph.cpp:322
tree_nodeRef node
The tree node associated with this vertex.
Definition: op_graph.hpp:376
CustomSet< unsigned int > cited_variables
set of cited variables (i.e., variables which are included in the c printing of this statement) ...
Definition: op_graph.hpp:366
~OpGraph() override
Destructor.
void PrintVariablesLists(std::ostream &stream, const std::string &name, const CustomMap< FunctionBehavior_VariableAccessType, CustomSet< unsigned int >> variables, const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
Definition: op_graph.cpp:189
OpEdgeSet CGetOutEdges(const vertex v) const
Return the edge outgoing from a vertex.
Definition: op_graph.cpp:407
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
bool FlgEdgeF() const
Function returning true when the edge is an else flow edge.
Definition: op_graph.cpp:73
#define EXIT_ID
constant used to represent tree node index of exit operation
Definition: op_graph.hpp:81
virtual void RemoveVertex(boost::graph_traits< boost_graphs_collection >::vertex_descriptor v)
Remove a vertex from this graph.
Definition: graph.cpp:44
This class specifies the characteristic of a particular operation working on a given functional unit...
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
#define ENTRY
Superclass include.
const CustomSet< unsigned int > & GetVariables(const FunctionBehavior_VariableType variable_type, const FunctionBehavior_VariableAccessType access_type) const
Return a set of accessed scalar variables.
Definition: op_graph.cpp:118
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Definition: tree_node.hpp:146
const std::string GetOperation() const
Return the operation associated with the vertex.
Definition: op_graph.cpp:124
const OpGraphInfoConstRef CGetOpGraphInfo() const
Returns the property associated with the graph.
Definition: op_graph.hpp:871
std::map< int, CustomOrderedSet< unsigned int > > labels
edge labels; key is the selector
OpNodeInfo()
Constructor.
Definition: op_graph.cpp:82
void Print(std::ostream &stream, const BehavioralHelperConstRef behavioral_helper, const bool dotty_format) const
Print the content of this node.
Definition: op_graph.cpp:231
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
#define T_COND
constant used to represent control edges representing a true edge of a conditional statement...
General class used to describe a graph in PandA.
Definition: graph.hpp:771
FunctionBehavior_VariableAccessType
The access type to a variable.
Classes specification of the tree_node data structures.
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
OpVertexSet operations
The set of operations.
Definition: op_graph.hpp:719
OpEdgeInfo()
Constructor.
null deleter
Definition: refcount.hpp:51
bool operator()(const EdgeDescriptor x, const EdgeDescriptor y) const
Compare position of two edges.
Definition: op_graph.cpp:308
bulk graph.
Definition: graph.hpp:287
OpGraphInfo()
Constructor.
string full_name
Definition: test_panda.py:841
void PrintMemoriesLists(std::ostream &stream, const std::string &name, const CustomMap< FunctionBehavior_VariableAccessType, CustomSet< MemoryAddress >> variables, const BehavioralHelperConstRef behavioral_helper, const bool dotty_format)
Definition: op_graph.cpp:211
Class specification of the tree_reindex support class.
#define ENTRY_ID
constant used to represent tree node index of entry operation
Definition: op_graph.hpp:79
Collect all structs used to write a graph in the dot format.
~OpGraphInfo() override
Destructor();.
OpVertexSorter(const OpGraphConstRef op_graph)
Constructor.
Definition: op_graph.cpp:291
#define NOP
constant string identifying a no operation.
Definition: op_graph.hpp:280
void Initialize()
Initialize variable maps.
Definition: op_graph.cpp:87
Data structures used in operations graph.
OpEdgeSet(const OpGraphConstRef op_graph)
Constructor.
Definition: op_graph.cpp:317
this class is used to manage the command-line or XML options.
#define F_COND
constant used to represent control edges representing a false edge of a conditional statement...
OpVertexSet(const OpGraphConstRef op_graph)
Constructor.
Definition: op_graph.cpp:300
OpEdgeSorter(const OpGraphConstRef op_graph)
Constructor.
Definition: op_graph.cpp:304
void Clear()
Remove all the edges and vertices from the graph.
Definition: op_graph.cpp:275
x
Return the smallest n such that 2^n >= _x.
Class used to describe a particular graph with operations as nodes.
Definition: op_graph.hpp:783
graphs_collection * collection
The graph collection.
Definition: graph.hpp:846
This structure defines graphs where nodes are operations.
Definition: op_graph.hpp:715
virtual boost::graph_traits< boost_graphs_collection >::vertex_descriptor AddVertex(const NodeInfoRef info)
Add a vertex to this graph with a property.
Definition: graph.cpp:57
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
const OpVertexSet CGetOperations() const
Return the vertices belonging to the graph.
Definition: op_graph.cpp:257
Class specification of the manager of the tree structures extracted from the raw file.
void PrintMemoriesList(std::ostream &stream, const std::string &name, const CustomSet< MemoryAddress > variables, const BehavioralHelperConstRef, const bool dotty_format)
Definition: op_graph.cpp:176
bool operator()(const vertex x, const vertex y) const
Compare position of two vertices.
Definition: op_graph.cpp:295
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.
Definition: graph.hpp:1316
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:50 for PandA-2024.02 by doxygen 1.8.13