49 #include "config_HAVE_ASSERTS.hpp" 83 const DesignFlowManagerConstRef _design_flow_manager)
93 switch(relationship_type)
97 relationships.insert(std::make_pair(BLOCK_FIX,
SAME_FUNCTION));
98 relationships.insert(std::make_pair(FIX_STRUCTS_PASSED_BY_VALUE,
SAME_FUNCTION));
99 relationships.insert(std::make_pair(FIX_VDEF,
SAME_FUNCTION));
101 relationships.insert(std::make_pair(HWCALL_INJECTION,
SAME_FUNCTION));
102 relationships.insert(std::make_pair(REBUILD_INITIALIZATION,
SAME_FUNCTION));
103 relationships.insert(std::make_pair(REMOVE_CLOBBER_GA,
SAME_FUNCTION));
104 relationships.insert(std::make_pair(SWITCH_FIX,
SAME_FUNCTION));
118 return relationships;
125 TM =
AppM->get_tree_manager();
132 switch(relationship_type)
141 const auto* technology_flow_step_factory = GetPointer<const TechnologyFlowStepFactory>(
143 const std::string technology_flow_signature =
147 technology_flow_step ?
148 design_flow_graph->CGetDesignFlowStepInfo(technology_flow_step)->design_flow_step :
150 relationship.insert(technology_design_flow_step);
230 #define MULT_COST_LESS(X, Y) ((X).cost < (Y) || ((X).cost == (Y) && (X).latency < (Y))) 236 #define CHEAPER_MULT_COST(X, Y) ((X).cost < (Y).cost || ((X).cost == (Y).cost && (X).latency < (Y).latency)) 253 short op_cost, op_latency;
254 unsigned long long int orig_t = t;
255 unsigned long long int q;
256 auto maxm =
static_cast<int>(
std::min(32ull, data_bitsize));
257 bool cache_hit =
false;
265 alg_out.
cost.
cost =
static_cast<short>(cost_limit.
cost + 1);
268 if(cost_limit.
cost < 0 || (cost_limit.
cost == 0 && cost_limit.
latency <= 0))
293 best_cost = cost_limit;
296 std::pair<enum alg_code, struct mult_cost> res =
alg_hash.find(std::make_pair(data_bitsize, t))->second;
297 cache_alg = res.first;
335 goto do_alg_addsub_t_m2;
339 goto do_alg_addsub_factor;
342 goto do_alg_add_t2_m;
345 goto do_alg_sub_t2_m;
369 op_cost =
static_cast<short>(m * 1 );
374 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
375 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
376 synth_mult(alg_in, q, new_limit, data_bitsize, TM);
382 best_cost = alg_in.
cost;
383 std::swap(alg_in, best_alg);
384 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
391 if(static_cast<long long int>(orig_t) < 0)
400 op_cost =
static_cast<short>(m * 1) ;
405 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
406 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
407 synth_mult(alg_in, q, new_limit, data_bitsize, TM);
413 best_cost = alg_in.
cost;
414 std::swap(alg_in, best_alg);
415 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
429 unsigned long long int w;
432 for(w = 1; (w & t) != 0; w <<= 1)
449 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
450 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
451 synth_mult(alg_in, t + 1, new_limit, data_bitsize, TM);
457 best_cost = alg_in.
cost;
458 std::swap(alg_in, best_alg);
459 best_alg.
log[best_alg.
ops] = 0;
468 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
469 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
470 synth_mult(alg_in, t - 1, new_limit, data_bitsize, TM);
476 best_cost = alg_in.
cost;
477 std::swap(alg_in, best_alg);
478 best_alg.
log[best_alg.
ops] = 0;
485 m =
static_cast<int>(
exact_log2(-orig_t + 1));
486 if(m >= 0 && m < maxm)
489 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
490 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
491 synth_mult(alg_in, static_cast<unsigned long long int>(-orig_t + 1) >> m, new_limit, data_bitsize, TM);
497 best_cost = alg_in.
cost;
498 std::swap(alg_in, best_alg);
499 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
520 do_alg_addsub_factor:
521 for(m = static_cast<int>(
floor_log2(t - 1)); m >= 2; m--)
523 unsigned long long int d;
526 if(t % d == 0 && t > d && m < maxm && (!cache_hit || cache_alg ==
alg_add_factor))
543 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
544 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_latency);
545 synth_mult(alg_in, t / d, new_limit, data_bitsize, TM);
555 best_cost = alg_in.
cost;
556 std::swap(alg_in, best_alg);
557 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
565 if(t % d == 0 && t > d && m < maxm && (!cache_hit || cache_alg ==
alg_sub_factor))
582 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
583 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_latency);
584 synth_mult(alg_in, t / d, new_limit, data_bitsize, TM);
594 best_cost = alg_in.
cost;
595 std::swap(alg_in, best_alg);
596 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
615 if(m >= 0 && m < maxm)
618 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
619 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
620 synth_mult(alg_in, (t - 1) >> m, new_limit, data_bitsize, TM);
626 best_cost = alg_in.
cost;
627 std::swap(alg_in, best_alg);
628 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
641 if(m >= 0 && m < maxm)
644 new_limit.
cost =
static_cast<short>(best_cost.
cost - op_cost);
645 new_limit.
latency =
static_cast<short>(best_cost.
latency - op_cost);
646 synth_mult(alg_in, (t + 1) >> m, new_limit, data_bitsize, TM);
652 best_cost = alg_in.
cost;
653 std::swap(alg_in, best_alg);
654 best_alg.
log[best_alg.
ops] =
static_cast<char>(m);
681 alg_hash[std::make_pair(data_bitsize, t)] = std::make_pair(best_alg.
op[best_alg.
ops], last_limit);
686 if(best_alg.
ops == 64)
695 alg_out.
ops =
static_cast<short>(best_alg.
ops + 1);
722 op_cost =
static_cast<short>(2 * data_bitsize * 1 );
723 if(Mult_cost > op_cost)
729 limit.
cost = Mult_cost;
731 synth_mult(alg, static_cast<unsigned long long int>(val), limit, data_bitsize, TM);
735 if(8 *
sizeof(
int) >= data_bitsize)
740 limit.
cost =
static_cast<short>(alg.
cost.
cost - op_cost);
745 limit.
cost =
static_cast<short>(Mult_cost - op_cost);
746 limit.
latency =
static_cast<short>(Mult_cost - op_cost);
749 synth_mult(alg2, static_cast<unsigned long long int>(-val), limit, data_bitsize, TM);
762 limit.
cost =
static_cast<short>(alg.
cost.
cost - op_cost);
767 limit.
cost =
static_cast<short>(Mult_cost - op_cost);
768 limit.
latency =
static_cast<short>(Mult_cost - op_cost);
771 synth_mult(alg2, static_cast<unsigned long long int>(val - 1), limit, data_bitsize, TM);
785 const std::string& srcp_default)
787 long long int val_so_far = 0;
792 auto data_mask = data_bitsize >= 64 ? ~0ULL : (1ULL << data_bitsize) - 1;
816 for(opno = 1; opno < alg.
ops; opno++)
818 auto log = alg.
log[opno];
835 block->PushBefore(tem_ga, stmt,
AppM);
836 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
841 if(log_node != COST0)
846 block->PushBefore(tem_ga, stmt,
AppM);
847 tem = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
858 block->PushBefore(tem_ga, stmt,
AppM);
859 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
865 val_so_far += 1LL << log;
869 if(log_node != COST0)
874 block->PushBefore(tem_ga, stmt,
AppM);
875 tem = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
891 block->PushBefore(tem_ga, stmt,
AppM);
892 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
893 val_so_far -= 1LL << log;
897 if(log_node != COST0 && accum != COST0)
902 block->PushBefore(tem_ga, stmt,
AppM);
903 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
910 block->PushBefore(tem_ga, stmt,
AppM);
911 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
917 val_so_far = (val_so_far << log) + 1;
921 if(log_node != COST0 && accum != COST0)
926 block->PushBefore(tem_ga, stmt,
AppM);
927 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
939 block->PushBefore(tem_ga, stmt,
AppM);
940 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
941 val_so_far = (val_so_far << log) - 1;
945 if(log_node != COST0 && accum != COST0)
950 block->PushBefore(tem_ga, stmt,
AppM);
951 tem = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
962 block->PushBefore(tem_ga, stmt,
AppM);
963 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
969 val_so_far += val_so_far << log;
973 if(log_node != COST0 && accum != COST0)
978 block->PushBefore(tem_ga, stmt,
AppM);
979 tem = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
990 block->PushBefore(tem_ga, stmt,
AppM);
991 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
997 val_so_far = (val_so_far << log) - val_so_far;
1011 val_so_far = -val_so_far;
1015 block->PushBefore(tem_ga, stmt,
AppM);
1016 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
1021 val_so_far = val_so_far + 1;
1025 block->PushBefore(tem_ga, stmt,
AppM);
1026 accum = GetPointer<gimple_assign>(
GET_NODE(tem_ga))->op0;
1032 val = val & data_mask;
1033 val_so_far = val_so_far &
static_cast<long long int>(data_mask);
1035 THROW_ASSERT(val == static_cast<unsigned long long int>(val_so_far),
"unexpected difference");
1043 const std::string& srcp_default)
1045 unsigned long long int masklow;
1054 AppM->RegisterTransformation(
GetName(), signmask_ga);
1055 block->PushBefore(signmask_ga, stmt,
AppM);
1057 type, GetPointer<gimple_assign>(
GET_NODE(signmask_ga))->op0, constm1, const0, srcp_default, cond_expr_K);
1059 const auto signmask_condexpr =
1062 AppM->RegisterTransformation(
GetName(), signmask_condexpr);
1063 block->PushBefore(signmask_condexpr, stmt,
AppM);
1065 auto signmask_var = GetPointer<gimple_assign>(
GET_NODE(signmask_condexpr))->op0;
1068 if(logd > 63 || size < logd)
1072 masklow = (1ULL << logd) - 1;
1080 auto nop_vd = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
1081 block->PushBefore(ga_nop, stmt,
AppM);
1085 block->PushBefore(temp_ga, stmt,
AppM);
1086 nop_vd = GetPointer<gimple_assign>(
GET_NODE(temp_ga))->op0;
1088 block->PushBefore(ga_nop, stmt,
AppM);
1089 signmask_var = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
1097 block->PushBefore(temp_ga, stmt,
AppM);
1098 signmask_var = GetPointer<gimple_assign>(
GET_NODE(temp_ga))->op0;
1104 block->PushBefore(temp_ga, stmt,
AppM);
1105 auto temp_var = GetPointer<gimple_assign>(
GET_NODE(temp_ga))->op0;
1110 block->PushBefore(temp_ga, stmt,
AppM);
1111 temp_var = GetPointer<gimple_assign>(
GET_NODE(temp_ga))->op0;
1118 const std::string& srcp_default)
1127 block->PushBefore(cond_op0_ga, stmt,
AppM);
1128 const auto cond_op0_ga_var = GetPointer<gimple_assign>(
GET_NODE(cond_op0_ga))->op0;
1135 const auto cond_op =
1138 block->PushBefore(t_ga, stmt,
AppM);
1139 const auto cond_ga_var = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1149 block->PushBefore(t_ga, stmt,
AppM);
1150 const auto t_ga_var = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1152 const auto cond_op =
1156 block->PushBefore(t2_ga, stmt,
AppM);
1158 const auto t2_ga_var = GetPointer<gimple_assign>(
GET_NODE(t2_ga))->op0;
1165 const std::string& srcp_default)
1167 if(!
AppM->ApplyNewTransformation())
1172 short int mult_plus_ratio = 3;
1177 ext_op1 <<= 64 - typeSize;
1178 ext_op1 >>= 64 - typeSize;
1180 if(GetPointer<HLS_manager>(
AppM))
1183 bool use64bitMul =
false;
1189 auto fu_prec =
std::max(8ull, ceil_pow2(data_bitsize));
1190 if(fu_prec >= 64 && use64bitMul)
1194 auto component_name_mult =
1197 THROW_ASSERT(mult_f_unit,
"missing component: " + component_name_mult);
1198 auto* mult_fu = GetPointer<functional_unit>(mult_f_unit);
1200 THROW_ASSERT(mult_op_node,
"missing mult_expr from " + component_name_mult);
1201 auto* mult_op = GetPointer<operation>(mult_op_node);
1202 double mult_delay = mult_op->time_m->get_execution_time();
1203 auto component_name_add =
ADDER_STD + std::string(
"_") +
STR(fu_prec) +
"_" +
STR(fu_prec) +
"_" +
STR(fu_prec);
1205 THROW_ASSERT(add_f_unit,
"missing component: " + component_name_add);
1206 auto* add_fu = GetPointer<functional_unit>(add_f_unit);
1208 THROW_ASSERT(add_op_node,
"missing plus_expr from " + component_name_add);
1209 auto* add_op = GetPointer<operation>(add_op_node);
1210 double add_delay = add_op->time_m->get_execution_time();
1211 mult_plus_ratio =
static_cast<short int>(ceil(mult_delay / add_delay));
1220 else if(ext_op1 == 1)
1225 else if(ext_op1 == -1)
1235 short int max_cost =
1241 stmt, block, type_expr, srcp_default);
1244 block->PushBefore(temp_expr_ga, stmt,
AppM);
1256 auto coeff =
static_cast<unsigned long long int>(ext_op1);
1267 short int max_cost =
1271 if(
choose_mult_variant(data_bitsize, static_cast<long long int>(coeff), alg, variant, max_cost,
TM))
1273 return expand_mult_const(op0, coeff, alg, variant, stmt, block, type_expr, srcp_default);
1286 const std::string& srcp_default,
bool temp_addr)
1291 bool changed =
false;
1319 auto* ic_step_node = GetPointer<integer_cst>(
GET_NODE(tmr->
step));
1320 type_sum = ic_step_node->type;
1326 block->PushBefore(t_ga, stmt,
AppM);
1328 accum = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1336 block->PushBefore(t_ga, stmt,
AppM);
1338 accum = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1359 const auto casted_offset_ga =
1361 block->PushBefore(casted_offset_ga, stmt,
AppM);
1364 const auto casted_offset_var = GetPointerS<gimple_assign>(
GET_NODE(casted_offset_ga))->op0;
1372 block->PushBefore(t_ga, stmt,
AppM);
1374 accum = GetPointerS<gimple_assign>(
GET_NODE(t_ga))->op0;
1378 accum = casted_offset_var;
1397 block->PushBefore(casted_idx2_ga, stmt,
AppM);
1407 block->PushBefore(t_ga, stmt,
AppM);
1409 accum = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1413 accum = casted_idx2_var;
1421 block->PushBefore(t_ga, stmt,
AppM);
1423 accum = GetPointer<gimple_assign>(
GET_NODE(t_ga))->op0;
1441 GetPointer<gimple_assign>(
GET_NODE(ae_ga))->temporary_address = temp_addr;
1442 block->PushBefore(ae_ga, stmt,
AppM);
1458 GetPointer<gimple_assign>(
GET_NODE(ppe_ga))->temporary_address = temp_addr;
1459 block->PushBefore(ppe_ga, stmt,
AppM);
1468 const std::list<tree_nodeRef>::const_iterator it_los,
1469 const blocRef&
block,
const std::string& srcp_default)
1491 int half_data_bitsize = data_bitsize / 2;
1500 block->PushBefore(u0_ga, *it_los,
AppM);
1507 block->PushBefore(u1_ga, *it_los,
AppM);
1510 long long int v0 =
static_cast<long long int>(ml) & ((1LL << half_data_bitsize) - 1);
1515 v1 =
static_cast<long long int>(ml >> half_data_bitsize);
1519 v1 =
static_cast<long long int>(ml) >> half_data_bitsize;
1529 u0v0_ga_var = u0_ga_var;
1538 block->PushBefore(u0v0_ga, *it_los,
AppM);
1539 u0v0_ga_var = GetPointer<gimple_assign>(
GET_NODE(u0v0_ga))->op0;
1546 srcp_default, rshift_expr_K);
1549 block->PushBefore(u0v0h_ga, *it_los,
AppM);
1550 u0v0h_ga_var = GetPointer<gimple_assign>(
GET_NODE(u0v0h_ga))->op0;
1553 if(u0v0h_ga_var && !unsignedp)
1559 block->PushBefore(u0v0hU_ga, *it_los,
AppM);
1560 u0v0hU_ga_var = GetPointer<gimple_assign>(
GET_NODE(u0v0hU_ga))->op0;
1564 u0v0hU_ga_var = u0v0h_ga_var;
1571 u1v0_ga_var = u1_ga_var;
1579 block->PushBefore(u1v0_ga, *it_los,
AppM);
1580 u1v0_ga_var = GetPointer<gimple_assign>(
GET_NODE(u1v0_ga))->op0;
1591 block->PushBefore(u0v0hu1v0_ga, *it_los,
AppM);
1592 u0v0hu1v0_ga_var = GetPointer<gimple_assign>(
GET_NODE(u0v0hu1v0_ga))->op0;
1595 if(u0v0hu1v0_ga_var)
1601 block->PushBefore(w1_ga, *it_los,
AppM);
1602 w1_ga_var = GetPointer<gimple_assign>(
GET_NODE(w1_ga))->op0;
1606 if(u0v0hu1v0_ga_var)
1609 srcp_default, rshift_expr_K);
1612 block->PushBefore(w2_ga, *it_los,
AppM);
1613 w2_ga_var = GetPointer<gimple_assign>(
GET_NODE(w2_ga))->op0;
1621 u0v1_ga_var = u0_ga_var;
1630 block->PushBefore(u0v1_ga, *it_los,
AppM);
1631 u0v1_ga_var = GetPointer<gimple_assign>(
GET_NODE(u0v1_ga))->op0;
1643 block->PushBefore(w1u0v1_ga, *it_los,
AppM);
1644 w1u0v1_ga_var = GetPointer<gimple_assign>(
GET_NODE(w1u0v1_ga))->op0;
1648 w1u0v1_ga_var = w1_ga_var;
1651 else if(u0v1_ga_var)
1653 w1u0v1_ga_var = u0v1_ga_var;
1660 srcp_default, rshift_expr_K);
1663 block->PushBefore(w1u0v1h_ga, *it_los,
AppM);
1664 w1u0v1h_ga_var = GetPointer<gimple_assign>(
GET_NODE(w1u0v1h_ga))->op0;
1671 u1v1_ga_var = u1_ga_var;
1679 block->PushBefore(u1v1_ga, *it_los,
AppM);
1680 u1v1_ga_var = GetPointer<gimple_assign>(
GET_NODE(u1v1_ga))->op0;
1692 block->PushBefore(w1u0v1hw2_ga, *it_los,
AppM);
1693 w1u0v1hw2_ga_var = GetPointer<gimple_assign>(
GET_NODE(w1u0v1hw2_ga))->op0;
1697 w1u0v1hw2_ga_var = w1u0v1h_ga_var;
1702 w1u0v1hw2_ga_var = w2_ga_var;
1706 if(w1u0v1hw2_ga_var)
1714 block->PushBefore(res_ga, *it_los,
AppM);
1715 res_ga_var = GetPointer<gimple_assign>(
GET_NODE(res_ga))->op0;
1719 res_ga_var = w1u0v1hw2_ga_var;
1722 else if(u1v1_ga_var)
1724 res_ga_var = u1v1_ga_var;
1734 std::pair<unsigned int, blocRef>
block,
1735 std::list<tree_nodeRef>::const_iterator it_los,
bool temp_addr)
1743 GetPointer<gimple_assign>(
GET_NODE(ae_ga))->temporary_address = temp_addr;
1745 block.second->PushBefore(ae_ga, *it_los,
AppM);
1756 offset_node = GetPointer<gimple_assign>(
GET_NODE(nop_ga))->op0;
1757 block.second->PushBefore(nop_ga, *it_los,
AppM);
1761 offset_node = AR->op1;
1765 "array_type expected: @" +
STR(ar_op0_type_node->index));
1769 for(
size_t ind = 1; ind < dims.size(); ++ind)
1771 n_byte *= dims.at(ind);
1779 block.second->PushBefore(m_ga, *it_los,
AppM);
1784 GetPointer<gimple_assign>(
GET_NODE(pp_ga))->temporary_address = temp_addr;
1786 block.second->PushBefore(pp_ga, *it_los,
AppM);
1796 const auto ga = GetPointer<const gimple_assign>(
GET_CONST_NODE(stmt));
1801 if(op1->get_kind() == cond_expr_K)
1805 if(not ga->init_assignment and op0->
get_kind() == ssa_name_K and op1->get_kind() == var_decl_K)
1811 if(not
AppM->ApplyNewTransformation())
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
This struct specifies the integer_cst node.
T floor_log2(T x)
Given X, an unsigned number, return the largest int Y such that 2**Y <= X. If X is 0...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
bool reached_max_transformation_limit(const tree_nodeRef &stmt)
check if the max transformation limit has been reached
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;.
static std::vector< unsigned long long > GetArrayDimensions(const tree_nodeConstRef &node)
Return the dimension of the array.
static CustomUnorderedMap< std::pair< unsigned int, unsigned long long >, std::pair< enum alg_code, struct mult_cost > > alg_hash
File containing functions and utilities to support the printing of debug messagges.
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
std::string ToString() const
Print this node as string in gimple format.
technology_nodeRef get_fu(const std::string &fu_name, const std::string &Library) const
Return the reference to a component given its name.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
static bool is_unsigned(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of unsigned integer type.
short latency
Total cost of the multiplication sequence.
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
tree_nodeRef idx
INDEX register.
std::string GetName() const override
Return the name of this design step.
tree_nodeRef expand_mult_const(const tree_nodeRef &op0, unsigned long long int val, const struct algorithm &alg, enum mult_variant &variant, const tree_nodeRef &stmt, const blocRef &block, const tree_nodeRef &type, const std::string &srcp_default)
A subroutine of expand_mult, used for constant multiplications.
tree_nodeRef CreateUnsigned(const tree_nodeConstRef &signed_type) const
Create an unsigned integer type starting from signed type.
RelationshipType
The relationship type.
Source must be executed to satisfy target.
mathematical utility function not provided by standard libraries
tree_nodeRef GetSizeType() const
create a sizetype builtin type in case it has not already been created, otherwise it returns the one ...
This structure records a sequence of operations.
Class specification of the graph structures.
exceptions managed by PandA
tree_nodeRef create_binary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const std::string &srcp, enum kind operation_kind) const
Function used to create a binary expression.
G get_parameter(const std::string &key) const
Returns a parameter by key.
IR_lowering(const ParameterConstRef Param, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
Collect information about resource performance.
T exact_log2(T x)
Return the logarithm of X, base 2, considering X unsigned, if X is a power of 2.
static unsigned long long GetArrayElementSize(const tree_nodeConstRef &node)
Return the size (in bits) of the base element of the array.
#define CHEAPER_MULT_COST(X, Y)
This macro is used to compare two mult_costs against each other.
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.
tree_nodeRef base
BASE register.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define LIBRARY_STD_FU
standard library where all standard HLS resources are defined
Class specification of the manager of the technology library data structures.
tree_nodeRef expand_MC(const tree_nodeRef &op0, const integer_cst *ic_node, const tree_nodeRef &old_target, const tree_nodeRef &stmt, const blocRef &block, const tree_nodeRef &type_expr, const std::string &srcp_default)
Data structure describing a basic block at tree level.
static unsigned int get_type_index(const tree_managerConstRef &TM, const unsigned int index, long long int &vec_size, bool &is_a_pointer, bool &is_a_function)
Return the treenode index of the type of index.
redefinition of map to manage ordered/unordered structures
tree_nodeRef create_unary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op, const std::string &srcp, enum kind operation_kind) const
EXPRESSION_TREE_NODES.
tree_nodeRef CreateGimpleAssign(const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, const tree_nodeRef &op, unsigned int function_decl_nid, const std::string &srcp) const
Create gimple assignment.
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.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
void ComputeRelationships(DesignFlowStepSet &relationship, const DesignFlowStep::RelationshipType relationship_type) override
Compute the relationships of a step with other steps.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
#define MULT_COST_LESS(X, Y)
This macro is used to compare a pointer to a mult_cost against an single integer "cost" value...
#define ASSERT_PARAMETER(parameter)
Pure virtual base class for all the design flow step factory.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
#define EXACT_POWER_OF_2_OR_ZERO_P(x)
Test whether a value is zero of a power of two.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
tree_nodeRef GetPointerType(const tree_nodeConstRef &ptd, unsigned long long algn=0) const
Function that creates a pointer type if it is not already present, otherwise it returns the one that ...
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
tree_managerRef TM
The tree manager.
This C++ header file contains common macros for the tree structure.
void Initialize() override
Initialize the step (i.e., like a constructor, but executed just before exec.
mult_variant
Indicates the type of fixup needed after a constant multiplication.
Class specification of the data structures used to manage technology information. ...
static integer_cst_t get_integer_cst_value(const integer_cst *ic)
Convert a integer_cst in a long long value.
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...
Low-level memory addressing.
Classes to describe design flow graph.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
Target must be reexecuted.
static const std::string ComputeSignature(const TechnologyFlowStep_Type technology_flow_step_type)
Compute the signature of a technology flow step.
Factory for technology flow step.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
const Wrefcount< const DesignFlowManager > design_flow_manager
The design flow manager.
unsigned offset[NUM_VERTICES+1]
tree_nodeRef step
STEP integer constant.
#define GET_CONST_NODE(t)
tree_nodeRef expand_smod_pow2(const tree_nodeRef &op0, unsigned long long int d, const tree_nodeRef &stmt, const blocRef &block, const tree_nodeRef &type, const std::string &srcp_default)
Expand signed modulus of OP0 by a power of two D in mode MODE.
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
bool expand_target_mem_ref(target_mem_ref461 *tmr, const tree_nodeRef &stmt, const blocRef &block, const std::string &srcp_default, bool temp_addr)
tree_nodeRef GetBooleanType() const
Function that creates a boolean type if it is not already present, otherwise it returns the one that ...
T compute_n_bytes(T bitsize)
This struct specifies the block node.
This file collects some utility functions.
tree_manipulationRef tree_man
The IR manipulation.
alg_code
the code for lowering of div, mult and rem comes from GCC sources (expmed.c)
tree_nodeRef type
type of the expression
refcount< T > lock() const
tree_nodeRef create_ternary_operation(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const std::string &srcp, enum kind operation_kind) const
Function used to create a ternary expression.
const unsigned int function_id
The index of the function to be analyzed.
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
tree_nodeRef expand_mult_highpart(const tree_nodeRef &op0, unsigned long long int ml, const tree_nodeRef &type_expr, int data_bitsize, const std::list< tree_nodeRef >::const_iterator it_los, const blocRef &block, const std::string &srcp_default)
Decompose some complex gimple statements into set of simple operations.
bool has_parameter(const std::string &key) const
Check if parameter exist.
technology_managerRef get_technology_manager() const
Returns the technology manager.
tree_nodeRef expand_sdiv_pow2(const tree_nodeRef &op0, unsigned long long int d, const tree_nodeRef &stmt, const blocRef &block, const tree_nodeRef &type, const std::string &srcp_default)
Expand signed division of OP0 by a power of two D in mode MODE.
tree_nodeRef array_ref_lowering(array_ref *AR, const std::string &srcp_default, std::pair< unsigned int, blocRef > block, std::list< tree_nodeRef >::const_iterator it_los, bool temp_addr)
This file collects some hash functors.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
tree_nodeRef CreateNopExpr(const tree_nodeConstRef &operand, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, unsigned int function_decl_nid) const
Create a nop_expr to perform a conversion.
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
static void synth_mult(struct algorithm &alg_out, unsigned long long t, const struct mult_cost &cost_limit, unsigned long long data_bitsize, tree_managerRef &TM)
Compute and return the best algorithm for multiplying by T.
tree_nodeRef idx2
INDEX register.
this class is used to manage the command-line or XML options.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
This structure holds the "cost" of a multiply sequence.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
~IR_lowering() override
Destructor.
static bool choose_mult_variant(unsigned long long data_bitsize, long long int val, struct algorithm &alg, enum mult_variant &variant, short int Mult_cost, tree_managerRef &TM)
Find the cheapest way of multiplying a value of mode MODE by VAL.
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
tree_nodeRef offset
OFFSET integer constant.
Class specification of the manager of the tree structures extracted from the raw file.
Base class for technology flow steps.
HLS specialization of generic_device.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...