PandA-2024.02
extract_patterns.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  */
33 
45 #include "extract_patterns.hpp"
46 
47 #include "Parameter.hpp"
48 #include "application_manager.hpp"
49 #include "behavioral_helper.hpp"
50 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
51 #include "function_behavior.hpp"
52 #include "hls_device.hpp"
53 #include "hls_manager.hpp"
54 #include "string_manipulation.hpp" // for GET_CLASS
55 #include "tree_basic_block.hpp"
56 #include "tree_helper.hpp"
57 #include "tree_manager.hpp"
58 #include "tree_manipulation.hpp"
59 #include "tree_reindex.hpp"
60 #include <cmath>
61 #include <fstream>
62 #include <string>
63 
65  unsigned int _function_id, const DesignFlowManagerConstRef _design_flow_manager)
66  : FunctionFrontendFlowStep(_AppM, _function_id, EXTRACT_PATTERNS, _design_flow_manager, _parameters)
67 {
68  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
69 }
70 
72 
75 {
77  switch(relationship_type)
78  {
80  {
81  relationships.insert(std::make_pair(USE_COUNTING, SAME_FUNCTION));
82  break;
83  }
85  {
86 #if HAVE_ILP_BUILT
87  relationships.insert(std::make_pair(SDC_CODE_MOTION, SAME_FUNCTION));
88 #endif
89  break;
90  }
92  {
93  break;
94  }
95  default:
97  }
98  return relationships;
99 }
100 
101 static kind ternary_operation_type0(kind operation_kind1, kind operation_kind2)
102 {
103  if(operation_kind1 == plus_expr_K && operation_kind2 == plus_expr_K)
104  {
105  return ternary_plus_expr_K;
106  }
107  else if(operation_kind1 == plus_expr_K && operation_kind2 == minus_expr_K)
108  {
109  return ternary_pm_expr_K;
110  }
111  else if(operation_kind1 == minus_expr_K && operation_kind2 == plus_expr_K)
112  {
113  return ternary_mp_expr_K;
114  }
115  else
116  { // if(operation_kind1 == minus_expr_K && operation_kind2 == minus_expr_K)
117  return ternary_mm_expr_K;
118  }
119 }
120 
121 static kind ternary_operation_type1(kind operation_kind1, kind operation_kind2)
122 {
123  if(operation_kind1 == plus_expr_K && operation_kind2 == plus_expr_K)
124  {
125  return ternary_plus_expr_K;
126  }
127  else if(operation_kind1 == plus_expr_K && operation_kind2 == minus_expr_K)
128  {
129  return ternary_mm_expr_K;
130  }
131  else if(operation_kind1 == minus_expr_K && operation_kind2 == plus_expr_K)
132  {
133  return ternary_pm_expr_K;
134  }
135  else
136  { // if(operation_kind1 == minus_expr_K && operation_kind2 == minus_expr_K)
137  return ternary_mp_expr_K;
138  }
139 }
140 
142 {
143  if(parameters->IsParameter("disable-extract-patterns") &&
144  parameters->GetParameter<unsigned int>("disable-extract-patterns") == 1)
145  {
147  }
148  const auto hls_d = GetPointer<const HLS_manager>(AppM)->get_HLS_device();
149  if(hls_d->has_parameter("disable_extract_ternary_patterns") &&
150  hls_d->get_parameter<unsigned>("disable_extract_ternary_patterns"))
151  {
155  }
156  PRINT_DBG_MEX(DEBUG_LEVEL_PEDANTIC, debug_level, " --------- EXTRACT_PATTERNS ---------- ");
157  const auto TM = AppM->get_tree_manager();
158  const auto tn = TM->CGetTreeNode(function_id);
159  // tree_nodeRef Scpe = TM->GetTreeReindex(function_id);
160  const auto fd = GetPointer<const function_decl>(tn);
161  THROW_ASSERT(fd && fd->body, "Node is not a function or it hasn't a body");
162  auto sl = GetPointer<statement_list>(GET_NODE(fd->body));
163  THROW_ASSERT(sl, "Body is not a statement_list");
164 
166  bool modified = false;
167  for(const auto& bb_pair : sl->list_of_bloc)
168  {
169  const auto& B = bb_pair.second;
170  const auto& B_id = B->number;
171  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Examining BB" + STR(B_id));
172  const auto list_of_stmt = B->CGetStmtList();
174  auto it_los = list_of_stmt.begin();
175  auto it_los_end = list_of_stmt.end();
176  while(it_los != it_los_end)
177  {
178  if(!AppM->ApplyNewTransformation())
179  {
180  break;
181  }
183  "-->Examining statement " + GET_CONST_NODE(*it_los)->ToString());
184  if(GET_CONST_NODE(*it_los)->get_kind() == gimple_assign_K)
185  {
186  const auto ga = GetPointerS<const gimple_assign>(GET_CONST_NODE(*it_los));
187  const auto code0 = GET_CONST_NODE(ga->op0)->get_kind();
188  const auto code1 = GET_CONST_NODE(ga->op1)->get_kind();
189  if(code0 == ssa_name_K && (code1 == plus_expr_K || code1 == minus_expr_K))
190  {
191  if(!(tree_helper::IsRealType(ga->op0) || tree_helper::IsComplexType(ga->op0) ||
192  tree_helper::IsVectorType(ga->op0)))
193  {
194  const auto ssa_defined = GetPointerS<const ssa_name>(GET_CONST_NODE(ga->op0));
195  const auto ssa_defined_size = tree_helper::Size(tree_helper::CGetType(ga->op0));
196  const auto binop0 = GetPointerS<const binary_expr>(GET_CONST_NODE(ga->op1));
197  if((ssa_defined->CGetNumberUses() == 1) &&
198  (ssa_defined_size == tree_helper::Size(tree_helper::CGetType(binop0->op0))) &&
199  (ssa_defined_size == tree_helper::Size(tree_helper::CGetType(binop0->op1))))
200  {
201  const auto statement_node = ssa_defined->CGetUseStmts().begin()->first;
202  if(GET_CONST_NODE(statement_node)->get_kind() == gimple_assign_K)
203  {
204  auto ga_dest = GetPointerS<gimple_assign>(GET_NODE(statement_node));
205  const auto code_dest0 = GET_CONST_NODE(ga_dest->op0)->get_kind();
206  const auto code_dest1 = GET_CONST_NODE(ga_dest->op1)->get_kind();
207  const auto ssa_dest0_size = tree_helper::Size(tree_helper::CGetType(ga_dest->op0));
208  if(code_dest0 == ssa_name_K && (code_dest1 == plus_expr_K || code_dest1 == minus_expr_K) &&
209  ga_dest->bb_index == B_id && ssa_dest0_size == ssa_defined_size)
210  {
214  "---Ternary plus expr statement found ");
215  const auto srcp_default = ga_dest->include_name + ":" + STR(ga_dest->line_number) + ":" +
216  STR(ga_dest->column_number);
217  const auto binop_dest = GetPointerS<const binary_expr>(GET_CONST_NODE(ga_dest->op1));
218  if(GET_INDEX_CONST_NODE(ga->op0) == GET_INDEX_CONST_NODE(binop_dest->op0))
219  {
220  const auto ternary_op = IRman->create_ternary_operation(
221  binop_dest->type, binop0->op0, binop0->op1, binop_dest->op1, srcp_default,
222  ternary_operation_type0(code1, code_dest1));
223  TM->ReplaceTreeNode(statement_node, ga_dest->op1, ternary_op);
224  }
225  else
226  {
227  const auto ternary_op = IRman->create_ternary_operation(
228  binop_dest->type, binop_dest->op0, binop0->op0, binop0->op1, srcp_default,
229  ternary_operation_type1(code1, code_dest1));
230  TM->ReplaceTreeNode(statement_node, ga_dest->op1, ternary_op);
231  }
233  "<--Statement removed " + GET_NODE(*it_los)->ToString());
234  B->RemoveStmt(*it_los, AppM);
235  it_los = list_of_stmt.begin();
236  it_los_end = list_of_stmt.end();
237  AppM->RegisterTransformation(GetName(), statement_node);
238  modified = true;
239  continue;
240  }
241  }
242  }
243  }
244  }
245  }
247  "<--Statement analyzed " + GET_CONST_NODE(*it_los)->ToString());
248  ++it_los;
249  }
250  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Examined BB" + STR(B_id));
251  }
252 
253  if(modified)
254  {
255  function_behavior->UpdateBBVersion();
256  }
258 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
Data structure representing the entire HLS information.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
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.
Step successfully executed.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Definition of the class representing a generic C application.
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
static kind ternary_operation_type1(kind operation_kind1, kind operation_kind2)
static kind ternary_operation_type0(kind operation_kind1, kind operation_kind2)
Data structure describing a basic block at tree level.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
~extract_patterns() override
Destructor.
DesignFlowStep_Status InternalExec() override
Extract patterns from the GCC/CLANG IR.
kind
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
This file collects some utility functions.
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.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
extract_patterns(const ParameterConstRef _Param, const application_managerRef _AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
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.
Class extracting patterns extending the GCC/CLANG IR.
this class is used to manage the command-line or XML options.
int debug_level
The debug level.
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
#define B
Definition: generate.c:14
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
HLS specialization of generic_device.
A brief description of the C++ Header File.
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
int sl
Definition: adpcm.c:105
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

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