95 :
std::pair<unsigned int, ControlStep>(basic_block_index, control_step)
103 if(this->second != other.second)
105 return this->second < other.second;
107 return this->first < other.first;
112 : hls_manager(_hls_manager),
113 TM(_hls_manager->get_tree_manager()),
115 allocation_information(_hls_manager->get_HLS(_function_index)->allocation_information),
116 function_index(_function_index),
120 debug_level(_parameters->get_class_debug_level(
GET_CLASS(*this)))
129 std::map<AbsControlStep, OpVertexSet> csteps_partitions;
131 for(boost::tie(sch_i, sch_end) = boost::vertices(*g); sch_i != sch_end; sch_i++)
133 const auto control_step =
get_cstep(*sch_i);
134 if(csteps_partitions.find(control_step) == csteps_partitions.end())
136 csteps_partitions.insert(std::make_pair(control_step,
OpVertexSet(g)));
138 auto& control_step_ops = csteps_partitions.at(control_step);
139 control_step_ops.insert(*sch_i);
141 for(
const auto& control_step : csteps_partitions)
143 for(
const auto op : control_step.second)
147 " scheduled at control step (" +
STR(
get_cstep(op).second) +
"-" +
149 (Rfu ? (
"on functional unit " + Rfu->
get_fu_name(op)) :
""));
168 :
GraphWriter(op_graph.get(), 0), sch(_sch), opSet(_opSet)
177 os <<
"//Scheduling solution\n";
178 os <<
"splines=ortho;\n";
179 std::map<ControlStep, UnorderedSetStdStable<vertex>> inverse_relation;
181 for(boost::tie(v, v_end) = boost::vertices(*printing_graph); v != v_end; v++)
183 if(!opSet || opSet->find(*v) != opSet->end())
185 inverse_relation[sch->get_cstep(*v).second].insert(*v);
190 os <<
"//Control Step: " <<
level << std::endl;
191 os <<
"CS" <<
level <<
" [style=plaintext]\n{rank=same; CS" <<
level <<
" ";
192 for(
const auto operation : inverse_relation[level])
194 os << boost::get(boost::vertex_index_t(), *printing_graph)[
operation] <<
" ";
200 os <<
"CS" <<
level - 1u <<
" -> CS" <<
level <<
";\n";
204 if(!inverse_relation[
level].empty())
206 os <<
"CS" <<
level <<
" -> " 207 << boost::get(boost::vertex_index_t(), *printing_graph)[*inverse_relation[
level].begin()]
208 <<
" [style=invis weight=1000 color=dimgrey];\n";
216 auto local_op_graph = sub_op_graph ? sub_op_graph :
op_graph;
218 std::string output_directory =
220 if(!std::filesystem::exists(output_directory))
222 std::filesystem::create_directories(output_directory);
224 const VertexWriterConstRef op_label_writer(
new OpWriter(local_op_graph.get(), 0));
225 const EdgeWriterConstRef op_edge_property_writer(
new OpEdgeWriter(local_op_graph.get()));
226 const GraphWriterConstRef graph_writer(
229 output_directory + file_name, op_label_writer, op_edge_property_writer, graph_writer);
289 "Operation " +
STR(operation_index) +
" has not been scheduled");
344 const auto current_starting_time =
starting_times[operation_index];
349 const auto gn = GetPointer<const gimple_node>(tn);
351 "-->Computing ending time of new statement " +
STR(gn->index) +
": " + gn->ToString());
353 const auto clock_period = hls->HLS_C->get_clock_period() * hls->HLS_C->get_clock_period_resource_fraction();
355 const auto curr_bb_index = gn->bb_index;
356 THROW_ASSERT(curr_bb_index,
"Basic block of " + gn->ToString() +
" not set");
357 auto starting_time = 0.0;
360 ControlStep starting_cs = ControlStep(0);
365 if(gn->get_kind() == gimple_assign_K)
369 else if(gn->get_kind() == gimple_cond_K)
373 else if(gn->get_kind() == gimple_multi_way_if_K)
375 const auto gmwi = GetPointer<const gimple_multi_way_if>(tn);
376 for(
const auto& cond : gmwi->list_of_cond)
384 else if(gn->get_kind() == gimple_phi_K or gn->get_kind() == gimple_nop_K or gn->get_kind() == gimple_label_K)
387 else if(gn->get_kind() == gimple_return_K)
389 const auto gr = GetPointer<const gimple_return>(tn);
395 else if(gn->get_kind() == gimple_switch_K)
397 const auto gs = GetPointer<const gimple_switch>(tn);
401 else if(gn->get_kind() == gimple_call_K)
405 else if(gn->get_kind() == gimple_asm_K)
407 const auto ga = GetPointer<const gimple_asm>(tn);
419 THROW_UNREACHABLE(
"Compute new ending time of " + gn->ToString() +
" (" + gn->get_kind_text() +
")");
421 for(
const auto ssa_use : rhs_ssa_uses)
423 if(ssa_use->virtual_flag)
428 const auto def = ssa_use->CGetDefStmt();
429 const auto def_gn = GetPointer<const gimple_node>(
GET_CONST_NODE(def));
430 if(def_gn->get_kind() == gimple_nop_K)
435 if(def_gn->get_kind() == gimple_assign_K and GetPointer<const gimple_assign>(
GET_NODE(def))->clobber)
441 "Basic block of " + def_gn->ToString() +
" which defines " + ssa_use->ToString() +
" not set");
442 if(def_gn->bb_index != curr_bb_index)
445 "---Definition " +
STR(def->index) +
" - " + def->ToString() +
" is in BB" +
455 def_gn->ToString() +
" (which defines " +
456 ssa_use->ToString() +
") is unknown");
458 "---Definition " +
STR(def->index) +
" - " + def->ToString() +
" ends at " +
468 const auto ending_time =
ending_times.at(def_gn->index);
471 if(ending_time + connection_time >= starting_time)
473 starting_time = ending_time + connection_time;
481 const auto first_stage_latency =
485 auto first_stage_ending = starting_time + first_stage_latency;
486 if(first_stage_ending != 0.0 and
487 (floor((first_stage_ending + margin) / clock_period) != floor((starting_time) / clock_period)))
489 first_stage_ending = ((ceil((first_stage_ending + margin) / clock_period) + 1) * clock_period);
493 first_stage_ending = ((ceil((first_stage_ending + margin) / clock_period) * clock_period));
495 const auto other_cycles_latency =
496 (cycles - 2) * clock_period +
498 ending_times[operation_index] = first_stage_ending + other_cycles_latency;
503 ending_times[operation_index] = starting_time + latency;
509 clock_period) != floor(
starting_times[operation_index] / clock_period))
519 const bool updated_time =
starting_times[operation_index] != current_starting_time or
524 "---Execution time updated from [" +
STR(current_starting_time) +
"---" +
536 auto valS = ControlStep(static_cast<unsigned int>(floor(
starting_times[operation_index] / clock_period)));
545 auto valE = ControlStep(static_cast<unsigned int>(floor(
ending_times[operation_index] / clock_period)));
558 "-->Checking if simultaneous operations have to be rescheduled");
559 const auto reschedule = [&]() ->
bool {
580 const auto sl = GetPointer<const statement_list>(
GET_NODE(fd->body));
581 for(
const auto& stmt : sl->list_of_bloc.at(gn->bb_index)->CGetStmtList())
583 if(
op_starting_cycle.at(stmt->index) >= current_cs and stmt->index != operation_index and
591 "<--Checked if simultaneous operations have to be rescheduled");
602 const unsigned int basic_block_index)
const 609 if(not behavioral_helper->CanBeMoved(statement_index))
612 "<--No because it is artifical and cannot be moved by default");
615 const auto clock_period = hls->HLS_C->get_clock_period() * hls->HLS_C->get_clock_period_resource_fraction();
618 auto current_cs = ControlStep(static_cast<unsigned int>(floor(bb_ending_time / clock_period)));
622 if(behavioral_helper->IsLoad(statement_index))
629 if(unbounded_operation)
644 double new_ending_time = 0.0;
647 for(
const auto ssa_use : rhs_ssa_uses)
650 "---Considering used ssa " +
STR(ssa_use->index) +
" - " + ssa_use->ToString());
651 const auto def =
GET_NODE(ssa_use->CGetDefStmt());
652 const auto gn = GetPointer<const gimple_node>(def);
653 if(gn->bb_index != basic_block_index)
657 "---Defined in a different basic block from the current (BB" +
STR(gn->bb_index) +
" BB" +
658 STR(basic_block_index) +
")");
662 "Ending time of " + gn->ToString() +
" is not available");
664 "---Definition " +
STR(def->index) +
" - " + def->ToString() +
" ends at " +
676 "---Ending time + connection delay of predecessor is " +
STR(ending_time));
677 const auto operation_margin =
678 (ceil(ending_time / clock_period) * clock_period) - ending_time - clock_period_margin;
680 "---Connection time to phi is " +
684 statement_index, 0,
AbsControlStep(basic_block_index, current_cs)))
686 if(ending_time + latency > new_ending_time)
688 new_ending_time = ending_time + latency;
693 "---Ending time of this operation: " +
STR((ceil(ending_time / clock_period) * clock_period)) +
694 " + " +
STR(latency) +
" + " +
STR(clock_period) +
" = " +
695 STR((ceil(ending_time / clock_period) * clock_period) + latency + clock_period_margin));
697 if(((ceil(ending_time / clock_period) * clock_period) + latency + clock_period_margin) > new_ending_time)
699 new_ending_time = ((ceil(ending_time / clock_period) * clock_period) + latency);
702 if(ceil(bb_ending_time / clock_period) * clock_period < (ceil(new_ending_time / clock_period) * clock_period))
705 "<--No because it can increase the latency of a previus BB: " +
STR(bb_ending_time) +
" vs. " +
706 STR(new_ending_time));
711 "<--Yes because of chaining - New ending time is " +
STR(new_ending_time));
716 bool Schedule::CanBeChained(
const vertex first_statement,
const vertex second_statement)
const 720 const auto ret = CanBeChained(first_statement_index, second_statement_index);
724 bool Schedule::CanBeChained(
const unsigned int first_statement_index,
const unsigned int second_statement_index)
const 726 if(first_statement_index ==
ENTRY_ID or first_statement_index ==
EXIT_ID or second_statement_index ==
ENTRY_ID or second_statement_index ==
EXIT_ID)
730 const auto first_tree_node =
TM->
CGetTreeNode(first_statement_index);
731 const auto second_tree_node =
TM->
CGetTreeNode(second_statement_index);
733 const auto first_operation = GetPointer<const gimple_node>(first_tree_node)->
operation;
734 const auto second_operation = GetPointer<const gimple_node>(second_tree_node)->
operation;
736 const auto behavioral_helper = hls->FB->CGetBehavioralHelper();
737 if(behavioral_helper->IsStore(first_statement_index))
754 else if ((first_tree_node->get_kind() == gimple_cond_K or first_tree_node->get_kind() == gimple_multi_way_if_K) and behavioral_helper->IsStore(second_statement_index))
766 else if ((first_tree_node->get_kind() == gimple_cond_K or first_tree_node->get_kind() == gimple_multi_way_if_K) and (second_tree_node->get_kind() == gimple_label_K))
772 else if ((first_tree_node->get_kind() == gimple_cond_K or first_tree_node->get_kind() == gimple_multi_way_if_K) and (GetPointer<const gimple_node>(second_tree_node)->vdef))
788 const unsigned second_condition,
unsigned int function_decl_nid)
const 790 if(not first_condition or not second_condition)
802 const auto or_ending_time =
809 "---Checking if merging of conditions can be put at then end BB" +
STR(statement->bb_index) +
810 " (ending with " + statement->ToString());
815 const unsigned int second_statement_index,
816 unsigned int function_decl_nid)
const 819 const auto basic_block_graph =
821 const auto list_of_block =
822 GetPointer<statement_list>(
827 const auto first_basic_block = GetPointer<const gimple_node>(first_statement)->bb_index;
828 const auto first_block = list_of_block.at(first_basic_block);
829 const auto second_basic_block = GetPointer<const gimple_node>(second_statement)->bb_index;
831 const auto new_ending_time = [=]() ->
double {
832 if(first_statement->get_kind() == gimple_cond_K and second_statement->get_kind() == gimple_cond_K)
834 const auto first_gc = GetPointer<const gimple_cond>(first_statement);
835 const auto first_gc_op =
GET_NODE(first_gc->op0);
837 "Condition of the first gimple cond is " + first_gc_op->ToString());
838 const auto first_gc_input_delay =
GetReadyTime(first_gc_op->index, first_gc->bb_index);
839 const auto second_gc = GetPointer<const gimple_cond>(second_statement);
840 const auto second_gc_op =
GET_NODE(second_gc->op0);
842 "Condition of the first gimple cond is " + second_gc_op->ToString());
843 const auto second_gc_input_delay =
GetReadyTime(second_gc_op->index, second_gc->bb_index);
844 const auto second_block = list_of_block.at(second_basic_block);
845 if(first_block->true_edge == second_basic_block)
848 const auto not_ending_time =
849 second_gc_input_delay +
851 const auto and_operation =
853 const auto and_ending_time =
854 std::max(not_ending_time, first_gc_input_delay) +
856 return and_ending_time;
858 else if(first_block->false_edge == second_basic_block)
861 const auto not_ending_time =
862 first_gc_input_delay +
864 const auto and_operation =
866 const auto and_ending_time =
867 std::max(not_ending_time, second_gc_input_delay) +
869 return and_ending_time;
873 THROW_UNREACHABLE(
"BB" +
STR(second_basic_block) +
" is not on the true edge nor on the false edge of BB" +
874 STR(first_basic_block));
877 else if(first_statement->get_kind() == gimple_cond_K and second_statement->get_kind() == gimple_multi_way_if_K)
879 const auto first_gc = GetPointer<const gimple_cond>(first_statement);
880 const auto second_gmwi = GetPointer<const gimple_multi_way_if>(second_statement);
881 if(first_block->true_edge == second_basic_block)
883 const auto first_gc_op =
GET_NODE(first_gc->op0);
885 "Condition of the first gimple cond is " + first_gc_op->ToString());
886 const auto first_gc_input_delay =
GetReadyTime(first_gc_op->index, first_gc->bb_index);
887 auto current_condition = first_gc_op;
888 auto current_ending_time = first_gc_input_delay;
889 for(
const auto& cond : second_gmwi->list_of_cond)
894 const auto cond_delay =
GetReadyTime(cond.first->index, first_gc->bb_index);
895 const auto not_ending_time =
899 GetPointer<const gimple_assign>(
GET_NODE(current_condition))->op0,
900 GetPointer<const gimple_assign>(
GET_NODE(not_operation))->op0, blocRef(), function_decl_nid);
901 current_condition = and_operation;
902 current_ending_time =
903 std::max(not_ending_time, current_ending_time) +
907 return current_ending_time;
909 else if(first_block->false_edge == second_basic_block)
911 const auto first_gc_op =
GET_NODE(first_gc->op0);
913 "Condition of the first gimple cond is " + first_gc_op->ToString());
914 auto current_ending_time = 0.0;
916 const auto not_ending_time =
919 for(
const auto& cond : second_gmwi->list_of_cond)
921 const auto and_operation =
923 blocRef(), function_decl_nid);
924 const auto and_ending_time =
927 current_ending_time =
std::max(current_ending_time, and_ending_time);
929 return current_ending_time;
933 THROW_UNREACHABLE(
"BB" +
STR(second_basic_block) +
" is not on the true edge nor on the false edge of BB" +
934 STR(first_basic_block));
937 else if(first_statement->get_kind() == gimple_multi_way_if_K and second_statement->get_kind() == gimple_cond_K)
939 const auto first_gmwi = GetPointer<const gimple_multi_way_if>(first_statement);
940 const auto second_gc = GetPointer<const gimple_cond>(second_statement);
941 const auto second_gc_op =
GET_NODE(second_gc->op0);
944 const auto default_basic_block = first_gmwi->list_of_cond.back().second;
945 if(default_basic_block != second_basic_block)
947 for(
const auto& cond : first_gmwi->list_of_cond)
949 if(cond.second == second_basic_block)
952 auto const not_ending_time =
955 const auto and_operation =
957 blocRef(), function_decl_nid);
958 const auto and_ending_time =
961 return and_ending_time;
969 auto current_ending_time = 0.0;
970 for(
const auto& cond : first_gmwi->list_of_cond)
975 const auto not_ending_time =
978 const auto and_operation =
982 const auto and_ending_time =
984 (
std::max(not_ending_time, current_ending_time) +
987 current_condition = and_operation;
988 current_ending_time = and_ending_time;
991 const auto and_operation =
993 const auto and_ending_time =
996 return and_ending_time;
999 else if(first_statement->get_kind() == gimple_multi_way_if_K and
1000 second_statement->get_kind() == gimple_multi_way_if_K)
1002 const auto first_gmwi = GetPointer<const gimple_multi_way_if>(first_statement);
1003 const auto second_gmwi = GetPointer<const gimple_multi_way_if>(second_statement);
1005 const auto default_basic_block = first_gmwi->list_of_cond.back().second;
1006 if(default_basic_block != second_basic_block)
1008 for(
const auto& first_cond : first_gmwi->list_of_cond)
1010 if(first_cond.second == second_basic_block)
1012 auto current_condition = first_cond.first;
1013 auto current_ending_time =
GetReadyTime(first_cond.first->index, first_basic_block);
1014 for(
const auto& second_cond : second_gmwi->list_of_cond)
1016 if(second_cond.first)
1018 const auto not_operation =
1020 const auto cond_delay =
GetReadyTime(second_cond.first->index, first_basic_block);
1021 const auto not_ending_time =
1024 const auto and_operation =
1026 GetPointer<const gimple_assign>(
GET_NODE(not_operation))->op0,
1027 blocRef(), function_decl_nid);
1028 current_condition = and_operation;
1029 current_ending_time =
1030 std::max(not_ending_time, current_ending_time) +
1034 return current_ending_time;
1042 auto current_ending_time = 0.0;
1043 for(
const auto& cond : first_gmwi->list_of_cond)
1048 const auto not_ending_time =
GetReadyTime(cond.first->index, first_basic_block);
1049 const auto and_operation =
1052 cond.first, blocRef(), function_decl_nid) :
1054 const auto and_ending_time =
1056 std::max(not_ending_time, current_ending_time) +
1059 current_condition = and_operation;
1060 current_ending_time = and_ending_time;
1063 for(
const auto& cond : second_gmwi->list_of_cond)
1067 const auto and_operation =
1069 cond.first, blocRef(), function_decl_nid);
1070 const auto and_ending_time =
1073 current_ending_time =
std::max(and_ending_time, current_ending_time);
1076 return current_ending_time;
1094 const auto def = GetPointer<gimple_node>(
GET_NODE(sn->CGetDefStmt()));
1095 if(def->get_kind() == gimple_phi_K)
1100 if(def->get_kind() == gimple_assign_K)
1102 if(def->bb_index != basic_block_index)
1108 "Ending time of " + def->ToString() +
" not found");
1119 const auto clock_period =
hls->
HLS_C->get_clock_period() *
hls->
HLS_C->get_clock_period_resource_fraction();
1122 const auto fd = GetPointer<const function_decl>(tn);
1123 THROW_ASSERT(GetPointer<statement_list>(
GET_NODE(fd->body))->list_of_bloc.find(basic_block_index) !=
1124 GetPointer<statement_list>(
GET_NODE(fd->body))->list_of_bloc.end(),
1125 "BB" +
STR(basic_block_index) +
" not found");
1126 const auto block = GetPointer<statement_list>(
GET_NODE(fd->body))->list_of_bloc.at(basic_block_index);
1127 const auto stmt_list = block->CGetStmtList();
1128 if(stmt_list.size() == 0)
1132 const auto ending_time =
1137 return ceil((
ending_times.at((*ending_time)->index) + margin) / clock_period) * clock_period;
1147 "Ending time of operation " +
STR(
TM->
CGetTreeNode(operation_index)) +
" not found");
1158 "Starting time of operation " +
STR(operation_index) +
" not found");
1164 const auto edge = std::pair<unsigned int, unsigned int>(first_operation, second_operation);
1205 if(starting_times.at(x) == starting_times.at(y))
1211 return starting_times.at(x) < starting_times.at(y);
1223 double ending_state_time = 0;
1224 for(
const auto starting_operation : state_info->starting_operations)
1232 if(stmt->get_kind() == gimple_phi_K)
1236 const bool found = std::find(state_info->ending_operations.begin(), state_info->ending_operations.end(),
1237 starting_operation) != state_info->ending_operations.end();
1238 const auto ending_time =
1245 "---Ending time of " + stmt->ToString() +
" is " +
STR(ending_time));
1246 if(ending_time > ending_state_time)
1249 "---Updating ending time to " +
STR(ending_time) +
" because of " + stmt->ToString());
1250 ending_state_time = ending_time;
1255 std::set<unsigned int, StartingTimeSorter> to_be_processed =
1257 for(
const auto starting_operation : state_info->starting_operations)
1266 "---Stmt " + stmt->ToString() +
" ends at " +
STR(
ending_times.at(stmt->index)));
1267 const bool found = std::find(state_info->ending_operations.begin(), state_info->ending_operations.end(),
1268 starting_operation) != state_info->ending_operations.end();
1269 const auto ending_time =
1275 if(ending_time == ending_state_time)
1277 to_be_processed.insert(stmt->index);
1278 critical_paths.insert(stmt->index);
1282 while(to_be_processed.size())
1284 const auto last = *(to_be_processed.rbegin());
1286 to_be_processed.erase(last);
1289 const auto gn = GetPointer<const gimple_node>(stmt_tn);
1291 if(gn->get_kind() == gimple_assign_K)
1295 else if(gn->get_kind() == gimple_cond_K)
1299 else if(gn->get_kind() == gimple_multi_way_if_K)
1301 const auto gmwi = GetPointer<const gimple_multi_way_if>(stmt_tn);
1302 for(
const auto& cond : gmwi->list_of_cond)
1310 else if(gn->get_kind() == gimple_phi_K or gn->get_kind() == gimple_nop_K or gn->get_kind() == gimple_label_K)
1313 else if(gn->get_kind() == gimple_return_K)
1315 const auto gr = GetPointer<const gimple_return>(stmt_tn);
1321 else if(gn->get_kind() == gimple_switch_K)
1323 const auto gs = GetPointer<const gimple_switch>(stmt_tn);
1327 else if(gn->get_kind() == gimple_call_K)
1331 else if(gn->get_kind() == gimple_asm_K)
1337 THROW_UNREACHABLE(
"Computing critical path analyzing " + gn->ToString() +
" (" + gn->get_kind_text() +
")");
1339 for(
const auto ssa_use : rhs_ssa_uses)
1341 if(ssa_use->virtual_flag)
1346 const auto def =
GET_NODE(ssa_use->CGetDefStmt());
1347 const auto def_gn = GetPointer<const gimple_node>(def);
1348 if(def_gn->get_kind() == gimple_nop_K)
1353 if(def_gn->get_kind() == gimple_pragma_K)
1358 if(GetPointer<const gimple_assign>(def) and GetPointer<const gimple_assign>(def)->clobber)
1364 "Basic block of " + def_gn->ToString() +
" which defines " + ssa_use->ToString() +
" not set");
1365 if(state_info->BB_ids.find(def_gn->bb_index) == state_info->BB_ids.end())
1368 "---Definition " +
STR(def->index) +
" - " + def->ToString() +
" is in other state");
1372 "Not possible because ending time of " + def_gn->ToString() +
" (which defines " +
1373 ssa_use->ToString() +
") is unknown");
1375 "---Definition " +
STR(def->index) +
" - " + def->ToString() +
" ends at " +
1378 const auto ending_time =
ending_times.at(def_gn->index);
1380 def_gn->index, last,
1385 to_be_processed.insert(def_gn->index);
1386 critical_paths.insert(def_gn->index);
1388 "---Adding " + def_gn->ToString() +
" to critical path");
1394 return critical_paths;
1414 connection_times[std::pair<unsigned int, unsigned int>(first_operation, second_operation)] = value;
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
tree_nodeRef CreateOrExpr(const tree_nodeConstRef &first_condition, const tree_nodeConstRef &second_condition, const blocRef &block, unsigned int function_decl_nid) const
Create an or expression.
AbsControlStep()
Empty constructor.
tree_nodeRef CreateNotExpr(const tree_nodeConstRef &condition, const blocRef &block, unsigned int function_decl_nid) const
UTILITY.
OpGraphConstRef op_graph
The operation graph (for scheduling purpose) (cannot be const because of = operator) ...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
CustomUnorderedMapUnstable< unsigned int, ControlStep > op_ending_cycle
map between the operation index and the clock cycle on which the operations ends its execution ...
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.
ScheduleWriter(const OpGraphConstRef op_graph, const ScheduleConstRef _sch, OpVertexSet *_opSet)
Constructor.
std::string ToString() const
Print this node as string in gimple format.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
Operation cannot be moved.
Dest from_strongtype_cast(Source source)
std::string get_function_name() const
Return the name of the function.
#define BB_EXIT
constant identifying the basic block node of type exit
std::map< vertex, double > op_slack
slack map
CustomMap< unsigned int, double > starting_times
The absolute starting time of each operation as computed by the scheduling Key is the index of the gi...
Edge writer for operation graph.
AbsControlStep get_cstep(const vertex &op) const
Returns the clock cycle where the given operation has been scheduled.
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
double get_fo_correction(unsigned int first_operation, unsigned int second_operation) const
return the fan-out correction for a given edge
unsigned int num_scheduled() const
Returns the number of scheduled operations.
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
tree_managerRef TM
The tree manager.
std::string NumberToString(const T number, const size_t precision, const size_t size)
Function with print number in desired format.
CustomOrderedMap< T, U > CustomMap
ControlStep tot_csteps
total number of control steps
AbsControlStep get_cstep_end(const vertex &op) const
Return the last clock cycle in which the operation execute.
const ScheduleConstRef sch
The schedule to be printed.
static const ControlStep UNKNOWN
Constant used to specify unknown control step.
Definition of hash function for EdgeDescriptor.
void Initialize()
Initialize the data structure.
Class specification of the manager of the technology library data structures.
This class contains the base representation for a generic frontend flow step which works on a single ...
CustomUnorderedMap< vertex, bool > spec
Map for speculation property of each operation vertex.
Data structure describing a basic block at tree level.
std::string get_fu_name(vertex const &v) const
Returns the name of the functional unit.
AllocationInformationConstRef allocation_information
The allocation information.
Absolute Control step First field is the basic block Second field is the relative control step...
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
A set of operation vertices.
const std::string PrintTimingInformation(const unsigned int statement_index) const
Print the timing information about an operation.
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.
CustomMap< ControlStep, CustomSet< unsigned int > > starting_cycles_to_ops
The reverse of op_starting_cycle.
const ParameterConstRef parameters
The set of input parameters.
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 OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
void UpdateTime(const unsigned int operation_index, bool update_cs=true)
Compute the starting and the ending time of a statement.
void WriteDot(const std::string &file_name, OpGraphConstRef sub_op_graph=OpGraphConstRef(), OpVertexSet *opSet=nullptr) const
Function that writes the dot file of the scheduling by using the AT&T direct graph representation...
#define EXIT_ID
constant used to represent tree node index of exit operation
This class specifies the characteristic of a particular operation working on a given functional unit...
Functor used to write the content of the property of a graph to a dotty file.
Data structure used to store the schedule of the operations.
tree_manipulationConstRef tree_man
The tree manipulation.
static void compute_ssa_uses_rec_ptr(const tree_nodeConstRef &tn, CustomOrderedSet< const ssa_name *> &ssa_uses)
recursively compute the pointers to the ssa_name variables used in a statement
FunctionFrontendFlowStep_Movable CanBeMoved(const unsigned int statement_index, const unsigned int basic_block) const
Check if a statement can be moved at the end of a basic block.
CustomMap< std::pair< unsigned int, unsigned int >, double > connection_times
Connection times The key is an operation graph edge.
void AddConnectionTimes(unsigned int first_operation, unsigned int second_operation, const double value)
Add fan out correction time.
double GetBBEndingTime(const unsigned int basic_block_index) const
Return the ending time of a basic block (i.e., the ending time of the last ending operation...
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...
Basic block control flow graph with feedback.
void set_execution_end(const vertex &op, ControlStep c_step_end)
Sets the ending clock cycle for the given operation.
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
#define BB_ENTRY
constant identifying the basic block node of type entry
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
const unsigned int function_index
The index of the function.
This file contains the structures needed to manage a graph that will represent the state transition g...
bool EvaluateMultiWayIfsMerging(const unsigned int first_statement_index, const unsigned int second_statement_index, unsigned int function_decl_nid) const
Evaluate if two conditional statements can be merged to create a gimple_multi_way_if.
#define GET_CONST_NODE(t)
const BehavioralHelperConstRef CGetBehavioralHelper() const
Returns the helper associated with the function.
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
Classes specification of the tree_node data structures.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
static const unsigned int UNKNOWN
The value used to identified unknown functional unit.
bool EvaluateCondsMerging(const unsigned statement_index, const unsigned int first_condition, const unsigned second_condition, unsigned int function_decl_nid) const
Check if a further condition can be added to gimple multi way if without increasing basic block laten...
Data structure definition for HLS constraints.
This struct specifies the block node.
This file collects some utility functions.
double GetStartingTime(const unsigned int operation) const
Return the starting time of the operation.
void print(fu_bindingRef Rfu=fu_bindingRef()) const
Function that prints the class schedule.
bool operator<(const AbsControlStep &other) const
Compare two scheduling step.
refcount< T > lock() const
FunctionFrontendFlowStep_Movable
Enum class used to specify if a statement can be moved.
refcount< const Schedule > ScheduleConstRef
const int debug_level
The debug level.
CustomSet< unsigned int > ComputeCriticalPath(const StateInfoConstRef state_info) const
Compute the critical path inside a state.
bool is_scheduled(const vertex &op) const
Returns true if the given operation has been already scheduled, false otherwise.
Class specification of the tree_reindex support class.
#define ENTRY_ID
constant used to represent tree node index of entry operation
Collect all structs used to write a graph in the dot format.
Data structure used to store the functional-unit binding of the vertexes.
const OpGraphConstRef CGetOpGraph(FunctionBehavior::graph_type gt) const
This method returns the operation graphs.
CustomMap< unsigned int, double > ending_times
The absolute ending time of each operation as computed by the scheduling Key is the index of the gimp...
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
void clear()
Erases the current results.
System dependence + anti-dependence + output dependence graph + flow graph.
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.
const Wrefcount< const HLS_manager > hls_manager
The HLS manager.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
double GetReadyTime(const unsigned int tree_node_index, const unsigned int basic_block_index) const
Get when in a basic block an ssa is ready.
Data structure that contains all information about high level synthesis process.
const CustomMap< unsigned int, double > & starting_times
The starting time.
x
Return the smallest n such that 2^n >= _x.
const HLS_constraintsRef HLS_C
store the HLS constraints
StartingTimeSorter(const CustomMap< unsigned int, double > &_starting_times)
The constructor.
const OpVertexSet * opSet
double GetEndingTime(const unsigned int operation) const
Return the starting time of the operation.
void operator()(std::ostream &os) const override
Redifinition of operator()
Data structure definition for high-level synthesis flow.
Operation cannot be moved because of timing.
void set_execution(const vertex &op, ControlStep c_step)
Sets the starting clock cycle for the given operation.
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.
HLS specialization of generic_device.
A brief description of the C++ Header File.
CustomUnorderedMapUnstable< unsigned int, ControlStep > op_starting_cycle
map between the operation index and the clock cycle on which the operation starts its execution NOTE:...
bool operator()(const unsigned int x, const unsigned int y) const
Compare position of two operations.
Schedule(const HLS_managerConstRef hls_manager, const unsigned int function_index, const OpGraphConstRef op_graph, const ParameterConstRef parameters)
Constructor.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...