PandA-2024.02
add_bb_ecfg_edges.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  */
43 #include "add_bb_ecfg_edges.hpp"
45 
47 #include "application_manager.hpp"
48 #include "basic_block.hpp"
50 #include "behavioral_helper.hpp"
51 #include "function_behavior.hpp"
52 #include "loop.hpp"
53 #include "loops.hpp"
54 #include "tree_basic_block.hpp"
55 
57 #include "graph.hpp"
58 
60 #include "Parameter.hpp"
61 
63 #include "custom_set.hpp"
64 #include <list>
65 
67 #include "dbgPrintHelper.hpp"
68 #include "exceptions.hpp"
69 #include "hash_helper.hpp"
70 #include "string_manipulation.hpp" // for GET_CLASS
71 
72 AddBbEcfgEdges::AddBbEcfgEdges(const application_managerRef _AppM, unsigned int _function_id,
73  const DesignFlowManagerConstRef _design_flow_manager,
74  const ParameterConstRef _parameters)
75  : FunctionFrontendFlowStep(_AppM, _function_id, ADD_BB_ECFG_EDGES, _design_flow_manager, _parameters)
76 {
77  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
78 }
79 
81 
84 {
86  switch(relationship_type)
87  {
89  {
90  relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION, SAME_FUNCTION));
91  relationships.insert(std::make_pair(BB_ORDER_COMPUTATION, SAME_FUNCTION));
92  break;
93  }
96  {
97  break;
98  }
99  default:
100  {
101  THROW_UNREACHABLE("");
102  }
103  }
104  return relationships;
105 }
106 
108 {
110  const BehavioralHelperConstRef behavioral_helper = function_behavior->CGetBehavioralHelper();
111 
113 #ifndef NDEBUG
114  const std::string function_name = behavioral_helper->get_function_name();
115 #endif
116  const BBGraphRef fbb = function_behavior->GetBBGraph(FunctionBehavior::FBB);
118 
120  const std::list<LoopConstRef>& loops = function_behavior->CGetLoops()->GetList();
121 
123  std::list<LoopConstRef>::const_iterator loop, loop_end = loops.end();
124  for(loop = loops.begin(); loop != loop_end; ++loop)
125  {
126  if((*loop)->GetId() == 0)
127  {
128  continue;
129  }
130  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Considering loop " + std::to_string((*loop)->GetId()));
131 
134  (*loop)->get_recursively_bb(loop_bbs);
135  for(auto cur_bb1 : (*loop)->get_entries())
136  {
137  for(auto cur_bb2 : (*loop)->get_entries())
138  {
139  if(cur_bb1 != cur_bb2)
140  {
141  InEdgeIterator ie, ie_end;
142  for(boost::tie(ie, ie_end) = boost::in_edges(cur_bb1, *fbb); ie != ie_end; ie++)
143  {
144  vertex source = boost::source(*ie, *fbb);
145  if(loop_bbs.find(source) == loop_bbs.end())
146  {
147  function_behavior->bbgc->AddEdge(source, cur_bb2, ECFG_SELECTOR);
148 #ifndef NDEBUG
150  {
151  try
152  {
153  const BBGraphRef ebb_graph = function_behavior->GetBBGraph(FunctionBehavior::EBB);
154  std::list<vertex> vertices;
155  ebb_graph->TopologicalSort(vertices);
156  }
157  catch(const char* msg)
158  {
159  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
160  }
161  catch(const std::string& msg)
162  {
163  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
164  }
165  catch(const std::exception& ex)
166  {
167  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
168  }
169  catch(...)
170  {
171  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
172  }
173  }
174 #endif
175  }
176  }
177  }
178  }
179  }
180 
183 
188 
190  for(auto sp_back_edge : (*loop)->get_sp_back_edges())
191  {
193  if(fbb->CGetBBNodeInfo(sp_back_edge.second)->loop_id == (*loop)->GetId())
194  {
195  sources.insert(sp_back_edge.first);
197  "---Found source BB" +
198  std::to_string(fbb->CGetBBNodeInfo(sp_back_edge.first)->block->number) +
199  " (Target is BB" + STR(fbb->CGetBBNodeInfo(sp_back_edge.second)->block->number) + ")");
200  }
201  }
203  CustomUnorderedSet<vertex> landing_pads = (*loop)->GetLandingPadBlocks();
204  LoopConstRef other_loop = *loop;
206  while([&]() -> bool {
207  for(const auto landing_pad : landing_pads)
208  {
210  "---Analyzing landing pad " + STR(fbb->CGetBBNodeInfo(landing_pad)->block->number));
211  InEdgeIterator ie, ie_end;
212  for(boost::tie(ie, ie_end) = boost::in_edges(landing_pad, *fbb); ie != ie_end; ie++)
213  {
214  const auto source = boost::source(*ie, *fbb);
216  "---Analyzing Edge BB" + STR(fbb->CGetBBNodeInfo(source)->block->number) + "-->BB" +
217  STR(fbb->CGetBBNodeInfo(landing_pad)->block->number));
218  if(fbb->GetSelector(*ie) & FB_CFG_SELECTOR)
219  {
220  if(fbb->CGetBBNodeInfo(source)->loop_id == other_loop->GetId())
221  {
223  "---Going to landing pad BB" +
224  STR(fbb->CGetBBNodeInfo(landing_pad)->block->number) + " of loop " +
225  STR(other_loop->GetId()) + " is feedback edge. Going up one level");
226  return true;
227  }
228  else
229  {
231  other_loop->get_recursively_bb(bb_loops);
232  if(bb_loops.find(source) != bb_loops.end())
233  {
235  "---Going to landing pad BB" +
236  STR(fbb->CGetBBNodeInfo(landing_pad)->block->number) + " of loop " +
237  STR(other_loop->GetId()) + " is feedback edge. Going up one level");
238  return true;
239  }
240  }
241  }
242  }
243  }
244  return false;
245  }())
246  {
247  other_loop = other_loop->Parent();
248  landing_pads = other_loop->GetLandingPadBlocks();
249  }
250  targets.insert(landing_pads.begin(), landing_pads.end());
251 
252  CustomUnorderedSet<vertex>::const_iterator s, s_end = sources.end(), t, t_end = targets.end();
253  for(s = sources.begin(); s != s_end; ++s)
254  {
255  for(t = targets.begin(); t != t_end; ++t)
256  {
258  "---Adding edge from BB" + std::to_string(fbb->CGetBBNodeInfo(*s)->block->number) +
259  " to BB" + std::to_string(fbb->CGetBBNodeInfo(*t)->block->number));
260  function_behavior->bbgc->AddEdge(*s, *t, ECFG_SELECTOR);
261 #ifndef NDEBUG
263  {
264  try
265  {
266  const BBGraphRef ebb_graph = function_behavior->GetBBGraph(FunctionBehavior::EBB);
267  std::list<vertex> vertices;
268  ebb_graph->TopologicalSort(vertices);
269  }
270  catch(const char* msg)
271  {
272  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
273  }
274  catch(const std::string& msg)
275  {
276  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
277  }
278  catch(const std::exception& ex)
279  {
280  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
281  }
282  catch(...)
283  {
284  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
285  }
286  }
287 #endif
288  }
289  }
290  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered loop " + std::to_string((*loop)->GetId()));
291  }
292 
293  if(parameters->getOption<bool>(OPT_print_dot))
294  {
295  function_behavior->GetBBGraph(FunctionBehavior::EBB)->WriteDot("BB_EBB.dot");
296  }
297 
298 #ifndef NDEBUG
299  try
300  {
301  const BBGraphRef ebb_graph = function_behavior->GetBBGraph(FunctionBehavior::EBB);
302  std::list<vertex> vertices;
303  ebb_graph->TopologicalSort(vertices);
304  }
305  catch(const char* msg)
306  {
307  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
308  }
309  catch(const std::string& msg)
310  {
311  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
312  }
313  catch(const std::exception& ex)
314  {
315  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
316  }
317  catch(...)
318  {
319  THROW_UNREACHABLE("ecfg graph of function " + function_name + " is not acyclic");
320  }
321 #endif
323 }
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
int GetSelector() const
Return the selector of this graph.
Definition: graph.hpp:922
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
DesignFlowStep_Status InternalExec() override
Performs the adding of flow edges.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
Definition of the class representing a generic C application.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
Class specification of the graph structures.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
Definition: graph.hpp:1310
exceptions managed by PandA
Basic block control flow graph with edges imposing that basic block inside a loop are executed before...
This class provides methods to build a basic blocks graph.
Data structure describing a basic block at tree level.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
#define FB_CFG_SELECTOR
Feedback control flow edge selector.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
Basic block control flow graph with feedback.
redefinition of set to manage ordered/unordered structures
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
Analysis step which extends basic block cfg.
AddBbEcfgEdges(const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
void TopologicalSort(std::list< boost::graph_traits< graphs_collection >::vertex_descriptor > &sorted_vertices) const
Compute the topological order of the graph.
Definition: graph.hpp:996
Class specification of the basic_block structure.
This file collects some hash functors.
interface of a loop
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
~AddBbEcfgEdges() override
Destructor.
interface of loops finding algorithm
this class is used to manage the command-line or XML options.
int debug_level
The debug level.
#define ECFG_SELECTOR
Extended control flow graph selector.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.

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