76 unsigned int _function_id,
const DesignFlowManagerConstRef _design_flow_manager)
90 switch(relationship_type)
94 relationships.insert(std::make_pair(SWITCH_FIX,
SAME_FUNCTION));
95 relationships.insert(std::make_pair(BLOCK_FIX,
SAME_FUNCTION));
96 relationships.insert(std::make_pair(USE_COUNTING,
SAME_FUNCTION));
100 relationships.insert(std::make_pair(UPDATE_SCHEDULE,
SAME_FUNCTION));
103 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
105 relationships.insert(std::make_pair(BITVALUE_RANGE,
SAME_FUNCTION));
107 relationships.insert(std::make_pair(SHORT_CIRCUIT_TAF,
SAME_FUNCTION));
116 GetPointer<const HLS_manager>(
AppM) and GetPointer<const HLS_manager>(
AppM)->get_HLS(
function_id) and
126 design_flow_graph->CGetDesignFlowStepInfo(update_schedule)->design_flow_step;
127 if(GetPointer<const FunctionFrontendFlowStep>(design_flow_step)->
CGetBBVersion() !=
130 relationships.insert(std::make_pair(UPDATE_SCHEDULE,
SAME_FUNCTION));
140 relationships.insert(std::make_pair(DETERMINE_MEMORY_ACCESSES,
SAME_FUNCTION));
142 relationships.insert(std::make_pair(REMOVE_CLOBBER_GA,
SAME_FUNCTION));
150 return relationships;
156 TM =
AppM->get_tree_manager();
159 const auto fd = GetPointerS<const function_decl>(temp);
160 sl = GetPointerS<statement_list>(
GET_NODE(fd->body));
163 GetPointer<const HLS_manager>(
AppM) and GetPointer<const HLS_manager>(
AppM)->get_HLS(
function_id) and
166 for(
const auto&
block : sl->list_of_bloc)
178 pred_bb->list_of_succ.erase(std::remove(pred_bb->list_of_succ.begin(), pred_bb->list_of_succ.end(), curr_bb->number),
179 pred_bb->list_of_succ.end());
182 for(
const auto succ : curr_bb->list_of_succ)
187 succ_bb->list_of_pred.erase(
188 std::remove(succ_bb->list_of_pred.begin(), succ_bb->list_of_pred.end(), curr_bb->number),
189 succ_bb->list_of_pred.end());
192 if(std::find(succ_bb->list_of_pred.begin(), succ_bb->list_of_pred.end(), pred_bb->number) ==
193 succ_bb->list_of_pred.end())
195 succ_bb->list_of_pred.push_back(pred_bb->number);
199 if(std::find(pred_bb->list_of_succ.begin(), pred_bb->list_of_succ.end(), succ) == pred_bb->list_of_succ.end())
201 pred_bb->list_of_succ.push_back(succ);
205 for(
const auto&
phi : succ_bb->CGetPhiList())
208 auto* current_phi = GetPointerS<gimple_phi>(
GET_NODE(
phi));
209 for(
const auto& def_edge : current_phi->CGetDefEdgesList())
211 if(def_edge.second == curr_bb->number)
232 inverse_vertex_map[
block.first] =
238 const auto& curr_bbi = bb.first;
239 const auto& curr_bb = bb.second;
240 for(
const auto pred : curr_bb->list_of_pred)
242 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map[pred], inverse_vertex_map[curr_bbi],
CFG_SELECTOR);
244 for(
const auto succ : curr_bb->list_of_succ)
248 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map[curr_bbi], inverse_vertex_map[succ],
CFG_SELECTOR);
251 if(curr_bb->list_of_succ.empty())
253 GCC_bb_graphs_collection->AddEdge(inverse_vertex_map[curr_bbi], inverse_vertex_map[
bloc::EXIT_BLOCK_ID],
261 std::list<vertex> bb_sorted_vertices;
263 for(
auto bb : bb_sorted_vertices)
266 const auto& curr_bbi = bb_node_info->block->number;
267 const auto& curr_bb = bb_node_info->block;
270 (!
parameters->IsParameter(
"print-dot-FF") ||
parameters->GetParameter<
unsigned int>(
"print-dot-FF")))
274 if(curr_bbi == bloc::ENTRY_BLOCK_ID || curr_bbi == bloc::EXIT_BLOCK_ID)
279 if(bb_node_info->block->list_of_pred.size() > 1)
284 const auto pred = bb_node_info->block->list_of_pred.front();
285 if(pred == bloc::ENTRY_BLOCK_ID)
292 if(pred_bb->CGetStmtList().empty())
297 const auto last_pred_stmt =
GET_NODE(pred_bb->CGetStmtList().back());
298 if(last_pred_stmt->get_kind() != gimple_cond_K && last_pred_stmt->get_kind() != gimple_multi_way_if_K)
301 "<--Skipped because predecessor ends with " + last_pred_stmt->get_kind_text());
304 if(curr_bb->CGetStmtList().size() != 1)
309 const auto last_curr_stmt =
GET_NODE(curr_bb->CGetStmtList().back());
311 if(last_curr_stmt->get_kind() == gimple_multi_way_if_K)
317 if(last_curr_stmt->get_kind() != gimple_cond_K && last_curr_stmt->get_kind() != gimple_multi_way_if_K)
320 "<--Skipped because it ends with a " + last_curr_stmt->get_kind_text());
323 if(curr_bb->CGetPhiList().size() != 0)
328 if(!
AppM->ApplyNewTransformation())
339 const auto& curr_list_of_succ = curr_bb->list_of_succ;
343 for(
const auto succ_bbi : pred_bb->list_of_succ)
345 if(std::find(curr_list_of_succ.begin(), curr_list_of_succ.end(), succ_bbi) != curr_list_of_succ.end())
348 "---BB" +
STR(succ_bbi) +
" is a common sucessor");
353 (!
parameters->IsParameter(
"print-dot-FF") ||
parameters->GetParameter<
unsigned int>(
"print-dot-FF")))
365 if(last_pred_stmt->get_kind() == gimple_cond_K && last_curr_stmt->get_kind() == gimple_cond_K)
368 "---Merging gimple_cond with gimple_cond (BB" +
STR(curr_bbi) +
" with BB" +
STR(pred) +
")");
371 else if(last_pred_stmt->get_kind() == gimple_cond_K && last_curr_stmt->get_kind() == gimple_multi_way_if_K)
374 "---Merging gimple_cond with gimple_multi_way_if (BB" +
STR(curr_bbi) +
" with BB" +
STR(pred) +
378 else if(last_pred_stmt->get_kind() == gimple_multi_way_if_K &&
379 last_curr_stmt->get_kind() == gimple_multi_way_if_K)
382 "---Merging gimple_multi_way_if with gimple_multi_way_if (BB" +
STR(curr_bbi) +
" with BB" +
389 "---Merging gimple_multi_way_if with gimple_cond (BB" +
STR(curr_bbi) +
" with BB" +
STR(pred) +
395 bb_to_be_removed.insert(curr_bbi);
397 (!
parameters->IsParameter(
"print-dot-FF") ||
parameters->GetParameter<
unsigned int>(
"print-dot-FF")))
404 for(it_tbr = bb_to_be_removed.begin(); it_tbr != it_tbr_end; ++it_tbr)
408 bb_to_be_removed.clear();
417 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
423 new_gwi->bb_index = pred_bb->number;
425 const auto old_gwi = GetPointerS<const gimple_multi_way_if>(
GET_CONST_NODE(curr_bb->CGetStmtList().back()));
431 pred_bb->RemoveStmt(pred_bb->CGetStmtList().back(),
AppM);
434 while(curr_bb->CGetStmtList().size())
436 curr_bb->RemoveStmt(curr_bb->CGetStmtList().front(),
AppM);
440 if(pred_bb->true_edge == curr_bb->number)
442 auto default_bb = 0u;
443 for(
const auto& old_cond : old_gwi->list_of_cond)
448 new_gwi->add_cond(new_cond, old_cond.second);
452 default_bb = old_cond.second;
462 new_gwi->add_cond(ce_cond, pred_bb->true_edge);
463 for(
const auto& old_cond : old_gwi->list_of_cond)
471 new_gwi->add_cond(new_cond, old_cond.second);
475 pred_bb->false_edge = 0;
476 pred_bb->true_edge = 0;
483 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
489 new_gwi->bb_index = pred_bb->number;
491 const auto old_gwi1 = GetPointerS<const gimple_multi_way_if>(
GET_CONST_NODE(pred_bb->CGetStmtList().back()));
492 const auto old_gwi2 = GetPointerS<const gimple_multi_way_if>(
GET_CONST_NODE(curr_bb->CGetStmtList().back()));
497 pred_bb->RemoveStmt(pred_bb->CGetStmtList().back(),
AppM);
500 while(curr_bb->CGetStmtList().size())
502 curr_bb->RemoveStmt(curr_bb->CGetStmtList().front(),
AppM);
505 for(
const auto& old_cond1 : old_gwi1->list_of_cond)
508 "-->Considering condition " + (old_cond1.first ? old_cond1.first->ToString() :
" default"));
510 if(old_cond1.first && old_cond1.second == curr_bb->number)
513 "---It is not default and nested gimple_multi_way_if is on this edge");
514 for(
const auto& old_cond2 : old_gwi2->list_of_cond)
519 new_gwi->add_cond(new_cond, old_cond2.second);
524 for(
const auto& other_old_cond2 : old_gwi2->list_of_cond)
526 if(other_old_cond2.first)
541 new_gwi->add_cond(new_cond, old_cond2.second);
546 else if(old_cond1.first)
549 "---It is not default and nested gimple_multi_way_if is not on this edge");
550 new_gwi->add_cond(old_cond1.first, old_cond1.second);
553 else if(old_cond1.second == curr_bb->number)
556 "---It is default and nested gimple_multi_way_if is on this edge");
559 for(
const auto& other_old_cond1 : old_gwi1->list_of_cond)
561 if(other_old_cond1.first)
575 for(
const auto& old_cond2 : old_gwi2->list_of_cond)
580 new_gwi->add_cond(new_cond, old_cond2.second);
592 "---It is default and nested gimple_multi_way_if is not on this edge");
596 "<--Considered condition " + (old_cond1.first ? old_cond1.first->ToString() :
" default"));
605 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
611 new_gwi->bb_index = pred_bb->number;
613 const auto old_gwi = GetPointerS<const gimple_multi_way_if>(
GET_CONST_NODE(pred_bb->CGetStmtList().back()));
614 const auto old_ce = curr_bb->CGetStmtList().back();
619 pred_bb->RemoveStmt(pred_bb->CGetStmtList().back(),
AppM);
622 while(curr_bb->CGetStmtList().size())
624 curr_bb->RemoveStmt(curr_bb->CGetStmtList().front(),
AppM);
629 for(
const auto& old_cond : old_gwi->list_of_cond)
632 if(old_cond.first && old_cond.second == curr_bb->number)
635 new_gwi->add_cond(true_cond, curr_bb->true_edge);
638 new_gwi->add_cond(false_cond, curr_bb->false_edge);
641 else if(old_cond.first)
643 new_gwi->add_cond(old_cond.first, old_cond.second);
646 else if(old_cond.second == curr_bb->number)
650 for(
const auto& other_old_cond : old_gwi->list_of_cond)
652 if(other_old_cond.first)
667 new_gwi->add_cond(true_cond, curr_bb->true_edge);
683 const auto list_of_stmt_cond1 = pred_bb->CGetStmtList();
685 const auto cond1_statement = list_of_stmt_cond1.back();
686 pred_bb->RemoveStmt(cond1_statement,
AppM);
690 const auto list_of_stmt_cond2 = curr_bb->CGetStmtList();
692 const auto cond2_statement = list_of_stmt_cond2.back();
693 curr_bb->RemoveStmt(cond2_statement,
AppM);
697 std::map<TreeVocabularyTokenTypes_TokenEnum, std::string> IR_schema;
703 const auto gimple_multi_way_if_stmt =
TM->
GetTreeReindex(gimple_multi_way_if_id);
704 auto* gmwi = GetPointerS<gimple_multi_way_if>(
GET_NODE(gimple_multi_way_if_stmt));
705 gmwi->bb_index = pred_bb->number;
706 if(pred_bb->false_edge == curr_bb->number)
708 gmwi->add_cond(ssa1_node, pred_bb->true_edge);
711 gmwi->add_cond(res_and, curr_bb->true_edge);
717 gmwi->add_cond(res_not, pred_bb->false_edge);
719 gmwi->add_cond(res_and2, curr_bb->true_edge);
722 pred_bb->PushBack(gimple_multi_way_if_stmt,
AppM);
723 pred_bb->false_edge = 0;
724 pred_bb->true_edge = 0;
731 const unsigned int new_basic_block_index = (
sl->
list_of_bloc.rbegin())->first + 1;
735 const auto new_block = blocRef(
new bloc(new_basic_block_index));
738 new_block->list_of_pred.push_back(pred_bb->number);
739 new_block->list_of_succ.push_back(succ_bb->number);
740 new_block->loop_id = succ_bb->loop_id;
741 new_block->SetSSAUsesComputed();
742 new_block->schedule = pred_bb->schedule;
745 THROW_ASSERT(std::find(pred_bb->list_of_succ.begin(), pred_bb->list_of_succ.end(), succ_bb->number) !=
746 pred_bb->list_of_succ.end(),
748 pred_bb->list_of_succ.erase(std::remove(pred_bb->list_of_succ.begin(), pred_bb->list_of_succ.end(), succ_bb->number),
749 pred_bb->list_of_succ.end());
750 pred_bb->list_of_succ.push_back(new_basic_block_index);
751 if(pred_bb->true_edge == succ_bb->number)
753 pred_bb->true_edge = new_basic_block_index;
755 if(pred_bb->false_edge == succ_bb->number)
757 pred_bb->false_edge = new_basic_block_index;
761 const auto& pred_list_of_stmt = pred_bb->CGetStmtList();
762 THROW_ASSERT(pred_list_of_stmt.size(),
"Unexpexted condition");
763 const auto pred_last_stmt =
GET_NODE(pred_list_of_stmt.back());
764 if(pred_last_stmt->get_kind() == gimple_multi_way_if_K)
766 auto gmwi = GetPointerS<gimple_multi_way_if>(pred_last_stmt);
767 for(
auto& cond : gmwi->list_of_cond)
769 if(cond.second == succ_bb->number)
771 cond.second = new_basic_block_index;
777 succ_bb->list_of_pred.erase(std::remove(succ_bb->list_of_pred.begin(), succ_bb->list_of_pred.end(), pred_bb->number),
778 succ_bb->list_of_pred.end());
779 succ_bb->list_of_pred.push_back(new_basic_block_index);
782 for(
const auto&
phi : succ_bb->CGetPhiList())
785 for(
auto& def_edge : gp->CGetDefEdgesList())
787 if(def_edge.second == pred_bb->number)
806 if(GetPointer<const HLS_manager>(
AppM) and GetPointer<const HLS_manager>(
AppM)->get_HLS(
function_id) and
816 design_flow_graph->CGetDesignFlowStepInfo(update_schedule)->design_flow_step;
817 if(GetPointer<const FunctionFrontendFlowStep>(design_flow_step)->
CGetBBVersion() !=
840 if(
parameters->getOption<
int>(OPT_gcc_openmp_simd))
842 const auto vectorize_vertex =
848 const auto vectorize_step =
850 if(GetPointer<const FunctionFrontendFlowStep>(vectorize_step)->
CGetBBVersion() == 0)
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
statement_list * sl
The statement list of the analyzed function.
tree_nodeRef CreateNotExpr(const tree_nodeConstRef &condition, const blocRef &block, unsigned int function_decl_nid) const
UTILITY.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
tree_nodeRef ExtractCondition(const tree_nodeRef &condition, const blocRef &block, unsigned int function_decl_nid) const
Extract computation of condition from a gimple_cond.
Data structure representing the entire HLS information.
This struct specifies the field bloc (basic block).
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
multi_way_if(const ParameterConstRef _Param, const application_managerRef _AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
File containing functions and utilities to support the printing of debug messagges.
Step successfully executed.
Definition of the node_info object for the basic_block graph.
void MergeMultiMulti(const blocRef &pred_bb, const blocRef &curr_bb)
Merge two gimple_multi_way_if in a single one.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void MergeCondCond(const blocRef &pred_bb, const blocRef &curr_bb)
Merge two basic blocks both ending with gimple_cond_K.
~multi_way_if() override
Destructor.
void UpdateCfg(const blocRef &pred_bb, const blocRef &curr_bb)
Update the basic block control flow graph data structure.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
std::string GetName() const override
Return the name of this design step.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
bool bb_modified
Modified file.
A simple interface to token object of the raw files.
std::map< unsigned int, blocRef > list_of_bloc
list_of_bloc field is the list of basic block. If this field is null then the list_of_stmt field is n...
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
void MergeCondMulti(const blocRef &pred_bb, const blocRef &curr_bb)
Build the gimple_multi_way_if by mergin a gimple_cond with a gimple_multi_way_if. ...
Data structure describing a basic block at tree level.
redefinition of map to manage ordered/unordered structures
#define TOK(token)
Macro used to convert a token symbol into a treeVocabularyTokenTypes.
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
const tree_nodeRef get_tree_node_const(unsigned int i) const
Return the reference to the i-th tree_node Constant version of get_tree_node.
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.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void FixCfg(const blocRef &pred_bb, const blocRef &succ_bb)
Insert a basic block on an edge.
void MergeMultiCond(const blocRef &pred_bb, const blocRef &curr_bb)
Merge a gimple_cond in a gimple_multi_way_if.
Class used to describe a particular graph with basic blocks as nodes.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Data structure used to store the schedule of the operations.
unsigned int new_tree_node_id(const unsigned int ask=0)
Return a new node id in the intermediate representation.
void cyclic_topological_sort(VertexListGraph &g, OutputIterator result, const boost::bgl_named_params< P, T, R > ¶ms)
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
refcount< BBNodeInfo > BBNodeInfoRef
refcount definition of the class
void WriteBBGraphDot(const std::string &filename) const
Write the current version of statement list in dot format.
Information associated with the whole basic-block graph.
void create_tree_node(const unsigned int node_id, enum kind tree_node_type, std::map< TreeVocabularyTokenTypes_TokenEnum, std::string > &tree_node_schema)
Factory method.
Classes to describe design flow graph.
Target must be reexecuted.
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
redefinition of set to manage ordered/unordered structures
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
Analysis step rebuilding multi-way if.
unsigned int CGetBBVersion() const
#define GET_CONST_NODE(t)
refcount< const tree_node > tree_nodeConstRef
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.
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 struct specifies the block node.
This file collects some utility functions.
tree_manipulationRef tree_man
The tree manipulation.
refcount< T > lock() const
const unsigned int function_id
The index of the function to be analyzed.
tree_managerRef TM
The tree manager.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
File used to compute the topological sort in a cyclic graph.
Class specification of the basic_block structure.
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...
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.
int debug_level
The debug level.
#define CFG_SELECTOR
Control flow graph edge selector.
Data structure definition for high-level synthesis flow.
DesignFlowStep_Status InternalExec() override
Restructures the unstructured code.
refcount< BBGraphInfo > BBGraphInfoRef
refcount definition of the class
#define NULL_VERTEX
null vertex definition
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.
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.
static const std::string ComputeSignature(const FrontendFlowStepType frontend_flow_step_type, const unsigned int function_id)
Compute the signature of a function frontend flow step.
This structure defines graphs where nodes are basic_blocks.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...