PandA-2024.02
switch_fix.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "switch_fix.hpp"
46 
48 #include "Parameter.hpp"
49 
51 #include "application_manager.hpp"
52 #include "function_behavior.hpp"
53 
55 #include "token_interface.hpp"
56 
58 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
59 #include "ext_tree_node.hpp"
60 #include "string_manipulation.hpp" // for GET_CLASS
61 #include "tree_basic_block.hpp"
62 #include "tree_helper.hpp"
63 #include "tree_manager.hpp"
64 #include "tree_manipulation.hpp"
65 #include "tree_node.hpp"
66 #include "tree_reindex.hpp"
67 
68 SwitchFix::SwitchFix(const application_managerRef _AppM, unsigned int _function_id,
69  const DesignFlowManagerConstRef _design_flow_manager, const ParameterConstRef _parameters)
70  : FunctionFrontendFlowStep(_AppM, _function_id, SWITCH_FIX, _design_flow_manager, _parameters)
71 {
72  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
73 }
74 
75 SwitchFix::~SwitchFix() = default;
76 
79 {
81  switch(relationship_type)
82  {
84  {
85  relationships.insert(std::make_pair(BLOCK_FIX, SAME_FUNCTION));
86  break;
87  }
89  {
90  break;
91  }
93  {
94  break;
95  }
96  default:
97  {
99  }
100  }
101  return relationships;
102 }
103 
105 {
106  const tree_managerRef TM = AppM->get_tree_manager();
107 
108  const auto tree_man = tree_manipulationRef(new tree_manipulation(TM, parameters, AppM));
110  auto* fd = GetPointer<function_decl>(temp);
111  auto* sl = GetPointer<statement_list>(GET_NODE(fd->body));
112  auto& list_of_block = sl->list_of_bloc;
113 
115  for(const auto& basic_block : list_of_block)
116  {
117  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Examining BB" + STR(basic_block.first));
118  const auto list_of_stmt = basic_block.second->CGetStmtList();
119  // Checking for switch
120  if(!list_of_stmt.empty() && GET_NODE(*(list_of_stmt.rbegin()))->get_kind() == gimple_switch_K)
121  {
122  const auto gs = GetPointer<const gimple_switch>(GET_NODE(list_of_stmt.back()));
124  "-->BB" + STR(basic_block.first) + " ends with a switch");
126  "-->Checking if some successor has more than two gimple_label");
129  CustomUnorderedSet<unsigned int> multiple_labels_blocks;
130  for(const auto succ : basic_block.second->list_of_succ)
131  {
132  const auto succ_list_of_stmt = list_of_block.find(succ)->second->CGetStmtList();
133  auto next = succ_list_of_stmt.begin();
134  next = succ_list_of_stmt.size() > 1 ? ++next : next;
135  if(succ_list_of_stmt.size() > 1 and GET_NODE(*next)->get_kind() == gimple_label_K)
136  {
138  multiple_labels_blocks.insert(succ);
139  }
140  }
142 
143  CustomUnorderedSet<unsigned int>::iterator multiple_labels_block,
144  multiple_labels_block_end = multiple_labels_blocks.end();
145  for(multiple_labels_block = multiple_labels_blocks.begin(); multiple_labels_block != multiple_labels_block_end;
146  ++multiple_labels_block)
147  {
148  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Splitting BB" + STR(*multiple_labels_block));
150  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Computing case labels");
152  const tree_vec* tv = GetPointer<tree_vec>(GET_NODE(gs->op1));
153  std::vector<tree_nodeRef>::const_iterator it, it_end = tv->list_of_op.end();
154  for(it = tv->list_of_op.begin(); it != it_end; ++it)
155  {
156  cases.insert(GET_NODE(GetPointer<case_label_expr>(GET_NODE(*it))->got));
157  }
159  blocRef current_block = list_of_block.find(*multiple_labels_block)->second;
160  const auto current_list_of_stmt = list_of_block.find(*multiple_labels_block)->second->CGetStmtList();
161  auto current_tree_node = current_list_of_stmt.front();
162  tree_nodeRef ld = GET_NODE(GetPointer<gimple_label>(GET_NODE(current_tree_node))->op);
163  if(cases.find(ld) == cases.end())
164  {
165  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->First label is not a case");
166  size_t stmt_i = 1;
167  auto stmt_index = current_list_of_stmt.begin();
168  THROW_ASSERT(current_list_of_stmt.size() > 1, "expected more than one statement");
169  ++stmt_index;
170  while(stmt_index != current_list_of_stmt.end())
171  {
172  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Examining operation " + STR(stmt_i));
173  current_tree_node = *stmt_index;
174  THROW_ASSERT(GET_NODE(current_tree_node)->get_kind() == gimple_label_K,
175  "An artificial label_decl has not been found at the beginning of the basic block");
176  ld = GET_NODE(GetPointer<gimple_label>(GET_NODE(current_tree_node))->op);
177  if(cases.find(ld) != cases.end())
178  {
179  break;
180  }
181  ++stmt_index;
182  ++stmt_i;
183  }
184  THROW_ASSERT(stmt_i < current_list_of_stmt.size(),
185  "An artificial label_decl has not been found at the beginning of the basic block");
186  const auto temp_label = *stmt_index;
187  list_of_block.find(*multiple_labels_block)->second->RemoveStmt(temp_label, AppM);
188  list_of_block.find(*multiple_labels_block)->second->PushFront(temp_label, AppM);
189  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Labels inverted");
190  }
191  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Splitting first label");
192 
193  current_tree_node = current_list_of_stmt.front();
194  list_of_block.find(*multiple_labels_block)->second->RemoveStmt(*(current_list_of_stmt.begin()), AppM);
197  blocRef new_bb = blocRef(new bloc(list_of_block.rbegin()->first + 1));
198  new_bb->loop_id = current_block->loop_id;
199  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created BB" + STR(new_bb->number));
200  list_of_block[new_bb->number] = new_bb;
201  new_bb->list_of_pred = current_block->list_of_pred;
203  for(auto predecessor : current_block->list_of_pred)
204  {
205  if(predecessor != basic_block.first)
206  {
207  auto& successors = list_of_block.find(predecessor)->second->list_of_succ;
208  successors.erase(std::find(successors.begin(), successors.end(), *multiple_labels_block));
209  successors.push_back(new_bb->number);
210  }
211  }
212  new_bb->PushFront(current_tree_node, AppM);
213  basic_block.second->list_of_succ.push_back(new_bb->number);
214  blocRef previous_block = new_bb;
215  auto next = current_list_of_stmt.begin();
216  next = current_list_of_stmt.size() > 1 ? ++next : next;
217  while(current_list_of_stmt.size() > 1 and GET_NODE(*next)->get_kind() == gimple_label_K)
218  {
219  ++next;
220  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Splitting next label");
222  current_tree_node = current_list_of_stmt.front();
223  list_of_block.find(*multiple_labels_block)->second->RemoveStmt(current_tree_node, AppM);
225  new_bb = blocRef(new bloc(list_of_block.rbegin()->first + 1));
226  new_bb->loop_id = previous_block->loop_id;
227  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created BB" + STR(new_bb->number));
228  list_of_block[new_bb->number] = new_bb;
229  new_bb->list_of_pred.push_back(previous_block->number);
230  previous_block->list_of_succ.push_back(new_bb->number);
231  new_bb->PushFront(current_tree_node, AppM);
232  previous_block = new_bb;
233 
234  ld = GET_NODE(GetPointer<gimple_label>(GET_NODE(current_tree_node))->op);
235  if(cases.find(ld) != cases.end())
236  {
237  new_bb->list_of_pred.push_back(basic_block.first);
238  basic_block.second->list_of_succ.push_back(new_bb->number);
239  }
240  }
242  current_block->list_of_pred.clear();
243  current_block->list_of_pred.push_back(previous_block->number);
244  previous_block->list_of_succ.push_back(*multiple_labels_block);
245 
248  current_tree_node = current_list_of_stmt.front();
249 
250  ld = GET_NODE(GetPointer<gimple_label>(GET_NODE(current_tree_node))->op);
251  if(cases.find(ld) == cases.end())
252  {
253  std::vector<unsigned int>& switch_list_of_succ = basic_block.second->list_of_succ;
254 
255  THROW_ASSERT(std::find(switch_list_of_succ.begin(), switch_list_of_succ.end(), current_block->number) !=
256  switch_list_of_succ.end(),
257  "current block not found between successors of current one");
258 
259  switch_list_of_succ.erase(
260  std::find(switch_list_of_succ.begin(), switch_list_of_succ.end(), current_block->number));
261  }
262  else
263  {
264  current_block->list_of_pred.push_back(basic_block.first);
265  }
266  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Split BB" + STR(*multiple_labels_block));
267  }
269  {
270  PrintTreeManager(false);
271  }
273  (!parameters->IsParameter("print-dot-FF") || parameters->GetParameter<unsigned int>("print-dot-FF")))
274  {
275  WriteBBGraphDot("BB_After_" + GetName() + "_BB" + STR(basic_block.first) + ".dot");
276  }
278  for(const auto succ : basic_block.second->list_of_succ)
279  {
280  if(list_of_block.find(succ)->second->list_of_pred.size() > 1)
281  {
282  to_be_fixed.insert(succ);
283  }
284  }
285  CustomUnorderedSet<unsigned int>::const_iterator t, t_end = to_be_fixed.end();
286  for(t = to_be_fixed.begin(); t != t_end; ++t)
287  {
289  // Creating new basic block
290  blocRef new_bb = blocRef(new bloc(list_of_block.rbegin()->first + 1));
291  new_bb->loop_id = basic_block.second->loop_id;
292  list_of_block[new_bb->number] = new_bb;
293  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding BB" + STR(new_bb->number));
294  new_bb->list_of_pred.push_back(basic_block.first);
295  new_bb->list_of_succ.push_back(*t);
296  size_t i, i_end;
297  i_end = basic_block.second->list_of_succ.size();
298  for(i = 0; i != i_end; i++)
299  {
300  if(basic_block.second->list_of_succ[i] == *t)
301  {
302  basic_block.second->list_of_succ[i] = new_bb->number;
303  break;
304  }
305  }
306  // if this flag true, there are more than one predecessor of *t basic block which end with a switch
307  bool multiple_pred_switch = false;
308  i_end = list_of_block.find(*t)->second->list_of_pred.size();
309  for(i = 0; i != i_end; i++)
310  {
311  if(list_of_block.find(*t)->second->list_of_pred[i] == basic_block.first)
312  {
313  list_of_block.find(*t)->second->list_of_pred[i] = new_bb->number;
314  for(const auto& phi : list_of_block.find(*t)->second->CGetPhiList())
315  {
316  auto* current_phi = GetPointer<gimple_phi>(GET_NODE(phi));
317  for(const auto& def_edge : current_phi->CGetDefEdgesList())
318  {
319  if(def_edge.second == basic_block.first)
320  {
321  current_phi->ReplaceDefEdge(TM, def_edge,
322  gimple_phi::DefEdge(def_edge.first, new_bb->number));
323  }
324  }
325  }
326  }
327  else
328  {
329  if(list_of_block.find(list_of_block.find(*t)->second->list_of_pred[i])->second and
330  list_of_block.find(list_of_block.find(*t)->second->list_of_pred[i])->second->CGetStmtList().size())
331  {
332  if(GET_NODE(list_of_block.find(list_of_block.find(*t)->second->list_of_pred[i])
333  ->second->CGetStmtList()
334  .back())
335  ->get_kind() == gimple_switch_K)
336  {
337  multiple_pred_switch = true;
338  }
339  }
340  }
341  }
342  // moving label expr
343  THROW_ASSERT(GET_NODE(list_of_block.find(*t)->second->CGetStmtList().front())->get_kind() == gimple_label_K,
344  "BB" + STR(*t) + " follows switch " + STR(basic_block.first) +
345  " but it does not start with a label");
346  if(multiple_pred_switch)
347  {
348  auto label_expr_node = list_of_block.find(*t)->second->CGetStmtList().front();
349  auto* le = GetPointer<gimple_label>(GET_NODE(label_expr_node));
350  tree_nodeRef label_decl_node = le->op;
351  auto* ld = GetPointer<label_decl>(GET_NODE(label_decl_node));
352  unsigned int new_label_decl_id = TM->new_tree_node_id();
353  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
354  IR_schema[TOK(TOK_TYPE)] = STR(GET_INDEX_NODE(ld->type));
355  IR_schema[TOK(TOK_SCPE)] = STR(GET_INDEX_NODE(ld->scpe));
356  IR_schema[TOK(TOK_SRCP)] = ld->include_name + ":" + STR(ld->line_number) + ":" + STR(ld->column_number);
357  IR_schema[TOK(TOK_ARTIFICIAL)] = STR(ld->artificial_flag);
358  TM->create_tree_node(new_label_decl_id, label_decl_K, IR_schema);
359  unsigned int new_label_expr_id = TM->new_tree_node_id();
360  IR_schema.clear();
361  IR_schema[TOK(TOK_SCPE)] = STR(GET_INDEX_NODE(ld->scpe));
362  IR_schema[TOK(TOK_OP)] = STR(new_label_decl_id);
363  IR_schema[TOK(TOK_SRCP)] = le->include_name + ":" + STR(le->line_number) + ":" + STR(ld->column_number);
364  TM->create_tree_node(new_label_expr_id, gimple_label_K, IR_schema);
365  auto gl = GetPointer<gimple_label>(TM->get_tree_node_const(new_label_expr_id));
366  gl->bb_index = new_bb->number;
367  auto* te = GetPointer<tree_vec>(GET_NODE(gs->op1));
368  std::vector<tree_nodeRef>& list_of_op = te->list_of_op;
369  for(auto& ind : list_of_op)
370  {
371  auto* cl = GetPointer<case_label_expr>(GET_NODE(ind));
372  if(GET_INDEX_NODE(cl->got) == GET_INDEX_NODE(le->op))
373  {
374  tree_nodeRef new_label_decl_reindex = TM->GetTreeReindex(new_label_decl_id);
375  cl->got = new_label_decl_reindex;
376  }
377  }
378  new_bb->PushFront(TM->GetTreeReindex(new_label_expr_id), AppM);
379  }
380  else
381  {
382  auto label = list_of_block.find(*t)->second->CGetStmtList().front();
383  list_of_block.find(*t)->second->RemoveStmt(label, AppM);
384  new_bb->PushFront(label, AppM);
385  }
387  }
389  {
390  PrintTreeManager(false);
391  }
393  (!parameters->IsParameter("print-dot-FF") || parameters->GetParameter<unsigned int>("print-dot-FF")))
394  {
395  WriteBBGraphDot("BB_After_" + GetName() + "_BB" + STR(basic_block.first) + ".dot");
396  }
397  if(AppM->ApplyNewTransformation())
398  {
399  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Removing switch");
401  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
402  unsigned int gimple_multi_way_if_id = TM->new_tree_node_id();
403  IR_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
404  IR_schema[TOK(TOK_SCPE)] = STR(function_id);
405  TM->create_tree_node(gimple_multi_way_if_id, gimple_multi_way_if_K, IR_schema);
406  auto new_gwi = GetPointer<gimple_multi_way_if>(TM->get_tree_node_const(gimple_multi_way_if_id));
407 
410  const auto gotos = GetPointer<const tree_vec>(GET_NODE(gs->op1));
411  for(const auto& goto_ : gotos->list_of_op)
412  {
413  const auto cle = GetPointer<const case_label_expr>(GET_NODE(goto_));
414  THROW_ASSERT(cle, STR(goto_));
416  "---Destination: " + STR(cle->got->index) + " CLE " + STR(cle->index));
417  case_labels[cle->got->index].insert(goto_);
418  }
419 
421  unsigned int default_bb = 0;
422 
424  for(auto succ : basic_block.second->list_of_succ)
425  {
426  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Considering successor BB" + STR(succ));
427  const auto succ_list_of_stmt = list_of_block.find(succ)->second->CGetStmtList();
428  const auto label = succ_list_of_stmt.front();
429  const auto gl = GetPointer<const gimple_label>(GET_NODE(label));
430  THROW_ASSERT(gl, STR(label));
431  tree_nodeRef cond = tree_nodeRef();
432  for(const auto& case_label : case_labels.find(gl->op->index)->second)
433  {
434  const auto cle = GetPointer<const case_label_expr>(GET_CONST_NODE(case_label));
435  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Considering case " + cle->ToString());
436  if(cle->op0)
437  {
438  if(cle->op1)
439  {
440  const auto low_value = tree_helper::GetConstValue(cle->op0);
441  const auto high_value = tree_helper::GetConstValue(cle->op1);
442  const auto eq = tree_man->CreateEqExpr(gs->op0, cle->op0, basic_block.second, function_id);
444  "---Equality is " +
445  GetPointer<const ssa_name>(GET_NODE(eq))->CGetDefStmt()->ToString());
446  cond = cond ? tree_man->CreateOrExpr(cond, eq, basic_block.second, function_id) : eq;
447  for(integer_cst_t index = low_value + 1; index <= high_value; index++)
448  {
449  cond = tree_man->CreateOrExpr(
450  cond,
451  tree_man->CreateEqExpr(
452  gs->op0, TM->CreateUniqueIntegerCst(index, tree_helper::CGetType(cle->op0)),
453  basic_block.second, function_id),
454  basic_block.second, function_id);
455  }
456  }
457  else
458  {
459  const auto eq = tree_man->CreateEqExpr(gs->op0, cle->op0, basic_block.second, function_id);
460  cond = cond ? tree_man->CreateOrExpr(cond, eq, basic_block.second, function_id) : eq;
461  }
462  }
464  else
465  {
466  default_bb = succ;
467  }
469  }
470  if(cond)
471  {
472  new_gwi->add_cond(cond, succ);
473  }
474  list_of_block.find(succ)->second->RemoveStmt(list_of_block.find(succ)->second->CGetStmtList().front(),
475  AppM);
476  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Considered successor BB" + STR(succ));
477  }
478  new_gwi->add_cond(tree_nodeRef(), default_bb);
479  basic_block.second->RemoveStmt(basic_block.second->CGetStmtList().back(), AppM);
480  basic_block.second->PushBack(TM->GetTreeReindex(gimple_multi_way_if_id), AppM);
481  AppM->RegisterTransformation(GetName(), TM->CGetTreeNode(gimple_multi_way_if_id));
483  }
485  {
486  PrintTreeManager(false);
487  }
489  }
490  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Examined BB" + STR(basic_block.first));
491  }
492 
493  function_behavior->UpdateBBVersion();
495 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
This struct specifies the field bloc (basic block).
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
A simple interface to token object of the raw files.
void PrintTreeManager(const bool before) const
Dump the tree manager.
#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
DesignFlowStep_Status InternalExec() override
Updates the tree to have a more compliant CFG.
Definition: switch_fix.cpp:104
Data structure describing a basic block at tree level.
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
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 THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
~SwitchFix() override
Destructor.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
void WriteBBGraphDot(const std::string &filename) const
Write the current version of statement list in dot format.
void create_tree_node(const unsigned int node_id, enum kind tree_node_type, std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
Factory method.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
#define index(x, y)
Definition: Keccak.c:74
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
Definition: tree_node.hpp:3750
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
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.
Definition: switch_fix.cpp:78
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
This file collects some utility functions.
Definition: APInt.hpp:53
#define BUILTIN_SRCP
const unsigned int function_id
The index of the function to be analyzed.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
SwitchFix(const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
Definition: switch_fix.cpp:68
std::vector< tree_nodeRef > list_of_op
list_of_op is the array of tree node stored in tree_vec node.(macro TREE_VEC_ELT) ...
Definition: tree_node.hpp:5310
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.
Analysis step that modifies the control flow graph to fix switches.
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.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
This struct specifies the tree_vec node.
Definition: tree_node.hpp:5299
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
int sl
Definition: adpcm.c:105
#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