PandA-2024.02
operations_cfg_computation.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  */
45 #include "Parameter.hpp"
46 #include "application_manager.hpp"
47 #include "basic_block.hpp"
49 #include "behavioral_helper.hpp"
50 #include "call_graph_manager.hpp"
51 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
52 #include "design_flow_graph.hpp"
53 #include "design_flow_manager.hpp"
54 #include "ext_tree_node.hpp"
55 #include "function_behavior.hpp"
56 #include "graph.hpp"
57 #include "op_graph.hpp"
59 #include "string_manipulation.hpp" // for GET_CLASS
60 #include "token_interface.hpp"
61 #include "tree_basic_block.hpp"
62 #include "tree_helper.hpp"
63 #include "tree_manager.hpp"
64 #include "tree_node.hpp"
65 #include "tree_reindex.hpp"
66 
68  const application_managerRef _AppM, unsigned int _function_id,
69  const DesignFlowManagerConstRef _design_flow_manager)
70  : FunctionFrontendFlowStep(_AppM, _function_id, OPERATIONS_CFG_COMPUTATION, _design_flow_manager, _parameters)
71 {
72  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
73 }
74 
76 
79 {
81  switch(relationship_type)
82  {
84  {
85  if(parameters->getOption<bool>(OPT_parse_pragma))
86  {
87  relationships.insert(std::make_pair(EXTRACT_OMP_ATOMIC, SAME_FUNCTION));
88  }
89  relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION, SAME_FUNCTION));
90  relationships.insert(std::make_pair(LUT_TRANSFORMATION, SAME_FUNCTION));
91  relationships.insert(std::make_pair(BASIC_BLOCKS_CFG_COMPUTATION, SAME_FUNCTION));
92  break;
93  }
95  {
96  break;
97  }
99  {
100  if(!parameters->getOption<int>(OPT_gcc_openmp_simd))
101  {
102  relationships.insert(std::make_pair(BITVALUE_RANGE, SAME_FUNCTION));
103  }
104  relationships.insert(std::make_pair(BUILD_VIRTUAL_PHI, SAME_FUNCTION));
105  relationships.insert(std::make_pair(COND_EXPR_RESTRUCTURING, SAME_FUNCTION));
106  relationships.insert(std::make_pair(VECTORIZE, SAME_FUNCTION));
107  break;
108  }
109  default:
110  {
111  THROW_UNREACHABLE("");
112  }
113  }
114  return relationships;
115 }
116 
118 {
119  if(bb_version != 0)
120  {
121  function_behavior->ogc->Clear();
122  const BBGraphRef basic_block_graph = function_behavior->GetBBGraph(FunctionBehavior::BB);
123  if(boost::num_vertices(*basic_block_graph) != 0)
124  {
125  VertexIterator basic_block, basic_block_end;
126  for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph);
127  basic_block != basic_block_end; basic_block++)
128  {
129  basic_block_graph->GetBBNodeInfo(*basic_block)->statements_list.clear();
130  }
131  }
132  }
133 }
134 
136 {
137  const tree_managerRef TM = AppM->get_tree_manager();
138  const BBGraphRef fbb = function_behavior->GetBBGraph(FunctionBehavior::FBB);
139  VertexIterator v_iter, v_iter_end;
140  const BehavioralHelperConstRef helper = function_behavior->CGetBehavioralHelper();
141  const operations_graph_constructorRef& ogc = function_behavior->ogc;
142  const BasicBlocksGraphConstructorRef bbgc = function_behavior->bbgc;
143  const auto root_functions = AppM->CGetCallGraphManager()->GetRootFunctions();
144 
147  ogc->AddOperation(TM, ENTRY, ENTRY, BB_ENTRY, 0);
148  bbgc->add_operation_to_bb(ogc->getIndex(ENTRY), BB_ENTRY);
149  ogc->add_type(ENTRY, TYPE_ENTRY);
150 
151  ogc->AddOperation(TM, EXIT, EXIT, BB_EXIT, 0);
152  bbgc->add_operation_to_bb(ogc->getIndex(EXIT), BB_EXIT);
153  ogc->add_type(EXIT, TYPE_EXIT);
154 
155  std::string res;
156  std::string f_name = helper->get_function_name() + "_" + STR(function_id);
157 
158  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Computing label map");
160  for(boost::tie(v_iter, v_iter_end) = boost::vertices(*fbb); v_iter != v_iter_end; ++v_iter)
161  {
162  THROW_ASSERT(fbb->CGetBBGraphInfo()->exit_vertex, "Exit basic block not set");
163  if(*v_iter == fbb->CGetBBGraphInfo()->exit_vertex)
164  {
165  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Skipping exit vertex");
166  continue;
167  }
168  const BBNodeInfoConstRef bb_node_info = fbb->CGetBBNodeInfo(*v_iter);
169  const auto block = bb_node_info->block;
170  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Examining BB" + STR(block->number));
171  if(block->CGetStmtList().empty() and *v_iter != fbb->CGetBBGraphInfo()->entry_vertex and
172  *v_iter != fbb->CGetBBGraphInfo()->exit_vertex)
173  {
174  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_nop_schema;
175  const auto new_tree_node_id = TM->new_tree_node_id();
176  gimple_nop_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
177  gimple_nop_schema[TOK(TOK_SCPE)] = STR(function_id);
178  TM->create_tree_node(new_tree_node_id, gimple_nop_K, gimple_nop_schema);
179  auto gn = GetPointer<gimple_nop>(TM->GetTreeNode(new_tree_node_id));
180  gn->bb_index = block->number;
182  "---Created gimple_nop " + TM->get_tree_node_const(new_tree_node_id)->ToString());
183  block->PushBack(TM->GetTreeReindex(new_tree_node_id), AppM);
184  }
185  if(block->CGetStmtList().size())
186  {
187  auto front = block->CGetStmtList().front();
188  if(GET_NODE(front)->get_kind() == gimple_label_K)
189  {
190  auto* le = GetPointer<gimple_label>(GET_NODE(front));
191  THROW_ASSERT(le->op, "Label expr without object");
192  res = get_first_node(front, f_name);
193  label_decl_map[GET_INDEX_NODE(le->op)] = res;
194  }
195  else if(block->CGetPhiList().empty())
196  {
197  res = get_first_node(front, f_name);
198  }
199  else
200  {
201  res = get_first_node(block->CGetPhiList().front(), f_name);
202  }
203  }
204  else if(block->CGetPhiList().size())
205  {
206  res = get_first_node(block->CGetPhiList().front(), f_name);
207  }
208  else if(*v_iter == fbb->CGetBBGraphInfo()->entry_vertex)
209  {
210  res = ENTRY;
211  first_statement[block->number] = res;
212  continue;
213  }
214  else /*empty basic block*/
215  {
216  THROW_UNREACHABLE("");
217  }
218  first_statement[block->number] = res;
219  }
220  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Computed label map");
222  tree_nodeRef last_instruction;
223  for(boost::tie(v_iter, v_iter_end) = boost::vertices(*fbb); v_iter != v_iter_end; ++v_iter)
224  {
225  if(/* *v_iter == fbb->CGetBBGraphInfo()->entry_vertex || */ *v_iter == fbb->CGetBBGraphInfo()->exit_vertex)
226  {
227  continue;
228  }
229  const BBNodeInfoConstRef bb_node_info = fbb->CGetBBNodeInfo(*v_iter);
230  const auto block = bb_node_info->block;
232  "-->Building operation of basic block BB" + STR(block->number));
233  bool skip_first_stmt = false;
234  if(block->CGetStmtList().size())
235  {
236  const auto front = block->CGetStmtList().front();
237  if(GET_NODE(front)->get_kind() == gimple_label_K)
238  {
239  actual_name = get_first_node(front, f_name);
241  "the name of the first vertice has to be the same of the label expression vertex");
242  if(!empty_start_nodes())
243  {
245  }
247  build_operation_recursive(TM, ogc, front, f_name, block->number);
248  bbgc->add_operation_to_bb(ogc->getIndex(actual_name), block->number);
249  skip_first_stmt = true;
250  }
251  }
252  for(const auto& phi : block->CGetPhiList())
253  {
254  actual_name = get_first_node(phi, f_name);
256  if(!empty_start_nodes())
257  {
259  }
261  build_operation_recursive(TM, ogc, phi, f_name, block->number);
262  bbgc->add_operation_to_bb(ogc->getIndex(actual_name), block->number);
264  }
266  "---List of operations size " + STR(block->CGetStmtList().size()));
267  auto s_end = block->CGetStmtList().end();
268  auto s = block->CGetStmtList().begin();
269  if(skip_first_stmt)
270  {
271  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Skipped first statement");
272  s++;
273  }
274  for(; s != s_end; s++)
275  {
276  actual_name = get_first_node(*s, f_name);
277  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Analyzing operation " + actual_name);
278  if(!empty_start_nodes())
279  {
281  }
283  build_operation_recursive(TM, ogc, *s, f_name, block->number);
284  bbgc->add_operation_to_bb(ogc->getIndex(actual_name), block->number);
285  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Analyzed operation " + actual_name);
286  }
288  if(block->CGetStmtList().empty())
289  {
290  if(!block->CGetPhiList().empty())
291  {
292  last_instruction = block->CGetPhiList().back();
293  }
294  else
295  {
296  last_instruction = tree_nodeRef();
297  }
298  }
299  else if(block->CGetStmtList().size() == 1 && skip_first_stmt)
300  {
301  if(block->CGetPhiList().size())
302  {
303  last_instruction = block->CGetPhiList().back();
304  }
305  else
306  {
307  last_instruction = block->CGetStmtList().back();
308  }
309  }
310  else
311  {
312  last_instruction = block->CGetStmtList().back();
313  }
314  if(last_instruction && GET_NODE(last_instruction)->get_kind() != gimple_switch_K)
315  {
316  init_start_nodes(get_first_node(last_instruction, f_name));
317  }
318  else if(!last_instruction)
319  {
321  }
322  if(block->list_of_succ.size() == 0 and root_functions.find(function_id) != root_functions.end())
323  {
324  std::list<std::string>::iterator operation, operation_end = start_nodes.end();
325  for(operation = start_nodes.begin(); operation != operation_end; ++operation)
326  {
327  ogc->add_type(*operation, TYPE_LAST_OP);
328  }
329  }
330  else
331  {
332  for(const auto successor : block->list_of_succ)
333  {
334  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Considering successor BB" + STR(successor));
335  if(successor == bloc::EXIT_BLOCK_ID)
336  {
338  if(root_functions.find(function_id) != root_functions.end())
339  {
340  std::list<std::string>::iterator operation, operation_end = start_nodes.end();
341  for(operation = start_nodes.begin(); operation != operation_end; ++operation)
342  {
343  ogc->add_type(*operation, TYPE_LAST_OP);
344  }
345  }
346  }
347  else
348  {
349  if(successor == block->true_edge)
350  {
351  connect_start_nodes(ogc, first_statement[successor], true, false);
352  }
353  else if(successor == block->false_edge)
354  {
355  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Successor is on the false edge");
356  THROW_ASSERT(first_statement.find(successor) != first_statement.end(),
357  "First statement of successor BB" + STR(successor) + " not found");
358  connect_start_nodes(ogc, first_statement[successor], false, true);
359  }
360  else if(last_instruction && GetPointer<gimple_goto>(GET_NODE(last_instruction)) &&
361  block->list_of_succ.size() > 1)
362  {
363  connect_start_nodes(ogc, first_statement[successor], true, true, successor);
364  }
365  else
366  {
367  connect_start_nodes(ogc, first_statement[successor]);
368  }
369  }
370  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered successor BB" + STR(successor));
371  }
372  }
375  }
376  label_decl_map.clear();
377  first_statement.clear();
379 
380  if(parameters->getOption<bool>(OPT_print_dot))
381  {
382  function_behavior->CGetOpGraph(FunctionBehavior::CFG)->WriteDot("OP_CFG_Cleaned.dot");
383  }
385 }
386 
387 std::string operations_cfg_computation::get_first_node(const tree_nodeRef& tn, const std::string& f_name) const
388 {
389  tree_nodeRef curr_tn;
390  if(tn->get_kind() == tree_reindex_K)
391  {
392  curr_tn = GET_NODE(tn);
393  }
394  else
395  {
396  curr_tn = tn;
397  }
398  auto ind = GET_INDEX_NODE(tn);
399  std::string src;
400  src = f_name + "_" + STR(ind);
401 
402  switch(curr_tn->get_kind())
403  {
404  case CASE_GIMPLE_NODES:
405  return src;
406  case case_label_expr_K:
407  {
408  auto* cle = GetPointer<case_label_expr>(curr_tn);
409  ind = GET_INDEX_NODE(cle->got);
410  THROW_ASSERT(label_decl_map.find(ind) != label_decl_map.end(), "Label " + STR(ind) + " doesn't exist");
411  return label_decl_map.find(ind)->second;
412  }
413  case binfo_K:
414  case block_K:
415  case constructor_K:
416  case call_expr_K:
417  case aggr_init_expr_K:
418  case identifier_node_K:
419  case ssa_name_K:
420  case statement_list_K:
421  case target_expr_K:
422  case target_mem_ref_K:
423  case target_mem_ref461_K:
424  case tree_list_K:
425  case tree_vec_K:
426  case error_mark_K:
428  case CASE_CPP_NODES:
429  case CASE_CST_NODES:
430  case CASE_DECL_NODES:
431  case CASE_FAKE_NODES:
432  case CASE_PRAGMA_NODES:
435  case CASE_TYPE_NODES:
437  case lut_expr_K:
438  default:
439  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, std::string("Node not supported (") + STR(ind) +
440  std::string("): ") + curr_tn->get_kind_text());
441  }
442  return "";
443 }
444 
445 void operations_cfg_computation::insert_start_node(const std::string& start_node)
446 {
447  start_nodes.push_back(start_node);
448 }
449 
451 {
452  start_nodes.clear();
453 }
454 
456 {
457  return start_nodes.empty();
458 }
459 
460 void operations_cfg_computation::init_start_nodes(const std::string& start_node)
461 {
462  start_nodes.clear();
463  start_nodes.push_back(start_node);
464 }
465 
466 void operations_cfg_computation::connect_start_nodes(const operations_graph_constructorRef ogc, const std::string& next,
467  bool true_edge, bool false_edge, unsigned int nodeid)
468 {
469  const auto root_functions = AppM->CGetCallGraphManager()->GetRootFunctions();
470  for(const auto& Start_node : start_nodes)
471  {
473  if(root_functions.count(function_id) && Start_node == ENTRY)
474  {
475  ogc->add_type(next, TYPE_FIRST_OP);
476  }
477  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding edge from " + Start_node + " to " + next);
478  ogc->AddEdge(ogc->getIndex(Start_node), ogc->getIndex(next), CFG_SELECTOR);
479  if(true_edge && false_edge)
480  {
481  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding label " + STR(nodeid));
482  ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next), CFG_SELECTOR, nodeid);
483  }
484  if(true_edge && !false_edge)
485  {
486  ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next), CFG_SELECTOR, T_COND);
487  }
488  if(false_edge && !true_edge)
489  {
490  ogc->add_edge_info(ogc->getIndex(Start_node), ogc->getIndex(next), CFG_SELECTOR, F_COND);
491  }
492  }
493 }
494 
496  const operations_graph_constructorRef ogc,
497  const tree_nodeRef tn, const std::string& f_name,
498  unsigned int bb_index)
499 {
500  const auto curr_tn = GET_NODE(tn);
501  const auto ind = GET_INDEX_NODE(tn);
503  "-->Building CFG of node " + STR(ind) + " of type " + curr_tn->get_kind_text());
504  switch(curr_tn->get_kind())
505  {
506  case gimple_return_K:
507  {
508  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
509  ogc->add_type(actual_name, TYPE_RET);
510  break;
511  }
512  case gimple_assign_K:
513  {
514  const auto me = GetPointerS<const gimple_assign>(curr_tn);
515  const auto op0_kind = GET_NODE(me->op0)->get_kind();
516  const auto op1_kind = GET_NODE(me->op1)->get_kind();
517  const auto op0_type = tree_helper::CGetType(me->op0);
518  const auto op1_type = tree_helper::CGetType(me->op1);
519  const auto& fun_mem_data = function_behavior->get_function_mem();
520 
521  const auto load_candidate = tree_helper::IsLoad(tn, fun_mem_data);
522  const auto store_candidate = tree_helper::IsStore(tn, fun_mem_data);
523 
524  if(!me->clobber && !tree_helper::IsVectorType(me->op0) &&
525  ((((tree_helper::IsArrayEquivType(me->op0) && !tree_helper::IsPointerType(me->op0))) ||
526  op1_kind == constructor_K)))
527  {
528  if(!tree_helper::IsArrayEquivType(me->op0) ||
529  (((op1_kind == constructor_K || (op1_kind == var_decl_K && GetPointerS<const var_decl>(me->op1)->init) ||
530  op1_kind == string_cst_K)) &&
531  (GetPointer<const decl_node>(me->op0) || op0_kind == ssa_name_K)))
532  {
533  function_behavior->GetBehavioralHelper()->add_initialization(me->op0->index, me->op1->index);
534  ogc->add_type(actual_name, TYPE_INIT);
535  }
536  }
537 
538  if(me->init_assignment || me->clobber)
539  {
540  ogc->AddOperation(TM, actual_name, NOP, bb_index, me->index);
541  ogc->add_type(actual_name, TYPE_NOP);
542  }
543  else if(op1_kind == float_expr_K)
544  {
545  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - set as float_expr_xx_to_xxx operation");
546  const auto fe = GetPointerS<const float_expr>(GET_CONST_NODE(me->op1));
547  auto size_dest = tree_helper::Size(fe->type);
548  auto size_from = tree_helper::Size(fe->op);
549  if(size_from < 32)
550  {
551  size_from = 32;
552  }
553  else if(size_from > 32 && size_from < 64)
554  {
555  size_from = 64;
556  }
557  ogc->AddOperation(TM, actual_name, FLOAT_EXPR + STR("_") + STR(size_from) + "_to_" + STR(size_dest),
558  bb_index, me->index);
559  ogc->add_type(actual_name, TYPE_GENERIC);
560  }
561  else if(op1_kind == fix_trunc_expr_K)
562  {
563  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - set as fix_trunc_expr_xx_to_xxx operation");
564  const auto fte = GetPointerS<const fix_trunc_expr>(GET_CONST_NODE(me->op1));
565  auto size_dest = tree_helper::Size(fte->type);
566  const auto is_unsigned = tree_helper::IsUnsignedIntegerType(fte->type);
567  const auto size_from = tree_helper::Size(fte->op);
568  if(size_dest < 32)
569  {
570  size_dest = 32;
571  }
572  else if(size_dest > 32 && size_dest < 64)
573  {
574  size_dest = 64;
575  }
576  ogc->AddOperation(TM, actual_name,
577  FIX_TRUNC_EXPR + STR("_") + STR(size_from) + "_to_" + (is_unsigned ? "u" : "") +
578  STR(size_dest),
579  bb_index, me->index);
580  ogc->add_type(actual_name, TYPE_GENERIC);
581  }
582  else if(tree_helper::IsVectorType(me->op0) && op1_kind == constructor_K)
583  {
584  PRINT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, " - set as VECTOR CONCATENATION operation");
585  const auto co = GetPointerS<const constructor>(GET_CONST_NODE(me->op1));
586  const auto size_obj = tree_helper::Size(co->type);
587  const auto n_byte = size_obj / 8;
588  ogc->AddOperation(TM, actual_name,
589  VECT_CONCATENATION + STR("_") + STR(n_byte) + "_" + STR(co->list_of_idx_valu.size()),
590  bb_index, me->index);
591  ogc->add_type(actual_name, TYPE_GENERIC);
592  }
593  else if(op1_kind == complex_expr_K)
594  {
595  ogc->AddOperation(TM, actual_name, tree_node::GetString(op1_kind), bb_index, me->index);
596  ogc->add_type(actual_name, TYPE_GENERIC);
597  }
598  else if(!store_candidate && (op0_kind == realpart_expr_K || op0_kind == imagpart_expr_K))
599  {
600  ogc->AddOperation(TM, actual_name, tree_node::GetString(op0_kind) + "_write", bb_index, me->index);
601  ogc->add_type(actual_name, TYPE_GENERIC);
602  }
603  else if(op0_type && op1_type && GET_CONST_NODE(me->op1)->get_kind() != insertvalue_expr_K &&
604  GET_CONST_NODE(me->op1)->get_kind() != extractvalue_expr_K &&
605  ((GET_CONST_NODE(op0_type)->get_kind() == record_type_K &&
606  GET_CONST_NODE(op1_type)->get_kind() == record_type_K && op1_kind != view_convert_expr_K) ||
607  (GET_CONST_NODE(op0_type)->get_kind() == union_type_K &&
608  GET_CONST_NODE(op1_type)->get_kind() == union_type_K && op1_kind != view_convert_expr_K) ||
609  (GET_CONST_NODE(op0_type)->get_kind() == array_type_K) ||
610  (fun_mem_data.count(GET_INDEX_NODE(me->op0)) && fun_mem_data.count(GET_INDEX_NODE(me->op1))) ||
611  (fun_mem_data.count(GET_INDEX_NODE(me->op0)) && load_candidate) ||
612  (store_candidate && fun_mem_data.count(GET_INDEX_NODE(me->op1)))))
613  {
614  if(op1_kind == constructor_K && GetPointer<const constructor>(GET_CONST_NODE(me->op1)) &&
615  GetPointer<const constructor>(GET_CONST_NODE(me->op1))->list_of_idx_valu.empty())
616  {
617  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---set as MEMSET operation");
618  ogc->AddOperation(TM, actual_name, MEMSET, bb_index, me->index);
619  ogc->add_type(actual_name, TYPE_GENERIC);
620  }
621  else
622  {
623  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---set as MEMCPY operation");
624  ogc->AddOperation(TM, actual_name, MEMCPY, bb_index, me->index);
625  ogc->add_type(actual_name, TYPE_MEMCPY);
626  }
627  }
628  else if(store_candidate || fun_mem_data.count(GET_INDEX_NODE(me->op0)))
629  {
630  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---set as STORE operation");
631  ogc->AddOperation(TM, actual_name, "STORE", bb_index, me->index);
632  ogc->add_type(actual_name, TYPE_STORE);
633  }
634  else if(load_candidate || fun_mem_data.count(GET_INDEX_NODE(me->op1)))
635  {
636  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---set as LOAD operation");
637  ogc->AddOperation(TM, actual_name, "LOAD", bb_index, me->index);
638  ogc->add_type(actual_name, TYPE_LOAD);
639  }
640  else
641  {
642  ogc->AddOperation(TM, actual_name, ASSIGN, bb_index, me->index);
643  ogc->add_type(actual_name, TYPE_ASSIGN);
644  build_operation_recursive(TM, ogc, me->op1, f_name, bb_index);
645  }
646  if(me->predicate)
647  {
648  ogc->add_type(actual_name, TYPE_PREDICATED);
649  }
650  break;
651  }
652  case gimple_pragma_K:
653  case gimple_nop_K:
654  {
655  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
656  ogc->add_type(actual_name, TYPE_NOP);
657  break;
658  }
659  case call_expr_K:
660  case aggr_init_expr_K:
661  {
662  const auto ce = GetPointerS<const call_expr>(curr_tn);
663  const function_decl* fd = nullptr;
664 
665  if(GET_CONST_NODE(ce->fn)->get_kind() == addr_expr_K)
666  {
667  const auto ue = GetPointerS<const unary_expr>(GET_CONST_NODE(ce->fn));
668  fd = GetPointerS<const function_decl>(GET_CONST_NODE(ue->op));
669  }
670  else if(GET_CONST_NODE(ce->fn)->get_kind() == obj_type_ref_K)
671  {
672  const auto fu_node = tree_helper::find_obj_type_ref_function(GET_CONST_NODE(ce->fn));
673  fd = GetPointerS<const function_decl>(GET_CONST_NODE(fu_node));
674  }
675  if(fd)
676  {
677  std::string fun_name = tree_helper::print_function_name(TM, fd);
678  fun_name = tree_helper::NormalizeTypename(fun_name);
679  // const std::string builtin_prefix("__builtin_");
680  // if(fun_name.find(builtin_prefix) == 0)
681  // fun_name = fun_name.substr(builtin_prefix.size());
682 
683  // Creating node of call
684  ogc->AddOperation(TM, actual_name, fun_name, bb_index, 0);
685  unsigned type_external = TYPE_EXTERNAL;
686  if(fd->writing_memory || fd->reading_memory)
687  {
688  type_external = type_external | TYPE_RW;
689  }
690  ogc->add_type(actual_name, type_external);
691  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---set as TYPE_EXTERNAL operation");
692  if(fun_name == "exit" || fun_name == "abort" || fun_name == "__builtin_exit" ||
693  fun_name == "__builtin_abort")
694  {
695  ogc->add_type(actual_name, TYPE_LAST_OP);
696  }
697 #if HAVE_FROM_PRAGMA_BUILT
698  if(fd->omp_atomic)
699  {
700  ogc->add_type(actual_name, TYPE_ATOMIC);
701  }
702 #endif
703  ogc->add_called_function(actual_name, fd->index);
704  }
705  else
706  {
707  // Call of not an usual function decl (for example array_ref of an array of function pointer)
708  // This call is needed to set the basic block index of this operation. Otherwise
709  // vertex is created but basic block index is not setted
710  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
711  }
712  break;
713  }
714  case gimple_call_K:
715  {
716  const auto ce = GetPointerS<const gimple_call>(curr_tn);
717  const function_decl* fd = nullptr;
718 
719  if(GET_CONST_NODE(ce->fn)->get_kind() == addr_expr_K)
720  {
721  const auto ue = GetPointerS<const unary_expr>(GET_CONST_NODE(ce->fn));
722  fd = GetPointerS<const function_decl>(GET_CONST_NODE(ue->op));
723  }
724  else if(GET_CONST_NODE(ce->fn)->get_kind() == obj_type_ref_K)
725  {
726  const auto fu_node = tree_helper::find_obj_type_ref_function(GET_CONST_NODE(ce->fn));
727  fd = GetPointerS<const function_decl>(GET_CONST_NODE(fu_node));
728  }
729  if(fd)
730  {
732  {
733  ogc->AddOperation(TM, actual_name, NOP, bb_index, ce->index);
734  ogc->add_type(actual_name, TYPE_NOP);
735  }
736  else
737  {
738  std::string fun_name = tree_helper::print_function_name(TM, fd);
739  fun_name = tree_helper::NormalizeTypename(fun_name);
740  // const std::string builtin_prefix("__builtin_");
741  // if(fun_name.find(builtin_prefix) == 0)
742  // fun_name = fun_name.substr(builtin_prefix.size());
743 
744  // Creating node of call
745  ogc->AddOperation(TM, actual_name, fun_name, bb_index, ce->index);
746  unsigned int type_external = TYPE_EXTERNAL;
747  if(fd->writing_memory || fd->reading_memory)
748  {
749  type_external = type_external | TYPE_RW;
750  }
751  ogc->add_type(actual_name, type_external);
752  if(fun_name == "exit" || fun_name == "abort" || fun_name == "__builtin_exit" ||
753  fun_name == "__builtin_abort")
754  {
755  ogc->add_type(actual_name, TYPE_LAST_OP);
756  }
757 #if HAVE_FROM_PRAGMA_BUILT
758  if(fd->omp_atomic)
759  {
760  ogc->add_type(actual_name, TYPE_ATOMIC);
761  }
762 #endif
763  ogc->add_called_function(actual_name, fd->index);
764  }
765  }
766  else
767  {
768  // Call of not an usual function decl (for example array_ref of an array of function pointer)
769  // This call is needed to set the basic block index of this operation. Otherwise
770  // vertex is created but basic block index is not setted
771  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, ce->index);
772  }
773  break;
774  }
775  case gimple_goto_K:
776  {
777  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
778  ogc->add_type(actual_name, TYPE_GOTO);
779  break;
780  }
781  case gimple_label_K:
782  {
783  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
784  const auto le = GetPointerS<const gimple_label>(curr_tn);
785  THROW_ASSERT(le->op, "expected a gimple_label operand");
786  const auto ld = GetPointerS<const label_decl>(GET_CONST_NODE(le->op));
787  if(ld->artificial_flag)
788  {
789  ogc->add_type(actual_name, TYPE_NOP);
790  }
791  else
792  {
793  ogc->add_type(actual_name, TYPE_LABEL);
794  }
795  break;
796  }
797  case gimple_cond_K:
798  {
799  const auto gc = GetPointerS<const gimple_cond>(curr_tn);
800  ogc->AddOperation(TM, actual_name, READ_COND, bb_index, gc->index);
801  build_operation_recursive(TM, ogc, gc->op0, f_name, bb_index);
802  ogc->add_type(actual_name, TYPE_IF);
803  break;
804  }
805  case gimple_multi_way_if_K:
806  {
807  ogc->AddOperation(TM, actual_name, MULTI_READ_COND, bb_index, curr_tn->index);
808  ogc->add_type(actual_name, TYPE_MULTIIF);
809  break;
810  }
811  case gimple_while_K:
812  {
813  const auto we = GetPointerS<const gimple_while>(curr_tn);
814  ogc->AddOperation(TM, actual_name, READ_COND, bb_index, curr_tn->index);
815  build_operation_recursive(TM, ogc, we->op0, f_name, bb_index);
816  ogc->add_type(actual_name, TYPE_WHILE);
817  break;
818  }
819  case gimple_for_K:
820  {
821  ogc->AddOperation(TM, actual_name, READ_COND, bb_index, curr_tn->index);
822  ogc->add_type(actual_name, TYPE_FOR);
823  break;
824  }
825  case gimple_switch_K:
826  {
827  const auto se = GetPointerS<const gimple_switch>(curr_tn);
828 
829  ogc->AddOperation(TM, actual_name, SWITCH_COND, bb_index, curr_tn->index);
830  build_operation_recursive(TM, ogc, se->op0, actual_name, bb_index);
831  ogc->add_type(actual_name, TYPE_SWITCH);
832 
833  tree_nodeConstRef case_label_exprs;
834  if(se->op1)
835  {
836  case_label_exprs = GET_CONST_NODE(se->op1);
837  }
838  else
839  {
841  std::string("op2 in gimple_switch not yet supported (") + STR(ind) + std::string(")"));
842  }
843  if(case_label_exprs->get_kind() == tree_vec_K)
844  {
845  const auto tv = GetPointerS<const tree_vec>(case_label_exprs);
846  for(const auto& i : tv->list_of_op)
847  {
848  const auto res = get_first_node(i, f_name);
849  THROW_ASSERT(res != "", "Impossible to find first operation of case " + STR(GET_INDEX_CONST_NODE(i)));
850  if(GET_CONST_NODE(i)->get_kind() == case_label_expr_K)
851  {
852  const auto cl = GetPointerS<const case_label_expr>(GET_CONST_NODE(i));
853  if(cl->default_flag)
854  {
855  connect_start_nodes(ogc, res, true, true, default_COND);
856  }
857  else
858  {
859  connect_start_nodes(ogc, res, true, true, GET_INDEX_CONST_NODE(i));
860  }
861  }
862  else
863  {
864  connect_start_nodes(ogc, res, true, true, GET_INDEX_CONST_NODE(i));
865  }
866  }
867  }
868  else
869  {
870  THROW_ERROR(std::string("expected tree_vec in op1 in gimple_switch (") + STR(ind) + std::string(")"));
871  }
872  break;
873  }
875  {
876  const auto ue = GetPointerS<const unary_expr>(curr_tn);
877  build_operation_recursive(TM, ogc, ue->op, f_name, bb_index);
878  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
879  ogc->add_type(actual_name, TYPE_GENERIC);
880  break;
881  }
883  {
884  const auto be = GetPointerS<const binary_expr>(curr_tn);
885  build_operation_recursive(TM, ogc, be->op0, f_name, bb_index);
886  build_operation_recursive(TM, ogc, be->op1, f_name, bb_index);
887  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
888  ogc->add_type(actual_name, TYPE_GENERIC);
889  break;
890  }
892  {
893  const auto te = GetPointerS<const ternary_expr>(curr_tn);
894  build_operation_recursive(TM, ogc, te->op0, f_name, bb_index);
895  if(te->op1)
896  {
897  build_operation_recursive(TM, ogc, te->op1, f_name, bb_index);
898  }
899  if(te->op2)
900  {
901  build_operation_recursive(TM, ogc, te->op2, f_name, bb_index);
902  }
903  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
904  ogc->add_type(actual_name, TYPE_GENERIC);
905  break;
906  }
908  {
909  const auto qe = GetPointerS<const quaternary_expr>(curr_tn);
910  build_operation_recursive(TM, ogc, qe->op0, f_name, bb_index);
911  if(qe->op1)
912  {
913  build_operation_recursive(TM, ogc, qe->op1, f_name, bb_index);
914  }
915  if(qe->op2)
916  {
917  build_operation_recursive(TM, ogc, qe->op2, f_name, bb_index);
918  }
919  if(qe->op3)
920  {
921  build_operation_recursive(TM, ogc, qe->op3, f_name, bb_index);
922  }
923  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
924  ogc->add_type(actual_name, TYPE_GENERIC);
925  break;
926  }
927  case lut_expr_K:
928  {
929  const auto le = GetPointerS<const lut_expr>(curr_tn);
930  build_operation_recursive(TM, ogc, le->op0, f_name, bb_index);
931  build_operation_recursive(TM, ogc, le->op1, f_name, bb_index);
932  if(le->op2)
933  {
934  build_operation_recursive(TM, ogc, le->op2, f_name, bb_index);
935  }
936  if(le->op3)
937  {
938  build_operation_recursive(TM, ogc, le->op3, f_name, bb_index);
939  }
940  if(le->op4)
941  {
942  build_operation_recursive(TM, ogc, le->op4, f_name, bb_index);
943  }
944  if(le->op5)
945  {
946  build_operation_recursive(TM, ogc, le->op5, f_name, bb_index);
947  }
948  if(le->op6)
949  {
950  build_operation_recursive(TM, ogc, le->op6, f_name, bb_index);
951  }
952  if(le->op7)
953  {
954  build_operation_recursive(TM, ogc, le->op7, f_name, bb_index);
955  }
956  if(le->op8)
957  {
958  build_operation_recursive(TM, ogc, le->op8, f_name, bb_index);
959  }
960  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, 0);
961  ogc->add_type(actual_name, TYPE_GENERIC);
962  break;
963  }
964  case ssa_name_K:
965  case integer_cst_K:
966  case real_cst_K:
967  case string_cst_K:
968  case vector_cst_K:
969  case void_cst_K:
970  case complex_cst_K:
971  case constructor_K:
972  case target_mem_ref_K:
973  case target_mem_ref461_K:
974  case CASE_DECL_NODES:
975  {
976  break;
977  }
978  case gimple_asm_K:
979  {
980  const auto ae = GetPointerS<const gimple_asm>(curr_tn);
981  if(!ae->volatile_flag && (ae->in && ae->out))
982  {
983  ogc->add_type(actual_name, TYPE_GENERIC);
984  }
985  else
986  {
987  ogc->add_type(actual_name, TYPE_GENERIC | TYPE_OPAQUE);
988  }
989  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
990  break;
991  }
992  case gimple_phi_K:
993  {
994  const auto phi = GetPointerS<const gimple_phi>(curr_tn);
995  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
996  ogc->add_type(actual_name, phi->virtual_flag ? TYPE_VPHI : TYPE_PHI);
997  break;
998  }
999  case CASE_CPP_NODES:
1000 
1001  {
1002  ogc->AddOperation(TM, actual_name, curr_tn->get_kind_text(), bb_index, curr_tn->index);
1003  ogc->add_type(actual_name, TYPE_GENERIC);
1004  break;
1005  }
1006  case binfo_K:
1007  case block_K:
1008  case case_label_expr_K:
1009  case gimple_bind_K:
1010  case gimple_predict_K:
1011  case gimple_resx_K:
1012  case identifier_node_K:
1013  case statement_list_K:
1014  case tree_list_K:
1015  case tree_vec_K:
1016  case CASE_FAKE_NODES:
1017  case CASE_PRAGMA_NODES:
1018  case CASE_TYPE_NODES:
1019  case target_expr_K:
1020  case error_mark_K:
1021  default:
1022  {
1023  THROW_UNREACHABLE("");
1024  }
1025  }
1026  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Built CFG of node " + STR(ind));
1027 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
static bool IsStore(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign writing something which will be allocated in memory...
#define TYPE_SWITCH
constant identifying the node type of a SWITCH operation.
Definition: op_graph.hpp:105
#define EXIT
Definition: global.h:46
#define TYPE_NOP
constant string identifying a type for a no operation.
Definition: op_graph.hpp:130
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool is_a_nop_function_decl(const function_decl *fd)
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define MEMCPY
constant string identifying the operation performed when two objects are memcopied.
Definition: op_graph.hpp:310
Basic block control flow graph.
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;.
DesignFlowStep_Status InternalExec() override
Computes the operations CFG graph data structure.
#define FLOAT_EXPR
constant string identifying integer to float conversions
Definition: op_graph.hpp:340
std::string ToString() const
Print this node as string in gimple format.
#define TYPE_PREDICATED
Constant identifying a predicated operation.
Definition: op_graph.hpp:212
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
#define TYPE_MULTIIF
constant identifying the a multi-way if
Definition: op_graph.hpp:202
#define TYPE_VPHI
constant string identifying an operation node of type virtual phi-nodes
Definition: op_graph.hpp:162
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
#define BB_EXIT
constant identifying the basic block node of type exit
#define TYPE_IF
constant identifying the node type of an IF operation.
Definition: op_graph.hpp:100
Definition of the class representing a generic C application.
static bool IsArrayEquivType(const tree_nodeConstRef &type)
Return true if treenode is an array or it is equivalent to an array (record recursively having a sing...
#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
RelationshipType
The relationship type.
struct definition of the function_decl tree node.
Definition: tree_node.hpp:2759
Source must be executed to satisfy target.
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
Definition: tree_node.cpp:120
~operations_cfg_computation() override
Destructor.
Class specification of the graph structures.
Analysis step creating the control flow graph for the operations.
#define READ_COND
constant string identifying the operation performed by a READ_COND.
Definition: op_graph.hpp:255
std::map< unsigned int, std::string > label_decl_map
relation between label declaration and first statement id
A simple interface to token object of the raw files.
void connect_start_nodes(const operations_graph_constructorRef ogc, const std::string &next, bool true_edge=false, bool false_edge=false, unsigned int nodeid=0)
Connect start_node with the next node.
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
void build_operation_recursive(const tree_managerRef TM, const operations_graph_constructorRef ogc, const tree_nodeRef tn, const std::string &f_name, unsigned int bb_index)
Builds recursively the operation for a given tree node.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:361
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
#define TYPE_INIT
Constant string identifying an operation that is a variable initialization.
Definition: op_graph.hpp:167
This class provides methods to build a basic blocks graph.
#define TYPE_FIRST_OP
A vertex of type FIRST_OP if it is the first operation of the application.
Definition: op_graph.hpp:192
Node not yet supported.
Definition: exceptions.hpp:323
Data structure describing a basic block at tree level.
unsigned int bb_version
The version of the basic block intermediate representation on which this step has been applied...
void clean_start_nodes()
Clean the list of start nodes.
#define VECT_CONCATENATION
constant string identifying the operation performed when a vector concatenation is considered...
Definition: op_graph.hpp:325
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
#define TYPE_LOAD
Constant string identifying a memory load operation.
Definition: op_graph.hpp:172
#define TYPE_PHI
constant string identifying an operation node of type PHI
Definition: op_graph.hpp:135
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
#define MEMSET
constant string identifying the operation performed when two objects are memsetted.
Definition: op_graph.hpp:320
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 TYPE_LABEL
A vertex is of type TYPE_LABEL when it is a target of a goto expression.
Definition: op_graph.hpp:151
#define TYPE_EXIT
constant identifying the node type of an exit node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
operations_cfg_computation(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
#define TYPE_GOTO
A vertex is of type TYPE_GOTO when it is associated with a goto expression.
Definition: op_graph.hpp:157
This class specifies the characteristic of a particular operation working on a given functional unit...
#define ENTRY
Superclass include.
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
Control flow graph.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
#define TYPE_ATOMIC
Constant identifying an atomic operation.
Definition: op_graph.hpp:207
#define TYPE_EXTERNAL
constant identifying the node type of a EXTERNAL operation (a function call)
Definition: op_graph.hpp:95
#define default_COND
constant used to represent label "default" of a switch construct
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.
Classes to describe design flow graph.
Basic block control flow graph with feedback.
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
std::string actual_name
store the name of the current vertex
std::map< unsigned int, std::string > first_statement
relation between basic block and first statement id
#define TYPE_STORE
Constant string identifying a memory store operation.
Definition: op_graph.hpp:177
#define BB_ENTRY
constant identifying the basic block node of type entry
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
#define TYPE_FOR
constant string identifying the node type of an WHILE operation.
Definition: op_graph.hpp:115
#define T_COND
constant used to represent control edges representing a true edge of a conditional statement...
#define TYPE_RW
Constant identifying if a TYPE_EXTERNAL write or read memory.
Definition: op_graph.hpp:217
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Definition: graph.hpp:1307
Classes specification of the tree_node data structures.
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
#define FIX_TRUNC_EXPR
constant string identifying float to integer conversions
Definition: op_graph.hpp:345
Wrapper of design_flow.
This struct specifies the block node.
Definition: tree_node.hpp:1820
bool empty_start_nodes() const
Return true if start_node is empty.
#define TYPE_ASSIGN
constant string identifying the node type of an ASSIGN operation.
Definition: op_graph.hpp:125
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
#define SWITCH_COND
constant string identifying the operation performed by a SWITCH_COND.
Definition: op_graph.hpp:265
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
static tree_nodeRef find_obj_type_ref_function(const tree_nodeConstRef &tn)
Given the tree_node of an obj_type_ref return the tree_node of the called function.
BBNodeInfoRef GetBBNodeInfo(const vertex node)
Return the info associated with a basic block.
#define BUILTIN_SRCP
const unsigned int function_id
The index of the function to be analyzed.
#define TYPE_MEMCPY
A vertex is of type TYPE_MEMCPY when it is associated with a assignment between struct/union.
Definition: op_graph.hpp:182
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
void insert_start_node(const std::string &start_node)
Insert a start node to the list of start nodes.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
#define ASSIGN
constant string identifying the operation performed by an assignment.
Definition: op_graph.hpp:224
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
Class specification of the basic_block structure.
#define NOP
constant string identifying a no operation.
Definition: op_graph.hpp:280
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
#define TYPE_WHILE
constant string identifying the node type of an WHILE operation.
Definition: op_graph.hpp:110
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
std::string get_first_node(const tree_nodeRef &tn, const std::string &f_name) const
Return the name of the first node given a tree node.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
#define F_COND
constant used to represent control edges representing a false edge of a conditional statement...
#define TYPE_ENTRY
constant identifying the node type of an entry node.
Wrapper to call graph.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
int debug_level
The debug level.
This class provides methods to build an operations graph.
#define TYPE_GENERIC
constant identifying the node type of a GENERIC operation.
#define TYPE_RET
constant string identifying an operation node of type return expr
Definition: op_graph.hpp:140
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
void init_start_nodes(const std::string &start_node)
Initialize the list of start nodes.
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
#define CFG_SELECTOR
Control flow graph edge selector.
#define TYPE_OPAQUE
constant identifying a node of opaque type
Definition: op_graph.hpp:90
static bool IsLoad(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign reading something which will be allocated in memory...
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
#define MULTI_READ_COND
constant string identifying the operation performed by a MULTI_READ_COND.
Definition: op_graph.hpp:260
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
Class specification of the manager of the tree structures extracted from the raw file.
std::list< std::string > start_nodes
store the name of the nodes at which the next node should be attached.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#define TYPE_LAST_OP
A vertex of type LAST_OP if it is the last operation of the application.
Definition: op_graph.hpp:197
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

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