PandA-2024.02
vectorize.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  */
41 #include "vectorize.hpp"
43 
45 #include "Parameter.hpp"
46 
48 #include "loop.hpp"
49 #include "loops.hpp"
50 
52 #include "application_manager.hpp"
53 #include "basic_block.hpp"
54 #include "call_graph.hpp"
55 #include "call_graph_manager.hpp"
56 #include "function_behavior.hpp"
57 
59 #include "design_flow_graph.hpp"
60 #include "design_flow_manager.hpp"
61 
63 #include "token_interface.hpp"
64 
66 #include "behavioral_helper.hpp"
67 #include "ext_tree_node.hpp"
68 #include "tree_basic_block.hpp"
69 #include "tree_helper.hpp"
70 #include "tree_manager.hpp"
71 #include "tree_manipulation.hpp"
73 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
74 #include "tree_node_dup.hpp"
75 #include "tree_reindex.hpp"
76 
77 #include "dbgPrintHelper.hpp"
78 #include "string_manipulation.hpp"
79 #include "utility.hpp"
80 
81 #include <boost/algorithm/string/replace.hpp>
82 
83 #ifndef NDEBUG
84 static std::string ToString(Transformation transformation)
85 {
86  switch(transformation)
87  {
88  case(NONE):
89  return "None";
90  case(COND_CON):
91  return "Convergent Cond";
92  case(COND_DIV):
93  return "Divergent Cond";
94  case(INC):
95  return "Inc";
96  case(INIT):
97  return "Init";
98  case(SCALAR):
99  return "Scalar";
100  case(SIMD):
101  return "Simd";
102  default:
103  {
104  THROW_UNREACHABLE("");
105  }
106  }
107  return "";
108 }
109 #endif
110 
111 Vectorize::Vectorize(const application_managerRef _AppM, unsigned int _function_id,
112  const DesignFlowManagerConstRef _design_flow_manager, const ParameterConstRef _parameters)
113  : FunctionFrontendFlowStep(_AppM, _function_id, VECTORIZE, _design_flow_manager, _parameters),
114  TM(_AppM->get_tree_manager()),
115  tree_man(new tree_manipulation(TM, _parameters, _AppM))
116 {
117  debug_level = _parameters->get_class_debug_level(GET_CLASS(*this));
118 }
119 
120 Vectorize::~Vectorize() = default;
121 
124 {
126  switch(relationship_type)
127  {
129  {
130  relationships.insert(std::make_pair(BB_CONTROL_DEPENDENCE_COMPUTATION, SAME_FUNCTION));
131  relationships.insert(std::make_pair(LOOPS_ANALYSIS_BAMBU, SAME_FUNCTION));
132  relationships.insert(std::make_pair(BB_ORDER_COMPUTATION, SAME_FUNCTION));
133  relationships.insert(std::make_pair(BB_REACHABILITY_COMPUTATION, SAME_FUNCTION));
134  relationships.insert(std::make_pair(PREDICATE_STATEMENTS, SAME_FUNCTION));
135  const auto is_simd = tree_helper::has_omp_simd(GetPointerS<const statement_list>(
136  GET_CONST_NODE(GetPointerS<const function_decl>(TM->CGetTreeNode(function_id))->body)));
137  if(is_simd)
138  {
139  relationships.insert(std::make_pair(SERIALIZE_MUTUAL_EXCLUSIONS, SAME_FUNCTION));
140  }
141  break;
142  }
144  {
146  {
147  relationships.insert(std::make_pair(DEAD_CODE_ELIMINATION, SAME_FUNCTION));
148  relationships.insert(std::make_pair(MULTI_WAY_IF, SAME_FUNCTION));
149  relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF, SAME_FUNCTION));
150  }
151  break;
152  }
154  {
155  relationships.insert(std::make_pair(REMOVE_CLOBBER_GA, SAME_FUNCTION));
156  relationships.insert(std::make_pair(SIMPLE_CODE_MOTION, SAME_FUNCTION));
157  relationships.insert(std::make_pair(DEAD_CODE_ELIMINATION, SAME_FUNCTION));
158  relationships.insert(std::make_pair(DEAD_CODE_ELIMINATION_IPA, WHOLE_APPLICATION));
159  break;
160  }
161  default:
162  {
163  THROW_UNREACHABLE("");
164  }
165  }
166  return relationships;
167 }
168 
170 {
171  if(parameters->IsParameter("vectorize") and parameters->GetParameter<std::string>("vectorize") == "disable")
172  {
174  }
175 
177  ClassifyLoop(function_behavior->GetLoops()->GetLoop(0), 0);
178 
180  AddGuards();
181 #ifndef NDEBUG
183  {
184  WriteBBGraphDot("BB_Inside_" + GetName() + "_Guards.dot");
185  }
186 #endif
187 
189  FixPhis();
190 #ifndef NDEBUG
192  {
193  WriteBBGraphDot("BB_Inside_" + GetName() + "_FixPhis.dot");
194  }
195 #endif
196  SetPredication();
198 #ifndef NDEBUG
200  {
201  WriteBBGraphDot("BB_Inside_" + GetName() + "_Predicated.dot");
202  }
203 #endif
204 
206  const BBGraphRef bb_graph = function_behavior->GetBBGraph(FunctionBehavior::BB);
207  VertexIterator bb, bb_end;
208  for(boost::tie(bb, bb_end) = boost::vertices(*bb_graph); bb != bb_end; bb++)
209  {
210  const BBNodeInfoConstRef bb_node_info = bb_graph->CGetBBNodeInfo(*bb);
211  if(simd_loop_type[bb_node_info->loop_id] != SIMD_NONE)
212  {
213  const blocRef block = bb_node_info->block;
214  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Classifying statement of BB" + STR(block->number));
215  for(const auto& statement : block->CGetStmtList())
216  {
217  ClassifyTreeNode(bb_node_info->loop_id, GET_CONST_NODE(statement));
218  }
219  for(const auto& phi : block->CGetPhiList())
220  {
221  ClassifyTreeNode(bb_node_info->loop_id, GET_CONST_NODE(phi));
222  }
223  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Classified statement of BB" + STR(block->number));
224  }
225  }
226 
228  for(boost::tie(bb, bb_end) = boost::vertices(*bb_graph); bb != bb_end; bb++)
229  {
230  const BBNodeInfoConstRef bb_node_info = bb_graph->CGetBBNodeInfo(*bb);
231  if(simd_loop_type[bb_node_info->loop_id] != SIMD_NONE)
232  {
233  const blocRef block = bb_node_info->block;
235  "-->Transforming increment statement of BB" + STR(block->number));
236  for(const auto& statement : block->CGetStmtList())
237  {
238  if(transformations.find(statement->index)->second == INC)
239  {
241  {
242  const std::string file_name = parameters->getOption<std::string>(OPT_output_temporary_directory) +
243  "before_" + STR(statement->index) + "_expansion.gimple";
244  std::ofstream gimple_file(file_name.c_str());
245  TM->PrintGimple(gimple_file, false);
246  gimple_file.close();
247  }
248  const auto new_statement = DuplicateIncrement(bb_node_info->loop_id, GET_NODE(statement));
249  block->PushBefore(TM->GetTreeReindex(new_statement), statement, AppM);
250  ClassifyTreeNode(bb_node_info->loop_id, TM->get_tree_node_const(new_statement));
251  transformations[new_statement] = INC;
253  {
254  const std::string file_name = parameters->getOption<std::string>(OPT_output_temporary_directory) +
255  "after_" + STR(statement->index) + "_expansion.gimple";
256  std::ofstream gimple_file(file_name.c_str());
257  TM->PrintGimple(gimple_file, false);
258  gimple_file.close();
259  }
260  }
261  }
263  "<--Transformed increment statement of BB" + STR(block->number));
264  }
265  }
266 #ifndef NDEBUG
268  {
269  WriteBBGraphDot("BB_Inside_" + GetName() + "_Duplicated.dot");
270  }
271 #endif
272 
274  for(boost::tie(bb, bb_end) = boost::vertices(*bb_graph); bb != bb_end; bb++)
275  {
276  const BBNodeInfoConstRef bb_node_info = bb_graph->CGetBBNodeInfo(*bb);
277  if(simd_loop_type[bb_node_info->loop_id] != SIMD_NONE)
278  {
279  const blocRef block = bb_node_info->block;
281  "-->Transforming statement of BB" + STR(block->number) + " - Loop " +
282  STR(bb_node_info->loop_id) + " - Parallel degree " +
283  STR(loop_parallel_degree[bb_node_info->loop_id]));
284  std::list<tree_nodeRef> new_statement_list;
285  std::vector<tree_nodeRef> new_phi_list;
286  for(const auto& statement : block->CGetStmtList())
287  {
288  TM->GetTreeReindex(Transform(statement->index, loop_parallel_degree[bb_node_info->loop_id], 0,
289  new_statement_list, new_phi_list));
290  }
291  for(const auto& phi : block->CGetPhiList())
292  {
293  TM->GetTreeReindex(Transform(phi->index, loop_parallel_degree[bb_node_info->loop_id], 0, new_statement_list,
294  new_phi_list));
295  }
297  const auto& old_statement_list = block->CGetStmtList();
298  while(old_statement_list.size())
299  {
300  block->RemoveStmt(old_statement_list.front(), AppM);
301  }
303  const auto& old_phi_list = block->CGetPhiList();
304  while(old_phi_list.size())
305  {
306  block->RemovePhi(old_phi_list.front());
307  }
309  for(const auto& new_stmt : new_statement_list)
310  {
311  block->PushBack(new_stmt, AppM);
312  }
314  for(const auto& new_phi : new_phi_list)
315  {
316  block->AddPhi(new_phi);
317  }
318  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Transformed statement of BB" + STR(block->number));
319  }
320  }
321 
322  iv_increment.clear();
323  simd_loop_type.clear();
324  loop_parallel_degree.clear();
325  basic_block_divergence.clear();
326  transformations.clear();
327  function_behavior->UpdateBBVersion();
328  guards.clear();
330 }
331 
332 void Vectorize::ClassifyLoop(const LoopConstRef loop, const size_t parallel_degree)
333 {
334  const auto loop_id = loop->GetId();
335  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Analyzing loop " + STR(loop_id));
336  const auto cdg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::CDG_BB);
337 
339  const auto potential_parallel_degree = parameters->getOption<size_t>(OPT_gcc_openmp_simd);
340  const size_t current_parallel_degree = parallel_degree != 0 ? parallel_degree :
341  (loop->loop_type & DOALL_LOOP) ? potential_parallel_degree :
342  0;
343  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Loop parallel degree: " + STR(current_parallel_degree));
344 
345  if(loop->loop_type & DOALL_LOOP)
346  {
347  const auto iteration_number =
348  (loop->loop_type & COUNTABLE_LOOP) ?
349  ((loop->upper_bound + (loop->close_interval ? 1 : 0) - loop->lower_bound) / loop->increment) :
350  integer_cst_t(0);
352  if(loop->loop_type & COUNTABLE_LOOP && iteration_number % static_cast<long long>(potential_parallel_degree) == 0)
353  {
356  "-->Loop is parallelizable, countable and the iterations number is multiple of parallel degree");
358  basic_block_divergence[loop_id] = false;
359 
361  THROW_ASSERT(boost::in_degree(loop->GetHeader(), *cdg_bb_graph) == 1, "");
362  InEdgeIterator ie, ie_end;
363  boost::tie(ie, ie_end) = boost::in_edges(loop->GetHeader(), *cdg_bb_graph);
364  auto edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
365  auto source = boost::source(*ie, *cdg_bb_graph);
366  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
367  const auto header_controller =
368  std::pair<vertex, unsigned int>(source, edge_labels.size() ? *(edge_labels.begin()) : 0);
369 
371  const auto blocks = loop->get_blocks();
372  for(const auto block : blocks)
373  {
374  boost::tie(ie, ie_end) = boost::in_edges(block, *cdg_bb_graph);
375  edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
376  source = boost::source(*ie, *cdg_bb_graph);
377  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
378  const auto current_controller =
379  std::pair<vertex, unsigned int>(source, edge_labels.size() ? *(edge_labels.begin()) : 0);
380  const auto bb_index = cdg_bb_graph->CGetBBNodeInfo(block)->block->number;
381  if(current_controller == header_controller)
382  {
383  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "BB" + STR(bb_index) + " does not diverge");
384  basic_block_divergence[bb_index] = false;
385  }
386  else
387  {
388  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "BB" + STR(bb_index) + " diverges");
389  basic_block_divergence[bb_index] = true;
390  }
391  }
393  }
394  else
395  {
398  "Loop is parallelizable but not countable or iterations number is not multiple of parallel degree");
399  const auto blocks = loop->get_blocks();
400  for(const auto block : blocks)
401  {
402  basic_block_divergence[cdg_bb_graph->CGetBBNodeInfo(block)->block->number] = true;
403  }
404  }
405  }
406  else if(current_parallel_degree != 0)
407  {
408  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Loop is an inner simd");
410  THROW_ASSERT(boost::in_degree(loop->GetHeader(), *cdg_bb_graph) == 1, "");
411  InEdgeIterator ie, ie_end;
412  boost::tie(ie, ie_end) = boost::in_edges(loop->GetHeader(), *cdg_bb_graph);
413  auto edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
414  auto source = boost::source(*ie, *cdg_bb_graph);
415  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
416  const auto header_controller =
417  std::pair<vertex, unsigned int>(source, edge_labels.size() ? *(edge_labels.begin()) : 0);
418  if(!basic_block_divergence[cdg_bb_graph->CGetBBNodeInfo(header_controller.first)->block->number] and
419  (loop->loop_type & COUNTABLE_LOOP) and !basic_block_divergence.find(loop->Parent()->GetId())->second)
420  {
421  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Header does not diverge");
422  basic_block_divergence[loop_id] = false;
424  const auto blocks = loop->get_blocks();
425  for(const auto block : blocks)
426  {
427  boost::tie(ie, ie_end) = boost::in_edges(block, *cdg_bb_graph);
428  edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
429  source = boost::source(*ie, *cdg_bb_graph);
430  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
431  const auto current_controller =
432  std::pair<vertex, unsigned int>(source, edge_labels.size() ? *(edge_labels.begin()) : 0);
433  const auto bb_index = cdg_bb_graph->CGetBBNodeInfo(block)->block->number;
434  if(current_controller == header_controller)
435  {
436  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "BB" + STR(bb_index) + " does not diverge");
437  basic_block_divergence[bb_index] = false;
438  }
439  else
440  {
441  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "BB" + STR(bb_index) + " diverges");
442  basic_block_divergence[bb_index] = true;
443  }
444  }
446  }
447  else
448  {
450  "---Header diverges, so all the basic blocks of the loop diverge");
451  const auto blocks = loop->get_blocks();
452  for(const auto block : blocks)
453  {
454  basic_block_divergence[cdg_bb_graph->CGetBBNodeInfo(block)->block->number] = true;
455  }
456  }
458  }
459 
460  loop_parallel_degree[loop_id] = current_parallel_degree;
461 
463  if(current_parallel_degree != parallel_degree)
464  {
465  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Loop " + STR(loop_id) + ": outer simd");
466  simd_loop_type[loop_id] = SIMD_OUTER;
467  }
468  else if(current_parallel_degree != 0)
469  {
470  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Loop " + STR(loop_id) + ": inner simd");
471  simd_loop_type[loop_id] = SIMD_INNER;
472  }
473  else
474  {
475  simd_loop_type[loop_id] = SIMD_NONE;
476  }
477 
478  for(const auto& nested_loop : loop->GetChildren())
479  {
480  ClassifyLoop(nested_loop, current_parallel_degree);
481  }
482  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Analyzed loop " + STR(loop_id));
483 }
484 
485 void Vectorize::ClassifyTreeNode(const unsigned int loop_id, const tree_nodeConstRef tree_node)
486 {
487  if(transformations.find(tree_node->index) != transformations.end())
488  {
489  return;
490  }
492  "-->Classifying " + tree_node->get_kind_text() + " " + STR(tree_node->index) + ": " +
493  tree_node->ToString());
494  const LoopConstRef loop = function_behavior->CGetLoops()->CGetLoop(loop_id);
495  switch(tree_node->get_kind())
496  {
497  case gimple_assign_K:
498  {
499  const auto* ga = GetPointer<const gimple_assign>(tree_node);
500  const auto behavioral_helper = function_behavior->CGetBehavioralHelper();
501  ClassifyTreeNode(loop_id, GET_NODE(ga->op0));
502  ClassifyTreeNode(loop_id, GET_NODE(ga->op1));
503  if(ga->vdef)
504  {
505  ClassifyTreeNode(loop_id, GET_NODE(ga->vdef));
506  }
507 
509  if(ga->predicate)
510  {
511  transformations[tree_node->index] = SCALAR;
512  }
513  else if(loop->inc_id == tree_node->index and simd_loop_type[loop->GetId()] == SIMD_OUTER)
514  {
515  transformations[tree_node->index] = INC;
516  }
518  else if(transformations.find(ga->index) == transformations.end())
519  {
520  if((transformations.find(ga->op1->index) != transformations.end() and
521  transformations.find(ga->op1->index)->second == SCALAR) or
522  (transformations.find(ga->op0->index) != transformations.end() and
523  transformations.find(ga->op0->index)->second == SCALAR))
524  {
525  transformations[tree_node->index] = SCALAR;
526  }
527  else
528  {
529  transformations[tree_node->index] = SIMD;
530  }
531  }
532  break;
533  }
534  case ssa_name_K:
535  {
536  const auto* sa = GetPointer<const ssa_name>(tree_node);
537  THROW_ASSERT(sa->CGetDefStmts().size() == 1,
538  "Not in ssa form: " + STR(sa->CGetDefStmts().size()) + " definitions");
539  const auto bb_index = GetPointer<const gimple_node>(GET_NODE(sa->CGetDefStmt()))->bb_index;
540  const BBGraphConstRef bb_fcfg = function_behavior->CGetBBGraph(FunctionBehavior::FBB);
541  const auto loop_index =
542  bb_fcfg->CGetBBNodeInfo(bb_fcfg->CGetBBGraphInfo()->bb_index_map.find(bb_index)->second)->loop_id;
543  if(GetPointer<const gimple_pragma>(GET_CONST_NODE(sa->CGetDefStmt())))
544  {
545  // SKIP
546  }
547  else if(simd_loop_type.find(loop_index)->second == SIMD_NONE)
548  {
549  transformations[tree_node->index] = NONE;
550  }
551  else if(GET_CONST_NODE(tree_helper::CGetType(tree_node))->get_kind() == pointer_type_K or sa->virtual_flag)
552  {
553  transformations[tree_node->index] = SCALAR;
554  }
555  else
556  {
557  transformations[tree_node->index] = SIMD;
558  }
559  break;
560  }
562  {
563  const auto* ue = GetPointer<const unary_expr>(tree_node);
564  ClassifyTreeNode(loop_id, GET_NODE(ue->op));
565  if(tree_node->get_kind() == nop_expr_K or tree_node->get_kind() == convert_expr_K or
566  tree_node->get_kind() == abs_expr_K)
567  {
569  transformations[tree_node->index] = SCALAR;
570  }
571  else
572  {
573  transformations[tree_node->index] = transformations[ue->op->index];
574  }
575  break;
576  }
578  {
579  const auto* be = GetPointer<const binary_expr>(tree_node);
580  if(tree_node->get_kind() == mem_ref_K or tree_node->get_kind() == trunc_div_expr_K or
581  tree_node->get_kind() == trunc_mod_expr_K or tree_node->get_kind() == widen_mult_expr_K or
582  tree_node->get_kind() == mult_expr_K or tree_node->get_kind() == extract_bit_expr_K)
583  {
584  transformations[tree_node->index] = SCALAR;
585  }
587  else if(tree_node->get_kind() == rshift_expr_K or tree_node->get_kind() == lshift_expr_K or
588  tree_node->get_kind() == le_expr_K /*) and (GET_NODE(be->op0)->get_kind() == integer_cst_K)*/)
589  {
590  transformations[tree_node->index] = SCALAR;
591  }
592 #if 0
593  else if(tree_node->get_kind() == plus_expr_K)
594  {
595  ClassifyTreeNode(loop_id, GET_NODE(be->op0));
596  ClassifyTreeNode(loop_id, GET_NODE(be->op1));
597  transformations[tree_node->index] = SIMD;
598  }
599 #endif
600  else
601  {
602  transformations[tree_node->index] = SCALAR;
603  ClassifyTreeNode(loop_id, GET_NODE(be->op0));
604  ClassifyTreeNode(loop_id, GET_NODE(be->op1));
605  transformations[tree_node->index] = SIMD;
606  }
607  break;
608  }
609  case CASE_CST_NODES:
610  {
611  break;
612  }
613  case gimple_phi_K:
614  {
615  const auto* gp = GetPointer<const gimple_phi>(tree_node);
616  for(const auto& def_edge : gp->CGetDefEdgesList())
617  {
618  ClassifyTreeNode(loop_id, GET_NODE(def_edge.first));
619  THROW_ASSERT(GET_NODE(def_edge.first)->get_kind() != var_decl_K,
620  "Unsupported pattern - Phi is" + STR(tree_node));
621  if(def_edge.first->get_kind() == var_decl_K)
622  {
623  THROW_ERROR("Unsupported pattern");
624  }
625  transformations[tree_node->index] = SIMD;
626  }
627  ClassifyTreeNode(loop_id, GET_NODE(gp->res));
629  if(loop->init_gimple_id == tree_node->index and simd_loop_type[loop->GetId()] == SIMD_OUTER)
630  {
631  iv_increment[gp->res->index] = function_behavior->CGetLoops()->CGetLoop(loop_id)->increment;
632  transformations[tree_node->index] = INIT;
633  }
635  else if(loop->GetId() == gp->bb_index and simd_loop_type[loop->GetId()] == SIMD_OUTER)
636  {
637  if(gp->virtual_flag || GET_CONST_NODE(tree_helper::CGetType(gp->res))->get_kind() == boolean_type_K)
638  {
639  transformations[gp->index] = SIMD;
640  }
641  else
642  {
643  const BBGraphConstRef bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::BB);
644  const vertex header = bb_graph->CGetBBGraphInfo()->bb_index_map.find(loop_id)->second;
645  if(boost::in_degree(header, *bb_graph) != 1)
646  {
647  THROW_ASSERT(false, "Header loop has more than non-feedback incoming edge");
648  THROW_ERROR("Unsupported pattern");
649  }
650  InEdgeIterator ie, ie_end;
651  boost::tie(ie, ie_end) = boost::in_edges(header, *bb_graph);
652  const vertex previous = boost::source(*ie, *bb_graph);
653  const auto previous_id = bb_graph->CGetBBNodeInfo(previous)->block->number;
654  for(const auto& def_edge : gp->CGetDefEdgesList())
655  {
656  if(def_edge.second != previous_id)
657  {
658  const tree_nodeRef loop_ssa = GET_NODE(def_edge.first);
659  if(loop_ssa->get_kind() != ssa_name_K)
660  {
661  THROW_ASSERT(false, "Unsupported pattern - Operand of ssa is " + loop_ssa->ToString());
662  THROW_ERROR("Unsupported pattern");
663  }
664  const auto* sn = GetPointer<const ssa_name>(loop_ssa);
665  if(sn->CGetDefStmts().size() != 1)
666  {
667  THROW_ASSERT(false, sn->ToString() + " has not a single definition");
668  THROW_ERROR("Unsupported pattern");
669  }
670  const auto* ga = GetPointer<const gimple_assign>(GET_NODE(sn->CGetDefStmt()));
671  if(!ga)
672  {
673  THROW_ASSERT(false, sn->ToString() + " is not defined in a gimple assignment but in " +
674  sn->CGetDefStmt()->ToString());
675  THROW_ERROR("Unsupported pattern");
676  }
677  const auto* pe = GetPointer<const plus_expr>(GET_NODE(ga->op1));
678  if(!pe)
679  {
680  THROW_ASSERT(false, "Unexpected pattern: " + ga->op1->ToString());
681  THROW_ERROR("Unsupported pattern");
682  }
683  if(pe->op0->index != gp->res->index)
684  {
685  THROW_ASSERT(false, "Unexpected pattern: " + pe->op0->ToString());
686  THROW_ERROR("Unsupported pattern");
687  }
688  const auto* ic = GetPointer<const integer_cst>(GET_NODE(pe->op1));
689  if(!ic)
690  {
691  THROW_ASSERT(false, "Unexpected pattern: " + pe->op1->ToString());
692  THROW_ERROR("Unsupported pattern");
693  }
694  iv_increment[gp->res->index] = tree_helper::GetConstValue(pe->op1);
695  transformations[gp->index] = INIT;
696  transformations[ga->index] = INC;
697  break;
698  }
699  }
700  }
701  }
702  else
703  {
704  transformations[tree_node->index] = SIMD;
705  }
706 
707  break;
708  }
709  case target_mem_ref461_K:
710  {
711  const auto* tmr = GetPointer<const target_mem_ref461>(tree_node);
712  if(tmr->base)
713  {
714  ClassifyTreeNode(loop_id, GET_NODE(tmr->base));
715  }
716  if(tmr->offset)
717  {
718  ClassifyTreeNode(loop_id, GET_NODE(tmr->offset));
719  }
720  if(tmr->idx)
721  {
722  ClassifyTreeNode(loop_id, GET_NODE(tmr->idx));
723  }
724  if(tmr->step)
725  {
726  ClassifyTreeNode(loop_id, GET_NODE(tmr->step));
727  }
728  if(tmr->idx2)
729  {
730  ClassifyTreeNode(loop_id, GET_NODE(tmr->idx2));
731  }
732  transformations[tree_node->index] = SCALAR;
733  break;
734  }
735  case var_decl_K:
736  {
737  transformations[tree_node->index] = SCALAR;
738  break;
739  }
740  case gimple_cond_K:
741  {
742  const auto* gc = GetPointer<const gimple_cond>(tree_node);
744  const auto basic_block_index = gc->bb_index;
745  const BBGraphConstRef fbb = function_behavior->CGetBBGraph(FunctionBehavior::FBB);
746  const auto basic_block = fbb->CGetBBGraphInfo()->bb_index_map.find(basic_block_index)->second;
747  ClassifyTreeNode(loop_id, GET_NODE(gc->op0));
748  bool divergent = false;
749  if(std::find(loop->exit_block_iter_begin(), loop->exit_block_iter_end(), basic_block) ==
750  loop->exit_block_iter_end())
751  {
752  divergent = true;
753  }
754  else
755  {
756  divergent = basic_block_divergence.find(basic_block_index)->second;
758  OutEdgeIterator oe, oe_end;
759  for(boost::tie(oe, oe_end) = boost::out_edges(basic_block, *fbb); oe != oe_end; oe++)
760  {
761  const auto target_basic_block = boost::target(*oe, *fbb);
762  const auto target_basic_block_index = fbb->CGetBBNodeInfo(target_basic_block)->block->number;
763  if(basic_block_divergence.find(target_basic_block_index) == basic_block_divergence.end() or
764  !basic_block_divergence.find(target_basic_block_index)->second)
765  {
766  }
767  else
768  {
769  divergent = true;
770  }
771  }
772  }
773  transformations[tree_node->index] = divergent ? COND_DIV : COND_CON;
774  break;
775  }
776  case cond_expr_K:
777  {
778  const auto* ce = GetPointer<const cond_expr>(tree_node);
779  ClassifyTreeNode(loop_id, GET_NODE(ce->op0));
780  ClassifyTreeNode(loop_id, GET_NODE(ce->op1));
781  ClassifyTreeNode(loop_id, GET_NODE(ce->op2));
782  transformations[tree_node->index] = SIMD;
783  break;
784  }
785  case array_ref_K:
786  {
787  const auto* ar = GetPointer<const array_ref>(tree_node);
788  ClassifyTreeNode(loop_id, GET_NODE(ar->op0));
789  ClassifyTreeNode(loop_id, GET_NODE(ar->op1));
790  if(ar->op2)
791  {
792  ClassifyTreeNode(loop_id, GET_NODE(ar->op2));
793  }
794  if(ar->op3)
795  {
796  ClassifyTreeNode(loop_id, GET_NODE(ar->op3));
797  }
798  transformations[tree_node->index] = SCALAR;
799  break;
800  }
801  case call_expr_K:
802  case aggr_init_expr_K:
803  {
804  const auto* ce = GetPointer<const call_expr>(tree_node);
805  const auto* ae = GetPointer<const addr_expr>(GET_NODE(ce->fn));
806  const auto* fd = GetPointer<const function_decl>(GET_NODE(ae->op));
807  const auto* in = GetPointer<const identifier_node>(GET_NODE(fd->name));
808  const std::string function_name = in->strg;
809  transformations[tree_node->index] = TM->GetFunction("parallel_" + function_name) ? SIMD : SCALAR;
810  break;
811  }
812  case bit_ior_concat_expr_K:
813  case ternary_plus_expr_K:
814  case ternary_pm_expr_K:
815  case ternary_mp_expr_K:
816  case ternary_mm_expr_K:
817  case fshl_expr_K:
818  case fshr_expr_K:
819  case insertvalue_expr_K:
820  {
821  const auto te = GetPointer<const ternary_expr>(tree_node);
822  ClassifyTreeNode(loop_id, GET_NODE(te->op0));
823  ClassifyTreeNode(loop_id, GET_NODE(te->op1));
824  ClassifyTreeNode(loop_id, GET_NODE(te->op2));
825  transformations[tree_node->index] = SCALAR;
826  break;
827  }
828  case lut_expr_K:
829  {
830  auto* le = GetPointer<const lut_expr>(tree_node);
831  ClassifyTreeNode(loop_id, GET_NODE(le->op0));
832  ClassifyTreeNode(loop_id, GET_NODE(le->op1));
833  if(le->op2)
834  {
835  ClassifyTreeNode(loop_id, GET_NODE(le->op2));
836  }
837  if(le->op3)
838  {
839  ClassifyTreeNode(loop_id, GET_NODE(le->op3));
840  }
841  if(le->op4)
842  {
843  ClassifyTreeNode(loop_id, GET_NODE(le->op4));
844  }
845  if(le->op5)
846  {
847  ClassifyTreeNode(loop_id, GET_NODE(le->op5));
848  }
849  if(le->op6)
850  {
851  ClassifyTreeNode(loop_id, GET_NODE(le->op6));
852  }
853  if(le->op7)
854  {
855  ClassifyTreeNode(loop_id, GET_NODE(le->op7));
856  }
857  if(le->op8)
858  {
859  ClassifyTreeNode(loop_id, le->op8);
860  }
861  transformations[tree_node->index] = SCALAR;
862  break;
863  }
864  case const_decl_K:
865  case field_decl_K:
866  case function_decl_K:
867  case label_decl_K:
868  case namespace_decl_K:
869  case parm_decl_K:
870  case result_decl_K:
871  case translation_unit_decl_K:
872  case template_decl_K:
873  case error_mark_K:
874  case using_decl_K:
875  case type_decl_K:
876  case target_mem_ref_K:
877  case binfo_K:
878  case block_K:
879  case case_label_expr_K:
880  case constructor_K:
881  case identifier_node_K:
882  case statement_list_K:
883  case tree_list_K:
884  case tree_vec_K:
885  case CASE_CPP_NODES:
886  case CASE_FAKE_NODES:
887  case gimple_asm_K:
888  case gimple_bind_K:
889  case gimple_call_K:
890  case gimple_for_K:
891  case gimple_goto_K:
892  case gimple_label_K:
893  case gimple_multi_way_if_K:
894  case gimple_nop_K:
895  case gimple_pragma_K:
896  case gimple_predict_K:
897  case gimple_resx_K:
898  case gimple_return_K:
899  case gimple_switch_K:
900  case gimple_while_K:
901  case CASE_PRAGMA_NODES:
902  case array_range_ref_K:
903  case target_expr_K:
904  case component_ref_K:
905  case bit_field_ref_K:
906  case vtable_ref_K:
907  case with_cleanup_expr_K:
908  case obj_type_ref_K:
909  case save_expr_K:
910  case vec_cond_expr_K:
911  case vec_perm_expr_K:
912  case dot_prod_expr_K:
913  case insertelement_expr_K:
914  case CASE_TYPE_NODES:
915  {
916  THROW_UNREACHABLE("Not supported tree node " + tree_node->get_kind_text());
917  break;
918  }
919  default:
920  {
921  THROW_UNREACHABLE("");
922  }
923  }
925  "<--" +
926  (transformations.find(tree_node->index) != transformations.end() ?
927  ToString(transformations[tree_node->index]) :
928  "Unclassified") +
929  " - " + STR(tree_node->index) + ": " + tree_node->ToString());
930 }
931 
932 unsigned int Vectorize::DuplicateIncrement(const unsigned int loop_id, const tree_nodeRef statement)
933 {
934  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Duplicating " + statement->ToString());
935  auto* ga = GetPointer<gimple_assign>(statement);
936 
938  transformations[statement->index] = SIMD;
939 
941  const auto* sa = GetPointer<const ssa_name>(GET_NODE(ga->op0));
942  const auto ssa_tree_node =
943  tree_man->create_ssa_name(sa->var, sa->type, sa->min, sa->max, sa->volatile_flag, sa->virtual_flag);
944 
946  tree_node_dup tnd(remapping, AppM);
947  remapping[ga->op0->index] = GET_INDEX_CONST_NODE(ssa_tree_node);
948 
950  const auto new_gimple = tnd.create_tree_node(statement);
951 #ifndef NDEBUG
952  auto* new_ga = GetPointer<gimple_assign>(TM->get_tree_node_const(new_gimple));
953 #endif
954  const BBGraphRef bb_graph = function_behavior->GetBBGraph(FunctionBehavior::FBB);
955  LoopRef loop = function_behavior->GetLoops()->GetLoop(loop_id);
956  THROW_ASSERT(loop->IsReducible(), "Loop is not reducible");
958  for(const auto& phi : bb_graph->GetBBNodeInfo(loop->GetHeader())->block->CGetPhiList())
959  {
961  "---Replacing " + ga->op0->ToString() + " with " + GET_CONST_NODE(ssa_tree_node)->ToString() +
962  " in " + phi->ToString());
963  TM->ReplaceTreeNode(phi, ga->op0, ssa_tree_node);
964  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Result: " + phi->ToString());
965  }
966  THROW_ASSERT(loop->num_exits() == 1, "Loop with not a single exit");
967  const auto stmt_list = bb_graph->GetBBNodeInfo(*(loop->exit_block_iter_begin()))->block->CGetStmtList();
968  THROW_ASSERT(stmt_list.size(), "Empty loop exit");
969  THROW_ASSERT(stmt_list.size() and GetPointer<gimple_cond>(GET_NODE(stmt_list.back())),
970  "Loop exit is not a cond_expr: " + stmt_list.back()->ToString());
971  const auto gimple_cond_stmt = stmt_list.back();
972  auto* gc = GetPointer<gimple_cond>(GET_NODE(gimple_cond_stmt));
973  const auto condition_to_be_duplicated = gc->op0;
974  auto* cond_op = GetPointer<ssa_name>(GET_CONST_NODE(condition_to_be_duplicated));
975  THROW_ASSERT(cond_op, "Cond expression operand is " + STR(condition_to_be_duplicated));
976  THROW_ASSERT(cond_op->CGetDefStmts().size() == 1, "Cond argument is not defined in a single assignment");
977  auto def_statement = cond_op->CGetDefStmt();
978  const auto use_stmts = cond_op->CGetUseStmts();
979  if(use_stmts.size() > 1)
980  {
982  const auto dup_op_cond = tree_man->create_ssa_name(cond_op->var, cond_op->type, cond_op->min, cond_op->max,
983  cond_op->volatile_flag, cond_op->virtual_flag);
984  // cppcheck-suppress unreadVariable
985  remapping[cond_op->index] = GET_INDEX_CONST_NODE(dup_op_cond);
987  const auto new_cond_computation = tnd.create_tree_node(GET_NODE(def_statement));
988 
990  "---Created " + STR(TM->CGetTreeNode(new_cond_computation)));
991  const auto new_gc_cond = GetPointer<const gimple_assign>(TM->CGetTreeNode(new_cond_computation));
992  TM->ReplaceTreeNode(gimple_cond_stmt, condition_to_be_duplicated, new_gc_cond->op0);
993 
995  THROW_ASSERT(guards.find(loop_id) != guards.end(), "");
996  const auto header_guard_tn = guards.find(loop_id)->second;
997  if(GET_CONST_NODE(header_guard_tn)->get_kind() != integer_cst_K)
998  {
999  const auto header_guard_sn = GetPointer<const ssa_name>(GET_CONST_NODE(header_guard_tn));
1000  THROW_ASSERT(header_guard_sn, STR(header_guard_tn));
1001  const auto header_guard_stmt_tn = GET_CONST_NODE(header_guard_sn->CGetDefStmt());
1002  const auto header_guard_gp = GetPointer<const gimple_phi>(header_guard_stmt_tn);
1003  THROW_ASSERT(header_guard_gp, STR(header_guard_stmt_tn));
1004  const auto feedback_condition = [&]() -> tree_nodeRef {
1005  for(const auto& def_edge : header_guard_gp->CGetDefEdgesList())
1006  {
1007  if(def_edge.second == gc->bb_index)
1008  {
1009  return def_edge.first;
1010  }
1011  }
1012  THROW_UNREACHABLE("");
1013  return tree_nodeRef();
1014  }();
1015  const auto feedback_condition_sn = GetPointer<const ssa_name>(GET_CONST_NODE(feedback_condition));
1016  THROW_ASSERT(feedback_condition_sn, "");
1017  const auto feedback_condition_def_stmt = GET_CONST_NODE(feedback_condition_sn->CGetDefStmt());
1018 #if HAVE_ASSERTS
1019  const auto feedback_condition_def_ga = GetPointer<const gimple_assign>(feedback_condition_def_stmt);
1020  THROW_ASSERT(feedback_condition_def_ga, STR(feedback_condition_def_stmt));
1021  const auto feedback_condition_right_ta =
1022  GetPointer<const truth_and_expr>(GET_CONST_NODE(feedback_condition_def_ga->op1));
1023  THROW_ASSERT(feedback_condition_right_ta, GET_CONST_NODE(feedback_condition_def_ga->op1)->get_kind_text() +
1024  ": " + STR(feedback_condition_def_ga->op1));
1025  THROW_ASSERT(feedback_condition_right_ta->op0->index == condition_to_be_duplicated->index or
1026  feedback_condition_right_ta->op1->index == condition_to_be_duplicated->index,
1027  STR(feedback_condition_def_ga->op1));
1028 #endif
1029  TM->ReplaceTreeNode(feedback_condition_sn->CGetDefStmt(), condition_to_be_duplicated, new_gc_cond->op0);
1031  "---Replaced condition in feedback guard computation " + STR(feedback_condition_def_stmt));
1032  bb_graph->GetBBNodeInfo(*(loop->exit_block_iter_begin()))
1033  ->block->PushBefore(TM->GetTreeReindex(new_cond_computation), feedback_condition_sn->CGetDefStmt(), AppM);
1034  }
1035  else
1036  {
1037  bb_graph->GetBBNodeInfo(*(loop->exit_block_iter_begin()))
1038  ->block->PushBack(TM->GetTreeReindex(new_cond_computation), AppM);
1039  }
1040  ClassifyTreeNode(loop_id, TM->get_tree_node_const(new_cond_computation));
1041  }
1042  else
1043  {
1046  TM->ReplaceTreeNode(def_statement, ga->op0, ssa_tree_node);
1047  }
1048  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Created statement " + new_ga->ToString());
1049  return new_gimple;
1050 }
1051 
1053 {
1054  switch(tree_node->get_kind())
1055  {
1056  case target_mem_ref461_K:
1057  case ssa_name_K:
1058  case binfo_K:
1059  case block_K:
1060  case call_expr_K:
1061  case aggr_init_expr_K:
1062  case case_label_expr_K:
1063  case constructor_K:
1064  case identifier_node_K:
1065  case statement_list_K:
1066  case target_expr_K:
1067  case target_mem_ref_K:
1068  case tree_list_K:
1069  case tree_vec_K:
1070  case error_mark_K:
1071  case lut_expr_K:
1073  case CASE_CPP_NODES:
1074  case CASE_CST_NODES:
1075  case CASE_DECL_NODES:
1076  case CASE_FAKE_NODES:
1077  case CASE_GIMPLE_NODES:
1078  case CASE_PRAGMA_NODES:
1081  case CASE_TYPE_NODES:
1082  case CASE_UNARY_EXPRESSION:
1083  {
1084  THROW_UNREACHABLE("Not supported tree node " + tree_node->get_kind_text());
1085  break;
1086  }
1087  default:
1088  {
1089  THROW_UNREACHABLE("");
1090  }
1091  }
1092  return false;
1093 }
1094 #if HAVE_UNORDERED && NO_ABSEIL_HASH
1095 
1098 namespace std
1099 {
1100  template <>
1101  struct hash<std::tuple<unsigned int, vertex, unsigned int>>
1102  : public unary_function<std::tuple<unsigned int, vertex, unsigned int>, size_t>
1103  {
1104  size_t operator()(std::tuple<unsigned int, vertex, unsigned int> value) const
1105  {
1106  std::size_t ret = 0;
1107  hash<unsigned int> hasher;
1108  boost::hash_combine(ret, hasher(std::get<0>(value)));
1109  boost::hash_combine(ret, std::get<1>(value));
1110  boost::hash_combine(ret, hasher(std::get<2>(value)));
1111  return ret;
1112  }
1113  };
1114 } // namespace std
1115 #endif
1116 
1118 {
1119  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Computing guards");
1122  const auto boolean_type = tree_man->GetBooleanType();
1123  const auto true_value = TM->CreateUniqueIntegerCst(1, boolean_type);
1124  const auto cdg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::CDG_BB);
1125  const auto cfg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::BB);
1126  const auto fcfg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::FBB);
1127  std::list<vertex> basic_blocks;
1128  cfg_bb_graph->TopologicalSort(basic_blocks);
1129  for(const auto basic_block : basic_blocks)
1130  {
1131  const auto bb_node_info = cfg_bb_graph->CGetBBNodeInfo(basic_block);
1132  const auto basic_block_id = bb_node_info->block->number;
1133  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Analyzing BB" + STR(basic_block_id));
1134  const auto loop_id = bb_node_info->loop_id;
1135  if(simd_loop_type.find(loop_id)->second == SIMD_NONE)
1136  {
1137  guards[basic_block_id] = true_value;
1138  }
1139  else if(!basic_block_divergence.find(basic_block_id)->second)
1140  {
1141  guards[basic_block_id] = true_value;
1142  }
1144  else if(boost::in_degree(basic_block, *cfg_bb_graph) > 1 and
1145  boost::in_degree(basic_block, *cfg_bb_graph) == boost::in_degree(basic_block, *fcfg_bb_graph))
1146  {
1147  THROW_ASSERT(boost::in_degree(basic_block, *cdg_bb_graph) == 1, "");
1148  InEdgeIterator ie, ie_end;
1149  boost::tie(ie, ie_end) = boost::in_edges(basic_block, *cdg_bb_graph);
1150  auto edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
1151  auto source = boost::source(*ie, *cdg_bb_graph);
1152  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
1153  const auto controller = std::tuple<unsigned int, vertex, unsigned int>(
1154  bb_node_info->loop_id, source, edge_labels.size() ? *(edge_labels.begin()) : 0);
1155  THROW_ASSERT(condition_guards.find(controller) != condition_guards.end(), "");
1156  guards[basic_block_id] = condition_guards.find(controller)->second;
1157  }
1159  else if(boost::in_degree(basic_block, *fcfg_bb_graph) > 1)
1160  {
1161  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Adding phi in header BB" + STR(basic_block_id));
1163  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> ssa_schema;
1164  auto ssa_vers = TM->get_next_vers();
1165  auto ssa_node_nid = TM->new_tree_node_id();
1166  ssa_schema[TOK(TOK_TYPE)] = STR(boolean_type->index);
1167  ssa_schema[TOK(TOK_VERS)] = STR(ssa_vers);
1168  ssa_schema[TOK(TOK_VOLATILE)] = STR(false);
1169  ssa_schema[TOK(TOK_VIRTUAL)] = STR(false);
1170  TM->create_tree_node(ssa_node_nid, ssa_name_K, ssa_schema);
1171  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created " + STR(TM->CGetTreeNode(ssa_node_nid)));
1172 
1174  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_phi_schema;
1175  const auto gimple_phi_id = TM->new_tree_node_id();
1176  gimple_phi_schema[TOK(TOK_SRCP)] = BUILTIN_SRCP;
1177  gimple_phi_schema[TOK(TOK_SCPE)] = STR(function_id);
1178  gimple_phi_schema[TOK(TOK_TYPE)] = STR(boolean_type->index);
1179  gimple_phi_schema[TOK(TOK_RES)] = STR(ssa_node_nid);
1180  TM->create_tree_node(gimple_phi_id, gimple_phi_K, gimple_phi_schema);
1181  auto gp = GetPointer<gimple_phi>(TM->get_tree_node_const(gimple_phi_id));
1182  gp->SetSSAUsesComputed();
1183  THROW_ASSERT(gp, "");
1184  InEdgeIterator ie, ie_end;
1185  for(boost::tie(ie, ie_end) = boost::in_edges(basic_block, *cfg_bb_graph); ie != ie_end; ie++)
1186  {
1187  const auto source = boost::source(*ie, *cfg_bb_graph);
1188  THROW_ASSERT(cfg_bb_graph->CGetBBNodeInfo(source)->block, "");
1189  const auto source_id = source != cfg_bb_graph->CGetBBGraphInfo()->entry_vertex ?
1190  cfg_bb_graph->CGetBBNodeInfo(source)->block->number :
1191  BB_ENTRY;
1192  THROW_ASSERT(guards.find(source_id) != guards.end(), "");
1193  gp->AddDefEdge(TM, gimple_phi::DefEdge(guards.find(source_id)->second, source_id));
1194  }
1195  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created " + STR(TM->CGetTreeNode(gimple_phi_id)));
1196  bb_node_info->block->AddPhi(TM->GetTreeReindex(gimple_phi_id));
1197  boost::tie(ie, ie_end) = boost::in_edges(basic_block, *cdg_bb_graph);
1198  auto edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
1199  auto source = boost::source(*ie, *cdg_bb_graph);
1200  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == source, "");
1201  const auto controller = std::tuple<unsigned int, vertex, unsigned int>(
1202  bb_node_info->loop_id, source, edge_labels.size() ? *(edge_labels.begin()) : 0);
1203  condition_guards[controller] = gp->res;
1204  guards[basic_block_id] = gp->res;
1205  }
1206  else
1207  {
1208  InEdgeIterator ie, ie_end;
1209  boost::tie(ie, ie_end) = boost::in_edges(basic_block, *cfg_bb_graph);
1210  THROW_ASSERT(boost::in_degree(basic_block, *cdg_bb_graph) == 1, "");
1211  boost::tie(ie, ie_end) = boost::in_edges(basic_block, *cdg_bb_graph);
1212  const auto control = boost::source(*ie, *cdg_bb_graph);
1213  auto edge_labels = cdg_bb_graph->CGetBBEdgeInfo(*ie)->get_labels(CDG_SELECTOR);
1214  THROW_ASSERT(edge_labels.size() == 1 or cdg_bb_graph->CGetBBGraphInfo()->entry_vertex == control, "");
1215  const auto controller = std::tuple<unsigned int, vertex, unsigned int>(
1216  bb_node_info->loop_id, control, edge_labels.size() ? *(edge_labels.begin()) : 0);
1217  if(condition_guards.find(controller) != condition_guards.end())
1218  {
1219  const auto combined_condition = condition_guards.find(controller)->second;
1220  guards[basic_block_id] = combined_condition;
1221  }
1222  else
1223  {
1224  const auto control_bb_node_info = cfg_bb_graph->CGetBBNodeInfo(control)->block;
1225  const auto control_id = control_bb_node_info->number;
1226  const auto control_list_of_stmt = control_bb_node_info->CGetStmtList();
1227  THROW_ASSERT(control_list_of_stmt.size(), "");
1228  const auto gc = GetPointer<gimple_cond>(GET_NODE(control_list_of_stmt.back()));
1229  THROW_ASSERT(gc, "");
1230  const auto control_condition = guards.find(control_id)->second;
1231  const auto edge_condition = gc->op0;
1232  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Edge condition is " + STR(edge_condition));
1235  const auto combined_condition =
1236  control_condition->index != true_value->index ?
1237  tree_man->CreateAndExpr(control_condition, edge_condition, blocRef(), function_id) :
1238  edge_condition;
1239  if(control_condition->index != true_value->index)
1240  {
1241  bb_node_info->block->PushFront(GetPointer<const ssa_name>(GET_NODE(combined_condition))->CGetDefStmt(),
1242  AppM);
1243  }
1244  if(edge_condition != gc->op0)
1245  {
1246  bb_node_info->block->PushFront(GetPointer<const ssa_name>(GET_NODE(edge_condition))->CGetDefStmt(),
1247  AppM);
1248  }
1249  condition_guards[controller] = combined_condition;
1250  guards[basic_block_id] = combined_condition;
1251  }
1252  }
1254  if(simd_loop_type.find(loop_id)->second != SIMD_NONE)
1255  {
1256  if(boost::out_degree(basic_block, *cfg_bb_graph) != boost::out_degree(basic_block, *fcfg_bb_graph))
1257  {
1258  if(boost::out_degree(basic_block, *fcfg_bb_graph) == 1)
1259  {
1260  OutEdgeIterator oe, oe_end;
1261  boost::tie(oe, oe_end) = boost::out_edges(basic_block, *fcfg_bb_graph);
1262  const auto target = boost::target(*oe, *fcfg_bb_graph);
1263  const auto target_id = cfg_bb_graph->CGetBBNodeInfo(target)->block->number;
1264  if(basic_block_divergence.find(target_id)->second)
1265  {
1266  THROW_ASSERT(guards.find(target_id) != guards.end(), "");
1267  const auto guard = guards.find(target_id)->second;
1268  const auto sn = GetPointer<ssa_name>(GET_NODE(guard));
1269  THROW_ASSERT(sn, "");
1270  auto gp = GetPointer<gimple_phi>(GET_NODE(sn->CGetDefStmt()));
1271  THROW_ASSERT(gp, "");
1272  gp->AddDefEdge(TM, gimple_phi::DefEdge(guards.find(basic_block_id)->second, basic_block_id));
1273  }
1274  }
1275  else if(boost::out_degree(basic_block, *fcfg_bb_graph) == 2)
1276  {
1277  OutEdgeIterator oe, oe_end;
1278  for(boost::tie(oe, oe_end) = boost::out_edges(basic_block, *fcfg_bb_graph); oe != oe_end; oe++)
1279  {
1280  if(fcfg_bb_graph->GetSelector(*oe) & FB_CFG_SELECTOR)
1281  {
1282  const auto target = boost::target(*oe, *fcfg_bb_graph);
1283  const auto target_id = cfg_bb_graph->CGetBBNodeInfo(target)->block->number;
1285  "---Considering feedback edge BB" + STR(basic_block_id) + "-->" + STR(target_id));
1286  THROW_ASSERT(target_id == bb_node_info->block->true_edge, "");
1287  if(basic_block_divergence.find(target_id)->second)
1288  {
1289  THROW_ASSERT(guards.find(target_id) != guards.end(), "");
1290  const auto guard = guards.find(target_id)->second;
1291  const auto sn = GetPointer<ssa_name>(GET_NODE(guard));
1292  THROW_ASSERT(sn, "");
1293  auto gp = GetPointer<gimple_phi>(GET_NODE(sn->CGetDefStmt()));
1294  THROW_ASSERT(gp, "");
1295  const auto list_of_stmt = bb_node_info->block->CGetStmtList();
1296  THROW_ASSERT(list_of_stmt.size(), "");
1297  const auto gc = GetPointer<gimple_cond>(GET_NODE(list_of_stmt.back()));
1298  THROW_ASSERT(gc, "");
1299  const auto current_condition = guards.find(basic_block_id)->second;
1300  const auto feedback_condition = gc->op0;
1301  const auto combined_condition =
1302  current_condition->index != true_value->index ?
1303  tree_man->CreateAndExpr(current_condition, feedback_condition, bb_node_info->block,
1304  function_id) :
1305  gc->op0;
1306  gp->AddDefEdge(TM, gimple_phi::DefEdge(combined_condition, basic_block_id));
1307  }
1308  }
1309  }
1310  }
1311  else
1312  {
1313  THROW_UNREACHABLE("");
1314  }
1315  }
1316  }
1317  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Analyzed BB" + STR(basic_block_id));
1318  }
1319 #ifndef NDEBUG
1321  {
1322  for(const auto& guard : guards)
1323  {
1325  "---Guard of BB" + STR(guard.first) + " is " + STR(guard.second));
1326  }
1327  }
1328 #endif
1329  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Computed guards");
1330 }
1331 
1333 {
1335  const auto dom_graph = function_behavior->CGetBBGraph(FunctionBehavior::DOM_TREE);
1336  const auto fcfg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::FBB);
1337  const auto cdg_bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::CDG_BB);
1338  VertexIterator basic_block, basic_block_end;
1339  for(boost::tie(basic_block, basic_block_end) = boost::vertices(*fcfg_bb_graph); basic_block != basic_block_end;
1340  basic_block++)
1341  {
1342 #ifndef NDEBUG
1343  const auto basic_block_id = fcfg_bb_graph->CGetBBNodeInfo(*basic_block)->block->number;
1344 #endif
1345  if(boost::in_degree(*basic_block, *fcfg_bb_graph) <= 1)
1346  {
1348  "---Skipped BB" + STR(basic_block_id) + " because has not multiple incoming edges");
1349  continue;
1350  }
1351  const auto bb_node_info = fcfg_bb_graph->CGetBBNodeInfo(*basic_block);
1352  if(simd_loop_type.find(bb_node_info->loop_id)->second == SIMD_NONE)
1353  {
1355  "---Skipped BB" + STR(basic_block_id) + " because is outside parallelized loops");
1356  continue;
1357  }
1358  if(bb_node_info->loop_id == bb_node_info->block->number)
1359  {
1361  "---Skipped BB" + STR(basic_block_id) + " because is an header");
1362  continue;
1363  }
1365  bool diverge = false;
1366  InEdgeIterator ie, ie_end;
1367  for(boost::tie(ie, ie_end) = boost::in_edges(*basic_block, *fcfg_bb_graph); ie != ie_end; ie++)
1368  {
1369  const auto source = boost::source(*ie, *fcfg_bb_graph);
1370  const auto source_id = fcfg_bb_graph->CGetBBNodeInfo(source)->block->number;
1371  if(basic_block_divergence.find(source_id)->second)
1372  {
1373  diverge = true;
1374  break;
1375  }
1376  }
1377  if(!diverge)
1378  {
1380  "---Skipped BB" + STR(basic_block_id) + " because is not a convergence point");
1381  continue;
1382  }
1383  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Fixing phis in BB" + STR(basic_block_id));
1384  THROW_ASSERT(boost::in_degree(*basic_block, *dom_graph) == 1, "");
1385  boost::tie(ie, ie_end) = boost::in_edges(*basic_block, *dom_graph);
1386  vertex whole_dominator = boost::source(*ie, *dom_graph);
1387  THROW_ASSERT(fcfg_bb_graph->ExistsEdge(whole_dominator, *basic_block), "");
1388  const std::map<vertex, unsigned int>& bb_map_levels = function_behavior->get_bb_map_levels();
1389  const bb_vertex_order_by_map comp_i(bb_map_levels);
1390  std::set<vertex, bb_vertex_order_by_map> phi_inputs(comp_i);
1391  for(boost::tie(ie, ie_end) = boost::in_edges(*basic_block, *fcfg_bb_graph); ie != ie_end; ie++)
1392  {
1393  const auto source = boost::source(*ie, *fcfg_bb_graph);
1394  if(source != whole_dominator)
1395  {
1396  phi_inputs.insert(source);
1397  }
1398  }
1399  for(const auto& phi : bb_node_info->block->CGetPhiList())
1400  {
1403  auto gp = GetPointer<gimple_phi>(GET_NODE(phi));
1404  const auto type = tree_helper::CGetType(gp->res);
1405  THROW_ASSERT(type, "");
1406  for(const auto source : phi_inputs)
1407  {
1408  const auto source_id = fcfg_bb_graph->CGetBBNodeInfo(source)->block->number;
1409  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Fixing value coming from BB" + STR(source_id));
1410  InEdgeIterator ie_local, ie_end_local;
1411  THROW_ASSERT(boost::in_degree(source, *cdg_bb_graph) == 1, "");
1412  boost::tie(ie_local, ie_end_local) = boost::in_edges(source, *cdg_bb_graph);
1413  vertex local_dominator = boost::source(*ie_local, *cdg_bb_graph);
1414  const auto local_dominator_index = dom_graph->CGetBBNodeInfo(local_dominator)->block->number;
1415  const auto from_dominator = [&]() -> tree_nodeRef {
1416  if(local_dominator == whole_dominator)
1417  {
1418  for(const auto& def_edge : gp->CGetDefEdgesList())
1419  {
1420  if(def_edge.second == local_dominator_index)
1421  {
1422  return def_edge.first;
1423  }
1424  }
1425  THROW_UNREACHABLE("");
1426  return tree_nodeRef();
1427  }
1428  else
1429  {
1430  THROW_ASSERT(new_defs.find(local_dominator_index) != new_defs.end(), "");
1431  return new_defs.find(local_dominator_index)->second;
1432  }
1433  }();
1434  const auto from_source = [&]() -> gimple_phi::DefEdge {
1435  for(const auto& def_edge : gp->CGetDefEdgesList())
1436  {
1437  if(def_edge.second == source_id)
1438  {
1439  return def_edge;
1440  }
1441  }
1442  THROW_UNREACHABLE("");
1443  return gimple_phi::DefEdge();
1444  }();
1445  THROW_ASSERT(guards.count(source_id), "");
1446  const auto cond_expr_node = tree_man->create_ternary_operation(
1447  type, guards.at(source_id), from_source.first, from_dominator, BUILTIN_SRCP, cond_expr_K);
1449  "---Created cond_expr " + GET_CONST_NODE(cond_expr_node)->ToString());
1450 
1452  tree_nodeRef var;
1453  if(GET_NODE(from_source.first)->get_kind() == ssa_name_K and
1454  GET_NODE(from_dominator)->get_kind() == ssa_name_K)
1455  {
1456  const auto sn1 = GetPointer<const ssa_name>(GET_NODE(from_source.first));
1457  const auto sn2 = GetPointer<const ssa_name>(GET_NODE(from_dominator));
1458  if(sn1->var and sn2->var and sn1->var->index == sn2->var->index)
1459  {
1460  var = sn1->var;
1461  }
1462  }
1463  const auto ssa_node = tree_man->create_ssa_name(var, type, nullptr, nullptr, false, gp->virtual_flag);
1465  "---Created ssa_name " + GET_CONST_NODE(ssa_node)->ToString());
1466 
1468  const auto gimple_assign_node =
1469  tree_man->create_gimple_modify_stmt(ssa_node, cond_expr_node, function_id, BUILTIN_SRCP);
1470  fcfg_bb_graph->CGetBBNodeInfo(source)->block->PushBack(gimple_assign_node, AppM);
1472  "---Created gimple_assign " + GET_CONST_NODE(gimple_assign_node)->ToString());
1473  new_defs[source_id] = ssa_node;
1474  gp->ReplaceDefEdge(TM, from_source, gimple_phi::DefEdge(ssa_node, from_source.second));
1475  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Fixed value coming from BB" + STR(source_id));
1476  }
1478  }
1479  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Fixed phis in BB" + STR(basic_block_id));
1480  }
1482 }
1483 
1485 {
1486  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Creating predicated statements");
1487  const auto bb_graph = function_behavior->CGetBBGraph(FunctionBehavior::BB);
1488  const auto behavioral_helper = function_behavior->CGetBehavioralHelper();
1489  VertexIterator bb, bb_end;
1490  for(boost::tie(bb, bb_end) = boost::vertices(*bb_graph); bb != bb_end; bb++)
1491  {
1492  const BBNodeInfoConstRef bb_node_info = bb_graph->CGetBBNodeInfo(*bb);
1493  const auto basic_block_index = bb_node_info->block->number;
1494  if(basic_block_divergence.find(basic_block_index) != basic_block_divergence.end() and
1495  basic_block_divergence.find(basic_block_index)->second)
1496  {
1498  "-->Considering statements of BB" + STR(basic_block_index));
1499  for(const auto& stmt : bb_node_info->block->CGetStmtList())
1500  {
1501  auto ga = GetPointer<gimple_assign>(GET_NODE(stmt));
1502  if(ga && ga->predicate)
1503  {
1504  ga->predicate = guards.at(basic_block_index);
1505  const auto sn = GetPointer<ssa_name>(GET_NODE(ga->predicate));
1506  if(sn)
1507  {
1508  sn->AddUseStmt(stmt);
1509  }
1510  }
1511  }
1513  "<--Considered statements of BB" + STR(basic_block_index));
1514  }
1515  }
1516  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Created predicated statements");
1517 }
1518 
1519 unsigned int Vectorize::Transform(const unsigned int tree_node_index, const size_t parallel_degree,
1520  const size_t scalar_index, std::list<tree_nodeRef>& new_stmt_list,
1521  std::vector<tree_nodeRef>& new_phi_list)
1522 {
1524  "-->Transforming " + TM->get_tree_node_const(tree_node_index)->get_kind_text() + " " +
1525  STR(tree_node_index) +
1526  ((TM->get_tree_node_const(tree_node_index)->get_kind() != function_decl_K) ?
1527  ": " + TM->get_tree_node_const(tree_node_index)->ToString() :
1528  ""));
1529  const tree_nodeConstRef tn = TM->get_tree_node_const(tree_node_index);
1530  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> tree_node_schema;
1531  unsigned int return_value = 0;
1532  const auto transformation = [&]() -> Transformation {
1533  if(transformations.find(tree_node_index) != transformations.end() and
1534  transformations.find(tree_node_index)->second == NONE)
1535  {
1536  return NONE;
1537  }
1538  if(scalar_index != 0)
1539  {
1540  return SCALAR;
1541  }
1542  if(transformations.find(tree_node_index) != transformations.end())
1543  {
1544  return transformations.find(tree_node_index)->second;
1545  }
1546  return SIMD;
1547  }();
1548  switch(transformation)
1549  {
1550  case(NONE):
1551  {
1552  return_value = tree_node_index;
1553  break;
1554  }
1555  case(COND_CON):
1556  {
1557  THROW_ASSERT(tn->get_kind() == gimple_cond_K, "Condition is " + tn->get_kind_text());
1558  const auto* gc = GetPointer<const gimple_cond>(tn);
1559  std::string include_name = GetPointer<const srcp>(tn)->include_name;
1560  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
1561  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
1562  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
1563  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1564  tree_node_schema[TOK(TOK_OP0)] =
1565  STR(Transform(gc->op0->index, parallel_degree, 1, new_stmt_list, new_phi_list));
1566  unsigned int new_tree_node_index = TM->new_tree_node_id();
1567  TM->create_tree_node(new_tree_node_index, gimple_cond_K, tree_node_schema);
1568  auto* new_gc = GetPointer<gimple_cond>(TM->get_tree_node_const(new_tree_node_index));
1569  new_gc->memuse = gc->memuse;
1570  new_gc->memdef = gc->memdef;
1571  for(const auto& vuse : gc->vuses)
1572  {
1573  new_gc->AddVuse(
1574  TM->GetTreeReindex(Transform(vuse->index, parallel_degree, 1, new_stmt_list, new_phi_list)));
1575  }
1576  if(gc->vdef)
1577  {
1578  new_gc->vdef =
1579  TM->GetTreeReindex(Transform(gc->vdef->index, parallel_degree, 1, new_stmt_list, new_phi_list));
1580  }
1581  new_gc->vovers = gc->vovers;
1582  new_gc->pragmas = gc->pragmas;
1583  new_gc->use_set = gc->use_set;
1584  new_gc->clobbered_set = gc->clobbered_set;
1585  return_value = new_tree_node_index;
1586  new_stmt_list.push_back(TM->GetTreeReindex(new_tree_node_index));
1587  break;
1588  }
1589  case(COND_DIV):
1590  {
1591  std::list<tree_nodeRef> conditions;
1592  const auto* gc = GetPointer<const gimple_cond>(tn);
1593  for(size_t parallel_index = 1; parallel_index <= parallel_degree; parallel_index++)
1594  {
1595  conditions.push_back(TM->GetTreeReindex(
1596  Transform(gc->op0->index, parallel_degree, parallel_index, new_stmt_list, new_phi_list)));
1597  }
1598  while(conditions.size() > 1)
1599  {
1600  const auto first_condition = conditions.front();
1601  conditions.pop_front();
1602  const auto second_condition = conditions.front();
1603  conditions.pop_front();
1604  const auto new_cond = tree_man->CreateOrExpr(first_condition, second_condition, blocRef(), function_id);
1605  new_stmt_list.push_back(GetPointer<const ssa_name>(GET_NODE(new_cond))->CGetDefStmt());
1606  conditions.push_back(new_cond);
1607  }
1608  std::string include_name = GetPointer<const srcp>(tn)->include_name;
1609  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
1610  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
1611  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
1612  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1613  tree_node_schema[TOK(TOK_OP0)] = STR(conditions.front()->index);
1614  unsigned int new_tree_node_index = TM->new_tree_node_id();
1615  TM->create_tree_node(new_tree_node_index, gimple_cond_K, tree_node_schema);
1616  return_value = new_tree_node_index;
1617  new_stmt_list.push_back(TM->GetTreeReindex(new_tree_node_index));
1618  break;
1619  }
1620  case(INIT):
1621  {
1622  THROW_ASSERT(tn->get_kind() == gimple_phi_K, "Init is " + tn->get_kind_text());
1623  const auto* gp = GetPointer<const gimple_phi>(tn);
1624  tree_node_schema[TOK(TOK_SCPE)] =
1625  STR(Transform(gp->scpe->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1626  tree_node_schema[TOK(TOK_RES)] =
1627  STR(Transform(gp->res->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1628  tree_node_schema[TOK(TOK_VIRTUAL)] = STR(gp->virtual_flag);
1629  std::string include_name = gp->include_name;
1630  unsigned int line_number = gp->line_number;
1631  unsigned int column_number = gp->column_number;
1632  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
1633  unsigned int new_tree_node_id = TM->new_tree_node_id();
1634  TM->create_tree_node(new_tree_node_id, gimple_phi_K, tree_node_schema);
1635  auto* new_gp = GetPointer<gimple_phi>(TM->get_tree_node_const(new_tree_node_id));
1636  InEdgeIterator ie, ie_end;
1637  const BBGraphRef bb_graph = function_behavior->GetBBGraph(FunctionBehavior::BB);
1638  const vertex header = bb_graph->CGetBBGraphInfo()->bb_index_map.find(gp->bb_index)->second;
1639  boost::tie(ie, ie_end) = boost::in_edges(header, *bb_graph);
1640  const vertex previous = boost::source(*ie, *bb_graph);
1641  const unsigned int previous_id = bb_graph->CGetBBNodeInfo(previous)->block->number;
1642  const auto previous_block = bb_graph->GetBBNodeInfo(previous)->block;
1643  const auto previous_list_of_stmt = previous_block->CGetStmtList();
1644  for(const auto& def_edge : gp->CGetDefEdgesList())
1645  {
1646  if(def_edge.second == previous_id)
1647  {
1648  if(GET_NODE(def_edge.first)->get_kind() == integer_cst_K)
1649  {
1650  const auto* ic = GetPointer<const integer_cst>(GET_NODE(def_edge.first));
1651  tree_node_schema[TOK(TOK_TYPE)] =
1652  STR(Transform(ic->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1654  const auto original_init = tree_helper::GetConstValue(def_edge.first);
1655  unsigned int new_init_tree_node_id = TM->new_tree_node_id();
1656  TM->create_tree_node(new_init_tree_node_id, vector_cst_K, tree_node_schema);
1657  auto* new_tn = GetPointer<vector_cst>(TM->GetTreeNode(new_init_tree_node_id));
1658  THROW_ASSERT(iv_increment.count(gp->res->index),
1659  "Increment variable of " + gp->res->ToString() + " is unknown");
1660  const auto increment = iv_increment.at(gp->res->index);
1661  for(size_t i = 0; i < parallel_degree; i++)
1662  {
1663  const auto local_init = original_init + increment * static_cast<long long>(i);
1664  const auto new_ic = TM->CreateUniqueIntegerCst(local_init, ic->type);
1665  new_tn->list_of_valu.push_back(TM->GetTreeReindex(new_ic->index));
1666  }
1667  new_gp->AddDefEdge(TM, gimple_phi::DefEdge(TM->GetTreeReindex(new_tn->index), def_edge.second));
1668  }
1669  else if(GET_NODE(def_edge.first)->get_kind() == ssa_name_K)
1670  {
1671  CustomMap<size_t, unsigned int> version_to_ssa;
1672  for(size_t i = 1; i <= parallel_degree; i++)
1673  {
1674  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> gimple_tree_node_schema,
1675  plus_tree_node_schema, ssa_tree_node_schema;
1676 
1677  plus_tree_node_schema[TOK(TOK_SRCP)] =
1678  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1679  plus_tree_node_schema[TOK(TOK_OP0)] = STR(def_edge.first->index);
1680  plus_tree_node_schema[TOK(TOK_TYPE)] = STR(tree_helper::CGetType(def_edge.first)->index);
1681  THROW_ASSERT(iv_increment.count(gp->res->index),
1682  "Increment variable of " + gp->res->ToString() + " is unknown");
1683  const auto increment = iv_increment.at(gp->res->index) * static_cast<integer_cst_t>(i - 1);
1684  const auto new_ic = TM->CreateUniqueIntegerCst(increment, tree_man->GetUnsignedIntegerType());
1685  plus_tree_node_schema[TOK(TOK_OP1)] = STR(new_ic->index);
1686  unsigned int plus_tree_node_index = TM->new_tree_node_id();
1687  TM->create_tree_node(plus_tree_node_index, plus_expr_K, plus_tree_node_schema);
1688 
1689  THROW_ASSERT(GET_NODE(def_edge.first)->get_kind() == ssa_name_K, "");
1690  const auto* sa = GetPointer<const ssa_name>(GET_NODE(def_edge.first));
1691  if(sa->type)
1692  {
1693  ssa_tree_node_schema[TOK(TOK_TYPE)] = STR(sa->type->index);
1694  }
1695  if(sa->var)
1696  {
1697  ssa_tree_node_schema[TOK(TOK_VAR)] = STR(sa->var->index);
1698  }
1699  ssa_tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
1700  ssa_tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
1701  if(sa->volatile_flag)
1702  {
1703  ssa_tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
1704  }
1705  if(sa->virtual_flag)
1706  {
1707  ssa_tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
1708  }
1709  if(sa->max)
1710  {
1711  ssa_tree_node_schema[TOK(TOK_MAX)] = STR(sa->max->index);
1712  }
1713  if(sa->min)
1714  {
1715  ssa_tree_node_schema[TOK(TOK_MIN)] = STR(sa->min->index);
1716  }
1717  unsigned int ssa_tree_node_index = TM->new_tree_node_id();
1718  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, ssa_tree_node_schema);
1719  version_to_ssa[i] = ssa_tree_node_index;
1720 
1721  gimple_tree_node_schema[TOK(TOK_SRCP)] =
1722  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1723  gimple_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1724  gimple_tree_node_schema[TOK(TOK_OP1)] = STR(plus_tree_node_index);
1725  gimple_tree_node_schema[TOK(TOK_OP0)] = STR(ssa_tree_node_index);
1726  unsigned int gimple_tree_node_index = TM->new_tree_node_id();
1727  TM->create_tree_node(gimple_tree_node_index, gimple_assign_K, gimple_tree_node_schema);
1728 
1729  THROW_ASSERT(previous_list_of_stmt.empty() or
1730  GET_NODE((*(previous_list_of_stmt.begin())))->get_kind() != gimple_cond_K,
1731  "");
1732  previous_block->PushBack(TM->GetTreeReindex(gimple_tree_node_index), AppM);
1733  }
1734  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> constructor_tree_node_schema,
1735  gimple_tree_node_schema, ssa_tree_node_schema;
1736  constructor_tree_node_schema[TOK(TOK_TYPE)] = STR(Transform(
1737  tree_helper::CGetType(gp->res)->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1738  unsigned int constructor_index = TM->new_tree_node_id();
1739  TM->create_tree_node(constructor_index, constructor_K, constructor_tree_node_schema);
1740  auto* constr = GetPointer<constructor>(TM->get_tree_node_const(constructor_index));
1741  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
1742  {
1743  const auto new_ic = TM->CreateUniqueIntegerCst(static_cast<long long int>(scalar - 1),
1745  constr->add_idx_valu(new_ic, TM->GetTreeReindex(version_to_ssa[scalar]));
1746  }
1747 
1748  const auto* sa = GetPointer<const ssa_name>(GET_NODE(def_edge.first));
1749  if(sa->type)
1750  {
1751  ssa_tree_node_schema[TOK(TOK_TYPE)] =
1752  STR(Transform(sa->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1753  }
1754  if(sa->var)
1755  {
1756  ssa_tree_node_schema[TOK(TOK_VAR)] =
1757  STR(Transform(sa->var->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1758  }
1759  ssa_tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
1760  if(sa->volatile_flag)
1761  {
1762  ssa_tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
1763  }
1764  if(sa->virtual_flag)
1765  {
1766  ssa_tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
1767  }
1768  if(sa->max)
1769  {
1770  ssa_tree_node_schema[TOK(TOK_MAX)] =
1771  STR(Transform(sa->max->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1772  }
1773  if(sa->min)
1774  {
1775  ssa_tree_node_schema[TOK(TOK_MIN)] =
1776  STR(Transform(sa->min->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1777  }
1778  unsigned int ssa_tree_node_index = TM->new_tree_node_id();
1779  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, ssa_tree_node_schema);
1780 
1781  gimple_tree_node_schema[TOK(TOK_SRCP)] =
1782  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1783  gimple_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1784  gimple_tree_node_schema[TOK(TOK_OP1)] = STR(constructor_index);
1785  gimple_tree_node_schema[TOK(TOK_OP0)] = STR(ssa_tree_node_index);
1786  unsigned int gimple_tree_node_index = TM->new_tree_node_id();
1787  TM->create_tree_node(gimple_tree_node_index, gimple_assign_K, gimple_tree_node_schema);
1788  previous_block->PushBack(TM->GetTreeReindex(gimple_tree_node_index), AppM);
1789  new_gp->AddDefEdge(TM, gimple_phi::DefEdge(TM->GetTreeReindex(ssa_tree_node_index), def_edge.second));
1790  }
1791  else
1792  {
1793  THROW_UNREACHABLE(def_edge.first->ToString());
1794  }
1795  }
1796  else
1797  {
1798  THROW_ASSERT(transformations.find(def_edge.first->index) == transformations.end() or
1799  transformations.find(def_edge.first->index)->second == SIMD,
1800  "");
1801  new_gp->AddDefEdge(
1802  TM, gimple_phi::DefEdge(TM->GetTreeReindex(Transform(def_edge.first->index, parallel_degree, 0,
1803  new_stmt_list, new_phi_list)),
1804  def_edge.second));
1805  }
1806  }
1807  return_value = new_tree_node_id;
1808  new_phi_list.push_back(TM->GetTreeReindex(return_value));
1810  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
1811  {
1813  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> bit_field_ref_tree_node_schema,
1814  ssa_tree_node_schema, gimple_assign_tree_node_schema;
1815  unsigned int bit_field_ref_index = TM->new_tree_node_id();
1816  const auto element_type = tree_helper::CGetType(gp->res);
1818  const auto bit_size =
1819  GET_CONST_NODE(element_type)->get_kind() != boolean_type_K ? tree_helper::Size(element_type) : 32;
1820  const auto offset = TM->CreateUniqueIntegerCst(static_cast<long long int>((scalar - 1) * bit_size),
1822  const auto size =
1823  TM->CreateUniqueIntegerCst(static_cast<long long int>(bit_size), tree_man->GetUnsignedIntegerType());
1824  bit_field_ref_tree_node_schema[TOK(TOK_SRCP)] =
1825  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1826  bit_field_ref_tree_node_schema[TOK(TOK_TYPE)] = STR(tree_helper::CGetType(gp->res)->index);
1827  bit_field_ref_tree_node_schema[TOK(TOK_OP0)] =
1828  STR(Transform(gp->res->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1829  bit_field_ref_tree_node_schema[TOK(TOK_OP1)] = STR(size->index);
1830  bit_field_ref_tree_node_schema[TOK(TOK_OP2)] = STR(offset->index);
1831  TM->create_tree_node(bit_field_ref_index, bit_field_ref_K, bit_field_ref_tree_node_schema);
1832 
1833  const auto* sa = GetPointer<const ssa_name>(GET_NODE(gp->res));
1834  if(sa->type)
1835  {
1836  ssa_tree_node_schema[TOK(TOK_TYPE)] = STR(sa->type->index);
1837  }
1838  if(sa->var)
1839  {
1840  ssa_tree_node_schema[TOK(TOK_VAR)] = STR(sa->var->index);
1841  }
1842  ssa_tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
1843  ssa_tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
1844  if(sa->volatile_flag)
1845  {
1846  ssa_tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
1847  }
1848  if(sa->virtual_flag)
1849  {
1850  ssa_tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
1851  }
1852  if(sa->max)
1853  {
1854  ssa_tree_node_schema[TOK(TOK_MAX)] = STR(sa->max->index);
1855  }
1856  if(sa->min)
1857  {
1858  ssa_tree_node_schema[TOK(TOK_MIN)] = STR(sa->min->index);
1859  }
1860 
1861  unsigned int ssa_tree_node_index = TM->new_tree_node_id();
1862  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, ssa_tree_node_schema);
1863 
1864  gimple_assign_tree_node_schema[TOK(TOK_SRCP)] =
1865  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1866  gimple_assign_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1867  gimple_assign_tree_node_schema[TOK(TOK_OP1)] = STR(bit_field_ref_index);
1868  gimple_assign_tree_node_schema[TOK(TOK_OP0)] =
1869  STR(Transform(gp->res->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
1870  unsigned int gimple_new_tree_node_index = TM->new_tree_node_id();
1871  TM->create_tree_node(gimple_new_tree_node_index, gimple_assign_K, gimple_assign_tree_node_schema);
1873  new_stmt_list.push_front(TM->GetTreeReindex(gimple_new_tree_node_index));
1874  }
1875  break;
1876  }
1877  case(INC):
1878  {
1880  THROW_ASSERT(tn->get_kind() == gimple_assign_K, "Increment is " + tn->get_kind_text());
1881  const auto* ga = GetPointer<const gimple_assign>(tn);
1882  const auto increment = tree_helper::GetConstValue(GetPointer<binary_expr>(GET_NODE(ga->op1))->op1);
1883  std::string include_name = GetPointer<const srcp>(tn)->include_name;
1884  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
1885  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
1886  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
1887  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1888  tree_node_schema[TOK(TOK_CLOBBER)] = STR(ga->clobber);
1889  tree_node_schema[TOK(TOK_INIT)] = STR(ga->init_assignment);
1890  tree_node_schema[TOK(TOK_OP0)] =
1891  STR(Transform(ga->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1892  tree_node_schema[TOK(TOK_OP1)] =
1893  STR(Transform(ga->op1->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1894  unsigned int new_tree_node_index = TM->new_tree_node_id();
1895  TM->create_tree_node(new_tree_node_index, gimple_assign_K, tree_node_schema);
1896  auto* new_ga = GetPointer<gimple_assign>(TM->get_tree_node_const(new_tree_node_index));
1897  THROW_ASSERT(GET_NODE(new_ga->op1)->get_kind() == plus_expr_K or
1898  GET_NODE(new_ga->op1)->get_kind() == minus_expr_K,
1899  "Loop increment operation is not a plus expression nor a minus expression");
1900  auto* be = GetPointer<binary_expr>(GET_NODE(new_ga->op1));
1901  THROW_ASSERT(GET_NODE(be->op1)->get_kind() == vector_cst_K, "Increment is not constant");
1902  const auto type = GetPointer<const vector_type>(GET_CONST_NODE(tree_helper::CGetType(be->op1)))->elts;
1903  const auto new_increment = increment * static_cast<integer_cst_t>(parallel_degree);
1904  const auto new_ic = TM->CreateUniqueIntegerCst(new_increment, type);
1905  be->op1 = TM->GetTreeReindex(Transform(new_ic->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1906  new_ga->memuse = ga->memuse;
1907  new_ga->memdef = ga->memdef;
1908  for(const auto& vuse : ga->vuses)
1909  {
1910  new_ga->AddVuse(
1911  TM->GetTreeReindex(Transform(vuse->index, parallel_degree, 0, new_stmt_list, new_phi_list)));
1912  }
1913  if(ga->vdef)
1914  {
1915  new_ga->vdef =
1916  TM->GetTreeReindex(Transform(ga->vdef->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1917  }
1918  new_ga->vovers = ga->vovers;
1919  new_ga->pragmas = ga->pragmas;
1920  new_ga->use_set = ga->use_set;
1921  new_ga->clobbered_set = ga->clobbered_set;
1922  return_value = new_tree_node_index;
1923  new_stmt_list.push_back(TM->GetTreeReindex(new_tree_node_index));
1924 
1926 
1927  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
1928  {
1930  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> bit_field_ref_tree_node_schema,
1931  ssa_tree_node_schema, gimple_assign_tree_node_schema;
1932  unsigned int bit_field_ref_index = TM->new_tree_node_id();
1933  const auto element_type = tree_helper::CGetType(ga->op0);
1935  const auto bit_size =
1936  GET_CONST_NODE(element_type)->get_kind() != boolean_type_K ? tree_helper::Size(element_type) : 32;
1937  const auto offset = TM->CreateUniqueIntegerCst(static_cast<long long int>((scalar - 1) * bit_size),
1939  const auto size =
1940  TM->CreateUniqueIntegerCst(static_cast<long long int>(bit_size), tree_man->GetUnsignedIntegerType());
1941  bit_field_ref_tree_node_schema[TOK(TOK_SRCP)] =
1942  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1943  bit_field_ref_tree_node_schema[TOK(TOK_TYPE)] = STR(tree_helper::CGetType(tn)->index);
1944  bit_field_ref_tree_node_schema[TOK(TOK_OP0)] =
1945  STR(Transform(ga->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
1946  bit_field_ref_tree_node_schema[TOK(TOK_OP1)] = STR(size->index);
1947  bit_field_ref_tree_node_schema[TOK(TOK_OP2)] = STR(offset->index);
1948  TM->create_tree_node(bit_field_ref_index, bit_field_ref_K, bit_field_ref_tree_node_schema);
1949 
1950  const auto* sa = GetPointer<const ssa_name>(GET_NODE(ga->op0));
1951  if(sa->type)
1952  {
1953  ssa_tree_node_schema[TOK(TOK_TYPE)] = STR(sa->type->index);
1954  }
1955  if(sa->var)
1956  {
1957  ssa_tree_node_schema[TOK(TOK_VAR)] = STR(sa->var->index);
1958  }
1959  ssa_tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
1960  ssa_tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
1961  if(sa->volatile_flag)
1962  {
1963  ssa_tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
1964  }
1965  if(sa->virtual_flag)
1966  {
1967  ssa_tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
1968  }
1969  if(sa->max)
1970  {
1971  ssa_tree_node_schema[TOK(TOK_MAX)] = STR(sa->max->index);
1972  }
1973  if(sa->min)
1974  {
1975  ssa_tree_node_schema[TOK(TOK_MIN)] = STR(sa->min->index);
1976  }
1977 
1978  unsigned int ssa_tree_node_index = TM->new_tree_node_id();
1979  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, ssa_tree_node_schema);
1980 
1981  gimple_assign_tree_node_schema[TOK(TOK_SRCP)] =
1982  include_name + ":" + STR(line_number) + ":" + STR(column_number);
1983  gimple_assign_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
1984  gimple_assign_tree_node_schema[TOK(TOK_OP1)] = STR(bit_field_ref_index);
1985  gimple_assign_tree_node_schema[TOK(TOK_OP0)] =
1986  STR(Transform(ga->op0->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
1987  unsigned int gimple_new_tree_node_index = TM->new_tree_node_id();
1988  TM->create_tree_node(gimple_new_tree_node_index, gimple_assign_K, gimple_assign_tree_node_schema);
1989  new_stmt_list.push_back(TM->GetTreeReindex(gimple_new_tree_node_index));
1990  scalar_to_scalar[tree_node_index][scalar] = ssa_tree_node_index;
1991  }
1992  break;
1993  }
1994  case(SCALAR):
1995  {
1996  if(scalar_index != 0 and scalar_to_scalar.find(tn->index) != scalar_to_scalar.end() and
1997  scalar_to_scalar.find(tn->index)->second.find(scalar_index) !=
1998  scalar_to_scalar.find(tn->index)->second.end())
1999  {
2001  "<--Already transformed " + STR(tree_node_index) +
2002  ((TM->get_tree_node_const(tree_node_index)->get_kind() != function_decl_K) ?
2003  ": " + TM->get_tree_node_const(
2004  scalar_to_scalar.find(tn->index)->second.find(scalar_index)->second)
2005  ->ToString() :
2006  ""));
2007  return scalar_to_scalar.find(tn->index)->second.find(scalar_index)->second;
2008  }
2010  switch(tn->get_kind())
2011  {
2012  case gimple_assign_K:
2013  {
2014  const auto* ga = GetPointer<const gimple_assign>(tn);
2016  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Creating replicas of scalar");
2017  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
2018  {
2019  std::string include_name = GetPointer<const srcp>(tn)->include_name;
2020  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
2021  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
2022  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2023  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
2024  tree_node_schema[TOK(TOK_CLOBBER)] = STR(ga->clobber);
2025  tree_node_schema[TOK(TOK_ADDR)] = STR(ga->temporary_address);
2026  tree_node_schema[TOK(TOK_INIT)] = STR(ga->init_assignment);
2027  tree_node_schema[TOK(TOK_OP1)] =
2028  STR(Transform(ga->op1->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
2029  tree_node_schema[TOK(TOK_OP0)] =
2030  STR(Transform(ga->op0->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
2031  if(ga->predicate)
2032  {
2033  tree_node_schema[TOK(TOK_PREDICATE)] =
2034  STR(Transform(ga->predicate->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
2035  }
2036 
2037  unsigned int new_tree_node_index = TM->new_tree_node_id();
2038  TM->create_tree_node(new_tree_node_index, gimple_assign_K, tree_node_schema);
2039  auto* new_ga = GetPointer<gimple_assign>(TM->get_tree_node_const(new_tree_node_index));
2040  new_ga->memuse = ga->memuse;
2041  new_ga->memdef = ga->memdef;
2042  for(const auto& vuse : ga->vuses)
2043  {
2044  new_ga->AddVuse(TM->GetTreeReindex(
2045  Transform(vuse->index, parallel_degree, scalar, new_stmt_list, new_phi_list)));
2046  }
2047  if(ga->vdef)
2048  {
2049  new_ga->vdef = TM->GetTreeReindex(
2050  Transform(ga->vdef->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
2051  const auto old_vdef = GetPointer<const ssa_name>(GET_NODE(ga->vdef));
2052  for(const auto& use_stmt : old_vdef->CGetUseStmts())
2053  {
2054  const auto stmt = use_stmt.first;
2055  if(transformations.find(stmt->index) == transformations.end())
2056  {
2057  const auto gn = GetPointerS<gimple_node>(GET_NODE(stmt));
2058  const auto vuse_it = gn->vuses.find(ga->vdef);
2059  if(vuse_it != gn->vuses.end())
2060  {
2061  gn->vuses.erase(vuse_it);
2062  gn->vuses.insert(new_ga->vdef);
2063  }
2064  }
2065  }
2066  }
2067  new_ga->vovers = ga->vovers;
2068  new_ga->pragmas = ga->pragmas;
2069  new_ga->use_set = ga->use_set;
2070  new_ga->clobbered_set = ga->clobbered_set;
2071  new_stmt_list.push_back(TM->GetTreeReindex(new_tree_node_index));
2072  scalar_to_ssa[scalar] = new_ga->op0->index;
2073  return_value = new_tree_node_index;
2074  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Created " + new_ga->ToString());
2075  }
2076  tree_node_schema.clear();
2077  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Created replicas of scalar");
2079  if(transformations[ga->op0->index] == SIMD)
2080  {
2081  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Building constructor for left part");
2082 
2084  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> constructor_tree_node_schema;
2085  constructor_tree_node_schema[TOK(TOK_TYPE)] = STR(Transform(
2086  tree_helper::CGetType(ga->op0)->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2087  unsigned int constructor_index = TM->new_tree_node_id();
2088  TM->create_tree_node(constructor_index, constructor_K, constructor_tree_node_schema);
2089  auto* constr = GetPointer<constructor>(TM->get_tree_node_const(constructor_index));
2090  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
2091  {
2092  const auto new_ic = TM->CreateUniqueIntegerCst(static_cast<long long int>(scalar - 1),
2094  constr->add_idx_valu(new_ic, TM->GetTreeReindex(scalar_to_ssa[scalar]));
2095  }
2096 
2097  std::string include_name = GetPointer<const srcp>(tn)->include_name;
2098  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
2099  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
2100  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2101  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
2102  tree_node_schema[TOK(TOK_CLOBBER)] = STR(ga->clobber);
2103  tree_node_schema[TOK(TOK_INIT)] = STR(ga->init_assignment);
2104  tree_node_schema[TOK(TOK_OP1)] = STR(constr->index);
2105  tree_node_schema[TOK(TOK_OP0)] =
2106  STR(Transform(ga->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2107  unsigned int new_tree_node_index = TM->new_tree_node_id();
2108  TM->create_tree_node(new_tree_node_index, gimple_assign_K, tree_node_schema);
2109  new_stmt_list.push_back(TM->GetTreeReindex(new_tree_node_index));
2110  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Built constructor for left part");
2111  }
2112  break;
2113  }
2114  case CASE_UNARY_EXPRESSION:
2115  {
2116  const auto* ue = GetPointer<const unary_expr>(tn);
2117  tree_node_schema[TOK(TOK_TYPE)] = STR(ue->type->index);
2118  tree_node_schema[TOK(TOK_OP)] =
2119  STR(Transform(ue->op->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2120  std::string include_name = ue->include_name;
2121  unsigned int line_number = ue->line_number;
2122  unsigned int column_number = ue->column_number;
2123  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2124  unsigned int new_tree_node_id = TM->new_tree_node_id();
2125  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2126  return_value = new_tree_node_id;
2127  break;
2128  }
2130  {
2131  const auto* be = GetPointer<const binary_expr>(tn);
2132  tree_node_schema[TOK(TOK_OP0)] =
2133  STR(Transform(be->op0->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2134  std::string include_name = be->include_name;
2135  unsigned int line_number = be->line_number;
2136  unsigned int column_number = be->column_number;
2137  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2138  tree_node_schema[TOK(TOK_TYPE)] = STR(be->type->index);
2139  tree_node_schema[TOK(TOK_OP1)] =
2140  STR(Transform(be->op1->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2141  unsigned int new_tree_node_id = TM->new_tree_node_id();
2142  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2143  return_value = new_tree_node_id;
2144  break;
2145  }
2147  {
2148  const auto* te = GetPointer<const ternary_expr>(tn);
2149  tree_node_schema[TOK(TOK_OP0)] =
2150  STR(Transform(te->op0->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2151  std::string include_name = te->include_name;
2152  unsigned int line_number = te->line_number;
2153  unsigned int column_number = te->column_number;
2154  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2155  tree_node_schema[TOK(TOK_TYPE)] = STR(te->type->index);
2156  tree_node_schema[TOK(TOK_OP1)] =
2157  STR(Transform(te->op1->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2158  tree_node_schema[TOK(TOK_OP2)] =
2159  STR(Transform(te->op2->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2160  unsigned int new_tree_node_id = TM->new_tree_node_id();
2161  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2162  return_value = new_tree_node_id;
2163  break;
2164  }
2165  case lut_expr_K:
2166  {
2167  const auto* le = GetPointer<const lut_expr>(tn);
2168  tree_node_schema[TOK(TOK_OP0)] =
2169  STR(Transform(le->op0->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2170  std::string include_name = le->include_name;
2171  unsigned int line_number = le->line_number;
2172  unsigned int column_number = le->column_number;
2173  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2174  tree_node_schema[TOK(TOK_TYPE)] = STR(le->type->index);
2175  tree_node_schema[TOK(TOK_OP1)] =
2176  STR(Transform(le->op1->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2177  if(le->op2)
2178  {
2179  tree_node_schema[TOK(TOK_OP2)] =
2180  STR(Transform(le->op2->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2181  }
2182  if(le->op3)
2183  {
2184  tree_node_schema[TOK(TOK_OP3)] =
2185  STR(Transform(le->op3->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2186  }
2187  if(le->op4)
2188  {
2189  tree_node_schema[TOK(TOK_OP4)] =
2190  STR(Transform(le->op4->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2191  }
2192  if(le->op5)
2193  {
2194  tree_node_schema[TOK(TOK_OP5)] =
2195  STR(Transform(le->op5->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2196  }
2197  if(le->op6)
2198  {
2199  tree_node_schema[TOK(TOK_OP6)] =
2200  STR(Transform(le->op6->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2201  }
2202  if(le->op7)
2203  {
2204  tree_node_schema[TOK(TOK_OP7)] =
2205  STR(Transform(le->op7->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2206  }
2207  if(le->op8)
2208  {
2209  tree_node_schema[TOK(TOK_OP8)] =
2210  STR(Transform(le->op8->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2211  }
2212  unsigned int new_tree_node_id = TM->new_tree_node_id();
2213  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2214  return_value = new_tree_node_id;
2215  break;
2216  }
2217  case array_ref_K:
2218  {
2219  const auto* qe = GetPointer<const quaternary_expr>(tn);
2220  tree_node_schema[TOK(TOK_OP0)] =
2221  STR(Transform(qe->op0->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2222  std::string include_name = qe->include_name;
2223  unsigned int line_number = qe->line_number;
2224  unsigned int column_number = qe->column_number;
2225  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2226  tree_node_schema[TOK(TOK_TYPE)] = STR(qe->type->index);
2227  tree_node_schema[TOK(TOK_OP0)] =
2228  STR(Transform(qe->op0->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2229  tree_node_schema[TOK(TOK_OP1)] =
2230  STR(Transform(qe->op1->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2231  if(qe->op2)
2232  {
2233  tree_node_schema[TOK(TOK_OP2)] =
2234  STR(Transform(qe->op2->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2235  }
2236  if(qe->op3)
2237  {
2238  tree_node_schema[TOK(TOK_OP3)] =
2239  STR(Transform(qe->op3->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2240  }
2241  unsigned int new_tree_node_id = TM->new_tree_node_id();
2242  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2243  return_value = new_tree_node_id;
2244  break;
2245  }
2246 
2247  case target_mem_ref461_K:
2248  {
2249  const auto* tmr = GetPointer<const target_mem_ref461>(tn);
2250  tree_node_schema[TOK(TOK_TYPE)] = STR(tmr->type->index);
2251  if(tmr->base)
2252  {
2253  tree_node_schema[TOK(TOK_BASE)] =
2254  STR(Transform(tmr->base->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2255  }
2256  if(tmr->offset)
2257  {
2258  tree_node_schema[TOK(TOK_OFFSET)] =
2259  STR(Transform(tmr->offset->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2260  }
2261  if(tmr->idx)
2262  {
2263  tree_node_schema[TOK(TOK_IDX)] =
2264  STR(Transform(tmr->idx->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2265  }
2266  if(tmr->step)
2267  {
2268  tree_node_schema[TOK(TOK_STEP)] =
2269  STR(Transform(tmr->step->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2270  }
2271  if(tmr->idx2)
2272  {
2273  tree_node_schema[TOK(TOK_IDX2)] =
2274  STR(Transform(tmr->idx2->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list));
2275  }
2276  unsigned int new_tree_node_id = TM->new_tree_node_id();
2277  TM->create_tree_node(new_tree_node_id, target_mem_ref461_K, tree_node_schema);
2278  return_value = new_tree_node_id;
2279  break;
2280  }
2281  case CASE_CST_NODES:
2282  {
2283  return_value = tree_node_index;
2284  break;
2285  }
2286  case var_decl_K:
2287  {
2288  return_value = tree_node_index;
2289  break;
2290  }
2291  case ssa_name_K:
2292  {
2293  if(transformations.find(tn->index) != transformations.end())
2294  {
2295  const auto* sa = GetPointer<const ssa_name>(tn);
2296  if(sa->type)
2297  {
2298  tree_node_schema[TOK(TOK_TYPE)] = STR(sa->type->index);
2299  }
2300  if(sa->var)
2301  {
2302  tree_node_schema[TOK(TOK_VAR)] = STR(sa->var->index);
2303  }
2304  tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
2305  tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
2306  if(sa->volatile_flag)
2307  {
2308  tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
2309  }
2310  if(sa->virtual_flag)
2311  {
2312  tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
2313  }
2314  if(sa->max)
2315  {
2316  tree_node_schema[TOK(TOK_MAX)] = STR(sa->max->index);
2317  }
2318  if(sa->min)
2319  {
2320  tree_node_schema[TOK(TOK_MIN)] = STR(sa->min->index);
2321  }
2322 
2323  unsigned int ssa_tree_node_index = TM->new_tree_node_id();
2324  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, tree_node_schema);
2325  return_value = ssa_tree_node_index;
2326  }
2327  else
2328  {
2329  return_value = tree_node_index;
2330  }
2331  break;
2332  }
2333  case call_expr_K:
2334  case aggr_init_expr_K:
2335  {
2336  const auto* ce = GetPointer<const call_expr>(tn);
2337  std::string include_name = ce->include_name;
2338  unsigned int line_number = ce->line_number;
2339  unsigned int column_number = ce->column_number;
2340  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2341  tree_node_schema[TOK(TOK_TYPE)] = STR(ce->type->index);
2342  tree_node_schema[TOK(TOK_FN)] = STR(ce->fn->index);
2343  unsigned int call_expr_tree_node_index = TM->new_tree_node_id();
2344  TM->create_tree_node(call_expr_tree_node_index, call_expr_K, tree_node_schema);
2345  auto* new_ce = GetPointer<call_expr>(TM->get_tree_node_const(call_expr_tree_node_index));
2346  for(const auto& arg : ce->args)
2347  {
2348  new_ce->AddArg(TM->GetTreeReindex(
2349  Transform(arg->index, parallel_degree, scalar_index, new_stmt_list, new_phi_list)));
2350  }
2351  return_value = call_expr_tree_node_index;
2352  break;
2353  }
2354  case const_decl_K:
2355  case field_decl_K:
2356  case function_decl_K:
2357  case label_decl_K:
2358  case namespace_decl_K:
2359  case parm_decl_K:
2360  case result_decl_K:
2361  case translation_unit_decl_K:
2362  case template_decl_K:
2363  case error_mark_K:
2364  case using_decl_K:
2365  case type_decl_K:
2366  case binfo_K:
2367  case block_K:
2368  case case_label_expr_K:
2369  case constructor_K:
2370  case identifier_node_K:
2371  case statement_list_K:
2372  case target_mem_ref_K:
2373  case tree_list_K:
2374  case tree_vec_K:
2375  case CASE_CPP_NODES:
2376  case CASE_FAKE_NODES:
2377  case gimple_asm_K:
2378  case gimple_bind_K:
2379  case gimple_call_K:
2380  case gimple_cond_K:
2381  case gimple_for_K:
2382  case gimple_goto_K:
2383  case gimple_label_K:
2384  case gimple_multi_way_if_K:
2385  case gimple_nop_K:
2386  case gimple_phi_K:
2387  case gimple_pragma_K:
2388  case gimple_predict_K:
2389  case gimple_resx_K:
2390  case gimple_return_K:
2391  case gimple_switch_K:
2392  case gimple_while_K:
2393  case CASE_PRAGMA_NODES:
2394  case array_range_ref_K:
2395  case target_expr_K:
2396  case CASE_TYPE_NODES:
2397  {
2398  THROW_UNREACHABLE("Not supported tree node " + tn->get_kind_text());
2399  break;
2400  }
2401  default:
2402  {
2403  THROW_UNREACHABLE("");
2404  }
2405  }
2406  scalar_to_scalar[tree_node_index][scalar_index] = return_value;
2407  break;
2408  }
2409  case(SIMD):
2410  {
2411  if(scalar_to_vector.find(tree_node_index) != scalar_to_vector.end())
2412  {
2414  "<--Already transformed " + STR(tree_node_index) +
2415  ((TM->get_tree_node_const(tree_node_index)->get_kind() != function_decl_K) ?
2416  ": " + TM->get_tree_node_const(tree_node_index)->ToString() :
2417  ""));
2418  return scalar_to_vector.find(tree_node_index)->second;
2419  }
2421  switch(tn->get_kind())
2422  {
2423  case gimple_assign_K:
2424  {
2425  const auto* ga = GetPointer<const gimple_assign>(tn);
2426  std::string include_name = GetPointer<const srcp>(tn)->include_name;
2427  unsigned int line_number = GetPointer<const srcp>(tn)->line_number;
2428  unsigned int column_number = GetPointer<const srcp>(tn)->column_number;
2429  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2430  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
2431  tree_node_schema[TOK(TOK_CLOBBER)] = STR(ga->clobber);
2432  tree_node_schema[TOK(TOK_ADDR)] = STR(ga->temporary_address);
2433  tree_node_schema[TOK(TOK_INIT)] = STR(ga->init_assignment);
2434  tree_node_schema[TOK(TOK_OP1)] =
2435  STR(Transform(ga->op1->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2436  THROW_ASSERT(transformations.find(ga->op1->index) == transformations.end() or
2437  transformations.find(ga->op1->index)->second == SIMD,
2438  "Composition not yet implemented " + STR(tn));
2439  tree_node_schema[TOK(TOK_OP0)] =
2440  STR(Transform(ga->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2441  unsigned int new_tree_node_index = TM->new_tree_node_id();
2442  TM->create_tree_node(new_tree_node_index, gimple_assign_K, tree_node_schema);
2443  auto* new_ga = GetPointer<gimple_assign>(TM->get_tree_node_const(new_tree_node_index));
2444  new_ga->memuse = ga->memuse;
2445  new_ga->memdef = ga->memdef;
2446  for(const auto& vuse : ga->vuses)
2447  {
2448  new_ga->AddVuse(
2449  TM->GetTreeReindex(Transform(vuse->index, parallel_degree, 0, new_stmt_list, new_phi_list)));
2450  }
2451  if(new_ga->vdef)
2452  {
2453  new_ga->vdef =
2454  TM->GetTreeReindex(Transform(ga->vdef->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2455  }
2456  new_ga->vovers = ga->vovers;
2457  new_ga->pragmas = ga->pragmas;
2458  new_ga->use_set = ga->use_set;
2459  new_ga->clobbered_set = ga->clobbered_set;
2460  return_value = new_tree_node_index;
2461  THROW_ASSERT(GET_NODE(new_ga->op0)->get_kind() == ssa_name_K, "Left operand is not ssa");
2462  new_stmt_list.push_back(TM->GetTreeReindex(return_value));
2463  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
2464  {
2466  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> bit_field_ref_tree_node_schema,
2467  gimple_assign_tree_node_schema;
2468  unsigned int bit_field_ref_index = TM->new_tree_node_id();
2469  const auto element_type = tree_helper::CGetType(ga->op0);
2471  const auto bit_size =
2472  GET_CONST_NODE(element_type)->get_kind() != boolean_type_K ? tree_helper::Size(element_type) : 32;
2473  const auto offset = TM->CreateUniqueIntegerCst(static_cast<long long int>((scalar - 1) * bit_size),
2475  const auto size = TM->CreateUniqueIntegerCst(static_cast<long long int>(bit_size),
2477  bit_field_ref_tree_node_schema[TOK(TOK_SRCP)] =
2478  include_name + ":" + STR(line_number) + ":" + STR(column_number);
2479  bit_field_ref_tree_node_schema[TOK(TOK_TYPE)] = STR(tree_helper::CGetType(tn)->index);
2480  bit_field_ref_tree_node_schema[TOK(TOK_OP0)] =
2481  STR(Transform(ga->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2482  bit_field_ref_tree_node_schema[TOK(TOK_OP1)] = STR(size->index);
2483  bit_field_ref_tree_node_schema[TOK(TOK_OP2)] = STR(offset->index);
2484  TM->create_tree_node(bit_field_ref_index, bit_field_ref_K, bit_field_ref_tree_node_schema);
2485 
2486  gimple_assign_tree_node_schema[TOK(TOK_SRCP)] =
2487  include_name + ":" + STR(line_number) + ":" + STR(column_number);
2488  gimple_assign_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
2489  gimple_assign_tree_node_schema[TOK(TOK_OP1)] = STR(bit_field_ref_index);
2490  gimple_assign_tree_node_schema[TOK(TOK_OP0)] =
2491  STR(Transform(ga->op0->index, parallel_degree, scalar, new_stmt_list, new_phi_list));
2492  unsigned int gimple_new_tree_node_index = TM->new_tree_node_id();
2493  TM->create_tree_node(gimple_new_tree_node_index, gimple_assign_K, gimple_assign_tree_node_schema);
2495  "---Adding " + TM->get_tree_node_const(gimple_new_tree_node_index)->ToString());
2496  new_stmt_list.push_back(TM->GetTreeReindex(gimple_new_tree_node_index));
2497  scalar_to_scalar[tree_node_index][scalar] = return_value;
2498  }
2499  break;
2500  }
2501  case ssa_name_K:
2502  {
2503  const auto* sa = GetPointer<const ssa_name>(tn);
2504  if(sa->type)
2505  {
2506  tree_node_schema[TOK(TOK_TYPE)] =
2507  STR(Transform(sa->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2508  }
2509  if(sa->var)
2510  {
2511  tree_node_schema[TOK(TOK_VAR)] =
2512  STR(Transform(sa->var->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2513  }
2514  tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
2515  tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
2516  if(sa->volatile_flag)
2517  {
2518  tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
2519  }
2520  if(sa->virtual_flag)
2521  {
2522  tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
2523  }
2524  if(sa->max)
2525  {
2526  tree_node_schema[TOK(TOK_MAX)] =
2527  STR(Transform(sa->max->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2528  }
2529  if(sa->min)
2530  {
2531  tree_node_schema[TOK(TOK_MIN)] =
2532  STR(Transform(sa->min->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2533  }
2534 
2535  unsigned int new_tree_node_index = TM->new_tree_node_id();
2536  TM->create_tree_node(new_tree_node_index, ssa_name_K, tree_node_schema);
2537  return_value = new_tree_node_index;
2538  break;
2539  }
2540  case CASE_TYPE_NODES:
2541  {
2542  const auto* type = GetPointer<const type_node>(tn);
2543  tree_node_schema[TOK(TOK_QUAL)] = STR(static_cast<unsigned int>(type->qual));
2544  if(type->unql)
2545  {
2546  tree_node_schema[TOK(TOK_UNQL)] =
2547  STR(Transform(type->unql->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2548  }
2549  if(type->scpe)
2550  {
2551  tree_node_schema[TOK(TOK_SCPE)] =
2552  STR(Transform(type->scpe->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2553  }
2554  if(type->packed_flag)
2555  {
2556  tree_node_schema[TOK(TOK_PACKED)] = STR(type->packed_flag);
2557  }
2558  tree_node_schema[TOK(TOK_SYSTEM)] = STR(false);
2559  if(type->algn)
2560  {
2561  tree_node_schema[TOK(TOK_ALGN)] = STR(type->algn);
2562  }
2563  switch(type->get_kind())
2564  {
2565  case pointer_type_K:
2566 #if 0
2567  {
2568  const pointer_type * pt = GetPointer<const pointer_type>(tn);
2569  tree_node_schema[TOK(TOK_PTD)] = STR(Transform(pt->ptd->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2570  if(type->size)
2571  tree_node_schema[TOK(TOK_SIZE)] = STR(type->size->index);
2572  if(type->name)
2573  tree_node_schema[TOK(TOK_NAME)] = STR(Transform(type->name->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2574  unsigned int new_tree_node_id = TM->new_tree_node_id();
2575  TM->create_tree_node(new_tree_node_id, pointer_type_K, tree_node_schema);
2576  return_value = new_tree_node_id;
2577  break;
2578  }
2579 #endif
2580  case boolean_type_K:
2581  case integer_type_K:
2582  case void_type_K:
2583  {
2584  tree_node_schema[TOK(TOK_ELTS)] = type->get_kind() != boolean_type_K ?
2585  STR(type->index) :
2587  if(type->size)
2588  {
2589  const auto element_size = type->get_kind() != boolean_type_K ?
2590  tree_helper::Size(tn) :
2592  const auto bit_size = element_size * static_cast<unsigned int>(parallel_degree);
2593  const auto size = TM->CreateUniqueIntegerCst(static_cast<long long int>(bit_size),
2595  tree_node_schema[TOK(TOK_SIZE)] = STR(size->index);
2596  tree_node_schema[TOK(TOK_ALGN)] = STR(bit_size);
2597  }
2598  auto new_tree_node_id = TM->new_tree_node_id();
2599  TM->create_tree_node(new_tree_node_id, vector_type_K, tree_node_schema);
2600  return_value = new_tree_node_id;
2602  auto* new_type_node = GetPointer<type_node>(TM->get_tree_node_const(new_tree_node_id));
2603  if(new_type_node->name and GET_NODE(new_type_node->name)->get_kind() == type_decl_K)
2604  {
2605  auto* td = GetPointer<type_decl>(GET_NODE(new_type_node->name));
2606  td->type = TM->GetTreeReindex(new_tree_node_id);
2607  }
2608  break;
2609  }
2610  case array_type_K:
2611  case CharType_K:
2612  case nullptr_type_K:
2613  case type_pack_expansion_K:
2614  case complex_type_K:
2615  case enumeral_type_K:
2616  case function_type_K:
2617  case lang_type_K:
2618  case method_type_K:
2619  case offset_type_K:
2620  case qual_union_type_K:
2621  case real_type_K:
2622  case record_type_K:
2623  case reference_type_K:
2624  case set_type_K:
2625  case template_type_parm_K:
2626  case typename_type_K:
2627  case type_argument_pack_K:
2628  case union_type_K:
2629  case vector_type_K:
2630  case binfo_K:
2631  case block_K:
2632  case call_expr_K:
2633  case aggr_init_expr_K:
2634  case case_label_expr_K:
2635  case constructor_K:
2636  case identifier_node_K:
2637  case ssa_name_K:
2638  case statement_list_K:
2639  case target_expr_K:
2640  case target_mem_ref_K:
2641  case target_mem_ref461_K:
2642  case tree_list_K:
2643  case tree_vec_K:
2644  case error_mark_K:
2645  case lut_expr_K:
2647  case CASE_CPP_NODES:
2648  case CASE_CST_NODES:
2649  case CASE_DECL_NODES:
2650  case CASE_FAKE_NODES:
2651  case CASE_GIMPLE_NODES:
2652  case CASE_PRAGMA_NODES:
2655  case CASE_UNARY_EXPRESSION:
2656  {
2657  THROW_UNREACHABLE("Not supported tree node " + tn->get_kind_text());
2658  break;
2659  }
2660  default:
2661  {
2662  THROW_UNREACHABLE("");
2663  }
2664  }
2665  break;
2666  }
2667  case var_decl_K:
2668  case type_decl_K:
2669  {
2670  const auto* dn = GetPointer<const decl_node>(tn);
2671  if(dn->name)
2672  {
2673  tree_node_schema[TOK(TOK_NAME)] =
2674  STR(Transform(dn->name->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2675  }
2676  if(dn->mngl)
2677  {
2678  tree_node_schema[TOK(TOK_MNGL)] =
2679  STR(Transform(dn->mngl->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2680  }
2681  if(dn->orig)
2682  {
2683  tree_node_schema[TOK(TOK_ORIG)] = STR(dn->orig->index);
2684  }
2685  if(dn->type)
2686  {
2687  if(dn->get_kind() != type_decl_K)
2688  {
2689  tree_node_schema[TOK(TOK_TYPE)] =
2690  STR(Transform(dn->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2691  }
2692  }
2693  if(dn->scpe)
2694  {
2695  tree_node_schema[TOK(TOK_SCPE)] =
2696  STR(Transform(dn->scpe->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2697  }
2698  if(dn->attributes)
2699  {
2700  tree_node_schema[TOK(TOK_ATTRIBUTES)] = STR(dn->attributes->index);
2701  }
2702  if(dn->chan)
2703  {
2704  tree_node_schema[TOK(TOK_CHAN)] =
2705  STR(Transform(dn->chan->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2706  }
2707  if(dn->artificial_flag)
2708  {
2709  tree_node_schema[TOK(TOK_ARTIFICIAL)] = STR(dn->artificial_flag);
2710  }
2711  if(dn->packed_flag)
2712  {
2713  tree_node_schema[TOK(TOK_PACKED)] = STR(dn->packed_flag);
2714  }
2715  if(dn->operating_system_flag)
2716  {
2717  tree_node_schema[TOK(TOK_OPERATING_SYSTEM)] = STR(dn->operating_system_flag);
2718  }
2719  if(dn->library_system_flag)
2720  {
2721  tree_node_schema[TOK(TOK_LIBRARY_SYSTEM)] = STR(dn->library_system_flag);
2722  }
2723  if(dn->libbambu_flag)
2724  {
2725  tree_node_schema[TOK(TOK_LIBBAMBU)] = STR(dn->libbambu_flag);
2726  }
2727  if(dn->C_flag)
2728  {
2729  tree_node_schema[TOK(TOK_C)] = STR(dn->C_flag);
2730  }
2731  std::string include_name =
2732  dn->get_kind() == type_decl_K and dn->include_name == "<built-in>" ? "<new>" : dn->include_name;
2733  auto line_number = dn->line_number;
2734  auto column_number = dn->column_number;
2735  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2736  switch(tn->get_kind())
2737  {
2738  case(type_decl_K):
2739  {
2740  const auto* td = GetPointer<const type_decl>(tn);
2741  if(td->tmpl_parms)
2742  {
2743  tree_node_schema[TOK(TOK_TMPL_PARMS)] =
2744  STR(Transform(td->tmpl_parms->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2745  }
2746  if(td->tmpl_args)
2747  {
2748  tree_node_schema[TOK(TOK_TMPL_ARGS)] =
2749  STR(Transform(td->tmpl_args->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2750  }
2751  auto new_tree_node_id = TM->new_tree_node_id();
2752  TM->create_tree_node(new_tree_node_id, type_decl_K, tree_node_schema);
2753  return_value = new_tree_node_id;
2754  break;
2755  }
2756  case var_decl_K:
2757  {
2758  const auto* vd = GetPointer<const var_decl>(tn);
2759  if(vd->use_tmpl)
2760  {
2761  tree_node_schema[TOK(TOK_USE_TMPL)] = STR(vd->use_tmpl);
2762  }
2763  if(vd->static_static_flag)
2764  {
2765  tree_node_schema[TOK(TOK_STATIC_STATIC)] = STR(vd->static_static_flag);
2766  }
2767  if(vd->extern_flag)
2768  {
2769  tree_node_schema[TOK(TOK_EXTERN)] = STR(vd->extern_flag);
2770  }
2771  if(vd->static_flag)
2772  {
2773  tree_node_schema[TOK(TOK_STATIC)] = STR(vd->static_flag);
2774  }
2775  if(vd->init)
2776  {
2777  tree_node_schema[TOK(TOK_INIT)] =
2778  STR(Transform(vd->init->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2779  }
2780  if(vd->size)
2781  {
2783  const auto* type = GetPointer<const type_node>(TM->get_tree_node_const(
2784  Transform(dn->type->index, parallel_degree, 0, new_stmt_list, new_phi_list)));
2785  tree_node_schema[TOK(TOK_SIZE)] = STR(type->size->index);
2786  }
2787  if(vd->algn)
2788  {
2789  tree_node_schema[TOK(TOK_ALGN)] = STR(vd->algn);
2790  }
2791  if(vd->used)
2792  {
2793  tree_node_schema[TOK(TOK_USED)] = STR(vd->used);
2794  }
2795  if(vd->register_flag)
2796  {
2797  tree_node_schema[TOK(TOK_REGISTER)] = STR(vd->register_flag);
2798  }
2799  if(vd->smt_ann)
2800  {
2801  tree_node_schema[TOK(TOK_SMT_ANN)] =
2802  STR(Transform(vd->smt_ann->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2803  }
2804  auto new_tree_node_id = TM->new_tree_node_id();
2805  TM->create_tree_node(new_tree_node_id, var_decl_K, tree_node_schema);
2806  return_value = new_tree_node_id;
2807  break;
2808  }
2809  case const_decl_K:
2810  case field_decl_K:
2811  case function_decl_K:
2812  case label_decl_K:
2813  case namespace_decl_K:
2814  case parm_decl_K:
2815  case result_decl_K:
2816  case translation_unit_decl_K:
2817  case error_mark_K:
2818  case using_decl_K:
2819  case template_decl_K:
2820  case binfo_K:
2821  case block_K:
2822  case call_expr_K:
2823  case aggr_init_expr_K:
2824  case case_label_expr_K:
2825  case constructor_K:
2826  case identifier_node_K:
2827  case ssa_name_K:
2828  case statement_list_K:
2829  case target_expr_K:
2830  case target_mem_ref_K:
2831  case target_mem_ref461_K:
2832  case tree_list_K:
2833  case tree_vec_K:
2834  case lut_expr_K:
2836  case CASE_CPP_NODES:
2837  case CASE_CST_NODES:
2838  case CASE_FAKE_NODES:
2839  case CASE_GIMPLE_NODES:
2840  case CASE_PRAGMA_NODES:
2843  case CASE_TYPE_NODES:
2844  case CASE_UNARY_EXPRESSION:
2845  {
2846  THROW_UNREACHABLE("Not supported tree node " + tn->get_kind_text());
2847  break;
2848  }
2849  default:
2850  {
2851  THROW_UNREACHABLE("");
2852  }
2853  }
2854  break;
2855  }
2856  case using_decl_K:
2857  case translation_unit_decl_K:
2858  {
2859  return_value = tree_node_index;
2860  break;
2861  }
2862  case identifier_node_K:
2863  {
2864  const auto* in = GetPointer<const identifier_node>(tn);
2865  if(in->operator_flag)
2866  {
2867  tree_node_schema[TOK(TOK_OPERATOR)] = STR(in->operator_flag);
2868  }
2869  else
2870  {
2871  tree_node_schema[TOK(TOK_STRG)] = "vector_" + boost::replace_all_copy(in->strg, " ", "_");
2872  }
2873  auto new_tree_node_id = TM->new_tree_node_id();
2874  TM->create_tree_node(new_tree_node_id, identifier_node_K, tree_node_schema);
2875  return_value = new_tree_node_id;
2876  break;
2877  }
2878  case function_decl_K:
2879  {
2881  return_value = tree_node_index;
2882  break;
2883  }
2884  case CASE_UNARY_EXPRESSION:
2885  {
2886  const auto* ue = GetPointer<const unary_expr>(tn);
2887  tree_node_schema[TOK(TOK_TYPE)] =
2888  STR(Transform(ue->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2889  tree_node_schema[TOK(TOK_OP)] =
2890  STR(Transform(ue->op->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2891  THROW_ASSERT(transformations.find(ue->op->index) == transformations.end() or
2892  transformations.find(ue->op->index)->second != SCALAR,
2893  "");
2894  std::string include_name = ue->include_name;
2895  auto line_number = ue->line_number;
2896  auto column_number = ue->column_number;
2897  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2898  auto new_tree_node_id = TM->new_tree_node_id();
2899  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
2900  return_value = new_tree_node_id;
2901  break;
2902  }
2904  {
2905  const auto* be = GetPointer<const binary_expr>(tn);
2906  tree_node_schema[TOK(TOK_TYPE)] =
2907  STR(Transform(be->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2908  tree_node_schema[TOK(TOK_OP0)] =
2909  STR(Transform(be->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2910  if(tn->get_kind() == lshift_expr_K or tn->get_kind() == rshift_expr_K)
2911  {
2912  tree_node_schema[TOK(TOK_OP1)] = STR(be->op1->index);
2913  }
2914  else if(transformations.find(be->op1->index) == transformations.end() or
2915  transformations.find(be->op1->index)->second != SCALAR)
2916  {
2917  tree_node_schema[TOK(TOK_OP1)] =
2918  STR(Transform(be->op1->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2919  }
2920  else
2921  {
2922  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Building constructor for second operand");
2923 
2925  std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> constructor_tree_node_schema,
2926  temp_tree_node_schema, ssa_tree_node_schema;
2927  constructor_tree_node_schema[TOK(TOK_TYPE)] =
2928  STR(Transform(be->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2929  auto constructor_index = TM->new_tree_node_id();
2930  TM->create_tree_node(constructor_index, constructor_K, constructor_tree_node_schema);
2931  auto* constr = GetPointer<constructor>(TM->get_tree_node_const(constructor_index));
2932  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
2933  {
2934  const auto new_ic = TM->CreateUniqueIntegerCst(static_cast<long long int>(scalar - 1),
2936  constr->add_idx_valu(new_ic, TM->GetTreeReindex(be->op1->index));
2937  }
2938 
2939  std::string include_name = GetPointer<const srcp>(tn)->include_name;
2940  auto line_number = GetPointer<const srcp>(tn)->line_number;
2941  auto column_number = GetPointer<const srcp>(tn)->column_number;
2942  THROW_ASSERT(GET_NODE(be->op1)->get_kind() == ssa_name_K,
2943  "Unexpected operand " + GET_NODE(be->op1)->get_kind_text());
2944  const auto* sa = GetPointer<const ssa_name>(GET_NODE(be->op1));
2945  if(sa->type)
2946  {
2947  ssa_tree_node_schema[TOK(TOK_TYPE)] =
2948  STR(Transform(sa->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2949  }
2950  if(sa->var)
2951  {
2952  ssa_tree_node_schema[TOK(TOK_VAR)] =
2953  STR(Transform(sa->var->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2954  }
2955  ssa_tree_node_schema[TOK(TOK_VERS)] = STR(TM->get_next_vers());
2956  ssa_tree_node_schema[TOK(TOK_ORIG_VERS)] = STR(sa->orig_vers);
2957  if(sa->volatile_flag)
2958  {
2959  ssa_tree_node_schema[TOK(TOK_VOLATILE)] = STR(sa->volatile_flag);
2960  }
2961  if(sa->virtual_flag)
2962  {
2963  ssa_tree_node_schema[TOK(TOK_VIRTUAL)] = STR(sa->virtual_flag);
2964  }
2965  if(sa->max)
2966  {
2967  ssa_tree_node_schema[TOK(TOK_MAX)] =
2968  STR(Transform(sa->max->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2969  }
2970  if(sa->min)
2971  {
2972  ssa_tree_node_schema[TOK(TOK_MIN)] =
2973  STR(Transform(sa->min->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2974  }
2975 
2976  auto ssa_tree_node_index = TM->new_tree_node_id();
2977  TM->create_tree_node(ssa_tree_node_index, ssa_name_K, ssa_tree_node_schema);
2978  temp_tree_node_schema[TOK(TOK_SRCP)] =
2979  include_name + ":" + STR(line_number) + ":" + STR(column_number);
2980  temp_tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
2981  temp_tree_node_schema[TOK(TOK_OP1)] = STR(constr->index);
2982  temp_tree_node_schema[TOK(TOK_OP0)] = STR(ssa_tree_node_index);
2983  temp_tree_node_schema[TOK(TOK_TYPE)] = STR(Transform(
2984  tree_helper::CGetType(be->op1)->index, parallel_degree, 0, new_stmt_list, new_phi_list));
2985  auto temp_tree_node_index = TM->new_tree_node_id();
2986  TM->create_tree_node(temp_tree_node_index, gimple_assign_K, temp_tree_node_schema);
2987  auto* new_ga = GetPointer<gimple_assign>(TM->get_tree_node_const(temp_tree_node_index));
2988  new_stmt_list.push_back(TM->GetTreeReindex(temp_tree_node_index));
2989  tree_node_schema[TOK(TOK_OP1)] = STR(new_ga->op0->index);
2990  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Built constructor for second operand");
2991  }
2992  THROW_ASSERT(transformations.find(be->op0->index) == transformations.end() or
2993  transformations.find(be->op0->index)->second != SCALAR,
2994  "");
2995  std::string include_name = be->include_name;
2996  auto line_number = be->line_number;
2997  auto column_number = be->column_number;
2998  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
2999  auto new_tree_node_id = TM->new_tree_node_id();
3000  if(tn->get_kind() == truth_or_expr_K)
3001  {
3002  TM->create_tree_node(new_tree_node_id, bit_ior_expr_K, tree_node_schema);
3003  }
3004  else if(tn->get_kind() == truth_and_expr_K)
3005  {
3006  TM->create_tree_node(new_tree_node_id, bit_and_expr_K, tree_node_schema);
3007  }
3008  else if(tn->get_kind() == lshift_expr_K)
3009  {
3010  TM->create_tree_node(new_tree_node_id, vec_lshift_expr_K, tree_node_schema);
3011  }
3012  else if(tn->get_kind() == rshift_expr_K)
3013  {
3014  TM->create_tree_node(new_tree_node_id, vec_rshift_expr_K, tree_node_schema);
3015  }
3016  else
3017  {
3018  TM->create_tree_node(new_tree_node_id, tn->get_kind(), tree_node_schema);
3019  }
3020  return_value = new_tree_node_id;
3021  break;
3022  }
3023  case CASE_CST_NODES:
3024  {
3025  const auto* cn = GetPointer<const cst_node>(tn);
3026  tree_node_schema[TOK(TOK_TYPE)] =
3027  STR(Transform(cn->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3028  auto new_tree_node_id = TM->new_tree_node_id();
3029  TM->create_tree_node(new_tree_node_id, vector_cst_K, tree_node_schema);
3030  auto* new_tn = GetPointer<vector_cst>(TM->get_tree_node_const(new_tree_node_id));
3031  for(size_t i = 0; i < parallel_degree; i++)
3032  {
3033  new_tn->list_of_valu.push_back(TM->GetTreeReindex(tn->index));
3034  }
3035  return_value = new_tree_node_id;
3036  break;
3037  }
3038  case gimple_phi_K:
3039  {
3040  const auto* gp = GetPointer<const gimple_phi>(tn);
3041  tree_node_schema[TOK(TOK_SCPE)] =
3042  STR(Transform(gp->scpe->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3043  tree_node_schema[TOK(TOK_RES)] =
3044  STR(Transform(gp->res->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3045  tree_node_schema[TOK(TOK_VIRTUAL)] = STR(gp->virtual_flag);
3046  std::string include_name = gp->include_name;
3047  auto line_number = gp->line_number;
3048  auto column_number = gp->column_number;
3049  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
3050  tree_node_schema[TOK(TOK_SCPE)] = STR(function_id);
3051  auto new_tree_node_id = TM->new_tree_node_id();
3052  TM->create_tree_node(new_tree_node_id, gimple_phi_K, tree_node_schema);
3053  auto* new_gp = GetPointer<gimple_phi>(TM->get_tree_node_const(new_tree_node_id));
3054  new_gp->SetSSAUsesComputed();
3055  for(const auto& def_edge : gp->CGetDefEdgesList())
3056  {
3057  THROW_ASSERT(gp->virtual_flag or
3058  transformations.find(def_edge.first->index) == transformations.end() or
3059  transformations.find(def_edge.first->index)->second != SCALAR,
3060  "");
3061  if(transformations.find(def_edge.first->index) == transformations.end() or
3062  transformations.find(def_edge.first->index)->second == SIMD)
3063  {
3064  new_gp->AddDefEdge(
3065  TM, gimple_phi::DefEdge(TM->GetTreeReindex(Transform(def_edge.first->index, parallel_degree, 0,
3066  new_stmt_list, new_phi_list)),
3067  def_edge.second));
3068  }
3069  else
3070  {
3071  new_gp->AddDefEdge(
3072  TM, gimple_phi::DefEdge(TM->GetTreeReindex(def_edge.first->index), def_edge.second));
3073  }
3074  }
3075  return_value = new_tree_node_id;
3076  new_phi_list.push_back(TM->GetTreeReindex(return_value));
3077  if(!gp->virtual_flag)
3078  {
3080 
3081  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Creating scalar from simd");
3082  for(size_t scalar = 1; scalar <= parallel_degree; scalar++)
3083  {
3085  const auto new_srcp = include_name + ":" + STR(line_number) + ":" + STR(column_number);
3086  const auto element_type = tree_helper::CGetType(gp->res);
3088  const auto bit_size = GET_CONST_NODE(element_type)->get_kind() != boolean_type_K ?
3089  tree_helper::Size(element_type) :
3090  32U;
3091  const auto offset = TM->CreateUniqueIntegerCst(static_cast<long long int>((scalar - 1) * bit_size),
3093  const auto size = TM->CreateUniqueIntegerCst(static_cast<long long int>(bit_size),
3095  const auto bit_field_ref_node = tree_man->create_ternary_operation(
3096  element_type,
3097  TM->GetTreeReindex(Transform(gp->res->index, parallel_degree, 0, new_stmt_list, new_phi_list)),
3098  size, offset, new_srcp, bit_field_ref_K);
3099 
3100  const auto gimple_new_tree_node = tree_man->create_gimple_modify_stmt(
3101  TM->GetTreeReindex(
3102  Transform(gp->res->index, parallel_degree, scalar, new_stmt_list, new_phi_list)),
3103  bit_field_ref_node, function_id, new_srcp);
3105  new_stmt_list.push_front(gimple_new_tree_node);
3106  }
3107  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Created scalar from simd");
3108  }
3109  break;
3110  }
3111  case cond_expr_K:
3112  {
3113  const auto* te = GetPointer<const ternary_expr>(tn);
3114  tree_node_schema[TOK(TOK_TYPE)] =
3115  STR(Transform(te->type->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3116  tree_node_schema[TOK(TOK_OP2)] =
3117  STR(Transform(te->op2->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3118  tree_node_schema[TOK(TOK_OP1)] =
3119  STR(Transform(te->op1->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3120  tree_node_schema[TOK(TOK_OP0)] =
3121  STR(Transform(te->op0->index, parallel_degree, 0, new_stmt_list, new_phi_list));
3122  THROW_ASSERT(transformations.find(te->op2->index) == transformations.end() or
3123  transformations.find(te->op2->index)->second != SCALAR,
3124  "");
3125  THROW_ASSERT(transformations.find(te->op1->index) == transformations.end() or
3126  transformations.find(te->op1->index)->second != SCALAR,
3127  "");
3128  THROW_ASSERT(transformations.find(te->op0->index) == transformations.end() or
3129  transformations.find(te->op0->index)->second != SCALAR,
3130  "");
3131  std::string include_name = te->include_name;
3132  auto line_number = te->line_number;
3133  auto column_number = te->column_number;
3134  tree_node_schema[TOK(TOK_SRCP)] = include_name + ":" + STR(line_number) + ":" + STR(column_number);
3135  auto new_tree_node_id = TM->new_tree_node_id();
3136  TM->create_tree_node(new_tree_node_id, vec_cond_expr_K, tree_node_schema);
3137  return_value = new_tree_node_id;
3138  break;
3139  }
3140  case const_decl_K:
3141  case field_decl_K:
3142  case label_decl_K:
3143  case namespace_decl_K:
3144  case parm_decl_K:
3145  case result_decl_K:
3146  case template_decl_K:
3147  case binfo_K:
3148  case block_K:
3149  case call_expr_K:
3150  case aggr_init_expr_K:
3151  case case_label_expr_K:
3152  case constructor_K:
3153  case statement_list_K:
3154  case target_expr_K:
3155  case target_mem_ref_K:
3156  case target_mem_ref461_K:
3157  case tree_list_K:
3158  case tree_vec_K:
3159  case CASE_CPP_NODES:
3160  case CASE_FAKE_NODES:
3161  case gimple_asm_K:
3162  case gimple_bind_K:
3163  case gimple_call_K:
3164  case gimple_cond_K:
3165  case gimple_for_K:
3166  case gimple_goto_K:
3167  case gimple_label_K:
3168  case gimple_multi_way_if_K:
3169  case gimple_nop_K:
3170  case gimple_pragma_K:
3171  case gimple_predict_K:
3172  case gimple_resx_K:
3173  case gimple_return_K:
3174  case gimple_switch_K:
3175  case gimple_while_K:
3176  case CASE_PRAGMA_NODES:
3178  case component_ref_K:
3179  case bit_field_ref_K:
3180  case vtable_ref_K:
3181  case with_cleanup_expr_K:
3182  case obj_type_ref_K:
3183  case save_expr_K:
3184  case vec_cond_expr_K:
3185  case vec_perm_expr_K:
3186  case dot_prod_expr_K:
3187  case ternary_plus_expr_K:
3188  case ternary_pm_expr_K:
3189  case ternary_mp_expr_K:
3190  case ternary_mm_expr_K:
3191  case fshl_expr_K:
3192  case fshr_expr_K:
3193  case lut_expr_K:
3194  case bit_ior_concat_expr_K:
3195  case error_mark_K:
3196  case insertvalue_expr_K:
3197  case insertelement_expr_K:
3198  {
3200  {
3201  PrintTreeManager(false);
3202  }
3203  THROW_UNREACHABLE("Not supported tree node " + tn->get_kind_text());
3204  break;
3205  }
3206  default:
3207  {
3208  THROW_UNREACHABLE("");
3209  }
3210  }
3211  scalar_to_vector[tree_node_index] = return_value;
3212  break;
3213  }
3214  default:
3215  {
3216  THROW_UNREACHABLE("");
3217  }
3218  }
3220  "<--Transformed " + TM->get_tree_node_const(tree_node_index)->get_kind_text() + " " +
3221  STR(tree_node_index) +
3222  ((TM->get_tree_node_const(return_value)->get_kind() != function_decl_K) ?
3223  ": " + TM->get_tree_node_const(return_value)->ToString() :
3224  ""));
3225  return return_value;
3226 }
3227 
3229 {
3230  if(bb_version != 0)
3231  {
3232  return false;
3233  }
3234  if(function_behavior->CGetLoops())
3235  {
3236  for(const auto& loop : function_behavior->CGetLoops()->GetList())
3237  {
3238  if(loop->loop_type & DOALL_LOOP)
3239  {
3240  return true;
3241  }
3242  }
3243  }
3244  return false;
3245 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
tree_nodeRef CreateOrExpr(const tree_nodeConstRef &first_condition, const tree_nodeConstRef &second_condition, const blocRef &block, unsigned int function_decl_nid) const
Create an or expression.
tree_nodeRef ptd
ptd field points to the node for the type pointed to.
Definition: tree_node.hpp:3909
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
Definition: vectorize.cpp:3228
void ClassifyTreeNode(const unsigned int loop_id, const tree_nodeConstRef tree_node)
Classify a statement.
Definition: vectorize.cpp:485
This class contains the methods for vectorize loop or whole function.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
CustomUnorderedMap< unsigned int, CustomUnorderedMapStable< size_t, unsigned int > > scalar_to_scalar
Map between scalar tree node and versioned scalar tree node.
Definition: vectorize.hpp:73
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
Definition: graph.hpp:1312
Basic block control flow graph.
File containing functions and utilities to support the printing of debug messagges.
void SetPredication()
Set predicate of predicated instructions.
Definition: vectorize.cpp:1484
std::string ToString() const
Print this node as string in gimple format.
#define INIT(x, y)
Definition: spider.cpp:73
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
Step successfully executed.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
CustomMap< unsigned int, SimdLoop > simd_loop_type
Loop classification.
Definition: vectorize.hpp:92
string target
Definition: lenet_tvm.py:16
#define GET_CLASS(obj)
Macro returning the actual type of an object.
bool LookForScalar(const tree_nodeConstRef tree_node)
Check recursively if at least an ssa operand is defined an operation outside simd outer loop...
Definition: vectorize.cpp:1052
Definition of the class representing a generic C application.
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
Definition: tree_node.hpp:672
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
DesignFlowStep_Status InternalExec() override
Restructures the unstructured code.
Definition: vectorize.cpp:169
#define COUNTABLE_LOOP
countable loop
Definition: loop.hpp:138
CustomMap< unsigned int, bool > basic_block_divergence
Basic block classification: if value is true, the basic block can be executed or not in parallel inst...
Definition: vectorize.hpp:98
CustomOrderedMap< T, U > CustomMap
Definition: custom_map.hpp:167
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
Definition: graph.hpp:1310
Vectorize(const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const ParameterConstRef parameters)
Constructor.
Definition: vectorize.cpp:111
enum Transformation { NONE, COND_CON, COND_DIV, INC, INIT, SCALAR, SIMD, } Transformation
Enum used to classify the statement according to the required transformation.
Definition: vectorize.hpp:64
A simple interface to token object of the raw files.
void PrintTreeManager(const bool before) const
Dump the tree manager.
Definition of hash function for EdgeDescriptor.
Definition: graph.hpp:1321
size_t num_exits() const
Definition: loop.cpp:161
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...
std::list< vertex >::const_iterator exit_block_iter_begin() const
Definition: loop.cpp:166
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
Abstract pure class for the tree structure.
Definition: tree_node.hpp:139
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.
#define FB_CFG_SELECTOR
Feedback control flow edge selector.
CustomMap< unsigned int, integer_cst_t > iv_increment
The increment of induction variables; id is the index of the ssa name defined in the init gimple...
Definition: vectorize.hpp:82
#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.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
unsigned int DuplicateIncrement(const unsigned int loop_id, const tree_nodeRef statement)
Duplicate increment statement and update uses of defined variable when necessary. ...
Definition: vectorize.cpp:932
APInt integer_cst_t
Definition: panda_types.hpp:47
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
#define CDG_SELECTOR
Control dependence edge selector.
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
CustomUnorderedMapUnstable< unsigned int, unsigned int > scalar_to_vector
Map between scalar tree node and vector tree node.
Definition: vectorize.hpp:70
unsigned int create_tree_node(const tree_nodeRef &tn, int mode=tree_node_dup_mode::DEFAULT)
tree_node visitors
void WriteBBGraphDot(const std::string &filename) const
Write the current version of statement list in dot format.
Basic block dominator tree.
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Definition: tree_node.hpp:146
Classes to describe design flow graph.
Basic block control flow graph with feedback.
#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
static std::string ToString(Transformation transformation)
Header include.
Definition: vectorize.cpp:84
void ClassifyLoop(const LoopConstRef loop, const size_t parallel_degree)
Classify a loop.
Definition: vectorize.cpp:332
#define BB_ENTRY
constant identifying the basic block node of type entry
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
CustomMap< unsigned int, size_t > loop_parallel_degree
Loop parallel degree.
Definition: vectorize.hpp:95
unsigned offset[NUM_VERTICES+1]
Definition: graph.h:3
~Vectorize() override
Destructor.
unsigned int Transform(const unsigned int tree_node_index, const size_t parallel_degree, const size_t scalar_index, std::list< tree_nodeRef > &new_stmt_list, std::vector< tree_nodeRef > &new_phi_list)
Transform a tree node.
Definition: vectorize.cpp:1519
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Definition: graph.hpp:1307
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Basic block control dependence graph.
This file collects some utility functions and macros.
Call graph hierarchy.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
The key comparison function for vertices set based on levels.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
static bool has_omp_simd(const statement_list *sl)
Check if omp simd pragmas are present in given statement list.
Wrapper of design_flow.
struct definition of the pointer_type tree node.
Definition: tree_node.hpp:3896
tree_nodeRef GetBooleanType() const
Function that creates a boolean type if it is not already present, otherwise it returns the one that ...
This struct specifies the block node.
Definition: tree_node.hpp:1820
const tree_manipulationRef tree_man
The tree_manipulation.
Definition: vectorize.hpp:79
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
Definition: APInt.hpp:53
void AddGuards()
Add the guards for predicated operations.
Definition: vectorize.cpp:1117
BBNodeInfoRef GetBBNodeInfo(const vertex node)
Return the info associated with a basic block.
#define BUILTIN_SRCP
CustomMap< unsigned int, tree_nodeRef > guards
The guards for each basic block.
Definition: vectorize.hpp:104
tree_nodeRef create_ternary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const std::string &srcp, enum kind operation_kind) const
Function used to create a ternary expression.
const unsigned int function_id
The index of the function to be analyzed.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
const application_managerRef AppM
The application manager.
vertex GetHeader() const
returns loop header
Definition: loop.cpp:136
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
Class specification of the basic_block structure.
unsigned int size_t
Definition: test.c:1
interface of a loop
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
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.
tree_nodeRef GetUnsignedIntegerType() const
Function that creates a unsigned integer type if it is not already present, otherwise it returns the ...
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: vectorize.cpp:123
interface of loops finding algorithm
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
tree_nodeRef create_ssa_name(const tree_nodeConstRef &var, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, bool volatile_flag=false, bool virtual_flag=false) const
MISCELLANEOUS_OBJ_TREE_NODES.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
tree node duplication class.
Wrapper to call graph.
#define DOALL_LOOP
parallelizable for loop
Definition: loop.hpp:132
absl::node_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMapStable
Definition: custom_map.hpp:152
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
CustomMap< unsigned int, Transformation > transformations
Statement classification.
Definition: vectorize.hpp:101
bool IsReducible() const
tells if the loop is reducible
Definition: loop.cpp:146
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
tree_nodeRef create_gimple_modify_stmt(const tree_nodeRef &op0, const tree_nodeRef &op1, unsigned int function_decl_nid, const std::string &srcp) const
GIMPLE_ASSIGN.
void FixPhis()
Fix the phis to consider implicitly predicated operations.
Definition: vectorize.cpp:1332
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
tree_nodeRef CreateAndExpr(const tree_nodeConstRef &first_condition, const tree_nodeConstRef &second_condition, const blocRef &block, unsigned int function_decl_nid) const
Create an or expression.
#define 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.
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
const tree_managerRef TM
The tree manager.
Definition: vectorize.hpp:76
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

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