88 #include <boost/range/adaptor/reversed.hpp> 108 #pragma GCC diagnostic ignored "-Woverloaded-virtual" 116 #define MAX_DOUBLE std::numeric_limits<double>::max(); 120 const DesignFlowManagerConstRef _design_flow_manager)
132 switch(relationship_type)
136 relationships.insert(std::make_pair(BB_FEEDBACK_EDGES_IDENTIFICATION,
SAME_FUNCTION));
141 relationships.insert(std::make_pair(PHI_OPT,
SAME_FUNCTION));
142 relationships.insert(std::make_pair(BUILD_VIRTUAL_PHI,
SAME_FUNCTION));
143 relationships.insert(std::make_pair(SIMPLE_CODE_MOTION,
SAME_FUNCTION));
152 relationships.insert(std::make_pair(PHI_OPT,
SAME_FUNCTION));
153 relationships.insert(std::make_pair(SIMPLE_CODE_MOTION,
SAME_FUNCTION));
175 return relationships;
180 if(!
parameters->IsParameter(
"meif_threshold"))
191 const auto design_flow_step = design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step;
192 return GetPointerS<const simple_code_motion>(design_flow_step)->IsScheduleBased();
198 TM =
AppM->get_tree_manager();
201 sl = GetPointerS<statement_list>(
GET_NODE(fd->body));
202 if(GetPointer<const HLS_manager>(
AppM) && GetPointerS<const HLS_manager>(
AppM)->get_HLS(
function_id) &&
203 GetPointerS<const HLS_manager>(
AppM)->get_HLS(
function_id)->allocation_information)
212 const auto threshold =
parameters->GetParameter<
double>(
"meif_threshold");
213 const auto max_iteration_number =
parameters->IsParameter(
"meif_max_iterations_number") ?
214 parameters->GetParameter<
size_t>(
"meif_max_iterations_number") :
217 static size_t executed_iteration = 0;
218 if(executed_iteration >= max_iteration_number)
224 bool modified =
false;
226 std::list<unsigned int> block_to_erase;
234 const auto bb_index_map = bb_cfg->CGetBBGraphInfo()->bb_index_map;
237 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*bb_fcfg); basic_block != basic_block_end;
240 const auto block = bb_cfg->CGetBBNodeInfo(*basic_block)->
block;
242 if(!
AppM->ApplyNewTransformation())
248 if(
block->CGetStmtList().empty())
253 const auto last_stmt =
GET_NODE(
block->CGetStmtList().back());
255 last_stmt->get_kind() != gimple_cond_K && last_stmt->get_kind() != gimple_multi_way_if_K)
260 if(
block->list_of_pred.size() < 2)
265 const bool vdef_op = [&]() ->
bool {
266 for(
const auto& stmt :
block->CGetStmtList())
268 const auto ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(stmt));
269 if(ga && ga->temporary_address)
285 "<--Skipped because there is at least a vdef or a computation of an address");
290 const auto multiplier =
293 static_cast<double>(boost::in_degree(*basic_block, *bb_fcfg) - 1);
294 if(area_weight * multiplier > threshold)
297 "<--Skipped because too large " +
STR(area_weight) +
" * " +
298 STR((static_cast<double>(boost::in_degree(*basic_block, *bb_fcfg)) - 1)) +
299 " to be duplicated");
304 if(boost::in_degree(*basic_block, *bb_cfg) != boost::in_degree(*basic_block, *bb_fcfg))
309 const bool source_feedback =
310 boost::out_degree(*basic_block, *bb_cfg) != boost::out_degree(*basic_block, *bb_fcfg);
315 auto loop_id = bb_cfg->CGetBBNodeInfo(*basic_block)->loop_id;
318 auto depth = loops->CGetLoop(loop_id)->depth;
324 for(boost::tie(to_be_copied_ie, to_be_copied_ie_end) = boost::in_edges(*basic_block, *bb_cfg);
325 to_be_copied_ie != to_be_copied_ie_end; to_be_copied_ie++)
327 const auto source = boost::source(*to_be_copied_ie, *bb_cfg);
328 const auto source_block = bb_cfg->CGetBBNodeInfo(source)->block;
329 const auto source_id = source_block->number;
333 copy_ids[source_id] = new_bb_index;
335 const auto new_block = blocRef(
new bloc(new_bb_index));
336 new_block->loop_id =
block->loop_id;
339 new_block->schedule = GetPointerS<HLS_manager>(
AppM)->get_HLS(
function_id)->Rsch;
341 new_block->SetSSAUsesComputed();
344 std::replace(source_block->list_of_succ.begin(), source_block->list_of_succ.end(),
block->number,
346 if(source_block->true_edge ==
block->number)
348 source_block->true_edge = new_bb_index;
350 else if(source_block->false_edge ==
block->number)
352 source_block->false_edge = new_bb_index;
354 new_block->list_of_pred.push_back(source_id);
355 for(
const auto& succ :
block->list_of_succ)
358 const auto target_id = target_block->number;
359 if(target_block->number !=
BB_EXIT)
361 target_block->list_of_pred.push_back(new_bb_index);
363 new_block->list_of_succ.push_back(target_id);
364 if(
block->true_edge == target_id)
366 new_block->true_edge = target_id;
368 else if(
block->false_edge == target_id)
370 new_block->false_edge = target_id;
373 if(source_block->CGetStmtList().size() &&
374 GetPointer<gimple_multi_way_if>(
GET_NODE(source_block->CGetStmtList().back())))
376 const auto gmwi = GetPointerS<gimple_multi_way_if>(
GET_NODE(source_block->CGetStmtList().back()));
377 for(
auto& cond : gmwi->list_of_cond)
379 if(cond.second ==
block->number)
381 cond.second = new_bb_index;
389 for(boost::tie(oe, oe_end) = boost::out_edges(*basic_block, *bb_fcfg); oe != oe_end; oe++)
392 auto target_block = bb_cfg->CGetBBNodeInfo(
target)->block;
395 for(
const auto&
phi : target_block->CGetPhiList())
400 for(
const auto& def_edge : gp->CGetDefEdgesList())
402 if(def_edge.second ==
block->number)
404 const auto sn = GetPointer<const ssa_name>(
GET_NODE(def_edge.first));
406 GetPointerS<const gimple_node>(
GET_CONST_NODE(sn->CGetDefStmt()))->bb_index !=
block->number)
408 for(
const auto& copy_id : copy_ids)
415 def_edge_list.push_back(def_edge);
420 def_edge_list.push_back(def_edge);
423 gp->SetDefEdgeList(
TM, def_edge_list);
424 gp->SetSSAUsesComputed();
428 if(std::find(target_block->list_of_pred.begin(), target_block->list_of_pred.end(),
block->number) !=
429 target_block->list_of_pred.end())
431 target_block->list_of_pred.erase(
432 std::find(target_block->list_of_pred.begin(), target_block->list_of_pred.end(),
block->number));
438 for(
const auto& copy : copy_ids)
440 tree_node_dups[copy.second] = tree_node_dupRef(
new tree_node_dup(remaps[copy.second],
AppM));
445 std::list<tree_nodeRef> gimples;
446 for(
const auto&
phi :
block->CGetPhiList())
448 gimples.push_back(
phi);
450 for(
const auto& stmt :
block->CGetStmtList())
452 gimples.push_back(stmt);
454 for(
const auto& gimple : gimples)
472 const auto vdef = GetPointer<const gimple_node>(
GET_CONST_NODE(gimple))->vdef;
475 defined_sns.insert(vdef);
480 const auto old_gp = GetPointerS<const gimple_phi>(
GET_CONST_NODE(gimple));
481 defined_sns.insert(old_gp->res);
482 for(
const auto& def_edge : old_gp->CGetDefEdgesList())
485 "Copy BB connected to BB" +
STR(def_edge.second) +
" not found");
486 reaching_defs[copy_ids[def_edge.second]] = def_edge.first;
487 remaps[copy_ids[def_edge.second]][old_gp->res->index] = def_edge.first->index;
492 const auto old_ga = GetPointerS<const gimple_assign>(
GET_CONST_NODE(gimple));
493 if(
GET_NODE(old_ga->op0)->get_kind() == ssa_name_K)
495 defined_sns.insert(old_ga->op0);
498 else if(
GET_CONST_NODE(gimple)->get_kind() == gimple_multi_way_if_K ||
513 const auto ga = GetPointerS<const gimple_assign>(
GET_CONST_NODE(gimple));
515 for(
const auto& ssa_use : ssa_uses)
518 if(GetPointerS<const gimple_node>(
520 ->bb_index ==
block->number)
523 for(
const auto& copy : copy_ids)
525 THROW_ASSERT(remaps.at(copy.second).count(ssa_use.first->index),
STR(ssa_use.first));
531 for(
const auto& copy : copy_ids)
535 const auto ssa0 = GetPointerS<const ssa_name>(
GET_CONST_NODE(ga->op0));
537 remaps[copy.second][ga->op0->index] = new_ssa->
index;
538 reaching_defs[copy.second] = new_ssa;
543 nullptr, GetPointerS<const ssa_name>(
GET_CONST_NODE(ga->vdef))->type,
nullptr,
nullptr);
544 GetPointerS<ssa_name>(
GET_NODE(new_ssa))->virtual_flag =
true;
545 remaps[copy.second][ga->vdef->index] = new_ssa->
index;
546 reaching_defs[copy.second] = new_ssa;
548 const auto new_stmt = tree_node_dups[copy.second]->create_tree_node(
GET_NODE(gimple));
554 else if(
GET_CONST_NODE(gimple)->get_kind() == gimple_multi_way_if_K ||
559 for(
const auto& ssa_use : ssa_uses)
562 for(
const auto& copy : copy_ids)
564 if((GetPointerS<const gimple_node>(
566 ->bb_index !=
block->number))
569 remaps[copy.second][ssa_use.first->index] = ssa_use.first->index;
573 THROW_ASSERT(remaps.at(copy.second).count(ssa_use.first->index),
STR(ssa_use.first));
578 for(
const auto& copy : copy_ids)
580 const auto new_stmt = tree_node_dups[copy.second]->create_tree_node(
GET_NODE(gimple));
590 for(
const auto& defined_sn : defined_sns)
592 const auto sn = GetPointerS<ssa_name>(
GET_NODE(defined_sn));
596 for(
const auto& use_stmt : sn->CGetUseStmts())
599 "-->Considering use in " +
STR(use_stmt.first->index) +
" " +
STR(use_stmt.first));
600 const auto use_bb_index = GetPointerS<const gimple_node>(
GET_CONST_NODE(use_stmt.first))->bb_index;
601 if(bb_index_map.find(use_bb_index) == bb_index_map.end())
604 const auto gn = GetPointerS<gimple_node>(
GET_NODE(use_stmt.first));
605 THROW_ASSERT(gn->vovers.find(defined_sn) == gn->vovers.end(),
"vovers not handled");
606 THROW_ASSERT(gn->vuses.find(defined_sn) != gn->vuses.end(),
"vuse not found");
607 gn->vuses.erase(defined_sn);
608 uses_to_be_removed.insert(use_stmt.first);
612 const auto& use_bb = bb_index_map.at(use_bb_index);
614 use_stmts.insert(use_stmt.first);
615 use_bbs.insert(use_bb);
617 auto use_loop_id = bb_cfg->CGetBBNodeInfo(use_bb)->loop_id;
618 auto use_depth = loops->CGetLoop(use_loop_id)->depth;
621 if(sn->virtual_flag &&
GET_NODE(use_stmt.first)->get_kind() != gimple_phi_K &&
624 const auto gn = GetPointerS<gimple_node>(
GET_NODE(use_stmt.first));
625 THROW_ASSERT(gn->vovers.find(defined_sn) == gn->vovers.end(),
"vovers not handled");
626 THROW_ASSERT(gn->vuses.find(defined_sn) != gn->vuses.end(),
"vuse not found");
627 gn->vuses.erase(defined_sn);
628 uses_to_be_removed.insert(use_stmt.first);
630 "---Removing " +
STR(defined_sn) +
" from vuses of " + gn->ToString());
631 for(
const auto& copy : copy_ids)
635 const auto vssa = GetPointerS<ssa_name>(
TM->
GetTreeNode(remaps[copy.second][sn->index]));
636 vssa->AddUseStmt(use_stmt.first);
641 if(use_loop_id == loop_id)
648 "---Current loop is " +
STR(loop_id) +
" (depth is " +
STR(depth) +
") - Use loop is " +
649 STR(use_loop_id) +
" (depth " +
STR(use_depth) +
")");
651 while(use_depth > depth)
653 use_loop_id = loops->CGetLoop(use_loop_id)->Parent()->GetId();
654 use_depth = loops->CGetLoop(use_loop_id)->depth;
657 while(use_depth < depth)
659 loop_id = loops->CGetLoop(loop_id)->Parent()->GetId();
660 depth = loops->CGetLoop(loop_id)->depth;
662 while(use_loop_id != loop_id)
664 use_loop_id = loops->CGetLoop(use_loop_id)->Parent()->GetId();
665 loop_id = loops->CGetLoop(loop_id)->Parent()->GetId();
666 depth = loops->CGetLoop(loop_id)->depth;
669 "<--Loop to be considered updated to " +
STR(loop_id));
671 for(
const auto& use_to_be_removed : uses_to_be_removed)
673 sn->RemoveUse(use_to_be_removed);
679 auto current_loop = loops->CGetLoop(bb_cfg->CGetBBNodeInfo(*basic_block)->loop_id);
680 while(current_loop->GetId() != loop_id)
682 phi_headers.insert(current_loop->GetHeader());
684 "---Phi has to be added in header of loop " +
STR(current_loop->GetId()));
685 current_loop = current_loop->Parent();
687 phi_headers.insert(current_loop->GetHeader());
689 "---Phi has to be added in header of loop " +
STR(current_loop->GetId()));
693 loops->CGetLoop(loop_id)->get_recursively_bb(loop_basic_blocks);
695 if(use_bbs.find(loops->CGetLoop(loop_id)->GetHeader()) == use_bbs.end())
700 for(
const auto current : loop_basic_blocks)
703 "---Considering BB" +
STR(bb_cfg->CGetBBNodeInfo(current)->block->number));
704 bool reachable =
false;
705 for(
const auto use_bb : use_bbs)
710 "---BB" +
STR(bb_cfg->CGetBBNodeInfo(use_bb)->block->number) +
711 " can be reached from BB" +
712 STR(bb_cfg->CGetBBNodeInfo(current)->block->number));
716 else if(current == use_bb)
719 "---BB" +
STR(bb_cfg->CGetBBNodeInfo(use_bb)->block->number) +
727 to_be_removed.insert(current);
730 for(
const auto removable : to_be_removed)
733 "---Removing BB" +
STR(bb_cfg->CGetBBNodeInfo(removable)->block->number));
734 loop_basic_blocks.erase(removable);
739 std::set<vertex, bb_vertex_order_by_map> to_be_processed(
742 for(boost::tie(oe_basic_block, oe_basic_block_end) = boost::out_edges(*basic_block, *bb_cfg);
743 oe_basic_block != oe_basic_block_end; oe_basic_block++)
746 if(loop_basic_blocks.find(
target) != loop_basic_blocks.end())
748 to_be_processed.insert(
target);
752 while(to_be_processed.size())
754 const auto current = *(to_be_processed.begin());
755 const auto current_id = bb_cfg->CGetBBNodeInfo(current)->block->number;
757 to_be_processed.erase(current);
762 if(current_block->list_of_pred.size() == 1)
765 const auto source_id = current_block->list_of_pred.front();
766 if(reaching_defs.find(current_id) == reaching_defs.end() &&
767 reaching_defs.find(source_id) != reaching_defs.end())
769 reaching_defs[current_id] = reaching_defs[source_id];
774 bool build_phi =
true;
778 for(boost::tie(ie, ie_end) = boost::in_edges(current, *bb_fcfg); ie != ie_end; ie++)
780 const auto source = boost::source(*ie, *bb_fcfg);
781 const auto source_id = bb_fcfg->CGetBBNodeInfo(source)->block->number;
785 "---Skipping feedback edge coming from BB" +
STR(source_id));
787 else if(source_id ==
block->number)
789 for(
const auto& copy_id : copy_ids)
791 THROW_ASSERT(reaching_defs.find(copy_id.second) != reaching_defs.end(),
792 "Definition coming from BB" +
STR(copy_id.second) +
" not found");
794 "---" +
STR(reaching_defs.find(copy_id.second)->second) +
" from BB" +
795 STR(copy_id.second));
796 local_reaching_defs.insert(reaching_defs.find(copy_id.second)->second);
799 else if(reaching_defs.find(source_id) != reaching_defs.end())
802 "---" +
STR(reaching_defs.find(source_id)->second) +
" from BB" +
804 local_reaching_defs.insert(reaching_defs[source_id]);
809 "---Nothing comes from BB" +
STR(source_id));
815 if(local_reaching_defs.size() == 1)
818 reaching_defs[current_id] = *(local_reaching_defs.begin());
824 std::vector<gimple_phi::DefEdge> def_edges;
825 for(boost::tie(ie, ie_end) = boost::in_edges(current, *bb_fcfg); ie != ie_end; ie++)
827 const auto source = boost::source(*ie, *bb_fcfg);
828 const auto source_id = bb_fcfg->CGetBBNodeInfo(source)->block->number;
829 if(source_id ==
block->number)
831 for(
const auto& copy_id : copy_ids)
833 THROW_ASSERT(reaching_defs.find(copy_id.second) != reaching_defs.end(),
"");
834 THROW_ASSERT(reaching_defs.find(copy_id.second)->second,
"");
843 THROW_ASSERT(reaching_defs.find(source_id) != reaching_defs.end(),
"");
844 THROW_ASSERT(reaching_defs.find(source_id)->second,
"");
849 THROW_ASSERT(bb_fcfg->CGetBBNodeInfo(current)->loop_id ==
850 bb_fcfg->CGetBBNodeInfo(current)->block->number,
857 const auto phi_gimple_stmt =
862 auto new_gp = GetPointerS<gimple_phi>(
GET_NODE(phi_gimple_stmt));
863 new_gp->SetSSAUsesComputed();
867 bb_cfg->GetBBNodeInfo(current)->block->AddPhi(phi_gimple_stmt);
868 reaching_defs[current_id] = phi_def_ssa_node;
869 added_phis[current] = phi_gimple_stmt;
873 for(
const auto& local_phi : bb_cfg->CGetBBNodeInfo(current)->block->CGetPhiList())
881 auto local_gp = GetPointerS<gimple_phi>(
GET_NODE(local_phi));
882 for(
const auto& def_edge : local_gp->CGetDefEdgesList())
885 "---" +
STR(def_edge.first) +
" comes from BB" +
STR(def_edge.second));
886 if(def_edge.first->index == sn->index)
888 if(def_edge.second ==
block->number)
890 for(
const auto& copy_id : copy_ids)
892 const auto new_source_id = copy_id.second;
893 THROW_ASSERT(reaching_defs.find(new_source_id) != reaching_defs.end(),
894 "Defintion coming from " +
STR(new_source_id) +
" not found");
895 new_def_edge_list.push_back(
901 THROW_ASSERT(reaching_defs.find(def_edge.second) != reaching_defs.end(),
902 "Defintion coming from " +
STR(def_edge.second) +
" not found");
903 new_def_edge_list.push_back(
909 new_def_edge_list.push_back(def_edge);
912 local_gp->SetDefEdgeList(
TM, new_def_edge_list);
914 "<--Transformed in " + local_gp->ToString());
919 if(use_bbs.find(current) != use_bbs.end())
922 for(
const auto& stmt : bb_cfg->CGetBBNodeInfo(current)->block->CGetStmtList())
924 if(use_stmts.find(stmt) != use_stmts.end())
927 "---Replacing " +
STR(sn) +
" with " +
STR(reaching_defs[current_id]) +
" in " +
936 for(boost::tie(oe, oe_end) = boost::out_edges(current, *bb_fcfg); oe != oe_end; oe++)
939 if(loop_basic_blocks.find(
target) != loop_basic_blocks.end())
942 "---Considering BB" +
STR(bb_fcfg->CGetBBNodeInfo(
target)->block->number));
946 for(
const auto& target_phi : bb_fcfg->CGetBBNodeInfo(
target)->block->CGetPhiList())
949 auto gp = GetPointerS<gimple_phi>(
GET_NODE(target_phi));
950 for(
const auto& def_edge : gp->CGetDefEdgesList())
952 if(def_edge.first->index == sn->index && def_edge.second == current_id)
954 THROW_ASSERT(reaching_defs.find(current_id) != reaching_defs.end(),
"");
965 to_be_processed.insert(
target);
971 "<--Checked BB" +
STR(bb_cfg->CGetBBNodeInfo(current)->block->number));
981 "-->Duplicating BB is source of feeback edges - Fixing header phis");
982 for(boost::tie(oe, oe_end) = boost::out_edges(*basic_block, *bb_fcfg); oe != oe_end; oe++)
987 const auto& header_bb_node_info = bb_fcfg->CGetBBNodeInfo(header)->block;
989 "BB" +
STR(header_bb_node_info->number) +
" is the header");
990 for(
const auto&
phi : header_bb_node_info->CGetPhiList())
994 const auto old_def_edge_list = gp->CGetDefEdgesList();
996 for(
const auto& old_def_edge : old_def_edge_list)
998 if(old_def_edge.second !=
block->number)
1000 new_def_edge_list.push_back(old_def_edge);
1004 for(
const auto& copy : copy_ids)
1006 THROW_ASSERT(remaps.find(copy.second) != remaps.end(),
STR(copy.second));
1007 THROW_ASSERT(remaps.find(copy.second)->second.find(old_def_edge.first->index) !=
1008 remaps.find(copy.second)->second.end(),
1009 STR(old_def_edge.first->index) +
" " +
1012 TM->
GetTreeReindex(remaps[copy.second][old_def_edge.first->index]), copy.second));
1016 gp->SetDefEdgeList(
TM, new_def_edge_list);
1022 "<--Duplicated BB is source of feeback edges - Fixing header phis");
1024 while(
block->CGetStmtList().size())
1028 while(
block->CGetPhiList().size())
1030 block->RemovePhi(
block->CGetPhiList().front());
1034 executed_iteration++;
1043 "-->starting erasing blocks " +
STR(block_to_erase.size()));
1046 while(!block_to_erase.empty())
1049 block_to_erase.pop_back();
1060 double ret_value = 0.0;
1061 for(
const auto& temp_stmt : list_of_stmt)
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
MultipleEntryIfReduction(const ParameterConstRef _Param, const application_managerRef _AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
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;.
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
Basic block control flow graph.
File containing functions and utilities to support the printing of debug messagges.
Step successfully executed.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void ReplaceTreeNode(const tree_nodeRef &stmt, const tree_nodeRef &old_node, const tree_nodeRef &new_node)
Replace the occurrences of tree node old_node with new_node in statement identified by tn...
#define BB_EXIT
constant identifying the basic block node of type exit
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.
Step successfully executed but without any IR change.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
std::list< DefEdge > DefEdgeList
The type of the def edge list.
CustomOrderedMap< T, U > CustomMap
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
A simple interface to token object of the raw files.
Class performing the reduction of n input - m output BB by duplicating the BB over all its predecesso...
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...
tree_manipulationRef tree_man
The tree manipulation.
Data structure describing a basic block at tree level.
bool bb_modified
Modified file.
redefinition of map to manage ordered/unordered structures
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.
#define FB_CFG_SELECTOR
Feedback control flow edge selector.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
REF_FORWARD_DECL(tree_node_dup)
Header include.
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...
Classes to describe design flow graph.
Basic block control flow graph with feedback.
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.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define GET_CONST_NODE(t)
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
Classes specification of the tree_node data structures.
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.
The key comparison function for vertices set based on levels.
This struct specifies the block node.
This file collects some utility functions.
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
refcount< T > lock() const
tree_managerRef TM
The tree manager.
const unsigned int function_id
The index of the function to be analyzed.
Analysis step that performs some simple code motions over the IR.
~MultipleEntryIfReduction() override
Destructor.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
Class specification of the basic_block structure.
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.
AllocationInformationConstRef allocation_information
The allocation information.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
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.
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.
tree node duplication class.
statement_list * sl
The statement list.
int debug_level
The debug level.
block(unsigned int i)
constructor
double GetAreaCost(const std::list< tree_nodeRef > &list_of_stmt) const
Estimate the area cost of the statements of a basic block.
tree_nodeRef create_phi_node(tree_nodeRef &ssa_res, const std::vector< std::pair< tree_nodeRef, unsigned int >> &list_of_def_edge, unsigned int function_decl_nid, bool virtual_flag=false) const
GIMPLE_PHI.
Data structure definition for high-level synthesis flow.
static void ComputeSsaUses(const tree_nodeRef &, TreeNodeMap< size_t > &uses)
recursively compute the references to the ssa_name variables used in a statement
Step is symbolic and it has already been marked.
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.
A brief description of the C++ Header File.
DesignFlowStep_Status InternalExec() override
Extract patterns from the IR.
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.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...