77 const DesignFlowManagerConstRef _design_flow_manager,
const ParameterConstRef _parameters)
88 const auto TM =
AppM->get_tree_manager();
90 switch(relationship_type)
94 relationships.insert(std::make_pair(LOOPS_ANALYSIS_BAMBU,
SAME_FUNCTION));
110 return relationships;
126 const auto basic_block_graph_info = basic_block_graph->CGetBBGraphInfo();
127 const auto TM =
AppM->get_tree_manager();
128 if(behavioral_helper->GetOmpForDegree() or behavioral_helper->IsOmpBodyLoop())
133 (!
parameters->IsParameter(
"print-dot-FF") ||
parameters->GetParameter<
unsigned int>(
"print-dot-FF")))
138 bool changed =
false;
140 for(
const auto& loop : loops->GetList())
149 loop->get_recursively_bb(basic_blocks);
150 THROW_ASSERT(basic_blocks.size() >= 1,
"Unexpected pattern");
151 if(basic_blocks.size() == 1)
153 for(
const auto basic_block : basic_blocks)
155 const auto bb_node_info = basic_block_graph->CGetBBNodeInfo(basic_block);
157 "-->Analyzing BB" +
STR(bb_node_info->block->number));
158 if(bb_node_info->block->CGetStmtList().size() == 1)
160 THROW_ERROR(
"BB" +
STR(bb_node_info->block->number) +
" has only one statement");
164 const auto list_of_stmt = bb_node_info->block->CGetStmtList();
165 THROW_ASSERT(list_of_stmt.size() >= 2,
"Unexpected pattern");
166 const auto first_node = list_of_stmt.front();
167 const auto call = GetPointer<const gimple_call>(
GET_NODE(first_node));
170 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
172 auto stmt_it = list_of_stmt.begin();
174 const auto second_node = *stmt_it;
175 const auto ga = GetPointer<const gimple_assign>(
GET_NODE(second_node));
178 THROW_ERROR(
"Second operation of loop body is " + second_node->ToString());
180 const auto pe = GetPointer<const plus_expr>(
GET_NODE(ga->op1));
183 THROW_ERROR(
"Second operation of loop body is " + second_node->ToString());
185 const auto induction_variable = GetPointer<const ssa_name>(
GET_NODE(ga->op0));
187 if(not induction_variable or induction_variable->index != loop->main_iv)
189 THROW_ERROR(
"Induction variable is " + TM->get_tree_node_const(loop->main_iv)->ToString() +
190 " - Second operation of loop body is " + second_node->ToString());
192 const auto call_op = GetPointer<const addr_expr>(
GET_NODE(call->fn));
195 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
197 auto called_function = GetPointer<function_decl>(
GET_NODE(call_op->op));
198 if(not called_function)
200 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
202 called_function->omp_body_loop =
true;
206 if(loops->GetList().size() == 2)
209 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph);
210 basic_block != basic_block_end; basic_block++)
212 const auto basic_block_info = basic_block_graph->CGetBBNodeInfo(*basic_block);
213 if(*basic_block == basic_block_graph_info->entry_vertex or
214 *basic_block == basic_block_graph_info->exit_vertex)
218 if(basic_block_info->loop_id)
222 if(not basic_block_info->block->CGetStmtList().size())
226 if(boost::in_degree(*basic_block, *basic_block_graph) == 1 &&
227 boost::source(*(boost::in_edges(*basic_block, *basic_block_graph).first), *basic_block_graph) ==
228 basic_block_graph_info->entry_vertex)
230 const auto& stm_list = basic_block_info->block->CGetStmtList();
231 if(stm_list.size() != 3)
235 auto stmt_iter = stm_list.begin();
236 const auto ga1 = GetPointer<const gimple_assign>(
GET_NODE(*stmt_iter));
239 THROW_ERROR(
"First statement of pre-loop BB is " + (*stmt_iter)->ToString());
241 const auto nop1 = GetPointer<const nop_expr>(
GET_NODE(ga1->op1));
244 THROW_ERROR(
"First statement of pre-loop BB is " + (*stmt_iter)->ToString());
247 const auto ga2 = GetPointer<const gimple_assign>(
GET_NODE(*stmt_iter));
250 THROW_ERROR(
"Second statement of pre-loop BB is " + (*stmt_iter)->ToString());
252 if(
GET_NODE(ga2->op1)->get_kind() == gt_expr_K)
258 THROW_ERROR(
"Second statement of pre-loop BB is " + (*stmt_iter)->ToString());
261 for(
const auto& statement : basic_block_info->block->CGetStmtList())
263 const auto gr = GetPointer<const gimple_return>(
GET_NODE(statement));
264 if(gr and not gr->op)
271 auto fd = GetPointer<function_decl>(TM->get_tree_node_const(
function_id));
273 fd->omp_for_wrapper =
parameters->getOption<
size_t>(OPT_num_accelerators);
278 if(basic_blocks.size() == 2)
280 for(
const auto basic_block : basic_blocks)
282 if(basic_block == loop->GetHeader())
286 const auto bb_node_info = basic_block_graph->CGetBBNodeInfo(basic_block);
288 "-->Analyzing BB" +
STR(bb_node_info->block->number));
289 const auto list_of_stmt = bb_node_info->block->CGetStmtList();
290 const auto first_node = list_of_stmt.front();
292 if(list_of_stmt.size() == 1)
294 const auto header_node_info = basic_block_graph->CGetBBNodeInfo(loop->GetHeader());
295 const auto header_list_of_stmt = header_node_info->block->CGetStmtList();
296 if(header_list_of_stmt.size() != 3)
298 THROW_ERROR(
"Unexpected pattern in header. Number of operations is " +
299 STR(header_list_of_stmt.size()));
301 auto stmt_it = header_list_of_stmt.begin();
305 else if(list_of_stmt.size() == 2)
307 return list_of_stmt.back();
315 const auto call = GetPointer<const gimple_call>(
GET_NODE(first_node));
318 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
320 const auto ga = GetPointer<const gimple_assign>(
GET_NODE(second_node));
323 THROW_ERROR(
"Second operation of loop body is " + second_node->ToString());
325 const auto pe = GetPointer<const plus_expr>(
GET_NODE(ga->op1));
328 THROW_ERROR(
"Second operation of loop body is " + second_node->ToString());
330 const auto induction_variable = GetPointer<const ssa_name>(
GET_NODE(pe->op0));
332 if(not induction_variable or induction_variable->index != loop->main_iv)
334 THROW_ERROR(
"Induction variable is " + TM->get_tree_node_const(loop->main_iv)->ToString() +
335 " - Second operation of loop body is " + second_node->ToString());
337 const auto call_op = GetPointer<const addr_expr>(
GET_NODE(call->fn));
340 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
342 auto called_function = GetPointer<function_decl>(
GET_NODE(call_op->op));
343 if(not called_function)
345 THROW_ERROR(
"First operation of loop body is " + first_node->ToString());
347 called_function->omp_body_loop =
true;
350 if(loops->GetList().size() == 2)
353 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*basic_block_graph);
354 basic_block != basic_block_end; basic_block++)
356 const auto basic_block_info = basic_block_graph->CGetBBNodeInfo(*basic_block);
357 if(*basic_block == basic_block_graph_info->entry_vertex or
358 *basic_block == basic_block_graph_info->exit_vertex)
362 if(basic_block_info->loop_id)
366 if(not basic_block_info->block->CGetStmtList().size())
370 for(
const auto& statement : basic_block_info->block->CGetStmtList())
372 const auto gr = GetPointer<const gimple_return>(
GET_NODE(statement));
373 if(gr and not gr->op)
380 auto fd = GetPointer<function_decl>(TM->get_tree_node_const(
function_id));
382 fd->omp_for_wrapper =
parameters->getOption<
size_t>(OPT_num_accelerators);
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#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;.
Basic block control flow graph.
File containing functions and utilities to support the printing of debug messagges.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
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.
void PrintTreeManager(const bool before) const
Dump the tree manager.
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...
#define STR(s)
Macro which performs a lexical_cast to a string.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void WriteBBGraphDot(const std::string &filename) const
Write the current version of statement list in dot format.
Classes to describe design flow graph.
Target must be reexecuted.
redefinition of set to manage ordered/unordered structures
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
This file collects some utility functions and macros.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
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.
Class specification of the basic_block structure.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
interface of loops finding algorithm
this class is used to manage the command-line or XML options.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
#define DOALL_LOOP
parallelizable for loop
int debug_level
The debug level.
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.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...