71 #include <boost/range/adaptor/reversed.hpp> 80 class SDCSorter : std::binary_function<vertex, vertex, bool>
125 std::set<vertex, bb_vertex_order_by_map> loop_bbs,
const ParameterConstRef _parameters)
128 function_behavior(_function_behavior),
131 bb_index_map(basic_block_graph->CGetBBGraphInfo()->bb_index_map),
132 parameters(_parameters),
133 debug_level(_parameters->get_class_debug_level(
GET_CLASS(*this)))
137 for(
const auto& loop_bb : loop_bbs)
139 const auto& statements_list = basic_block_graph->
CGetBBNodeInfo(loop_bb)->statements_list;
141 for(
const auto vertex_to_be_analyzed : boost::adaptors::reverse(statements_list))
144 for(boost::tie(eo, eo_end) = boost::out_edges(vertex_to_be_analyzed, *op_graph); eo != eo_end; eo++)
147 reachability_map[vertex_to_be_analyzed].insert(target);
148 reachability_map[vertex_to_be_analyzed].insert(reachability_map[target].begin(),
149 reachability_map[target].end());
155 std::map<ControlStep, std::map<ControlStep, CustomSet<vertex>>> alap_asap_cluster;
158 for(boost::tie(op, op_end) = boost::vertices(*op_graph); op != op_end; op++)
160 alap_asap_cluster[alap->get_cstep(*op).second][asap->get_cstep(*op).second].insert(*op);
164 for(
const auto& alap_cluster : alap_asap_cluster)
166 for(
const auto& asap_cluster : alap_cluster.second)
168 auto to_process = std::set<vertex, op_vertex_order_by_map>(
170 for(
const auto cluster_op : asap_cluster.second)
172 to_process.insert(cluster_op);
174 for(
const auto cluster_op : to_process)
176 op_levels[cluster_op] =
static_cast<size_t>(op_levels.size());
191 const auto first_bb_index = op_graph->CGetOpNodeInfo(x)->bb_index;
192 const auto second_bb_index = op_graph->CGetOpNodeInfo(y)->bb_index;
193 const auto first_bb_vertex = bb_index_map.at(first_bb_index);
194 const auto second_bb_vertex = bb_index_map.at(second_bb_index);
195 if(function_behavior->CheckBBReachability(first_bb_vertex, second_bb_vertex))
199 if(function_behavior->CheckBBReachability(second_bb_vertex, first_bb_vertex))
205 return op_levels.at(x) < op_levels.at(y);
210 unsigned int _function_id,
const DesignFlowManagerConstRef _design_flow_manager,
213 _hls_flow_step_specialization),
226 const std::set<vertex, bb_vertex_order_by_map>& loop_bbs)
229 const auto FB =
HLSMgr->CGetFunctionBehavior(
funId);
243 std::list<vertex> basic_blocks;
246 for(
const auto basic_block : basic_blocks)
248 if(loop_bbs.count(basic_block))
251 const auto& statements_list = bb_node_info->statements_list;
252 for(
const auto current : statements_list)
255 "-->Processing " +
GET_NAME(filtered_op_graph, current));
258 const double current_op_execution_time = [&]() ->
double {
277 timeLatency.second) :
281 "---Its execution time is " +
STR(current_op_execution_time));
283 starting_times[current] = 0.0;
285 reverse_reachability.insert(std::make_pair(current,
OpVertexSet(filtered_op_graph)));
286 live_operations.insert(std::make_pair(current,
OpVertexSet(filtered_op_graph)));
288 for(boost::tie(ie, ie_end) = boost::in_edges(current, *filtered_op_graph); ie != ie_end; ie++)
296 const auto source = boost::source(*ie, *filtered_op_graph);
300 "---Considering " +
GET_NAME(filtered_op_graph, source));
301 if(ending_times.count(source) && ending_times.at(source) + connection_time > starting_times.at(current))
304 "---New starting time is " +
STR(ending_times.at(source) + connection_time));
305 starting_times[current] = ending_times.at(source) + connection_time;
307 reverse_reachability.at(current).insert(reverse_reachability.at(source).begin(),
308 reverse_reachability.at(source).end());
311 "<--Starting time is " +
STR(starting_times.at(current)));
312 ending_times[current] = starting_times.at(current) + current_op_execution_time;
316 for(boost::tie(ie, ie_end) = boost::in_edges(current, *filtered_op_graph); ie != ie_end; ie++)
324 const auto source = boost::source(*ie, *filtered_op_graph);
325 if(dead_operations.count(source))
329 auto CheckChaining = [&](
const vertex other) ->
bool {
330 bool constraint_to_be_added =
false;
334 constraint_to_be_added =
true;
338 constraint_to_be_added =
true;
340 if(constraint_to_be_added)
344 for(boost::tie(ie2, ie2_end) = boost::in_edges(current, *filtered_op_graph);
345 ie2 != ie2_end && !skip; ie2++)
347 const vertex other_source = boost::source(*ie2, *filtered_op_graph);
348 if(other_source == other)
352 if(reverse_reachability.at(other_source).count(other) == 0)
363 if(ending_times.at(other_source) - starting_times.at(other) <
clock_period)
373 if(constraints.count(other) == 0)
375 constraints.insert(std::make_pair(other,
OpVertexSet(filtered_op_graph)));
377 constraints.at(other).insert(current);
379 dead_operations.insert(other);
383 live_operations.at(current).insert(other);
385 return constraint_to_be_added;
387 const bool added_constraint = CheckChaining(source);
388 if(!added_constraint)
391 "-->Considering operations coming from " +
GET_NAME(filtered_op_graph, source));
392 for(
const auto& pred_live_operation : live_operations.at(source))
395 "-->Considering operation " +
GET_NAME(filtered_op_graph, pred_live_operation));
396 CheckChaining(pred_live_operation);
398 "<--Considered operation " +
GET_NAME(filtered_op_graph, pred_live_operation));
401 "<--Considered operations coming from " +
GET_NAME(filtered_op_graph, source));
404 for(
const auto& dead_operation : dead_operations)
406 if(live_operations.at(current).count(dead_operation))
408 live_operations.at(current).erase(live_operations.at(current).find(dead_operation));
412 "<--Processed " +
GET_NAME(filtered_op_graph, current));
416 for(
const auto& constraint : constraints)
418 for(
const auto& second : constraint.second)
422 std::map<int, double> coeffs;
423 coeffs[
static_cast<int>(
434 "---Adding edge " +
GET_NAME(filtered_op_graph, constraint.first) +
"-->" +
435 GET_NAME(filtered_op_graph, second));
438 std::list<vertex> vertices;
439 debug_filtered_op_graph->TopologicalSort(vertices);
441 catch(
const char* msg)
443 debug_filtered_op_graph->WriteDot(
"Error.dot");
447 catch(
const std::string& msg)
449 debug_filtered_op_graph->WriteDot(
"Error.dot");
453 catch(
const std::exception& ex)
455 debug_filtered_op_graph->WriteDot(
"Error.dot");
461 debug_filtered_op_graph->WriteDot(
"Error.dot");
474 bool simultaneous)
const 478 std::map<int, double> coeffs;
479 coeffs[
static_cast<int>(
operation_to_varindex.at(std::make_pair(source, source_cycle_latency - 1)))] = 1.0;
481 solver->add_row(coeffs, simultaneous ? 0.0 : -1.0,
meilp_solver::L, name);
488 for(
unsigned int stage = 1; stage < cycle_latency; stage++)
490 const std::string name =
"Stage_" +
GET_NAME(
op_graph, operation) +
"_" +
STR(stage - 1) +
"-" +
STR(stage);
491 std::map<int, double> coeffs;
512 design_flow_graph->CGetDesignFlowStepInfo(frontend_step)->design_flow_step :
513 GetPointer<const FrontendFlowStepFactory>(
515 ->CreateFunctionFrontendFlowStep(FrontendFlowStepType::SDC_CODE_MOTION,
funId);
516 relationship.insert(design_flow_step);
528 switch(relationship_type)
542 #if HAVE_FROM_PRAGMA_BUILT 543 if(
parameters->getOption<
bool>(OPT_parse_pragma))
576 const auto TM =
HLSMgr->get_tree_manager();
577 auto fnode = TM->get_tree_node_const(
funId);
578 auto fd = GetPointer<function_decl>(fnode);
582 const LoopsConstRef loops = FB->
CGetLoops();
584 auto initial_ctrl_step = ControlStep(0u);
587 if(
HLSMgr->design_interface_io.find(fname) !=
HLSMgr->design_interface_io.end())
589 for(
const auto& bb2arg2stmtsR :
HLSMgr->design_interface_io.at(fname))
591 for(
const auto& arg2stms : bb2arg2stmtsR.second)
593 if(arg2stms.second.size() > 0)
595 for(
const auto& stmt : arg2stms.second)
597 const auto op_it = flow_graph->CGetOpGraphInfo()->tree_node_to_operation.find(stmt);
598 if(op_it != flow_graph->CGetOpGraphInfo()->tree_node_to_operation.end())
600 RW_stmts.insert(op_it->second);
607 for(
const auto& loop : loops->GetList())
611 const unsigned int loop_id = loop->GetId();
615 std::set<vertex, bb_vertex_order_by_map> loop_bbs(comp_i);
619 for(boost::tie(bb, bb_end) = boost::vertices(*
basic_block_graph); bb != bb_end; bb++)
623 loop_bbs.insert(*bb);
626 loop_operations.insert(vit, vit_end);
627 Loop_operations.insert(vit, vit_end);
637 static_cast<meilp_solver::supported_solvers>(
parameters->getOption<
int>(OPT_ilp_solver))));
638 if(
parameters->getOption<
int>(OPT_ilp_max_time))
640 solver->setMaximumSeconds(
parameters->getOption<
int>(OPT_ilp_max_time));
645 filtered_op_graph->
WriteDot(
"Loop_" +
STR(loop_id) +
"_to_be_scheduled.dot");
650 unsigned int next_var_index = 0;
651 for(
const auto loop_operation : loop_operations)
654 for(
unsigned int stage = 0; stage < cycle_latency; stage++)
658 "---Creating variables for " +
GET_NAME(filtered_op_graph, loop_operation) +
" (executed by " +
" " +
660 ") stage " +
STR(stage) +
": " +
STR(next_var_index + 1));
669 for(
const auto basic_block : loop_bbs)
672 for(boost::tie(oe, oe_end) = boost::out_edges(basic_block, *
basic_block_graph); oe != oe_end; oe++)
679 path_end_to_varindex[basic_block] = next_var_index;
681 "---Creating variable for path ending in BB" +
691 for(
const auto basic_block : loop_bbs)
693 bb_to_begin[basic_block] = next_var_index;
695 bb_to_end[basic_block] = next_var_index;
700 const size_t num_variables = next_var_index;
703 solver->make(static_cast<int>(num_variables));
706 for(
size_t var_index = 0; var_index < num_variables; var_index++)
708 solver->set_int(static_cast<int>(var_index));
709 solver->set_lowbo(static_cast<int>(var_index), 0);
716 for(
auto const operation : loop_operations)
724 for(
const auto operation : loop_operations)
727 "-->Adding dependencies starting from " +
GET_NAME(filtered_op_graph,
operation));
729 for(boost::tie(oe, oe_end) = boost::out_edges(
operation, *filtered_op_graph); oe != oe_end; oe++)
747 "---Skipped dependence -> " +
752 "<--Added dependencies starting from " +
GET_NAME(filtered_op_graph,
operation));
759 debug_filtered_op_graph,
765 aslap->compute_ASAP();
768 SDCSorter(aslap->CGetASAP(), aslap->CGetALAP(), FB, filtered_op_graph, loop_bbs,
parameters);
779 for(
const auto basic_block : loop_bbs)
782 "-->Adding sorting constraints for BB" +
784 loop_unbounded_operations.insert(std::pair<vertex, OpVertexSet>(basic_block,
OpVertexSet(filtered_op_graph)));
785 loop_pipelined_operations.insert(std::pair<vertex, OpVertexSet>(basic_block,
OpVertexSet(filtered_op_graph)));
787 for(boost::tie(ie, ie_end) = boost::in_edges(basic_block, *
basic_block_graph); ie != ie_end; ie++)
792 if(loop_bbs.count(source))
794 loop_unbounded_operations.at(basic_block)
795 .insert(loop_unbounded_operations.at(source).begin(), loop_unbounded_operations.at(source).end());
796 loop_pipelined_operations.at(basic_block)
797 .insert(loop_pipelined_operations.at(source).begin(), loop_pipelined_operations.at(source).end());
798 for(
const auto& fu_type : constrained_operations_sequences[source])
800 constrained_operations_sequences[basic_block][fu_type.first].insert(fu_type.second.begin(),
801 fu_type.second.end());
806 std::set<vertex, SDCSorter> basic_block_sorted_operations(sdc_sorter);
811 basic_block_sorted_operations.insert(
operation);
813 for(
const auto debug_operation : basic_block_sorted_operations)
816 "---" +
GET_NAME(filtered_op_graph, debug_operation));
826 for(
const auto debug_operation : basic_block_sorted_operations)
829 "---" +
GET_NAME(filtered_op_graph, debug_operation));
834 for(
const auto operation : basic_block_sorted_operations)
842 for(
const auto other_unbounded_operation : loop_unbounded_operations.at(basic_block))
844 std::map<int, double> coeffs;
845 const bool other_before = sdc_sorter(other_unbounded_operation,
operation);
848 const std::string name =
861 "---Adding edge " +
GET_NAME(filtered_op_graph, other_unbounded_operation) +
865 std::list<vertex> vertices;
866 debug_filtered_op_graph->TopologicalSort(vertices);
868 catch(
const char* msg)
870 debug_filtered_op_graph->WriteDot(
"Error.dot");
874 catch(
const std::string& msg)
876 debug_filtered_op_graph->WriteDot(
"Error.dot");
880 catch(
const std::exception& ex)
882 debug_filtered_op_graph->WriteDot(
"Error.dot");
888 debug_filtered_op_graph->WriteDot(
"Error.dot");
899 const std::string name =
913 GET_NAME(filtered_op_graph, other_unbounded_operation));
916 std::list<vertex> vertices;
917 debug_filtered_op_graph->TopologicalSort(vertices);
919 catch(
const char* msg)
921 debug_filtered_op_graph->WriteDot(
"Error.dot");
925 catch(
const std::string& msg)
927 debug_filtered_op_graph->WriteDot(
"Error.dot");
931 catch(
const std::exception& ex)
933 debug_filtered_op_graph->WriteDot(
"Error.dot");
939 debug_filtered_op_graph->WriteDot(
"Error.dot");
948 loop_unbounded_operations.at(basic_block).insert(
operation);
949 for(
const auto loop_pipelined_operation : loop_pipelined_operations.at(basic_block))
951 std::map<int, double> coeffs;
952 const bool pipelined_before = sdc_sorter(loop_pipelined_operation,
operation);
955 const std::string name =
959 loop_pipelined_operation,
969 "---Adding edge " +
GET_NAME(filtered_op_graph, loop_pipelined_operation) +
973 std::list<vertex> vertices;
974 debug_filtered_op_graph->TopologicalSort(vertices);
976 catch(
const char* msg)
978 debug_filtered_op_graph->WriteDot(
"Error.dot");
982 catch(
const std::string& msg)
984 debug_filtered_op_graph->WriteDot(
"Error.dot");
988 catch(
const std::exception& ex)
990 debug_filtered_op_graph->WriteDot(
"Error.dot");
996 debug_filtered_op_graph->WriteDot(
"Error.dot");
1007 const std::string name =
1021 GET_NAME(filtered_op_graph, loop_pipelined_operation));
1024 std::list<vertex> vertices;
1025 debug_filtered_op_graph->TopologicalSort(vertices);
1027 catch(
const char* msg)
1029 debug_filtered_op_graph->WriteDot(
"Error.dot");
1033 catch(
const std::string& msg)
1035 debug_filtered_op_graph->WriteDot(
"Error.dot");
1039 catch(
const std::exception& ex)
1041 debug_filtered_op_graph->WriteDot(
"Error.dot");
1047 debug_filtered_op_graph->WriteDot(
"Error.dot");
1060 loop_pipelined_operations.at(basic_block).insert(
operation);
1061 for(
const auto loop_unbounded_operation : loop_unbounded_operations.at(basic_block))
1063 std::map<int, double> coeffs;
1064 const bool unbounded_before = sdc_sorter(loop_unbounded_operation,
operation);
1065 if(unbounded_before)
1067 const std::string name =
1080 "---Adding edge " +
GET_NAME(filtered_op_graph, loop_unbounded_operation) +
1084 std::list<vertex> vertices;
1085 debug_filtered_op_graph->TopologicalSort(vertices);
1087 catch(
const char* msg)
1089 debug_filtered_op_graph->WriteDot(
"Error.dot");
1093 catch(
const std::string& msg)
1095 debug_filtered_op_graph->WriteDot(
"Error.dot");
1099 catch(
const std::exception& ex)
1101 debug_filtered_op_graph->WriteDot(
"Error.dot");
1107 debug_filtered_op_graph->WriteDot(
"Error.dot");
1118 const std::string name =
1132 GET_NAME(filtered_op_graph, loop_unbounded_operation));
1136 std::list<vertex> vertices;
1137 debug_filtered_op_graph->TopologicalSort(vertices);
1139 catch(
const char* msg)
1141 debug_filtered_op_graph->WriteDot(
"Error.dot");
1145 catch(
const std::string& msg)
1147 debug_filtered_op_graph->WriteDot(
"Error.dot");
1151 catch(
const std::exception& ex)
1153 debug_filtered_op_graph->WriteDot(
"Error.dot");
1159 debug_filtered_op_graph->WriteDot(
"Error.dot");
1175 const auto& old_sequences = constrained_operations_sequences[basic_block][fu_type];
1176 if(old_sequences.size())
1179 for(
auto old_sequence : old_sequences)
1183 std::string old_sequence_string;
1184 for(
const auto temp : old_sequence)
1186 old_sequence_string +=
GET_NAME(filtered_op_graph, temp) +
"-";
1189 "-->Considering sequence " + old_sequence_string);
1192 if(old_sequence.size() > resources_number)
1194 const auto front = old_sequence.front();
1195 old_sequence.pop_front();
1198 std::map<int, double> coeffs;
1209 "---Adding edge " +
GET_NAME(filtered_op_graph, front) +
"-->" +
1213 std::list<vertex> vertices;
1214 debug_filtered_op_graph->TopologicalSort(vertices);
1216 catch(
const char* msg)
1218 debug_filtered_op_graph->WriteDot(
"Error.dot");
1222 catch(
const std::string& msg)
1224 debug_filtered_op_graph->WriteDot(
"Error.dot");
1228 catch(
const std::exception& ex)
1230 debug_filtered_op_graph->WriteDot(
"Error.dot");
1236 debug_filtered_op_graph->WriteDot(
"Error.dot");
1246 std::string old_sequence_string;
1247 for(
const auto temp : old_sequence)
1249 old_sequence_string +=
GET_NAME(filtered_op_graph, temp) +
"-";
1252 "<--New sequence " + old_sequence_string);
1254 new_sequences.insert(old_sequence);
1256 constrained_operations_sequences[basic_block][fu_type] = new_sequences;
1260 std::list<vertex> temp;
1262 constrained_operations_sequences[basic_block][fu_type].insert(temp);
1269 "<--Added sorting constraints for BB" +
1274 for(
const auto operation : loop_operations)
1280 for(
const auto other_operation : loop_operations)
1286 const std::string name =
1288 std::map<int, double> coeffs;
1310 for(
auto const path_end : path_end_to_varindex)
1318 std::map<int, double> coeffs;
1319 coeffs[
static_cast<int>(path_end.second)] = 1.0;
1330 for(
const auto basic_block : loop_bbs)
1335 std::map<int, double> coeffs;
1337 coeffs[
static_cast<int>(bb_to_begin.at(basic_block))] = -1.0;
1344 std::map<int, double> coeffs;
1345 coeffs[
static_cast<int>(bb_to_end.at(basic_block))] = 1.0;
1350 for(boost::tie(oe, oe_end) = boost::out_edges(basic_block, *
basic_block_graph); oe != oe_end; oe++)
1354 if(target_bb_node_info->loop_id == loop_id)
1357 std::map<int, double> coeffs;
1358 coeffs[
static_cast<int>(bb_to_begin.at(
target))] = 1.0;
1359 coeffs[
static_cast<int>(bb_to_end.at(basic_block))] = -1.0;
1368 std::map<int, double> objective_coeffs;
1369 for(
auto const& path_end : path_end_to_varindex)
1371 objective_coeffs[
static_cast<int>(path_end.second)] += 1.0;
1377 solver->print_to_file(
parameters->getOption<std::string>(OPT_output_temporary_directory) +
"/" +
1384 filtered_op_graph->WriteDot(
"HLS_SDC_" +
STR(loop_id) +
".dot");
1387 int ilp_result = solver->solve_ilp();
1402 std::map<int, double> vals;
1403 solver->get_vars_solution(vals);
1404 auto last_relative_step = ControlStep(0u);
1405 for(
const auto operation : loop_operations)
1408 ControlStep current_control_step =
1409 ControlStep(static_cast<unsigned int>(vals[static_cast<int>(begin_variable)]));
1411 "---" +
GET_NAME(filtered_op_graph, operation) +
" scheduled at relative step " +
1412 STR(current_control_step));
1417 if(last_relative_step < current_control_step + cycle_latency)
1419 last_relative_step = current_control_step + cycle_latency;
1431 initial_ctrl_step = last_relative_step + 1u;
1439 for(
const auto loop_bb : loop_bbs)
1442 "-->Checking if operations of BB" +
1450 "---Checking if " +
GET_NAME(filtered_op_graph, loop_operation) +
" has to be moved");
1451 auto curr_vertex_type =
GET_TYPE(filtered_op_graph, loop_operation);
1457 if((curr_vertex_type &
TYPE_PHI) != 0)
1459 bb_barrier[loop_operation].insert(loop_bb);
1464 bb_barrier[loop_operation].insert(loop_bb);
1469 bb_barrier[loop_operation].insert(loop_bb);
1472 if(RW_stmts.find(loop_operation) != RW_stmts.end())
1474 bb_barrier[loop_operation].insert(loop_bb);
1479 bb_barrier[loop_operation].insert(loop_bb);
1484 if(((curr_vertex_type &
TYPE_LOAD) != 0) &&
1487 bb_barrier[loop_operation].insert(loop_bb);
1493 bb_barrier[loop_operation].insert(loop_bb);
1496 if(loop_operation == filtered_op_graph->CGetOpGraphInfo()->entry_vertex)
1498 bb_barrier[loop_operation].insert(loop_bb);
1501 if(loop_operation == filtered_op_graph->CGetOpGraphInfo()->exit_vertex)
1503 bb_barrier[loop_operation].insert(loop_bb);
1510 for(boost::tie(ie, ie_end) = boost::in_edges(loop_operation, *filtered_op_graph); ie != ie_end; ie++)
1512 const auto source = boost::source(*ie, *filtered_op_graph);
1513 if(bb_barrier.count(source))
1515 for(
const auto pred_bb_barrier : bb_barrier.at(source))
1520 " because of " +
GET_NAME(filtered_op_graph, source));
1521 bb_barrier[loop_operation].insert(pred_bb_barrier);
1525 if(bb_barrier.count(loop_operation) && bb_barrier.at(loop_operation).count(loop_bb))
1528 "<--Cannot be moved because depends from a phi in the same bb");
1535 filtered_op_graph->CGetOpNodeInfo(loop_operation)->bb_index);
1536 auto current_bb_dominator = operation_bb;
1537 THROW_ASSERT(boost::in_degree(current_bb_dominator, *dominators) == 1,
1538 "Dominator is not a tree or entry was reached");
1539 boost::tie(ie, ie_end) = boost::in_edges(current_bb_dominator, *dominators);
1540 auto candidate_bb = boost::source(*ie, *dominators);
1544 "---Checking if it can be bemove in BB" +
1547 loop_bbs.count(candidate_bb) == 0)
1552 bool overlapping =
false;
1559 "---" +
GET_NAME(filtered_op_graph, dominator_op) +
" ends at " +
1562 " - " +
GET_NAME(filtered_op_graph, loop_operation) +
" ends at " +
1563 STR(operation_step));
1573 current_bb_dominator = candidate_bb;
1575 "---Updating dominator to BB" +
1577 THROW_ASSERT(boost::in_degree(current_bb_dominator, *dominators) == 1,
1578 "Dominator is not a tree or entry was reached");
1579 boost::tie(ie, ie_end) = boost::in_edges(current_bb_dominator, *dominators);
1580 candidate_bb = boost::source(*ie, *dominators);
1582 if(bb_barrier.count(loop_operation) && bb_barrier.at(loop_operation).count(current_bb_dominator))
1587 if(current_bb_dominator != operation_bb)
1590 "---Operation " +
GET_NAME(filtered_op_graph, loop_operation) +
" has to be moved in BB" +
1592 std::vector<unsigned int> movement;
1603 std::list<vertex> sorted_vertices;
1604 filtered_op_graph->TopologicalSort(sorted_vertices);
1605 for(
const auto sorted_vertex : sorted_vertices)
1607 HLS->
Rsch->
UpdateTime(filtered_op_graph->CGetOpNodeInfo(sorted_vertex)->GetNodeId(),
false);
1667 for(
auto resource_type = 0
U; resource_type != resource_types_number; resource_type++)
1670 if(resources_number < INFINITE_UINT && !allocation_information->is_vertex_bounded(resource_type))
1674 "---There are only " +
STR(resources_number) +
" of type " +
1680 "---There are " +
STR(resources_number) +
" of type " +
1687 for(boost::tie(basic_block, basic_block_end) = boost::vertices(*
basic_block_graph); basic_block != basic_block_end;
1698 for(
const auto operation : filtered_operations)
1714 not_limited_resources.insert(limited_resource);
1719 for(
const auto not_limited_resource : not_limited_resources)
1722 limited_resources.erase(not_limited_resource);
1733 for(
const auto operation : shared_resource.second)
#define TYPE_SWITCH
constant identifying the node type of a SWITCH operation.
bool CanBeSpeculated(const unsigned int node_index) const
Return true if an operation can be speculated.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const HLS_managerRef HLSMgr
information about all the HLS synthesis
int GetSelector() const
Return the selector of this graph.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
Class used to sort operation using ALAP in ascending order as primary key and ASAP ascending order as...
boost::graph_traits< graph >::out_edge_iterator OutEdgeIterator
out_edge_iterator definition.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
#define GET_TYPE(data, vertex_index)
Helper macro returning the type associated with a node.
double clock_period
The clock period.
~SDCScheduling() override
Destructor.
Basic block control flow graph.
DesignFlowStep_Status InternalExec() override
Execute the step.
const CustomUnorderedMap< unsigned int, vertex > & bb_index_map
The index basic block map.
#define TYPE_MULTIIF
constant identifying the a multi-way if
#define TYPE_VPHI
constant string identifying an operation node of type virtual phi-nodes
#define GET_CLASS(obj)
Macro returning the actual type of an object.
std::string get_function_name() const
Return the name of the function.
const operations_graph_constructorRef ogc
reference to the operations graph constructor
#define TYPE_IF
constant identifying the node type of an IF operation.
Class managing the schedule of the operations.
const ParameterConstRef parameters
The set of input parameters.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
const BBGraphInfoConstRef CGetBBGraphInfo() const
Returns the property associated with the graph.
AbsControlStep get_cstep(const vertex &op) const
Returns the clock cycle where the given operation has been scheduled.
const unsigned int funId
identifier of the function to be processed (0 means that it is a global step)
void set_csteps(ControlStep cs)
This method sets the number of control steps.
#define GET_NAME(data, vertex_index)
Helper macro returning the name associated with a node.
BBGraphConstRef basic_block_graph
The basic block cfg graph.
CustomOrderedMap< T, U > CustomMap
boost::graph_traits< graph >::in_edge_iterator InEdgeIterator
in_edge_iterator definition.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
#define DEBUG_SELECTOR
Debug selector.
OpGraphConstRef feedback_op_graph
The operation graph with feedback used to perform scheduling.
AllocationInformationRef allocation_information
Store the technology information.
CustomUnorderedSet< EdgeDescriptor > temp_edges
The set of temporary flow edges added to the op_graph.
static const ControlStep UNKNOWN
Constant used to specify unknown control step.
OpVertexSet operations
Set representing the subset of operations in the specification to be implemented. ...
bool ExistsEdge(const boost::graph_traits< graphs_collection >::vertex_descriptor source, const boost::graph_traits< graphs_collection >::vertex_descriptor target) const
Check if an edge exists.
CustomUnorderedMap< std::pair< vertex, unsigned int >, unsigned int > operation_to_varindex
Map operation-stage to variable index.
This class contains the base representation for a generic frontend flow step which works on a single ...
const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Compute the relationship of this step.
Data structure describing a basic block at tree level.
void ComputeRelationships(DesignFlowStepSet &design_flow_step_set, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
Absolute Control step First field is the basic block Second field is the relative control step...
Include a set of utilities used to manage CPU time measures.
#define TYPE_LOAD
Constant string identifying a memory load operation.
A set of operation vertices.
const std::map< vertex, unsigned int > & get_bb_map_levels() const
Return the map of bb vertex index sorted in topological order.
#define TYPE_PHI
constant string identifying an operation node of type PHI
void WriteDot(const std::string &file_name, const int detail_level=0) const
Writes this graph in dot format.
CustomMap< vertex, size_t > op_levels
For each operation its level.
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
const ScheduleConstRef asap
ASAP.
System dependence + anti-dependence + output dependence graph + flow graph + debug graph...
The key comparison function for vertices set based on levels.
#define TYPE_LABEL
A vertex is of type TYPE_LABEL when it is a target of a goto expression.
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Class specifying ALAP and ASAP algorithms.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
fu_bindingRef Rfu
Store the refcounted functional unit binding of the operations.
ScheduleRef Rsch
Store the refcounted scheduling of the operations.
void UpdateTime(const unsigned int operation_index, bool update_cs=true)
Compute the starting and the ending time of a statement.
This class specifies the characteristic of a particular operation working on a given functional unit...
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
#define CDG_SELECTOR
Control dependence edge selector.
CustomMap< vertex, CustomSet< vertex > > reachability_map
The reachability map built on the basis of dependencies, consolidated choices and current choice...
Data structure used to store the schedule of the operations.
#define TYPE_EXTERNAL
constant identifying the node type of a EXTERNAL operation (a function call)
const int debug_level
The debug level.
Basic block dominator tree.
unsigned int bb_version
The version of bb intermediate representation on which this step was applied.
Classes to describe design flow graph.
void set_execution_end(const vertex &op, ControlStep c_step_end)
Sets the ending clock cycle for the given operation.
Target must be reexecuted.
void bind(const vertex &v, unsigned int unit, unsigned int index=std::numeric_limits< unsigned int >::max())
Binds an operation vertex to a functional unit.
BehavioralHelperConstRef behavioral_helper
The behavioral helper.
#define TYPE_STORE
Constant string identifying a memory store operation.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
Class definition of the sdc scheduling.
Map from operation vertices to value.
#define TYPE_RW
Constant identifying if a TYPE_EXTERNAL write or read memory.
fu_bindingRef res_binding
The binding.
This class contains the base representation for a generic frontend flow step.
const BehavioralHelperConstRef CGetBehavioralHelper() const
Returns the helper associated with the function.
boost::graph_traits< graph >::vertex_iterator VertexIterator
vertex_iterator definition.
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
AllocationInformationConstRef allocation_information
The allocation.
void Initialize() override
Initialize the step.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
This file collects some utility functions and macros.
CONSTREF_FORWARD_DECL(Schedule)
Class managing ALAP and ASAP algorithms.
The key comparison function for vertices set based on levels.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
static const unsigned int UNKNOWN
The value used to identified unknown functional unit.
SDCSorter(const ScheduleConstRef _asap, const ScheduleConstRef _alap, const FunctionBehaviorConstRef _function_behavior, const OpGraphConstRef _op_graph, std::set< vertex, bb_vertex_order_by_map > loop_bbs, const ParameterConstRef _parameters)
Constructor.
Data structure definition for HLS constraints.
const ScheduleConstRef alap
ALAP.
CustomUnorderedSet< unsigned int > limited_resources
Set of reachable operations (in scheduling graph)
bool CheckReachability(const vertex first_operation, const vertex second_operation) const
Check if a path from first_operation to second_operation exists in control flow graph (without feedba...
This file collects some utility functions.
void TopologicalSort(std::list< boost::graph_traits< graphs_collection >::vertex_descriptor > &sorted_vertices) const
Compute the topological order of the graph.
const FunctionBehaviorConstRef function_behavior
The function behavior.
refcount< T > lock() const
CustomUnorderedMap< unsigned int, CustomSet< vertex > > sharing_operations
The set of unbounded operations.
void AddStageConstraints(const meilp_solverRef solver, const vertex operation) const
Add constraints to force consecutive execution of different pipeline stages.
Analysis step that performs some simple code motions over the IR.
static meilp_solverRef create_solver(supported_solvers solver_type)
Factory static member function.
bool operator()(const vertex x, const vertex y) const
Compare position of two vertices.
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.
Class specification of the basic_block structure.
hlsRef HLS
HLS data structure of the function to be analyzed.
This class contains the methods to create a frontend flow step.
SDCScheduling(const ParameterConstRef parameters, const HLS_managerRef HLSMgr, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager, const HLSFlowStepSpecializationConstRef hls_flow_step_specialization)
Constructor.
const BBNodeInfoConstRef CGetBBNodeInfo(const vertex node) const
Return the info associated with a basic block.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
const BBGraphConstRef CGetBBGraph(FunctionBehavior::bb_graph_type gt=FunctionBehavior::BB) const
This method returns the basic block graphs.
const LoopsConstRef CGetLoops() const
Return the loops.
void AddDelayConstraints(const meilp_solverRef solver, const OpGraphConstRef filtered_op_graph, const OpGraphConstRef debug_filtered_op_graph, const std::set< vertex, bb_vertex_order_by_map > &loop_bbs)
Add constraints to force execution in different steps of operations which cannot be chained...
interface of loops finding algorithm
System dependence + anti-dependence + output dependence graph + flow graph.
this class is used to manage the command-line or XML options.
void AddDependenceConstraint(const meilp_solverRef solver, const vertex source, const vertex target, const bool simultaneous) const
Add constraints to force consecutive execution of dependent operations.
Generic class managing scheduling algorithms.
x
Return the smallest n such that 2^n >= _x.
const HLS_constraintsRef HLS_C
store the HLS constraints
int debug_level
The debug level.
This package is used by all HLS packages to manage resource constraints and characteristics.
refcount< const HLSFlowStepSpecialization > HLSFlowStepSpecializationConstRef
const refcount definition of the class
This class provides methods to build an operations graph.
const BBGraphConstRef basic_block_graph
The basic block graph.
#define TYPE_RET
constant string identifying an operation node of type return expr
virtual const CustomUnorderedSet< std::tuple< HLSFlowStep_Type, HLSFlowStepSpecializationConstRef, HLSFlowStep_Relationship > > ComputeHLSRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Compute the relationship of this step.
Data structure definition for high-level synthesis flow.
System dependence + anti-dependence + output dependence graph + flow graph with feedback.
void set_execution(const vertex &op, ControlStep c_step)
Sets the starting clock cycle for the given operation.
#define NULL_VERTEX
null vertex definition
std::list< std::vector< unsigned int > > movements_list
Result of SPECULATIVE_LOOP: the list of movement to be performed (first element is the operation...
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
Datastructure to represent memory information in high-level synthesis.
OpGraphConstRef op_graph
The operation graph used to perform scheduling.
Class specification of the manager of the tree structures extracted from the raw file.
const OpGraphConstRef op_graph
The operation graph.
const bool speculation
flag to check speculation
double margin
The margin which has to be introduced with respect to clock period.
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 TYPE_LAST_OP
A vertex of type LAST_OP if it is the last operation of the application.
This class provide an interface to different solvers.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...