PandA-2024.02
tree_manipulation.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 "tree_manipulation.hpp"
47 
48 #include "Parameter.hpp"
49 #include "application_manager.hpp"
50 #include "call_graph_manager.hpp"
51 #include "dbgPrintHelper.hpp"
52 #include "exceptions.hpp"
53 #include "ext_tree_node.hpp"
54 #include "math_function.hpp"
55 #include "string_manipulation.hpp"
56 #include "token_interface.hpp"
57 #include "tree_basic_block.hpp"
58 #include "tree_helper.hpp"
59 #include "tree_manager.hpp"
60 #include "tree_node.hpp"
61 #include "tree_node_dup.hpp"
62 #include "tree_reindex.hpp"
63 
64 #include <boost/range/adaptor/reversed.hpp>
65 
66 #include <algorithm>
67 #include <iostream>
68 
70 
71 #define TREE_NOT_YET_IMPLEMENTED(token) THROW_ERROR(std::string("field not yet supported ") + STOK(token))
72 
75  const application_managerRef _AppM)
76  : TreeM(_TreeM),
77  AppM(_AppM),
78  reuse(_parameters->IsParameter("reuse_gimple") ? _parameters->GetParameter<bool>("reuse_gimple") : true),
79  parameters(_parameters),
80  debug_level(_parameters->get_class_debug_level(GET_CLASS(*this)))
81 {
82 }
83 
84 tree_manipulation::tree_manipulation(const tree_managerRef& _TreeM, const ParameterConstRef& _parameters, bool _reuse,
85  const application_managerRef _AppM)
86  : TreeM(_TreeM),
87  AppM(_AppM),
88  reuse(_reuse),
89  parameters(_parameters),
90  debug_level(_parameters->get_class_debug_level(GET_CLASS(*this)))
91 {
92 }
93 
96 
98 
102  const std::string& srcp, kind operation_kind) const
103 {
105  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
106  THROW_ASSERT(op->get_kind() == tree_reindex_K, "Operator node is not a tree reindex");
107  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
108 
110  switch(operation_kind)
111  {
113  {
114  break;
115  }
116 
117  case binfo_K:
118  case block_K:
119  case call_expr_K:
120  case aggr_init_expr_K:
121  case case_label_expr_K:
122  case constructor_K:
123  case identifier_node_K:
124  case ssa_name_K:
125  case statement_list_K:
126  case target_expr_K:
127  case target_mem_ref_K:
128  case target_mem_ref461_K:
129  case tree_list_K:
130  case tree_vec_K:
131  case error_mark_K:
132  case lut_expr_K:
134  case CASE_CPP_NODES:
135  case CASE_CST_NODES:
136  case CASE_DECL_NODES:
137  case CASE_FAKE_NODES:
138  case CASE_GIMPLE_NODES:
139  case CASE_PRAGMA_NODES:
142  case CASE_TYPE_NODES:
143  default:
144  THROW_ERROR("The operation given is not a unary expression");
145  }
146 
148  switch(GET_CONST_NODE(type)->get_kind())
149  {
150  case array_type_K:
151  case boolean_type_K:
152  case CharType_K:
153  case nullptr_type_K:
154  case type_pack_expansion_K:
155  case complex_type_K:
156  case enumeral_type_K:
157  case function_type_K:
158  case integer_type_K:
159  case lang_type_K:
160  case method_type_K:
161  case offset_type_K:
162  case pointer_type_K:
163  case qual_union_type_K:
164  case real_type_K:
165  case record_type_K:
166  case reference_type_K:
167  case set_type_K:
168  case template_type_parm_K:
169  case type_argument_pack_K:
170  case typename_type_K:
171  case union_type_K:
172  case vector_type_K:
173  case void_type_K:
174  {
175  break;
176  }
177  case binfo_K:
178  case block_K:
179  case call_expr_K:
180  case aggr_init_expr_K:
181  case case_label_expr_K:
182  case constructor_K:
183  case identifier_node_K:
184  case ssa_name_K:
185  case statement_list_K:
186  case target_expr_K:
187  case target_mem_ref_K:
188  case target_mem_ref461_K:
189  case tree_list_K:
190  case tree_vec_K:
191  case error_mark_K:
192  case lut_expr_K:
194  case CASE_CPP_NODES:
195  case CASE_CST_NODES:
196  case CASE_DECL_NODES:
197  case CASE_FAKE_NODES:
198  case CASE_GIMPLE_NODES:
199  case CASE_PRAGMA_NODES:
203  default:
204  THROW_ERROR(std::string("Type node not supported (") + STR(GET_INDEX_CONST_NODE(type)) + std::string("): ") +
205  GET_CONST_NODE(type)->get_kind_text());
206  }
207 
208  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
209  unsigned int node_nid = this->TreeM->new_tree_node_id();
210 
211  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
212  IR_schema[TOK(TOK_OP)] = STR(GET_INDEX_CONST_NODE(op));
213  IR_schema[TOK(TOK_SRCP)] = srcp;
214 
215  this->TreeM->create_tree_node(node_nid, operation_kind, IR_schema);
216  tree_nodeRef return_tree_reindex = TreeM->GetTreeReindex(node_nid);
218  "Created node " + STR(GET_INDEX_CONST_NODE(return_tree_reindex)) + " (" +
219  GET_NODE(return_tree_reindex)->get_kind_text() + ")");
220 
221  return return_tree_reindex;
222 }
223 
227  const tree_nodeRef& op1, const std::string& srcp,
228  kind operation_kind) const
229 {
231  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
232  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Operator 0 node is not a tree reindex");
233  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Operator 1 node is not a tree reindex");
234  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
235 
237  switch(operation_kind)
238  {
240  {
241  break;
242  }
243  case binfo_K:
244  case block_K:
245  case call_expr_K:
246  case aggr_init_expr_K:
247  case case_label_expr_K:
248  case constructor_K:
249  case identifier_node_K:
250  case ssa_name_K:
251  case statement_list_K:
252  case target_expr_K:
253  case target_mem_ref_K:
254  case target_mem_ref461_K:
255  case tree_list_K:
256  case tree_vec_K:
257  case error_mark_K:
258  case lut_expr_K:
259  case CASE_CPP_NODES:
260  case CASE_CST_NODES:
261  case CASE_DECL_NODES:
262  case CASE_FAKE_NODES:
263  case CASE_GIMPLE_NODES:
264  case CASE_PRAGMA_NODES:
267  case CASE_TYPE_NODES:
269  default:
270  THROW_ERROR("The operation given is not a binary expression");
271  }
272 
274  switch(GET_CONST_NODE(type)->get_kind())
275  {
276  case array_type_K:
277  case boolean_type_K:
278  case CharType_K:
279  case nullptr_type_K:
280  case type_pack_expansion_K:
281  case complex_type_K:
282  case enumeral_type_K:
283  case function_type_K:
284  case integer_type_K:
285  case lang_type_K:
286  case method_type_K:
287  case offset_type_K:
288  case pointer_type_K:
289  case qual_union_type_K:
290  case real_type_K:
291  case record_type_K:
292  case reference_type_K:
293  case set_type_K:
294  case template_type_parm_K:
295  case typename_type_K:
296  case type_argument_pack_K:
297  case union_type_K:
298  case vector_type_K:
299  case void_type_K:
300  {
301  break;
302  }
303  case binfo_K:
304  case block_K:
305  case call_expr_K:
306  case aggr_init_expr_K:
307  case case_label_expr_K:
308  case constructor_K:
309  case identifier_node_K:
310  case ssa_name_K:
311  case statement_list_K:
312  case target_expr_K:
313  case target_mem_ref_K:
314  case target_mem_ref461_K:
315  case tree_list_K:
316  case tree_vec_K:
317  case error_mark_K:
318  case lut_expr_K:
320  case CASE_CPP_NODES:
321  case CASE_CST_NODES:
322  case CASE_DECL_NODES:
323  case CASE_FAKE_NODES:
324  case CASE_GIMPLE_NODES:
325  case CASE_PRAGMA_NODES:
329  default:
330  THROW_ERROR(std::string("Type node not supported (") + STR(GET_INDEX_CONST_NODE(type)) + std::string("): ") +
331  GET_CONST_NODE(type)->get_kind_text());
332  }
333 
334  if(operation_kind == eq_expr_K || operation_kind == ne_expr_K || operation_kind == lt_expr_K ||
335  operation_kind == le_expr_K || operation_kind == gt_expr_K || operation_kind == ge_expr_K ||
336  operation_kind == ltgt_expr_K || operation_kind == truth_and_expr_K || operation_kind == truth_andif_expr_K ||
337  operation_kind == truth_or_expr_K || operation_kind == truth_orif_expr_K || operation_kind == truth_xor_expr_K)
338  {
341  "");
342  }
343 
344  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
345  unsigned int node_nid = this->TreeM->new_tree_node_id();
346 
347  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
348  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
349  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
350  IR_schema[TOK(TOK_SRCP)] = srcp;
351 
352  this->TreeM->create_tree_node(node_nid, operation_kind, IR_schema);
353  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
355  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
356  ")");
357 
358  return node_ref;
359 }
360 
364  const tree_nodeRef& op1, const tree_nodeRef& op2,
365  const std::string& srcp, kind operation_kind) const
366 {
368  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type is not a tree reindex");
369  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Operand 0 is not a tree reindex");
370  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Operand 1 is not a tree reindex");
371  THROW_ASSERT(op2->get_kind() == tree_reindex_K, "Operand 3 is not a tree reindex");
372  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
373 
375  switch(operation_kind)
376  {
378  {
379  break;
380  }
381  case binfo_K:
382  case block_K:
383  case call_expr_K:
384  case aggr_init_expr_K:
385  case case_label_expr_K:
386  case constructor_K:
387  case identifier_node_K:
388  case ssa_name_K:
389  case statement_list_K:
390  case target_expr_K:
391  case target_mem_ref_K:
392  case target_mem_ref461_K:
393  case tree_list_K:
394  case tree_vec_K:
395  case error_mark_K:
396  case lut_expr_K:
398  case CASE_CPP_NODES:
399  case CASE_CST_NODES:
400  case CASE_DECL_NODES:
401  case CASE_FAKE_NODES:
402  case CASE_GIMPLE_NODES:
403  case CASE_PRAGMA_NODES:
405  case CASE_TYPE_NODES:
407  default:
408  THROW_ERROR("The operation given is not a ternary expression");
409  }
410 
412  switch(GET_CONST_NODE(type)->get_kind())
413  {
414  case array_type_K:
415  case boolean_type_K:
416  case CharType_K:
417  case nullptr_type_K:
418  case type_pack_expansion_K:
419  case complex_type_K:
420  case enumeral_type_K:
421  case function_type_K:
422  case integer_type_K:
423  case lang_type_K:
424  case method_type_K:
425  case offset_type_K:
426  case pointer_type_K:
427  case qual_union_type_K:
428  case real_type_K:
429  case record_type_K:
430  case reference_type_K:
431  case set_type_K:
432  case template_type_parm_K:
433  case typename_type_K:
434  case type_argument_pack_K:
435  case union_type_K:
436  case vector_type_K:
437  case void_type_K:
438  {
439  break;
440  }
441  case binfo_K:
442  case block_K:
443  case call_expr_K:
444  case aggr_init_expr_K:
445  case case_label_expr_K:
446  case constructor_K:
447  case identifier_node_K:
448  case ssa_name_K:
449  case statement_list_K:
450  case target_expr_K:
451  case target_mem_ref_K:
452  case target_mem_ref461_K:
453  case tree_list_K:
454  case tree_vec_K:
455  case error_mark_K:
456  case lut_expr_K:
458  case CASE_CPP_NODES:
459  case CASE_CST_NODES:
460  case CASE_DECL_NODES:
461  case CASE_FAKE_NODES:
462  case CASE_GIMPLE_NODES:
463  case CASE_PRAGMA_NODES:
467  default:
468  THROW_ERROR(std::string("Type node not supported (") + STR(GET_INDEX_CONST_NODE(type)) + std::string("): ") +
469  GET_CONST_NODE(type)->get_kind_text());
470  }
471 
472  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
473  unsigned int node_nid = this->TreeM->new_tree_node_id();
474 
476  if(operation_kind == cond_expr_K)
477  {
480  "unexpected pattern (<" + STR(tree_helper::Size(tree_helper::CGetType(op1))) + ">" +
481  STR(tree_helper::CGetType(op1)) + " != <" + STR(tree_helper::Size(type)) + ">" +
482  GET_CONST_NODE(type)->ToString() + ")");
485  "unexpected pattern (<" + STR(tree_helper::Size(tree_helper::CGetType(op2))) + ">" +
486  STR(tree_helper::CGetType(op2)) + " != <" + STR(tree_helper::Size(type)) + ">" +
487  GET_CONST_NODE(type)->ToString() + ")");
488  }
489  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
490  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
491  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
492  IR_schema[TOK(TOK_OP2)] = STR(GET_INDEX_CONST_NODE(op2));
493  IR_schema[TOK(TOK_SRCP)] = srcp;
494 
495  this->TreeM->create_tree_node(node_nid, operation_kind, IR_schema);
496  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
498  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
499  ")");
500 
501  return node_ref;
502 }
503 
507  const tree_nodeRef& op1, const tree_nodeRef& op2,
508  const tree_nodeRef& op3, const std::string& srcp,
509  kind operation_kind) const
510 {
512  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
513  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Operand 0 node is not a tree reindex");
514  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Operand 1 node is not a tree reindex");
515  THROW_ASSERT(op2->get_kind() == tree_reindex_K, "Operand 2 node is not a tree reindex");
516  THROW_ASSERT(op3->get_kind() == tree_reindex_K, "Operand 3 node is not a tree reindex");
517  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
518 
520  switch(operation_kind)
521  {
523  {
524  break;
525  }
526  case binfo_K:
527  case block_K:
528  case call_expr_K:
529  case aggr_init_expr_K:
530  case case_label_expr_K:
531  case constructor_K:
532  case identifier_node_K:
533  case ssa_name_K:
534  case statement_list_K:
535  case target_expr_K:
536  case target_mem_ref_K:
537  case target_mem_ref461_K:
538  case tree_list_K:
539  case tree_vec_K:
540  case error_mark_K:
541  case lut_expr_K:
543  case CASE_CPP_NODES:
544  case CASE_CST_NODES:
545  case CASE_DECL_NODES:
546  case CASE_FAKE_NODES:
547  case CASE_GIMPLE_NODES:
548  case CASE_PRAGMA_NODES:
550  case CASE_TYPE_NODES:
552  default:
553  THROW_ERROR("The operation given is not a quaternary expression");
554  }
555 
556  switch(GET_CONST_NODE(type)->get_kind())
557  {
558  case array_type_K:
559  case boolean_type_K:
560  case CharType_K:
561  case nullptr_type_K:
562  case type_pack_expansion_K:
563  case complex_type_K:
564  case enumeral_type_K:
565  case function_type_K:
566  case integer_type_K:
567  case lang_type_K:
568  case method_type_K:
569  case offset_type_K:
570  case pointer_type_K:
571  case qual_union_type_K:
572  case real_type_K:
573  case record_type_K:
574  case reference_type_K:
575  case set_type_K:
576  case template_type_parm_K:
577  case typename_type_K:
578  case type_argument_pack_K:
579  case union_type_K:
580  case vector_type_K:
581  case void_type_K:
582  {
583  break;
584  }
585  case binfo_K:
586  case block_K:
587  case call_expr_K:
588  case aggr_init_expr_K:
589  case case_label_expr_K:
590  case constructor_K:
591  case identifier_node_K:
592  case ssa_name_K:
593  case statement_list_K:
594  case target_expr_K:
595  case target_mem_ref_K:
596  case target_mem_ref461_K:
597  case tree_list_K:
598  case tree_vec_K:
599  case error_mark_K:
600  case lut_expr_K:
602  case CASE_CPP_NODES:
603  case CASE_CST_NODES:
604  case CASE_DECL_NODES:
605  case CASE_FAKE_NODES:
606  case CASE_GIMPLE_NODES:
607  case CASE_PRAGMA_NODES:
611  default:
612  THROW_ERROR(std::string("Type node not supported (") + STR(GET_INDEX_CONST_NODE(type)) + std::string("): ") +
613  GET_CONST_NODE(type)->get_kind_text());
614  }
615 
616  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
617  unsigned int node_nid = this->TreeM->new_tree_node_id();
618 
619  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
620  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
621  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
622  IR_schema[TOK(TOK_OP2)] = STR(GET_INDEX_CONST_NODE(op2));
623  IR_schema[TOK(TOK_OP3)] = STR(GET_INDEX_CONST_NODE(op3));
624  IR_schema[TOK(TOK_SRCP)] = srcp;
625 
626  this->TreeM->create_tree_node(node_nid, operation_kind, IR_schema);
627  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
629  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
630  ")");
631 
632  return node_ref;
633 }
634 
636  const tree_nodeRef& op1, const tree_nodeRef& op2,
637  const tree_nodeRef& op3, const tree_nodeRef& op4,
638  const tree_nodeRef& op5, const tree_nodeRef& op6,
639  const tree_nodeRef& op7, const tree_nodeRef& op8,
640  const std::string& srcp) const
641 {
642  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
643  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Operand 0 node is not a tree reindex");
644  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Operand 1 node is not a tree reindex");
645  THROW_ASSERT(!op2 || op2->get_kind() == tree_reindex_K, "Operand 2 node is not a tree reindex");
646  THROW_ASSERT(!op3 || op3->get_kind() == tree_reindex_K, "Operand 3 node is not a tree reindex");
647  THROW_ASSERT(!op4 || op4->get_kind() == tree_reindex_K, "Operand 4 node is not a tree reindex");
648  THROW_ASSERT(!op5 || op5->get_kind() == tree_reindex_K, "Operand 5 node is not a tree reindex");
649  THROW_ASSERT(!op6 || op6->get_kind() == tree_reindex_K, "Operand 6 node is not a tree reindex");
650  THROW_ASSERT(!op7 || op7->get_kind() == tree_reindex_K, "Operand 7 node is not a tree reindex");
651  THROW_ASSERT(!op8 || op8->get_kind() == tree_reindex_K, "Operand 8 node is not a tree reindex");
652  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
653  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
654  unsigned int node_nid = this->TreeM->new_tree_node_id();
655 
656  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
657  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
658  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
659  if(op2)
660  {
661  IR_schema[TOK(TOK_OP2)] = STR(GET_INDEX_CONST_NODE(op2));
662  }
663  if(op3)
664  {
665  IR_schema[TOK(TOK_OP3)] = STR(GET_INDEX_CONST_NODE(op3));
666  }
667  if(op4)
668  {
669  IR_schema[TOK(TOK_OP4)] = STR(GET_INDEX_CONST_NODE(op4));
670  }
671  if(op5)
672  {
673  IR_schema[TOK(TOK_OP5)] = STR(GET_INDEX_CONST_NODE(op5));
674  }
675  if(op6)
676  {
677  IR_schema[TOK(TOK_OP6)] = STR(GET_INDEX_CONST_NODE(op6));
678  }
679  if(op7)
680  {
681  IR_schema[TOK(TOK_OP7)] = STR(GET_INDEX_CONST_NODE(op7));
682  }
683  if(op8)
684  {
685  IR_schema[TOK(TOK_OP8)] = STR(GET_INDEX_CONST_NODE(op8));
686  }
687  IR_schema[TOK(TOK_SRCP)] = srcp;
688 
689  this->TreeM->create_tree_node(node_nid, lut_expr_K, IR_schema);
690  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
692  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
693  ")");
694 
695  return node_ref;
696 }
697 
699  const std::string& srcp) const
700 {
701  auto boolType = GetBooleanType();
702  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Operand 0 node is not a tree reindex");
703  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Operand 1 node is not a tree reindex");
704  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
705  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
706  unsigned int node_nid = this->TreeM->new_tree_node_id();
707 
708  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(boolType));
709  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
710  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
711  IR_schema[TOK(TOK_SRCP)] = srcp;
712 
713  this->TreeM->create_tree_node(node_nid, extract_bit_expr_K, IR_schema);
714  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
716  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
717  ")");
718 
719  return node_ref;
720 }
722 
725  const unsigned int integer_cst_nid) const
726 {
727  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
728 
729  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
730  IR_schema[TOK(TOK_TYPE)] = STR(type->index);
731  IR_schema[TOK(TOK_VALUE)] = STR(value);
732 
733  TreeM->create_tree_node(integer_cst_nid, integer_cst_K, IR_schema);
734  const auto node_ref = TreeM->GetTreeReindex(integer_cst_nid);
735 
737  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
738  ")");
739 
740  return node_ref;
741 }
742 
744 
747 {
748  THROW_ASSERT(!strg.empty(), "It requires a non empty string");
749 
751  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
752  tree_nodeRef node_ref;
753 
754  IR_schema[TOK(TOK_STRG)] = strg;
755  unsigned int node_nid = this->TreeM->find(identifier_node_K, IR_schema);
756 
757  if(!node_nid)
758  {
759  node_nid = this->TreeM->new_tree_node_id();
760  this->TreeM->create_tree_node(node_nid, identifier_node_K, IR_schema);
761  node_ref = TreeM->GetTreeReindex(node_nid);
763  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
764  " " + strg + ")");
765  }
766  else
767  {
768  node_ref = TreeM->GetTreeReindex(node_nid);
770  "Found node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
771  " " + strg + ")");
772  }
773  return node_ref;
774 }
775 
777 
780  const tree_nodeRef& name, const tree_nodeConstRef& type, const tree_nodeRef& scpe, const tree_nodeRef& size,
781  const tree_nodeRef& smt_ann, const tree_nodeRef& init, const std::string& srcp, unsigned int algn, int used,
782  bool artificial_flag, int use_tmpl, bool static_static_flag, bool extern_flag, bool static_flag, bool register_flag,
783  bool readonly_flag, const std::string& bit_values, bool addr_taken, bool addr_not_taken) const
784 {
786  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Node is not a tree reindex");
787  THROW_ASSERT(scpe->get_kind() == tree_reindex_K, "Node is not a tree reindex");
788  THROW_ASSERT(size->get_kind() == tree_reindex_K, "Node is not a tree reindex");
789 
790  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
791 
792  unsigned int node_nid = this->TreeM->new_tree_node_id();
793 
794  unsigned int type_node_nid = GET_INDEX_CONST_NODE(type);
795  unsigned int size_node_nid = GET_INDEX_CONST_NODE(size);
796  unsigned int scpe_node_nid = GET_INDEX_CONST_NODE(scpe);
797 
798  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
799 
800  if(name)
801  {
802  THROW_ASSERT(name->get_kind() == tree_reindex_K, "Node is not a tree reindex");
803  unsigned int name_node_nid = GET_INDEX_CONST_NODE(name);
804  IR_schema[TOK(TOK_NAME)] = STR(name_node_nid);
805  }
806 
807  if(smt_ann)
808  {
809  THROW_ASSERT(smt_ann->get_kind() == tree_reindex_K, "Node is not a tree reindex");
810  unsigned int smt_node_nid = GET_INDEX_CONST_NODE(smt_ann);
811  IR_schema[TOK(TOK_SMT_ANN)] = STR(smt_node_nid);
812  }
813 
814  if(init)
815  {
816  THROW_ASSERT(init->get_kind() == tree_reindex_K, "Node is not a tree reindex");
817  unsigned int init_nid = GET_INDEX_CONST_NODE(init);
818  IR_schema[TOK(TOK_INIT)] = STR(init_nid);
819  }
820 
821  IR_schema[TOK(TOK_TYPE)] = STR(type_node_nid);
822  IR_schema[TOK(TOK_SCPE)] = STR(scpe_node_nid);
823  IR_schema[TOK(TOK_SIZE)] = STR(size_node_nid);
824  IR_schema[TOK(TOK_ALGN)] = STR(algn);
825  IR_schema[TOK(TOK_USED)] = STR(used);
826  IR_schema[TOK(TOK_SRCP)] = srcp;
827  IR_schema[TOK(TOK_USE_TMPL)] = STR(use_tmpl);
828  IR_schema[TOK(TOK_STATIC_STATIC)] = STR(static_static_flag);
829  IR_schema[TOK(TOK_EXTERN)] = STR(extern_flag);
830  IR_schema[TOK(TOK_STATIC)] = STR(static_flag);
831  IR_schema[TOK(TOK_REGISTER)] = STR(register_flag);
832  IR_schema[TOK(TOK_READONLY)] = STR(readonly_flag);
833  IR_schema[TOK(TOK_BIT_VALUES)] = bit_values;
834  IR_schema[TOK(TOK_ADDR_TAKEN)] = STR(addr_taken);
835  IR_schema[TOK(TOK_ADDR_NOT_TAKEN)] = STR(addr_not_taken);
836  IR_schema[TOK(TOK_ARTIFICIAL)] = STR(artificial_flag);
837 
838  this->TreeM->create_tree_node(node_nid, var_decl_K, IR_schema);
839  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
840 
842  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
843  ")");
844 
845  return node_ref;
846 }
847 
849 {
850  tree_nodeRef translation_unit_decl_node;
851  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
852  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
853  unsigned int translation_unit_decl_nid = this->TreeM->find(translation_unit_decl_K, IR_schema);
854  if(!translation_unit_decl_nid)
855  {
856  translation_unit_decl_nid = this->TreeM->new_tree_node_id();
857  this->TreeM->create_tree_node(translation_unit_decl_nid, translation_unit_decl_K, IR_schema);
858  translation_unit_decl_node = TreeM->GetTreeReindex(translation_unit_decl_nid);
860  "Created node " + STR(GET_INDEX_CONST_NODE(translation_unit_decl_node)) + " (" +
861  GET_NODE(translation_unit_decl_node)->get_kind_text() + ")");
862  }
863  else
864  {
865  translation_unit_decl_node = TreeM->GetTreeReindex(translation_unit_decl_nid);
867  "Found node " + STR(GET_INDEX_CONST_NODE(translation_unit_decl_node)) + " (" +
868  GET_NODE(translation_unit_decl_node)->get_kind_text() + ")");
869  }
870  return translation_unit_decl_node;
871 }
872 
875  const tree_nodeRef& scpe, const tree_nodeRef& size,
876  const tree_nodeRef& smt_ann, const tree_nodeRef& init,
877  const std::string& srcp, unsigned int algn,
878  bool artificial_flag) const
879 {
881  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Node is not a tree reindex");
882  THROW_ASSERT(scpe->get_kind() == tree_reindex_K, "Node is not a tree reindex");
883  THROW_ASSERT(size->get_kind() == tree_reindex_K, "Node is not a tree reindex");
884 
885  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
886 
887  unsigned int node_nid = this->TreeM->new_tree_node_id();
888 
889  unsigned int type_node_nid = GET_INDEX_CONST_NODE(type);
890  unsigned int size_node_nid = GET_INDEX_CONST_NODE(size);
891  unsigned int scpe_node_nid = GET_INDEX_CONST_NODE(scpe);
892 
893  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
894 
895  IR_schema[TOK(TOK_TYPE)] = STR(type_node_nid);
896  IR_schema[TOK(TOK_SCPE)] = STR(scpe_node_nid);
897  IR_schema[TOK(TOK_SIZE)] = STR(size_node_nid);
898  IR_schema[TOK(TOK_ALGN)] = STR(algn);
899  IR_schema[TOK(TOK_SRCP)] = srcp;
900  IR_schema[TOK(TOK_ARTIFICIAL)] = STR(artificial_flag);
901 
902  if(smt_ann)
903  {
904  THROW_ASSERT(smt_ann->get_kind() == tree_reindex_K, "Node is not a tree reindex");
905  unsigned int smt_node_nid = GET_INDEX_CONST_NODE(smt_ann);
906  IR_schema[TOK(TOK_SMT_ANN)] = STR(smt_node_nid);
907  }
908 
909  if(name)
910  {
911  THROW_ASSERT(name->get_kind() == tree_reindex_K, "Node is not a tree reindex");
912  unsigned int name_node_nid = GET_INDEX_CONST_NODE(name);
913  IR_schema[TOK(TOK_NAME)] = STR(name_node_nid);
914  }
915 
916  if(init)
917  {
918  THROW_ASSERT(init->get_kind() == tree_reindex_K, "Node is not a tree reindex");
919  unsigned int init_nid = GET_INDEX_CONST_NODE(init);
920  IR_schema[TOK(TOK_INIT)] = STR(init_nid);
921  }
922 
923  this->TreeM->create_tree_node(node_nid, result_decl_K, IR_schema);
924  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
925 
927  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
928  ")");
929 
930  return node_ref;
931 }
932 
935  const tree_nodeRef& scpe, const tree_nodeConstRef& argt,
936  const tree_nodeRef& smt_ann, const tree_nodeRef& init,
937  const std::string& srcp, int used, bool register_flag,
938  bool readonly_flag) const
939 {
941  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Node is not a tree reindex");
942  THROW_ASSERT(scpe->get_kind() == tree_reindex_K, "Node is not a tree reindex");
943 
944  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
945 
946  const auto tn = GetPointer<const type_node>(GET_CONST_NODE(type));
947 
948  const auto type_node_nid = GET_INDEX_CONST_NODE(type);
949  const auto size_node_nid = GET_INDEX_CONST_NODE(tn->size);
950  const auto scpe_node_nid = GET_INDEX_CONST_NODE(scpe);
951  const auto argt_node_nid = GET_INDEX_CONST_NODE(argt);
952 
953  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
954  IR_schema[TOK(TOK_TYPE)] = STR(type_node_nid);
955  IR_schema[TOK(TOK_SCPE)] = STR(scpe_node_nid);
956  IR_schema[TOK(TOK_SIZE)] = STR(size_node_nid);
957  IR_schema[TOK(TOK_ARGT)] = STR(argt_node_nid);
958  IR_schema[TOK(TOK_ALGN)] = STR(tn->algn);
959  IR_schema[TOK(TOK_USED)] = STR(used);
960  IR_schema[TOK(TOK_SRCP)] = srcp;
961  IR_schema[TOK(TOK_REGISTER)] = STR(register_flag);
962  IR_schema[TOK(TOK_READONLY)] = STR(readonly_flag);
963 
964  if(smt_ann)
965  {
966  THROW_ASSERT(smt_ann->get_kind() == tree_reindex_K, "Node is not a tree reindex");
967  const auto smt_node_nid = GET_INDEX_CONST_NODE(smt_ann);
968  IR_schema[TOK(TOK_SMT_ANN)] = STR(smt_node_nid);
969  }
970 
971  if(name)
972  {
973  THROW_ASSERT(name->get_kind() == tree_reindex_K, "Node is not a tree reindex");
974  const auto name_node_nid = GET_INDEX_CONST_NODE(name);
975  IR_schema[TOK(TOK_NAME)] = STR(name_node_nid);
976  }
977 
978  if(init)
979  {
980  THROW_ASSERT(init->get_kind() == tree_reindex_K, "Node is not a tree reindex");
981  const auto init_nid = GET_INDEX_CONST_NODE(init);
982  IR_schema[TOK(TOK_INIT)] = STR(init_nid);
983  }
984 
985  const auto node_nid = TreeM->new_tree_node_id();
986  TreeM->create_tree_node(node_nid, parm_decl_K, IR_schema);
987  const auto node_ref = TreeM->GetTreeReindex(node_nid);
988 
990  "Created node " + STR(node_nid) + " (" + GET_CONST_NODE(node_ref)->get_kind_text() + ")");
991 
992  return node_ref;
993 }
994 
996 
999 {
1004  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1005  tree_nodeRef void_node;
1006 
1007  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_VOID);
1008  // If a void type already exists, it is not created a new one
1009  unsigned int void_type_nid = this->TreeM->find(void_type_K, IR_schema);
1010 
1011  if(!void_type_nid)
1012  {
1013  void_type_nid = this->TreeM->new_tree_node_id();
1014  unsigned int type_decl_nid = this->TreeM->new_tree_node_id();
1015  unsigned int void_identifier_nid = GET_INDEX_CONST_NODE(create_identifier_node("void")); //@63
1016 
1019  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1020  this->TreeM->create_tree_node(void_type_nid, void_type_K, IR_schema);
1021  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Created node " + STR(void_type_nid) + " (void_type)");
1022 
1025  IR_schema.clear();
1026  IR_schema[TOK(TOK_NAME)] = STR(void_identifier_nid);
1027  IR_schema[TOK(TOK_TYPE)] = STR(void_type_nid);
1028  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1029  this->TreeM->create_tree_node(type_decl_nid, type_decl_K, IR_schema);
1030  void_node = TreeM->GetTreeReindex(void_type_nid);
1032  "Created node " + STR(GET_INDEX_CONST_NODE(void_node)) + " (" +
1033  GET_NODE(void_node)->get_kind_text() + " void)");
1034  }
1035  else
1036  {
1037  void_node = TreeM->GetTreeReindex(void_type_nid);
1039  "Found node " + STR(GET_INDEX_CONST_NODE(void_node)) + " (" +
1040  GET_NODE(void_node)->get_kind_text() + " void)");
1041  }
1042 
1043  return void_node;
1044 }
1045 
1048 {
1055  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1056  tree_nodeRef bit_size_node;
1057 
1060  tree_nodeRef bit_size_identifier_node = create_identifier_node("unsigned long long int");
1061  unsigned int bit_size_identifier_nid = GET_INDEX_CONST_NODE(bit_size_identifier_node);
1062 
1065  IR_schema[TOK(TOK_NAME)] = STR(bit_size_identifier_nid);
1066  unsigned int bit_size_type_nid = this->TreeM->find(integer_type_K, IR_schema);
1067 
1069  if(!bit_size_type_nid)
1070  {
1071  bit_size_type_nid = this->TreeM->new_tree_node_id();
1072  unsigned int size_node_nid = this->TreeM->new_tree_node_id();
1073  unsigned int min_node_nid = this->TreeM->new_tree_node_id();
1074  unsigned int max_node_nid = this->TreeM->new_tree_node_id();
1077  IR_schema[TOK(TOK_SIZE)] = STR(size_node_nid);
1078  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_BIT_SIZE);
1079  IR_schema[TOK(TOK_PREC)] = STR(PREC_BIT_SIZE);
1080  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1081  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1082  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1083  this->TreeM->create_tree_node(bit_size_type_nid, integer_type_K, IR_schema);
1084  bit_size_node = TreeM->GetTreeReindex(bit_size_type_nid);
1086  "Created node " + STR(GET_INDEX_CONST_NODE(bit_size_node)) + " (" +
1087  GET_NODE(bit_size_node)->get_kind_text() + " bit_size)");
1088 
1090  CreateIntegerCst(bit_size_node, SIZE_VALUE_BIT_SIZE, size_node_nid);
1091 
1093  CreateIntegerCst(bit_size_node, integer_cst_t(MIN_VALUE_BIT_SIZE), min_node_nid);
1094 
1096  CreateIntegerCst(bit_size_node, integer_cst_t(MAX_VALUE_BIT_SIZE), max_node_nid);
1097  }
1098  else
1099  {
1100  bit_size_node = TreeM->GetTreeReindex(bit_size_type_nid);
1102  "Found node " + STR(GET_INDEX_CONST_NODE(bit_size_node)) + " (" +
1103  GET_NODE(bit_size_node)->get_kind_text() + " bit_size)");
1104  }
1105  return bit_size_node;
1106 }
1107 
1110 {
1111  //@124 identifier_node strg: "sizetype" lngt: 8
1112  //@96 integer_type name: @124 size: @15 algn: 32
1113  // prec: 32 unsigned min : @125
1114  // max : @126
1115 
1122  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1123  tree_nodeRef size_node;
1124 
1125  //@124 identifier_node strg: "sizetype" lngt: 8
1127  tree_nodeRef size_identifier_node = create_identifier_node("unsigned long");
1128  unsigned int size_identifier_nid = GET_INDEX_CONST_NODE(size_identifier_node);
1129 
1130  //@96 integer_type name: @124 size: @15 algn: 32 prec: 32 unsigned min :
1131  //@125 max : @126
1132  IR_schema[TOK(TOK_NAME)] = STR(size_identifier_nid);
1133  unsigned int size_type_nid = this->TreeM->find(integer_type_K, IR_schema);
1134 
1136  if(!size_type_nid)
1137  {
1138  size_type_nid = this->TreeM->new_tree_node_id();
1139  const auto bit_size_node = TreeM->CreateUniqueIntegerCst(SIZE_VALUE_BIT_SIZE, GetBitsizeType());
1140  unsigned int min_node_nid = this->TreeM->new_tree_node_id();
1141  unsigned int max_node_nid = this->TreeM->new_tree_node_id();
1144  IR_schema[TOK(TOK_SIZE)] = STR(bit_size_node->index);
1145  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_BIT_SIZE);
1146  IR_schema[TOK(TOK_PREC)] = STR(PREC_BIT_SIZE);
1147  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1148  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1149  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1150  this->TreeM->create_tree_node(size_type_nid, integer_type_K, IR_schema);
1151  size_node = TreeM->GetTreeReindex(size_type_nid);
1153  "Created node " + STR(GET_INDEX_CONST_NODE(size_node)) + " (" +
1154  GET_NODE(size_node)->get_kind_text() + " bit_size)");
1155 
1157  CreateIntegerCst(size_node, integer_cst_t(MIN_VALUE_BIT_SIZE), min_node_nid);
1158 
1160  CreateIntegerCst(size_node, integer_cst_t(MAX_VALUE_BIT_SIZE), max_node_nid);
1161  }
1162  else
1163  {
1164  size_node = TreeM->GetTreeReindex(size_type_nid);
1166  "Found node " + STR(GET_INDEX_CONST_NODE(size_node)) + " (" +
1167  GET_NODE(size_node)->get_kind_text() + " bit_size)");
1168  }
1169  return size_node;
1170 }
1171 
1174 {
1179 
1181  tree_nodeRef boolean_type_node;
1182 
1183  tree_nodeRef boolean_identifier_node = create_identifier_node("_Bool");
1184  unsigned int boolean_identifier_nid = GET_INDEX_CONST_NODE(boolean_identifier_node);
1185 
1186  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1187 
1189  IR_schema[TOK(TOK_NAME)] = STR(boolean_identifier_nid); //@58
1190  unsigned int type_decl_nid = this->TreeM->find(type_decl_K, IR_schema);
1191 
1193  if(!type_decl_nid)
1194  {
1195  type_decl_nid = this->TreeM->new_tree_node_id();
1196  unsigned int boolean_type_nid = this->TreeM->new_tree_node_id();
1197  const auto size_node = TreeM->CreateUniqueIntegerCst(SIZE_VALUE_BOOL, GetBitsizeType());
1198 
1200  IR_schema[TOK(TOK_TYPE)] = STR(boolean_type_nid); //@48
1201  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1202  this->TreeM->create_tree_node(type_decl_nid, type_decl_K, IR_schema);
1204  "Created node " + STR(type_decl_nid) + " (type_decl boolean)");
1205 
1207  IR_schema.clear();
1208  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid); //@55
1209  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index); //@7
1210  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_BOOLEAN);
1211  this->TreeM->create_tree_node(boolean_type_nid, boolean_type_K, IR_schema);
1212  boolean_type_node = TreeM->GetTreeReindex(boolean_type_nid);
1214  "Created node " + STR(GET_INDEX_CONST_NODE(boolean_type_node)) + " (" +
1215  GET_NODE(boolean_type_node)->get_kind_text() + " boolean)");
1216  }
1217  else
1218  {
1219  IR_schema.clear();
1220  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1221  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_BOOLEAN);
1222 
1223  unsigned int boolean_type_nid = this->TreeM->find(boolean_type_K, IR_schema);
1224 
1225  if(!boolean_type_nid)
1226  {
1227  THROW_ERROR("Something wrong happened!");
1228  }
1229 
1230  boolean_type_node = TreeM->GetTreeReindex(boolean_type_nid);
1232  "Found node " + STR(GET_INDEX_CONST_NODE(boolean_type_node)) + " (" +
1233  GET_NODE(boolean_type_node)->get_kind_text() + " boolean)");
1234  }
1235  return boolean_type_node;
1236 }
1237 
1240 {
1249  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1250  tree_nodeRef integer_type_node;
1251 
1253  tree_nodeRef unsigned_int_identifier_node = create_identifier_node("unsigned int");
1254  unsigned int unsigned_int_identifier_nid = GET_INDEX_CONST_NODE(unsigned_int_identifier_node);
1255 
1258  IR_schema.clear();
1259  IR_schema[TOK(TOK_NAME)] = STR(unsigned_int_identifier_nid);
1260  unsigned int type_decl_nid = this->TreeM->find(type_decl_K, IR_schema);
1261 
1263  if(!type_decl_nid)
1264  {
1265  type_decl_nid = this->TreeM->new_tree_node_id();
1266  unsigned int integer_type_nid = this->TreeM->new_tree_node_id();
1268  unsigned int min_node_nid = this->TreeM->new_tree_node_id();
1269  unsigned int max_node_nid = this->TreeM->new_tree_node_id();
1270 
1273  IR_schema[TOK(TOK_TYPE)] = STR(integer_type_nid); //@8
1274  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1275  this->TreeM->create_tree_node(type_decl_nid, type_decl_K, IR_schema);
1277  "Created node " + STR(type_decl_nid) + " (type_decl unsigned_int)");
1278 
1281  IR_schema.clear();
1282  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1283  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index);
1284  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_UNSIGNED_INT);
1285  IR_schema[TOK(TOK_PREC)] = STR(PREC_UNSIGNED_INT);
1286  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1287  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1288  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1289  this->TreeM->create_tree_node(integer_type_nid, integer_type_K, IR_schema);
1290  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1292  "Created node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1293  GET_NODE(integer_type_node)->get_kind_text() + " unsigned_int)");
1294 
1296  CreateIntegerCst(integer_type_node, MIN_VALUE_UNSIGNED_INT, min_node_nid);
1298  CreateIntegerCst(integer_type_node, MAX_VALUE_UNSIGNED_INT, max_node_nid);
1299  }
1300  else
1301  {
1302  IR_schema.clear();
1303  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1304  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_UNSIGNED_INT);
1305  IR_schema[TOK(TOK_PREC)] = STR(PREC_UNSIGNED_INT);
1306  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1307  unsigned int integer_type_nid = this->TreeM->find(integer_type_K, IR_schema);
1308 
1309  if(!integer_type_nid)
1310  {
1311  THROW_ERROR("Something wrong happened!");
1312  }
1313 
1314  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1316  "Found node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1317  GET_NODE(integer_type_node)->get_kind_text() + " unsigned int)");
1318  }
1319  return integer_type_node;
1320 }
1321 
1323 {
1324  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1325  tree_nodeRef integer_type_node;
1326 
1327  tree_nodeRef unsigned_int_identifier_node = create_identifier_node("unsigned long long int");
1328  unsigned int unsigned_int_identifier_nid = GET_INDEX_CONST_NODE(unsigned_int_identifier_node);
1329 
1330  IR_schema.clear();
1331  IR_schema[TOK(TOK_NAME)] = STR(unsigned_int_identifier_nid);
1332  unsigned int type_decl_nid = this->TreeM->find(type_decl_K, IR_schema);
1333 
1335  if(!type_decl_nid)
1336  {
1337  type_decl_nid = this->TreeM->new_tree_node_id();
1338  unsigned int integer_type_nid = this->TreeM->new_tree_node_id();
1340  unsigned int min_node_nid = this->TreeM->new_tree_node_id();
1341  unsigned int max_node_nid = this->TreeM->new_tree_node_id();
1342 
1343  IR_schema[TOK(TOK_TYPE)] = STR(integer_type_nid); //@8
1344  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1345  this->TreeM->create_tree_node(type_decl_nid, type_decl_K, IR_schema);
1347  "Created node " + STR(type_decl_nid) + " (type_decl unsigned_int)");
1348 
1349  IR_schema.clear();
1350  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1351  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index);
1354  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1355  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1356  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1357  this->TreeM->create_tree_node(integer_type_nid, integer_type_K, IR_schema);
1358  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1360  "Created node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1361  GET_NODE(integer_type_node)->get_kind_text() + " unsigned long long int int)");
1362 
1364  CreateIntegerCst(integer_type_node, integer_cst_t(MIN_VALUE_UNSIGNED_LONG_LONG_INT), min_node_nid);
1366  CreateIntegerCst(integer_type_node, integer_cst_t(MAX_VALUE_UNSIGNED_LONG_LONG_INT), max_node_nid);
1367  }
1368  else
1369  {
1370  IR_schema.clear();
1371  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1374  IR_schema[TOK(TOK_UNSIGNED)] = STR(true);
1375  unsigned int integer_type_nid = this->TreeM->find(integer_type_K, IR_schema);
1376 
1377  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1379  "Found node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1380  GET_NODE(integer_type_node)->get_kind_text() + " unsigned long long int)");
1381  }
1382  return integer_type_node;
1383 }
1384 
1387 {
1396 
1397  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1398  tree_nodeRef integer_type_node;
1399 
1401  tree_nodeRef int_identifier_node = create_identifier_node("int");
1402  unsigned int int_identifier_nid = GET_INDEX_CONST_NODE(int_identifier_node);
1403 
1406  IR_schema.clear();
1407  IR_schema[TOK(TOK_NAME)] = STR(int_identifier_nid);
1408  unsigned int type_decl_nid = this->TreeM->find(type_decl_K, IR_schema);
1409 
1411  if(!type_decl_nid)
1412  {
1413  type_decl_nid = this->TreeM->new_tree_node_id();
1414  unsigned int integer_type_nid = this->TreeM->new_tree_node_id();
1416  const auto size_node = TreeM->CreateUniqueIntegerCst(SIZE_VALUE_INT, GetBitsizeType());
1417  unsigned int min_node_nid = this->TreeM->new_tree_node_id();
1418  unsigned int max_node_nid = this->TreeM->new_tree_node_id();
1419 
1422  IR_schema[TOK(TOK_TYPE)] = STR(integer_type_nid); //@8
1423  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1424  this->TreeM->create_tree_node(type_decl_nid, type_decl_K, IR_schema);
1425 
1426  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Created node " + STR(type_decl_nid) + " (type_decl int)");
1427 
1430  IR_schema.clear();
1431  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1432  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index);
1433  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_INT);
1434  IR_schema[TOK(TOK_PREC)] = STR(PREC_INT);
1435  IR_schema[TOK(TOK_UNSIGNED)] = STR(false);
1436  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1437  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1438  this->TreeM->create_tree_node(integer_type_nid, integer_type_K, IR_schema);
1439  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1441  "Created node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1442  GET_NODE(integer_type_node)->get_kind_text() + " int)");
1443 
1445  CreateIntegerCst(integer_type_node, MIN_VALUE_INT, min_node_nid);
1447  CreateIntegerCst(integer_type_node, MAX_VALUE_INT, max_node_nid);
1448  }
1449  else
1450  {
1451  IR_schema.clear();
1452  IR_schema[TOK(TOK_NAME)] = STR(type_decl_nid);
1453  IR_schema[TOK(TOK_ALGN)] = STR(ALGN_INT);
1454  IR_schema[TOK(TOK_PREC)] = STR(PREC_INT);
1455  IR_schema[TOK(TOK_UNSIGNED)] = STR(false);
1456 
1457  unsigned int integer_type_nid = this->TreeM->find(integer_type_K, IR_schema);
1458 
1459  if(!integer_type_nid)
1460  {
1461  THROW_ERROR("Something wrong happened!");
1462  }
1463 
1464  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1465 
1467  "Found node " + STR(GET_INDEX_CONST_NODE(integer_type_node)) + " (" +
1468  GET_NODE(integer_type_node)->get_kind_text() + " int)");
1469  }
1470  return integer_type_node;
1471 }
1472 
1474 tree_nodeRef tree_manipulation::GetPointerType(const tree_nodeConstRef& ptd, unsigned long long algn) const
1475 {
1479  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1480  IR_schema[TOK(TOK_PTD)] = STR(ptd->index);
1481  auto m64P = parameters->getOption<std::string>(OPT_gcc_m32_mx32).find("-m64") != std::string::npos;
1482  if(!algn)
1483  {
1484  algn = m64P ? ALGN_POINTER_M64 : ALGN_POINTER_M32;
1485  }
1486  IR_schema[TOK(TOK_ALGN)] = STR(algn);
1487 
1488  tree_nodeRef pointer_type_node;
1489 
1490  unsigned int pointer_type_nid = this->TreeM->find(pointer_type_K, IR_schema);
1491 
1492  if(!pointer_type_nid)
1493  {
1494  pointer_type_nid = this->TreeM->new_tree_node_id();
1495  const auto size_node =
1497 
1500  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index);
1501  this->TreeM->create_tree_node(pointer_type_nid, pointer_type_K, IR_schema);
1502  pointer_type_node = TreeM->GetTreeReindex(pointer_type_nid);
1504  "Created node " + STR(pointer_type_nid) + " (pointer_type)");
1505  }
1506  else
1507  {
1508  pointer_type_node = TreeM->GetTreeReindex(pointer_type_nid);
1509  }
1510  return pointer_type_node;
1511 }
1512 
1513 tree_nodeRef tree_manipulation::GetCustomIntegerType(unsigned long long prec, bool unsigned_p) const
1514 {
1515  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1516 
1517  IR_schema[TOK(TOK_ALGN)] = STR(get_aligned_bitsize(prec));
1518  IR_schema[TOK(TOK_PREC)] = STR(prec);
1519  IR_schema[TOK(TOK_UNSIGNED)] = STR(unsigned_p);
1520 
1521  tree_nodeRef integer_type_node;
1522  unsigned int integer_type_nid = TreeM->find(integer_type_K, IR_schema);
1523 
1524  if(!integer_type_nid)
1525  {
1526  integer_type_nid = TreeM->new_tree_node_id();
1527  const auto size_node = TreeM->CreateUniqueIntegerCst(integer_cst_t(prec), GetBitsizeType());
1528  const auto min_node_nid = TreeM->new_tree_node_id();
1529  const auto max_node_nid = TreeM->new_tree_node_id();
1530 
1531  IR_schema[TOK(TOK_SIZE)] = STR(GET_INDEX_CONST_NODE(size_node));
1532  IR_schema[TOK(TOK_MIN)] = STR(min_node_nid);
1533  IR_schema[TOK(TOK_MAX)] = STR(max_node_nid);
1534  TreeM->create_tree_node(integer_type_nid, integer_type_K, IR_schema);
1535  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1536 
1537  CreateIntegerCst(integer_type_node, unsigned_p ? 0 : (integer_cst_t(-1) << (prec - 1)), min_node_nid);
1538  CreateIntegerCst(integer_type_node, (integer_cst_t(1) << (prec - !unsigned_p)) - 1, max_node_nid);
1539  }
1540  else
1541  {
1542  integer_type_node = TreeM->GetTreeReindex(integer_type_nid);
1543  }
1544 
1545  if(auto it_name = GetPointerS<integer_type>(GET_NODE(integer_type_node))->name)
1546  {
1547  if(GET_NODE(it_name)->get_kind() == identifier_node_K)
1548  {
1549  auto in = GetPointerS<identifier_node>(GET_NODE(it_name));
1550  if(in->strg == "sizetype")
1551  {
1552  in->strg = "unsigned long";
1553  }
1554  if(in->strg == "ssizetype")
1555  {
1556  in->strg = "long";
1557  }
1558  else if(in->strg == "bitsizetype")
1559  {
1560  in->strg = "unsigned long long int";
1561  }
1562  else if(in->strg == "bit_size_type")
1563  {
1564  in->strg = "unsigned long long int";
1565  }
1566  }
1567  }
1568  return integer_type_node;
1569 }
1570 
1572  const std::vector<tree_nodeConstRef>& argsT) const
1573 {
1574  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1575  const auto size_node = TreeM->CreateUniqueIntegerCst(SIZE_VALUE_FUNCTION, GetBitsizeType());
1576 
1577  unsigned int tree_list_node_nid = 0, prev_tree_list_node_nid = 0;
1578  for(const auto& par_type : boost::adaptors::reverse(argsT))
1579  {
1580  tree_list_node_nid = this->TreeM->new_tree_node_id();
1581  IR_schema[TOK(TOK_VALU)] = STR(GET_INDEX_CONST_NODE(par_type));
1582  if(prev_tree_list_node_nid)
1583  {
1584  IR_schema[TOK(TOK_CHAN)] = STR(prev_tree_list_node_nid);
1585  }
1586  TreeM->create_tree_node(tree_list_node_nid, tree_list_K, IR_schema);
1587  IR_schema.clear();
1588  prev_tree_list_node_nid = tree_list_node_nid;
1589  }
1590 
1591  auto function_type_id = TreeM->new_tree_node_id();
1592  IR_schema[TOK(TOK_SIZE)] = STR(size_node->index);
1593  IR_schema[TOK(TOK_ALGN)] = STR(8);
1594  IR_schema[TOK(TOK_RETN)] = STR(GET_INDEX_CONST_NODE(returnType));
1595  if(tree_list_node_nid)
1596  {
1597  IR_schema[TOK(TOK_PRMS)] = STR(tree_list_node_nid);
1598  }
1599  TreeM->create_tree_node(function_type_id, function_type_K, IR_schema);
1600  return TreeM->GetTreeReindex(function_type_id);
1601 }
1602 
1604 
1606 
1609  const tree_nodeConstRef& min, const tree_nodeConstRef& max,
1610  bool volatile_flag, bool virtual_flag) const
1611 {
1613  "-->Creating ssa starting from var " + (var ? var->ToString() : "") + " and type " +
1614  (type ? type->ToString() : ""));
1615  THROW_ASSERT(!var || var->get_kind() == tree_reindex_K, "Var node is not a tree reindex");
1616  THROW_ASSERT(!min || min->get_kind() == tree_reindex_K, "min node is not a tree reindex");
1617  THROW_ASSERT(!max || max->get_kind() == tree_reindex_K, "max node is not a tree reindex");
1618 
1619  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1620  unsigned int vers = this->TreeM->get_next_vers();
1621  unsigned int node_nid = this->TreeM->new_tree_node_id();
1622 
1623  if(type)
1624  {
1625  IR_schema[TOK(TOK_TYPE)] = STR(type->index);
1626  }
1627  if(var)
1628  {
1629  THROW_ASSERT(GET_CONST_NODE(var)->get_kind() == var_decl_K or GET_CONST_NODE(var)->get_kind() == parm_decl_K,
1630  GET_CONST_NODE(var)->get_kind_text());
1631  IR_schema[TOK(TOK_VAR)] = STR(var->index);
1632  }
1633  if(min)
1634  {
1635  IR_schema[TOK(TOK_MIN)] = STR(min->index);
1636  }
1637  if(max)
1638  {
1639  IR_schema[TOK(TOK_MAX)] = STR(max->index);
1640  }
1641  IR_schema[TOK(TOK_VERS)] = STR(vers);
1642  IR_schema[TOK(TOK_VOLATILE)] = STR(volatile_flag);
1643  IR_schema[TOK(TOK_VIRTUAL)] = STR(virtual_flag);
1644 
1645  this->TreeM->create_tree_node(node_nid, ssa_name_K, IR_schema);
1646  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
1647  const tree_nodeRef curr_node = GET_NODE(node_ref);
1648 
1649  // TODO: use statements list of just created ssa_name should be always empty, shouldn't it?
1650  if(var && GetPointerS<ssa_name>(curr_node)->CGetUseStmts().empty())
1651  {
1652  THROW_ASSERT(GET_CONST_NODE(var)->get_kind() == var_decl_K || GET_CONST_NODE(var)->get_kind() == parm_decl_K,
1653  GET_CONST_NODE(var)->get_kind_text());
1654  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_nop_IR_schema;
1655  if(GET_CONST_NODE(var)->get_kind() == var_decl_K && GetPointer<const var_decl>(GET_CONST_NODE(var))->scpe)
1656  {
1657  gimple_nop_IR_schema[TOK(TOK_SCPE)] =
1658  STR(GET_INDEX_CONST_NODE(GetPointerS<const var_decl>(GET_CONST_NODE(var))->scpe));
1659  }
1660  if(GET_CONST_NODE(var)->get_kind() == parm_decl_K)
1661  {
1662  gimple_nop_IR_schema[TOK(TOK_SCPE)] =
1663  STR(GET_INDEX_CONST_NODE(GetPointerS<const parm_decl>(GET_CONST_NODE(var))->scpe));
1664  }
1665  gimple_nop_IR_schema[TOK(TOK_SRCP)] = GetPointer<const srcp>(GET_CONST_NODE(var))->include_name + ":" +
1666  STR(GetPointer<const srcp>(GET_CONST_NODE(var))->line_number) + ":" +
1667  STR(GetPointer<const srcp>(GET_CONST_NODE(var))->column_number);
1668  unsigned int gimple_nop_node_id = this->TreeM->new_tree_node_id();
1669  this->TreeM->create_tree_node(gimple_nop_node_id, gimple_nop_K, gimple_nop_IR_schema);
1670  tree_nodeRef gimple_nop_node_ref = TreeM->GetTreeReindex(gimple_nop_node_id);
1671  GetPointerS<ssa_name>(curr_node)->SetDefStmt(gimple_nop_node_ref);
1672  }
1673 
1674  const auto sn = GetPointerS<ssa_name>(curr_node);
1675  sn->virtual_flag = virtual_flag;
1676  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Created " + node_ref->ToString());
1677 
1678  return node_ref;
1679 }
1680 
1682 
1685  unsigned int function_decl_nid, const std::string& srcp) const
1686 {
1687  THROW_ASSERT(op0->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1688  THROW_ASSERT(op1->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1689  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
1690 
1691  unsigned int node_nid = this->TreeM->new_tree_node_id();
1692  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1693  IR_schema[TOK(TOK_SRCP)] = srcp;
1694  IR_schema[TOK(TOK_OP0)] = STR(GET_INDEX_CONST_NODE(op0));
1695  IR_schema[TOK(TOK_OP1)] = STR(GET_INDEX_CONST_NODE(op1));
1696  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
1697  this->TreeM->create_tree_node(node_nid, gimple_assign_K, IR_schema);
1698  tree_nodeRef node_ref = TreeM->GetTreeReindex(node_nid);
1699  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created node " + STR(node_ref));
1700 
1701  THROW_ASSERT(GET_INDEX_CONST_NODE(op0) == 0 || GET_INDEX_CONST_NODE(op1) == 0 ||
1703  "unexpected pattern - " + GET_CONST_NODE(node_ref)->ToString() + " (lhs = <" +
1705  "), rhs = <" + STR(tree_helper::Size(tree_helper::CGetType(op1))) + ">(" +
1706  STR(tree_helper::CGetType(op1)) + "))");
1707 
1708  return node_ref;
1709 }
1710 
1712  const tree_nodeConstRef& max, const tree_nodeRef& op,
1713  unsigned int function_decl_nid, const std::string& srcp) const
1714 {
1715  tree_nodeRef ssa_vd = create_ssa_name(tree_nodeConstRef(), type, min, max);
1716  auto ga = create_gimple_modify_stmt(ssa_vd, op, function_decl_nid, srcp);
1717  GetPointer<ssa_name>(TreeM->GetTreeNode(ssa_vd->index))->SetDefStmt(TreeM->GetTreeReindex(ga->index));
1718  return ga;
1719 }
1720 
1723  const std::vector<tree_nodeRef>& args,
1724  unsigned int function_decl_nid, const std::string& srcp) const
1725 {
1726  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
1727  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ae_IR_schema, gc_IR_schema;
1728 
1729  const auto function_type = tree_helper::CGetType(called_function);
1730 #if HAVE_ASSERTS
1731  const auto formal_count = GetPointer<const function_decl>(GET_CONST_NODE(called_function))->list_of_args.size();
1732  THROW_ASSERT(formal_count == args.size(), "Formal parameters count different from actual parameters count: " +
1733  STR(formal_count) + " != " + STR(args.size()));
1734 #endif
1735  ae_IR_schema[TOK(TOK_OP)] = STR(called_function->index);
1736  ae_IR_schema[TOK(TOK_TYPE)] = STR(GetPointerType(function_type)->index);
1737  ae_IR_schema[TOK(TOK_SRCP)] = srcp;
1738 
1739  std::string args_string;
1740  for(const auto& arg : args)
1741  {
1742  if(!args_string.empty())
1743  {
1744  args_string += "_";
1745  }
1746  args_string += STR(arg->index);
1747  }
1748 
1749  const unsigned int ae_id = TreeM->new_tree_node_id();
1750  TreeM->create_tree_node(ae_id, addr_expr_K, ae_IR_schema);
1751  gc_IR_schema[TOK(TOK_ARG)] = args_string;
1752  gc_IR_schema[TOK(TOK_FN)] = STR(ae_id);
1753  gc_IR_schema[TOK(TOK_TYPE)] = STR(function_type->index);
1754  gc_IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
1755  gc_IR_schema[TOK(TOK_SRCP)] = srcp;
1756  const unsigned int gc_id = TreeM->new_tree_node_id();
1757  TreeM->create_tree_node(gc_id, gimple_call_K, gc_IR_schema);
1758  tree_nodeRef node_ref = TreeM->GetTreeReindex(gc_id);
1759  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created node " + STR(node_ref));
1760  return node_ref;
1761 }
1762 
1764 
1766 tree_nodeRef tree_manipulation::create_gimple_cond(const tree_nodeRef& expr, unsigned int function_decl_nid,
1767  const std::string& srcp) const
1768 {
1769  THROW_ASSERT(expr->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1771  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
1772 
1774  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1775 
1776  unsigned int void_type_nid = GET_INDEX_CONST_NODE(GetVoidType());
1777  unsigned int expr_nid = GET_INDEX_CONST_NODE(expr);
1778  unsigned int gimple_cond_name_nid = this->TreeM->new_tree_node_id();
1779 
1781  IR_schema.clear();
1782  IR_schema[TOK(TOK_TYPE)] = STR(void_type_nid);
1783  IR_schema[TOK(TOK_OP0)] = STR(expr_nid);
1784  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
1785  IR_schema[TOK(TOK_SRCP)] = srcp;
1786  this->TreeM->create_tree_node(gimple_cond_name_nid, gimple_cond_K, IR_schema);
1787  tree_nodeRef node_ref = TreeM->GetTreeReindex(gimple_cond_name_nid);
1789  "Created node " + STR(GET_INDEX_CONST_NODE(node_ref)) + " (" + GET_NODE(node_ref)->get_kind_text() +
1790  ")");
1791 
1792  return node_ref;
1793 }
1794 
1797  unsigned int function_decl_nid, const std::string& srcp) const
1798 {
1799  THROW_ASSERT(!srcp.empty(), "It requires a non empty string");
1800 
1801  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1802  if(type)
1803  {
1804  THROW_ASSERT(type->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1805  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(type));
1806  }
1807  else
1808  {
1809  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_CONST_NODE(GetVoidType()));
1810  }
1811  if(expr)
1812  {
1813  THROW_ASSERT(expr->get_kind() == tree_reindex_K, "Node is not a tree reindex");
1814  IR_schema[TOK(TOK_OP)] = STR(GET_INDEX_CONST_NODE(expr));
1815  }
1816  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
1817  IR_schema[TOK(TOK_SRCP)] = srcp;
1818 
1819  const auto node_nid = TreeM->new_tree_node_id();
1820  TreeM->create_tree_node(node_nid, gimple_return_K, IR_schema);
1821  const auto node_ref = TreeM->GetTreeReindex(node_nid);
1823  "Created node " + STR(node_nid) + " (" + GET_NODE(node_ref)->get_kind_text() + ")");
1824 
1826  return node_ref;
1827 }
1828 
1830 
1834  const std::vector<std::pair<tree_nodeRef, unsigned int>>& list_of_def_edge,
1835  unsigned int function_decl_nid, bool virtual_flag) const
1836 {
1837  auto iterator = list_of_def_edge.begin();
1838  tree_nodeRef ssa_ref = iterator->first;
1839  auto* sn_ref = GetPointer<ssa_name>(GET_NODE(ssa_ref));
1840  THROW_ASSERT(ssa_ref->get_kind() == tree_reindex_K, "ssa_name res is not a tree_reindex node");
1841  for(++iterator; iterator != list_of_def_edge.end(); ++iterator)
1842  {
1843  tree_nodeRef tn = iterator->first;
1844  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "ssa_name res is not a tree_reindex node");
1845  if(!sn_ref && GetPointer<ssa_name>(GET_NODE(tn)))
1846  {
1847  ssa_ref = tn;
1848  sn_ref = GetPointer<ssa_name>(GET_NODE(ssa_ref));
1849  }
1850  }
1851  if(sn_ref)
1852  {
1853  ssa_res = create_ssa_name(sn_ref->var, sn_ref->type, sn_ref->min, sn_ref->max, false, virtual_flag);
1854  }
1855  else
1856  {
1857  const auto ssa_res_type_node = tree_helper::CGetType(list_of_def_edge.begin()->first);
1858  ssa_res = create_ssa_name(tree_nodeRef(), ssa_res_type_node, tree_nodeRef(), tree_nodeRef(), false, virtual_flag);
1859  }
1860 
1861  unsigned int phi_node_nid = this->TreeM->new_tree_node_id();
1862 
1863  // Create the gimple_phi
1864  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
1865  IR_schema[TOK(TOK_RES)] = STR(GET_INDEX_CONST_NODE(ssa_res));
1866  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
1867  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1868  this->TreeM->create_tree_node(phi_node_nid, gimple_phi_K, IR_schema);
1869  tree_nodeRef phi_stmt = TreeM->GetTreeReindex(phi_node_nid);
1870 
1871  auto* pn = GetPointer<gimple_phi>(GET_NODE(phi_stmt));
1872  pn->virtual_flag = virtual_flag;
1873 
1874  for(const auto& def_edge : list_of_def_edge)
1875  {
1877  tree_helper::Size(tree_helper::CGetType(def_edge.first)),
1878  "unexpected condition - lhs = <" + STR(tree_helper::Size(tree_helper::CGetType(ssa_res))) + ">" +
1879  STR(tree_helper::CGetType(ssa_res)) + ", rhs = <" +
1880  STR(tree_helper::Size(tree_helper::CGetType(def_edge.first))) + ">" +
1881  STR(tree_helper::CGetType(def_edge.first)));
1882  pn->AddDefEdge(TreeM, def_edge);
1883  }
1884 
1886  "Created node " + STR(GET_INDEX_CONST_NODE(phi_stmt)) + " (" + GET_NODE(phi_stmt)->get_kind_text() +
1887  ")");
1888 
1889  return phi_stmt;
1890 }
1891 
1893 
1895 blocRef tree_manipulation::create_basic_block(std::map<unsigned int, blocRef>& list_of_bloc,
1896  std::vector<unsigned int> predecessors,
1897  std::vector<unsigned int> successors, std::vector<tree_nodeRef> stmt,
1898  unsigned int number, unsigned int true_edge, unsigned int false_edge,
1899  std::vector<tree_nodeRef> phi) const
1900 {
1902  blocRef new_bb = blocRef(new bloc(number));
1903  // Add in the list of block the new bb
1904  list_of_bloc[new_bb->number] = new_bb;
1905 
1906  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Created BB " + STR(new_bb->number));
1907 
1909  new_bb->true_edge = true_edge;
1911  new_bb->false_edge = false_edge;
1912 
1914  " True Edge: " + STR(new_bb->true_edge) + " False Edge: " + STR(new_bb->false_edge));
1915 
1917  for(auto pred : predecessors)
1918  {
1919  new_bb->list_of_pred.push_back(pred);
1920  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " Added predecessor " + STR(pred));
1921  }
1923  for(auto suc : successors)
1924  {
1925  new_bb->list_of_succ.push_back(suc);
1926  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " Added successor " + STR(suc));
1927  }
1929  for(const auto& tn : stmt)
1930  {
1931  new_bb->PushBack(tn, AppM);
1933  " Added statement " + STR(GET_INDEX_CONST_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() +
1934  ").");
1935  }
1937  for(const auto& tn : phi)
1938  {
1939  new_bb->AddPhi(tn);
1941  " Added phi " + STR(GET_INDEX_CONST_NODE(tn)) + " (" + GET_NODE(tn)->get_kind_text() + ").");
1942  }
1943 
1944  return new_bb;
1945 }
1946 
1948 void tree_manipulation::bb_add_stmts(blocRef& bb, const std::vector<tree_nodeRef>& stmts) const
1949 {
1951  for(const auto& tn : stmts)
1952  {
1953  bb_add_stmt(bb, tn);
1954  }
1955 }
1956 
1958 void tree_manipulation::bb_add_stmt(blocRef& bb, const tree_nodeRef& stmt) const
1959 {
1961  bb->PushBack(stmt, AppM);
1963  " Added statement " + STR(GET_INDEX_CONST_NODE(stmt)) + " (" + GET_NODE(stmt)->get_kind_text() +
1964  ").");
1965 }
1966 
1968 void tree_manipulation::bb_add_successors(blocRef& bb, const std::vector<unsigned int>& successors) const
1969 {
1970  for(auto successor : successors)
1971  {
1972  bb_add_successor(bb, successor);
1973  }
1974 }
1975 
1977 void tree_manipulation::bb_add_successor(blocRef& bb, const unsigned int& successor) const
1978 {
1979  bb->add_succ(successor);
1980 }
1981 
1983 void tree_manipulation::bb_add_predecessors(blocRef& bb, const std::vector<unsigned int>& predecessors) const
1984 {
1985  for(auto predecessor : predecessors)
1986  {
1987  bb_add_predecessor(bb, predecessor);
1988  }
1989 }
1990 
1992 void tree_manipulation::bb_add_predecessor(blocRef& bb, const unsigned int& predecessor) const
1993 {
1994  bb->add_pred(predecessor);
1995 }
1996 
1998 void tree_manipulation::bb_remove_successors(blocRef& bb, const std::vector<unsigned int>& successors) const
1999 {
2000  for(auto successor : successors)
2001  {
2002  bb_remove_successor(bb, successor);
2003  }
2004 }
2005 
2007 void tree_manipulation::bb_remove_successor(blocRef& bb, const unsigned int& successor) const
2008 {
2009  std::vector<unsigned int>& list_of_succ = bb->list_of_succ;
2010  auto iterator_stmt = std::find(list_of_succ.begin(), list_of_succ.end(), successor);
2011  THROW_ASSERT(iterator_stmt != list_of_succ.end(), "Successor not found!");
2013  "Successor " + STR(*iterator_stmt) + " is going to be removed");
2014  list_of_succ.erase(iterator_stmt);
2015 }
2016 
2018 void tree_manipulation::bb_remove_predecessors(blocRef& bb, const std::vector<unsigned int>& predecessors) const
2019 {
2020  for(auto predecessor : predecessors)
2021  {
2022  bb_remove_predecessor(bb, predecessor);
2023  }
2024 }
2025 
2027 void tree_manipulation::bb_remove_predecessor(blocRef& bb, const unsigned int& predecessor) const
2028 {
2029  std::vector<unsigned int>& list_of_pred = bb->list_of_pred;
2030  auto iterator_stmt = std::find(list_of_pred.begin(), list_of_pred.end(), predecessor);
2031  THROW_ASSERT(iterator_stmt != list_of_pred.end(), "Successor not found!");
2033  "Successor " + STR(*iterator_stmt) + " is going to be removed");
2034  list_of_pred.erase(iterator_stmt);
2035 }
2036 
2039 {
2040  bb->list_of_pred.erase(bb->list_of_pred.begin(), bb->list_of_pred.end());
2041 }
2042 
2045 {
2046  bb->list_of_succ.erase(bb->list_of_succ.begin(), bb->list_of_succ.end());
2047 }
2048 
2050 void tree_manipulation::bb_set_false_edge(blocRef& bb, const unsigned int& false_edge_index) const
2051 {
2052  bb->false_edge = false_edge_index;
2053 }
2054 
2056 void tree_manipulation::bb_set_true_edge(blocRef& bb, const unsigned int& true_edge_index) const
2057 {
2058  bb->true_edge = true_edge_index;
2059 }
2060 
2061 void tree_manipulation::create_label(const blocRef& block, const unsigned int function_decl_nid) const
2062 {
2063  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
2066  if(!block->CGetStmtList().empty())
2067  {
2068  tree_nodeRef first_stmt = block->CGetStmtList().front();
2069  auto* le = GetPointer<gimple_label>(GET_NODE(first_stmt));
2070  if(le)
2071  {
2072  THROW_ASSERT(le->op && GET_NODE(le->op)->get_kind() == label_decl_K,
2073  "label expression pattern not yet supported");
2074  auto* ld = GetPointer<label_decl>(GET_NODE(le->op));
2075  THROW_ASSERT(!ld->name, "gimple_label already added");
2077  //@436 identifier_node strg: "GOTOLABEL0" lngt: 10
2078  unsigned int label_decl_name_nid_test;
2079  do
2080  {
2081  IR_schema[TOK(TOK_STRG)] = "GOTOLABEL" + STR(goto_label_unique_id++);
2082  label_decl_name_nid_test = TreeM->find(identifier_node_K, IR_schema);
2083  } while(label_decl_name_nid_test);
2084  unsigned int label_decl_name_nid = TreeM->new_tree_node_id(); // 436
2085  TreeM->create_tree_node(label_decl_name_nid, identifier_node_K, IR_schema);
2086  IR_schema.clear();
2087  tree_nodeRef tr_new_label_name = TreeM->GetTreeReindex(label_decl_name_nid);
2088  ld->name = tr_new_label_name;
2089  ld->artificial_flag = false;
2090  return;
2091  }
2092  }
2093 
2094  //@27 identifier_node strg: "void" lngt: 4
2095  IR_schema[TOK(TOK_STRG)] = "void";
2096  unsigned int type_decl_name_nid = TreeM->find(identifier_node_K, IR_schema);
2097  if(!type_decl_name_nid)
2098  {
2099  type_decl_name_nid = TreeM->new_tree_node_id(); // 27
2100  TreeM->create_tree_node(type_decl_name_nid, identifier_node_K, IR_schema);
2101  }
2102  IR_schema.clear();
2103 
2104  //@436 identifier_node strg: "GOTOLABEL0" lngt: 10
2105  unsigned int label_decl_name_nid_test;
2106  do
2107  {
2108  IR_schema[TOK(TOK_STRG)] = "GOTOLABEL" + STR(goto_label_unique_id++);
2109  label_decl_name_nid_test = TreeM->find(identifier_node_K, IR_schema);
2110  } while(label_decl_name_nid_test);
2111  unsigned int label_decl_name_nid = TreeM->new_tree_node_id(); // 436
2112  TreeM->create_tree_node(label_decl_name_nid, identifier_node_K, IR_schema);
2113  IR_schema.clear();
2114 
2115  //@23 type_decl name: @27 type: @15 srcp: "<built-in>":0
2116  IR_schema[TOK(TOK_NAME)] = STR(type_decl_name_nid);
2117  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2118  unsigned int label_void_type_name_nid = TreeM->find(type_decl_K, IR_schema);
2119  unsigned int label_type_nid;
2120  if(!label_void_type_name_nid)
2121  {
2122  label_void_type_name_nid = TreeM->new_tree_node_id(); // 23
2123  label_type_nid = TreeM->new_tree_node_id(); // 15
2124  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2125  TreeM->create_tree_node(label_void_type_name_nid, type_decl_K, IR_schema);
2126  IR_schema.clear();
2127  //@15 void_type name: @23 algn: 8
2128  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2129  IR_schema[TOK(TOK_ALGN)] = STR(8);
2130  TreeM->create_tree_node(label_type_nid, void_type_K, IR_schema);
2131  }
2132  else
2133  {
2134  IR_schema.clear();
2135  //@15 void_type name: @23 algn: 8
2136  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2137  IR_schema[TOK(TOK_ALGN)] = STR(8);
2138  label_type_nid = TreeM->find(void_type_K, IR_schema);
2139  if(!label_type_nid)
2140  {
2141  label_type_nid = TreeM->new_tree_node_id(); // 15
2142  label_void_type_name_nid = TreeM->new_tree_node_id(); // 23
2143  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2144  TreeM->create_tree_node(label_type_nid, void_type_K, IR_schema);
2145  IR_schema.clear();
2146  IR_schema[TOK(TOK_NAME)] = STR(type_decl_name_nid);
2147  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2148  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2149  TreeM->create_tree_node(label_void_type_name_nid, type_decl_K, IR_schema);
2150  }
2151  else
2152  {
2153  THROW_ASSERT(label_void_type_name_nid ==
2154  GET_INDEX_CONST_NODE(GetPointer<void_type>(TreeM->get_tree_node_const(label_type_nid))->name),
2155  "somenthing of wrong happen");
2156  }
2157  }
2158  IR_schema.clear();
2159 
2160  //@77 gimple_label type: @15 srcp: "<built-in>":0 op :
2161  //@242
2162  unsigned int label_expr_nid = TreeM->new_tree_node_id(); // 77
2163 
2164  unsigned int label_decl_nid = TreeM->new_tree_node_id(); // 242
2165  IR_schema[TOK(TOK_OP)] = STR(label_decl_nid);
2166  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
2167  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2168  TreeM->create_tree_node(label_expr_nid, gimple_label_K, IR_schema);
2169  IR_schema.clear();
2170 
2171  //@242 label_decl name: @436 type: @15 scpe: @32 srcp:
2172  //"<built-in>":0 UID : 5
2173  IR_schema[TOK(TOK_NAME)] = STR(label_decl_name_nid);
2174  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2175  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
2176  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2177  TreeM->create_tree_node(label_decl_nid, label_decl_K, IR_schema);
2178  IR_schema.clear();
2179 
2180  tree_nodeRef tr_new_stmt = TreeM->GetTreeReindex(label_expr_nid);
2181  GetPointer<gimple_node>(GET_NODE(tr_new_stmt))->bb_index = block->number;
2182  block->PushFront(tr_new_stmt, AppM);
2183 #if 0
2184  static int nid = 0;
2185  std::string raw_file_name = STR(nid++) + "create_label.raw";
2186  std::ofstream raw_file(raw_file_name.c_str());
2187  raw_file << TreeM;
2188  raw_file.close();
2189 #endif
2190 }
2191 
2192 void tree_manipulation::create_goto(const blocRef& block, const unsigned int function_decl_nid,
2193  const unsigned int label_expr_nid) const
2194 {
2195  TreeM->add_goto();
2197  auto* le = GetPointer<gimple_label>(TreeM->get_tree_node_const(label_expr_nid));
2198  THROW_ASSERT(le, "expected a label expression");
2199  unsigned int label_decl_nid = GET_INDEX_CONST_NODE(le->op);
2201  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
2202 
2203  //@27 identifier_node strg: "void" lngt: 4
2204  IR_schema[TOK(TOK_STRG)] = "void";
2205  unsigned int type_decl_name_nid = TreeM->find(identifier_node_K, IR_schema);
2206  if(!type_decl_name_nid)
2207  {
2208  type_decl_name_nid = TreeM->new_tree_node_id(); // 27
2209  TreeM->create_tree_node(type_decl_name_nid, identifier_node_K, IR_schema);
2210  }
2211  IR_schema.clear();
2212 
2213  //@23 type_decl name: @27 type: @15 srcp: "<built-in>":0
2214  IR_schema[TOK(TOK_NAME)] = STR(type_decl_name_nid);
2215  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2216  unsigned int label_void_type_name_nid = TreeM->find(type_decl_K, IR_schema);
2217  unsigned int label_type_nid;
2218  if(!label_void_type_name_nid)
2219  {
2220  label_void_type_name_nid = TreeM->new_tree_node_id(); // 23
2221  label_type_nid = TreeM->new_tree_node_id(); // 15
2222  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2223  TreeM->create_tree_node(label_void_type_name_nid, type_decl_K, IR_schema);
2224  IR_schema.clear();
2225  //@15 void_type name: @23 algn: 8
2226  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2227  IR_schema[TOK(TOK_ALGN)] = STR(8);
2228  TreeM->create_tree_node(label_type_nid, void_type_K, IR_schema);
2229  }
2230  else
2231  {
2232  IR_schema.clear();
2233  //@15 void_type name: @23 algn: 8
2234  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2235  IR_schema[TOK(TOK_ALGN)] = STR(8);
2236  label_type_nid = TreeM->find(void_type_K, IR_schema);
2237  if(!label_type_nid)
2238  {
2239  label_type_nid = TreeM->new_tree_node_id(); // 15
2240  label_void_type_name_nid = TreeM->new_tree_node_id(); // 23
2241  IR_schema[TOK(TOK_NAME)] = STR(label_void_type_name_nid);
2242  TreeM->create_tree_node(label_type_nid, void_type_K, IR_schema);
2243  IR_schema.clear();
2244  IR_schema[TOK(TOK_NAME)] = STR(type_decl_name_nid);
2245  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2246  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2247  TreeM->create_tree_node(label_void_type_name_nid, type_decl_K, IR_schema);
2248  }
2249  else
2250  {
2251  THROW_ASSERT(label_void_type_name_nid ==
2252  GET_INDEX_CONST_NODE(GetPointer<void_type>(TreeM->get_tree_node_const(label_type_nid))->name),
2253  "somenthing of wrong happen");
2254  }
2255  }
2256  IR_schema.clear();
2257 
2258  //@60 gimple_goto type: @15 srcp: "<built-in>":6 op :
2259  //@242
2260  unsigned int goto_expr_nid = TreeM->new_tree_node_id(); // 60
2261  IR_schema[TOK(TOK_TYPE)] = STR(label_type_nid);
2262  IR_schema[TOK(TOK_OP)] = STR(label_decl_nid);
2263  IR_schema[TOK(TOK_SCPE)] = STR(function_decl_nid);
2264  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2265  TreeM->create_tree_node(goto_expr_nid, gimple_goto_K, IR_schema);
2266  IR_schema.clear();
2267 
2268  tree_nodeRef tr_new_stmt = TreeM->GetTreeReindex(goto_expr_nid);
2269  GetPointer<gimple_node>(GET_NODE(tr_new_stmt))->bb_index = block->number;
2270  block->PushBack(tr_new_stmt, AppM);
2271 }
2272 
2273 tree_nodeRef tree_manipulation::create_function_decl(const std::string& function_name, const tree_nodeRef& scpe,
2274  const std::vector<tree_nodeConstRef>& argsT,
2275  const tree_nodeConstRef& returnType, const std::string& srcp,
2276  bool with_body) const
2277 {
2278  const auto fd_node = TreeM->GetFunction(function_name);
2279  if(fd_node)
2280  {
2281  return fd_node;
2282  }
2283  const auto function_decl_id = TreeM->new_tree_node_id();
2284 
2285  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
2286 
2287  IR_schema[TOK(TOK_STRG)] = function_name;
2288  unsigned int function_name_id = TreeM->find(identifier_node_K, IR_schema);
2289  if(!function_name_id)
2290  {
2291  function_name_id = TreeM->new_tree_node_id();
2292  TreeM->create_tree_node(function_name_id, identifier_node_K, IR_schema);
2293  }
2294  else
2295  {
2296  THROW_ERROR("identifier in use by someone else");
2297  }
2298  IR_schema.clear();
2299 
2300  const auto function_type = GetFunctionType(returnType, argsT);
2301  IR_schema[TOK(TOK_NAME)] = STR(function_name_id);
2303  IR_schema[TOK(TOK_SCPE)] = STR(GET_INDEX_CONST_NODE(scpe));
2304  IR_schema[TOK(TOK_SRCP)] = srcp;
2305  if(with_body)
2306  {
2307  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> statement_list_schema;
2308  auto statement_list_id = TreeM->get_next_available_tree_node_id();
2309  TreeM->create_tree_node(statement_list_id, statement_list_K, statement_list_schema);
2310  IR_schema[TOK(TOK_BODY)] = STR(statement_list_id);
2311  }
2312  TreeM->create_tree_node(function_decl_id, function_decl_K, IR_schema);
2313  IR_schema.clear();
2314 
2315  auto function_decl_res = TreeM->GetTreeReindex(function_decl_id);
2317  auto fd = GetPointerS<function_decl>(GET_NODE(function_decl_res));
2318  unsigned int Pindex = 0;
2319  for(const auto& par_type : argsT)
2320  {
2321  const auto p_name = "_P" + STR(Pindex);
2322  const auto p_identifier = create_identifier_node(p_name);
2323  const auto p_decl = create_parm_decl(p_identifier, par_type, function_decl_res, par_type, tree_nodeRef(),
2324  tree_nodeRef(), srcp, 1, false, false);
2325  fd->AddArg(p_decl);
2326  ++Pindex;
2327  }
2328  if(!with_body)
2329  {
2330  fd->undefined_flag = true;
2331  }
2332  TreeM->add_function(function_decl_id, GET_NODE(function_decl_res));
2333  return function_decl_res;
2334 }
2335 
2337  const tree_nodeConstRef& second_condition, const blocRef& block,
2338  unsigned int function_decl_nid) const
2339 {
2340  if(block && reuse)
2341  {
2342  for(const auto& statement : block->CGetStmtList())
2343  {
2344  const auto ga = GetPointer<const gimple_assign>(GET_NODE(statement));
2345  if(ga)
2346  {
2347  const auto toe = GetPointer<const truth_or_expr>(GET_NODE(ga->op1));
2348  if(toe and ((toe->op0->index == first_condition->index and toe->op1->index == second_condition->index) or
2349  (toe->op0->index == second_condition->index and toe->op1->index == first_condition->index)))
2350  {
2351  THROW_ASSERT(GET_NODE(ga->op0)->get_kind() == ssa_name_K, "unexpected condition");
2352  auto ssa0 = GetPointerS<ssa_name>(GET_NODE(ga->op0));
2353  ssa0->bit_values = "U";
2354  return ga->op0;
2355  }
2356  }
2357  }
2358  }
2359 
2360  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ssa_schema, truth_or_expr_schema, gimple_assign_schema;
2362  const auto truth_or_expr_id = TreeM->new_tree_node_id();
2363  const auto bt = GetBooleanType();
2364  truth_or_expr_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2365  truth_or_expr_schema[TOK(TOK_TYPE)] = STR(bt->index);
2366  truth_or_expr_schema[TOK(TOK_OP0)] = STR(first_condition->index);
2367  truth_or_expr_schema[TOK(TOK_OP1)] = STR(second_condition->index);
2368  TreeM->create_tree_node(truth_or_expr_id, truth_or_expr_K, truth_or_expr_schema);
2369 
2371  TreeM->GetTreeReindex(truth_or_expr_id), function_decl_nid, BUILTIN_SRCP);
2372  if(block)
2373  {
2374  block->PushBack(ga, AppM);
2375  }
2376  return GetPointer<gimple_assign>(GET_NODE(ga))->op0;
2377 }
2378 
2380  const tree_nodeConstRef& second_condition, const blocRef& block,
2381  unsigned int function_decl_nid) const
2382 {
2383  if(block and reuse)
2384  {
2385  for(const auto& statement : block->CGetStmtList())
2386  {
2387  const auto ga = GetPointer<const gimple_assign>(GET_NODE(statement));
2388  if(ga)
2389  {
2390  const auto toe = GetPointer<const truth_and_expr>(GET_NODE(ga->op1));
2391  if(toe and ((toe->op0->index == first_condition->index and toe->op1->index == second_condition->index) or
2392  (toe->op0->index == second_condition->index and toe->op1->index == first_condition->index)))
2393  {
2394  THROW_ASSERT(GET_NODE(ga->op0)->get_kind() == ssa_name_K, "unexpected condition");
2395  auto ssa0 = GetPointerS<ssa_name>(GET_NODE(ga->op0));
2396  ssa0->bit_values = "U";
2397  return ga->op0;
2398  }
2399  }
2400  }
2401  }
2402  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ssa_schema, truth_and_expr_schema, gimple_assign_schema;
2404  const auto truth_and_expr_id = TreeM->new_tree_node_id();
2405  const auto bt = GetBooleanType();
2406  truth_and_expr_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2407  truth_and_expr_schema[TOK(TOK_TYPE)] = STR(bt->index);
2408  truth_and_expr_schema[TOK(TOK_OP0)] = STR(first_condition->index);
2409  truth_and_expr_schema[TOK(TOK_OP1)] = STR(second_condition->index);
2410  TreeM->create_tree_node(truth_and_expr_id, truth_and_expr_K, truth_and_expr_schema);
2411 
2413  TreeM->GetTreeReindex(truth_and_expr_id), function_decl_nid, BUILTIN_SRCP);
2414  if(block)
2415  {
2416  block->PushBack(ga, AppM);
2417  }
2418  return GetPointer<gimple_assign>(GET_NODE(ga))->op0;
2419 }
2420 
2422  unsigned int function_decl_nid) const
2423 {
2424  if(block and reuse)
2425  {
2426  for(const auto& statement : block->CGetStmtList())
2427  {
2428  const auto ga = GetPointer<const gimple_assign>(GET_NODE(statement));
2429  if(ga)
2430  {
2431  const auto tne = GetPointer<const truth_not_expr>(GET_NODE(ga->op1));
2432  if(tne and tne->op->index == condition->index)
2433  {
2434  THROW_ASSERT(GET_NODE(ga->op0)->get_kind() == ssa_name_K, "unexpected condition");
2435  auto ssa0 = GetPointerS<ssa_name>(GET_NODE(ga->op0));
2436  ssa0->bit_values = "U";
2437  return ga->op0;
2438  }
2439  }
2440  }
2441  }
2442  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ssa_schema, truth_not_expr_schema, gimple_assign_schema;
2444  const auto truth_not_expr_id = TreeM->new_tree_node_id();
2445  const auto bt = GetBooleanType();
2446  truth_not_expr_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2447  truth_not_expr_schema[TOK(TOK_TYPE)] = STR(bt->index);
2448  truth_not_expr_schema[TOK(TOK_OP)] = STR(condition->index);
2449  TreeM->create_tree_node(truth_not_expr_id, truth_not_expr_K, truth_not_expr_schema);
2450 
2452  TreeM->GetTreeReindex(truth_not_expr_id), function_decl_nid, BUILTIN_SRCP);
2453  if(block)
2454  {
2455  block->PushBack(ga, AppM);
2456  }
2457  return GetPointer<gimple_assign>(GET_NODE(ga))->op0;
2458 }
2459 
2461  unsigned int function_decl_nid) const
2462 {
2463  THROW_ASSERT(block, "expected basic block");
2464  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Extracting condition from " + condition->ToString());
2465 
2466  const auto gc = GetPointer<const gimple_cond>(GET_CONST_NODE(condition));
2467  THROW_ASSERT(gc, "Trying to extract condition from " + condition->ToString());
2468  if(tree_helper::IsBooleanType(gc->op0) &&
2469  (GET_NODE(gc->op0)->get_kind() == ssa_name_K || GetPointer<const cst_node>(GET_CONST_NODE(gc->op0)) != nullptr))
2470  {
2472  "<--Condition already available as " + gc->op0->ToString());
2473  return gc->op0;
2474  }
2475  else
2476  {
2477  if(block && reuse)
2478  {
2479  for(const auto& statement : block->CGetStmtList())
2480  {
2481  const auto ga = GetPointer<const gimple_assign>(GET_CONST_NODE(statement));
2482  if(ga && ga->op1->index == condition->index && tree_helper::IsBooleanType(ga->op0))
2483  {
2484  THROW_ASSERT(GET_NODE(ga->op0)->get_kind() == ssa_name_K, "unexpected condition");
2485  auto ssa0 = GetPointerS<ssa_name>(GET_NODE(ga->op0));
2486  ssa0->bit_values = "U";
2487  return ga->op0;
2488  }
2489  }
2490  }
2491  const auto bt = GetBooleanType();
2492  tree_nodeRef ret;
2493  if(tree_helper::IsBooleanType(gc->op0))
2494  {
2495  const auto ga =
2497  function_decl_nid, BUILTIN_SRCP);
2498  block->PushBack(ga, AppM);
2499  ret = GetPointerS<const gimple_assign>(GET_CONST_NODE(ga))->op0;
2500  }
2501  else if((GET_CONST_NODE(gc->op0))->get_kind() == integer_cst_K)
2502  {
2503  const auto cst_val = tree_helper::GetConstValue(gc->op0);
2504  if(cst_val)
2505  {
2506  ret = TreeM->CreateUniqueIntegerCst(1, bt);
2507  }
2508  else
2509  {
2510  ret = TreeM->CreateUniqueIntegerCst(0, bt);
2511  }
2512  }
2513  else
2514  {
2515  const auto srcp_default = gc->include_name + ":" + STR(gc->line_number) + ":" + STR(gc->column_number);
2516  const auto constNE0 = TreeM->CreateUniqueIntegerCst(0, tree_helper::CGetType(gc->op0));
2517  const auto cond_op0 = create_binary_operation(bt, gc->op0, constNE0, srcp_default, ne_expr_K);
2518  const auto op0_ga =
2520  cond_op0, function_decl_nid, srcp_default);
2521  block->PushBack(op0_ga, AppM);
2522  ret = GetPointerS<const gimple_assign>(GET_CONST_NODE(op0_ga))->op0;
2523  }
2524  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Condition created is " + ret->ToString());
2525  return ret;
2526  }
2527 }
2528 
2530  const tree_nodeConstRef& min, const tree_nodeConstRef& max,
2531  unsigned int function_decl_nid) const
2532 {
2533  THROW_ASSERT(type and type->get_kind() == tree_reindex_K, "type is not a tree reindex");
2534 
2535  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ne_schema, ga_schema;
2536  ne_schema[TOK(TOK_TYPE)] = STR(type->index);
2537  ne_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2538  ne_schema[TOK(TOK_OP)] = STR(operand->index);
2539  const auto ne_id = TreeM->new_tree_node_id();
2540  TreeM->create_tree_node(ne_id, nop_expr_K, ne_schema);
2541 
2542  const auto ssa_operand = GetPointer<const ssa_name>(GET_CONST_NODE(operand));
2543  const auto int_cst_operand = GetPointer<const integer_cst>(GET_CONST_NODE(operand));
2544  if(!ssa_operand && !int_cst_operand)
2545  {
2548  THROW_UNREACHABLE("Cannot create nop expr from something that is not a ssa: " + operand->ToString());
2549  return tree_nodeRef();
2550  }
2551 
2552  const auto ga = CreateGimpleAssign(TreeM->GetTreeReindex(type->index), min, max, TreeM->GetTreeReindex(ne_id),
2553  function_decl_nid, BUILTIN_SRCP);
2554  if(ssa_operand)
2555  {
2556  GetPointerS<ssa_name>(GET_NODE(GetPointerS<gimple_assign>(GET_NODE(ga))->op0))->use_set = ssa_operand->use_set;
2557  }
2558  return ga;
2559 }
2560 
2562 {
2563  const auto int_signed_type = GetPointer<const integer_type>(signed_type);
2564  if(not int_signed_type)
2565  {
2566  THROW_ERROR(signed_type->ToString() + " is not an integer type");
2567  }
2568  THROW_ASSERT(not int_signed_type->unsigned_flag, signed_type->ToString() + " is not signed");
2569 
2570  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ut_schema;
2571 
2572  ut_schema[TOK(TOK_QUAL)] = STR(static_cast<int>(int_signed_type->qual));
2573  const auto quals = int_signed_type->qual;
2575  {
2576  THROW_ERROR(signed_type->ToString() + " has qualifiers");
2577  }
2578 
2579  ut_schema[TOK(TOK_SIZE)] = STR(int_signed_type->size->index);
2580  ut_schema[TOK(TOK_ALGN)] = STR(int_signed_type->algn);
2581  ut_schema[TOK(TOK_UNSIGNED)] = STR(false);
2582 
2583  const auto min = [&]() -> tree_nodeRef {
2584  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> min_schema;
2585  min_schema[TOK(TOK_VALUE)] = STR(0);
2586  const auto find = TreeM->find(integer_cst_K, min_schema);
2587  if(find)
2588  {
2589  return TreeM->GetTreeReindex(find);
2590  }
2591  const auto min_id = TreeM->new_tree_node_id();
2592  TreeM->create_tree_node(min_id, integer_cst_K, min_schema);
2593  return TreeM->GetTreeReindex(min_id);
2594  }();
2595  ut_schema[TOK(TOK_MIN)] = STR(min->index);
2596 
2597  const auto max = [&]() -> tree_nodeRef {
2598  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> max_schema;
2599  max_schema[TOK(TOK_VALUE)] = STR((2 * -(tree_helper::GetConstValue(int_signed_type->min))) - 1);
2600  const auto find = TreeM->find(integer_cst_K, max_schema);
2601  if(find)
2602  {
2603  return TreeM->GetTreeReindex(find);
2604  }
2605  const auto max_id = TreeM->new_tree_node_id();
2606  TreeM->create_tree_node(max_id, integer_cst_K, max_schema);
2607  return TreeM->GetTreeReindex(max_id);
2608  }();
2609  ut_schema[TOK(TOK_MAX)] = STR(max->index);
2610  ut_schema[TOK(TOK_PREC)] = STR(int_signed_type->prec);
2611  ut_schema[TOK(TOK_UNSIGNED)] = STR(true);
2612  const auto find = TreeM->find(integer_type_K, ut_schema);
2613  if(find)
2614  {
2615  return TreeM->GetTreeReindex(find);
2616  }
2617  else
2618  {
2619  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> in_schema;
2620  if(int_signed_type->name)
2621  {
2622  const auto type_name = GetPointer<const decl_node>(GET_CONST_NODE(int_signed_type->name));
2623  if(not type_name)
2624  {
2625  THROW_ERROR(signed_type->ToString() + " has not a type decl associated");
2626  }
2627 
2628  if(type_name->include_name != "<built-in>")
2629  {
2630  THROW_ERROR(signed_type->ToString() + " is not builtin");
2631  }
2632 
2633  const auto in = GetPointer<identifier_node>(GET_CONST_NODE(type_name->name));
2634  if(not in)
2635  {
2636  THROW_ERROR(signed_type->ToString() + " has not a name");
2637  }
2638 
2639  std::string unsigned_str = "unsigned " + in->strg;
2640  in_schema[TOK(TOK_STRG)] = unsigned_str;
2641  auto find_in = TreeM->find(identifier_node_K, in_schema);
2642  if(not find_in)
2643  {
2644  find_in = TreeM->new_tree_node_id();
2645  TreeM->create_tree_node(find_in, identifier_node_K, in_schema);
2646  }
2647  ut_schema[TOK(TOK_NAME)] = STR(find_in);
2648  }
2649  const auto new_tree_node_id = TreeM->new_tree_node_id();
2650  TreeM->create_tree_node(new_tree_node_id, integer_type_K, ut_schema);
2651  return TreeM->GetTreeReindex(new_tree_node_id);
2652  }
2653 }
2654 
2656  const tree_nodeConstRef& second_operand, const blocRef& block,
2657  unsigned int function_decl_nid) const
2658 {
2659  if(block and reuse)
2660  {
2661  for(const auto& statement : block->CGetStmtList())
2662  {
2663  const auto ga = GetPointer<const gimple_assign>(GET_NODE(statement));
2664  if(ga)
2665  {
2666  const auto ee = GetPointer<const eq_expr>(GET_NODE(ga->op1));
2667  if(ee and ((ee->op0->index == first_operand->index and ee->op1->index == second_operand->index) or
2668  (ee->op0->index == second_operand->index and ee->op1->index == first_operand->index)))
2669  {
2670  THROW_ASSERT(GET_NODE(ga->op0)->get_kind() == ssa_name_K, "unexpected condition");
2671  auto ssa0 = GetPointerS<ssa_name>(GET_NODE(ga->op0));
2672  ssa0->bit_values = "U";
2673  return ga->op0;
2674  }
2675  }
2676  }
2677  }
2678 
2679  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ssa_schema, eq_expr_schema, gimple_assign_schema;
2681  const auto bt = GetBooleanType();
2682  const auto eq_expr_id = TreeM->new_tree_node_id();
2683  eq_expr_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2684  eq_expr_schema[TOK(TOK_TYPE)] = STR(bt->index);
2685  eq_expr_schema[TOK(TOK_OP0)] = STR(first_operand->index);
2686  eq_expr_schema[TOK(TOK_OP1)] = STR(second_operand->index);
2687  TreeM->create_tree_node(eq_expr_id, eq_expr_K, eq_expr_schema);
2688 
2690  TreeM->GetTreeReindex(eq_expr_id), function_decl_nid, BUILTIN_SRCP);
2691  if(block)
2692  {
2693  block->PushBack(ga, AppM);
2694  }
2695  return GetPointer<gimple_assign>(GET_NODE(ga))->op0;
2696 }
2697 
2699  const std::vector<tree_nodeRef>& args, const std::string& srcp) const
2700 {
2701  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ae_IR_schema, ce_IR_schema;
2702  ae_IR_schema[TOK(TOK_OP)] = STR(called_function->index);
2703  const auto ft = tree_helper::CGetType(called_function);
2704  ae_IR_schema[TOK(TOK_TYPE)] = STR(GetPointerType(ft)->index);
2705  ae_IR_schema[TOK(TOK_SRCP)] = srcp;
2706  const unsigned int ae_id = TreeM->new_tree_node_id();
2707  TreeM->create_tree_node(ae_id, addr_expr_K, ae_IR_schema);
2708 
2709  std::string args_string;
2710  for(const auto& arg : args)
2711  {
2712  if(!args_string.empty())
2713  {
2714  args_string += "_";
2715  }
2716  args_string += STR(arg->index);
2717  }
2718  ce_IR_schema[TOK(TOK_ARG)] = args_string;
2719  ce_IR_schema[TOK(TOK_FN)] = STR(ae_id);
2720  ce_IR_schema[TOK(TOK_TYPE)] = STR(GetPointer<const function_type>(GET_CONST_NODE(ft))->retn->index);
2721  ce_IR_schema[TOK(TOK_SRCP)] = srcp;
2722  const unsigned int ce_id = TreeM->new_tree_node_id();
2723  TreeM->create_tree_node(ce_id, call_expr_K, ce_IR_schema);
2724  return TreeM->GetTreeReindex(ce_id);
2725 }
2726 
2728 {
2729  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ae_IR_schema;
2730  const auto type_node = tree_helper::CGetType(tn);
2731  ae_IR_schema[TOK(TOK_OP)] = STR(tn->index);
2732  auto align = 8u;
2733  if(tn->get_kind() == var_decl_K)
2734  {
2735  auto vd = GetPointer<const var_decl>(tn);
2736  align = vd->algn;
2737  }
2738  const auto ptr_type = GetPointerType(type_node, align);
2739  ae_IR_schema[TOK(TOK_TYPE)] = STR(ptr_type->index);
2740  ae_IR_schema[TOK(TOK_SRCP)] = srcp;
2741  const unsigned int ae_id = TreeM->new_tree_node_id();
2742  TreeM->create_tree_node(ae_id, addr_expr_K, ae_IR_schema);
2743  return TreeM->CGetTreeReindex(ae_id);
2744 }
2745 
2747  const std::string& srcp) const
2748 {
2749  auto addr_tn = CreateAddrExpr(tn, srcp);
2750  const auto ptr_type = GetPointer<addr_expr>(GET_NODE(addr_tn))->type;
2751  auto assign_node = CreateGimpleAssign(ptr_type, tree_nodeRef(), tree_nodeRef(), addr_tn, function_decl_nid, srcp);
2752  auto ga = GetPointer<gimple_assign>(GET_NODE(assign_node));
2753  auto ssa = GetPointer<ssa_name>(GET_NODE(ga->op0));
2754  ssa->use_set = PointToSolutionRef(new PointToSolution());
2755  ssa->use_set->Add(TreeM->CGetTreeReindex(tn->index));
2756  return assign_node;
2757 }
2758 
2759 tree_nodeRef tree_manipulation::CreateVectorBooleanType(const unsigned long long number_of_elements) const
2760 {
2761  const auto boolean_type = GetBooleanType();
2762  const auto size = TreeM->CreateUniqueIntegerCst(static_cast<long long>(number_of_elements), GetSizeType());
2763 
2764  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
2765  IR_schema[TOK(TOK_ELTS)] = STR(boolean_type->index);
2766  IR_schema[TOK(TOK_SIZE)] = STR(size->index);
2767 
2768  auto vector_type_id = TreeM->find(vector_type_K, IR_schema);
2769 
2771  if(vector_type_id == 0)
2772  {
2773  vector_type_id = this->TreeM->new_tree_node_id();
2774 
2775  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
2776  this->TreeM->create_tree_node(vector_type_id, vector_type_K, IR_schema);
2777  }
2778  return TreeM->GetTreeReindex(vector_type_id);
2779 }
2780 
2781 tree_nodeRef tree_manipulation::CloneFunction(const tree_nodeRef& tn, const std::string& fsuffix)
2782 {
2783  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Type node is not a tree reindex");
2784  THROW_ASSERT(GET_CONST_NODE(tn)->get_kind() == function_decl_K, "Type node is not a function_decl");
2785  const auto fd = GetPointerS<const function_decl>(GET_CONST_NODE(tn));
2786  THROW_ASSERT(GET_CONST_NODE(fd->name)->get_kind() == identifier_node_K, "operator based function not supported ");
2787  const auto fname = tree_helper::print_function_name(TreeM, fd);
2788  const auto fu_node = TreeM->GetFunction(fname + fsuffix);
2789  if(fu_node)
2790  {
2791  return fu_node;
2792  }
2793  const auto clone_fname = create_identifier_node(fname + fsuffix);
2795  tree_node_dup tnd(remapping, AppM);
2796  remapping[GET_INDEX_CONST_NODE(fd->name)] = GET_INDEX_CONST_NODE(clone_fname);
2797  if(fd->mngl)
2798  {
2799  const auto fmngl = tree_helper::GetMangledFunctionName(fd);
2800  const auto clone_mngl = create_identifier_node(fmngl + fsuffix);
2801  remapping[GET_INDEX_CONST_NODE(fd->mngl)] = GET_INDEX_CONST_NODE(clone_mngl);
2802  }
2803  const auto clone_fd = tnd.create_tree_node(GET_NODE(tn), tree_node_dup_mode::FUNCTION);
2804  return TreeM->GetTreeReindex(clone_fd);
2805 }
2806 
2807 unsigned int tree_manipulation::InlineFunctionCall(const tree_nodeRef& call_node, const tree_nodeRef& caller_node)
2808 {
2809  THROW_ASSERT(call_node->get_kind() == tree_reindex_K, "");
2810  const auto call_stmt = GET_CONST_NODE(call_node);
2811  tree_nodeRef fn;
2812  tree_nodeRef ret_val = nullptr;
2813  std::vector<tree_nodeRef> const* args;
2814  if(const auto gc = GetPointer<const gimple_call>(call_stmt))
2815  {
2816  fn = gc->fn;
2817  args = &gc->args;
2818  }
2819  else if(const auto ga = GetPointer<const gimple_assign>(call_stmt))
2820  {
2821  const auto ce = GetPointer<const call_expr>(GET_CONST_NODE(ga->op1));
2822  THROW_ASSERT(ce, "Assign statement does not contain a function call: " + STR(call_node));
2823  fn = ce->fn;
2824  args = &ce->args;
2825  ret_val = ga->op0;
2826  }
2827  else
2828  {
2829  THROW_UNREACHABLE("Unsupported call statement: " + call_stmt->get_kind_text() + " " + STR(call_node));
2830  }
2831  if(GET_CONST_NODE(fn)->get_kind() == addr_expr_K)
2832  {
2833  fn = GetPointerS<const unary_expr>(GET_CONST_NODE(fn))->op;
2834  }
2835  THROW_ASSERT(GET_CONST_NODE(fn)->get_kind() == function_decl_K,
2836  "Call statement should address a function declaration");
2837 
2838  const auto fd = GetPointer<function_decl>(GET_NODE(caller_node));
2839  auto sl = GetPointerS<statement_list>(GET_NODE(fd->body));
2840  const auto& block = sl->list_of_bloc.at(GetPointer<const gimple_node>(call_stmt)->bb_index);
2841  const auto splitBBI = sl->list_of_bloc.rbegin()->first + 1;
2842  THROW_ASSERT(!sl->list_of_bloc.count(splitBBI), "");
2843  const auto splitBB = sl->list_of_bloc[splitBBI] = blocRef(new bloc(splitBBI));
2844  splitBB->loop_id = block->loop_id;
2845  splitBB->SetSSAUsesComputed();
2846  THROW_ASSERT(!block->schedule, "Inlining should not be allowed after scheduling");
2847 
2848  std::replace(block->list_of_pred.begin(), block->list_of_pred.end(), block->number, splitBB->number);
2849  splitBB->list_of_succ.assign(block->list_of_succ.cbegin(), block->list_of_succ.cend());
2850  block->list_of_succ.clear();
2851  splitBB->false_edge = block->false_edge;
2852  splitBB->true_edge = block->true_edge;
2853  block->false_edge = 0;
2854  block->true_edge = 0;
2855 
2856  for(const auto& bbi : splitBB->list_of_succ)
2857  {
2858  THROW_ASSERT(sl->list_of_bloc.count(bbi), "");
2859  const auto& bb = sl->list_of_bloc.at(bbi);
2860  for(const auto& phi : bb->CGetPhiList())
2861  {
2862  auto gp = GetPointerS<gimple_phi>(GET_NODE(phi));
2863  const auto defFrom = std::find_if(gp->CGetDefEdgesList().begin(), gp->CGetDefEdgesList().end(),
2864  [&](const gimple_phi::DefEdge& de) { return de.second == block->number; });
2865  if(defFrom != gp->CGetDefEdgesList().end())
2866  {
2867  gp->ReplaceDefEdge(TreeM, *defFrom, {defFrom->first, splitBBI});
2868  }
2869  }
2870  }
2871  {
2872  auto it = std::find_if(block->CGetStmtList().begin(), block->CGetStmtList().end(), [&](const tree_nodeRef& tn) {
2873  return GET_INDEX_CONST_NODE(tn) == GET_INDEX_CONST_NODE(call_node);
2874  });
2875  THROW_ASSERT(it != block->CGetStmtList().end(), "");
2876  ++it;
2877  while(it != block->CGetStmtList().end())
2878  {
2879  const auto mv_stmt = *it;
2880  ++it;
2881  block->RemoveStmt(mv_stmt, AppM);
2882  splitBB->PushBack(mv_stmt, AppM);
2883  }
2884  block->RemoveStmt(call_node, AppM);
2885  }
2886 
2887  const auto max_loop_id = [&]() {
2888  unsigned int mlid = 0;
2889  for(const auto& ibb : sl->list_of_bloc)
2890  {
2891  mlid = std::max(mlid, ibb.second->loop_id);
2892  std::replace(ibb.second->list_of_pred.begin(), ibb.second->list_of_pred.end(), block->number, splitBB->number);
2893  }
2894  return mlid;
2895  }();
2896  const auto inline_fd = GetPointerS<const function_decl>(GET_CONST_NODE(fn));
2897  auto output_level = parameters->getOption<int>(OPT_output_level);
2898  INDENT_OUT_MEX(OUTPUT_LEVEL_MINIMUM, output_level,
2899  "Function call to " + tree_helper::print_function_name(TreeM, inline_fd) + " inlined in " +
2902  remapping.insert(std::make_pair(inline_fd->index, fd->index));
2903  std::for_each(inline_fd->list_of_args.cbegin(), inline_fd->list_of_args.cend(), [&](const tree_nodeRef& tn) {
2904  remapping.insert(std::make_pair(GET_INDEX_CONST_NODE(tn), GET_INDEX_CONST_NODE(tn)));
2905  });
2906  tree_node_dup tnd(remapping, AppM, splitBBI + 1, max_loop_id + 1, true);
2907  const auto dup_sl_id = tnd.create_tree_node(GET_NODE(inline_fd->body), tree_node_dup_mode::RENAME);
2908  const auto dup_sl = GetPointer<const statement_list>(TreeM->CGetTreeNode(dup_sl_id));
2909  THROW_ASSERT(dup_sl, "");
2910 
2911  const auto replace_arg_with_param = [&](const tree_nodeRef& stmt) {
2912  const auto uses = tree_helper::ComputeSsaUses(stmt);
2913  for(const auto& use : uses)
2914  {
2915  const auto SSA = GetPointer<const ssa_name>(GET_CONST_NODE(use.first));
2916  // If ssa_name references a parm_decl and is defined by a gimple_nop, it represents the formal function
2917  // parameter inside the function body
2918  if(SSA->var != nullptr && GET_CONST_NODE(SSA->var)->get_kind() == parm_decl_K &&
2919  GET_CONST_NODE(SSA->CGetDefStmt())->get_kind() == gimple_nop_K)
2920  {
2921  auto argIt = std::find_if(
2922  inline_fd->list_of_args.cbegin(), inline_fd->list_of_args.cend(),
2923  [&](const tree_nodeRef& arg) { return GET_INDEX_CONST_NODE(arg) == GET_INDEX_CONST_NODE(SSA->var); });
2924  THROW_ASSERT(argIt != inline_fd->list_of_args.cend(),
2925  "parm_decl associated with ssa_name not found in function parameters");
2926  size_t arg_pos = static_cast<size_t>(argIt - inline_fd->list_of_args.cbegin());
2927 
2928  THROW_ASSERT(arg_pos < args->size(), "");
2929  TreeM->ReplaceTreeNode(stmt, use.first, args->at(arg_pos));
2930  }
2931  }
2932  };
2933 
2934  std::vector<std::pair<tree_nodeRef, unsigned int>> list_of_def_edge;
2935  for(const auto& ibb : dup_sl->list_of_bloc)
2936  {
2937  if(ibb.first == bloc::ENTRY_BLOCK_ID || ibb.first == bloc::EXIT_BLOCK_ID)
2938  {
2939  continue;
2940  }
2941  auto& bb = ibb.second;
2942  sl->add_bloc(bb);
2943  for(auto it = bb->list_of_pred.begin(); it != bb->list_of_pred.end(); ++it)
2944  {
2945  if(*it == bloc::ENTRY_BLOCK_ID)
2946  {
2947  *it = block->number;
2948  block->list_of_succ.push_back(bb->number);
2949  }
2950  }
2951  for(auto it = bb->list_of_succ.begin(); it != bb->list_of_succ.end(); ++it)
2952  {
2953  const auto has_abort_call = [&]() -> bool {
2954  if(!bb->CGetStmtList().empty())
2955  {
2956  const auto& last_stmt = bb->CGetStmtList().back();
2957  if(GET_CONST_NODE(last_stmt)->get_kind() == gimple_call_K)
2958  {
2959  const auto gc = GetPointerS<const gimple_call>(GET_CONST_NODE(last_stmt));
2960  auto call_fd = gc->fn;
2961  const auto ae = GetPointer<addr_expr>(GET_CONST_NODE(call_fd));
2962  if(ae)
2963  {
2964  call_fd = ae->op;
2965  }
2966  const auto fu_name = tree_helper::print_function_name(
2967  TreeM, GetPointerS<const function_decl>(GET_CONST_NODE(call_fd)));
2968  if(fu_name == "abort" || fu_name == "exit")
2969  {
2970  return true;
2971  }
2972  }
2973  }
2974  return false;
2975  }();
2976  if(*it == bloc::EXIT_BLOCK_ID && !has_abort_call)
2977  {
2978  *it = splitBB->number;
2979  splitBB->list_of_pred.push_back(bb->number);
2980  }
2981  }
2982  for(const auto& phi : bb->CGetPhiList())
2983  {
2984  replace_arg_with_param(phi);
2985  }
2986  for(auto it = bb->CGetStmtList().begin(); it != bb->CGetStmtList().end();)
2987  {
2988  const auto stmt = *it;
2989  ++it;
2990  replace_arg_with_param(stmt);
2991 
2992  if(GET_CONST_NODE(stmt)->get_kind() == gimple_return_K)
2993  {
2994  if(ret_val)
2995  {
2996  const auto gr = GetPointerS<const gimple_return>(GET_CONST_NODE(stmt));
2997  THROW_ASSERT(gr->op, "");
2998  list_of_def_edge.push_back(std::make_pair(gr->op, bb->number));
2999  }
3000  bb->RemoveStmt(stmt, AppM);
3001  }
3002  }
3003  }
3004  THROW_ASSERT(block->list_of_succ.size() == 1, "There should be only one entry point.");
3005  if(ret_val)
3006  {
3007  THROW_ASSERT(!list_of_def_edge.empty(), "");
3008  tree_nodeRef phi_res;
3009  const auto ret_phi = create_phi_node(phi_res, list_of_def_edge, fd->index);
3010  auto gp = GetPointer<gimple_phi>(GET_NODE(ret_phi));
3011  gp->artificial = true;
3012  gp->SetSSAUsesComputed();
3013  splitBB->AddPhi(ret_phi);
3014  TreeM->ReplaceTreeNode(ret_phi, phi_res, ret_val);
3015  }
3016  if(splitBB->list_of_pred.empty())
3017  {
3018  THROW_ASSERT(splitBB->CGetStmtList().empty() && splitBB->CGetPhiList().empty(),
3019  "Unreachable BB after inlined call statement must be empty.");
3020  for(const auto& succ_bbi : splitBB->list_of_succ)
3021  {
3022  const auto& succ_bb = sl->list_of_bloc[succ_bbi];
3023  const auto new_end = std::remove(succ_bb->list_of_pred.begin(), succ_bb->list_of_pred.end(), splitBB->number);
3024  succ_bb->list_of_pred.erase(new_end, succ_bb->list_of_pred.end());
3025  }
3026  sl->list_of_bloc.erase(splitBB->number);
3027  }
3028  return splitBB->number;
3029 }
3030 
3031 bool tree_manipulation::VersionFunctionCall(const tree_nodeRef& call_node, const tree_nodeRef& caller_node,
3032  const std::string& version_suffix)
3033 {
3034  const auto call_stmt = GET_CONST_NODE(call_node);
3035  tree_nodeRef called_fn = nullptr;
3036  tree_nodeRef ret_val = nullptr;
3037  std::vector<tree_nodeRef> const* args = nullptr;
3038  if(const auto gc = GetPointer<const gimple_call>(call_stmt))
3039  {
3040  called_fn = gc->fn;
3041  args = &gc->args;
3042  }
3043  else if(const auto ga = GetPointer<const gimple_assign>(call_stmt))
3044  {
3045  const auto ce = GetPointer<const call_expr>(GET_CONST_NODE(ga->op1));
3046  THROW_ASSERT(ce, "Assign statement does not contain a function call: " + STR(call_node));
3047  called_fn = ce->fn;
3048  args = &ce->args;
3049  ret_val = ga->op0;
3050  }
3051  else
3052  {
3053  THROW_UNREACHABLE("Unsupported call statement: " + call_stmt->get_kind_text() + " " + STR(call_node));
3054  }
3055  if(GET_CONST_NODE(called_fn)->get_kind() == addr_expr_K)
3056  {
3057  called_fn = GetPointerS<const unary_expr>(GET_CONST_NODE(called_fn))->op;
3058  }
3059  THROW_ASSERT(GET_CONST_NODE(called_fn)->get_kind() == function_decl_K,
3060  "Call statement should address a function declaration");
3061 
3062  if(ends_with(tree_helper::GetFunctionName(TreeM, called_fn), version_suffix))
3063  {
3064  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Call already versioned...");
3065  return false;
3066  }
3067  const auto version_fn = CloneFunction(called_fn, version_suffix);
3068  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Call before versioning : " + STR(call_node));
3069  const auto caller_id = GET_INDEX_CONST_NODE(caller_node);
3070  if(ret_val)
3071  {
3072  const auto has_args = !GetPointer<const function_decl>(GET_CONST_NODE(version_fn))->list_of_args.empty();
3073  const auto ce = CreateCallExpr(version_fn, has_args ? *args : std::vector<tree_nodeRef>(), BUILTIN_SRCP);
3074  const auto ga = GetPointerS<const gimple_assign>(call_stmt);
3075  CustomUnorderedSet<unsigned int> already_visited;
3076  AppM->GetCallGraphManager()->RemoveCallPoint(caller_id, GET_INDEX_CONST_NODE(called_fn),
3077  GET_INDEX_CONST_NODE(call_node));
3078  TreeM->ReplaceTreeNode(call_node, ga->op1, ce);
3079  CallGraphManager::addCallPointAndExpand(already_visited, AppM, caller_id, GET_INDEX_CONST_NODE(version_fn),
3082  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Call after versioning : " + STR(call_node));
3083  }
3084  else
3085  {
3086  const auto version_call = create_gimple_call(version_fn, *args, caller_id, BUILTIN_SRCP);
3087  const auto caller_fd = GetPointer<function_decl>(GET_NODE(caller_node));
3088  const auto call_bbi = GetPointer<gimple_node>(call_stmt)->bb_index;
3089  const auto& call_bb = GetPointer<statement_list>(GET_NODE(caller_fd->body))->list_of_bloc.at(call_bbi);
3090  call_bb->Replace(call_node, version_call, true, AppM);
3091  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Call after versioning : " + STR(version_call));
3092  }
3093  return true;
3094 }
#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 CreateOrExpr(const tree_nodeConstRef &first_condition, const tree_nodeConstRef &second_condition, const blocRef &block, unsigned int function_decl_nid) const
Create an or expression.
This struct specifies a point-to solution.
Definition: tree_node.hpp:1001
tree_nodeRef CreateNotExpr(const tree_nodeConstRef &condition, const blocRef &block, unsigned int function_decl_nid) const
UTILITY.
~tree_manipulation()
This is the destructor of the tree_manipulation.
refcount< PointToSolution > PointToSolutionRef
Definition: tree_node.hpp:1073
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
tree_nodeRef GetBitsizeType() const
Function that creates a bit_size type if it is not already present, otherwise it returns the one that...
#define SIZE_VALUE_FUNCTION
tree_nodeRef ExtractCondition(const tree_nodeRef &condition, const blocRef &block, unsigned int function_decl_nid) const
Extract computation of condition from a gimple_cond.
tree_nodeRef create_quaternary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const tree_nodeRef &op3, const std::string &srcp, enum kind operation_kind) const
Function used to create a quaternary expression.
This struct specifies the field bloc (basic block).
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
tree_nodeRef CreateEqExpr(const tree_nodeConstRef &first_operand, const tree_nodeConstRef &second_operand, const blocRef &block, unsigned int function_decl_nid) const
Create an eq_expr.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
void bb_set_false_edge(blocRef &bb, const unsigned int &false_edge_index) const
Function that sets in basic block bb the index of the then basic block in case the last statement is ...
std::string ToString() const
Print this node as string in gimple format.
tree_nodeRef create_gimple_cond(const tree_nodeRef &expr, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_COND.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
void bb_add_stmt(blocRef &bb, const tree_nodeRef &stmt) const
Function that adds in basic block bb the statement stmt.
#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...
tree_managerRef TreeM
Tree Manager.
tree_nodeRef create_translation_unit_decl() const
create or find a global scope
static unsigned int goto_label_unique_id
store a unique id used during the creation of the label_decl associated with a gimple_goto.
#define PREC_BIT_SIZE
#define ALGN_UNSIGNED_LONG_LONG_INT
Definition of the class representing a generic C application.
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
Definition: tree_node.hpp:672
#define PREC_INT
struct definition of the source position.
Definition: tree_node.hpp:832
tree_nodeRef CreateUnsigned(const tree_nodeConstRef &signed_type) const
Create an unsigned integer type starting from signed type.
mathematical utility function not provided by standard libraries
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
tree_nodeRef GetSizeType() const
create a sizetype builtin type in case it has not already been created, otherwise it returns the one ...
static unsigned long long int align(unsigned long long int address, unsigned long long int alignment)
STL includes.
Definition: memory.cpp:81
#define PREC_UNSIGNED_LONG_LONG_INT
static tree_nodeConstRef CGetElements(const tree_nodeConstRef &type)
Given an array or a vector return the element type.
unsigned int InlineFunctionCall(const tree_nodeRef &call_node, const tree_nodeRef &caller_node)
Execute function call inlining of given call statement (call graph must be recomputed after inlining)...
unsigned int get_next_available_tree_node_id() const
return the next available tree node id.
exceptions managed by PandA
void bb_remove_successor(blocRef &bb, const unsigned int &successor) const
Function that removes a successor in basic block bb.
tree_nodeRef CloneFunction(const tree_nodeRef &tn, const std::string &funNameSuffix)
CloneFunction duplicates a function.
tree_nodeRef create_binary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const std::string &srcp, enum kind operation_kind) const
Function used to create a binary expression.
tree_nodeRef GetSignedIntegerType() const
Function that creates a integer type if it is not already present, otherwise it returns the one that ...
void bb_add_successor(blocRef &bb, const unsigned int &successor) const
Function that adds a successor in basic block bb.
A simple interface to token object of the raw files.
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
tree_nodeRef CreateIntegerCst(const tree_nodeConstRef &type, integer_cst_t value, const unsigned int integer_cst_nid) const
CONST_OBJ_TREE_NODES.
#define min(x, y)
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
struct definition of the function_type tree node.
Definition: tree_node.hpp:2960
unsigned int get_next_vers()
Return the next unused version number for ssa variables.
Data structure describing a basic block at tree level.
#define PREC_UNSIGNED_INT
#define MIN_VALUE_UNSIGNED_LONG_LONG_INT
#define MIN_VALUE_BIT_SIZE
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
tree_nodeRef CreateAddrExpr(const tree_nodeConstRef &tn, const std::string &srcp) const
Create an addr_expr.
#define ALGN_BIT_SIZE
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
tree_nodeRef create_unary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op, const std::string &srcp, enum kind operation_kind) const
EXPRESSION_TREE_NODES.
bool
Definition: bellmanford.c:29
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
void bb_add_predecessor(blocRef &bb, const unsigned int &predecessor) const
Function that adds a predecessor in basic block bb.
tree_nodeRef CreateGimpleAssign(const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, const tree_nodeRef &op, unsigned int function_decl_nid, const std::string &srcp) const
Create gimple assignment.
#define SIZE_VALUE_UNSIGNED_INT
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
tree_nodeRef create_parm_decl(const tree_nodeRef &name, const tree_nodeConstRef &type, const tree_nodeRef &scpe, const tree_nodeConstRef &argt, const tree_nodeRef &smt_ann, const tree_nodeRef &init, const std::string &srcp, int used, bool register_flag=false, bool readonly_flag=false) const
DECL_NODES.
Auxiliary methods for manipulating string.
#define max
Definition: backprop.h:17
blocRef create_basic_block(std::map< unsigned int, blocRef > &list_of_bloc, std::vector< unsigned int > predecessors, std::vector< unsigned int > successors, std::vector< tree_nodeRef > stmt, unsigned int number, unsigned int true_edge=0, unsigned int false_edge=0, std::vector< tree_nodeRef > phi=std::vector< tree_nodeRef >()) const
BASIC BLOCK.
#define SIZE_VALUE_BIT_SIZE
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
static void addCallPointAndExpand(CustomUnorderedSet< unsigned int > &AV, const application_managerRef AM, unsigned int caller_id, unsigned int called_id, unsigned int call_id, enum FunctionEdgeInfo::CallType call_type, int DL)
#define MAX_VALUE_UNSIGNED_INT
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.
#define ALGN_VOID
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
void bb_set_true_edge(blocRef &bb, const unsigned int &true_edge_index) const
Function that sets in basic block bb the index of the if basic block in case the last statement is a ...
tree_nodeRef create_lut_expr(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const tree_nodeRef &op3, const tree_nodeRef &op4, const tree_nodeRef &op5, const tree_nodeRef &op6, const tree_nodeRef &op7, const tree_nodeRef &op8, const std::string &srcp) const
create_lut_expr: function used to create a generic lut_expr operation
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
void bb_remove_successors(blocRef &bb, const std::vector< unsigned int > &successors) const
Function that removes a list of successors in basic block bb.
tree_nodeRef CreateVectorBooleanType(const unsigned long long number_of_elements) const
Create a vector bool type.
#define ALGN_UNSIGNED_INT
tree_nodeRef GetPointerType(const tree_nodeConstRef &ptd, unsigned long long algn=0) const
Function that creates a pointer type if it is not already present, otherwise it returns the one that ...
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
APInt integer_cst_t
Definition: panda_types.hpp:47
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...
void create_goto(const blocRef &block, unsigned int function_decl_nid, unsigned int label_expr_nid) const
create a goto expression.
const application_managerRef AppM
Application manager data structure.
#define MIN_VALUE_INT
#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.
void bb_add_successors(blocRef &bb, const std::vector< unsigned int > &successors) const
Function that adds a list of successors in basic block bb.
unsigned int create_tree_node(const tree_nodeRef &tn, int mode=tree_node_dup_mode::DEFAULT)
tree_node visitors
void add_function(unsigned int index, tree_nodeRef curr)
Add to the function_decl_nodes the current node.
void bb_remove_predecessors(blocRef &bb, const std::vector< unsigned int > &predecessors) const
Function that removes a list of predecessors in basic block bb.
void bb_add_predecessors(blocRef &bb, const std::vector< unsigned int > &predecessors) const
Function that adds a list of predecessors in basic block bb.
void bb_remove_all_predecessors(blocRef &bb) const
Function that removes all the predecessors of basic block bb.
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.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
#define index(x, y)
Definition: Keccak.c:74
kind
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
Definition: tree_node.hpp:3750
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
tree_nodeRef create_result_decl(const tree_nodeRef &name, const tree_nodeRef &type, const tree_nodeRef &scpe, const tree_nodeRef &size, const tree_nodeRef &smt_ann, const tree_nodeRef &init, const std::string &srcp, unsigned int algn, bool artificial_flag=false) const
Function used to create a result_decl.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
constexpr T get_aligned_bitsize(T bitsize)
void add_goto()
Increment the number of added gotos.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
#define MAX_VALUE_BIT_SIZE
#define SIZE_VALUE_POINTER_M32
refcount< const tree_node > tree_nodeConstRef
Definition: tree_node.hpp:213
bool ends_with(const std::string &str, const std::string &pattern)
Classes specification of the tree_node data structures.
tree_nodeRef GetFunctionType(const tree_nodeConstRef &returnType, const std::vector< tree_nodeConstRef > &argsT) const
Create a function type.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
tree_nodeRef create_function_decl(const std::string &function_name, const tree_nodeRef &scpe, const std::vector< tree_nodeConstRef > &argsT, const tree_nodeConstRef &returnType, const std::string &srcp, bool with_body) const
create the declaration of a function without its body
#define MIN_VALUE_UNSIGNED_INT
const ParameterConstRef parameters
The set of input parameters.
tree_nodeRef GetBooleanType() const
Function that creates a boolean type if it is not already present, otherwise it returns the one that ...
This struct specifies the block node.
Definition: tree_node.hpp:1820
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
tree_nodeRef create_gimple_return(const tree_nodeConstRef &type, const tree_nodeConstRef &expr, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_RETURN.
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
tree_nodeRef GetCustomIntegerType(unsigned long long prec, bool unsigned_p) const
create an integer type starting from a given prec
Definition: APInt.hpp:53
void init(int bucket[BUCKETSIZE])
Definition: sort.c:42
tree_nodeRef CreateCallExpr(const tree_nodeConstRef &called_function, const std::vector< tree_nodeRef > &args, const std::string &srcp) const
Create a call_expr.
#define BUILTIN_SRCP
tree_nodeRef create_ternary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const std::string &srcp, enum kind operation_kind) const
Function used to create a ternary expression.
#define ALGN_POINTER_M32
#define SIZE_VALUE_UNSIGNED_LONG_LONG_INT
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
bool VersionFunctionCall(const tree_nodeRef &call_node, const tree_nodeRef &caller_node, const std::string &version_suffix)
Perform function call versioning.
struct definition of the type node structures.
Definition: tree_node.hpp:1318
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
#define ALGN_INT
#define MAX_VALUE_INT
tree_nodeRef GetUnsignedLongLongType() const
Function that creates a long long unsigned int type if it is not already present, otherwise return th...
void bb_remove_all_successors(blocRef &bb) const
Function that removes all the successors of basic block bb.
tree_nodeRef GetVoidType() const
TYPE_OBJ.
tree_nodeRef create_gimple_call(const tree_nodeConstRef &called_function, const std::vector< tree_nodeRef > &args, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_CALL.
void bb_add_stmts(blocRef &bb, const std::vector< tree_nodeRef > &stmt) const
Function that adds in basic block bb the statements listed in vector stmt.
tree_nodeRef CreateNopExpr(const tree_nodeConstRef &operand, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, unsigned int function_decl_nid) const
Create a nop_expr to perform a conversion.
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
tree_nodeRef GetUnsignedIntegerType() const
Function that creates a unsigned integer type if it is not already present, otherwise it returns the ...
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 MAX_VALUE_UNSIGNED_LONG_LONG_INT
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
tree_nodeRef create_extract_bit_expr(const tree_nodeRef &op0, const tree_nodeRef &op1, const std::string &srcp) const
tree_nodeRef create_ssa_name(const tree_nodeConstRef &var, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, bool volatile_flag=false, bool virtual_flag=false) const
MISCELLANEOUS_OBJ_TREE_NODES.
#define SIZE_VALUE_BOOL
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
tree node duplication class.
static std::string GetFunctionName(const tree_managerConstRef &TM, const tree_nodeConstRef &decl)
Return the name of the function.
Wrapper to call graph.
#define SIZE_VALUE_POINTER_M64
absl::node_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMapStable
Definition: custom_map.hpp:152
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
tree_nodeRef CreateGimpleAssignAddrExpr(const tree_nodeConstRef &tn, unsigned int function_decl_nid, const std::string &srcp) const
Create a gimple_assign with op0 a new ssa_name, and op1 an addr_expr which takes the address of the t...
#define ALGN_POINTER_M64
tree_nodeRef create_phi_node(tree_nodeRef &ssa_res, const std::vector< std::pair< tree_nodeRef, unsigned int >> &list_of_def_edge, unsigned int function_decl_nid, bool virtual_flag=false) const
GIMPLE_PHI.
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
const int debug_level
debug level.
const bool reuse
True if statements can be reused.
#define SIZE_VALUE_INT
tree_nodeRef create_identifier_node(const std::string &strg) const
IDENTIFIER_TREE_NODE.
tree_manipulation(const tree_managerRef &TreeM, const ParameterConstRef &parameters, const application_managerRef _AppM)
This is the constructor of the tree_manipulation.
tree_nodeRef create_gimple_modify_stmt(const tree_nodeRef &op0, const tree_nodeRef &op1, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_ASSIGN.
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 GetFunction(const std::string &function_name) const
Return the index of a function given its name.
tree_nodeRef CreateAndExpr(const tree_nodeConstRef &first_condition, const tree_nodeConstRef &second_condition, const blocRef &block, unsigned int function_decl_nid) const
Create an or expression.
#define ALGN_BOOLEAN
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
void bb_remove_predecessor(blocRef &bb, const unsigned int &predecessor) const
Function that removes a predecessor in basic block bb.
void create_label(const blocRef &block, unsigned int function_decl_nid) const
create a label expression in a header of a loop.
Class specification of the manager of the tree structures extracted from the raw file.
int sl
Definition: adpcm.c:105
tree_nodeRef create_var_decl(const tree_nodeRef &name, const tree_nodeConstRef &type, const tree_nodeRef &scpe, const tree_nodeRef &size, const tree_nodeRef &smt_ann, const tree_nodeRef &init, const std::string &srcp, unsigned int algn, int used, bool artificial_flag=false, int use_tmpl=-1, bool static_static_flag=false, bool extern_flag=false, bool static_flag=false, bool register_flag=false, bool readonly_flag=false, const std::string &bit_values="", bool addr_taken=false, bool addr_not_taken=false) const
Function used to create a var_decl.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

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