PandA-2024.02
parm2ssa.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) 2019-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 "parm2ssa.hpp"
45 
47 #include "application_manager.hpp"
48 #include "call_graph.hpp"
49 #include "call_graph_manager.hpp"
50 #include "function_behavior.hpp"
51 
53 
55 #include "Parameter.hpp"
56 
58 #include <fstream>
59 
61 #include "custom_map.hpp"
62 #include <string>
63 
65 #include "behavioral_helper.hpp"
66 #include "ext_tree_node.hpp"
67 #include "tree_basic_block.hpp"
68 #include "tree_helper.hpp"
69 #include "tree_manager.hpp"
70 #include "tree_manipulation.hpp"
71 #include "tree_node.hpp"
72 #include "tree_reindex.hpp"
73 
75 #include "dbgPrintHelper.hpp"
76 #include "exceptions.hpp"
77 #include "string_manipulation.hpp" // for GET_CLASS
78 
79 parm2ssa::parm2ssa(const ParameterConstRef _parameters, const application_managerRef _AppM, unsigned int _function_id,
80  const DesignFlowManagerConstRef _design_flow_manager)
81  : FunctionFrontendFlowStep(_AppM, _function_id, PARM2SSA, _design_flow_manager, _parameters)
82 {
83  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
84 }
85 
86 parm2ssa::~parm2ssa() = default;
87 
90 {
92  switch(relationship_type)
93  {
95  {
96  relationships.insert(std::make_pair(PARM_DECL_TAKEN_ADDRESS, SAME_FUNCTION));
97  relationships.insert(std::make_pair(FIX_STRUCTS_PASSED_BY_VALUE, SAME_FUNCTION));
98  break;
99  }
101  {
102  break;
103  }
105  {
106  break;
107  }
108  default:
109  {
110  THROW_UNREACHABLE("");
111  }
112  }
113  return relationships;
114 }
115 
117 {
118  const auto TM = AppM->get_tree_manager();
119  const tree_manipulationRef IRman(new tree_manipulation(TM, parameters, AppM));
121  CustomUnorderedSet<unsigned int> already_visited_ae;
122 
123  const auto beforeParm2SSA = AppM->getACopyParm2SSA(function_id);
124  AppM->clearParm2SSA(function_id);
125 
126  const auto curr_tn = TM->GetTreeNode(function_id);
127  const auto fd = GetPointer<function_decl>(curr_tn);
128  const auto sl = GetPointer<statement_list>(GET_NODE(fd->body));
129  const std::string srcp_default = fd->include_name + ":" + STR(fd->line_number) + ":" + STR(fd->column_number);
131  "-->Analyzing function " + STR(function_id) + ": " + tree_helper::GetMangledFunctionName(fd));
132 
133  for(const auto& arg : fd->list_of_args)
134  {
135  recursive_analysis(arg, srcp_default, already_visited_ae);
136  }
137 
138  for(const auto& bb : sl->list_of_bloc)
139  {
140  for(const auto& stmt : bb.second->CGetStmtList())
141  {
142  recursive_analysis(stmt, srcp_default, already_visited_ae);
143  }
144  for(const auto& phi : bb.second->CGetPhiList())
145  {
146  recursive_analysis(phi, srcp_default, already_visited_ae);
147  }
148  }
149 
150  // TODO: should not be requested, but removing this causes issues with BitValue Inference steps
151  for(const auto& arg : fd->list_of_args)
152  {
153  if(!AppM->getSSAFromParm(function_id, GET_INDEX_CONST_NODE(arg)))
154  {
155  const auto pd = GetPointer<const parm_decl>(GET_NODE(arg));
156  const auto ssa_par = IRman->create_ssa_name(arg, pd->type, tree_nodeRef(), tree_nodeRef());
157  AppM->setSSAFromParm(function_id, GET_INDEX_CONST_NODE(arg), GET_INDEX_CONST_NODE(ssa_par));
158  }
159  }
160 
162  "<--Analyzed function " + STR(function_id) + ": " + tree_helper::GetMangledFunctionName(fd));
163  const auto afterParm2SSA = AppM->getACopyParm2SSA(function_id);
164  const auto modified = afterParm2SSA != beforeParm2SSA;
165  if(modified)
166  {
167  function_behavior->UpdateBBVersion();
168  }
170 }
171 
172 void parm2ssa::recursive_analysis(const tree_nodeRef& tn, const std::string& srcp,
173  CustomUnorderedSet<unsigned int>& already_visited_ae)
174 {
175  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
176  const auto TM = AppM->get_tree_manager();
177  const auto curr_tn = GET_NODE(tn);
179  "-->Analyzing recursively " + curr_tn->get_kind_text() + " " + STR(GET_INDEX_NODE(tn)) + ": " +
180  curr_tn->ToString());
181  switch(curr_tn->get_kind())
182  {
183  case call_expr_K:
184  case aggr_init_expr_K:
185  {
186  const auto ce = GetPointerS<call_expr>(curr_tn);
187  for(const auto& arg : ce->args)
188  {
189  recursive_analysis(arg, srcp, already_visited_ae);
190  }
191  break;
192  }
193  case gimple_call_K:
194  {
195  const auto ce = GetPointerS<gimple_call>(curr_tn);
196  for(const auto& arg : ce->args)
197  {
198  recursive_analysis(arg, srcp, already_visited_ae);
199  }
200  break;
201  }
202  case gimple_assign_K:
203  {
204  const auto gm = GetPointerS<gimple_assign>(curr_tn);
205  if(!gm->clobber)
206  {
207  if(!gm->init_assignment)
208  {
209  recursive_analysis(gm->op0, srcp, already_visited_ae);
210  recursive_analysis(gm->op1, srcp, already_visited_ae);
211  if(gm->predicate)
212  {
213  recursive_analysis(gm->predicate, srcp, already_visited_ae);
214  }
215  }
216  }
217  break;
218  }
219  case gimple_nop_K:
220  {
221  break;
222  }
223  case var_decl_K:
224  case parm_decl_K:
225  {
226  break;
227  }
228  case ssa_name_K:
229  {
230  const auto sn = GetPointerS<ssa_name>(curr_tn);
231  if(sn->var)
232  {
233  const auto defStmt = sn->CGetDefStmt();
234  if(GET_NODE(sn->var)->get_kind() == parm_decl_K && GET_NODE(defStmt)->get_kind() == gimple_nop_K)
235  {
237  "---Setting " + STR(GET_INDEX_NODE(sn->var)) + "-> " + STR(GET_INDEX_NODE(tn)) + " " +
238  STR(GET_INDEX_NODE(tn)));
239  AppM->setSSAFromParm(function_id, GET_INDEX_NODE(sn->var), GET_INDEX_NODE(tn));
240  }
241  recursive_analysis(sn->var, srcp, already_visited_ae);
242  }
243  break;
244  }
245  case tree_list_K:
246  {
247  auto current = tn;
248  while(current)
249  {
250  recursive_analysis(GetPointerS<tree_list>(GET_NODE(current))->valu, srcp, already_visited_ae);
251  current = GetPointerS<tree_list>(GET_NODE(current))->chan;
252  }
253  break;
254  }
256  {
257  if(curr_tn->get_kind() == addr_expr_K)
258  {
259  if(already_visited_ae.find(GET_INDEX_NODE(tn)) != already_visited_ae.end())
260  {
261  break;
262  }
263  already_visited_ae.insert(GET_INDEX_NODE(tn));
264  }
265  const auto ue = GetPointerS<unary_expr>(curr_tn);
266  recursive_analysis(ue->op, srcp, already_visited_ae);
267  break;
268  }
270  {
271  const auto be = GetPointerS<binary_expr>(curr_tn);
272  recursive_analysis(be->op0, srcp, already_visited_ae);
273  recursive_analysis(be->op1, srcp, already_visited_ae);
274  break;
275  }
277  {
278  const auto te = GetPointerS<ternary_expr>(curr_tn);
279  recursive_analysis(te->op0, srcp, already_visited_ae);
280  if(te->op1)
281  {
282  recursive_analysis(te->op1, srcp, already_visited_ae);
283  }
284  if(te->op2)
285  {
286  recursive_analysis(te->op2, srcp, already_visited_ae);
287  }
288  break;
289  }
291  {
292  const auto qe = GetPointerS<quaternary_expr>(curr_tn);
293  recursive_analysis(qe->op0, srcp, already_visited_ae);
294  if(qe->op1)
295  {
296  recursive_analysis(qe->op1, srcp, already_visited_ae);
297  }
298  if(qe->op2)
299  {
300  recursive_analysis(qe->op2, srcp, already_visited_ae);
301  }
302  if(qe->op3)
303  {
304  recursive_analysis(qe->op3, srcp, already_visited_ae);
305  }
306  break;
307  }
308  case lut_expr_K:
309  {
310  const auto le = GetPointerS<lut_expr>(curr_tn);
311  recursive_analysis(le->op0, srcp, already_visited_ae);
312  recursive_analysis(le->op1, srcp, already_visited_ae);
313  if(le->op2)
314  {
315  recursive_analysis(le->op2, srcp, already_visited_ae);
316  }
317  if(le->op3)
318  {
319  recursive_analysis(le->op3, srcp, already_visited_ae);
320  }
321  if(le->op4)
322  {
323  recursive_analysis(le->op4, srcp, already_visited_ae);
324  }
325  if(le->op5)
326  {
327  recursive_analysis(le->op5, srcp, already_visited_ae);
328  }
329  if(le->op6)
330  {
331  recursive_analysis(le->op6, srcp, already_visited_ae);
332  }
333  if(le->op7)
334  {
335  recursive_analysis(le->op7, srcp, already_visited_ae);
336  }
337  if(le->op8)
338  {
339  recursive_analysis(le->op8, srcp, already_visited_ae);
340  }
341  break;
342  }
343  case constructor_K:
344  {
345  const auto co = GetPointerS<constructor>(curr_tn);
346  for(const auto& idx_valu : co->list_of_idx_valu)
347  {
348  recursive_analysis(idx_valu.second, srcp, already_visited_ae);
349  }
350  break;
351  }
352  case gimple_cond_K:
353  {
354  const auto gc = GetPointerS<gimple_cond>(curr_tn);
355  recursive_analysis(gc->op0, srcp, already_visited_ae);
356  break;
357  }
358  case gimple_switch_K:
359  {
360  auto se = GetPointer<gimple_switch>(curr_tn);
361  recursive_analysis(se->op0, srcp, already_visited_ae);
362  break;
363  }
364  case gimple_multi_way_if_K:
365  {
366  const auto gmwi = GetPointerS<gimple_multi_way_if>(curr_tn);
367  for(const auto& cond : gmwi->list_of_cond)
368  {
369  if(cond.first)
370  {
371  recursive_analysis(cond.first, srcp, already_visited_ae);
372  }
373  }
374  break;
375  }
376  case gimple_return_K:
377  {
378  const auto re = GetPointerS<gimple_return>(curr_tn);
379  if(re->op)
380  {
381  recursive_analysis(re->op, srcp, already_visited_ae);
382  }
383  break;
384  }
385  case gimple_for_K:
386  {
387  const auto fe = GetPointerS<gimple_for>(curr_tn);
388  recursive_analysis(fe->op0, srcp, already_visited_ae);
389  recursive_analysis(fe->op1, srcp, already_visited_ae);
390  recursive_analysis(fe->op2, srcp, already_visited_ae);
391  break;
392  }
393  case gimple_while_K:
394  {
395  const auto we = GetPointerS<gimple_while>(curr_tn);
396  recursive_analysis(we->op0, srcp, already_visited_ae);
397  break;
398  }
399  case gimple_phi_K:
400  {
401  const auto gp = GetPointerS<gimple_phi>(curr_tn);
402  for(const auto& def_edge_pair : gp->list_of_def_edge)
403  {
404  recursive_analysis(def_edge_pair.first, srcp, already_visited_ae);
405  }
406  break;
407  }
408  case CASE_TYPE_NODES:
409  case type_decl_K:
410  {
411  break;
412  }
413  case target_mem_ref_K:
414  {
415  const auto tmr = GetPointerS<target_mem_ref>(curr_tn);
416  if(tmr->symbol)
417  {
418  recursive_analysis(tmr->symbol, srcp, already_visited_ae);
419  }
420  if(tmr->base)
421  {
422  recursive_analysis(tmr->base, srcp, already_visited_ae);
423  }
424  if(tmr->idx)
425  {
426  recursive_analysis(tmr->idx, srcp, already_visited_ae);
427  }
428  break;
429  }
430  case target_mem_ref461_K:
431  {
432  const auto tmr = GetPointerS<target_mem_ref461>(curr_tn);
433  if(tmr->base)
434  {
435  recursive_analysis(tmr->base, srcp, already_visited_ae);
436  }
437  if(tmr->idx)
438  {
439  recursive_analysis(tmr->idx, srcp, already_visited_ae);
440  }
441  if(tmr->idx2)
442  {
443  recursive_analysis(tmr->idx2, srcp, already_visited_ae);
444  }
445  break;
446  }
447  case string_cst_K:
448  {
449  break;
450  }
451  case real_cst_K:
452  case complex_cst_K:
453  case integer_cst_K:
454  case field_decl_K:
455  case function_decl_K:
456  case label_decl_K:
457  case result_decl_K:
458  case template_decl_K:
459  case vector_cst_K:
460  case void_cst_K:
461  case tree_vec_K:
462  case case_label_expr_K:
463  case gimple_label_K:
464  case gimple_asm_K:
465  case gimple_goto_K:
466  case gimple_pragma_K:
467  case gimple_resx_K:
468  case CASE_PRAGMA_NODES:
469  break;
470  case binfo_K:
471  case block_K:
472  case const_decl_K:
473  case CASE_CPP_NODES:
474  case gimple_bind_K:
475  case gimple_predict_K:
476  case identifier_node_K:
477  case last_tree_K:
478  case namespace_decl_K:
479  case none_K:
480  case placeholder_expr_K:
481  case statement_list_K:
482  case translation_unit_decl_K:
483  case error_mark_K:
484  case using_decl_K:
485  case tree_reindex_K:
486  case target_expr_K:
487  {
488  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "Not supported node: " + curr_tn->get_kind_text());
489  break;
490  }
491  default:
492  THROW_UNREACHABLE("");
493  }
495  "<--Analyzed recursively " + STR(GET_INDEX_NODE(tn)) + ": " + STR(tn));
496  return;
497 }
#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 DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
parm2ssa(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int _function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
Definition: parm2ssa.cpp:79
#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.
Step successfully executed.
#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.
Definition of the class representing a generic C application.
struct definition of the source position.
Definition: tree_node.hpp:832
RelationshipType
The relationship type.
Source must be executed to satisfy target.
exceptions managed by PandA
~parm2ssa() override
Destructor.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:361
Node not yet supported.
Definition: exceptions.hpp:323
Data structure describing a basic block at tree level.
redefinition of map to manage ordered/unordered structures
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
Pre-analysis step computing the relation between parm_decl and the associated ssa_name.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Call graph hierarchy.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
const unsigned int function_id
The index of the function to be analyzed.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
void recursive_analysis(const tree_nodeRef &tn, const std::string &srcp, CustomUnorderedSet< unsigned int > &already_visited_ae)
Recursive tree node analysis.
Definition: parm2ssa.cpp:172
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
tree_nodeRef create_ssa_name(const tree_nodeConstRef &var, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, bool volatile_flag=false, bool virtual_flag=false) const
MISCELLANEOUS_OBJ_TREE_NODES.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
Wrapper to call graph.
int debug_level
The debug level.
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.
Definition: parm2ssa.cpp:89
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
DesignFlowStep_Status InternalExec() override
Computes the relation between parameters and their SSA obj.
Definition: parm2ssa.cpp:116
#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 FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
int sl
Definition: adpcm.c:105
#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:52 for PandA-2024.02 by doxygen 1.8.13