PandA-2024.02
application_manager.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 "application_manager.hpp"
45 
46 #include "config_HAVE_FROM_DISCREPANCY_BUILT.hpp"
47 #include "config_HAVE_PRAGMA_BUILT.hpp"
48 
49 #include <limits> // for numeric_limits
50 #if HAVE_FROM_DISCREPANCY_BUILT
51 #include "Discrepancy.hpp" // for Discrepancy
52 #endif
53 #include "Parameter.hpp" // for Parameter, OPT_cfg_max_tra...
54 #include "UnfoldedFunctionInfo.hpp" // for FunctionBehaviorConstRef
55 #include "behavioral_helper.hpp" // for OpGraphConstRef, tree_nodeRef
56 #include "call_graph.hpp" // for CallGraph, CallGraphInfo
57 #include "call_graph_manager.hpp" // for CallGraphManager, CallGrap...
58 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_NONE, INDENT_O...
59 #include "exceptions.hpp" // for THROW_ASSERT, THROW_ERROR
60 #include "ext_tree_node.hpp" // for gimple_while
61 #include "function_behavior.hpp" // for FunctionBehavior, Function...
62 #include "loops.hpp" // for FunctionBehaviorRef
63 #include "op_graph.hpp" // for ENTRY_ID, EXIT_ID, OpGraph
64 #if HAVE_PRAGMA_BUILT
65 #include "pragma_manager.hpp" // for pragma_manager, pragma_man...
66 #endif
67 #include "string_manipulation.hpp" // for STR GET_CLASS
68 #include "tree_common.hpp" // for target_mem_ref461_K, targe...
69 #include "tree_helper.hpp"
70 #include "tree_manager.hpp" // for ParameterConstRef, tree_no...
71 #include "tree_node.hpp" // for tree_nodeRef, tree_node
72 #include "tree_reindex.hpp"
73 
74 application_manager::application_manager(const FunctionExpanderConstRef function_expander,
75  const bool _allow_recursive_functions, const ParameterConstRef _Param)
76  : TM(new tree_manager(_Param)),
77  call_graph_manager(new CallGraphManager(function_expander, _allow_recursive_functions, TM, _Param)),
78  Param(_Param),
79  address_bitsize(
80  _Param->isOption(OPT_addr_bus_bitsize) ?
81  _Param->getOption<unsigned int>(OPT_addr_bus_bitsize) :
82  (_Param->getOption<std::string>(OPT_gcc_m32_mx32).find("-m64") != std::string::npos ? 64 : 32)),
83 #if HAVE_PRAGMA_BUILT
84  PM(new pragma_manager(application_managerRef(this, null_deleter()), _Param)),
85 #endif
86  cfg_transformations(0),
87  debug_level(_Param->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE))
88 #if HAVE_FROM_DISCREPANCY_BUILT
89  ,
90  RDiscr(((_Param->isOption(OPT_discrepancy) and _Param->getOption<bool>(OPT_discrepancy)) or
91  (_Param->isOption(OPT_discrepancy_hw) and _Param->getOption<bool>(OPT_discrepancy_hw))) ?
92  new Discrepancy() :
93  nullptr)
94 #endif
95 {
96  const auto in_files = _Param->getOption<std::list<std::string>>(OPT_input_file);
97  input_files.reserve(in_files.size());
98  std::copy(in_files.begin(), in_files.end(), std::back_inserter(input_files));
99 }
100 
102 
104 {
105  return Param;
106 }
107 
109 {
110  return TM;
111 }
112 
114 {
115  return call_graph_manager;
116 }
117 
119 {
120  return call_graph_manager;
121 }
122 
123 bool application_manager::hasToBeInterfaced(unsigned int funId) const
124 {
125  const auto root_functions = CGetCallGraphManager()->GetRootFunctions();
126  const auto addressed_functions = CGetCallGraphManager()->GetAddressedFunctions();
127 
128  // all the root functions and the reached addressed functions must be interfaced
129  return root_functions.count(funId) || addressed_functions.count(funId);
130 }
131 
133 {
134  const auto& behaviors = call_graph_manager->CGetCallGraph()->CGetCallGraphInfo()->behaviors;
135  THROW_ASSERT(behaviors.find(index) != behaviors.end(), "There is no function with index " + STR(index));
136  return behaviors.at(index);
137 }
138 
140 {
141  const auto& behaviors = call_graph_manager->CGetCallGraph()->CGetCallGraphInfo()->behaviors;
142  THROW_ASSERT(behaviors.count(index), "There is no function with index " + STR(index));
143  return behaviors.at(index);
144 }
145 
147 {
148  return global_variables;
149 }
150 
152 {
153  global_variables.insert(var);
154 }
155 
157 {
158  return call_graph_manager->GetReachedBodyFunctions();
159 }
160 
162 {
163  return call_graph_manager->GetReachedLibraryFunctions();
164 }
165 
166 #if HAVE_PRAGMA_BUILT
167 const pragma_managerRef application_manager::get_pragma_manager() const
168 {
169  return PM;
170 }
171 #endif
172 
173 unsigned int application_manager::get_produced_value(unsigned int fun_id, const vertex& v) const
174 {
175  const auto node = GetProducedValue(fun_id, v);
176  return node ? GET_INDEX_CONST_NODE(node) : 0;
177 }
178 
180 {
181  const auto cfg = CGetFunctionBehavior(fun_id)->CGetOpGraph(FunctionBehavior::CFG);
182  const auto node = cfg->CGetOpNodeInfo(v)->node;
183  return node ? GetProducedValue(node) : nullptr;
184 }
185 
187 {
188  const auto node = GetProducedValue(tn);
189  return node ? GET_INDEX_CONST_NODE(node) : 0;
190 }
191 
193 {
194  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
195  switch(tn->get_kind())
196  {
197  case gimple_while_K:
198  {
199  const auto we = GetPointerS<const gimple_while>(tn);
200  return we->op0;
201  }
202  case gimple_cond_K:
203  {
204  const auto gc = GetPointerS<const gimple_cond>(tn);
205  return gc->op0;
206  }
207  case gimple_label_K:
208  case gimple_return_K:
209  case gimple_call_K:
210  case gimple_goto_K:
211  case CASE_PRAGMA_NODES:
212  case gimple_multi_way_if_K:
213  case gimple_nop_K:
214  {
215  break;
216  }
217  case gimple_phi_K:
218  {
219  const auto gp = GetPointerS<const gimple_phi>(tn);
220  return gp->res;
221  }
222  case gimple_switch_K:
223  {
224  const auto se = GetPointerS<const gimple_switch>(tn);
225  return se->op0;
226  }
227  case gimple_assign_K:
228  {
229  const auto gm = GetPointerS<const gimple_assign>(tn);
230  const auto op0 = GET_CONST_NODE(gm->op0);
231  if(gm->init_assignment || gm->clobber)
232  {
233  break;
234  }
235  else if(op0->get_kind() == array_ref_K)
236  {
237  break;
238  }
239  else if(op0->get_kind() == indirect_ref_K)
240  {
241  break;
242  }
243  else if(op0->get_kind() == misaligned_indirect_ref_K)
244  {
245  break;
246  }
247  else if(op0->get_kind() == mem_ref_K)
248  {
249  break;
250  }
251  else if(op0->get_kind() == target_mem_ref_K)
252  {
253  break;
254  }
255  else if(op0->get_kind() == target_mem_ref461_K)
256  {
257  break;
258  }
259  else
260  {
261  return gm->op0;
262  }
263  break;
264  }
265  case gimple_asm_K:
266  {
267  const auto ga = GetPointerS<const gimple_asm>(tn);
268  if(ga->out)
269  {
270  const auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ga->out));
272  if(tl->valu)
273  {
274  return tl->valu;
275  }
276  else
277  {
278  THROW_ERROR("unexpected condition");
279  }
280  }
281  else
282  {
283  return nullptr;
284  }
285  break;
286  }
287  case binfo_K:
288  case block_K:
289  case call_expr_K:
290  case aggr_init_expr_K:
291  case case_label_expr_K:
292  case constructor_K:
293  case gimple_bind_K:
294  case gimple_for_K:
295  case gimple_pragma_K:
296  case gimple_predict_K:
297  case gimple_resx_K:
298  case identifier_node_K:
299  case ssa_name_K:
300  case statement_list_K:
301  case target_expr_K:
302  case target_mem_ref_K:
303  case target_mem_ref461_K:
304  case tree_list_K:
305  case tree_vec_K:
306  case error_mark_K:
307  case lut_expr_K:
309  case CASE_CPP_NODES:
310  case CASE_CST_NODES:
311  case CASE_DECL_NODES:
312  case CASE_FAKE_NODES:
315  case CASE_TYPE_NODES:
317  THROW_ERROR("Operation not yet supported: " + tn->get_kind_text());
318  break;
319  default:
320  {
321  THROW_UNREACHABLE("");
322  }
323  }
324  return nullptr;
325 }
326 
327 void application_manager::add_written_object(unsigned int node_id)
328 {
329  // std::cerr << "Written object " << node_id << std::endl;
330  written_objects.insert(node_id);
331 }
332 
334 {
335  return written_objects;
336 }
337 
339 {
340  written_objects.clear();
341 }
342 
344 {
345 #ifndef NDEBUG
346  return cfg_transformations < Param->getOption<size_t>(OPT_max_transformations);
347 #else
348  return true;
349 #endif
350 }
351 
353 #ifndef NDEBUG
354  step
355 #endif
356  ,
357  const tree_nodeConstRef
358 #ifndef NDEBUG
359  new_tn
360 #endif
361 )
362 {
363 #ifndef NDEBUG
364  std::string tn_str = "";
365  if(new_tn)
366  {
367  const auto tn = new_tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(new_tn) : new_tn;
368  tn_str = tn->get_kind() == function_decl_K ?
369  ("@" + STR(new_tn->index) +
370  tree_helper::print_function_name(get_tree_manager(), GetPointerS<const function_decl>(tn))) :
371  tn->ToString();
372  }
373  THROW_ASSERT(cfg_transformations < Param->getOption<size_t>(OPT_max_transformations),
374  step + " - " + tn_str + " Transformations " + STR(cfg_transformations));
376  if(Param->getOption<size_t>(OPT_max_transformations) != std::numeric_limits<size_t>::max())
377  {
378  INDENT_OUT_MEX(0, 0, "---Transformation " + STR(cfg_transformations) + " - " + step + " - " + tn_str);
379  }
380 #endif
381 }
382 
383 unsigned application_manager::getSSAFromParm(unsigned int functionID, unsigned parm_index) const
384 {
385  THROW_ASSERT(parm_index, "unexpected null parm_decl index");
386  const auto fun_parms = Parm2SSA_map.find(functionID);
387  if(fun_parms != Parm2SSA_map.end())
388  {
389  const auto parm = fun_parms->second.find(parm_index);
390  if(parm != fun_parms->second.end())
391  {
392  return parm->second;
393  }
394  }
395  return 0U;
396 }
397 
398 void application_manager::setSSAFromParm(unsigned int functionID, unsigned int parm_index, unsigned ssa_index)
399 {
400  THROW_ASSERT(functionID, "unexpected null function id: " + STR(functionID));
401  THROW_ASSERT(parm_index, "unexpected null parm_decl index " + STR(parm_index));
402  THROW_ASSERT(ssa_index, "unexpected null ssa_name index " + STR(ssa_index));
403  if(Parm2SSA_map.find(functionID) == Parm2SSA_map.end())
404  {
405  Parm2SSA_map[functionID][parm_index] = ssa_index;
406  }
407  else
408  {
409  if(Parm2SSA_map.find(functionID)->second.find(parm_index) == Parm2SSA_map.find(functionID)->second.end())
410  {
411  Parm2SSA_map[functionID][parm_index] = ssa_index;
412  }
413  else
414  {
415  THROW_ASSERT(Parm2SSA_map.find(functionID)->second.find(parm_index)->second == ssa_index,
416  "unexpected condition " + STR(functionID) + " " + STR(parm_index) + " " + STR(ssa_index));
417  }
418  }
419 }
420 void application_manager::clearParm2SSA(unsigned int functionID)
421 {
422  Parm2SSA_map[functionID].clear();
423 }
424 
426 {
427  return Parm2SSA_map[functionID];
428 }
application_manager(const FunctionExpanderConstRef function_expander, const bool allow_recursive_functions, const ParameterConstRef _Param)
Constructor.
const ParameterConstRef get_parameter() const
Returns the parameter data-structure.
CustomMap< unsigned, unsigned > getACopyParm2SSA(unsigned int functionID)
return a copy of parameter to SSA map
CustomOrderedSet< unsigned int > get_functions_with_body() const
Returns the set of functions whose implementation is present in the parsed input specification (i...
File containing functions and utilities to support the printing of debug messagges.
std::vector< std::string > input_files
The original input file and the actual source code file to be elaborated.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
#define GET_CLASS(obj)
Macro returning the actual type of an object.
tree_nodeConstRef GetProducedValue(const tree_nodeConstRef &tn) const
Returns the values produced by a vertex (recursive version)
const tree_managerRef get_tree_manager() const
Returns the tree manager associated with the application.
Definition of the class representing a generic C application.
CallGraphManagerRef GetCallGraphManager()
Returns the call graph associated with the application.
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
Definition: tree_node.hpp:672
const tree_managerRef TM
class representing the application information at low level
This class manages the tree structures extracted from the raw file.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
const FunctionBehaviorConstRef CGetFunctionBehavior(unsigned int index) const
Returns the data-structure associated with the given identifier.
CustomOrderedSet< unsigned int > get_functions_without_body() const
Returns the set of functions whose implementation is not present in the parsed input specification (i...
CustomOrderedMap< T, U > CustomMap
Definition: custom_map.hpp:167
exceptions managed by PandA
bool hasToBeInterfaced(unsigned int funId) const
Check for interface generation.
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
const ParameterConstRef Param
class containing all the parameters
bool
Definition: bellmanford.c:29
size_t cfg_transformations
The number of cfg transformations applied to this function.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
A set of const tree node.
Definition: tree_node.hpp:267
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
#define max
Definition: backprop.h:17
CustomOrderedSet< unsigned int > written_objects
store memory objects which can be written
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Definition: op_graph.hpp:843
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
void add_written_object(unsigned int node_id)
Add the node_id to the set of object modified by a store.
void setSSAFromParm(unsigned int functionID, unsigned int parm_index, unsigned ssa_index)
setSSAFromParm defines the parm_decl versus ssa_name relation
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
Control flow graph.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
This C++ header file contains common macros for the tree structure.
This class is used to manage the pragma directives found in the source code.
void AddGlobalVariable(const tree_nodeConstRef &var)
Adds a global variable.
Manager for pragma annotations.
#define index(x, y)
Definition: Keccak.c:74
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
const TreeNodeConstSet & GetGlobalVariables() const
Returns the set of original global variables.
Classes specification of the tree_node data structures.
Call graph hierarchy.
void clearParm2SSA(unsigned int functionID)
clearParm2SSA cleans the map putting into relation parm_decl and ssa_name
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
null deleter
Definition: refcount.hpp:51
CustomMap< unsigned, CustomMap< unsigned, unsigned > > Parm2SSA_map
put into relation formal parameters and the associated ssa variables in a given function ...
TreeNodeConstSet global_variables
set of global variables
bool ApplyNewTransformation() const
Return true if a new transformation can be applied.
virtual ~application_manager()
Destructor.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
void clean_written_objects()
clean_written_objects clean the written object data structure
FunctionBehaviorRef GetFunctionBehavior(unsigned int index)
Returns the data structure associated with the given identifier.
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
unsigned int get_produced_value(const tree_nodeRef &tn) const
Returns the values produced by a vertex (recursive version)
const CallGraphManagerRef call_graph_manager
class representing the call graph of the application
This class manages the accesses to the CallGraph.
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
interface of loops finding algorithm
void RegisterTransformation(const std::string &step, const tree_nodeConstRef new_tn)
Register a transformation.
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
Wrapper to call graph.
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
unsigned getSSAFromParm(unsigned int functionID, unsigned parm_index) const
getSSAFromParm returns the ssa_name index associated with the parm_decl index, 0 in case there is not...
const CustomOrderedSet< unsigned int > & get_written_objects() const
Return the set of variables modified by a store.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
const CallGraphManagerConstRef CGetCallGraphManager() const
Returns the call graph associated with the application.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#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