PandA-2024.02
CallGraphUnfolding.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) 2015-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  */
37 #include "CallGraphUnfolding.hpp"
38 
39 // include from ./
40 #include "Parameter.hpp"
41 
42 // includes from behavior/
43 #include "call_graph.hpp"
44 #include "call_graph_manager.hpp"
45 #include "op_graph.hpp"
46 
47 // include from HLS/
48 #include "hls_manager.hpp"
49 
50 // includes from HLS/vcd/
52 #include "Discrepancy.hpp"
53 #include "UnfoldedCallGraph.hpp"
54 #include "UnfoldedCallInfo.hpp"
55 #include "UnfoldedFunctionInfo.hpp"
56 #include "dbgPrintHelper.hpp"
57 #include "string_manipulation.hpp" // for STR
58 
60  const CallGraphConstRef& cg, const CallSitesInfoRef& call_sites_info)
61 {
62  const auto caller_id = get_node_info<UnfoldedFunctionInfo>(caller_v, ucg)->f_id;
63  // if this function does not call other functions we're done
64  const auto caller = call_sites_info->fu_id_to_call_ids.find(caller_id);
65  if(caller == call_sites_info->fu_id_to_call_ids.cend())
66  {
67  return;
68  }
69 
70  for(const auto& call_id : caller->second) // loop on the calls performed by function caller_id
71  {
72  if(call_id == 0)
73  { // this should happen only for artificial calls
74  continue;
75  }
76  const auto is_direct =
77  !call_sites_info->indirect_calls.count(call_id) && !call_sites_info->taken_addresses.count(call_id);
78  for(const auto& called_id :
79  call_sites_info->call_id_to_called_id.at(call_id)) // loop on the function called by call_id
80  {
81  // compute the behavior of the new vertex
82  const auto& behaviors = cg->CGetCallGraphInfo()->behaviors;
83  const auto b = behaviors.find(called_id);
84  // add a new copy of the vertex representing the called function
85  const auto called_v = ucg.AddVertex(NodeInfoRef(
86  new UnfoldedFunctionInfo(called_id, (b != behaviors.end()) ? b->second : FunctionBehaviorConstRef())));
87  // add an edge between the caller and the called
88  ucg.AddEdge(caller_v, called_v, EdgeInfoRef(new UnfoldedCallInfo(call_id, is_direct)));
89  RecursivelyUnfold(called_v, ucg, cg, call_sites_info);
90  }
91  }
92 }
93 
94 static void Unfold(const HLS_managerRef& HLSMgr)
95 {
96  // check that there is only one root function
97  const auto CGM = HLSMgr->CGetCallGraphManager();
98  const auto root_functions = CGM->GetRootFunctions();
99  THROW_ASSERT(root_functions.size() == 1, STR(root_functions.size()));
100  const auto root_function = *(root_functions.begin());
101  const auto CG = CGM->CGetCallGraph();
102  {
103  /*
104  * Use a visitor to analyze the call graph in HLSMgr and to initialize the
105  * CallSitesInfo in the Discrepancy data.
106  */
107  std::vector<boost::default_color_type> csc_color(boost::num_vertices(*CG));
108  boost::depth_first_visit(*CG, CGM->GetVertex(root_function), CallSitesCollectorVisitor(HLSMgr),
109  boost::make_iterator_property_map(
110  csc_color.begin(), boost::get(boost::vertex_index_t(), *CG), boost::white_color));
111  }
112  /*
113  * After the collection of the data on the call sites we can actually start
114  * to unfold the call graph
115  */
116  const auto FB = HLSMgr->CGetFunctionBehavior(root_function);
117  for(const auto fun_id : CGM->GetReachedFunctionsFrom(root_function))
118  {
119  const auto op_graph = HLSMgr->CGetFunctionBehavior(fun_id)->CGetOpGraph(FunctionBehavior::FCFG);
120  THROW_ASSERT(boost::num_vertices(*op_graph) >= 2,
121  "at least ENTRY and EXIT node must exist for op graph of function " + STR(fun_id));
122  HLSMgr->RDiscr->n_total_operations += boost::num_vertices(*op_graph) - 2;
123  }
124  // insert in the unfolded call graph the root function node
125  HLSMgr->RDiscr->unfolded_root_v =
126  HLSMgr->RDiscr->DiscrepancyCallGraph.AddVertex(NodeInfoRef(new UnfoldedFunctionInfo(root_function, FB)));
127  RecursivelyUnfold(HLSMgr->RDiscr->unfolded_root_v, HLSMgr->RDiscr->DiscrepancyCallGraph, CG,
128  HLSMgr->RDiscr->call_sites_info);
129 }
130 
132  const DesignFlowManagerConstRef _design_flow_manager)
133  : HLS_step(_Param, _HLSMgr, _design_flow_manager, HLSFlowStep_Type::CALL_GRAPH_UNFOLDING)
134 {
135 }
136 
138 
141 {
143 
144  switch(relationship_type)
145  {
147  {
150  break;
151  }
154  {
155  break;
156  }
157  default:
158  {
159  THROW_UNREACHABLE("");
160  }
161  }
162  return ret;
163 }
164 
166 {
167  return true;
168 }
169 
171 {
172  // cleanup data structure if this is not the first execution
173  HLSMgr->RDiscr->clear();
174  /* unfold the call graph and compute data structures used for discrepancy analysis*/
175  INDENT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, "-->Unfolding call graph");
176  Unfold(HLSMgr);
177  INDENT_OUT_MEX(OUTPUT_LEVEL_VERBOSE, output_level, "<--Unfolded call graph");
179 }
const HLS_managerRef HLSMgr
information about all the HLS synthesis
Definition: hls_step.hpp:205
Data structure representing the entire HLS information.
~CallGraphUnfolding() override
File containing functions and utilities to support the printing of debug messagges.
static void Unfold(const HLS_managerRef &HLSMgr)
boost::graph_traits< boost_raw_graph >::vertex_descriptor AddVertex(const NodeInfoRef v_info)
Definition: graph.hpp:108
DesignFlowStep_Status Exec() override
Execute the step.
const int output_level
The output level.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
CallGraphUnfolding(const ParameterConstRef Param, const HLS_managerRef HLSMgr, const DesignFlowManagerConstRef design_flow_manager)
CustomUnorderedMap< unsigned int, UnorderedSetStdStable< unsigned int > > fu_id_to_call_ids
Maps every function to the calls it performs.
Definition: Discrepancy.hpp:66
static void RecursivelyUnfold(const UnfoldedVertexDescriptor caller_v, UnfoldedCallGraph &ucg, const CallGraphConstRef &cg, const CallSitesInfoRef &call_sites_info)
boost::graph_traits< boost_raw_graph >::edge_descriptor AddEdge(boost::graph_traits< boost_raw_graph >::vertex_descriptor src, boost::graph_traits< boost_raw_graph >::vertex_descriptor tgt, const EdgeInfoRef e_info)
Definition: graph.hpp:131
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
HLSFlowStep_Type
Definition: hls_step.hpp:95
refcount< EdgeInfo > EdgeInfoRef
RefCount type definition of the edge_info class structure.
Definition: edge_info.hpp:67
CustomUnorderedMap< unsigned int, UnorderedSetStdStable< unsigned int > > call_id_to_called_id
Maps every id of a call site to the id of the called function.
Definition: Discrepancy.hpp:68
DesignFlowStep_Status
The status of a step.
Call graph hierarchy.
boost::graph_traits< UnfoldedCallGraph >::vertex_descriptor UnfoldedVertexDescriptor
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
refcount< NodeInfo > NodeInfoRef
RefCount type definition of the NodeInfo class structure.
Definition: node_info.hpp:98
CustomUnorderedSet< unsigned int > indirect_calls
Set of indirect calls.
Definition: Discrepancy.hpp:70
CustomUnorderedSet< unsigned int > taken_addresses
Set of taken addresses.
Definition: Discrepancy.hpp:72
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
this class is used to manage the command-line or XML options.
Wrapper to call graph.
Control flow graph with feedback.
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
Definition: hls_step.hpp:93
#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:54 for PandA-2024.02 by doxygen 1.8.13