PandA-2024.02
tree_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  */
46 #include "config_HAVE_HEXFLOAT.hpp"
48 #include "config_NPROFILE.hpp"
49 
51 #include "exceptions.hpp" // for THROW_ASSERT, THROW...
52 #include "string_manipulation.hpp" // for STR GET_CLASS
53 #include "tree_manager.hpp"
54 #include <cstring> // for strlen, size_t
55 #include <fstream> // for operator<<, basic_o...
56 #include <iostream> // for operator<<, basic_o...
57 #include <list> // for list
58 #include <vector> // for vector, allocator
59 #if !HAVE_HEXFLOAT
60 #include <cstdio>
61 #endif
62 
64 #include "Parameter.hpp"
65 
67 #include "token_interface.hpp"
68 
70 #include "ext_tree_node.hpp"
71 #include "gimple_writer.hpp"
72 #include "raw_writer.hpp"
73 #include "tree_basic_block.hpp"
74 #include "tree_helper.hpp"
75 #include "tree_node.hpp"
76 #include "tree_node_factory.hpp"
77 #include "tree_node_finder.hpp"
78 #include "tree_nodes_merger.hpp"
79 #include "tree_reindex.hpp"
80 
82 #include "compiler_wrapper.hpp"
83 
84 #include "dbgPrintHelper.hpp"
85 #include "utility.hpp"
86 
88  : n_pl(0),
89  added_goto(0),
90  removed_pointer_plus(0),
91  removable_pointer_plus(0),
92  unremoved_pointer_plus(0),
93  debug_level(_Param->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE)),
94  last_node_id(1),
95  Param(_Param),
96  next_vers(0),
97  collapse_into_counter(0)
98 {
99 }
100 
101 tree_manager::~tree_manager() = default;
102 
103 unsigned int tree_manager::get_implementation_node(unsigned int decl_node) const
104 {
105  THROW_ASSERT(GetPointer<function_decl>(get_tree_node_const(decl_node)),
106  "Node " + STR(decl_node) +
107  " is not a function decl: " + get_tree_node_const(decl_node)->get_kind_text());
108  if(GetPointer<function_decl>(get_tree_node_const(decl_node))->body)
109  {
110  return decl_node;
111  }
112  else
113  {
114  return 0;
115  }
116 }
117 
118 void tree_manager::AddTreeNode(unsigned int i, const tree_nodeRef& curr)
119 {
120  THROW_ASSERT(i > 0, "Expected a positive index");
121  THROW_ASSERT(curr, "Invalid tree node: " + STR(i));
122  if(i >= last_node_id)
123  {
124  last_node_id = i + 1;
125  }
126  tree_nodes[i] = curr;
127 }
128 
130 {
131  THROW_ASSERT(index > 0, "Expected a positive index (" + STR(index) + ")");
132  if(index >= last_node_id)
133  {
134  last_node_id = index + 1;
135  }
136  return tree_nodeRef(new tree_reindex(index, tree_nodes[index]));
137 }
138 
139 const tree_nodeRef tree_manager::CGetTreeReindex(const unsigned int i) const
140 {
141  THROW_ASSERT(i > 0 and i < last_node_id, "(C) Expected a positive index less than the total number of tree nodes (" +
142  STR(i) + ") (" + STR(last_node_id) + ")");
143  THROW_ASSERT(tree_nodes.find(i) != tree_nodes.end(), "Tree node " + STR(i) + " does not exist");
144  return tree_nodeRef(new tree_reindex(i, tree_nodes.at(i)));
145 }
146 
148 {
149  THROW_ASSERT(tree_nodes.find(index) != tree_nodes.end(), "Tree node with index " + STR(index) + " not found");
150  return tree_nodes.find(index)->second;
151 }
152 
154 {
155  THROW_ASSERT(i > 0 and i < last_node_id, "(C) Expected a positive index less than the total number of tree nodes (" +
156  STR(i) + ") (" + STR(last_node_id) + ")");
157  THROW_ASSERT(tree_nodes.find(i) != tree_nodes.end(), "Tree node " + STR(i) + " does not exist");
158  THROW_ASSERT(tree_nodes.find(i)->second, "Tree node " + STR(i) + " is empty");
159  return tree_nodes.find(i)->second;
160 }
161 
162 const tree_nodeConstRef tree_manager::CGetTreeNode(const unsigned int i) const
163 {
164  THROW_ASSERT(i > 0 and i < last_node_id, "(C) Expected a positive index less than the total number of tree nodes (" +
165  STR(i) + ") (" + STR(last_node_id) + ")");
166  THROW_ASSERT(tree_nodes.find(i) != tree_nodes.end(), "Tree node " + STR(i) + " does not exist");
167  THROW_ASSERT(tree_nodes.find(i)->second, "Tree node " + STR(i) + " is empty");
168  return tree_nodes.find(i)->second;
169 }
170 
171 bool tree_manager::is_tree_node(unsigned int i) const
172 {
173  return tree_nodes.find(i) != tree_nodes.end();
174 }
175 
176 // *****************************************************************************************
177 
179 {
180  return function_index("sc_main");
181 }
182 
183 unsigned int tree_manager::function_index(const std::string& function_name) const
184 {
185  const auto tn = GetFunction(function_name);
186  return tn ? tn->index : 0;
187 }
188 
189 tree_nodeRef tree_manager::GetFunction(const std::string& function_name) const
190 {
191  null_deleter null_del;
192  tree_managerConstRef TM(this, null_del);
193  for(const auto& function_decl_node : function_decl_nodes)
194  {
195  const auto& curr_tn = function_decl_node.second;
196  const auto fd = GetPointerS<const function_decl>(curr_tn);
197  const auto id_name = GET_CONST_NODE(fd->name);
198  std::string simple_name, mangled_name;
199  if(id_name->get_kind() == identifier_node_K)
200  {
201  const auto in = GetPointerS<const identifier_node>(id_name);
202  if(!in->operator_flag)
203  {
204  simple_name = in->strg;
205  }
206  }
207  if(fd->mngl)
208  {
209  tree_nodeRef mangled_id_name = GET_NODE(fd->mngl);
210  if(mangled_id_name->get_kind() == identifier_node_K)
211  {
212  auto* in = GetPointer<identifier_node>(mangled_id_name);
213  if(!in->operator_flag)
214  {
215  mangled_name = in->strg;
216  }
217  }
218  }
219  const auto name = [&]() {
220  const auto fname = tree_helper::print_function_name(TM, fd);
221  if(TM->is_CPP())
222  {
223  const auto demangled_name = cxa_demangle(fname);
224  if(!demangled_name.empty())
225  {
226  return demangled_name.substr(0, demangled_name.find('('));
227  }
228  }
229  return fname;
230  }();
231  if(name == function_name || function_name == std::string("-") ||
232  (!simple_name.empty() && function_name == simple_name) ||
233  (!mangled_name.empty() && mangled_name == function_name))
234  {
235  return CGetTreeReindex(function_decl_node.first);
236  }
237  }
238  return nullptr;
239 }
240 
241 unsigned int tree_manager::function_index_mngl(const std::string& function_name) const
242 {
243  null_deleter null_del;
244  tree_managerConstRef TM(this, null_del);
245  unsigned int function_id = 0;
246  for(const auto& function_decl_node : function_decl_nodes)
247  {
248  tree_nodeRef curr_tn = function_decl_node.second;
249  auto* fd = GetPointer<function_decl>(curr_tn);
250  tree_nodeRef id_name = GET_NODE(fd->name);
251  std::string simple_name, mangled_name;
252  if(id_name->get_kind() == identifier_node_K)
253  {
254  auto* in = GetPointer<identifier_node>(id_name);
255  if(!in->operator_flag)
256  {
257  simple_name = in->strg;
258  }
259  }
260  if(fd->mngl)
261  {
262  tree_nodeRef mangled_id_name = GET_NODE(fd->mngl);
263  if(mangled_id_name->get_kind() == identifier_node_K)
264  {
265  auto* in = GetPointer<identifier_node>(mangled_id_name);
266  if(!in->operator_flag)
267  {
268  mangled_name = in->strg;
269  }
270  }
271  }
272  std::string name = tree_helper::print_function_name(TM, fd);
273  if(name == function_name || function_name == std::string("-") ||
274  (!simple_name.empty() && function_name == simple_name) ||
275  (!mangled_name.empty() && mangled_name == function_name))
276  {
277  function_id = function_decl_node.first;
278  }
279  }
280  return function_id;
281 }
282 
283 void tree_manager::print(std::ostream& os) const
284 {
285  raw_writer RW(os);
286 
288 
289  unsigned int node_index = 0;
290  for(node_index = 0; node_index <= last_node_id; node_index++)
291  {
292  if(tree_nodes.find(node_index) != tree_nodes.end())
293  {
294  os << "@" << tree_nodes.find(node_index)->first << " ";
295  tree_nodes.find(node_index)->second->visit(&RW);
296  os << std::endl;
297  }
298  }
299 }
300 
301 void tree_manager::PrintGimple(std::ostream& os, const bool use_uid) const
302 {
303  GimpleWriter gimple_writer(os, use_uid);
304 
305  for(const auto& id_func : function_decl_nodes)
306  {
307  if(GetPointer<function_decl>(id_func.second)->body)
308  {
309  id_func.second->visit(&gimple_writer);
310  }
311  }
312 }
313 
314 void tree_manager::create_tree_node(const unsigned int node_id, enum kind tree_node_type,
315  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string>& tree_node_schema)
316 {
317  tree_node_factory TNF(tree_node_schema, *this);
318  TNF.create_tree_node(node_id, tree_node_type);
320  "---Created tree node " + STR(node_id) + ": " + STR(CGetTreeNode(node_id)));
321 }
322 
323 unsigned int tree_manager::new_tree_node_id(const unsigned int ask)
324 {
325  if(ask && !tree_nodes.count(ask))
326  {
327  GetTreeReindex(ask);
328  return ask;
329  }
330  unsigned int temp = last_node_id;
332  return temp;
333 }
334 
336 {
337  return last_node_id;
338 }
339 
341 {
342  function_decl_nodes[index] = curr;
343 }
344 
346 {
347  return function_decl_nodes.size();
348 }
349 
350 unsigned int tree_manager::find(enum kind tree_node_type,
351  const std::map<TreeVocabularyTokenTypes_TokenEnum, std::string>& tree_node_schema)
352 {
353  if(tree_node_type == identifier_node_K)
354  {
355  std::string id;
356  if(tree_node_schema.find(TOK(TOK_STRG)) != tree_node_schema.end())
357  {
358  id = tree_node_schema.find(TOK(TOK_STRG))->second;
359  }
360  else if(tree_node_schema.find(TOK(TOK_OPERATOR)) != tree_node_schema.end())
361  {
362  id = STOK(TOK_OPERATOR);
363  }
364  else
365  {
366  THROW_ERROR("Incorrect schema for identifier_node: no TOK_STRG nor TOK_OPERATOR");
367  }
368  return find_identifier_nodeID(id);
369  }
370  std::string key = tree_node::GetString(tree_node_type);
371  const auto tns_end = tree_node_schema.end();
372  for(auto tns = tree_node_schema.begin(); tns != tns_end; ++tns)
373  {
374  key += ";" + STOK2(tns->first) + "=" + tns->second;
375  }
376  // std::cout << "KEY: " + key + "[" << (find_cache.find(key) != find_cache.end() ? find_cache.find(key)->second : 0)
377  // << "]" << std::endl;
378  if(find_cache.find(key) != find_cache.end())
379  {
380  return find_cache.find(key)->second;
381  }
382  tree_node_finder TNF(tree_node_schema);
383  for(const auto& ti : tree_nodes)
384  {
385  unsigned int node_id = ti.first;
387  if(!ti.second)
388  {
389  continue;
390  }
391 
392  if(ti.second->get_kind() == tree_node_type and TNF.check(ti.second))
393  {
394  find_cache[key] = node_id;
395  return node_id;
396  }
397  }
398  return 0;
399 }
400 
401 void tree_manager::collapse_into(const unsigned int& funID,
403  const tree_nodeRef& tn, CustomUnorderedSet<unsigned int>& removed_nodes,
404  const application_managerRef AppM)
405 {
406  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
407  const unsigned int tree_node_index = GET_INDEX_NODE(tn);
409  "-->Collapsing into " + STR(tree_node_index) + " (" + std::string(GET_NODE(tn)->get_kind_text()) +
410  "): " + tn->ToString());
413  {
414  const std::string gimple_file_name = Param->getOption<std::string>(OPT_output_temporary_directory) +
415  "collapse_into_" + STR(collapse_into_counter) + "_before_" +
416  STR(GET_INDEX_NODE(tn)) + ".gimple";
418  std::ofstream gimple_file(gimple_file_name.c_str());
419  PrintGimple(gimple_file, false);
420  gimple_file.close();
421  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Writing file " + gimple_file_name);
422  }
423  tree_nodeRef curr_tn = GET_NODE(tn);
424  switch(curr_tn->get_kind())
425  {
426  case gimple_assign_K:
427  {
428  stack.push_front(tn);
429  auto* gm = GetPointer<gimple_assign>(curr_tn);
432  null_deleter null_del;
433  if(GET_NODE(gm->op1)->get_kind() != nop_expr_K ||
435  GetPointer<nop_expr>(GET_NODE(gm->op1))->type))
436  {
437  collapse_into(funID, stmt_to_bloc, gm->op1, removed_nodes, AppM);
438  }
439  stack.pop_front();
440  break;
441  }
442  case gimple_cond_K:
443  {
444  stack.push_front(tn);
445  auto* gc = GetPointer<gimple_cond>(curr_tn);
446  collapse_into(funID, stmt_to_bloc, gc->op0, removed_nodes, AppM);
447  stack.pop_front();
448  break;
449  }
450  /* Unary expressions. */
452  {
453  auto* ue = GetPointer<unary_expr>(curr_tn);
454  collapse_into(funID, stmt_to_bloc, ue->op, removed_nodes, AppM);
455  break;
456  }
458  {
459  auto* be = GetPointer<binary_expr>(curr_tn);
460  collapse_into(funID, stmt_to_bloc, be->op0, removed_nodes, AppM);
461  collapse_into(funID, stmt_to_bloc, be->op1, removed_nodes, AppM);
462  break;
463  }
464  /*ternary expressions*/
465  case gimple_switch_K:
466  {
467  auto* se = GetPointer<gimple_switch>(curr_tn);
468  collapse_into(funID, stmt_to_bloc, se->op0, removed_nodes, AppM);
469  break;
470  }
472  {
473  auto* te = GetPointer<ternary_expr>(curr_tn);
474  collapse_into(funID, stmt_to_bloc, te->op0, removed_nodes, AppM);
475  collapse_into(funID, stmt_to_bloc, te->op1, removed_nodes, AppM);
476  if(te->op2)
477  {
478  collapse_into(funID, stmt_to_bloc, te->op2, removed_nodes, AppM);
479  }
480  break;
481  }
483  {
484  auto* qe = GetPointer<quaternary_expr>(curr_tn);
485  collapse_into(funID, stmt_to_bloc, qe->op0, removed_nodes, AppM);
486  collapse_into(funID, stmt_to_bloc, qe->op1, removed_nodes, AppM);
487  if(qe->op2)
488  {
489  collapse_into(funID, stmt_to_bloc, qe->op2, removed_nodes, AppM);
490  }
491  if(qe->op3)
492  {
493  collapse_into(funID, stmt_to_bloc, qe->op3, removed_nodes, AppM);
494  }
495  break;
496  }
497  case lut_expr_K:
498  {
499  auto* le = GetPointer<lut_expr>(curr_tn);
500  collapse_into(funID, stmt_to_bloc, le->op0, removed_nodes, AppM);
501  collapse_into(funID, stmt_to_bloc, le->op1, removed_nodes, AppM);
502  if(le->op2)
503  {
504  collapse_into(funID, stmt_to_bloc, le->op2, removed_nodes, AppM);
505  }
506  if(le->op3)
507  {
508  collapse_into(funID, stmt_to_bloc, le->op3, removed_nodes, AppM);
509  }
510  if(le->op4)
511  {
512  collapse_into(funID, stmt_to_bloc, le->op4, removed_nodes, AppM);
513  }
514  if(le->op5)
515  {
516  collapse_into(funID, stmt_to_bloc, le->op5, removed_nodes, AppM);
517  }
518  if(le->op6)
519  {
520  collapse_into(funID, stmt_to_bloc, le->op6, removed_nodes, AppM);
521  }
522  if(le->op7)
523  {
524  collapse_into(funID, stmt_to_bloc, le->op7, removed_nodes, AppM);
525  }
526  if(le->op8)
527  {
528  collapse_into(funID, stmt_to_bloc, le->op8, removed_nodes, AppM);
529  }
530  break;
531  }
532  case var_decl_K:
533  case result_decl_K:
534  case parm_decl_K:
535  case integer_cst_K:
536  case real_cst_K:
537  case string_cst_K:
538  case vector_cst_K:
539  case void_cst_K:
540  case complex_cst_K:
541  case field_decl_K:
542  case label_decl_K:
543  case gimple_label_K:
544  case gimple_asm_K:
545  case gimple_phi_K:
546  case target_mem_ref_K:
547  case target_mem_ref461_K:
548  case gimple_nop_K:
549  case gimple_multi_way_if_K:
550  case function_decl_K:
551  {
552  break;
553  }
554  case ssa_name_K:
555  {
556  auto* sn = GetPointer<ssa_name>(curr_tn);
557 
558  if(sn->CGetDefStmts().size() == 1)
559  {
560  auto* gm = GetPointer<gimple_assign>(GET_NODE(sn->CGetDefStmt()));
561  // Don't continue if declaration of ssa variable is not a gimple_assign
562  if((!gm and GET_NODE(sn->CGetDefStmt())->get_kind() == gimple_asm_K) ||
563  (!gm and GET_NODE(sn->CGetDefStmt())->get_kind() == nop_expr_K) ||
564  (!gm and GET_NODE(sn->CGetDefStmt())->get_kind() == gimple_nop_K))
565  {
566  break;
567  }
568  if(!gm)
569  {
570  THROW_ERROR("unexpected statement " + sn->CGetDefStmt()->ToString());
571  }
572  if(gm->memdef)
573  {
575  "---The gimple assignment where ssa name is defined has virtual def");
576  break;
577  }
580  null_deleter null_del;
581  if(GET_NODE(gm->op1)->get_kind() == nop_expr_K &&
583  GetPointer<nop_expr>(GET_NODE(gm->op1))->type))
584  {
586  "---The gimple assignment where ssa name is defined has a non-builtin nop_expr");
587  break;
588  }
589 
590  if(gm->predicate)
591  {
592  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---The gimple assignment is predicated");
593  break;
594  }
595  collapse_into(funID, stmt_to_bloc, sn->CGetDefStmt(), removed_nodes, AppM);
596  THROW_ASSERT(gm, "ssa name " + STR(GET_INDEX_NODE(tn)) +
597  " not defined in a gimple modify stmt, nor in gimple_asm, nor in a nop_expr");
598 
599  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Definition of " + STR(GET_INDEX_NODE(tn)) + ":");
601  "---" + STR(GET_INDEX_NODE(sn->CGetDefStmt())) + " (" +
602  std::string(GET_NODE(sn->CGetDefStmt())->get_kind_text()) + ")");
604  "---Uses of " + STR(GET_INDEX_NODE(tn)) + " - " + STR(sn->CGetNumberUses()) + ":");
605 #ifndef NDEBUG
606  for(const auto& use : sn->CGetUseStmts())
607  {
608  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---" + use.first->ToString());
609  }
610 #endif
611  // Retrieve curr_block, the block which contains the conditional expression that originated the collapsing
612  tree_nodeRef temp = get_tree_node_const(funID);
613  auto* fd = GetPointer<function_decl>(temp);
614  auto* sl = GetPointer<statement_list>(GET_NODE(fd->body));
615  const std::map<unsigned int, blocRef>& list_of_bloc = sl->list_of_bloc;
616 #if 1
617  THROW_ASSERT(!stack.empty(), "stack is empty");
618  THROW_ASSERT(stmt_to_bloc.find((*(stack.rbegin()))->index) != stmt_to_bloc.end(),
619  "BB of statement " + STR((*(stack.begin()))->index) + " not found");
620  THROW_ASSERT(list_of_bloc.find(stmt_to_bloc.find((*(stack.begin()))->index)->second) != list_of_bloc.end(),
621  "BB of statement not found");
622  blocRef curr_block = list_of_bloc.find(stmt_to_bloc.find((*(stack.begin()))->index)->second)->second;
623 #else
624  unsigned int curr_block_index;
625  blocRef curr_block;
626  // Find the conditional expression in the stack
627  std::deque<tree_nodeRef>::iterator stack_it;
628  for(stack_it = stack.begin(); stack_it != stack.end(); stack_it++)
629  {
630  if(GET_NODE(*stack_it)->get_kind() == gimple_cond_K)
631  {
632  curr_block_index = (stmt_to_bloc.find(GET_INDEX_NODE(*stack_it)))->second;
633  curr_block = list_of_bloc.find(curr_block_index)->second;
635  "---Found gimple_cond in block: " +
636  STR((stmt_to_bloc.find(GET_INDEX_NODE(*stack_it)))->second));
637  break;
638  }
639  }
640  THROW_ASSERT(curr_block, "Conditional expression not found in stack");
641 #endif
642 
643  // Retrieve def_block, the block which contains the definition of ssa_name (could be different from
644  // curr_block
645  THROW_ASSERT(stmt_to_bloc.find(GET_INDEX_NODE(sn->CGetDefStmt())) != stmt_to_bloc.end(),
646  "Statement not found in stmt_to_bloc map: " + STR(GET_INDEX_NODE(sn->CGetDefStmt())));
647  const blocRef def_block =
648  list_of_bloc.find((stmt_to_bloc.find(GET_INDEX_NODE(sn->CGetDefStmt())))->second)->second;
649  THROW_ASSERT(def_block, "Definition block not found");
650 
651  // If the defined ssa variable is not only used in the conditional statement, copy the definition in the
652  // blocks where it is used
653  if(sn->CGetNumberUses() != 1)
654  {
658  if(GET_NODE(gm->op1)->get_kind() != ssa_name_K and GET_NODE(gm->op1)->get_kind() != var_decl_K)
659  {
660  break;
661  }
662 
663  // This check is needed to avoid situations in which variables are modified internally to the conditional
664  // statement An example is the ++ (or --) operator. In such case the collapsing procedure has to be
665  // stopped (break). The control is carried out in the following way: if almost one instruction which is
666  // between the conditional expression and the current gimple_modify_statement (ssa_name definition) has
667  // virtual operands, then the collapsing procedure stops.
668  bool in_between = false;
669  bool memdef_found = false;
670  for(const auto& stmt : curr_block->CGetStmtList())
671  {
672  if(in_between and GET_NODE(stmt)->get_kind() == gimple_assign_K)
673  {
674  auto* gms = GetPointer<gimple_assign>(GET_NODE(stmt));
675  if(gms->memdef)
676  {
678  "---Statement " + STR(GET_INDEX_NODE(stmt)) + " contains vdef");
679  memdef_found = true;
680  }
681  }
682  if(GET_INDEX_NODE(stmt) == GET_INDEX_NODE(sn->CGetDefStmt()))
683  {
684  in_between = true;
685  }
686  }
687  if(memdef_found)
688  {
689  break;
690  }
691 
693  "---None of uses of current ssa contains virtual defs so continuing in collapsing");
694 
695  // If the definition of ssa_name is elsewhere, there is no need of copying it
696  if(curr_block == def_block)
697  {
698  // Group the uses of ssa variables on the basis of the basic block they belong to
700  for(auto const& use : sn->CGetUseStmts())
701  {
702  THROW_ASSERT(stmt_to_bloc.find(use.first->index) != stmt_to_bloc.end(),
703  STR(use.first->index) + " is not in stmt_to_bloc");
704  unsigned int copy_block_index = (stmt_to_bloc.find(use.first->index))->second;
705  copy_bloc_to_stmt[copy_block_index].push_back(use.first);
707  "ssa_name is used in operation " + STR(use.first->index) + " of BB" +
708  STR(copy_block_index));
709  }
710 
711  // Copy the definition statement into each block the ssa variable is used in
712  for(auto& copy_block_it : copy_bloc_to_stmt)
713  {
714  const blocRef copy_block = list_of_bloc.find(copy_block_it.first)->second;
715  std::vector<tree_nodeRef> copy_block_use_stmts = copy_block_it.second;
716 
717  if(copy_block != curr_block)
718  {
720  "Copying statement " + STR(GET_INDEX_NODE(sn->CGetDefStmt())) + " in block " +
721  STR(copy_block_it.first) + " (!= " +
722  STR((stmt_to_bloc.find(GET_INDEX_NODE(sn->CGetDefStmt())))->second) + ")");
723 
724  // Create a new ssa_node, identical to the one being analyzed, but with different version number
725  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
726  unsigned int version = get_next_vers();
727  if(sn->var)
728  {
729  IR_schema[TOK(TOK_VAR)] = STR(GET_INDEX_NODE(sn->var));
730  }
731  else
732  {
733  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_NODE(sn->type));
734  }
735  IR_schema[TOK(TOK_VERS)] = STR(version);
736  IR_schema[TOK(TOK_VOLATILE)] = STR(sn->volatile_flag);
737  unsigned int sn_index = new_tree_node_id();
738  create_tree_node(sn_index, ssa_name_K, IR_schema);
739  tree_nodeRef tree_reindexRef_sn = GetTreeReindex(sn_index);
740  auto* new_sn = GetPointer<ssa_name>(GET_NODE(tree_reindexRef_sn));
741  for(const auto& use_stmt : sn->CGetUseStmts())
742  {
743  for(decltype(use_stmt.second) repetition = 0; repetition < use_stmt.second; repetition++)
744  {
745  new_sn->AddUseStmt(use_stmt.first);
746  }
747  }
748 
749  // Replace the occurrences of the considered ssa variable with the newly created ssa variable
750  for(auto& copy_block_use_stmt : copy_block_use_stmts)
751  {
752  RecursiveReplaceTreeNode(copy_block_use_stmt, tn, tree_reindexRef_sn, copy_block_use_stmt,
753  false);
754  new_sn->AddUseStmt(copy_block_use_stmt);
755  }
756 
757  // Create a new node, the copy of the definition of ssa_name
758  IR_schema.clear();
759  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
760  IR_schema[TOK(TOK_SCPE)] = STR(GET_INDEX_CONST_NODE(gm->scpe));
761  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_NODE(tree_reindexRef_sn));
762  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_NODE(gm->op1));
763  unsigned int gm_index = new_tree_node_id();
764  create_tree_node(gm_index, gimple_assign_K, IR_schema);
765  tree_nodeRef tree_reindexRef_gm = GetTreeReindex(gm_index);
766 
768  if(GetPointer<const ssa_name>(GET_NODE(gm->op1)))
769  {
770  auto* sn_right = GetPointer<ssa_name>(GET_NODE(gm->op1));
771  sn_right->AddUseStmt(tree_reindexRef_gm);
772  }
773 
774  auto* new_gm = GetPointer<gimple_assign>(GET_NODE(tree_reindexRef_gm));
775  new_gm->memuse = gm->memuse;
776  new_gm->memdef = gm->memdef;
777  new_gm->vuses = gm->vuses;
778  new_gm->vdef = gm->vdef;
779  new_gm->vovers = gm->vovers;
780  // Need to control whether there are labels at the beginning of the block
781  // In such case, copy the statement after the labels
782  for(const auto& copy_block_stmt : copy_block->CGetStmtList())
783  {
784  if(GET_NODE(copy_block_stmt)->get_kind() != gimple_label_K)
785  {
786  copy_block->PushBefore(tree_reindexRef_gm, copy_block_stmt, AppM);
787  break;
788  }
789  }
790  // Update stmt_to_bloc map
791  stmt_to_bloc[GET_INDEX_NODE(tree_reindexRef_gm)] = copy_block_it.first;
792  }
793  else
794  {
795  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "copy_block = curr_block");
796  }
797  }
798  }
799  }
800 
801  if(gm->memuse)
802  {
803  // Target of collapsing is a conditional expression; we can't put into it expression with side effects
804  if(gm->memdef)
805  {
806  break;
807  }
808  tree_nodeRef top = stack.front();
809  if(GET_NODE(top)->get_kind() == gimple_cond_K)
810  {
811  auto* gc = GetPointer<gimple_cond>(GET_NODE(top));
812  gc->memuse = gm->memuse;
813  gc->vuses = gm->vuses;
814  gc->vovers = gm->vovers;
815  }
816  else if(GET_NODE(top)->get_kind() == gimple_assign_K)
817  {
818  auto* top_gm = GetPointer<gimple_assign>(GET_NODE(top));
819  top_gm->memuse = gm->memuse;
820  top_gm->vuses = gm->vuses;
821  top_gm->vovers = gm->vovers;
822  }
823  else
824  {
825  THROW_ERROR("Unsupported type of tree node during collapsing");
826  }
827  }
829  "Substituting operand " + STR(GET_INDEX_NODE(tn)) + " with " + STR(GET_INDEX_NODE(gm->op1)));
830  const tree_nodeRef tn_old = tn;
831  // Change the operand into every statement in the curr_block which uses the considered ssa_name
832  if(def_block == curr_block)
833  {
834  for(const auto& use : sn->CGetUseStmts())
835  {
836  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Checking for operation " + STR(use.first->index));
837  THROW_ASSERT(stmt_to_bloc.find(use.first->index) != stmt_to_bloc.end(),
838  "Statement not found in stmt_to_bloc map: " + STR(use.first->index));
839  unsigned int use_block_index = (stmt_to_bloc.find(use.first->index))->second;
840  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Operation belongs to BB" + STR(use_block_index));
841  const blocRef use_block = list_of_bloc.find(use_block_index)->second;
842  if(use_block == curr_block)
843  {
844  auto statement = use.first;
845  RecursiveReplaceTreeNode(statement, tn_old, gm->op1, use.first, false);
846  // Erase usage information about the definition being erased of the current ssa variable in every
847  // ssa variable used in it
848  erase_usage_info(sn->CGetDefStmt(), sn->CGetDefStmt());
849  // Insert usage information about the target statement of the substitution in every ssa variable
850  // used in the definition being erased
851  insert_usage_info(sn->CGetDefStmt(), use.first);
852  }
853  }
854  }
855  for(const auto& stmt : curr_block->CGetStmtList())
856  {
857  // Remove the definition statements contained in curr_block
858  if(GET_INDEX_NODE(stmt) == GET_INDEX_NODE(sn->CGetDefStmt()))
859  {
860  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Removed statement " + STR(stmt->index));
861  removed_nodes.insert(GET_INDEX_NODE(stmt));
862  curr_block->RemoveStmt(stmt, AppM);
863  break;
864  }
865  }
866  }
867  else
868  {
870  "Multiple definitions for ssa_name " + STR(GET_INDEX_NODE(tn)));
871  }
872  break;
873  }
874 
875  case call_expr_K:
876  case aggr_init_expr_K:
877  {
878  auto* ce = GetPointer<call_expr>(curr_tn);
879  const std::vector<tree_nodeRef>& args = ce->args;
880  std::vector<tree_nodeRef>::const_iterator arg, arg_end = args.end();
881  for(arg = args.begin(); arg != arg_end; ++arg)
882  {
883  collapse_into(funID, stmt_to_bloc, *arg, removed_nodes, AppM);
884  }
885  break;
886  }
887  case gimple_call_K:
888  {
889  stack.push_front(tn);
890  auto* ce = GetPointer<gimple_call>(curr_tn);
891  const std::vector<tree_nodeRef>& args = ce->args;
892  std::vector<tree_nodeRef>::const_iterator arg, arg_end = args.end();
893  for(arg = args.begin(); arg != arg_end; ++arg)
894  {
895  collapse_into(funID, stmt_to_bloc, *arg, removed_nodes, AppM);
896  }
897  stack.pop_front();
898  break;
899  }
900  case binfo_K:
901  case block_K:
902  case case_label_expr_K:
903  case const_decl_K:
904  case constructor_K:
905  case gimple_bind_K:
906  case gimple_for_K:
907  case gimple_goto_K:
908  case gimple_pragma_K:
909  case gimple_predict_K:
910  case gimple_resx_K:
911  case gimple_return_K:
912  case gimple_while_K:
913  case identifier_node_K:
914  case namespace_decl_K:
915  case statement_list_K:
916  case target_expr_K:
917  case translation_unit_decl_K:
918  case template_decl_K:
919  case using_decl_K:
920  case tree_list_K:
921  case tree_vec_K:
922  case type_decl_K:
923  case error_mark_K:
924  case CASE_CPP_NODES:
925  case CASE_FAKE_NODES:
926  case CASE_PRAGMA_NODES:
927  case CASE_TYPE_NODES:
928  default:
929  THROW_ERROR(std::string("Node not supported (") + STR(GET_INDEX_NODE(tn)) + std::string("): ") +
930  curr_tn->get_kind_text());
931  }
933  {
934  const std::string raw_file_name = Param->getOption<std::string>(OPT_output_temporary_directory) +
935  "collapse_into_" + STR(collapse_into_counter) + "_after_" +
936  STR(tree_node_index) + ".raw";
937  std::ofstream raw_file(raw_file_name.c_str());
938  raw_file << *this;
939  raw_file.close();
940  const std::string gimple_file_name = Param->getOption<std::string>(OPT_output_temporary_directory) +
941  "collapse_into_" + STR(collapse_into_counter) + "_after_" +
942  STR(tree_node_index) + ".gimple";
944  std::ofstream gimple_file(gimple_file_name.c_str());
945  PrintGimple(gimple_file, false);
946  gimple_file.close();
947  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Writing file " + gimple_file_name);
948  }
950  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Ended collapsing into " + STR(tree_node_index));
951 }
952 
953 void tree_manager::ReplaceTreeNode(const tree_nodeRef& stmt, const tree_nodeRef& old_node, const tree_nodeRef& new_node)
954 {
955  THROW_ASSERT(GetPointer<const gimple_node>(GET_NODE(stmt)), "Replacing ssa name starting from " + stmt->ToString());
956  THROW_ASSERT(!GetPointer<const gimple_node>(GET_NODE(new_node)), "new node cannot be a gimple_node");
957  THROW_ASSERT(!GetPointer<const gimple_node>(GET_NODE(old_node)),
958  "old node cannot be a gimple_node: " + STR(old_node));
961  tree_nodeRef temp = stmt;
962  RecursiveReplaceTreeNode(temp, old_node, new_node, stmt, false);
963 }
964 
966  const tree_nodeRef& stmt, const bool definition) // NOLINT
967 {
968  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
969  tree_nodeRef curr_tn = GET_NODE(tn);
971  "-->Replacing " + old_node->ToString() + " (" + GET_NODE(old_node)->get_kind_text() + ") with " +
972  new_node->ToString() + "(" + GET_NODE(new_node)->get_kind_text() +
973  ") starting from node: " + tn->ToString() + "(" + GET_NODE(tn)->get_kind_text() + ")");
974  if(GET_INDEX_NODE(tn) == GET_INDEX_NODE(old_node))
975  {
977  const auto gn = GetPointer<const gimple_node>(GET_NODE(stmt));
978  if(gn)
979  {
980  const auto ga = GetPointer<const gimple_assign>(GET_NODE(stmt));
981  const auto gp = GetPointer<const gimple_phi>(GET_NODE(stmt));
982  // Not in a assign and not in a phi or in right part of a phi or in right part of assign
983  if(!definition)
984  {
985  THROW_ASSERT(gn->bb_index, stmt->ToString() + " is not in a basic block");
986  const auto used_ssas = tree_helper::ComputeSsaUses(old_node);
987  for(const auto& used_ssa : used_ssas)
988  {
989  for(decltype(used_ssa.second) counter = 0; counter < used_ssa.second; counter++)
990  {
991  GetPointerS<ssa_name>(GET_NODE(used_ssa.first))->RemoveUse(stmt);
992  }
993  }
994 #ifndef NDEBUG
995  tn = new_node;
996 #endif
997  const auto new_used_ssas = tree_helper::ComputeSsaUses(new_node);
998  for(const auto& new_used_ssa : new_used_ssas)
999  {
1000  for(decltype(new_used_ssa.second) counter = 0; counter < new_used_ssa.second; counter++)
1001  {
1002  GetPointerS<ssa_name>(GET_NODE(new_used_ssa.first))->AddUseStmt(stmt);
1003  }
1004  }
1005  }
1006  else
1007  {
1008  if(gn->vdef && gn->vdef->index == old_node->index)
1009  {
1010  const auto vssa = GetPointerS<ssa_name>(GET_NODE(new_node));
1011  vssa->SetDefStmt(stmt);
1012  }
1013  if(gn->memdef && gn->memdef->index == old_node->index)
1014  {
1015  const auto vssa = GetPointerS<ssa_name>(GET_NODE(new_node));
1016  vssa->SetDefStmt(stmt);
1017  }
1018  if(ga && ga->op0->index == old_node->index && GET_NODE(old_node)->get_kind() == ssa_name_K)
1019  {
1020  GetPointerS<ssa_name>(GET_NODE(new_node))->SetDefStmt(stmt);
1021  }
1022  if(gp && gp->res->index == old_node->index && !GetPointer<cst_node>(GET_CONST_NODE(new_node)))
1023  {
1024  THROW_ASSERT(GET_CONST_NODE(new_node)->get_kind() == ssa_name_K,
1025  GET_CONST_NODE(new_node)->get_kind_text());
1027  "---Setting " + STR(stmt) + " as new define statement of " + STR(new_node));
1028  GetPointerS<ssa_name>(GET_NODE(new_node))->SetDefStmt(stmt);
1029  }
1030  }
1031  }
1032  tn = new_node;
1034  "<--Replaced " + old_node->ToString() + " (" + GET_NODE(old_node)->get_kind_text() + ") with " +
1035  new_node->ToString() + "(" + GET_NODE(new_node)->get_kind_text() +
1036  ") New statement: " + tn->ToString());
1037  return;
1038  }
1039  const auto gn = GetPointer<gimple_node>(curr_tn);
1040  if(gn)
1041  {
1043  if(gn->memdef)
1044  {
1045  RecursiveReplaceTreeNode(gn->memdef, old_node, new_node, stmt, true);
1046  }
1047  if(gn->memuse)
1048  {
1049  RecursiveReplaceTreeNode(gn->memuse, old_node, new_node, stmt, false);
1050  }
1051  const auto vuse_it = gn->vuses.find(old_node);
1052  if(vuse_it != gn->vuses.end())
1053  {
1054  gn->vuses.erase(vuse_it);
1055  const auto old_vssa = GetPointerS<ssa_name>(GET_NODE(old_node));
1056  old_vssa->RemoveUse(stmt);
1057  if(gn->AddVuse(new_node))
1058  {
1059  const auto new_vssa = GetPointerS<ssa_name>(GET_NODE(new_node));
1060  new_vssa->AddUseStmt(stmt);
1061  }
1062  }
1063  const auto vover_it = gn->vovers.find(old_node);
1064  if(vover_it != gn->vovers.end())
1065  {
1066  gn->vovers.erase(vover_it);
1067  const auto old_vssa = GetPointerS<ssa_name>(GET_NODE(old_node));
1068  old_vssa->RemoveUse(stmt);
1069  if(gn->AddVover(new_node))
1070  {
1071  const auto new_vssa = GetPointerS<ssa_name>(GET_NODE(new_node));
1072  new_vssa->AddUseStmt(stmt);
1073  }
1074  }
1075  if(gn->vdef)
1076  {
1077  RecursiveReplaceTreeNode(gn->vdef, old_node, new_node, stmt, true);
1078  }
1080  }
1081  switch(curr_tn->get_kind())
1082  {
1083  case gimple_assign_K:
1084  {
1085  const auto gm = GetPointerS<gimple_assign>(curr_tn);
1086  RecursiveReplaceTreeNode(gm->op0, old_node, new_node, stmt, GET_NODE(new_node)->get_kind() == ssa_name_K);
1087  RecursiveReplaceTreeNode(gm->op1, old_node, new_node, stmt, false);
1088  for(auto& use : gm->use_set->variables)
1089  {
1090  RecursiveReplaceTreeNode(use, old_node, new_node, stmt, false);
1091  }
1092  for(auto& clb : gm->clobbered_set->variables)
1093  {
1094  RecursiveReplaceTreeNode(clb, old_node, new_node, stmt, false);
1095  }
1096  if(gm->predicate)
1097  {
1098  RecursiveReplaceTreeNode(gm->predicate, old_node, new_node, stmt, false);
1099  }
1100  break;
1101  }
1102  case gimple_asm_K:
1103  {
1104  auto* gasm = GetPointerS<gimple_asm>(curr_tn);
1105  if(gasm->in)
1106  {
1107  RecursiveReplaceTreeNode(gasm->in, old_node, new_node, stmt, false);
1108  }
1109  if(gasm->out)
1110  {
1111  RecursiveReplaceTreeNode(gasm->out, old_node, new_node, stmt, true);
1112  }
1113  if(gasm->clob)
1114  {
1115  RecursiveReplaceTreeNode(gasm->clob, old_node, new_node, stmt, false);
1116  }
1117  break;
1118  }
1119  case gimple_cond_K:
1120  {
1121  auto* gc = GetPointerS<gimple_cond>(curr_tn);
1122  RecursiveReplaceTreeNode(gc->op0, old_node, new_node, stmt, false);
1123  break;
1124  }
1125  case CASE_UNARY_EXPRESSION:
1126  {
1127  auto* ue = GetPointerS<unary_expr>(curr_tn);
1128  RecursiveReplaceTreeNode(ue->op, old_node, new_node, stmt, false);
1129  break;
1130  }
1132  {
1133  auto* be = GetPointerS<binary_expr>(curr_tn);
1134  RecursiveReplaceTreeNode(be->op0, old_node, new_node, stmt, false);
1135  RecursiveReplaceTreeNode(be->op1, old_node, new_node, stmt, false);
1136  break;
1137  }
1138  case gimple_switch_K:
1139  {
1140  auto* se = GetPointerS<gimple_switch>(curr_tn);
1141  RecursiveReplaceTreeNode(se->op0, old_node, new_node, stmt, false);
1142  break;
1143  }
1144  case gimple_multi_way_if_K:
1145  {
1146  auto* gmwi = GetPointerS<gimple_multi_way_if>(curr_tn);
1147  for(auto& cond : gmwi->list_of_cond)
1148  {
1149  if(cond.first)
1150  {
1151  RecursiveReplaceTreeNode(cond.first, old_node, new_node, stmt, false);
1152  }
1153  }
1154  break;
1155  }
1157  {
1158  auto* te = GetPointerS<ternary_expr>(curr_tn);
1159  RecursiveReplaceTreeNode(te->op0, old_node, new_node, stmt, false);
1160  RecursiveReplaceTreeNode(te->op1, old_node, new_node, stmt, false);
1161  if(te->op2)
1162  {
1163  RecursiveReplaceTreeNode(te->op2, old_node, new_node, stmt, false);
1164  }
1165  break;
1166  }
1168  {
1169  auto* qe = GetPointerS<quaternary_expr>(curr_tn);
1170  RecursiveReplaceTreeNode(qe->op0, old_node, new_node, stmt, false);
1171  RecursiveReplaceTreeNode(qe->op1, old_node, new_node, stmt, false);
1172  if(qe->op2)
1173  {
1174  RecursiveReplaceTreeNode(qe->op2, old_node, new_node, stmt, false);
1175  }
1176  if(qe->op3)
1177  {
1178  RecursiveReplaceTreeNode(qe->op3, old_node, new_node, stmt, false);
1179  }
1180  break;
1181  }
1182  case lut_expr_K:
1183  {
1184  auto* le = GetPointerS<lut_expr>(curr_tn);
1185  RecursiveReplaceTreeNode(le->op0, old_node, new_node, stmt, false);
1186  RecursiveReplaceTreeNode(le->op1, old_node, new_node, stmt, false);
1187  if(le->op2)
1188  {
1189  RecursiveReplaceTreeNode(le->op2, old_node, new_node, stmt, false);
1190  }
1191  if(le->op3)
1192  {
1193  RecursiveReplaceTreeNode(le->op3, old_node, new_node, stmt, false);
1194  }
1195  if(le->op4)
1196  {
1197  RecursiveReplaceTreeNode(le->op4, old_node, new_node, stmt, false);
1198  }
1199  if(le->op5)
1200  {
1201  RecursiveReplaceTreeNode(le->op5, old_node, new_node, stmt, false);
1202  }
1203  if(le->op6)
1204  {
1205  RecursiveReplaceTreeNode(le->op6, old_node, new_node, stmt, false);
1206  }
1207  if(le->op7)
1208  {
1209  RecursiveReplaceTreeNode(le->op7, old_node, new_node, stmt, false);
1210  }
1211  if(le->op8)
1212  {
1213  RecursiveReplaceTreeNode(le->op8, old_node, new_node, stmt, false);
1214  }
1215  break;
1216  }
1217  case gimple_phi_K:
1218  {
1219  auto* gp = GetPointerS<gimple_phi>(curr_tn);
1220  for(auto& def_edge : gp->list_of_def_edge)
1221  {
1222  RecursiveReplaceTreeNode(def_edge.first, old_node, new_node, stmt, false);
1223  }
1224  RecursiveReplaceTreeNode(gp->res, old_node, new_node, stmt, true);
1225  break;
1226  }
1227  case target_mem_ref_K:
1228  {
1229  auto tmr = GetPointerS<target_mem_ref>(curr_tn);
1230  if(tmr->symbol)
1231  {
1232  RecursiveReplaceTreeNode(tmr->symbol, old_node, new_node, stmt, false);
1233  }
1234  if(tmr->base)
1235  {
1236  RecursiveReplaceTreeNode(tmr->base, old_node, new_node, stmt, false);
1237  }
1238  if(tmr->idx)
1239  {
1240  RecursiveReplaceTreeNode(tmr->idx, old_node, new_node, stmt, false);
1241  }
1242  break;
1243  }
1244  case target_mem_ref461_K:
1245  {
1246  auto tmr = GetPointerS<target_mem_ref461>(curr_tn);
1247  if(tmr->base)
1248  {
1249  RecursiveReplaceTreeNode(tmr->base, old_node, new_node, stmt, false);
1250  }
1251  if(tmr->idx)
1252  {
1253  RecursiveReplaceTreeNode(tmr->idx, old_node, new_node, stmt, false);
1254  }
1255  if(tmr->idx2)
1256  {
1257  RecursiveReplaceTreeNode(tmr->idx2, old_node, new_node, stmt, false);
1258  }
1259  break;
1260  }
1261  case var_decl_K:
1262  case result_decl_K:
1263  case parm_decl_K:
1264  case integer_cst_K:
1265  case real_cst_K:
1266  case string_cst_K:
1267  case vector_cst_K:
1268  case void_cst_K:
1269  case complex_cst_K:
1270  case field_decl_K:
1271  case label_decl_K:
1272  case gimple_label_K:
1273  case gimple_nop_K:
1274  case function_decl_K:
1275  {
1276  break;
1277  }
1278  case ssa_name_K:
1279  {
1280  break;
1281  }
1282  case call_expr_K:
1283  case aggr_init_expr_K:
1284  {
1285  auto* ce = GetPointerS<call_expr>(curr_tn);
1286  for(auto& arg : ce->args)
1287  {
1288  RecursiveReplaceTreeNode(arg, old_node, new_node, stmt, false);
1289  }
1290  break;
1291  }
1292  case gimple_call_K:
1293  {
1294  auto* gc = GetPointerS<gimple_call>(curr_tn);
1295  for(auto& arg : gc->args)
1296  {
1297  RecursiveReplaceTreeNode(arg, old_node, new_node, stmt, false);
1298  }
1299  for(auto& use : gc->use_set->variables)
1300  {
1301  RecursiveReplaceTreeNode(use, old_node, new_node, stmt, false);
1302  }
1303  for(auto& clb : gc->clobbered_set->variables)
1304  {
1305  RecursiveReplaceTreeNode(clb, old_node, new_node, stmt, false);
1306  }
1307  break;
1308  }
1309  case gimple_return_K:
1310  {
1311  auto* gr = GetPointerS<gimple_return>(curr_tn);
1312  if(gr->op)
1313  {
1314  RecursiveReplaceTreeNode(gr->op, old_node, new_node, stmt, false);
1315  }
1316  break;
1317  }
1318  case constructor_K:
1319  {
1320  auto* constr = GetPointerS<constructor>(curr_tn);
1321  for(auto& idx_value : constr->list_of_idx_valu)
1322  {
1323  RecursiveReplaceTreeNode(idx_value.second, old_node, new_node, stmt, false);
1324  }
1325  break;
1326  }
1327  case tree_list_K:
1328  {
1329  auto* tl = GetPointerS<tree_list>(curr_tn);
1330  while(tl)
1331  {
1332  if(tl->valu)
1333  {
1334  RecursiveReplaceTreeNode(tl->valu, old_node, new_node, stmt, false);
1335  }
1336  tl = tl->chan ? GetPointerS<tree_list>(GET_NODE(tl->chan)) : nullptr;
1337  }
1338  break;
1339  }
1340  case binfo_K:
1341  case block_K:
1342  case case_label_expr_K:
1343  case const_decl_K:
1344  case gimple_bind_K:
1345  case gimple_for_K:
1346  case gimple_goto_K:
1347  case gimple_pragma_K:
1348  case gimple_predict_K:
1349  case gimple_resx_K:
1350  case gimple_while_K:
1351  case identifier_node_K:
1352  case namespace_decl_K:
1353  case statement_list_K:
1354  case target_expr_K:
1355  case translation_unit_decl_K:
1356  case template_decl_K:
1357  case using_decl_K:
1358  case tree_vec_K:
1359  case type_decl_K:
1360  case error_mark_K:
1361  case CASE_CPP_NODES:
1362  case CASE_FAKE_NODES:
1363  case CASE_PRAGMA_NODES:
1364  case CASE_TYPE_NODES:
1365  default:
1366  THROW_ERROR(std::string("Node not supported (") + STR(GET_INDEX_NODE(tn)) + std::string("): ") +
1367  curr_tn->get_kind_text());
1368  }
1370  "<--Replaced " + old_node->ToString() + " (" + GET_NODE(old_node)->get_kind_text() + ") with " +
1371  new_node->ToString() + "(" + GET_NODE(new_node)->get_kind_text() +
1372  ") New statement: " + tn->ToString());
1373 }
1374 
1376 {
1378  "-->Erase usage into node " + STR(GET_INDEX_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() +
1379  "). Statement: " + STR(GET_INDEX_NODE(stmt)) + " (" + GET_NODE(stmt)->get_kind_text() + ")");
1380  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1381  tree_nodeRef curr_tn = GET_NODE(tn);
1382  switch(curr_tn->get_kind())
1383  {
1384  case gimple_assign_K:
1385  {
1386  auto* gm = GetPointer<gimple_assign>(curr_tn);
1387  erase_usage_info(gm->op1, stmt);
1388  if(gm->predicate)
1389  {
1390  erase_usage_info(gm->predicate, stmt);
1391  }
1392  break;
1393  }
1394  case gimple_cond_K:
1395  {
1396  auto* gc = GetPointer<gimple_cond>(curr_tn);
1397  erase_usage_info(gc->op0, stmt);
1398  break;
1399  }
1400  case CASE_UNARY_EXPRESSION:
1401  {
1402  if(curr_tn->get_kind() == addr_expr_K)
1403  {
1404  /* if(already_visited.find(curr_tn) != already_visited.end())
1405  {
1406  break;
1407  }
1408  already_visited.insert(curr_tn);*/
1409  }
1410  auto* ue = GetPointer<unary_expr>(curr_tn);
1411  erase_usage_info(ue->op, stmt);
1412  break;
1413  }
1415  {
1416  auto* be = GetPointer<binary_expr>(curr_tn);
1417  erase_usage_info(be->op0, stmt);
1418  erase_usage_info(be->op1, stmt);
1419  break;
1420  }
1421  case gimple_switch_K:
1422  {
1423  auto* se = GetPointer<gimple_switch>(curr_tn);
1424  erase_usage_info(se->op0, stmt);
1425  break;
1426  }
1427  case gimple_multi_way_if_K:
1428  {
1429  auto* gmwi = GetPointer<gimple_multi_way_if>(curr_tn);
1430  for(const auto& cond : gmwi->list_of_cond)
1431  {
1432  if(cond.first)
1433  {
1434  erase_usage_info(cond.first, stmt);
1435  }
1436  }
1437  break;
1438  }
1440  {
1441  auto* te = GetPointer<ternary_expr>(curr_tn);
1442  erase_usage_info(te->op0, stmt);
1443  erase_usage_info(te->op1, stmt);
1444  if(te->op2)
1445  {
1446  erase_usage_info(te->op2, stmt);
1447  }
1448  break;
1449  }
1451  {
1452  auto* qe = GetPointer<quaternary_expr>(curr_tn);
1453  erase_usage_info(qe->op0, stmt);
1454  erase_usage_info(qe->op1, stmt);
1455  if(qe->op2)
1456  {
1457  erase_usage_info(qe->op2, stmt);
1458  }
1459  if(qe->op3)
1460  {
1461  erase_usage_info(qe->op3, stmt);
1462  }
1463  break;
1464  }
1465  case lut_expr_K:
1466  {
1467  auto* le = GetPointer<lut_expr>(curr_tn);
1468  erase_usage_info(le->op0, stmt);
1469  erase_usage_info(le->op1, stmt);
1470  if(le->op2)
1471  {
1472  erase_usage_info(le->op2, stmt);
1473  }
1474  if(le->op3)
1475  {
1476  erase_usage_info(le->op3, stmt);
1477  }
1478  if(le->op4)
1479  {
1480  erase_usage_info(le->op4, stmt);
1481  }
1482  if(le->op5)
1483  {
1484  erase_usage_info(le->op5, stmt);
1485  }
1486  if(le->op6)
1487  {
1488  erase_usage_info(le->op6, stmt);
1489  }
1490  if(le->op7)
1491  {
1492  erase_usage_info(le->op7, stmt);
1493  }
1494  if(le->op8)
1495  {
1496  erase_usage_info(le->op8, stmt);
1497  }
1498  break;
1499  }
1500  case var_decl_K:
1501  case result_decl_K:
1502  case parm_decl_K:
1503  case integer_cst_K:
1504  case real_cst_K:
1505  case string_cst_K:
1506  case vector_cst_K:
1507  case void_cst_K:
1508  case complex_cst_K:
1509  case field_decl_K:
1510  case label_decl_K:
1511  case gimple_label_K:
1512  case gimple_asm_K:
1513  case gimple_phi_K:
1514  case target_mem_ref_K:
1515  case target_mem_ref461_K:
1516  case function_decl_K:
1517  {
1518  break;
1519  }
1520  case ssa_name_K:
1521  {
1522  auto* sn = GetPointer<ssa_name>(curr_tn);
1523  for(const auto& use_stmt : sn->CGetUseStmts())
1524  {
1525  if(GET_INDEX_NODE(use_stmt.first) == GET_INDEX_NODE(stmt))
1526  {
1527  for(decltype(use_stmt.second) repetition = 0; repetition < use_stmt.second; repetition++)
1528  {
1529  sn->RemoveUse(use_stmt.first);
1530  }
1531  }
1532  }
1533  break;
1534  }
1535  case call_expr_K:
1536  case aggr_init_expr_K:
1537  {
1538  auto* ce = GetPointer<call_expr>(curr_tn);
1539  std::vector<tree_nodeRef>& args = ce->args;
1540  std::vector<tree_nodeRef>::iterator arg, arg_end = args.end();
1541  for(arg = args.begin(); arg != arg_end; ++arg)
1542  {
1543  erase_usage_info(*arg, stmt);
1544  }
1545  break;
1546  }
1547  case gimple_call_K:
1548  {
1549  auto* ce = GetPointer<gimple_call>(curr_tn);
1550  std::vector<tree_nodeRef>& args = ce->args;
1551  std::vector<tree_nodeRef>::iterator arg, arg_end = args.end();
1552  for(arg = args.begin(); arg != arg_end; ++arg)
1553  {
1554  erase_usage_info(*arg, stmt);
1555  }
1556  break;
1557  }
1558  case binfo_K:
1559  case block_K:
1560  case case_label_expr_K:
1561  case const_decl_K:
1562  case constructor_K:
1563  case gimple_bind_K:
1564  case gimple_for_K:
1565  case gimple_goto_K:
1566  case gimple_nop_K:
1567  case gimple_pragma_K:
1568  case gimple_predict_K:
1569  case gimple_resx_K:
1570  case gimple_return_K:
1571  case gimple_while_K:
1572  case identifier_node_K:
1573  case namespace_decl_K:
1574  case statement_list_K:
1575  case target_expr_K:
1576  case translation_unit_decl_K:
1577  case template_decl_K:
1578  case using_decl_K:
1579  case tree_list_K:
1580  case type_decl_K:
1581  case tree_vec_K:
1582  case error_mark_K:
1583  case CASE_CPP_NODES:
1584  case CASE_FAKE_NODES:
1585  case CASE_PRAGMA_NODES:
1586  case CASE_TYPE_NODES:
1587  default:
1588  THROW_ERROR(std::string("Node not supported (") + STR(GET_INDEX_NODE(tn)) + std::string("): ") +
1589  curr_tn->get_kind_text());
1590  }
1592  "<--Erased usage into node " + STR(GET_INDEX_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() +
1593  "). Statement: " + STR(GET_INDEX_NODE(stmt)) + " (" + GET_NODE(stmt)->get_kind_text() + ")");
1594 }
1595 
1597 {
1599  "-->Insert usage info into node " + STR(GET_INDEX_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() +
1600  "). Statement: " + STR(GET_INDEX_NODE(stmt)) + " (" + GET_NODE(stmt)->get_kind_text() + ")");
1601  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1602  tree_nodeRef curr_tn = GET_NODE(tn);
1603  switch(curr_tn->get_kind())
1604  {
1605  case gimple_assign_K:
1606  {
1607  auto* gm = GetPointer<gimple_assign>(curr_tn);
1608  insert_usage_info(gm->op1, stmt);
1609  if(gm->predicate)
1610  {
1611  insert_usage_info(gm->predicate, stmt);
1612  }
1613  break;
1614  }
1615  case gimple_cond_K:
1616  {
1617  auto* gc = GetPointer<gimple_cond>(curr_tn);
1618  insert_usage_info(gc->op0, stmt);
1619  break;
1620  }
1621  case CASE_UNARY_EXPRESSION:
1622  {
1623  if(curr_tn->get_kind() == addr_expr_K)
1624  {
1625  /* if(already_visited.find(curr_tn) != already_visited.end())
1626  {
1627  break;
1628  }
1629  already_visited.insert(curr_tn);*/
1630  }
1631  auto* ue = GetPointer<unary_expr>(curr_tn);
1632  insert_usage_info(ue->op, stmt);
1633  break;
1634  }
1636  {
1637  auto* be = GetPointer<binary_expr>(curr_tn);
1638  insert_usage_info(be->op0, stmt);
1639  insert_usage_info(be->op1, stmt);
1640  break;
1641  }
1642  case gimple_switch_K:
1643  {
1644  auto* se = GetPointer<gimple_switch>(curr_tn);
1645  insert_usage_info(se->op0, stmt);
1646  break;
1647  }
1648  case gimple_multi_way_if_K:
1649  {
1650  auto* gmwi = GetPointer<gimple_multi_way_if>(curr_tn);
1651  for(const auto& cond : gmwi->list_of_cond)
1652  {
1653  if(cond.first)
1654  {
1655  insert_usage_info(cond.first, stmt);
1656  }
1657  }
1658  break;
1659  }
1661  {
1662  auto* te = GetPointer<ternary_expr>(curr_tn);
1663  insert_usage_info(te->op0, stmt);
1664  insert_usage_info(te->op1, stmt);
1665  if(te->op2)
1666  {
1667  insert_usage_info(te->op2, stmt);
1668  }
1669  break;
1670  }
1672  {
1673  auto* qe = GetPointer<quaternary_expr>(curr_tn);
1674  insert_usage_info(qe->op0, stmt);
1675  insert_usage_info(qe->op1, stmt);
1676  if(qe->op2)
1677  {
1678  insert_usage_info(qe->op2, stmt);
1679  }
1680  if(qe->op3)
1681  {
1682  insert_usage_info(qe->op3, stmt);
1683  }
1684  break;
1685  }
1686  case lut_expr_K:
1687  {
1688  auto* le = GetPointer<lut_expr>(curr_tn);
1689  insert_usage_info(le->op0, stmt);
1690  insert_usage_info(le->op1, stmt);
1691  if(le->op2)
1692  {
1693  insert_usage_info(le->op2, stmt);
1694  }
1695  if(le->op3)
1696  {
1697  insert_usage_info(le->op3, stmt);
1698  }
1699  if(le->op4)
1700  {
1701  insert_usage_info(le->op4, stmt);
1702  }
1703  if(le->op5)
1704  {
1705  insert_usage_info(le->op5, stmt);
1706  }
1707  if(le->op6)
1708  {
1709  insert_usage_info(le->op6, stmt);
1710  }
1711  if(le->op7)
1712  {
1713  insert_usage_info(le->op7, stmt);
1714  }
1715  if(le->op8)
1716  {
1717  insert_usage_info(le->op8, stmt);
1718  }
1719  break;
1720  }
1721  case var_decl_K:
1722  case result_decl_K:
1723  case parm_decl_K:
1724  case integer_cst_K:
1725  case real_cst_K:
1726  case string_cst_K:
1727  case vector_cst_K:
1728  case void_cst_K:
1729  case complex_cst_K:
1730  case field_decl_K:
1731  case label_decl_K:
1732  case gimple_label_K:
1733  case gimple_asm_K:
1734  case gimple_phi_K:
1735  case target_mem_ref_K:
1736  case target_mem_ref461_K:
1737  case function_decl_K:
1738  {
1739  break;
1740  }
1741  case ssa_name_K:
1742  {
1743  auto* sn = GetPointer<ssa_name>(curr_tn);
1744  sn->AddUseStmt(stmt);
1745  break;
1746  }
1747  case call_expr_K:
1748  case aggr_init_expr_K:
1749  {
1750  auto* ce = GetPointer<call_expr>(curr_tn);
1751  const std::vector<tree_nodeRef>& args = ce->args;
1752  std::vector<tree_nodeRef>::const_iterator arg, arg_end = args.end();
1753  for(arg = args.begin(); arg != arg_end; ++arg)
1754  {
1755  insert_usage_info(*arg, stmt);
1756  }
1757  break;
1758  }
1759  case gimple_call_K:
1760  {
1761  auto* ce = GetPointer<gimple_call>(curr_tn);
1762  std::vector<tree_nodeRef>& args = ce->args;
1763  std::vector<tree_nodeRef>::iterator arg, arg_end = args.end();
1764  for(arg = args.begin(); arg != arg_end; ++arg)
1765  {
1766  insert_usage_info(*arg, stmt);
1767  }
1768  break;
1769  }
1770  case binfo_K:
1771  case block_K:
1772  case case_label_expr_K:
1773  case const_decl_K:
1774  case constructor_K:
1775  case gimple_bind_K:
1776  case gimple_for_K:
1777  case gimple_goto_K:
1778  case gimple_nop_K:
1779  case gimple_pragma_K:
1780  case gimple_predict_K:
1781  case gimple_resx_K:
1782  case gimple_return_K:
1783  case gimple_while_K:
1784  case identifier_node_K:
1785  case namespace_decl_K:
1786  case statement_list_K:
1787  case target_expr_K:
1788  case translation_unit_decl_K:
1789  case template_decl_K:
1790  case using_decl_K:
1791  case tree_list_K:
1792  case tree_vec_K:
1793  case type_decl_K:
1794  case error_mark_K:
1795  case CASE_CPP_NODES:
1796  case CASE_FAKE_NODES:
1797  case CASE_PRAGMA_NODES:
1798  case CASE_TYPE_NODES:
1799  default:
1800  THROW_ERROR(std::string("Node not supported (") + STR(GET_INDEX_NODE(tn)) + std::string("): ") +
1801  curr_tn->get_kind_text());
1802  }
1804  "<--Inserted usage info into node " + STR(GET_INDEX_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() +
1805  "). Statement: " + STR(GET_INDEX_NODE(stmt)) + " (" + GET_NODE(stmt)->get_kind_text() + ")");
1806 }
1807 
1809 {
1810  n_pl++;
1811 }
1812 
1813 unsigned int tree_manager::get_n_pl() const
1814 {
1815  return n_pl;
1816 }
1817 
1818 void tree_manager::merge_tree_managers(const tree_managerRef& source_tree_manager)
1819 {
1820  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Starting merging of new tree_manager");
1832 
1838 
1840  CustomUnorderedMap<unsigned int, std::string> global_type_unql_symbol_table;
1842  CustomUnorderedSet<std::string> static_symbol_table;
1843  CustomUnorderedSet<std::string> static_function_header_symbol_table;
1844  null_deleter nullDel;
1845  tree_managerRef TM_this(this, nullDel);
1847  {
1848  std::string raw_file_name = Param->getOption<std::string>(OPT_output_temporary_directory) + "before_tree_merge_" +
1850  std::ofstream raw_file(raw_file_name.c_str());
1851  raw_file << TM_this;
1852  raw_file.close();
1853  }
1854 
1857  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Building the global symbol table of this tree manager");
1858  std::string symbol_name;
1859  std::string symbol_scope;
1860  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Checking types");
1861  for(const auto& ti : tree_nodes)
1862  {
1863  const tree_nodeRef tn = ti.second;
1864  auto* dn = GetPointer<decl_node>(tn);
1865  if(not dn)
1866  {
1867  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Checking " + STR(ti.first));
1868  if(check_for_type(tn, TM_this, symbol_name, symbol_scope, global_type_symbol_table, ti.first))
1869  {
1870  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Is NOT inserted in the symbol table");
1871  continue;
1872  }
1873  else
1874  {
1875  THROW_ASSERT(
1876  global_type_symbol_table.find(symbol_name) == global_type_symbol_table.end(),
1877  "duplicated symbol in global_type_symbol_table: " + global_type_symbol_table.find(symbol_name)->first +
1878  " " + STR(global_type_symbol_table.find(symbol_name)->second) + " " + STR(ti.first));
1880  "---Is INSERTED in the symbol table " + symbol_name + " --> " + STR(ti.first));
1881  global_type_symbol_table[symbol_name] = ti.first;
1883  if(tn->get_kind() == record_type_K and GetPointer<record_type>(tn)->unql and
1884  GetPointer<record_type>(tn)->qual == TreeVocabularyTokenTypes_TokenEnum::FIRST_TOKEN)
1885  {
1886  global_type_symbol_table["u struct " + symbol_name] = GET_INDEX_NODE(GetPointer<record_type>(tn)->unql);
1887  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)] =
1888  "u struct " + symbol_name;
1889  }
1890  else if(tn->get_kind() == union_type_K and GetPointer<union_type>(tn)->unql and
1891  GetPointer<union_type>(tn)->qual == TreeVocabularyTokenTypes_TokenEnum::FIRST_TOKEN)
1892  {
1893  global_type_symbol_table["u union " + symbol_name] = GET_INDEX_NODE(GetPointer<union_type>(tn)->unql);
1894  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)] =
1895  "u union " + symbol_name;
1896  }
1897  }
1898  }
1899  }
1900  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Checked types");
1901  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Checking declarations");
1902  for(const auto& ti : tree_nodes)
1903  {
1905  const tree_nodeRef tn = ti.second;
1906  auto* dn = GetPointer<decl_node>(tn);
1907  if(dn)
1908  {
1909  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Checking " + STR(ti.first));
1910  if(check_for_decl(tn, TM_this, symbol_name, symbol_scope, ti.first, global_type_unql_symbol_table))
1911  {
1912  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Is NOT inserted in the symbol table");
1913  continue;
1914  }
1915  else
1916  {
1917  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Not skipped");
1919  if((GetPointer<function_decl>(tn) and GetPointer<function_decl>(tn)->static_flag) or
1920  (GetPointer<var_decl>(tn) and
1921  (GetPointer<var_decl>(tn)->static_flag or GetPointer<var_decl>(tn)->static_static_flag)))
1922  {
1923  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Static declaration");
1924  THROW_ASSERT(
1925  (GetPointer<function_decl>(tn) and GetPointer<function_decl>(tn)->body) or
1926  (GetPointer<var_decl>(tn) and
1927  static_symbol_table.find(symbol_name + "-" + symbol_scope) == static_symbol_table.end()) or
1928  (GetPointer<function_decl>(tn) and not GetPointer<function_decl>(tn)->body and
1929  static_function_header_symbol_table.find(symbol_name + "-" + symbol_scope) ==
1930  static_function_header_symbol_table.end()),
1931  "duplicated static symbol in the current tree_manager: " + symbol_name + "-" + symbol_scope + " " +
1932  STR(ti.first));
1933  if(GetPointer<function_decl>(tn) and !GetPointer<function_decl>(tn)->body)
1934  {
1935  static_function_header_symbol_table.insert(symbol_name + "-" + symbol_scope);
1936  }
1937  else
1938  {
1939  static_symbol_table.insert(symbol_name + "-" + symbol_scope);
1940  }
1941  continue;
1942  }
1944  if(dn->get_kind() == function_decl_K and
1945  global_decl_symbol_table.find(symbol_name + "-" + symbol_scope) != global_decl_symbol_table.end())
1946  {
1947  if(GetPointer<function_decl>(
1948  tree_nodes.find(global_decl_symbol_table.find(symbol_name + "-" + symbol_scope)->second)->second)
1949  ->body)
1950  {
1951  continue;
1952  }
1953  if(GetPointer<function_decl>(tn)->undefined_flag)
1954  {
1955  continue;
1956  }
1957  // else do overwrite
1958  }
1959  else if(dn->get_kind() == var_decl_K and
1960  global_decl_symbol_table.find(symbol_name + "-" + symbol_scope) != global_decl_symbol_table.end())
1961  {
1962  if(!GetPointer<var_decl>(
1963  tree_nodes.find(global_decl_symbol_table.find(symbol_name + "-" + symbol_scope)->second)->second)
1964  ->extern_flag)
1965  {
1966  continue;
1967  }
1968  if(GetPointer<var_decl>(tn)->extern_flag)
1969  {
1970  continue;
1971  }
1972  // else do overwrite
1973  }
1974  else if(dn->get_kind() != function_decl_K && dn->get_kind() != var_decl_K && dn->get_kind() != type_decl_K)
1975  {
1976  // THROW_ASSERT(global_decl_symbol_table.find(symbol_name+"-"+symbol_scope) ==
1977  // global_decl_symbol_table.end(), "duplicated symbol in global_decl_symbol_table:
1978  // "+global_decl_symbol_table.find(symbol_name+"-"+symbol_scope)->first + " == " +
1979  // std::to_string(ti.first));
1980  continue;
1981  }
1982 
1984  "---Adding to global declaration table " + symbol_name + "-" + symbol_scope + " (" +
1985  STR(ti.first) + ")");
1986 
1987  global_decl_symbol_table[symbol_name + "-" + symbol_scope] = ti.first;
1988  }
1989  }
1990  }
1991  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Checked declarations");
1993 
1994  auto gtust_i_end = global_type_unql_symbol_table.end();
1995  for(auto gtust_i = global_type_unql_symbol_table.begin(); gtust_i != gtust_i_end; ++gtust_i)
1996  {
1997  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, STR(gtust_i->first) + "-unqualified_type>" + gtust_i->second);
1998  }
1999  auto gst_i_end = global_decl_symbol_table.end();
2000  for(auto gst_i = global_decl_symbol_table.begin(); gst_i != gst_i_end; ++gst_i)
2001  {
2002  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, STR(gst_i->second) + "-decl>" + gst_i->first);
2003  }
2004 
2005  gst_i_end = global_type_symbol_table.end();
2006  for(auto gst_i = global_type_symbol_table.begin(); gst_i != gst_i_end; ++gst_i)
2007  {
2008  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, STR(gst_i->second) + "-type>" + gst_i->first);
2009  }
2010 
2011  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Built table for this tree_manager");
2014  CustomUnorderedMapUnstable<std::string, std::string> source_static_symbol_table;
2017 
2020 
2023  CustomUnorderedMapUnstable<std::string, unsigned int> static_forward_declaration_functions;
2024 
2026  CustomUnorderedMapUnstable<std::string, unsigned int> static_implementation_functions;
2027 
2029  OrderedSetStd<unsigned int> not_yet_remapped;
2030  OrderedSetStd<unsigned int> to_be_visited;
2032 
2036 #if HAVE_UNORDERED
2037  std::map<unsigned int, tree_nodeRef> source_tree_nodes;
2038  for(auto source_tree_node : source_tree_manager->tree_nodes)
2039  {
2040  source_tree_nodes.insert(source_tree_node);
2041  }
2042 #else
2043  auto& source_tree_nodes = source_tree_manager->tree_nodes;
2044 #endif
2045 
2049  "-->Analyzing " + STR(source_tree_nodes.size()) + " tree nodes of second tree manager");
2050  for(const auto& ti_source : source_tree_nodes)
2051  {
2052  const tree_nodeRef tn = ti_source.second;
2054  auto* dn = GetPointer<decl_node>(tn);
2055  if(not dn)
2056  {
2057  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Checking " + STR(ti_source.first));
2058  if(GetPointer<identifier_node>(tn))
2059  {
2060  auto* id = GetPointer<identifier_node>(tn);
2061  unsigned int node_id = find_identifier_nodeID(id->strg);
2062  if(node_id)
2063  {
2064  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Identifier FOUND: remapped!");
2065  remap[ti_source.first] = node_id;
2066  }
2067  else
2068  {
2069  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Identifier NOT found: skipped!");
2070  continue;
2071  }
2072  }
2073  else if(check_for_type(tn, source_tree_manager, symbol_name, symbol_scope, global_type_symbol_table,
2074  ti_source.first))
2075  {
2076  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Is NOT inserted in the symbol table");
2077  continue;
2078  }
2079  else
2080  {
2082  STR(ti_source.first) + "-ntype>" + symbol_name + "-" + symbol_scope);
2083  if(tn->get_kind() == record_type_K and GetPointer<record_type>(tn)->unql and
2084  GetPointer<record_type>(tn)->qual == TreeVocabularyTokenTypes_TokenEnum::FIRST_TOKEN)
2085  {
2086  auto gst_it = global_type_symbol_table.find("u struct " + symbol_name);
2087  if(gst_it != global_type_symbol_table.end())
2088  {
2089  remap[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)] = gst_it->second;
2090  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)] =
2091  "u struct " + symbol_name;
2093  STR(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)) + "-nutype>" + symbol_name);
2094  // std::cout << "remap unql: " + gst_it->first << " " << gst_it->second << std::endl;
2095  }
2096  else
2097  {
2098  unsigned int new_tree_index;
2099  if(remap.find(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)) == remap.end())
2100  {
2101  new_tree_index = new_tree_node_id(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql));
2102  not_yet_remapped.insert(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql));
2103  remap[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)] = new_tree_index;
2104  to_be_visited.insert(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql));
2105  }
2106  else
2107  {
2108  new_tree_index = remap[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)];
2109  }
2110  global_type_symbol_table["u struct " + symbol_name] = new_tree_index;
2111  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)] =
2112  "u struct " + symbol_name;
2114  "other " + STR(GET_INDEX_NODE(GetPointer<record_type>(tn)->unql)) + "-nutype>" +
2115  symbol_name);
2116  }
2117  }
2118  else if(tn->get_kind() == union_type_K and GetPointer<union_type>(tn)->unql and
2119  GetPointer<union_type>(tn)->qual == TreeVocabularyTokenTypes_TokenEnum::FIRST_TOKEN)
2120  {
2121  auto gst_it = global_type_symbol_table.find("u union " + symbol_name);
2122  if(gst_it != global_type_symbol_table.end())
2123  {
2124  remap[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)] = gst_it->second;
2125  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)] =
2126  "u union " + symbol_name;
2128  STR(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)) + "-nutype>" + symbol_name);
2129  // std::cout << "remap unql: " + gst_it->first << std::endl;
2130  }
2131  else
2132  {
2133  unsigned int new_tree_index;
2134  if(remap.find(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)) == remap.end())
2135  {
2136  new_tree_index = new_tree_node_id(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql));
2137  remap[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)] = new_tree_index;
2138  not_yet_remapped.insert(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql));
2139  to_be_visited.insert(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql));
2140  }
2141  else
2142  {
2143  new_tree_index = remap[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)];
2144  }
2145  global_type_symbol_table["u union " + symbol_name] = new_tree_index;
2146  global_type_unql_symbol_table[GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)] =
2147  "u union " + symbol_name;
2149  "other " + STR(GET_INDEX_NODE(GetPointer<union_type>(tn)->unql)) + "-nutype>" +
2150  symbol_name);
2151  }
2152  }
2153  auto gst_it = global_type_symbol_table.find(symbol_name);
2154  if(gst_it == global_type_symbol_table.end())
2155  {
2156  if(remap.find(ti_source.first) == remap.end())
2157  {
2158  unsigned int new_tree_index = new_tree_node_id(ti_source.first);
2159  global_type_symbol_table[symbol_name] = remap[ti_source.first] = new_tree_index;
2160  not_yet_remapped.insert(ti_source.first);
2161  to_be_visited.insert(ti_source.first);
2162  }
2163  continue;
2164  }
2165  else
2166  {
2167  // record type
2168  if(tn->get_kind() == record_type_K)
2169  {
2170  // present in this tree_manager
2171  if(tree_nodes.find(gst_it->second) != tree_nodes.end())
2172  {
2173  if(GetPointer<record_type>(tree_nodes.find(gst_it->second)->second) and
2174  GetPointer<record_type>(tree_nodes.find(gst_it->second)->second)->list_of_flds.empty() and
2175  !GetPointer<record_type>(tn)->list_of_flds.empty())
2176  {
2177  not_yet_remapped.insert(ti_source.first);
2178  to_be_visited.insert(ti_source.first);
2180  "RECORD TYPE: " + gst_it->first + " " + STR(ti_source.first));
2181  }
2182  }
2183  else
2184  {
2185  THROW_ASSERT(source_tree_nodes.find(gst_it->second) != source_tree_nodes.end(),
2186  "There is a symbol which is not present in this nor tree_manager nor the other");
2187  if(GetPointer<record_type>(source_tree_nodes.find(gst_it->second)->second)
2188  ->list_of_flds.empty() and
2189  !GetPointer<record_type>(tn)->list_of_flds.empty())
2190  {
2191  not_yet_remapped.insert(ti_source.first);
2192  to_be_visited.insert(ti_source.first);
2194  "RECORD TYPE: " + gst_it->first + " " + STR(ti_source.first));
2195  }
2196  }
2197  }
2198  if(tn->get_kind() == union_type_K)
2199  {
2200  // present in this tree_manager
2201  if(tree_nodes.find(gst_it->second) != tree_nodes.end())
2202  {
2203  if(GetPointer<union_type>(tree_nodes.find(gst_it->second)->second) and
2204  GetPointer<union_type>(tree_nodes.find(gst_it->second)->second)->list_of_flds.empty() and
2205  !GetPointer<union_type>(tn)->list_of_flds.empty())
2206  {
2207  not_yet_remapped.insert(ti_source.first);
2208  to_be_visited.insert(ti_source.first);
2210  "UNION TYPE: " + gst_it->first + " " + STR(ti_source.first));
2211  }
2212  }
2213  else
2214  {
2215  THROW_ASSERT(source_tree_nodes.find(gst_it->second) != source_tree_nodes.end(),
2216  "There is a symbol which is not present in this nor tree_manager nor the other");
2217  if(GetPointer<union_type>(source_tree_nodes.find(gst_it->second)->second)->list_of_flds.empty() and
2218  !GetPointer<union_type>(tn)->list_of_flds.empty())
2219  {
2220  not_yet_remapped.insert(ti_source.first);
2221  to_be_visited.insert(ti_source.first);
2223  "UNION TYPE: " + gst_it->first + " " + STR(ti_source.first));
2224  }
2225  }
2226  }
2227  remap[ti_source.first] = gst_it->second;
2228  }
2229  }
2230  }
2231  }
2232  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Analyzed tree nodes of second tree manager");
2233 
2235  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Remapping declaration nodes");
2236  for(const auto& ti_source : source_tree_nodes)
2237  {
2238  const tree_nodeRef tn = ti_source.second;
2240  auto* dn = GetPointer<decl_node>(tn);
2241  if(dn)
2242  {
2244  "-->Examining declaration node " + STR(ti_source.first) + " of second tree:" + STR(tn));
2245  if(check_for_decl(tn, source_tree_manager, symbol_name, symbol_scope, ti_source.first,
2246  global_type_unql_symbol_table))
2247  {
2248  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Not suitable for symbol table");
2249  continue;
2250  }
2252  STR(ti_source.first) + "-ndecl>" + symbol_name + "-" + symbol_scope);
2254  if((GetPointer<function_decl>(tn) and GetPointer<function_decl>(tn)->static_flag) or
2255  (GetPointer<var_decl>(tn) and
2256  (GetPointer<var_decl>(tn)->static_flag or GetPointer<var_decl>(tn)->static_static_flag)))
2257  {
2259  if(GetPointer<function_decl>(tn))
2260  {
2262  if(GetPointer<function_decl>(tn)->body)
2263  {
2266  const unsigned int new_index = new_tree_node_id(ti_source.first);
2267  remap[ti_source.first] = new_index;
2268  not_yet_remapped.insert(ti_source.first);
2269  to_be_visited.insert(ti_source.first);
2270 
2271  static_implementation_functions[symbol_name] = ti_source.first;
2272 
2274  if(static_forward_declaration_functions.find(symbol_name) !=
2275  static_forward_declaration_functions.end())
2276  {
2277  remap[static_forward_declaration_functions[symbol_name]] = new_index;
2278  }
2279  }
2281  else
2282  {
2283  static_forward_declaration_functions[symbol_name] = ti_source.first;
2285  if(static_implementation_functions.find(symbol_name) != static_implementation_functions.end())
2286  {
2287  remap[ti_source.first] = remap[static_implementation_functions[symbol_name]];
2288  }
2289  }
2290  }
2291 
2293  if(source_static_symbol_table.find(symbol_name) != source_static_symbol_table.end())
2294  {
2295  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Already present in source static symbol table");
2296  unsigned int node_id_source =
2297  source_tree_manager->find_identifier_nodeID(source_static_symbol_table.find(symbol_name)->second);
2298 
2300  dn->name = source_tree_manager->GetTreeReindex(node_id_source);
2301  }
2302  else if(static_symbol_table.find(symbol_name + "-" + symbol_scope) != static_symbol_table.end() or
2303  static_function_header_symbol_table.find(symbol_name + "-" + symbol_scope) !=
2304  static_function_header_symbol_table.end())
2305  {
2307  "---Already present in destination static symbol table");
2311  unsigned int counter = 0;
2312  unsigned int node_id_this, node_id_source;
2313  do
2314  {
2315  counter++;
2316  node_id_this = find_identifier_nodeID(symbol_name + STR(counter));
2317  node_id_source = source_tree_manager->find_identifier_nodeID(symbol_name + STR(counter));
2318  } while((node_id_this > 0 || node_id_source > 0));
2319  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> tree_node_schema;
2320  tree_node_schema[TOK(TOK_STRG)] = symbol_name + STR(counter);
2321  node_id_source = source_tree_manager->new_tree_node_id(ti_source.first);
2322  source_tree_manager->create_tree_node(node_id_source, identifier_node_K, tree_node_schema);
2323 
2325  dn->name = source_tree_manager->GetTreeReindex(node_id_source);
2326  source_static_symbol_table[symbol_name] = symbol_name + STR(counter);
2327  }
2328  else
2329  {
2330  if(not GetPointer<function_decl>(tn))
2331  {
2332  static_symbol_table.insert(symbol_name + "-" + symbol_scope);
2333  }
2335  continue;
2336  }
2337  }
2338  else
2339  {
2340  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Not Static");
2341  auto gst_it = global_decl_symbol_table.find(symbol_name + "-" + symbol_scope);
2342  if(gst_it == global_decl_symbol_table.end())
2343  {
2344  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Not yet in global decl symbol table");
2345  unsigned int new_index;
2346  new_index = new_tree_node_id(ti_source.first);
2347  global_decl_symbol_table[symbol_name + "-" + symbol_scope] = remap[ti_source.first] = new_index;
2348  if(dn->get_kind() == function_decl_K and not GetPointer<const function_decl>(tn)->body)
2349  {
2350  reverse_remap[new_index] = ti_source.first;
2351  }
2352  if(dn->get_kind() == var_decl_K and GetPointer<const var_decl>(tn)->extern_flag)
2353  {
2354  reverse_remap[new_index] = ti_source.first;
2355  }
2356  not_yet_remapped.insert(ti_source.first);
2357  to_be_visited.insert(ti_source.first);
2360  continue;
2361  }
2362  else
2363  {
2364  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Already in global decl symbol table");
2365  if((tn->get_kind() == function_decl_K
2366  // and
2367  // (
2368  // !GetPointer<function_decl>(tree_nodes.find(gst_it->second)->second)
2369  // ||
2370  // !GetPointer<function_decl>(tree_nodes.find(gst_it->second)->second)->body
2371  // )
2372  and GetPointer<function_decl>(tn)->body) ||
2373  // In the first tree manager there is extern type variable, in the second there is the definition
2374  (tn->get_kind() == var_decl_K and
2375  (!GetPointer<var_decl>(tree_nodes.find(gst_it->second)->second) ||
2376  GetPointer<var_decl>(tree_nodes.find(gst_it->second)->second)->extern_flag) and
2377  !GetPointer<var_decl>(tn)->extern_flag) ||
2378  // In the first tree manager there is a function_decl without srcp, in the second there is a
2379  // funcion_decl with srcp
2380  (tn->get_kind() == function_decl_K and
2381  GetPointer<function_decl>(tree_nodes.find(gst_it->second)->second) and
2382  (GetPointer<function_decl>(tree_nodes.find(gst_it->second)->second))->include_name ==
2383  "<built-in>" and
2384  !(GetPointer<function_decl>(tn))->include_name.empty() and
2385  (GetPointer<function_decl>(tn))->include_name != "<built-in>"))
2386  {
2387  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---but... forced overwriting");
2389  not_yet_remapped.insert(ti_source.first);
2390  to_be_visited.insert(ti_source.first);
2391  remap[ti_source.first] = gst_it->second;
2394  if(reverse_remap.find(gst_it->second) != reverse_remap.end())
2395  {
2396  THROW_ASSERT(not_yet_remapped.find(reverse_remap.find(gst_it->second)->second) !=
2397  not_yet_remapped.end(),
2398  "Trying to cancel remapping of " + STR(reverse_remap.find(gst_it->second)->second));
2399  not_yet_remapped.erase(reverse_remap.find(gst_it->second)->second);
2400  }
2401  }
2402  else
2403  {
2404  remap[ti_source.first] = gst_it->second;
2405  }
2406  }
2408  }
2410  }
2411  else
2412  {
2414  }
2415  }
2416  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Remapped declaration nodes");
2418  tree_node_reached TNR(remap, not_yet_remapped, tree_managerRef(this, null_deleter()));
2419  auto it_to_be_visited_end = to_be_visited.end();
2420  for(auto it_to_be_visited = to_be_visited.begin(); it_to_be_visited_end != it_to_be_visited; ++it_to_be_visited)
2421  {
2422  source_tree_manager->get_tree_node_const(*it_to_be_visited)->visit(&TNR);
2423  }
2424 
2426  for(auto& function_decl_node : source_tree_manager->function_decl_nodes)
2427  {
2428  tree_nodeRef curr_tn = function_decl_node.second;
2429  auto* fd = GetPointer<function_decl>(curr_tn);
2430  if(remap.find(function_decl_node.first) == remap.end())
2431  {
2432  remap[function_decl_node.first] = new_tree_node_id(function_decl_node.first);
2434  "Function decl: old " + STR(function_decl_node.first) + " - new " +
2435  STR(remap[function_decl_node.first]));
2436  fd->visit(&TNR);
2437  not_yet_remapped.insert(function_decl_node.first);
2438  }
2439  }
2440  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Already remapped tree_node");
2441  auto it_remap_end = remap.end();
2442  for(auto it_remap = remap.begin(); it_remap_end != it_remap; ++it_remap)
2443  {
2445  "Original " + STR(it_remap->first) + " New " + STR(it_remap->second));
2446  }
2447 
2448  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Starting remapping remaining nodes");
2449  auto it_not_yet_remapped_end = not_yet_remapped.end();
2450  for(auto it_not_yet_remapped = not_yet_remapped.begin(); it_not_yet_remapped_end != it_not_yet_remapped;
2451  ++it_not_yet_remapped)
2452  {
2454  "Original " + STR(*it_not_yet_remapped) + " New " + STR(remap[*it_not_yet_remapped]));
2455  TNIF.create_tree_node(remap[*it_not_yet_remapped],
2456  source_tree_manager->get_tree_node_const(*it_not_yet_remapped));
2457 
2459  "Type is " +
2460  std::string(source_tree_manager->get_tree_node_const(*it_not_yet_remapped)->get_kind_text()));
2462  }
2464  {
2465  std::string raw_file_name = Param->getOption<std::string>(OPT_output_temporary_directory) + "after_" +
2467  std::cerr << raw_file_name << std::endl;
2468  std::ofstream raw_file(raw_file_name.c_str());
2469  raw_file << TM_this;
2470  raw_file.close();
2471  }
2472  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Ended merging of new tree_manager");
2473 }
2474 
2475 bool tree_manager::check_for_decl(const tree_nodeRef& tn, const tree_managerRef& TM_this, std::string& symbol_name,
2476  std::string& symbol_scope, unsigned int ASSERT_PARAMETER(node_id),
2477  const CustomUnorderedMap<unsigned int, std::string>& global_type_unql_symbol_table)
2478 {
2479  THROW_ASSERT(GetPointer<decl_node>(tn), "Node should be a declaration node");
2480  const decl_node* dn = GetPointer<decl_node>(tn);
2481  symbol_name = symbol_scope = "";
2483  if(!dn->name)
2484  {
2485  return true;
2486  }
2487  if(GET_NODE(dn->name)->get_kind() == identifier_node_K)
2488  {
2490  "---check_for_decl is considering: " + GetPointer<identifier_node>(GET_NODE(dn->name))->strg +
2491  ":" + dn->include_name);
2492  }
2494  if(GetPointer<memory_tag>(tn) || dn->get_kind() == parm_decl_K || dn->get_kind() == result_decl_K)
2495  {
2496  return true;
2497  }
2499  if(dn->scpe and GET_NODE(dn->scpe)->get_kind() == function_decl_K)
2500  {
2501  return true;
2502  }
2503  const function_decl* fd = GetPointer<function_decl>(tn);
2504  if(!fd and dn->scpe and GetPointer<type_node>(GET_NODE(dn->scpe)) and
2505  (!GetPointer<type_node>(GET_NODE(dn->scpe))->name and
2506  global_type_unql_symbol_table.find(GET_INDEX_NODE(dn->scpe)) == global_type_unql_symbol_table.end()))
2507  {
2508  return true;
2509  }
2510  if(dn->mngl)
2511  {
2512  THROW_ASSERT(GET_NODE(dn->mngl)->get_kind() == identifier_node_K,
2513  "expected an identifier_node: " + STR(GET_NODE(dn->mngl)->get_kind_text()));
2514  if(dn->name)
2515  {
2516  THROW_ASSERT(GET_NODE(dn->name)->get_kind() == identifier_node_K,
2517  "expected an identifier_node: " + STR(GET_NODE(dn->name)->get_kind_text()) + " " + STR(node_id));
2518  if(fd)
2519  {
2520  if(fd->builtin_flag)
2521  {
2522  symbol_name = GetPointer<identifier_node>(GET_NODE(dn->name))->strg;
2523  if(starts_with(symbol_name, "__builtin_"))
2524  {
2525  symbol_name = symbol_name.substr(strlen("__builtin_"));
2526  }
2527  // if(fd->undefined_flag && symbol_name.find("__builtin_") == std::string::npos)
2528  // symbol_name = "__builtin_" + symbol_name;
2529  }
2530  else
2531  {
2532  symbol_name = GetPointer<identifier_node>(GET_NODE(dn->mngl))->strg;
2533  }
2534  }
2535  else
2536  {
2537  symbol_name = GetPointer<identifier_node>(GET_NODE(dn->mngl))->strg;
2538  }
2539  }
2540  else
2541  {
2542  symbol_name = GetPointer<identifier_node>(GET_NODE(dn->mngl))->strg;
2543  }
2544  }
2545  else
2546  {
2547  THROW_ASSERT(GET_NODE(dn->name)->get_kind() == identifier_node_K,
2548  "expected an identifier_node: " + STR(GET_NODE(dn->name)->get_kind_text()) + " " + STR(node_id));
2549  symbol_name = GetPointer<identifier_node>(GET_NODE(dn->name))->strg;
2550  if(starts_with(symbol_name, "__builtin_"))
2551  {
2552  symbol_name = symbol_name.substr(strlen("__builtin_"));
2553  }
2554  // if(fd && fd->undefined_flag && fd->builtin_flag && symbol_name.find("__builtin_") == std::string::npos)
2555  // symbol_name = "__builtin_" + symbol_name;
2556  }
2557  if(dn->scpe and GetPointer<type_node>(GET_NODE(dn->scpe)) and GetPointer<type_node>(GET_NODE(dn->scpe))->name)
2558  {
2559  auto* type = GetPointer<type_node>(GET_NODE(dn->scpe));
2560  THROW_ASSERT(type, "expected a type_node: " + std::string(GET_NODE(dn->scpe)->get_kind_text()));
2562  if(type->scpe and GET_NODE(type->scpe)->get_kind() == function_decl_K)
2563  {
2564  return true;
2565  }
2566  const auto quals = type->qual;
2567  std::string type_name;
2568  if(GET_NODE(type->name)->get_kind() == identifier_node_K)
2569  {
2570  type_name = GetPointer<identifier_node>(GET_NODE(type->name))->strg;
2571  }
2572  else
2573  {
2574  type_name = tree_helper::get_type_name(TM_this, GET_INDEX_NODE(type->name));
2575  }
2576  if(type->name and (GET_NODE(type->name)->get_kind() == type_decl_K))
2577  {
2579  {
2580  symbol_scope = tree_helper::return_qualifier_prefix(quals) + type_name;
2581  }
2582  else
2583  {
2584  symbol_scope = type_name;
2585  }
2586  }
2587  else if(type->name)
2588  {
2589  symbol_scope = "struct " + type_name;
2590  }
2591  if(fd)
2592  {
2593  symbol_scope = symbol_scope + "#F";
2594  }
2595  }
2596  else if(dn->scpe and GetPointer<type_node>(GET_NODE(dn->scpe)) and
2597  !GetPointer<type_node>(GET_NODE(dn->scpe))->name and
2598  global_type_unql_symbol_table.find(GET_INDEX_NODE(dn->scpe)) != global_type_unql_symbol_table.end())
2599  {
2600  symbol_scope = global_type_unql_symbol_table.find(GET_INDEX_NODE(dn->scpe))->second;
2601  }
2602  else if(fd)
2603  {
2604  if(fd->scpe && fd->static_flag)
2605  {
2606  symbol_scope = "#F:" + STR(GET_INDEX_NODE(fd->scpe));
2607  }
2608  else
2609  {
2610  symbol_scope = "#F";
2611  }
2612  }
2613  else
2614  {
2615  symbol_scope = "";
2616  }
2617  return false;
2618 }
2619 
2620 bool tree_manager::check_for_type(const tree_nodeRef& tn, const tree_managerRef& TM, std::string& symbol_name,
2621  std::string& symbol_scope,
2622  const CustomUnorderedMapUnstable<std::string, unsigned int>& global_type_symbol_table,
2623  unsigned int DEBUG_PARAMETER(node_id))
2624 {
2625  PRINT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Checking for type " + STR(node_id));
2626  auto* type = GetPointer<type_node>(tn);
2627  symbol_name = symbol_scope = "";
2628  if(!type || !type->name)
2629  {
2630  return true;
2631  }
2632  if(type->scpe and ((GET_NODE(type->scpe)->get_kind() == function_decl_K)))
2633  {
2634  return true;
2635  }
2636  const auto quals = type->qual;
2637  std::string type_name;
2638  THROW_ASSERT(GET_NODE(type->name), "wrong");
2639  if(GET_NODE(type->name)->get_kind() == identifier_node_K)
2640  {
2641  type_name = GetPointer<identifier_node>(GET_NODE(type->name))->strg;
2642  }
2643  else
2644  {
2645  type_name = tree_helper::get_type_name(TM, GET_INDEX_NODE(type->name));
2646  }
2647  if(type->name and (GET_NODE(type->name)->get_kind() == type_decl_K || type->unql))
2648  {
2650  {
2651  symbol_name = tree_helper::return_qualifier_prefix(quals) + type_name;
2652  }
2653  else if(type->unql)
2654  {
2655  symbol_name = type_name + "#unqualified";
2656  }
2657  else
2658  {
2659  symbol_name = type_name;
2660  }
2661  }
2662  else if(type->name and tn->get_kind() == record_type_K)
2663  {
2664  symbol_name = "struct " + type_name;
2665  }
2666  else if(type->name and tn->get_kind() == union_type_K)
2667  {
2668  symbol_name = "union " + type_name;
2669  }
2670  else if(type->name and tn->get_kind() == enumeral_type_K)
2671  {
2672  symbol_name = "enum " + type_name;
2673  }
2674  else if(type->name)
2675  {
2676  symbol_name = type_name;
2677  }
2678  else
2679  {
2680  return true;
2681  }
2682 
2683  return global_type_symbol_table.find(symbol_name) != global_type_symbol_table.end();
2684 }
2685 
2686 unsigned int tree_manager::find_identifier_nodeID(const std::string& str) const
2687 {
2688  auto it = identifiers_unique_table.find(str);
2689  if(it == identifiers_unique_table.end())
2690  {
2691  return 0;
2692  }
2693  else
2694  {
2695  return it->second;
2696  }
2697 }
2698 
2699 void tree_manager::add_identifier_node(unsigned int nodeID, const bool& ASSERT_PARAMETER(op))
2700 {
2701  THROW_ASSERT(op, "improper use of add_identifier_node");
2703 }
2704 
2706 {
2708  std::map<unsigned int, tree_nodeRef>::const_iterator beg, end;
2709  for(beg = function_decl_nodes.begin(), end = function_decl_nodes.end(); beg != end; ++beg)
2710  {
2711  functions.insert(beg->first);
2712  }
2713  return functions;
2714 }
2715 
2717 {
2718  if(next_vers == 0)
2719  {
2720  for(const auto& ti : tree_nodes)
2721  {
2722  if(ti.second)
2723  {
2724  tree_nodeRef tn = ti.second;
2725  if(tn->get_kind() == ssa_name_K)
2726  {
2727  auto* sn = GetPointer<ssa_name>(tn);
2728  if(sn->vers > next_vers)
2729  {
2730  next_vers = sn->vers;
2731  }
2732  }
2733  }
2734  }
2735  }
2737  return ++next_vers;
2738 }
2739 
2741 {
2742  added_goto++;
2743 }
2744 
2745 unsigned int tree_manager::get_added_goto() const
2746 {
2747  return added_goto;
2748 }
2749 
2751 {
2753 }
2754 
2756 {
2757  return removed_pointer_plus;
2758 }
2759 
2761 {
2763 }
2764 
2766 {
2767  return removable_pointer_plus;
2768 }
2769 
2771 {
2773 }
2774 
2776 {
2777  return unremoved_pointer_plus;
2778 }
2779 
2781 {
2782  const auto key = std::make_pair(val, type->index);
2783  const auto unique_cst = unique_cst_map.find(key);
2784  if(unique_cst != unique_cst_map.end())
2785  {
2786  return unique_cst->second;
2787  }
2788 
2789  const auto cst_nid = new_tree_node_id();
2790  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
2791  IR_schema[TOK(TOK_TYPE)] = STR(type->index);
2792  if(tree_helper::IsRealType(type))
2793  {
2794  IR_schema[TOK(TOK_VALR)] = val;
2795  IR_schema[TOK(TOK_VALX)] = val;
2796  create_tree_node(cst_nid, real_cst_K, IR_schema);
2797  }
2798  else
2799  {
2800  IR_schema[TOK(TOK_VALUE)] = val;
2801  create_tree_node(cst_nid, integer_cst_K, IR_schema);
2802  }
2803  const auto cost_node = GetTreeReindex(cst_nid);
2804  unique_cst_map[key] = cost_node;
2805  return cost_node;
2806 }
2807 
2809 {
2810  const auto bitsize = tree_helper::Size(type);
2811  if(tree_helper::IsSignedIntegerType(type) && ((value >> (bitsize - 1)) & 1))
2812  {
2813  value |= integer_cst_t(-1) << bitsize;
2814  THROW_ASSERT(value < 0, "");
2815  }
2816  else
2817  {
2818  value &= (integer_cst_t(1) << bitsize) - 1;
2819  }
2820  return create_unique_const(STR(value), type);
2821 }
2822 
2824 {
2825  std::stringstream ssX;
2826 #if HAVE_HEXFLOAT
2827  ssX << std::hexfloat << value;
2828 #else
2829  {
2830  char buffer[256];
2831  sprintf(buffer, "%La", value);
2832  ssX << buffer;
2833  }
2834 #endif
2835 
2836  return create_unique_const(ssX.str(), type);
2837 }
2838 
2840 {
2841  return Param->isOption(OPT_input_format) &&
2842  (Param->getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_CPP ||
2843  Param->getOption<Parameters_FileFormat>(OPT_input_format) == Parameters_FileFormat::FF_LLVM_CPP);
2844 }
2845 
2847 {
2848  if(fd->name)
2849  {
2850  tree_nodeRef id_name = GET_NODE(fd->name);
2851  std::string simple_name;
2852  if(id_name->get_kind() == identifier_node_K)
2853  {
2854  auto* in = GetPointer<identifier_node>(id_name);
2855  if(!in->operator_flag)
2856  {
2857  simple_name = in->strg;
2858  }
2859  if(!simple_name.empty())
2860  {
2861  if(Param->isOption(OPT_top_functions_names))
2862  {
2863  const auto top_functions_names = Param->getOption<std::list<std::string>>(OPT_top_functions_names);
2864  for(const auto& top_function_name : top_functions_names)
2865  {
2866  if(simple_name == top_function_name)
2867  {
2868  return true;
2869  }
2870  }
2871  }
2872  if(Param->isOption(OPT_top_design_name))
2873  {
2874  const auto top_rtldesign_function = Param->getOption<std::string>(OPT_top_design_name);
2875  if(simple_name == top_rtldesign_function)
2876  {
2877  return true;
2878  }
2879  }
2880  }
2881  }
2882  }
2883  return false;
2884 }
2885 
2886 bool tree_manager::check_ssa_uses(unsigned int fun_id) const
2887 {
2888  tree_nodeRef fd_node = get_tree_node_const(fun_id);
2889  auto* fd = GetPointer<function_decl>(fd_node);
2890  auto* sl = GetPointer<statement_list>(GET_NODE(fd->body));
2891 
2892  for(const auto& bb : sl->list_of_bloc)
2893  {
2894  std::list<tree_nodeRef> whole_list = bb.second->CGetStmtList();
2895  for(auto& phi : bb.second->CGetPhiList())
2896  {
2897  whole_list.push_back(phi);
2898  }
2899  for(auto& statement_node : whole_list)
2900  {
2901  auto orig_string = statement_node->ToString();
2902  TreeNodeMap<size_t> ssas = tree_helper::ComputeSsaUses(statement_node);
2903  for(auto& ssa : ssas)
2904  {
2905  tree_nodeRef tn = GET_NODE(ssa.first);
2906  if(tn->get_kind() == ssa_name_K)
2907  {
2908  auto* sn = GetPointer<ssa_name>(tn);
2909  bool found = false;
2910  for(auto& use : sn->CGetUseStmts())
2911  {
2912  const TreeNodeMap<size_t>& used_ssa = tree_helper::ComputeSsaUses(use.first);
2913  if(used_ssa.find(tn) == used_ssa.end())
2914  {
2915  return false;
2916  }
2917  if(GET_INDEX_CONST_NODE(use.first) == GET_INDEX_CONST_NODE(statement_node))
2918  {
2919  found = true;
2920  }
2921  }
2922  if(!found)
2923  {
2924  std::cerr << "stmt: " << orig_string << " var: " << sn->ToString() << std::endl;
2925  for(auto& stmt : sn->CGetUseStmts())
2926  {
2927  std::cerr << "stmt referred: " << GET_INDEX_CONST_NODE(stmt.first) << std::endl;
2928  }
2929  return false;
2930  }
2931  }
2932  else
2933  {
2934  THROW_ERROR("unexpected node");
2935  }
2936  }
2937  }
2938  }
2939  return true;
2940 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
tree_nodeRef create_unique_const(const std::string &val, const tree_nodeConstRef &type)
void increment_unremoved_pointer_plus()
Increment the number of not removed pointer plus.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void * top(node_stack *head)
Definition: tree.c:75
unsigned int next_vers
Next version number for ssa variables.
File containing functions and utilities to support the printing of debug messagges.
unsigned int get_removed_pointer_plus() const
Return the number of removed pointer plus.
void add_parallel_loop()
increment the number a parallel loop
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define STOK(token)
Macro used to convert a token symbol into the corresponding string.
const ParameterConstRef Param
Set of parameters.
std::string ToString() const
Print this node as string in gimple format.
void increment_removable_pointer_plus()
Increment the number of removable pointer plus.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
const CustomUnorderedSet< unsigned int > GetAllFunctions() const
Returns all the functions in the tree_manager.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void ReplaceTreeNode(const tree_nodeRef &stmt, const tree_nodeRef &old_node, const tree_nodeRef &new_node)
Replace the occurrences of tree node old_node with new_node in statement identified by tn...
static std::string bambu_ir_info
The version of the frontend compiler.
tree_nodeRef name
name field contains an identifier_node used to represent a name.
Definition: tree_node.hpp:883
struct definition of the function_decl tree node.
Definition: tree_node.hpp:2759
unsigned int get_removable_pointer_plus() const
Return the number of not removed pointer plus.
unsigned int last_node_id
last node_id used
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
Definition: tree_node.cpp:120
tree_nodeRef mngl
mngl field contains the name of the object as the assembler will see it.
Definition: tree_node.hpp:890
unsigned int get_next_available_tree_node_id() const
return the next available tree node id.
tree node factory.
exceptions managed by PandA
void AddTreeNode(const unsigned int i, const tree_nodeRef &curr)
Add to the tree manager the current node.
unsigned int get_unremoved_pointer_plus() const
Return the number of not removed pointer plus.
A simple interface to token object of the raw files.
#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
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMapUnstable
Definition: custom_map.hpp:156
unsigned int get_next_vers()
Return the next unused version number for ssa variables.
Data structure describing a basic block at tree level.
This class is used to perform the re-index of all tree nodes.
void create_tree_node(const unsigned int node_id, const tree_nodeRef &tn)
tree_node visitors
unsigned int added_goto
the number of added goto
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
std::string include_name
include_name is a filename string, this can be the location of a reference, if no definition has been...
Definition: tree_node.hpp:839
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
bool builtin_flag
flag true when the function is a builtin
Definition: tree_node.hpp:2853
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.
void RecursiveReplaceTreeNode(tree_nodeRef &tn, const tree_nodeRef old_node, const tree_nodeRef &new_node, const tree_nodeRef &stmt, bool definition)
Replace the occurrences of tree node old_node with new_node in statement identified by tn...
Auxiliary methods for manipulating string.
int key[32]
Definition: aes.h:67
tree_manager(const ParameterConstRef &Param)
This is the constructor of the tree_manager which initializes the vector of functions.
tree node finder.
static bool HasToBeDeclared(const tree_managerConstRef &TM, const tree_nodeConstRef &type)
Return true if the type has to be declared.
unsigned int function_index_mngl(const std::string &function_name) const
Return the index of a function given its mangled name.
const tree_nodeRef get_tree_node_const(unsigned int i) const
Return the reference to the i-th tree_node Constant version of get_tree_node.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
#define STOK2(token)
Macro used to convert an int token symbol into the corresponding string.
#define ASSERT_PARAMETER(parameter)
Definition: utility.hpp:96
unsigned int function_index(const std::string &function_name) const
Return the index of a function given its name.
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
bool starts_with(const std::string &str, const std::string &pattern)
bool is_top_function(const function_decl *fd) const
is_top_function checks if a function is one of the application top functions.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
std::set< Key, Compare, Alloc > OrderedSetStd
Definition: custom_set.hpp:59
APInt integer_cst_t
Definition: panda_types.hpp:47
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
unsigned int find(enum kind tree_node_type, const std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
if there exist return the node id of a tree node compatible with the tree_node_schema and of type tre...
#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
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
tree_nodeRef CreateUniqueRealCst(long double value, const tree_nodeConstRef &type)
memoization of integer constants
int debug_level
The debug level.
void add_function(unsigned int index, tree_nodeRef curr)
Add to the function_decl_nodes the current node.
CustomUnorderedMapUnstable< std::string, unsigned int > identifiers_unique_table
this table stores all identifier_nodes with their nodeID.
unsigned int n_pl
the number of parallel loops
decl_node
Definition: tree_node.cpp:163
bool check_ssa_uses(unsigned int fun_id) const
check_ssa_uses check if the uses of a ssa are correct
void erase_usage_info(const tree_nodeRef &tn, const tree_nodeRef &stmt)
Erase the information about variable usage (remove stmt from use_stmts attribute) in ssa variables re...
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Definition: tree_node.hpp:146
void create_tree_node(const unsigned int node_id, enum kind tree_node_type, std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
Factory method.
void increment_removed_pointer_plus()
Increment the number of removed pointer plus.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
#define index(x, y)
Definition: Keccak.c:74
static std::string return_qualifier_prefix(const TreeVocabularyTokenTypes_TokenEnum quals)
return the prefix given a qualifier
kind
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
bool check(const tree_nodeRef &t)
tree_node visitors
unsigned long get_function_decl_node_n() const
Return the number of function_decl_node.
bool check_for_decl(const tree_nodeRef &tn, const tree_managerRef &TM, std::string &symbol_name, std::string &symbol_scope, unsigned int node_id, const CustomUnorderedMap< unsigned int, std::string > &global_type_unql_symbol_table)
check for decl_node and return true if not suitable for symbol table or otherwise its symbol_name and...
unsigned int get_implementation_node(unsigned int decl_node) const
Return the index of function_decl node that implements the declaration node.
void add_goto()
Increment the number of added gotos.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
Classes specification of the tree_node data structures.
unsigned int unremoved_pointer_plus
the number of unremoved pointer_plus
void merge_tree_managers(const tree_managerRef &source_tree_manager)
merge two tree manager: this with TM_source
This file collects some utility functions and macros.
tree node merger classess.
#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
bool static_flag
static_flag is true if function has been defined (macro TREE_STATIC)
Definition: tree_node.hpp:2864
refcount< tree_manager > tree_managerRef
void collapse_into(const unsigned int &funID, CustomUnorderedMapUnstable< unsigned int, unsigned int > &stmt_to_bloc, const tree_nodeRef &tn, CustomUnorderedSet< unsigned int > &removed_nodes, const application_managerRef AppM)
Collapse operations chains into the examinated node.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
std::map< unsigned int, tree_nodeRef > function_decl_nodes
Variable containing set of function_declaration with their index node.
bool is_CPP() const
is_CPP return true in case we have at least one CPP source code
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
Definition: APInt.hpp:53
null deleter
Definition: refcount.hpp:51
#define GET_FUNCTION_DEBUG_LEVEL(parameters)
Macro returning the debug_level of a function.
Definition: utility.hpp:107
Definition: tree.c:10
#define BUILTIN_SRCP
std::map< _Key, _Tp, _Compare, _Alloc > OrderedMapStd
Definition: custom_map.hpp:60
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 create_tree_node(const unsigned int node_id, enum kind)
tree_node visitors
unsigned int find_identifier_nodeID(const std::string &str) const
Return the nodeID of the identifier_node representing string str.
OrderedMapStd< unsigned int, tree_nodeRef > tree_nodes
Variable containing set of tree_nodes.
bool is_tree_node(unsigned int i) const
Return true if there exists a tree node associated with the given id, false otherwise.
unsigned int get_n_pl() const
return the number of parallel loops
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
char str[25]
Definition: fixedptc.c:8
Parameters_FileFormat
File formats.
Definition: Parameter.hpp:261
unsigned int collapse_into_counter
Index of current call of collapse_into_counter.
tree node writer.
void insert_usage_info(const tree_nodeRef &tn, const tree_nodeRef &stmt)
Insert the information about variable usage (insert stmt in use_stmts attribute) in ssa variables rec...
#define DEBUG_PARAMETER(parameter)
macro used to solve problem of parameters used only in not-release
Definition: utility.hpp:91
#define DEBUG_LEVEL_PARANOIC
paranoid level debugging print is performed.
unsigned int get_added_goto() const
Return the number of added gotos.
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
static std::string get_type_name(const tree_managerConstRef &TM, const unsigned int index)
Return name of the type.
tree node writer.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
unsigned counter[N_THREADS]
Definition: data.c:3
void print(std::ostream &os) const
Function that prints the class tree_manager.
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
CustomUnorderedMapUnstable< std::string, unsigned int > find_cache
cache for tree_manager::find
bool check_for_type(const tree_nodeRef &tn, const tree_managerRef &TM, std::string &symbol_name, std::string &symbol_scope, const CustomUnorderedMapUnstable< std::string, unsigned int > &global_type_symbol_table, unsigned int node_id)
check for type and return true if not suitable for symbol table or otherwise its symbol_name and symb...
void add_identifier_node(unsigned int nodeID, const std::string &str)
Add an identifier_node to the corresponding unique table.
static void ComputeSsaUses(const tree_nodeRef &, TreeNodeMap< size_t > &uses)
recursively compute the references to the ssa_name variables used in a statement
tree_nodeRef scpe
scope declaration
Definition: tree_node.hpp:910
tree_nodeRef GetFunction(const std::string &function_name) const
Return the index of a function given its name.
std::string cxa_demangle(const std::string &input)
unsigned int find_sc_main_node() const
Determine the index node of "sc_main" function in tree_node vector.
struct definition of the declaration node structures.
Definition: tree_node.hpp:877
#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.
CustomUnorderedMap< std::pair< std::string, unsigned int >, tree_nodeRef > unique_cst_map
unsigned int removable_pointer_plus
the number of removable pointer_plus
unsigned int removed_pointer_plus
the number of removed pointer_plus
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
int sl
Definition: adpcm.c:105
void PrintGimple(std::ostream &os, const bool use_uid) const
Function that prints the bodies of function in gimple format.
#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
Implementation of the wrapper to Gcc for C sources.

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