60 #include "config_HAVE_PRAGMA_BUILT.hpp" 63 unsigned int _function_id,
const DesignFlowManagerConstRef _design_flow_manager)
75 switch(relationship_type)
79 relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION,
SAME_FUNCTION));
80 relationships.insert(std::make_pair(LOOPS_COMPUTATION,
SAME_FUNCTION));
81 relationships.insert(std::make_pair(EXTRACT_GIMPLE_COND_OP,
SAME_FUNCTION));
86 relationships.insert(std::make_pair(SERIALIZE_MUTUAL_EXCLUSIONS,
SAME_FUNCTION));
96 relationships.insert(std::make_pair(SIMPLE_CODE_MOTION,
SAME_FUNCTION));
104 return relationships;
109 const auto TM =
AppM->get_tree_manager();
116 if(!loop->IsReducible())
121 const vertex header = loop->GetHeader();
122 #if HAVE_PRAGMA_BUILT 123 const auto PM =
AppM->get_pragma_manager();
130 const auto nexit = loop->num_exits();
138 const auto exit_vertex = *loop->exit_block_iter_begin();
139 bool do_while =
false;
140 if(exit_vertex == header && loop->num_blocks() != 1)
154 const tree_nodeRef last_stmt =
GET_NODE(fbb->CGetBBNodeInfo(exit_vertex)->block->CGetStmtList().back());
155 if(last_stmt->
get_kind() != gimple_cond_K)
160 const auto SPBE = loop->get_sp_back_edges();
167 const auto sourceSPBE1 = SPBE.begin()->first;
168 const unsigned int sourceSPBE1_index = fbb->CGetBBNodeInfo(sourceSPBE1)->block->number;
171 boost::tie(e, found) = boost::edge(sourceSPBE1, SPBE.begin()->second, *fbb);
173 const auto op =
GET_NODE(GetPointerS<const gimple_cond>(last_stmt)->op0);
175 "---Condition operand (" + op->get_kind_text() +
") is " + op->ToString());
176 const auto cond_sn = GetPointer<const ssa_name>(op);
182 const auto cond_defs = cond_sn->CGetDefStmts();
183 if(cond_defs.size() != 1)
186 "<--Condition variable is not defined in a single statement");
189 const auto cond_def =
GET_NODE(*(cond_defs.begin()));
190 if(cond_def->get_kind() != gimple_assign_K)
195 const auto cond =
GET_NODE(GetPointer<const gimple_assign>(cond_def)->op1);
197 if(cond->get_kind() != eq_expr_K && cond->get_kind() != ge_expr_K && cond->get_kind() != gt_expr_K &&
198 cond->get_kind() != le_expr_K && cond->get_kind() != lt_expr_K && cond->get_kind() != ne_expr_K &&
199 cond->get_kind() != uneq_expr_K and cond->get_kind() != ungt_expr_K && cond->get_kind() != unge_expr_K &&
200 cond->get_kind() != unle_expr_K && cond->get_kind() != unlt_expr_K)
206 const auto cond_be = GetPointerS<const binary_expr>(cond);
207 const auto first_operand =
GET_NODE(cond_be->op0);
209 if(first_operand->get_kind() != ssa_name_K)
214 const auto sn = GetPointerS<const ssa_name>(first_operand);
216 const auto defs = sn->CGetDefStmts();
224 const auto temp_def =
GET_NODE(*(defs.begin()));
229 const auto gp = GetPointer<const gimple_phi>(temp_def);
234 for(
const auto& def_edge : gp->CGetDefEdgesList())
236 if(def_edge.second == sourceSPBE1_index)
238 const auto temp_sn = GetPointer<const ssa_name>(
GET_NODE(def_edge.first));
243 return GET_NODE(temp_sn->CGetDefStmt());
253 if(def->get_kind() != gimple_assign_K)
256 "<--Induction variable is assigned in " + def->ToString());
260 const auto ga = GetPointerS<const gimple_assign>(def);
261 if(
GET_NODE(ga->op1)->get_kind() != plus_expr_K &&
GET_NODE(ga->op1)->get_kind() != minus_expr_K)
264 "<--Induction variable is not incremented or decremented");
267 const auto be = GetPointerS<const binary_expr>(
GET_NODE(ga->op1));
268 if(
GET_NODE(be->op1)->get_kind() != integer_cst_K)
271 "<--Induction variable is not incremented or decremented by a constant");
274 const auto second_induction_variable =
GET_NODE(be->op0);
275 if(second_induction_variable->get_kind() != ssa_name_K)
280 const auto defs2 = GetPointerS<const ssa_name>(second_induction_variable)->CGetDefStmts();
281 if(defs2.size() != 1)
286 const auto def2 =
GET_NODE(*(defs2.begin()));
287 if(def2->get_kind() != gimple_phi_K)
292 const auto gp = GetPointerS<const gimple_phi>(def2);
293 if(gp->CGetDefEdgesList().size() != 2)
300 for(
const auto& def_edge : gp->CGetDefEdgesList())
303 "---" + def_edge.first->ToString() +
" comes from " +
STR(def_edge.second));
304 if(def_edge.second != sourceSPBE1_index)
306 return def_edge.first;
311 loop->main_iv = first_operand->index;
313 loop->init_gimple_id = def2->index;
314 loop->inc_id = ga->index;
315 if(
GET_NODE(be->op1)->get_kind() == integer_cst_K)
318 if(be->get_kind() == minus_expr_K)
320 loop->increment = -loop->increment;
323 loop->upper_bound_tn = cond_be->op1;
324 loop->increment_tn = be->op1;
326 "---Comparison is " +
STR(cond) +
" (" + cond->get_kind_text() +
")");
327 if(
GET_NODE(init)->get_kind() == integer_cst_K &&
GET_NODE(cond_be->op1)->get_kind() == integer_cst_K)
329 const auto cond_type = cond_be->get_kind();
332 if(cond_type == ge_expr_K || cond_type == le_expr_K || cond_type == unge_expr_K || cond_type == unle_expr_K)
335 loop->close_interval =
true;
345 "---Increment " +
GET_NODE(loop->increment_tn)->ToString());
347 if(do_while && loop->is_innermost() && loop->num_blocks() == 1)
355 if(
parameters->getOption<
bool>(OPT_print_dot))
#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.
DesignFlowStep_Status InternalExec() override
Performs the loops analysis.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
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.
#define PIPELINABLE_LOOP
pipelinable loop
RelationshipType
The relationship type.
Source must be executed to satisfy target.
#define COUNTABLE_LOOP
countable loop
Data structure describing a basic block at tree level.
#define UNKNOWN_LOOP
unknown loop
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 WHILE_LOOP
while or for loop
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
LoopsAnalysisBambu(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
Manager for pragma annotations.
Basic block control flow graph with feedback.
Target must be reexecuted.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
static bool has_omp_simd(const statement_list *sl)
Check if omp simd pragmas are present in given statement list.
~LoopsAnalysisBambu() override
Destructor.
This file collects some utility functions.
void init(int bucket[BUCKETSIZE])
const unsigned int function_id
The index of the function to be analyzed.
#define DO_WHILE_LOOP
do while loop
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
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
Class specification of the manager of the tree structures extracted from the raw file.
#define SINGLE_EXIT_LOOP
loop with single exit
A brief description of the C++ Header File.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
boost::graph_traits< graph >::edge_descriptor EdgeDescriptor
edge definition.