52 #include "config_HAVE_FROM_DISCREPANCY_BUILT.hpp" 73 #include <boost/range/adaptor/reversed.hpp> 93 #define DEBUG_CALLSITE (__FILE__ + std::string(":") + STR(__LINE__)) 96 unsigned int _function_id,
const DesignFlowManagerConstRef _design_flow_manager)
108 switch(relationship_type)
112 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
114 relationships.insert(std::make_pair(BIT_VALUE,
SAME_FUNCTION));
121 relationships.insert(std::make_pair(PARM2SSA,
SAME_FUNCTION));
122 relationships.insert(std::make_pair(USE_COUNTING,
SAME_FUNCTION));
133 if(!
parameters->getOption<
int>(OPT_gcc_openmp_simd))
135 relationships.insert(std::make_pair(BIT_VALUE,
SAME_FUNCTION));
143 return relationships;
153 if(
parameters->IsParameter(
"bitvalue-opt") && !
parameters->GetParameter<
unsigned int>(
"bitvalue-opt"))
158 const auto TM =
AppM->get_tree_manager();
163 const auto fd = GetPointerS<const function_decl>(tn);
164 THROW_ASSERT(fd && fd->body,
"Node is not a function or it hasn't a body");
185 RangeRef constraintRange(
186 new Range(
Regular, static_cast<Range::bw_t>(nbitType), -(1ll << (nbit - 1)), (1ll << (nbit - 1)) - 1));
189 if(op_ssa->
range->getSpan() < constraintRange->getSpan())
196 op_ssa->
range = constraintRange;
203 RangeRef constraintRange(
new Range(
Regular, static_cast<Range::bw_t>(nbitType), 0, (1ll << nbit) - 1));
206 if(op_ssa->
range->getSpan() < constraintRange->getSpan())
213 op_ssa->
range = constraintRange;
228 size_t index_val = 0;
229 for(
auto current_el : boost::adaptors::reverse(bit_values))
231 if(current_el ==
'1')
239 if(is_signed && bit_values[0] ==
'1')
249 bool is_constant = bit_values.size() != 0;
250 for(
auto current_el : bit_values)
252 if(current_el ==
'U')
272 for(
const auto& use : StmtUses)
274 if(!
AppM->ApplyNewTransformation())
282 AppM->RegisterTransformation(
GetName(), use.first);
288 THROW_ASSERT(GetPointer<const HLS_manager>(
AppM)->get_HLS_device(),
"unexpected condition");
289 const auto hls_d = GetPointerS<const HLS_manager>(
AppM)->get_HLS_device();
290 THROW_ASSERT(hls_d->has_parameter(
"max_lut_size"),
"unexpected condition");
291 const auto max_lut_size = hls_d->get_parameter<
size_t>(
"max_lut_size");
303 if(
AppM->ApplyNewTransformation())
307 const auto p = GetPointer<const ssa_name>(parmssa);
308 THROW_ASSERT(!p->bit_values.empty(),
"unexpected condition");
320 for(
const auto& bb_pair : sl->list_of_bloc)
322 const auto B = bb_pair.second;
324 const auto list_of_stmt =
B->CGetStmtList();
325 for(
const auto& stmt : list_of_stmt)
328 if(!
AppM->ApplyNewTransformation())
331 "<--Skipped because reached limit of CFG transformations");
334 if(GetPointerS<gimple_node>(
GET_NODE(stmt))->keep)
337 "<--Skipped because the statement has been annotated with the keep tag");
340 if(
GET_NODE(stmt)->get_kind() == gimple_assign_K)
342 auto ga = GetPointerS<gimple_assign>(
GET_NODE(stmt));
344 auto ssa = GetPointer<ssa_name>(
GET_NODE(ga->op0));
345 if(ssa && !ssa->bit_values.empty() && !ssa->CGetUseStmts().empty())
347 auto condPropageValue = [&](
tree_nodeRef val, std::string debug_callsite) {
357 const auto& val_type = ssa->type;
359 const auto shift_offset =
361 const auto shl_expr =
368 const auto shr_expr =
373 B->PushBefore(op0_ga, stmt,
AppM);
374 auto op0_ga_var = GetPointerS<gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
375 auto op0_ga_varSSA = GetPointerS<ssa_name>(
GET_CONST_NODE(op0_ga_var));
376 op0_ga_varSSA->bit_values = ssa->bit_values;
383 auto real_BVO = [&] {
384 if(
GET_NODE(ga->op1)->get_kind() == cond_expr_K)
386 const auto me = GetPointerS<cond_expr>(
GET_NODE(ga->op1));
389 const auto condition =
GET_NODE(me->op0);
398 "---Cond expr with constant condition");
407 else if(GetPointer<cst_node>(
GET_NODE(ga->op1)))
411 else if(GetPointer<ssa_name>(
GET_NODE(ga->op1)))
415 else if(
GET_NODE(ga->op1)->get_kind() == view_convert_expr_K)
417 auto vce = GetPointerS<view_convert_expr>(
GET_NODE(ga->op1));
418 if(GetPointer<cst_node>(
GET_NODE(vce->op)))
420 if(
GET_NODE(vce->op)->get_kind() == integer_cst_K)
425 if(bitwidth_op == 32)
432 __conv_union.source =
static_cast<int>(cst_val);
435 else if(bitwidth_op == 64)
440 long long int source;
442 __conv_union.source =
static_cast<long long int>(cst_val);
447 THROW_ERROR(
"not supported floating point bitwidth");
480 if((GetPointer<integer_cst>(
GET_NODE(ga->op1)) || GetPointer<real_cst>(
GET_NODE(ga->op1))) &&
484 "---constant pointer value assignments not considered: " +
490 if(GetPointer<call_expr>(
GET_NODE(ga->op1)) and ga->vdef)
498 if(GetPointer<addr_expr>(
GET_NODE(ga->op1)))
509 const auto& bit_values = ssa->bit_values;
511 auto rel_expr_BVO = [&] {
512 auto* me = GetPointer<binary_expr>(
GET_NODE(ga->op1));
517 const auto is_op0_ssa = GetPointer<const ssa_name>(op0);
518 const auto is_op1_ssa = GetPointer<const ssa_name>(op1);
521 s0 = GetPointerS<const ssa_name>(op0)->bit_values;
525 "---Skipped because bitvalue of op0 is empty");
531 THROW_ASSERT(op0->get_kind() == integer_cst_K,
"unexpected condition");
535 s1 = GetPointerS<const ssa_name>(op1)->bit_values;
539 "---Skipped because bitvalue of op1 is empty");
545 THROW_ASSERT(op1->get_kind() == integer_cst_K,
"unexpected condition");
547 if(!is_op0_ssa && !is_op1_ssa)
552 unsigned int trailing_zero = 0;
564 for(
auto s0it = s0.rbegin(), s1it = s1.rbegin(), s0end = s0.rend(), s1end = s1.rend();
565 s0it != s0end && s1it != s1end; ++s0it, ++s1it)
567 if((*s0it == *s1it && (*s1it ==
'0' || *s1it ==
'1')) || *s0it ==
'X' || *s1it ==
'X')
576 auto min_size =
std::min(s0.size(), s1.size());
577 if(trailing_zero < min_size && trailing_zero)
580 "-->Bit Value Opt: " + std::string(
GET_NODE(ga->op1)->get_kind_text()) +
581 " optimized, nbits = " +
STR(trailing_zero));
585 const auto srcp_default =
586 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
592 const auto op0_const_node =
595 srcp_default, rshift_expr_K);
596 const auto op0_ga = IRman->
CreateGimpleAssign(op0_op_type,
nullptr,
nullptr, op0_expr,
599 B->PushBefore(op0_ga, stmt,
AppM);
600 const auto op0_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
603 auto op0_ssa = GetPointer<ssa_name>(
GET_NODE(op0_ga_var));
604 THROW_ASSERT(s0.size() - trailing_zero > 0,
"unexpected condition");
605 op0_ssa->bit_values = s0.substr(0, s0.size() - trailing_zero);
617 const auto op1_const_node =
620 srcp_default, rshift_expr_K);
621 const auto op1_ga = IRman->
CreateGimpleAssign(op1_op_type,
nullptr,
nullptr, op1_expr,
624 B->PushBefore(op1_ga, stmt,
AppM);
625 const auto op1_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op1_ga))->op0;
628 const auto op1_ssa = GetPointer<ssa_name>(
GET_NODE(op1_ga_var));
629 THROW_ASSERT(s1.size() - trailing_zero > 0,
"unexpected condition");
630 op1_ssa->bit_values = s1.substr(0, s1.size() - trailing_zero);
647 "---Left part is constant " + bit_values);
659 if(
AppM->ApplyNewTransformation())
661 if(
GET_CONST_NODE(ga->op0)->get_kind() == ssa_name_K && ga->predicate)
670 "---zero predicated statement: " + stmt->ToString());
686 auto ssa_name_BVO = [&] {
687 if(!ssa->bit_values.empty() && ssa->bit_values.at(0) ==
'0' && ssa->bit_values.size() <= 64)
689 const auto srcp_default =
690 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
691 const auto bit_mask_constant_node =
694 ssa->type, ga->op1, bit_mask_constant_node, srcp_default, bit_and_expr_K);
696 "---replace ssa usage before: " + stmt->ToString());
699 "---replace ssa usage after: " + stmt->ToString());
719 auto mult_expr_BVO = [&] {
720 const auto me = GetPointer<const binary_expr>(
GET_CONST_NODE(ga->op1));
727 if(!isSigned &&
GET_CONST_NODE(ga->op1)->get_kind() == mult_expr_K &&
728 (data_bitsize_in0 == 1 || data_bitsize_in1 == 1))
733 const auto srcp_default =
734 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
737 bt, data_bitsize_in0 == 1 ? me->op0 : me->op1, constNE0, srcp_default, ne_expr_K);
742 B->PushBefore(op0_ga, stmt,
AppM);
743 const auto op0_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
746 ga_op_type, op0_ga_var, data_bitsize_in1 == 1 ? me->op0 : me->op1, const0, srcp_default,
752 "---Replacing " +
STR(ga->op1) +
" with " +
STR(cond_op) +
" in " +
756 "---replace expression with a cond_expr: " + stmt->ToString());
760 unsigned int trailing_zero_op0 = 0;
761 unsigned int trailing_zero_op1 = 0;
762 std::string bit_values_op0;
763 std::string bit_values_op1;
764 bool is_op0_ssa = op0->get_kind() == ssa_name_K;
765 bool is_op1_ssa = op1->get_kind() == ssa_name_K;
768 bit_values_op0 = GetPointer<const ssa_name>(op0)->bit_values;
769 if(bit_values_op0.empty())
772 "---Skipped because bitvalue of op0 is empty");
775 for(
auto current_el : boost::adaptors::reverse(bit_values_op0))
777 if(current_el ==
'0' || current_el ==
'X')
789 THROW_ASSERT(op0->get_kind() == integer_cst_K,
"unexpected case");
792 for(
unsigned int index = 0;
index < bit_values_op0.size() && cst_val != 0; ++
index)
806 bit_values_op1 = GetPointer<const ssa_name>(op1)->bit_values;
807 if(bit_values_op1.empty())
810 "---Skipped because bitvalue of op1 is empty");
813 for(
auto current_el : boost::adaptors::reverse(bit_values_op1))
815 if(current_el ==
'0' || current_el ==
'X')
827 THROW_ASSERT(op1->get_kind() == integer_cst_K,
"unexpected case");
830 for(
unsigned int index = 0;
index < bit_values_op1.size() && cst_val != 0; ++
index)
842 if(trailing_zero_op0 != 0 || trailing_zero_op1 != 0)
847 "-->Bit Value Opt: mult_expr/widen_mult_expr optimized, nbits = " +
848 STR(trailing_zero_op0 + trailing_zero_op1));
850 const auto srcp_default =
851 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
852 if(trailing_zero_op0 != 0)
856 static_cast<long long int>(trailing_zero_op0), op0_type);
858 srcp_default, rshift_expr_K);
862 B->PushBefore(op0_ga, stmt,
AppM);
863 const auto op0_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
868 auto op0_ssa = GetPointer<ssa_name>(
GET_NODE(op0_ga_var));
869 THROW_ASSERT(bit_values_op0.size() - trailing_zero_op0 > 0,
"unexpected condition");
870 op0_ssa->bit_values =
871 bit_values_op0.substr(0, bit_values_op0.size() - trailing_zero_op0);
875 if(trailing_zero_op1 != 0 && !squareP)
879 static_cast<long long int>(trailing_zero_op1), op1_type);
881 srcp_default, rshift_expr_K);
885 B->PushBefore(op1_ga, stmt,
AppM);
886 const auto op1_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op1_ga))->op0;
891 auto* op1_ssa = GetPointer<ssa_name>(
GET_NODE(op1_ga_var));
892 THROW_ASSERT(bit_values_op1.size() - trailing_zero_op1 > 0,
"unexpected condition");
893 op1_ssa->bit_values =
894 bit_values_op1.substr(0, bit_values_op1.size() - trailing_zero_op1);
899 const auto ssa_vd = IRman->
create_ssa_name(
nullptr, ga_op_type,
nullptr,
nullptr);
900 auto sn = GetPointer<ssa_name>(
GET_NODE(ssa_vd));
902 THROW_ASSERT(ssa->bit_values.size() - trailing_zero_op0 - trailing_zero_op1 > 0,
903 "unexpected condition");
904 sn->bit_values = ssa->bit_values.substr(0, ssa->bit_values.size() - trailing_zero_op0 -
907 const auto op_const_node =
910 srcp_default, lshift_expr_K);
911 const auto curr_ga = IRman->
CreateGimpleAssign(ga_op_type, ssa->min, ssa->max, op_expr,
915 curr_ga, GetPointer<const gimple_assign>(
GET_CONST_NODE(curr_ga))->op0, ga->op0);
917 B->PushAfter(curr_ga, stmt,
AppM);
927 auto plus_minus_BVO = [&] {
928 const auto me = GetPointer<const binary_expr>(
GET_CONST_NODE(ga->op1));
942 const auto op_const_node =
944 const auto srcp_default =
945 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
947 srcp_default, lshift_expr_K);
958 bool is_op0_ssa = op0->get_kind() == ssa_name_K;
959 bool is_op1_ssa = op1->get_kind() == ssa_name_K;
960 std::string bit_values_op0;
961 std::string bit_values_op1;
966 ->CGetBehavioralHelper()
967 ->PrintVariable(output_uid) +
968 " bitstring: " + bit_values);
969 unsigned int trailing_zero_op0 = 0;
970 unsigned int trailing_zero_op1 = 0;
971 bool is_op0_null =
false;
972 bool is_op1_null =
false;
978 bit_values_op0 = GetPointerS<const ssa_name>(op0)->bit_values;
979 if(bit_values_op0.empty())
982 "---Skipped because bitvalue of op0 is empty");
988 ->CGetBehavioralHelper()
990 " bitstring: " + bit_values_op0);
991 for(
const auto& current_el : boost::adaptors::reverse(bit_values_op0))
993 if(current_el ==
'0' || current_el ==
'X')
1002 if(bit_values_op0.find_first_not_of(
"0X") == std::string::npos ||
1003 trailing_zero_op0 >= bit_values.size())
1010 THROW_ASSERT(op0->get_kind() == integer_cst_K,
"unexpected case");
1027 ++trailing_zero_op0;
1030 if(trailing_zero_op0 >= bit_values.size())
1041 bit_values_op0 = GetPointerS<const ssa_name>(op0)->bit_values;
1042 if(bit_values_op0.empty())
1045 "---Skipped because bitvalue of op0 is empty");
1053 bit_values_op1 = GetPointerS<const ssa_name>(op1)->bit_values;
1054 if(bit_values_op1.empty())
1057 "---Skipped because bitvalue of op1 is empty");
1063 ->CGetBehavioralHelper()
1065 " bitstring: " + bit_values_op1);
1066 for(
const auto& current_el : boost::adaptors::reverse(bit_values_op1))
1068 if(current_el ==
'0' || current_el ==
'X')
1070 ++trailing_zero_op1;
1077 if(bit_values_op1.find_first_not_of(
"0X") == std::string::npos ||
1078 trailing_zero_op1 >= bit_values.size())
1085 THROW_ASSERT(op1->get_kind() == integer_cst_K,
"unexpected case");
1102 ++trailing_zero_op1;
1105 if(trailing_zero_op1 >= bit_values.size())
1113 "---Trailing zeros op0=" +
STR(trailing_zero_op0) +
1114 ", trailing zeros op1=" +
STR(trailing_zero_op1));
1119 else if(is_op1_null)
1123 else if(trailing_zero_op0 != 0 || trailing_zero_op1 != 0)
1127 const auto srcp_default =
1128 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1129 const auto is_first_max = trailing_zero_op0 > trailing_zero_op1;
1131 auto shift_const = is_first_max ? trailing_zero_op0 : trailing_zero_op1;
1134 "---Bit Value Opt: " +
1136 std::string(
"plus_expr") :
1137 std::string(
"minus_expr")) +
1138 " optimized, nbits = " +
STR(shift_const));
1139 const auto shift_constant_node =
1143 const auto b_node = is_first_max ? me->op1 : me->op0;
1144 const auto b_type = is_first_max ? op1_type : op0_type;
1148 const auto cst_val =
1150 if(ssa->bit_values.size() <= shift_const)
1156 if((cst_val >> shift_const) == 0)
1158 is_op0_null =
GET_CONST_NODE(ga->op1)->get_kind() == plus_expr_K;
1166 std::string resulting_bit_values;
1168 if((bit_values_op0.size() - shift_const) > 0)
1170 resulting_bit_values = bit_values_op0.substr(0, bit_values_op0.size() - shift_const);
1174 resulting_bit_values = bit_values_op0.substr(0, 1);
1178 resulting_bit_values =
"0";
1181 if(resulting_bit_values.find_first_not_of(
"0X") == std::string::npos &&
1189 op0_type, me->op0, shift_constant_node, srcp_default, rshift_expr_K);
1193 B->PushBefore(op0_ga, stmt,
AppM);
1194 const auto op0_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
1196 "---Replacing " + me->op0->ToString() +
" with " +
1197 op0_ga_var->ToString() +
" in " + stmt->ToString());
1199 #if HAVE_FROM_DISCREPANCY_BUILT 1206 parameters->getOption<
bool>(OPT_discrepancy))
1208 AppM->RDiscr->ssa_to_skip_if_address.insert(
GET_NODE(op0_ga_var));
1211 auto op0_ssa = GetPointer<ssa_name>(
GET_NODE(op0_ga_var));
1213 THROW_ASSERT(resulting_bit_values.size() > 0,
"unexpected condition");
1214 op0_ssa->bit_values = resulting_bit_values;
1219 ->CGetBehavioralHelper()
1221 " bitstring: " +
STR(op0_ssa->bit_values));
1227 const auto cst_val =
1229 if(ssa->bit_values.size() <= shift_const)
1235 if((cst_val >> shift_const) == 0)
1245 std::string resulting_bit_values;
1247 if((bit_values_op1.size() - shift_const) > 0)
1249 resulting_bit_values = bit_values_op1.substr(0, bit_values_op1.size() - shift_const);
1253 resulting_bit_values = bit_values_op1.substr(0, 1);
1257 resulting_bit_values =
"0";
1260 if(resulting_bit_values.find_first_not_of(
"0X") == std::string::npos)
1267 op1_type, me->op1, shift_constant_node, srcp_default, rshift_expr_K);
1271 B->PushBefore(op1_ga, stmt,
AppM);
1272 const auto op1_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op1_ga))->op0;
1274 "---Replacing " + me->op1->ToString() +
" with " +
1275 op1_ga_var->ToString() +
" in " + stmt->ToString());
1277 #if HAVE_FROM_DISCREPANCY_BUILT 1284 parameters->getOption<
bool>(OPT_discrepancy))
1286 AppM->RDiscr->ssa_to_skip_if_address.insert(
GET_NODE(op1_ga_var));
1289 auto* op1_ssa = GetPointer<ssa_name>(
GET_NODE(op1_ga_var));
1291 THROW_ASSERT(resulting_bit_values.size() > 0,
"unexpected condition");
1292 op1_ssa->bit_values = resulting_bit_values;
1297 ->CGetBehavioralHelper()
1299 " bitstring: " +
STR(op1_ssa->bit_values));
1310 else if(is_op1_null)
1322 B->PushBefore(curr_ga, stmt,
AppM);
1323 const auto curr_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(curr_ga))->op0;
1324 #if HAVE_FROM_DISCREPANCY_BUILT 1332 AppM->RDiscr->ssa_to_skip_if_address.insert(
GET_NODE(curr_ga_var));
1335 auto op_ssa = GetPointer<ssa_name>(
GET_NODE(curr_ga_var));
1337 THROW_ASSERT(ssa->bit_values.size() - shift_const > 0,
"unexpected condition");
1338 op_ssa->bit_values = ssa->bit_values.substr(0, ssa->bit_values.size() - shift_const);
1343 ->CGetBehavioralHelper()
1345 " bitstring: " +
STR(op_ssa->bit_values));
1348 ga_op_type, curr_ga_var, shift_constant_node, srcp_default, lshift_expr_K);
1349 const auto lshift_ga = IRman->
CreateGimpleAssign(ga_op_type,
nullptr,
nullptr, op_expr,
1352 B->PushBefore(lshift_ga, stmt,
AppM);
1353 const auto lshift_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(lshift_ga))->op0;
1355 auto lshift_ssa = GetPointer<ssa_name>(
GET_NODE(lshift_ga_var));
1356 THROW_ASSERT(ssa->bit_values.size() - shift_const > 0,
"unexpected condition");
1357 lshift_ssa->bit_values = ssa->bit_values.substr(0, ssa->bit_values.size() - shift_const);
1358 while(lshift_ssa->bit_values.size() < ssa->bit_values.size())
1360 lshift_ssa->bit_values.push_back(
'0');
1366 ->CGetBehavioralHelper()
1368 " bitstring: " +
STR(lshift_ssa->bit_values));
1370 bool do_final_or =
false;
1371 unsigned int n_iter = 0;
1372 for(
const auto& cur_bit : boost::adaptors::reverse(ssa->bit_values))
1374 if(cur_bit ==
'1' || cur_bit ==
'U')
1380 if(n_iter == shift_const)
1388 #if HAVE_FROM_DISCREPANCY_BUILT 1396 AppM->RDiscr->ssa_to_skip_if_address.insert(
GET_NODE(lshift_ga_var));
1406 ga_op_type, lshift_ga_var, b_node_val, shift_constant_node,
1407 srcp_default, bit_ior_concat_expr_K));
1412 static_cast<long long int>((1ULL << shift_const) - 1), b_type);
1414 b_type, b_node, bit_mask_constant_node, srcp_default, bit_and_expr_K);
1418 B->PushBefore(band_ga, stmt,
AppM);
1419 const auto band_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(band_ga))->op0;
1420 #if HAVE_FROM_DISCREPANCY_BUILT 1427 parameters->getOption<
bool>(OPT_discrepancy))
1429 AppM->RDiscr->ssa_to_skip_if_address.insert(
GET_NODE(band_ga_var));
1432 auto band_ssa = GetPointer<ssa_name>(
GET_NODE(band_ga_var));
1434 for(
const auto& cur_bit : boost::adaptors::reverse(ssa->bit_values))
1436 band_ssa->bit_values = cur_bit + band_ssa->bit_values;
1437 if(band_ssa->bit_values.size() == shift_const)
1442 band_ssa->bit_values =
"0" + band_ssa->bit_values;
1447 ->CGetBehavioralHelper()
1449 " bitstring: " +
STR(band_ssa->bit_values));
1452 ga_op_type, lshift_ga_var, band_ga_var, shift_constant_node, srcp_default,
1453 bit_ior_concat_expr_K);
1469 const auto srcp_default =
1470 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1471 const auto res_expr =
1484 auto eq_ne_expr_BVO = [&] {
1485 const auto me = GetPointer<const binary_expr>(
GET_CONST_NODE(ga->op1));
1486 const auto& op0 = me->op0;
1487 const auto& op1 = me->op1;
1494 bool is_op1_zero =
false;
1503 if(op0->index == op1->index)
1505 const auto const_value =
GET_CONST_NODE(ga->op1)->get_kind() == eq_expr_K ? 1LL : 0LL;
1509 else if(is_op1_zero &&
GET_CONST_NODE(ga->op1)->get_kind() == ne_expr_K && op0_size == 1)
1513 if(data_bitsize == 1)
1516 if(!ssa->CGetUseStmts().empty())
1518 if(
AppM->ApplyNewTransformation())
1520 const auto srcp_default =
1521 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1522 const auto nop_expr_node =
1532 const auto srcp_default =
1533 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1536 op0_op_type, me->op0, one_const_node, srcp_default, bit_and_expr_K);
1542 B->PushBefore(op0_ga, stmt,
AppM);
1543 const auto op0_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
1547 B->PushBefore(ga_nop, stmt,
AppM);
1550 const auto nop_ga_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(ga_nop))->op0;
1571 auto bit_expr_BVO = [&] {
1572 const auto me = GetPointer<const binary_expr>(
GET_CONST_NODE(ga->op1));
1573 const auto& op0 = me->op0;
1574 const auto& op1 = me->op1;
1578 bool is_op0_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(op0));
1579 bool is_op1_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(op1));
1582 s0 = GetPointer<const ssa_name>(
GET_CONST_NODE(op0))->bit_values;
1586 "---Skipped because bitvalue of s0 is empty");
1597 s1 = GetPointer<const ssa_name>(
GET_CONST_NODE(op1))->bit_values;
1601 "---Skipped because bitvalue of s1 is empty");
1611 unsigned int trailing_zero = 0;
1612 bool is_zero0 = s0.find_first_not_of(
"0X") == std::string::npos;
1616 is_zero0 = uvalue == 0;
1619 bool is_zero1 = s1.find_first_not_of(
"0X") == std::string::npos;
1623 is_zero1 = uvalue == 0;
1626 if(is_zero0 || is_zero1)
1631 "---replace bit_and_expr usage before: " + stmt->ToString());
1639 "---replace bit_xor_expr usage before: " + stmt->ToString());
1640 const auto val = is_zero0 ? op1 : op0;
1646 for(
auto s0it = s0.rbegin(), s1it = s1.rbegin(), s0end = s0.rend(), s1end = s1.rend();
1647 s0it != s0end && s1it != s1end; ++s0it, ++s1it)
1649 if((expr_kind == bit_and_expr_K && (*s0it ==
'0' || *s1it ==
'0')) || *s0it ==
'X' ||
1659 auto min_size =
std::min(s0.size(), s1.size());
1660 if(trailing_zero < min_size && trailing_zero)
1663 "---Bit Value Opt: " + std::string(
GET_NODE(ga->op1)->get_kind_text()) +
1664 " optimized, nbits = " +
STR(trailing_zero));
1667 const auto srcp_default =
1668 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1676 srcp_default, rshift_expr_K);
1677 const auto op0_ga = IRman->
CreateGimpleAssign(op0_op_type,
nullptr,
nullptr, op0_expr,
1680 B->PushBefore(op0_ga, stmt,
AppM);
1681 const auto op0_ga_var = GetPointerS<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
1684 auto op0_ssa = GetPointerS<ssa_name>(
GET_NODE(op0_ga_var));
1685 THROW_ASSERT(s0.size() - trailing_zero > 0,
"unexpected condition");
1686 op0_ssa->bit_values = s0.substr(0, s0.size() - trailing_zero);
1691 const auto cst_val =
1698 const auto op1_const_node =
1701 srcp_default, rshift_expr_K);
1702 const auto op1_ga = IRman->
CreateGimpleAssign(op1_op_type,
nullptr,
nullptr, op1_expr,
1705 B->PushBefore(op1_ga, stmt,
AppM);
1706 const auto op1_ga_var = GetPointerS<const gimple_assign>(
GET_CONST_NODE(op1_ga))->op0;
1709 auto op1_ssa = GetPointerS<ssa_name>(
GET_NODE(op1_ga_var));
1710 THROW_ASSERT(s1.size() - trailing_zero > 0,
"unexpected condition");
1711 op1_ssa->bit_values = s1.substr(0, s1.size() - trailing_zero);
1716 const auto cst_val =
1722 const auto ssa_vd = IRman->
create_ssa_name(
nullptr, ga_op_type,
nullptr,
nullptr);
1723 auto sn = GetPointerS<ssa_name>(
GET_NODE(ssa_vd));
1725 THROW_ASSERT(ssa->bit_values.size() - trailing_zero > 0,
"unexpected condition");
1726 sn->bit_values = ssa->bit_values.substr(0, ssa->bit_values.size() - trailing_zero);
1728 const auto op_const_node =
1731 srcp_default, lshift_expr_K);
1732 const auto curr_ga = IRman->
CreateGimpleAssign(ga_op_type, ssa->min, ssa->max, op_expr,
1736 curr_ga, GetPointer<const gimple_assign>(
GET_CONST_NODE(curr_ga))->op0, ga->op0);
1738 B->PushAfter(curr_ga, stmt,
AppM);
1747 auto cond_expr_BVO = [&] {
1748 const auto me = GetPointer<const cond_expr>(
GET_CONST_NODE(ga->op1));
1752 const auto cond_op0_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(me->op0));
1755 const auto defStmt =
GET_CONST_NODE(cond_op0_ssa->CGetDefStmt());
1756 if(defStmt->get_kind() == gimple_assign_K)
1758 const auto prev_ga = GetPointer<const gimple_assign>(defStmt);
1759 const auto prev_code1 =
GET_CONST_NODE(prev_ga->op1)->get_kind();
1760 if(prev_code1 == nop_expr_K)
1762 const auto ne = GetPointer<const nop_expr>(
GET_CONST_NODE(prev_ga->op1));
1766 "---replace cond_expr condition before: " + stmt->ToString());
1769 "---replace cond_expr condition after: " + stmt->ToString());
1777 if(!
AppM->ApplyNewTransformation())
1780 "---Skipped because reached limit of cfg transformations");
1783 const auto& op0 = me->op1;
1784 const auto& op1 = me->op2;
1791 else if(condition->get_kind() == integer_cst_K)
1794 "---Cond expr with constant condition");
1803 bool is_op0_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(op0));
1804 bool is_op1_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(op1));
1805 unsigned long long s0_precision = 0;
1806 bool is_s0_null =
false;
1807 bool is_s0_one =
false;
1810 s0 = GetPointerS<const ssa_name>(
GET_CONST_NODE(op0))->bit_values;
1814 "---Skipped because so is empty");
1817 s0_precision =
static_cast<unsigned int>(s0.size());
1818 is_s0_null = s0.find_first_not_of(
"0X") == std::string::npos;
1819 is_s0_one = s0 ==
"1" || s0 ==
"01";
1828 is_s0_null = uvalue == 0;
1829 is_s0_one = uvalue == 1;
1831 unsigned long long s1_precision = 0;
1832 bool is_s1_null =
false;
1833 bool is_s1_one =
false;
1836 s1 = GetPointerS<const ssa_name>(
GET_CONST_NODE(op1))->bit_values;
1840 "---Skipped because s1 is empty");
1843 s1_precision =
static_cast<unsigned int>(s1.size());
1844 is_s1_null = s1.find_first_not_of(
"0X") == std::string::npos;
1845 is_s1_one = s1 ==
"1" || s1 ==
"01";
1854 is_s1_null = uvalue == 0;
1855 is_s1_one = uvalue == 1;
1858 unsigned long long minimum_precision =
std::min(s0_precision, s1_precision);
1859 unsigned int trailing_eq = 0;
1861 "---Bit_value strings are " + s0 +
" and " + s1);
1864 if((s0[s0.size() -
index - 1] ==
'0' || s0[s0.size() -
index - 1] ==
'X') &&
1865 (s1[s1.size() -
index - 1] ==
'0' || s1[s1.size() -
index - 1] ==
'X'))
1877 "---Bit Value Opt: cond_expr optimized, nbits = " +
STR(trailing_eq));
1879 const auto srcp_default =
1880 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
1886 const auto op0_const_node =
1889 op0_op_type, me->op1, op0_const_node, srcp_default, rshift_expr_K);
1890 const auto op0_ga = IRman->
CreateGimpleAssign(op0_op_type,
nullptr,
nullptr, op0_expr,
1893 B->PushBefore(op0_ga, stmt,
AppM);
1894 const auto op0_ga_var = GetPointerS<const gimple_assign>(
GET_CONST_NODE(op0_ga))->op0;
1897 auto op0_ssa = GetPointerS<ssa_name>(
GET_NODE(op0_ga_var));
1898 THROW_ASSERT(s0.size() - trailing_eq > 0,
"unexpected condition");
1899 op0_ssa->bit_values = s0.substr(0, s0.size() - trailing_eq);
1904 const auto cst_val =
1911 const auto op1_const_node =
1914 op1_op_type, me->op2, op1_const_node, srcp_default, rshift_expr_K);
1918 B->PushBefore(op1_ga, stmt,
AppM);
1919 const auto op1_ga_var = GetPointerS<const gimple_assign>(
GET_CONST_NODE(op1_ga))->op0;
1922 auto op1_ssa = GetPointerS<ssa_name>(
GET_NODE(op1_ga_var));
1923 THROW_ASSERT(s1.size() - trailing_eq > 0,
"unexpected condition");
1924 op1_ssa->bit_values = s1.substr(0, s1.size() - trailing_eq);
1929 const auto cst_val =
1934 const auto ssa_vd = IRman->
create_ssa_name(
nullptr, ga_op_type,
nullptr,
nullptr);
1935 auto* sn = GetPointer<ssa_name>(
GET_NODE(ssa_vd));
1937 if(ssa->bit_values.size())
1939 THROW_ASSERT(ssa->bit_values.size() - trailing_eq > 0,
"unexpected condition");
1940 sn->bit_values = ssa->bit_values.substr(0, ssa->bit_values.size() - trailing_eq);
1943 const auto op_const_node =
1946 srcp_default, lshift_expr_K);
1947 const auto curr_ga = IRman->
CreateGimpleAssign(ga_op_type, ssa->min, ssa->max, op_expr,
1951 curr_ga, GetPointer<const gimple_assign>(
GET_CONST_NODE(curr_ga))->op0, ga->op0);
1953 B->PushAfter(curr_ga, stmt,
AppM);
1957 else if(is_s0_one && is_s1_null)
1960 "---Cond expr with true and false");
1970 B->PushBefore(ga_nop, stmt,
AppM);
1973 cond_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(ga_nop))->op0;
1977 else if(is_s0_null && is_s1_one)
1980 "---Cond expr with false and true");
1984 const auto new_stmt = GetPointer<const ssa_name>(
GET_CONST_NODE(new_ssa))->CGetDefStmt();
1985 B->PushBefore(new_stmt, stmt,
AppM);
1995 B->PushBefore(ga_nop, stmt,
AppM);
1996 cond_var = GetPointer<const gimple_assign>(
GET_CONST_NODE(ga_nop))->op0;
2006 auto bit_ior_expr_BVO = [&] {
2007 const auto bie = GetPointer<const bit_ior_expr>(
GET_CONST_NODE(ga->op1));
2036 else if(
GET_CONST_NODE(ga->op1)->get_kind() == pointer_plus_expr_K)
2038 auto pointer_plus_expr_BVO = [&] {
2039 const auto ppe = GetPointer<const pointer_plus_expr>(
GET_CONST_NODE(ga->op1));
2049 const auto temp_def =
2051 if(temp_def->get_kind() == gimple_assign_K)
2053 const auto prev_ga = GetPointer<const gimple_assign>(temp_def);
2054 if(
GET_CONST_NODE(prev_ga->op1)->get_kind() == pointer_plus_expr_K)
2056 const auto prev_ppe =
2057 GetPointer<const pointer_plus_expr>(
GET_CONST_NODE(prev_ga->op1));
2065 "---replace constant usage before: " + stmt->ToString());
2069 "---replace constant usage after: " + stmt->ToString());
2078 pointer_plus_expr_BVO();
2082 auto addr_expr_BVO = [&] {
2083 const auto ae = GetPointer<const addr_expr>(
GET_CONST_NODE(ga->op1));
2085 if(ae_code == mem_ref_K)
2087 const auto MR = GetPointer<const mem_ref>(
GET_CONST_NODE(ae->op));
2089 if(op1_val == 0 &&
GET_CONST_NODE(MR->op0)->get_kind() == ssa_name_K)
2091 const auto temp_def =
2093 if(temp_def->get_kind() == gimple_assign_K)
2095 const auto prev_ga = GetPointer<const gimple_assign>(temp_def);
2102 else if(op1_val == 0 &&
GET_CONST_NODE(MR->op0)->get_kind() == integer_cst_K)
2105 "---replace constant usage before: " + stmt->ToString());
2109 "---replace constant usage after: " + stmt->ToString());
2115 else if(
GET_NODE(ga->op1)->get_kind() == extract_bit_expr_K)
2117 auto extract_bit_expr_BVO = [&] {
2118 const auto srcp_default =
2119 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
2120 const auto ebe = GetPointer<const extract_bit_expr>(
GET_CONST_NODE(ga->op1));
2124 const auto ebe_op0_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(ebe->op0));
2134 "---replace extract_bit_expr usage before: " + stmt->ToString());
2143 B->PushBefore(eb_ga, stmt,
AppM);
2146 ebe->type, GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2147 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2152 "---replace extract_bit_expr usage after: " + stmt->ToString());
2159 "---replace extract_bit_expr usage before: " + stmt->ToString());
2171 if(defStmt->get_kind() == gimple_assign_K)
2173 const auto prev_ga = GetPointer<const gimple_assign>(defStmt);
2175 if(prev_code1 == nop_expr_K || prev_code1 == convert_expr_K)
2177 auto ne = GetPointer<const unary_expr>(
GET_CONST_NODE(prev_ga->op1));
2183 "---replace extract_bit_expr usage before: " +
2185 const auto bit_mask_constant_node =
2187 const auto masking =
2189 srcp_default, truth_and_expr_K);
2194 "---replace extract_bit_expr usage after: " +
2214 "---replace extract_bit_expr usage before: " +
2223 "---Created " +
STR(eb_ga));
2224 B->PushBefore(eb_ga, stmt,
AppM);
2225 const auto bit_mask_constant_node =
2228 ebe->type, GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2229 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2234 "---replace extract_bit_expr usage after: " +
2245 "---replace extract_bit_expr usage before: " +
2257 "---Created " +
STR(eb_ga));
2258 B->PushBefore(eb_ga, stmt,
AppM);
2259 const auto bit_mask_constant_node =
2264 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2269 "---replace extract_bit_expr usage after: " +
2277 "---replace extract_bit_expr usage before: " +
2286 else if(prev_code1 == bit_and_expr_K)
2288 const auto bae = GetPointerS<const bit_and_expr>(
GET_CONST_NODE(prev_ga->op1));
2292 auto bae_op0 = bae->op0;
2293 auto bae_op1 = bae->op1;
2296 std::swap(bae_op0, bae_op1);
2299 const auto masked_value = (bae_mask_value & (
integer_cst_t(1) << pos_value));
2300 if(masked_value &&
GET_CONST_NODE(bae_op0)->get_kind() != integer_cst_K)
2303 "---replace extract_bit_expr usage before: " +
2312 "---Created " +
STR(eb_ga));
2313 B->PushBefore(eb_ga, stmt,
AppM);
2316 ebe->type, GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2317 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2322 "---replace extract_bit_expr usage after: " +
2330 "---replace extract_bit_expr usage before: " +
2332 const auto zero_node =
2338 else if(prev_code1 == bit_ior_concat_expr_K)
2341 GetPointerS<const bit_ior_concat_expr>(
GET_CONST_NODE(prev_ga->op1));
2343 "unexpected condition");
2346 "---replace extract_bit_expr usage before: " + stmt->ToString());
2348 nbit_value > pos_value ? bice->op1 : bice->op0, ebe->op1, srcp_default);
2353 B->PushBefore(eb_ga, stmt,
AppM);
2356 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2357 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2362 "---replace extract_bit_expr usage after: " + stmt->ToString());
2366 else if(prev_code1 == lshift_expr_K)
2368 const auto lse = GetPointerS<const lshift_expr>(
GET_CONST_NODE(prev_ga->op1));
2372 if((pos_value - lsbit_value) >= 0)
2377 "---replace extract_bit_expr usage before: " +
2386 "---Created " +
STR(eb_ga));
2387 B->PushBefore(eb_ga, stmt,
AppM);
2390 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2391 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2396 "---replace extract_bit_expr usage after: " +
2404 "---replace extract_bit_expr usage before: " +
2411 else if(prev_code1 == rshift_expr_K)
2413 const auto rse = GetPointerS<const rshift_expr>(
GET_CONST_NODE(prev_ga->op1));
2417 THROW_ASSERT((pos_value + rsbit_value) >= 0,
"unexpected condition");
2421 "---replace extract_bit_expr usage before: " + stmt->ToString());
2428 "---Created " +
STR(eb_ga));
2429 B->PushBefore(eb_ga, stmt,
AppM);
2432 ebe->type, GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2433 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2438 "---replace extract_bit_expr usage after: " + stmt->ToString());
2444 const auto res_value =
2450 if(max_lut_size > 0)
2453 "---replace extract_bit_expr usage before: " +
2457 for(log2 = 1; precision > (1u << log2); ++log2)
2462 for(
auto i = 0u; i < log2; ++i)
2464 const auto new_pos =
2473 "---Created " +
STR(eb_ga));
2474 B->PushBefore(eb_ga, stmt,
AppM);
2475 const auto eb_ga_ssa_var =
2479 op1 = eb_ga_ssa_var;
2483 op2 = eb_ga_ssa_var;
2487 op3 = eb_ga_ssa_var;
2491 op4 = eb_ga_ssa_var;
2495 op5 = eb_ga_ssa_var;
2499 op6 = eb_ga_ssa_var;
2508 const auto lut_constant_node =
2512 op4, op5, op6, op7, op8, srcp_default);
2518 "---Created " +
STR(eb_ga));
2519 B->PushBefore(eb_ga, stmt,
AppM);
2520 const auto bit_mask_constant_node =
2525 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2530 "---replace extract_bit_expr usage after: " +
2538 "---No lut allowed, lut replacement skipped...");
2545 "---replace extract_bit_expr usage before: " +
2549 "---replace extract_bit_expr usage after: " +
2556 else if(prev_code1 == bit_not_expr_K)
2558 const auto bne = GetPointerS<const bit_not_expr>(
GET_CONST_NODE(prev_ga->op1));
2560 "---replace extract_bit_expr usage before: " + stmt->ToString());
2566 B->PushBefore(eb_ga, stmt,
AppM);
2568 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2569 srcp_default, truth_not_expr_K);
2572 "---replace extract_bit_expr usage after: " + stmt->ToString());
2576 else if(prev_code1 == bit_and_expr_K)
2578 const auto bae = GetPointerS<const bit_and_expr>(
GET_CONST_NODE(prev_ga->op1));
2580 "---replace extract_bit_expr usage before: " + stmt->ToString());
2587 B->PushBefore(eb_ga0, stmt,
AppM);
2594 B->PushBefore(eb_ga1, stmt,
AppM);
2596 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga0))->op0,
2597 GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga1))->op0, srcp_default,
2601 "---replace extract_bit_expr usage after: " + stmt->ToString());
2605 else if(prev_code1 == bit_ior_expr_K)
2607 const auto bie = GetPointerS<const bit_ior_expr>(
GET_CONST_NODE(prev_ga->op1));
2609 "---replace extract_bit_expr usage before: " + stmt->ToString());
2616 B->PushBefore(eb_ga0, stmt,
AppM);
2623 B->PushBefore(eb_ga1, stmt,
AppM);
2625 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga0))->op0,
2626 GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga1))->op0, srcp_default,
2630 "---replace extract_bit_expr usage after: " + stmt->ToString());
2634 else if(prev_code1 == bit_xor_expr_K)
2636 const auto bxe = GetPointerS<const bit_xor_expr>(
GET_CONST_NODE(prev_ga->op1));
2638 "---replace extract_bit_expr usage before: " + stmt->ToString());
2645 B->PushBefore(eb_ga0, stmt,
AppM);
2652 B->PushBefore(eb_ga1, stmt,
AppM);
2654 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga0))->op0,
2655 GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga1))->op0, srcp_default,
2659 "---replace extract_bit_expr usage after: " + stmt->ToString());
2663 else if(prev_code1 == cond_expr_K)
2665 const auto ce = GetPointerS<const cond_expr>(
GET_CONST_NODE(prev_ga->op1));
2667 "---replace extract_bit_expr usage before: " + stmt->ToString());
2673 B->PushBefore(eb_ga1, stmt,
AppM);
2679 B->PushBefore(eb_ga2, stmt,
AppM);
2683 GetPointer<const gimple_assign>(
GET_CONST_NODE(eb_ga2))->op0, srcp_default,
2687 "---replace extract_bit_expr usage after: " + stmt->ToString());
2691 else if(prev_code1 == plus_expr_K)
2693 const auto pe = GetPointerS<const plus_expr>(
GET_CONST_NODE(prev_ga->op1));
2698 "---replace extract_bit_expr usage before: " + stmt->ToString());
2701 for(
integer_cst_t bitIndex = 0; bitIndex <= pos_value; ++bitIndex)
2703 const auto bitIndex_node =
2712 "---Created " +
STR(eb_ga1));
2713 B->PushBefore(eb_ga1, stmt,
AppM);
2721 "---Created " +
STR(eb_ga2));
2722 B->PushBefore(eb_ga2, stmt,
AppM);
2724 ebe->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga1))->op0,
2726 srcp_default, truth_xor_expr_K);
2732 "---Created " +
STR(sum0_ga1));
2733 B->PushBefore(sum0_ga1, stmt,
AppM);
2736 GetPointerS<const gimple_assign>(
GET_CONST_NODE(sum0_ga1))->op0, carry,
2737 srcp_default, truth_xor_expr_K);
2738 if(bitIndex < pos_value)
2745 "---Created " +
STR(sum_ga1));
2746 B->PushBefore(sum_ga1, stmt,
AppM);
2750 GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga1))->op0, carry,
2751 srcp_default, truth_and_expr_K);
2757 "---Created " +
STR(and1_ga));
2758 B->PushBefore(and1_ga, stmt,
AppM);
2762 GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga2))->op0, carry,
2763 srcp_default, truth_and_expr_K);
2769 "---Created " +
STR(and2_ga));
2770 B->PushBefore(and2_ga, stmt,
AppM);
2776 srcp_default, truth_and_expr_K);
2782 "---Created " +
STR(and3_ga));
2783 B->PushBefore(and3_ga, stmt,
AppM);
2789 srcp_default, truth_or_expr_K);
2795 "---Created " +
STR(or1_ga));
2796 B->PushBefore(or1_ga, stmt,
AppM);
2802 srcp_default, truth_or_expr_K);
2808 "---Created " +
STR(carry1_ga));
2809 B->PushBefore(carry1_ga, stmt,
AppM);
2810 carry = GetPointerS<const gimple_assign>(
GET_CONST_NODE(carry1_ga))->op0;
2815 "---replace extract_bit_expr usage after: " + stmt->ToString());
2825 const auto res_value =
2833 extract_bit_expr_BVO();
2837 auto nop_expr_BVO = [&] {
2838 const auto ne = GetPointerS<const nop_expr>(
GET_CONST_NODE(ga->op1));
2847 const auto ne_op_ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(ne->op));
2850 if(
GET_CONST_NODE(ne_op_ssa->type)->get_kind() == integer_type_K)
2853 "---replace extract_bit_expr usage before: " + stmt->ToString());
2856 const auto srcp_default =
2857 ga->include_name +
":" +
STR(ga->line_number) +
":" +
STR(ga->column_number);
2863 B->PushBefore(eb_ga, stmt,
AppM);
2866 ne->type, GetPointerS<const gimple_assign>(
GET_CONST_NODE(eb_ga))->op0,
2867 bit_mask_constant_node, srcp_default, truth_and_expr_K);
2872 "---replace extract_bit_expr usage after: " + stmt->ToString());
2884 if(bw_op1 <= bw_op0)
2899 for(
const auto&
phi :
B->CGetPhiList())
2904 bool is_virtual = pn->virtual_flag;
2908 const auto ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(pn->res));
2909 if(ssa && !ssa->bit_values.empty())
2911 const auto& bit_values = ssa->bit_values;
2916 const auto const_value =
2921 if(
AppM->ApplyNewTransformation())
2924 THROW_ASSERT(ssa->CGetUseStmts().empty(),
"unexpected case");
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static bool IsSameType(const tree_nodeConstRef &tn0, const tree_nodeConstRef &tn1)
Given two nodes tells if they have same base type (const is not considered: const double == double) ...
tree_nodeRef CreateNotExpr(const tree_nodeConstRef &condition, const blocRef &block, unsigned int function_decl_nid) const
UTILITY.
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
const TreeNodeMap< size_t > & CGetUseStmts() const
Return the use stmts.
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;.
RangeRef range
Range information about numerical values of the SSA variable.
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
static bool is_int(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of integer type.
std::string ToString() const
Print this node as string in gimple format.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
Step successfully executed.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
#define GET_CLASS(obj)
Macro returning the actual type of an object.
void ReplaceTreeNode(const tree_nodeRef &stmt, const tree_nodeRef &old_node, const tree_nodeRef &new_node)
Replace the occurrences of tree node old_node with new_node in statement identified by tn...
Definition of the class representing a generic C application.
refcount< tree_manipulation > tree_manipulationRef
const int output_level
The output level.
std::string GetName() const override
Return the name of this design step.
static bool is_real(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of real type.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
struct definition of the source position.
RelationshipType
The relationship type.
struct definition of the function_decl tree node.
Source must be executed to satisfy target.
void optimize(const function_decl *fd, tree_managerRef TM, tree_manipulationRef IRman)
do bit value based optimization such as:
mathematical utility function not provided by standard libraries
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
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.
static void shl(size_t p[2], int n)
Bit_Value_opt(const ParameterConstRef _Param, const application_managerRef _AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
Data structure describing a basic block at tree level.
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.
std::string include_name
include_name is a filename string, this can be the location of a reference, if no definition has been...
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
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.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
std::string ToString(ActorGraphBackend_Type actor_graph_backend_type)
Header include.
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.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
std::string convert_to_binary(G _value, unsigned long long precision)
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
tree_nodeRef create_lut_expr(const tree_nodeConstRef &type, const tree_nodeRef &op0, const tree_nodeRef &op1, const tree_nodeRef &op2, const tree_nodeRef &op3, const tree_nodeRef &op4, const tree_nodeRef &op5, const tree_nodeRef &op6, const tree_nodeRef &op7, const tree_nodeRef &op8, const std::string &srcp) const
create_lut_expr: function used to create a generic lut_expr operation
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
~Bit_Value_opt() override
Destructor.
tree_nodeRef CreateUniqueRealCst(long double value, const tree_nodeConstRef &type)
memoization of integer constants
Classes to describe design flow graph.
tree_nodeRef body
body field is the saved representation of the body of the entire function.
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
Target must be reexecuted.
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
static integer_cst_t convert_bitvalue_to_integer_cst(const std::string &bit_values, tree_managerRef TM, unsigned int var_id)
#define GET_CONST_NODE(t)
DesignFlowStep_Status GetStatus() const
Return the status of this design step.
static unsigned long long Size(const tree_nodeConstRef &t)
Classes specification of the tree_node data structures.
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
This file collects some utility functions and macros.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
static bool is_a_pointer(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a pointer.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
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 GetBooleanType() const
Function that creates a boolean type if it is not already present, otherwise it returns the one that ...
This file collects some utility functions.
static void constrainSSA(ssa_name *op_ssa, tree_managerRef TM)
std::vector< tree_nodeRef > list_of_args
args field holds a chain of parm_decl nodes for the arguments.
Class performing some optimizations on the IR exploiting Bit Value analysis.
DesignFlowStep_Status InternalExec() override
Optimize IR after the BitValue/BitValueIPA has been executed.
static bool is_bit_values_constant(const std::string &bit_values)
void propagateValue(const ssa_name *ssa, tree_managerRef TM, tree_nodeRef old_val, tree_nodeRef new_val, const std::string callSiteString)
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 min
minimum values this SSA may reach
tree_nodeRef GetUnsignedLongLongType() const
Function that creates a long long unsigned int type if it is not already present, otherwise return th...
static bool is_a_complex(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a complex.
This class contains the methods to create a frontend flow step.
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.
Classes specification of the tree_node data structures not present in the gcc.
this class is used to manage the command-line or XML options.
tree_nodeRef create_extract_bit_expr(const tree_nodeRef &op0, const tree_nodeRef &op1, const std::string &srcp) const
tree_nodeRef create_ssa_name(const tree_nodeConstRef &var, const tree_nodeConstRef &type, const tree_nodeConstRef &min, const tree_nodeConstRef &max, bool volatile_flag=false, bool virtual_flag=false) const
MISCELLANEOUS_OBJ_TREE_NODES.
unsigned int bitvalue_version
The version of the bitvalue information on which this step has been applied.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
std::string bit_values
for each bit of the SSA variable tells if it is equal to U,X,0,1
This struct specifies the ssa_name node.
bool modified
when true IR has been modified
static bool is_a_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a vector.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
int debug_level
The debug level.
#define OUTPUT_LEVEL_VERBOSE
verbose debugging print is performed.
tree_nodeRef type
starting from GCC 4.7.2 ssa_name has a type
#define GET_INDEX_CONST_NODE(t)
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
#define DEBUG_CALLSITE
Autoheader include.
tree_nodeRef max
maximum values this SSA may reach
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
Class specification of the manager of the tree structures extracted from the raw file.
HLS specialization of generic_device.
A brief description of the C++ Header File.
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
const FunctionBehaviorRef function_behavior
The function behavior of the function to be analyzed.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...