PandA-2024.02
string_cst_fix.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 "string_cst_fix.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_manager.hpp"
69 #include "tree_manipulation.hpp"
70 #include "tree_node.hpp"
71 #include "tree_reindex.hpp"
72 
74 #include "dbgPrintHelper.hpp"
75 #include "exceptions.hpp"
76 #include "string_manipulation.hpp" // for GET_CLASS
77 
78 string_cst_fix::string_cst_fix(const application_managerRef _AppM, const DesignFlowManagerConstRef _design_flow_manager,
79  const ParameterConstRef _parameters)
80  : ApplicationFrontendFlowStep(_AppM, STRING_CST_FIX, _design_flow_manager, _parameters)
81 {
82  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
83 }
84 
86 
89 {
91  switch(relationship_type)
92  {
94  {
95  relationships.insert(std::make_pair(FUNCTION_ANALYSIS, WHOLE_APPLICATION));
96  break;
97  }
99  {
100  break;
101  }
103  {
104  break;
105  }
106  default:
107  {
108  THROW_UNREACHABLE("");
109  }
110  }
111  return relationships;
112 }
113 
115 {
116  const auto CG = AppM->CGetCallGraphManager();
117  const auto TM = AppM->get_tree_manager();
118  const auto reached_body_fun_ids = CG->GetReachedBodyFunctions();
119 
120  for(const auto& function_id : reached_body_fun_ids)
121  {
122  const auto curr_tn = TM->GetTreeNode(function_id);
123  const auto fd = GetPointerS<function_decl>(curr_tn);
124  const auto sl = GetPointerS<statement_list>(GET_NODE(fd->body));
125  const std::string srcp_default = fd->include_name + ":" + STR(fd->line_number) + ":" + STR(fd->column_number);
126 
127  for(auto& arg : fd->list_of_args)
128  {
129  recursive_analysis(arg, srcp_default);
130  }
131 
132  std::map<unsigned int, blocRef>& blocks = sl->list_of_bloc;
133  std::map<unsigned int, blocRef>::iterator it, it_end;
134 
135  it_end = blocks.end();
136  for(it = blocks.begin(); it != it_end; ++it)
137  {
138  for(auto stmt : it->second->CGetStmtList())
139  {
140  recursive_analysis(stmt, srcp_default);
141  }
142  for(auto phi : it->second->CGetPhiList())
143  {
144  recursive_analysis(phi, srcp_default);
145  }
146  }
147  }
148  already_visited_ae.clear();
149  string_cst_map.clear();
151 }
152 
154 {
155  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
156  const tree_managerRef TM = AppM->get_tree_manager();
157  const tree_nodeRef curr_tn = GET_NODE(tn);
159  "-->Analyzing recursively " + curr_tn->get_kind_text() + " " + STR(GET_INDEX_NODE(tn)) + ": " +
160  curr_tn->ToString());
161  switch(curr_tn->get_kind())
162  {
163  case call_expr_K:
164  case aggr_init_expr_K:
165  {
166  auto* ce = GetPointer<call_expr>(curr_tn);
167  for(auto& arg : ce->args)
168  {
169  recursive_analysis(arg, srcp);
170  }
171  break;
172  }
173  case gimple_call_K:
174  {
175  auto* ce = GetPointer<gimple_call>(curr_tn);
176  for(auto& arg : ce->args)
177  {
178  recursive_analysis(arg, srcp);
179  }
180  break;
181  }
182  case gimple_assign_K:
183  {
184  auto* gm = GetPointer<gimple_assign>(curr_tn);
185  if(!gm->clobber)
186  {
187  if(GET_NODE(gm->op0)->get_kind() == var_decl_K &&
188  (GET_NODE(gm->op1)->get_kind() == string_cst_K || GET_NODE(gm->op1)->get_kind() == constructor_K))
189  {
190  auto* vd = GetPointer<var_decl>(GET_NODE(gm->op0));
191  THROW_ASSERT(vd, "not valid variable");
192  if(vd->readonly_flag)
193  {
194  vd->init = gm->op1;
195  gm->init_assignment = true;
196  }
198  }
199  else if(GET_NODE(gm->op0)->get_kind() == var_decl_K && GET_NODE(gm->op1)->get_kind() == var_decl_K &&
200  GetPointer<var_decl>(GET_NODE(gm->op1))->init && GetPointer<var_decl>(GET_NODE(gm->op1))->used == 0)
201  {
202  auto* vd = GetPointer<var_decl>(GET_NODE(gm->op0));
203  THROW_ASSERT(vd, "not valid variable");
204  if(vd->readonly_flag)
205  {
206  vd->init = GetPointer<var_decl>(GET_NODE(gm->op1))->init;
207  gm->init_assignment = true;
208  }
209  else
210  {
212  auto* vd1 = GetPointer<var_decl>(GET_NODE(gm->op1));
213  vd1->include_name = gm->include_name;
214  vd1->line_number = gm->line_number;
215  vd1->column_number = gm->column_number;
216  }
217  }
218  if(!gm->init_assignment)
219  {
220  if(GET_NODE(gm->op0)->get_kind() == var_decl_K &&
221  GetPointer<var_decl>(GET_NODE(gm->op0))->readonly_flag && GET_NODE(gm->op1)->get_kind() == ssa_name_K)
222  {
223  GetPointer<var_decl>(GET_NODE(gm->op0))->readonly_flag = false;
224  }
225  recursive_analysis(gm->op0, srcp);
226  recursive_analysis(gm->op1, srcp);
227  if(gm->predicate)
228  {
229  recursive_analysis(gm->predicate, srcp);
230  }
231  }
232  }
233  break;
234  }
235  case gimple_nop_K:
236  {
237  break;
238  }
239  case var_decl_K:
240  case parm_decl_K:
241  {
242  break;
243  }
244  case ssa_name_K:
245  {
246  auto* sn = GetPointer<ssa_name>(curr_tn);
247  if(sn->var)
248  {
249  recursive_analysis(sn->var, srcp);
250  }
251  break;
252  }
253  case tree_list_K:
254  {
255  tree_nodeRef current = tn;
256  while(current)
257  {
258  recursive_analysis(GetPointer<tree_list>(GET_NODE(current))->valu, srcp);
259  current = GetPointer<tree_list>(GET_NODE(current))->chan;
260  }
261  break;
262  }
264  {
265  if(curr_tn->get_kind() == addr_expr_K)
266  {
268  {
269  break;
270  }
272  }
273  auto* ue = GetPointer<unary_expr>(curr_tn);
274  recursive_analysis(ue->op, srcp);
275  break;
276  }
278  {
279  auto* be = GetPointer<binary_expr>(curr_tn);
280  recursive_analysis(be->op0, srcp);
281  recursive_analysis(be->op1, srcp);
282  break;
283  }
285  {
286  auto* te = GetPointer<ternary_expr>(curr_tn);
287  recursive_analysis(te->op0, srcp);
288  if(te->op1)
289  {
290  recursive_analysis(te->op1, srcp);
291  }
292  if(te->op2)
293  {
294  recursive_analysis(te->op2, srcp);
295  }
296  break;
297  }
299  {
300  auto* qe = GetPointer<quaternary_expr>(curr_tn);
301  recursive_analysis(qe->op0, srcp);
302  if(qe->op1)
303  {
304  recursive_analysis(qe->op1, srcp);
305  }
306  if(qe->op2)
307  {
308  recursive_analysis(qe->op2, srcp);
309  }
310  if(qe->op3)
311  {
312  recursive_analysis(qe->op3, srcp);
313  }
314  break;
315  }
316  case lut_expr_K:
317  {
318  auto* le = GetPointer<lut_expr>(curr_tn);
319  recursive_analysis(le->op0, srcp);
320  recursive_analysis(le->op1, srcp);
321  if(le->op2)
322  {
323  recursive_analysis(le->op2, srcp);
324  }
325  if(le->op3)
326  {
327  recursive_analysis(le->op3, srcp);
328  }
329  if(le->op4)
330  {
331  recursive_analysis(le->op4, srcp);
332  }
333  if(le->op5)
334  {
335  recursive_analysis(le->op5, srcp);
336  }
337  if(le->op6)
338  {
339  recursive_analysis(le->op6, srcp);
340  }
341  if(le->op7)
342  {
343  recursive_analysis(le->op7, srcp);
344  }
345  if(le->op8)
346  {
347  recursive_analysis(le->op8, srcp);
348  }
349  break;
350  }
351  case constructor_K:
352  {
353  auto* co = GetPointer<constructor>(curr_tn);
354  std::vector<std::pair<tree_nodeRef, tree_nodeRef>>& list_of_idx_valu = co->list_of_idx_valu;
355  std::vector<std::pair<tree_nodeRef, tree_nodeRef>>::iterator it, it_end = list_of_idx_valu.end();
356  for(it = list_of_idx_valu.begin(); it != it_end; ++it)
357  {
358  recursive_analysis(it->second, srcp);
359  }
360  break;
361  }
362  case gimple_cond_K:
363  {
364  auto* gc = GetPointer<gimple_cond>(curr_tn);
365  recursive_analysis(gc->op0, srcp);
366  break;
367  }
368  case gimple_switch_K:
369  {
370  auto* se = GetPointer<gimple_switch>(curr_tn);
371  recursive_analysis(se->op0, srcp);
372  break;
373  }
374  case gimple_multi_way_if_K:
375  {
376  auto* gmwi = GetPointer<gimple_multi_way_if>(curr_tn);
377  for(auto cond : gmwi->list_of_cond)
378  {
379  if(cond.first)
380  {
381  recursive_analysis(cond.first, srcp);
382  }
383  }
384  break;
385  }
386  case gimple_return_K:
387  {
388  auto* re = GetPointer<gimple_return>(curr_tn);
389  if(re->op)
390  {
391  recursive_analysis(re->op, srcp);
392  }
393  break;
394  }
395  case gimple_for_K:
396  {
397  auto* fe = GetPointer<gimple_for>(curr_tn);
398  recursive_analysis(fe->op0, srcp);
399  recursive_analysis(fe->op1, srcp);
400  recursive_analysis(fe->op2, srcp);
401  break;
402  }
403  case gimple_while_K:
404  {
405  auto* we = GetPointer<gimple_while>(curr_tn);
406  recursive_analysis(we->op0, srcp);
407  break;
408  }
409  case gimple_phi_K:
410  {
411  auto* gp = GetPointer<gimple_phi>(curr_tn);
412  for(auto def_edge_pair : gp->list_of_def_edge)
413  {
414  recursive_analysis(def_edge_pair.first, srcp);
415  }
416  break;
417  }
418  case CASE_TYPE_NODES:
419  case type_decl_K:
420  {
421  break;
422  }
423  case target_mem_ref_K:
424  {
425  auto* tmr = GetPointer<target_mem_ref>(curr_tn);
426  if(tmr->symbol)
427  {
428  recursive_analysis(tmr->symbol, srcp);
429  }
430  if(tmr->base)
431  {
432  recursive_analysis(tmr->base, srcp);
433  }
434  if(tmr->idx)
435  {
436  recursive_analysis(tmr->idx, srcp);
437  }
438  break;
439  }
440  case target_mem_ref461_K:
441  {
442  auto* tmr = GetPointer<target_mem_ref461>(curr_tn);
443  if(tmr->base)
444  {
445  recursive_analysis(tmr->base, srcp);
446  }
447  if(tmr->idx)
448  {
449  recursive_analysis(tmr->idx, srcp);
450  }
451  if(tmr->idx2)
452  {
453  recursive_analysis(tmr->idx2, srcp);
454  }
455  break;
456  }
457  case string_cst_K:
458  {
459  if(string_cst_map.find(GET_INDEX_NODE(tn)) == string_cst_map.end())
460  {
461  auto* sc = GetPointer<string_cst>(curr_tn);
463  const auto* type_sc = GetPointer<const type_node>(GET_NODE(sc->type));
464  const std::string local_var_name = "__bambu_artificial_var_string_cst_" + STR(GET_INDEX_NODE(tn));
465  auto local_var_identifier = tree_man->create_identifier_node(local_var_name);
466  auto global_scpe = tree_man->create_translation_unit_decl();
467  auto new_var_decl =
468  tree_man->create_var_decl(local_var_identifier, TM->CGetTreeReindex(GET_INDEX_NODE(sc->type)),
469  global_scpe, TM->CGetTreeReindex(GET_INDEX_NODE(type_sc->size)),
470  tree_nodeRef(), TM->CGetTreeReindex(GET_INDEX_NODE(tn)), srcp, type_sc->algn,
471  1, true, -1, false, false, true, false, true);
472  string_cst_map[GET_INDEX_NODE(tn)] = new_var_decl;
473  tn = new_var_decl;
474  }
475  else
476  {
477  tn = string_cst_map.find(GET_INDEX_NODE(tn))->second;
478  }
479  break;
480  }
481  case real_cst_K:
482  case complex_cst_K:
483  case integer_cst_K:
484  case field_decl_K:
485  case function_decl_K:
486  case label_decl_K:
487  case result_decl_K:
488  case template_decl_K:
489  case vector_cst_K:
490  case void_cst_K:
491  case tree_vec_K:
492  case case_label_expr_K:
493  case gimple_label_K:
494  case gimple_asm_K:
495  case gimple_goto_K:
496  case gimple_pragma_K:
497  case gimple_resx_K:
498  case CASE_PRAGMA_NODES:
499  break;
500  case binfo_K:
501  case block_K:
502  case const_decl_K:
503  case CASE_CPP_NODES:
504  case gimple_bind_K:
505  case gimple_predict_K:
506  case identifier_node_K:
507  case last_tree_K:
508  case namespace_decl_K:
509  case none_K:
510  case placeholder_expr_K:
511  case statement_list_K:
512  case translation_unit_decl_K:
513  case error_mark_K:
514  case using_decl_K:
515  case tree_reindex_K:
516  case target_expr_K:
517  {
518  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "Not supported node: " + std::string(curr_tn->get_kind_text()));
519  break;
520  }
521  default:
522  THROW_UNREACHABLE("");
523  }
525  "<--Analyzed recursively " + STR(GET_INDEX_NODE(tn)) + ": " + STR(tn));
526  return;
527 }
#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.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
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.
File containing functions and utilities to support the printing of debug messagges.
std::string ToString() const
Print this node as string in gimple format.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
CustomUnorderedSet< unsigned int > already_visited_ae
Already visited address expression (used to avoid infinite recursion)
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
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
#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
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.
string_cst_fix(const application_managerRef AppM, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
Pre-analysis step fixing readonly initializations and string_cst references.
DesignFlowStep_Status Exec() override
Fixes the var_decl duplication.
#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
void recursive_analysis(tree_nodeRef &tn, const std::string &srcp)
Recursive tree node analysis.
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
void init(int bucket[BUCKETSIZE])
Definition: sort.c:42
CustomUnorderedMap< unsigned int, tree_nodeRef > string_cst_map
relation between constant string and read-only variable initialized with the string_cst.
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
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
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.
~string_cst_fix() override
Destructor.
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
#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.
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