PandA-2024.02
edge_c_writer.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  */
40 #include "edge_c_writer.hpp"
41 
42 #include "Dominance.hpp"
43 #include "Parameter.hpp"
44 #include "basic_block.hpp"
45 #include "behavioral_helper.hpp"
46 #include "custom_map.hpp"
47 #include "ext_tree_node.hpp"
48 #include "function_behavior.hpp"
49 #include "graph.hpp"
50 #include "hls_manager.hpp"
52 #include "instruction_writer.hpp"
53 #include "loop.hpp"
54 #include "loops.hpp"
55 #include "op_graph.hpp"
57 #include "tree_basic_block.hpp"
58 #include "tree_manager.hpp"
59 #include "tree_reindex.hpp"
60 
61 EdgeCWriter::EdgeCWriter(const HLS_managerConstRef _HLSMgr, const InstructionWriterRef _instruction_writer,
62  const IndentedOutputStreamRef _indented_output_stream, const ParameterConstRef _Param,
63  bool _verbose)
64  : CWriter(_HLSMgr, _instruction_writer, _indented_output_stream, _Param, _verbose),
65  dumped_edges(ltedge<BBGraph>(nullptr)),
66  counter(0)
67 {
68  debug_level = Param->get_class_debug_level(GET_CLASS(*this));
69 }
70 
71 EdgeCWriter::~EdgeCWriter() = default;
72 
74 {
76  counter = 0;
77  fun_loop_to_index.clear();
78  // Iterating over all functions
79  for(const auto f : HLSMgr->get_functions_with_body())
80  {
81  const auto FB = HLSMgr->CGetFunctionBehavior(f);
82  const std::list<LoopConstRef> loops = FB->CGetLoops()->GetList();
83  std::list<LoopConstRef>::const_iterator l, l_end = loops.end();
84  for(l = loops.begin(); l != l_end; ++l)
85  {
86  fun_loop_to_index[f][(*l)->GetId()] = counter;
87  counter++;
88  }
89  }
90 }
91 
93 {
94  dumped_edges.insert(e);
95 }
96 
97 void EdgeCWriter::print_end_path(unsigned int, unsigned int)
98 {
99 }
100 
102 {
103 }
104 
106 {
107 }
108 
110 {
111 }
112 
114 {
115 }
116 
117 void EdgeCWriter::writeRoutineInstructions_rec(vertex current_vertex, bool bracket)
118 {
120  const BBGraphInfoConstRef bb_graph_info = bb_fcfgGraph->CGetBBGraphInfo();
122  const CustomUnorderedMap<unsigned int, vertex>& bb_index_map = bb_graph_info->bb_index_map;
124  unsigned int funId = behavioral_helper->get_function_index();
125 
126  const BBNodeInfoConstRef bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(current_vertex);
127  const unsigned int bb_number = bb_node_info->block->number;
128 
130  const vertex entry_vertex = bb_fcfgGraph->CGetBBGraphInfo()->entry_vertex;
131 
133  const vertex exit_vertex = bb_fcfgGraph->CGetBBGraphInfo()->exit_vertex;
134 
135  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Starting writing BB" + std::to_string(bb_number));
137  THROW_ASSERT(bb_frontier.find(current_vertex) == bb_frontier.end(),
138  "current_vertex cannot be part of the basic block frontier");
139 
140  if(bb_analyzed.find(current_vertex) != bb_analyzed.end())
141  {
143  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--BB" + std::to_string(bb_number) + " already written");
144  return;
145  }
146 
147  bool add_phi_nodes_assignment = basic_block_tail.find(bb_number) != basic_block_tail.end();
148  bool add_phi_nodes_assignment_prefix = basic_block_prefix.find(bb_number) != basic_block_prefix.end();
149  bb_analyzed.insert(current_vertex);
150  if(this->verbose)
151  {
152  indented_output_stream->Append("//Basic block " + std::to_string(bb_number) + " - loop " +
153  std::to_string(bb_node_info->loop_id) + "\n");
154  }
155 
157  vertex bb_PD = post_dominators->get_immediate_dominator(current_vertex);
158 #ifndef NDEBUG
159  const BBNodeInfoConstRef bb_node_info_pd = bb_fcfgGraph->CGetBBNodeInfo(bb_PD);
160  const unsigned int bb_number_PD = bb_node_info_pd->block->number;
161  std::string frontier_string;
162  CustomOrderedSet<vertex>::iterator bb_frontier_begin, bb_frontier_end = bb_frontier.end();
163  for(bb_frontier_begin = bb_frontier.begin(); bb_frontier_begin != bb_frontier_end; ++bb_frontier_begin)
164  {
165  frontier_string += "BB" + std::to_string(bb_fcfgGraph->CGetBBNodeInfo(*bb_frontier_begin)->block->number) + " ";
166  }
167  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Frontier at the moment is: " + frontier_string);
168  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Its post-dominator is BB" + std::to_string(bb_number_PD));
169 #endif
170  bool analyze_bb_PD = bb_frontier.find(bb_PD) == bb_frontier.end() && bb_analyzed.find(bb_PD) == bb_analyzed.end();
171  if(analyze_bb_PD)
172  {
173  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Post dominator will be examinated");
174  bb_frontier.insert(bb_PD);
175  }
177  vertex last_stmt = NULL_VERTEX;
178  std::list<vertex>::const_reverse_iterator vRIter, vRIterEnd;
179  bool is_there = false;
180 #if 0
181  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Operations of task ");
183  {
185  OpVertexSet::const_iterator it, it_end;
186  it_end = local_rec_instructions.end();
187  for(it = local_rec_instructions.begin(); it != it_end; ++it)
190  }
191 #endif
192  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Looking for last statement");
194  for(vRIter = bb_node_info->statements_list.rbegin(), vRIterEnd = bb_node_info->statements_list.rend();
195  vRIter != vRIterEnd; ++vRIter)
196  {
197  if(local_rec_instructions.find(*vRIter) == local_rec_instructions.end())
198  {
199  continue;
200  }
201  if(GET_TYPE(cfgGraph, *vRIter) & TYPE_VPHI)
202  {
203  continue;
204  }
205  if((GET_TYPE(cfgGraph, *vRIter) & TYPE_INIT) != 0)
206  {
207  continue;
208  }
209  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Considering operation " + GET_NAME(cfgGraph, *vRIter));
210  is_there = true;
212  "This is basic block is not empty in this task. Last operation to be printed id " +
213  GET_NAME(cfgGraph, *vRIter));
214  last_stmt = *vRIter;
215  break;
216  }
219  bool last_statement_is_a_cond_or_goto = is_there and
220  behavioral_helper->end_with_a_cond_or_goto(bb_node_info->block) != 0 &&
221  last_stmt == bb_node_info->statements_list.back();
222  THROW_ASSERT(!last_statement_is_a_cond_or_goto || !is_there ||
223  (last_statement_is_a_cond_or_goto && last_stmt == bb_node_info->statements_list.back()),
224  "inconsistent recursion");
226  bool start_with_a_label = behavioral_helper->start_with_a_label(bb_node_info->block);
227 
228  if(start_with_a_label)
229  {
230  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Basic block starts with a label");
231  }
232 
233  bool add_bb_label = goto_list.find(current_vertex) != goto_list.end();
234 
235  if(add_bb_label)
236  {
237  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Basic block should start with a label");
238  }
239 
240  if(!add_bb_label and !start_with_a_label and boost::in_degree(current_vertex, *bb_fcfgGraph) > 1)
241  {
243  "Basic block has an indegree > 1 and not associated label");
244  InEdgeIterator inE, inEEnd;
245  for(boost::tie(inE, inEEnd) = boost::in_edges(current_vertex, *bb_fcfgGraph); inE != inEEnd; ++inE)
246  {
247  vertex source = boost::source(*inE, *bb_fcfgGraph);
248  const BBNodeInfoConstRef pred_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(source);
249 
250  // This condition match first basic block of case preceded by a case without break
251  if(pred_bb_node_info->statements_list.size() and
252  (GET_TYPE(cfgGraph, *(pred_bb_node_info->statements_list.rbegin())) & TYPE_SWITCH) and
253  post_dominators->get_immediate_dominator(source) != current_vertex)
254  {
256  "Basic block is the first case of a case preceded by a case without break");
257  add_bb_label = true;
258  break;
259  }
260  // Basic block start the body of a short circuit
261  else if(bb_analyzed.find(source) == bb_analyzed.end() and
262  !((FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*inE))))
263  {
265  "Basic block should start with a label since is the body of a short-circuit");
266  add_bb_label = true;
267  break;
268  }
269  // Basic block is a header loop, but it does not end with while or for
270  else if((bb_analyzed.find(source) == bb_analyzed.end() or current_vertex == source) and
271  (bb_node_info->statements_list.empty() or
272  ((GET_TYPE(cfgGraph, *(bb_node_info->statements_list.rbegin())) & (TYPE_WHILE | TYPE_FOR)) == 0)))
273  {
275  "Basic block is the header of a loop and it does not end with while or for");
276  add_bb_label = true;
277  break;
278  }
279  }
280  }
281  add_bb_label = add_bb_label && !start_with_a_label;
282  bool add_semicolon = false;
284  if(bracket)
285  {
286  if(analyze_bb_PD || is_there || add_bb_label || add_phi_nodes_assignment || add_phi_nodes_assignment_prefix)
287  {
289  }
290  else
291  {
292  add_semicolon = true;
293  }
294  }
295 
296  if(local_inc.find(current_vertex) == local_inc.end())
297  {
298  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "There is no local_inc");
299  // Counting not feedback incoming edges
300  InEdgeIterator ei, ei_end;
301  EdgeDescriptor only_edge;
302  for(boost::tie(ei, ei_end) = boost::in_edges(current_vertex, *bb_fcfgGraph); ei != ei_end; ei++)
303  {
304  if(!(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*ei)))
305  {
306  only_edge = *ei;
307  }
308  }
309 
310  // Entry block
311  if(current_vertex == entry_vertex)
312  {
313  OutEdgeIterator eo, eo_end;
314  for(boost::tie(eo, eo_end) = boost::out_edges(current_vertex, *bb_fcfgGraph); eo != eo_end; eo++)
315  {
316  if(exit_vertex != boost::target(*eo, *bb_fcfgGraph))
317  {
318  print_loop_starting(*eo);
319  }
320  }
321  }
322  }
323  else
324  {
326  "---There is already an edge instrumentation associated with the current basic block");
327  EdgeDescriptor e = local_inc[current_vertex];
328  unsigned int first_loop_index = support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
329  unsigned int second_loop_index = support_cfg->CGetBBNodeInfo(boost::target(e, *support_cfg))->loop_id;
330  // Different loop
331  if(first_loop_index != second_loop_index)
332  {
334  "---Changing from loop " + std::to_string(first_loop_index) + " to " +
335  std::to_string(second_loop_index));
336  unsigned int first_depth = 0;
337  unsigned int second_depth = 0;
338  if(first_loop_index)
339  {
340  first_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
341  }
342  if(second_loop_index)
343  {
344  second_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
345  }
346  // Second vertex is an header
347  if(first_depth < second_depth)
348  {
350  }
351  // First vertex is an exit
352  else if(second_depth < first_depth)
353  {
355  }
356  // First vertex is an exit, second vertex is an header
357  else
358  {
360  }
361  }
362  else
363  {
364  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
365  }
366  }
367 
368  // Header block
369  if((bb_node_info->loop_id == bb_number) && bb_number)
370  {
371  if(verbose)
372  {
374  "//Starting of a loop - average iteration number " +
375  std::to_string(
376  HLSMgr->CGetFunctionBehavior(funId)->CGetProfilingInformation()->GetLoopAvgIterations(bb_number)) +
377  "\n");
378  }
379  }
380 
381  if(add_bb_label)
382  {
383  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "A label should be added at the beginning");
384  THROW_ASSERT(basic_blocks_labels.find(bb_number) != basic_blocks_labels.end(),
385  "I do not know the destination: " + STR(bb_number));
386  indented_output_stream->Append(basic_blocks_labels.find(bb_number)->second + ":\n");
387  add_semicolon = true;
388  }
389  else if(start_with_a_label)
390  {
391  add_semicolon = true;
392  }
393  std::list<vertex>::const_iterator vIter, vIterEnd, vIterBegin;
394  vIter = bb_node_info->statements_list.begin();
395  vIterBegin = vIter;
396  vIterEnd = bb_node_info->statements_list.end();
397  if(not is_there)
398  {
399  OutEdgeIterator oi, oend;
400  bool notFeedBack = true;
401  for(boost::tie(oi, oend) = boost::out_edges(current_vertex, *bb_fcfgGraph); oi != oend and notFeedBack; oi++)
402  {
403  if(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*oi))
404  {
405  notFeedBack = false;
406  }
407  }
408  }
409  if(is_there)
410  {
412  "There are instructions to be printed for this pair task - basic block");
413 
415  if(renaming_table.find(current_vertex) != renaming_table.end())
416  {
417  const std::map<unsigned int, std::string>& rvt = renaming_table.find(current_vertex)->second;
418  auto rvt_it_end = rvt.end();
419  for(auto rvt_it = rvt.begin(); rvt_it != rvt_it_end; ++rvt_it)
420  {
421  BehavioralHelper::rename_a_variable(rvt_it->first, rvt_it->second);
422  }
423  }
424  bool label_has_to_be_printed = start_with_a_label;
425  bool prefix_has_to_be_printed = basic_block_prefix.find(bb_number) != basic_block_prefix.end();
426  unsigned int analyzed_statement = 0;
427  do
428  {
431  if(prefix_has_to_be_printed and not label_has_to_be_printed)
432  {
433  prefix_has_to_be_printed = false;
434  indented_output_stream->Append(basic_block_prefix.find(bb_number)->second);
435  }
436  if(local_rec_instructions.find(*vIter) == local_rec_instructions.end())
437  {
438  continue;
439  }
440  analyzed_statement++;
443  label_has_to_be_printed = false;
445  "Preparing printing of operation " + GET_NAME(cfgGraph, *vIter));
446  // Now I print the instruction
447  if(this->verbose)
448  {
449  indented_output_stream->Append("//Instruction: " + GET_NAME(cfgGraph, *vIter) + "\n");
450  }
451 
452  if(start_with_a_label && vIter == vIterBegin)
453  {
454  InEdgeIterator inE, inEEnd;
455  for(boost::tie(inE, inEEnd) = boost::in_edges(current_vertex, *bb_fcfgGraph); inE != inEEnd; inE++)
456  {
457  if(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*inE))
458  {
459  indented_output_stream->Append("//start of a loop\n");
460  }
461  }
462  }
463  bool isLastIntruction = last_stmt == *vIter;
465  bool print_phi_now =
466  ((GET_TYPE(cfgGraph, *vIter) & (TYPE_IF | TYPE_WHILE | TYPE_FOR | TYPE_SWITCH | TYPE_MULTIIF))) ||
467  behavioral_helper->end_with_a_cond_or_goto(bb_node_info->block);
468  if(add_phi_nodes_assignment && isLastIntruction && print_phi_now)
469  {
471  }
472  if((GET_TYPE(cfgGraph, *vIter) & (TYPE_VPHI)) == 0)
473  {
474  if(GET_TYPE(cfgGraph, *vIter) & (TYPE_WHILE | TYPE_FOR) and this->verbose and
475  local_rec_function_behavior->CGetLoops()->CGetLoop(bb_node_info->loop_id)->loop_type & DOALL_LOOP)
476  {
477  indented_output_stream->Append("//#pragma omp parallel for\n");
478  }
479  // End of a loop with goto
480  if(isLastIntruction and behavioral_helper->end_with_a_cond_or_goto(bb_node_info->block) and
481  boost::out_degree(current_vertex, *bb_fcfgGraph) == 1)
482  {
483  OutEdgeIterator eo1, eo_end1;
484  boost::tie(eo1, eo_end1) = boost::out_edges(current_vertex, *bb_fcfgGraph);
485  if(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*eo1))
486  {
487  print_loop_ending(*eo1);
488  }
489  }
490  else if((GET_TYPE(cfgGraph, *vIter) & TYPE_RET) != 0)
491  {
493  }
494  if((GET_TYPE(cfgGraph, *vIter) & TYPE_LAST_OP) != 0 and (GET_TYPE(cfgGraph, *vIter) & TYPE_RET) == 0)
495  {
497  }
499  if((GET_TYPE(cfgGraph, *vIter) & TYPE_LABEL) == 0)
500  {
501  add_semicolon = false;
502  }
503  }
504  else if(this->verbose)
505  {
506  indented_output_stream->Append("//(removed virtual phi instruction)\n");
507  }
508  if(!isLastIntruction)
509  {
510  continue;
511  }
513  if(add_phi_nodes_assignment && !print_phi_now)
514  {
515  indented_output_stream->Append(basic_block_tail.find(bb_number)->second);
516  }
517  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---This is not the last statement");
518  if(boost::out_degree(current_vertex, *support_cfg) == 1 and
519  boost::out_degree(current_vertex, *bb_fcfgGraph) == 1)
520  {
521  OutEdgeIterator eo1, eo_end1;
522  boost::tie(eo1, eo_end1) = boost::out_edges(current_vertex, *support_cfg);
523  vertex next = boost::target(*eo1, *support_cfg);
524  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id == bb_fcfgGraph->CGetBBNodeInfo(next)->loop_id)
525  {
526  THROW_ASSERT(fun_loop_to_index.find(funId) != fun_loop_to_index.end(),
527  "Function " + std::to_string(funId) + " not found");
528  THROW_ASSERT(fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id) !=
529  fun_loop_to_index.find(funId)->second.end(),
530  "Loop " + std::to_string(bb_node_info->loop_id) + " not found");
531  print_edge(*eo1, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
532  }
533  }
534  // Now I check if this is a control statement and I consequently print
535  // the instructions contained in its branches
536  if(GET_TYPE(cfgGraph, *vIter) & TYPE_IF)
537  {
538  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Operation is an if");
539  const unsigned int bb_true_number = bb_node_info->block->true_edge;
540  const vertex true_vertex = bb_index_map.find(bb_true_number)->second;
541  const unsigned int bb_false_number = bb_node_info->block->false_edge;
542  vertex false_vertex = bb_index_map.find(bb_false_number)->second;
543  bool add_false_to_goto = false;
544  if(bb_frontier.find(true_vertex) == bb_frontier.end())
545  {
546  if(bb_frontier.find(false_vertex) == bb_frontier.end() &&
547  goto_list.find(false_vertex) == goto_list.end())
548  {
549  goto_list.insert(false_vertex);
550  add_false_to_goto = true;
551  }
552  if(bb_analyzed.find(true_vertex) == bb_analyzed.end())
553  {
554  EdgeDescriptor e;
555  bool inserted;
556  boost::tie(e, inserted) = boost::edge(current_vertex, true_vertex, *support_cfg);
557  THROW_ASSERT(inserted, "Missing edge");
558  local_inc[true_vertex] = e;
559  writeRoutineInstructions_rec(true_vertex, true);
560  }
561  else
562  {
563  THROW_ASSERT(basic_blocks_labels.find(bb_true_number) != basic_blocks_labels.end(),
564  "I do not know the destination");
566  EdgeDescriptor e;
567  bool inserted;
568  boost::tie(e, inserted) = boost::edge(current_vertex, true_vertex, *bb_fcfgGraph);
569  THROW_ASSERT(inserted, "Edge missing");
570  if(not(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(e)))
571  {
572  unsigned int first_loop_index =
573  support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
574  unsigned int second_loop_index =
576  // Different loop
577  if(first_loop_index != second_loop_index)
578  {
579  unsigned int first_depth = 0;
580  unsigned int second_depth = 0;
581  if(first_loop_index)
582  {
583  first_depth =
584  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
585  }
586  if(second_loop_index)
587  {
588  second_depth =
589  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
590  }
591  // Second vertex is an header
592  if(first_depth < second_depth)
593  {
595  }
596  // First vertex is an exit
597  else if(second_depth < first_depth)
598  {
600  }
601  // First vertex is an exit, second vertex is an header
602  else
603  {
605  }
606  }
607  else
608  {
609  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
610  }
611  }
612  else
613  {
615  }
616  indented_output_stream->Append("goto " + basic_blocks_labels.find(bb_true_number)->second + ";\n");
618  }
619  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---True edge was not in the frontier");
620  }
621  else
622  {
624  EdgeDescriptor e;
625  bool inserted;
626  boost::tie(e, inserted) = boost::edge(current_vertex, true_vertex, *support_cfg);
627  unsigned int first_loop_index = support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
628  unsigned int second_loop_index = support_cfg->CGetBBNodeInfo(boost::target(e, *support_cfg))->loop_id;
629  // Different loop
630  if(first_loop_index != second_loop_index)
631  {
632  unsigned int first_depth = 0;
633  unsigned int second_depth = 0;
634  if(first_loop_index)
635  {
636  first_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
637  }
638  if(second_loop_index)
639  {
640  second_depth =
641  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
642  }
643  // Second vertex is an header
644  if(first_depth < second_depth)
645  {
647  }
648  // First vertex is an exit
649  else if(second_depth < first_depth)
650  {
652  }
653  // First vertex is an exit, second vertex is an header
654  else
655  {
657  }
658  }
659  else
660  {
661  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
662  }
664  }
665  if(add_false_to_goto)
666  {
667  goto_list.erase(false_vertex);
668  }
669  if(bb_frontier.find(false_vertex) == bb_frontier.end())
670  {
671  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "False BB is not on the frontier");
672  EdgeDescriptor e;
673  bool ins;
674  boost::tie(e, ins) = boost::edge(current_vertex, false_vertex, *bb_fcfgGraph);
675  if(not(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(e)))
676  {
677  indented_output_stream->Append("else\n");
678  if(bb_analyzed.find(false_vertex) == bb_analyzed.end())
679  {
680  local_inc[false_vertex] = e;
681  writeRoutineInstructions_rec(false_vertex, true);
682  }
683  else
684  {
685  THROW_ASSERT(basic_blocks_labels.find(bb_false_number) != basic_blocks_labels.end(),
686  "I do not know the destination");
688  boost::tie(e, ins) = boost::edge(current_vertex, false_vertex, *support_cfg);
689  THROW_ASSERT(ins, "Missing edge");
690  unsigned int first_loop_index =
691  support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
692  unsigned int second_loop_index =
694  // Different loop
695  if(first_loop_index != second_loop_index)
696  {
697  unsigned int first_depth = 0;
698  unsigned int second_depth = 0;
699  if(first_loop_index)
700  {
701  first_depth =
702  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
703  }
704  if(second_loop_index)
705  {
706  second_depth =
707  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
708  }
709  // Second vertex is an header
710  if(first_depth < second_depth)
711  {
713  }
714  // First vertex is an exit
715  else if(second_depth < first_depth)
716  {
718  }
719  // First vertex is an exit, second vertex is an header
720  else
721  {
723  }
724  }
725  else
726  {
727  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
728  }
729 
730  indented_output_stream->Append(" goto " + basic_blocks_labels.find(bb_false_number)->second +
731  ";/*goto6*/\n");
733  }
734  }
736  else
737  {
738  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Target is a header");
739  const vertex target = boost::target(e, *bb_fcfgGraph);
740  const BBNodeInfoConstRef target_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(target);
742  if(target_bb_node_info->statements_list.empty() or
743  ((GET_TYPE(cfgGraph, *(target_bb_node_info->statements_list.rbegin())) &
744  (TYPE_WHILE | TYPE_FOR)) == 0))
745  {
746  indented_output_stream->Append("else\n");
748 
750  THROW_ASSERT(basic_blocks_labels.find(bb_false_number) != basic_blocks_labels.end(),
751  "I do not know the destination");
752  indented_output_stream->Append(" goto " + basic_blocks_labels.find(bb_false_number)->second +
753  ";/*goto7*/\n");
755  }
756  }
757  }
758  else
759  {
760  indented_output_stream->Append("else\n");
762  EdgeDescriptor e;
763  bool inserted;
764  false_vertex = bb_fcfgGraph->CGetBBGraphInfo()->bb_index_map.find(bb_false_number)->second;
765  boost::tie(e, inserted) = boost::edge(current_vertex, false_vertex, *bb_fcfgGraph);
766  unsigned int first_loop_index = support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
767  unsigned int second_loop_index = support_cfg->CGetBBNodeInfo(boost::target(e, *support_cfg))->loop_id;
768  // Different loop
769  if(first_loop_index != second_loop_index)
770  {
771  unsigned int first_depth = 0;
772  unsigned int second_depth = 0;
773  if(first_loop_index)
774  {
775  first_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
776  }
777  if(second_loop_index)
778  {
779  second_depth =
780  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
781  }
782  // Second vertex is an header
783  if(first_depth < second_depth)
784  {
786  }
787  // First vertex is an exit
788  else if(second_depth < first_depth)
789  {
791  }
792  // First vertex is an exit, second vertex is an header
793  else
794  {
796  }
797  }
798  else
799  {
800  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
801  }
803  }
804  }
805  else if(GET_TYPE(cfgGraph, *vIter) & (TYPE_WHILE | TYPE_FOR))
806  {
807  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Operation is a while or a for");
808  const unsigned int bb_true_number = bb_node_info->block->true_edge;
809  const vertex true_vertex = bb_index_map.find(bb_true_number)->second;
810  if(bb_frontier.find(true_vertex) == bb_frontier.end())
811  {
812  if(bb_analyzed.find(true_vertex) == bb_analyzed.end())
813  {
814  if(analyzed_statement == local_rec_instructions.size())
815  {
816  return;
817  }
818  EdgeDescriptor e;
819  bool inserted;
820  boost::tie(e, inserted) = boost::edge(current_vertex, true_vertex, *bb_fcfgGraph);
821  THROW_ASSERT(inserted, "Missing edge");
822  local_inc[true_vertex] = e;
823  writeRoutineInstructions_rec(true_vertex, true);
824  }
825  else
826  {
827  THROW_ERROR("Body of a loop has yet been printed before the while statement");
828  }
829  }
830  else
831  {
832  return;
833  }
834 
835  const unsigned int bb_false_number = bb_node_info->block->false_edge;
836  const vertex false_vertex = bb_index_map.find(bb_false_number)->second;
837  EdgeDescriptor e;
838  bool inserted;
839  boost::tie(e, inserted) = boost::edge(current_vertex, false_vertex, *bb_fcfgGraph);
840  unsigned int first_loop_index = support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
841  unsigned int second_loop_index = support_cfg->CGetBBNodeInfo(boost::target(e, *support_cfg))->loop_id;
842  // Different loop
843  if(first_loop_index != second_loop_index)
844  {
845  unsigned int first_depth = 0;
846  unsigned int second_depth = 0;
847  if(first_loop_index)
848  {
849  first_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
850  }
851  else
852  {
853  THROW_ERROR("Basic block of for or while it is not in a loop");
854  }
855  if(second_loop_index)
856  {
857  second_depth = HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
858  }
859  // Second vertex is an header
860  if(first_depth < second_depth)
861  {
862  THROW_ERROR("A loop is followed by a loop with higher depth");
863  }
864  // First vertex is an exit
865  else if(second_depth < first_depth)
866  {
868  }
869  // First vertex is an exit, second vertex is an header
870  else
871  {
873  }
874  }
875  else
876  {
877  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
878  }
879 
880  if(bb_frontier.find(false_vertex) == bb_frontier.end())
881  {
882  if(bb_analyzed.find(false_vertex) == bb_analyzed.end())
883  {
884  writeRoutineInstructions_rec(false_vertex, false);
885  }
886  else
887  {
888  indented_output_stream->Append("goto " + basic_blocks_labels.find(bb_false_number)->second + ";\n");
889  goto_list.insert(false_vertex);
890  }
891  }
892  }
893  else if(GET_TYPE(cfgGraph, *vIter) & TYPE_MULTIIF)
894  {
895  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Operation is a multiif");
896  unsigned int node_id = cfgGraph->CGetOpNodeInfo(last_stmt)->GetNodeId();
897  const tree_nodeRef node = TM->get_tree_node_const(node_id);
898  THROW_ASSERT(node->get_kind() == gimple_multi_way_if_K, "unexpected node");
899  auto* gmwi = GetPointer<gimple_multi_way_if>(node);
900  std::map<unsigned int, bool> add_elseif_to_goto;
901  for(const auto& cond : gmwi->list_of_cond)
902  {
903  unsigned int bb_index_num = cond.second;
904  const vertex bb_vertex = bb_index_map.find(bb_index_num)->second;
905  if(cond != gmwi->list_of_cond.front())
906  {
907  bool to_be_added =
908  bb_frontier.find(bb_vertex) == bb_frontier.end() && goto_list.find(bb_vertex) == goto_list.end();
909  add_elseif_to_goto[bb_index_num] = to_be_added;
910  if(to_be_added)
911  {
912  goto_list.insert(bb_vertex);
913  }
914  }
915  else
916  {
917  add_elseif_to_goto[bb_index_num] = false;
918  }
919  }
920  for(const auto& cond : gmwi->list_of_cond)
921  {
922  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Considering successor BB" + STR(cond.second));
923  unsigned int bb_index_num = cond.second;
924  const vertex bb_vertex = bb_index_map.find(bb_index_num)->second;
925  if(cond != gmwi->list_of_cond.front())
926  {
927  if(cond.first)
928  {
929  indented_output_stream->Append("else if(");
930  indented_output_stream->Append(behavioral_helper->PrintVariable(GET_INDEX_NODE(cond.first)));
932  }
933  else
934  {
935  indented_output_stream->Append("else\n");
936  }
937  }
938  if(add_elseif_to_goto.find(bb_index_num) != add_elseif_to_goto.end() &&
939  add_elseif_to_goto.find(bb_index_num)->second)
940  {
941  goto_list.erase(bb_vertex);
942  }
943  if(bb_frontier.find(bb_vertex) == bb_frontier.end())
944  {
945  if(bb_analyzed.find(bb_vertex) == bb_analyzed.end())
946  {
947  EdgeDescriptor e;
948  bool inserted;
949  boost::tie(e, inserted) = boost::edge(current_vertex, bb_vertex, *support_cfg);
950  THROW_ASSERT(inserted, "Missing edge");
951  local_inc[bb_vertex] = e;
952  writeRoutineInstructions_rec(bb_vertex, true);
953  }
954  else
955  {
956  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor has already been examined");
957 
958  THROW_ASSERT(basic_blocks_labels.find(bb_index_num) != basic_blocks_labels.end(),
959  "I do not know the destination " + std::to_string(bb_index_num));
961  EdgeDescriptor e;
962  bool inserted;
963  boost::tie(e, inserted) = boost::edge(current_vertex, bb_vertex, *bb_fcfgGraph);
964  THROW_ASSERT(inserted, "Edge missing");
965  if(not(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(e)))
966  {
967  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Connected by feedback edge");
968  unsigned int first_loop_index =
969  support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
970  unsigned int second_loop_index =
972  // Different loop
973  if(first_loop_index != second_loop_index)
974  {
975  unsigned int first_depth = 0;
976  unsigned int second_depth = 0;
977  if(first_loop_index)
978  {
979  first_depth =
980  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
981  }
982  if(second_loop_index)
983  {
984  second_depth =
985  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
986  }
988  "---Depth of first loop is " + STR(first_depth));
990  "---Depth of second loop is " + STR(second_depth));
991  // Second vertex is an header
992  if(first_depth < second_depth)
993  {
995  }
996  // First vertex is an exit
997  else if(second_depth < first_depth)
998  {
1000  }
1001  // First vertex is an exit, second vertex is an header
1002  else
1003  {
1005  }
1006  }
1007  else
1008  {
1009  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
1010  }
1011  }
1012  else
1013  {
1014  print_loop_ending(e);
1015  }
1016  indented_output_stream->Append("goto " + basic_blocks_labels.find(bb_index_num)->second + ";\n");
1017  goto_list.insert(bb_vertex);
1019  }
1020  }
1021  else
1022  {
1023  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Connected by forward edge");
1025  EdgeDescriptor e;
1026  bool inserted;
1027  boost::tie(e, inserted) = boost::edge(current_vertex, bb_vertex, *support_cfg);
1028  unsigned int first_loop_index = support_cfg->CGetBBNodeInfo(boost::source(e, *support_cfg))->loop_id;
1029  unsigned int second_loop_index = support_cfg->CGetBBNodeInfo(boost::target(e, *support_cfg))->loop_id;
1030  // Different loop
1031  if(first_loop_index != second_loop_index)
1032  {
1033  unsigned int first_depth = 0;
1034  unsigned int second_depth = 0;
1035  if(first_loop_index)
1036  {
1037  first_depth =
1038  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(first_loop_index)->depth;
1039  }
1040  if(second_loop_index)
1041  {
1042  second_depth =
1043  HLSMgr->CGetFunctionBehavior(funId)->CGetLoops()->CGetLoop(second_loop_index)->depth;
1044  }
1046  "---Depth of first loop is " + STR(first_depth));
1048  "---Depth of second loop is " + STR(second_depth));
1049  // Second vertex is an header
1050  if(first_depth < second_depth)
1051  {
1053  }
1054  // First vertex is an exit
1055  else if(second_depth < first_depth)
1056  {
1058  }
1059  // First vertex is an exit, second vertex is an header
1060  else
1061  {
1063  }
1064  }
1065  else
1066  {
1067  print_edge(e, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
1068  }
1070  }
1071  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered successor BB" + STR(cond.second));
1072  }
1073  }
1074  else if(GET_TYPE(cfgGraph, *vIter) & TYPE_SWITCH)
1075  {
1076  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Operation is a switch");
1079  OutEdgeIterator oE, oEEnd;
1080  for(boost::tie(oE, oEEnd) = boost::out_edges(current_vertex, *bb_fcfgGraph); oE != oEEnd; oE++)
1081  {
1082  bool empty_block = false;
1083  vertex next_bb = boost::target(*oE, *bb_fcfgGraph);
1084  const BBNodeInfoConstRef next_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(next_bb);
1085 #ifndef NDEBUG
1086  const unsigned int bb_number_next_bb = next_bb_node_info->block->number;
1087 #endif
1089  "Examining successor " + std::to_string(bb_number_next_bb));
1090  unsigned int in_edge_counter = 0;
1091  InEdgeIterator ei, ei_end;
1092  for(boost::tie(ei, ei_end) = boost::in_edges(next_bb, *bb_fcfgGraph); ei != ei_end; ei++)
1093  {
1094  if(not(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*ei)))
1095  {
1096  in_edge_counter++;
1097  }
1098  }
1100  CustomOrderedSet<unsigned int> Set = bb_fcfgGraph->CGetBBEdgeInfo(*oE)->get_labels(CFG_SELECTOR);
1101  for(eIdBeg = Set.begin(), eIdEnd = Set.end(); eIdBeg != eIdEnd; ++eIdBeg)
1102  {
1103  if(*eIdBeg == default_COND)
1104  {
1105  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor is default case");
1106  if(next_bb == post_dominators->get_immediate_dominator(current_vertex))
1107  {
1109  empty_block = true;
1110  indented_output_stream->Append("default:\n");
1112  print_edge(*oE, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
1114  if(current_vertex == dominators->get_immediate_dominator(next_bb))
1115  {
1116  analyze_bb_PD = true;
1117  }
1118  break;
1119  }
1120  local_inc[next_bb] = *oE;
1121  if(in_edge_counter != 1)
1122  {
1123  THROW_ERROR_CODE(PROFILING_EC, "Not yet supported type of switch in profiling");
1124  THROW_ERROR("Not yet supported type of switch in profiling");
1125  }
1126  indented_output_stream->Append("default");
1127  }
1128  else
1129  {
1130  local_inc[next_bb] = *oE;
1131  if(in_edge_counter != 1)
1132  {
1133  THROW_ERROR_CODE(PROFILING_EC, "Not yet supported type of switch in profiling - Function is " +
1134  std::to_string(funId) + " - current basic block is " +
1135  std::to_string(bb_number));
1136  THROW_ERROR("Not yet supported type of switch in profiling");
1137  }
1138  if(next_bb == bb_PD)
1139  {
1140  empty_block = true;
1141  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Removed current basic block");
1142  }
1143 
1144  indented_output_stream->Append("case " +
1145  behavioral_helper->PrintConstant(TM->CGetTreeReindex(*eIdBeg)));
1146  }
1148  }
1149  if(empty_block)
1150  {
1151  indented_output_stream->Append("break;\n");
1152  continue;
1153  }
1154  if(bb_analyzed.find(next_bb) == bb_analyzed.end())
1155  {
1156  writeRoutineInstructions_rec(next_bb, true);
1157  indented_output_stream->Append("break;\n");
1158  }
1159  else
1160  {
1161  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor has already been examined");
1162  const unsigned int next_bb_number = next_bb_node_info->block->number;
1163 
1164  THROW_ASSERT(basic_blocks_labels.find(next_bb_number) != basic_blocks_labels.end(),
1165  "I do not know the destination " + std::to_string(next_bb_number));
1166  indented_output_stream->Append(" goto " + basic_blocks_labels.find(next_bb_number)->second +
1167  ";/*goto8*/\n");
1168  }
1169  }
1171  }
1172  else if(behavioral_helper->end_with_a_cond_or_goto(bb_node_info->block))
1173  {
1174  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Basic block ends with a cond or a goto");
1175  if(last_statement_is_a_cond_or_goto)
1176  {
1178  OutEdgeIterator oE, oEEnd;
1179  for(boost::tie(oE, oEEnd) = boost::out_edges(current_vertex, *bb_fcfgGraph); oE != oEEnd; oE++)
1180  {
1181  vertex next_bb = boost::target(*oE, *bb_fcfgGraph);
1182  if(boost::out_degree(current_vertex, *bb_fcfgGraph) > 1)
1183  {
1184  THROW_ERROR_CODE(PROFILING_EC, "Profiling does not support computed goto");
1185  THROW_ERROR("Profiling does not support computed goto");
1186  }
1187  if(bb_frontier.find(next_bb) != bb_frontier.end())
1188  {
1189  continue;
1190  }
1191  goto_list.insert(next_bb);
1192  }
1193  }
1194  }
1195  else
1196  {
1197  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---It is not a special operation");
1198  const vertex bbentry = bb_fcfgGraph->CGetBBGraphInfo()->entry_vertex;
1199  if(current_vertex == bbentry)
1200  {
1203  "<--Ended writing basic block " + std::to_string(bb_number));
1204  return;
1205  }
1206  THROW_ASSERT(boost::out_degree(current_vertex, *bb_fcfgGraph) <= 1,
1207  "Only one edge expected as output of BB" +
1208  STR(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->block->number));
1209  OutEdgeIterator oE, oEEnd;
1210  for(boost::tie(oE, oEEnd) = boost::out_edges(current_vertex, *bb_fcfgGraph); oE != oEEnd; oE++)
1211  {
1212  vertex next_bb = boost::target(*oE, *bb_fcfgGraph);
1213  if(bb_frontier.find(next_bb) != bb_frontier.end())
1214  {
1215  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id !=
1216  bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id)
1217  {
1218  print_loop_starting(*oE);
1219  }
1221  "Not adding goto since target is in the frontier");
1222  continue;
1223  }
1224  if(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*oE))
1225  {
1226  print_loop_ending(*oE);
1227  const vertex target = boost::target(*oE, *bb_fcfgGraph);
1228  const BBNodeInfoConstRef target_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(target);
1229  if(target_bb_node_info->statements_list.size() and
1230  (GET_TYPE(cfgGraph, *(target_bb_node_info->statements_list.rbegin())) & (TYPE_WHILE | TYPE_FOR)))
1231  {
1233  "Not adding a goto since target is a while/for");
1234  continue;
1235  }
1236  }
1237  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id !=
1238  bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id)
1239  {
1240  print_loop_starting(*oE);
1241  }
1242  if(boost::in_degree(next_bb, *bb_fcfgGraph) == 1)
1243  {
1244  writeRoutineInstructions_rec(next_bb, false);
1245  }
1246  else
1247  {
1248  const BBNodeInfoConstRef next_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(next_bb);
1249  const unsigned int next_bb_number = next_bb_node_info->block->number;
1250  THROW_ASSERT(basic_blocks_labels.find(next_bb_number) != basic_blocks_labels.end(),
1251  "I do not know the destination");
1252  indented_output_stream->Append(" goto " + basic_blocks_labels.find(next_bb_number)->second +
1253  ";/*Goto4*/\n");
1254  goto_list.insert(next_bb);
1255  }
1256  }
1257  }
1258  } while(*vIter++ != last_stmt);
1259  if(add_semicolon)
1260  {
1261  indented_output_stream->Append(";\n");
1262  }
1263  }
1264  else
1265  {
1266  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "is_there is false");
1268  if(add_phi_nodes_assignment)
1269  {
1270  indented_output_stream->Append(basic_block_tail.find(bb_number)->second);
1271  add_semicolon = false;
1272  }
1273  if(!behavioral_helper->end_with_a_cond_or_goto(bb_node_info->block) &&
1274  ((bb_node_info->statements_list.empty()) ||
1275  ((GET_TYPE(cfgGraph, *bb_node_info->statements_list.rbegin()) & (TYPE_SWITCH | TYPE_WHILE | TYPE_FOR)) == 0)))
1276  {
1277  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Not end with a cond or goto nor switch");
1278  const vertex bbentry = bb_fcfgGraph->CGetBBGraphInfo()->entry_vertex;
1279  if(current_vertex == bbentry)
1280  {
1283  "<--Ended writing basic block " + std::to_string(bb_number));
1284  return;
1285  }
1286  THROW_ASSERT(boost::out_degree(current_vertex, *bb_fcfgGraph) <= 1, "only one edge expected BB(" +
1287  std::to_string(bb_number) + ") Fun(" +
1288  std::to_string(funId) + ")");
1289  OutEdgeIterator oE, oEEnd;
1290  for(boost::tie(oE, oEEnd) = boost::out_edges(current_vertex, *bb_fcfgGraph); oE != oEEnd; oE++)
1291  {
1292  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Examining the only? successor");
1293  vertex next_bb = boost::target(*oE, *bb_fcfgGraph);
1294  if(boost::in_degree(next_bb, *bb_fcfgGraph) == 1)
1295  {
1296  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor is the only");
1297  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id !=
1298  bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id)
1299  {
1300  print_loop_starting(*oE);
1301  }
1302  continue;
1303  }
1304  if(bb_frontier.find(next_bb) != bb_frontier.end())
1305  {
1306  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor belongs to frontier");
1307  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id !=
1308  bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id)
1309  {
1310  print_loop_starting(*oE);
1311  }
1312  else
1313  {
1314  print_edge(*oE, fun_loop_to_index.find(funId)->second.find(bb_node_info->loop_id)->second);
1315  }
1316  continue;
1317  }
1319  if(FB_CFG_SELECTOR & bb_fcfgGraph->GetSelector(*oE))
1320  {
1321  const vertex target = boost::target(*oE, *bb_fcfgGraph);
1322  const BBNodeInfoConstRef target_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(target);
1323  if(target_bb_node_info->statements_list.size() and
1324  (GET_TYPE(cfgGraph, *(target_bb_node_info->statements_list.rbegin())) & (TYPE_WHILE | TYPE_FOR)))
1325  {
1326  continue;
1327  }
1328  }
1329 
1330  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Successor does not belong to frontier");
1331  const BBNodeInfoConstRef next_bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(next_bb);
1332  const unsigned int next_bb_number = next_bb_node_info->block->number;
1333  THROW_ASSERT(basic_blocks_labels.find(next_bb_number) != basic_blocks_labels.end(),
1334  "I do not know the destination");
1335  if(bb_fcfgGraph->CGetBBNodeInfo(current_vertex)->loop_id != bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id)
1336  {
1337  print_loop_starting(*oE);
1338  }
1339  if(bb_fcfgGraph->CGetBBNodeInfo(next_bb)->loop_id == bb_fcfgGraph->CGetBBNodeInfo(next_bb)->block->number)
1340  {
1341  print_loop_ending(*oE);
1342  }
1343  indented_output_stream->Append(" goto " + basic_blocks_labels.find(next_bb_number)->second +
1344  ";/*goto5*/\n");
1345  goto_list.insert(next_bb);
1346  add_semicolon = false;
1347  }
1348  if(add_semicolon)
1349  {
1350  indented_output_stream->Append(";\n");
1351  }
1352  }
1353  else if(add_semicolon)
1354  {
1355  indented_output_stream->Append(" ;\n");
1356  }
1357  }
1358 
1359  if(analyze_bb_PD)
1360  {
1361  // recurse on the post dominator
1362  bb_frontier.erase(bb_PD);
1363  THROW_ASSERT(bb_analyzed.find(bb_PD) == bb_analyzed.end(),
1364  "something wrong happened " + std::to_string(bb_fcfgGraph->CGetBBNodeInfo(bb_PD)->block->number) +
1365  " Fun(" + std::to_string(funId) + ")");
1366  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "Printing the post dominator");
1367  writeRoutineInstructions_rec(bb_PD, false);
1368  }
1369  if((analyze_bb_PD || is_there || add_bb_label || add_phi_nodes_assignment || add_phi_nodes_assignment_prefix) &&
1370  bracket)
1371  {
1373  }
1375  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--BB" + std::to_string(bb_number) + " written");
1376 }
1377 
1378 void EdgeCWriter::writeRoutineInstructions(const unsigned int function_index, const OpVertexSet& instructions,
1379  const var_pp_functorConstRef variableFunctor, vertex bb_start,
1380  CustomOrderedSet<vertex> bb_end)
1381 {
1382  const FunctionBehaviorConstRef function_behavior = HLSMgr->CGetFunctionBehavior(function_index);
1383  const BehavioralHelperConstRef behavioral_helper = function_behavior->CGetBehavioralHelper();
1384  const BBGraphConstRef bb_fcfgGraph = function_behavior->CGetBBGraph(FunctionBehavior::FBB);
1385  fun_id = behavioral_helper->get_function_index();
1386  support_cfg = function_behavior->CGetBBGraph(FunctionBehavior::PPG);
1387  local_inc.clear();
1388  dumped_edges = std::set<EdgeDescriptor, ltedge<BBGraph>>(ltedge<BBGraph>(support_cfg.get()));
1389 
1390  const OpGraphConstRef cfgGraph = function_behavior->CGetOpGraph(FunctionBehavior::FCFG);
1392  "-->Edge profiling writer - start to fwrite body of function " +
1393  behavioral_helper->get_function_name());
1394  if(instructions.empty())
1395  {
1396  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Edge profiling writer - Empty function");
1397  return;
1398  }
1399  else if(instructions.size() == 1)
1400  {
1401  if(GET_TYPE(cfgGraph, (*instructions.begin())) & TYPE_ENTRY)
1402  {
1403  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Edge profiling writer - Empty function");
1404  return;
1405  }
1406  }
1408  basic_blocks_labels.clear();
1409  VertexIterator vi, vi_end;
1410  vertex bbentry;
1411  CustomOrderedSet<vertex> bb_exit;
1412  if(!bb_start)
1413  {
1414  bbentry = bb_fcfgGraph->CGetBBGraphInfo()->entry_vertex;
1415  }
1416  else
1417  {
1418  bbentry = bb_start;
1419  }
1420  if(bb_end.empty())
1421  {
1422  bb_exit.insert(bb_fcfgGraph->CGetBBGraphInfo()->exit_vertex);
1424  "There are " + std::to_string(bb_exit.size()) + " exit basic blocks");
1425  }
1426  else
1427  {
1428  bb_exit = bb_end;
1429  }
1430  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Computing labels");
1431  for(boost::tie(vi, vi_end) = boost::vertices(*bb_fcfgGraph); vi != vi_end; vi++)
1432  {
1433  size_t delta = bb_exit.find(*vi) != bb_exit.end() ? 1u : 0u;
1434  if(boost::in_degree(*vi, *bb_fcfgGraph) <= (1 + delta))
1435  {
1437  "---Skipped BB" + std::to_string(bb_fcfgGraph->CGetBBNodeInfo(*vi)->block->number));
1438  continue;
1439  }
1440  const BBNodeInfoConstRef bb_node_info = bb_fcfgGraph->CGetBBNodeInfo(*vi);
1441  const unsigned int le = behavioral_helper->start_with_a_label(bb_node_info->block);
1442  basic_blocks_labels[bb_node_info->block->number] =
1443  (le ? behavioral_helper->get_label_name(le) :
1444  ("BB_LABEL_" + std::to_string(bb_node_info->block->number)) +
1445  (bb_label_counter == 1 ? "" : "_" + std::to_string(bb_label_counter)));
1447  "---Label of BB" + std::to_string(bb_fcfgGraph->CGetBBNodeInfo(*vi)->block->number) + " is " +
1448  basic_blocks_labels[bb_node_info->block->number]);
1449  }
1450  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Computed labels");
1452  bb_analyzed.clear();
1453  bb_analyzed.insert(bb_exit.begin(), bb_exit.end());
1455  goto_list.clear();
1457  bb_frontier.clear();
1458  bb_frontier.insert(bb_exit.begin(), bb_exit.end());
1459  local_rec_variableFunctor = variableFunctor;
1460  local_rec_function_behavior = function_behavior;
1461  local_rec_instructions.clear();
1462  local_rec_instructions.insert(instructions.begin(), instructions.end());
1465 
1466  OutEdgeIterator oE, oEEnd;
1468  writeRoutineInstructions_rec(bbentry, false);
1469  if(!bb_start && bb_end.size() == 0)
1470  {
1471  for(boost::tie(oE, oEEnd) = boost::out_edges(bbentry, *bb_fcfgGraph); oE != oEEnd; oE++)
1472  {
1473  if(bb_exit.find(boost::target(*oE, *bb_fcfgGraph)) != bb_exit.end())
1474  {
1475  continue;
1476  }
1477  else
1478  {
1479  writeRoutineInstructions_rec(boost::target(*oE, *bb_fcfgGraph), false);
1480  }
1481  }
1482  }
1483  CustomOrderedSet<vertex> not_yet_considered;
1484  std::set_difference(goto_list.begin(), goto_list.end(), /*first set*/
1485  bb_analyzed.begin(), bb_analyzed.end(), /*second set*/
1486  std::inserter(not_yet_considered, not_yet_considered.begin()) /*result*/
1487  );
1488  while(!not_yet_considered.empty())
1489  {
1490  vertex next_bb = *not_yet_considered.begin();
1491  not_yet_considered.erase(next_bb);
1492  writeRoutineInstructions_rec(next_bb, false);
1493  not_yet_considered.clear();
1494  std::set_difference(goto_list.begin(), goto_list.end(), /*first set*/
1495  bb_analyzed.begin(), bb_analyzed.end(), /*second set*/
1496  std::inserter(not_yet_considered, not_yet_considered.begin()) /*result*/);
1497  }
1498  const vertex exit = bb_fcfgGraph->CGetBBGraphInfo()->exit_vertex;
1499  if(goto_list.find(exit) != goto_list.end() &&
1501  {
1503  }
1504  EdgeIterator e, e_end;
1505  for(boost::tie(e, e_end) = boost::edges(*support_cfg); e != e_end; e++)
1506  {
1507  if(dumped_edges.find(*e) == dumped_edges.end() &&
1508  boost::source(*e, *support_cfg) != support_cfg->CGetBBGraphInfo()->entry_vertex &&
1509  boost::target(*e, *support_cfg) != support_cfg->CGetBBGraphInfo()->exit_vertex)
1510  {
1511  WriteFile("Error.c");
1513  PROFILING_EC,
1514  "Profiling Instrumentation of Edge of function " + behavioral_helper->get_function_name() +
1515  " from vertex BB" +
1516  std::to_string(support_cfg->CGetBBNodeInfo(boost::source(*e, *support_cfg))->block->number) +
1517  " to BB" +
1518  std::to_string(support_cfg->CGetBBNodeInfo(boost::target(*e, *support_cfg))->block->number) +
1519  " not printed");
1520  }
1521  }
1522  INDENT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, "<--Edge profiling writer - ended");
1523 }
1524 
1525 const std::map<unsigned int, std::map<unsigned int, unsigned int>>& EdgeCWriter::CGetFunctionLoopToId() const
1526 {
1527  return fun_loop_to_index;
1528 }
1529 
1531 {
1532  indented_output_stream->Append("void __builtin_bambu_time_start(){}\n");
1533  indented_output_stream->Append("void __builtin_bambu_time_stop(){}\n\n");
1534  indented_output_stream->Append("#define __builtin_cond_expr32(cond, value1, value2) cond ? value1 : value2\n\n");
1535  indented_output_stream->Append("#define __builtin___divsc3 __divsc3\n");
1536  indented_output_stream->Append("#define __builtin___divdc3 __divdc3\n");
1537 }
#define TYPE_SWITCH
constant identifying the node type of a SWITCH operation.
Definition: op_graph.hpp:105
std::map< vertex, EdgeDescriptor > local_inc
Increment which should be added before the label in a basic block.
virtual void print_loop_escaping(EdgeDescriptor e)
Dump operations requested for record information about a path which exit from a loop.
error during profiling
Definition: exceptions.hpp:331
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
int GetSelector() const
Return the selector of this graph.
Definition: graph.hpp:922
Vertex get_immediate_dominator(Vertex v) const
Return the immediate dominator of a Vertex.
Definition: Dominance.hpp:757
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
Definition: graph.hpp:1312
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
const dominance< BBGraph > * dominators
Definition: c_writer.hpp:145
virtual void print_end_path(unsigned int fun_id, unsigned int loop_id)
Print operations needed to store into symbol table information about last path.
unsigned int counter
The size of fun_loop_to_index.
CustomOrderedSet< vertex > goto_list
Definition: c_writer.hpp:141
static void clear_renaming_table()
remove all the entries from the renaming table
const std::map< unsigned int, std::map< unsigned int, unsigned int > > & CGetFunctionLoopToId() const
Returns the map which associates to each loop a unique id.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
#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
string target
Definition: lenet_tvm.py:16
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
virtual unsigned int end_with_a_cond_or_goto(const blocRef &block) const
Return the nodeID of the last statement of a basic block in case that statement is a cond or a goto e...
int debug_level
the debug level
Definition: c_writer.hpp:122
#define TYPE_IF
constant identifying the node type of an IF operation.
Definition: op_graph.hpp:100
const dominance< BBGraph > * post_dominators
Definition: c_writer.hpp:146
virtual void Initialize()
Initialize data structure.
Definition: c_writer.cpp:228
Class used to write the C code representing a program, this class can&#39;t be directly instantiated sinc...
Definition: c_writer.hpp:91
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
CustomOrderedSet< vertex > bb_frontier
Definition: c_writer.hpp:138
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
Class specification of the graph structures.
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
Definition: graph.hpp:1310
std::map< unsigned int, std::map< unsigned int, unsigned int > > fun_loop_to_index
Map a pair function - loop to an unique index.
unsigned int get_function_index() const
Return the index of the function.
unsigned int fun_id
Index of the current function.
Class to print indented code.
Simple class to print single instruction.
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
bool verbose
Verbosity means that a comment is printed for each line in the output file.
Definition: c_writer.hpp:116
BBGraphConstRef support_cfg
Special control flow graphs.
#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
#define TYPE_INIT
Constant string identifying an operation that is a variable initialization.
Definition: op_graph.hpp:167
virtual void print_loop_starting(EdgeDescriptor e)
Dump initializations of variable for recording a loop path.
const tree_managerConstRef TM
The tree manager.
Definition: c_writer.hpp:98
Data structure describing a basic block at tree level.
redefinition of map to manage ordered/unordered structures
Functor used to sort edges.
Definition: graph.hpp:1270
dominance< BBGraph > * post_dominators
This class stores post-dominator information.
A set of operation vertices.
Definition: op_graph.hpp:654
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.
#define FB_CFG_SELECTOR
Feedback control flow edge selector.
virtual std::string PrintConstant(const tree_nodeConstRef &var, const var_pp_functorConstRef vppf=var_pp_functorConstRef()) const
Print the constant associated with var.
boost::graph_traits< graph >::edge_iterator EdgeIterator
edge_iterator definition.
Definition: graph.hpp:1314
virtual void WriteFile(const std::string &file_name)
Writes the final C file.
Definition: c_writer.cpp:1913
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
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Definition: op_graph.hpp:843
This file contains the routines necessary to create a C executable program with instrumented edges...
const BBEdgeInfoConstRef CGetBBEdgeInfo(const EdgeDescriptor e) const
Returns the info associated with an edge.
Class specification for storing profiling information.
const IndentedOutputStreamRef indented_output_stream
Represents the stream we are currently writing to.
Definition: c_writer.hpp:101
unsigned edges[4545]
Definition: graph.h:25
Class used to describe a particular graph with basic blocks as nodes.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
virtual void WriteHeader() override
Writes the header of the file.
const ParameterConstRef Param
set of parameters
Definition: c_writer.hpp:119
void Append(const std::string &str)
Append a string to the output.
void writeRoutineInstructions_rec(vertex current_vertex, bool bracket)
Write recursively instructions belonging to a basic block of task or of a function.
#define default_COND
constant used to represent label "default" of a switch construct
Basic block control flow graph with feedback.
virtual int unsigned start_with_a_label(const blocRef &block) const
Return the nodeID of the first statement of a basic block in case that statement is a label expressio...
static void rename_a_variable(unsigned int var, const std::string &new_name)
rename a variable
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
#define TYPE_FOR
constant string identifying the node type of an WHILE operation.
Definition: op_graph.hpp:115
Support basic block for path profiling.
virtual ~EdgeCWriter() override
const BehavioralHelperConstRef CGetBehavioralHelper() const
Returns the helper associated with the function.
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Definition: graph.hpp:1307
EdgeCWriter(const HLS_managerConstRef _HLSMgr, const InstructionWriterRef instruction_writer, const IndentedOutputStreamRef indented_output_stream, const ParameterConstRef Param, bool verbose=true)
Constructor of the class.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
void writeRoutineInstructions(const unsigned int function_index, const OpVertexSet &instructions, const var_pp_functorConstRef variableFunctor, vertex bb_start=NULL_VERTEX, CustomOrderedSet< vertex > bb_end=CustomOrderedSet< vertex >()) override
Writes the instructions of the current routine, being it a task or a function of the original program...
std::set< EdgeDescriptor, ltedge< BBGraph > > dumped_edges
Set of already dumped edges.
dominance< BBGraph > * dominators
This class stores dominator information.
const HLS_managerConstRef HLSMgr
the hls manager
Definition: c_writer.hpp:95
std::map< unsigned int, std::string > basic_blocks_labels
Definition: c_writer.hpp:140
size_t bb_label_counter
Counter of the invocations of writeRoutineInstructions; this counter allows to print different labels...
Definition: c_writer.hpp:113
CustomOrderedSet< vertex > bb_analyzed
Definition: c_writer.hpp:139
Class specification of the tree_reindex support class.
FunctionBehaviorConstRef local_rec_function_behavior
Definition: c_writer.hpp:143
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
virtual void print_edge(EdgeDescriptor e, unsigned int index)
Dump operation requested for instrument an edges.
Class specification of the basic_block structure.
virtual void print_loop_ending(EdgeDescriptor e)
Dump operations requested for record information about a loop path which ends.
interface of a loop
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
T * get() const
Definition: refcount.hpp:169
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
const BBGraphConstRef CGetBBGraph(FunctionBehavior::bb_graph_type gt=FunctionBehavior::BB) const
This method returns the basic block graphs.
const LoopsConstRef CGetLoops() const
Return the loops.
#define TYPE_WHILE
constant string identifying the node type of an WHILE operation.
Definition: op_graph.hpp:110
interface of loops finding algorithm
virtual void print_loop_switching(EdgeDescriptor e)
Print operation requested for record information about a path which exit from a loop and immediately ...
Classes specification of the tree_node data structures not present in the gcc.
std::map< unsigned int, std::string > basic_block_prefix
string to be printed at the beginning of a given basic block
Definition: c_writer.hpp:130
this class is used to manage the command-line or XML options.
#define TYPE_ENTRY
constant identifying the node type of an entry node.
Control flow graph with feedback.
unsigned counter[N_THREADS]
Definition: data.c:3
#define DOALL_LOOP
parallelizable for loop
Definition: loop.hpp:132
std::map< vertex, std::map< unsigned int, std::string > > renaming_table
renaming table used by phi node destruction procedure
Definition: c_writer.hpp:136
virtual const std::string get_label_name(unsigned int label_expr_nid) const
return the label name associated with the label expression
#define TYPE_RET
constant string identifying an operation node of type return expr
Definition: op_graph.hpp:140
virtual void Initialize() override
Initialize data structure.
#define CFG_SELECTOR
Control flow graph edge selector.
var_pp_functorConstRef local_rec_variableFunctor
Definition: c_writer.hpp:142
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
CustomOrderedSet< vertex > local_rec_instructions
Definition: c_writer.hpp:144
std::map< unsigned int, std::string > basic_block_tail
string to be printed at the end of a given basic block
Definition: c_writer.hpp:133
const InstructionWriterRef instrWriter
Contains the class used to write instructions.
Definition: c_writer.hpp:109
#define TYPE_LAST_OP
A vertex of type LAST_OP if it is the last operation of the application.
Definition: op_graph.hpp:197
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.
Definition: graph.hpp:1316
#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:51 for PandA-2024.02 by doxygen 1.8.13