36 #include "config_HAVE_ASSERTS.hpp" 37 #include "config_HAVE_FROM_DISCREPANCY_BUILT.hpp" 69 static unsigned long long int invert_mod2n(
unsigned long long int x,
unsigned long long n)
77 unsigned long long int mask;
81 mask = (n ==
sizeof(
long long int) * 8 ? ~static_cast<unsigned long long int>(0) :
82 (
static_cast<unsigned long long int>(1) << n) - 1);
86 y = y * (2 - x * y) & mask;
92 #define LOWPART(x) (static_cast<unsigned long long int>(x) & ((1ULL << 32) - 1)) 93 #define HIGHPART(x) (static_cast<unsigned long long int>(x) >> 32) 94 #define BASE (1LL << 32) 99 static void encode(
long long int* words,
unsigned long long int low,
long long int hi)
101 words[0] =
static_cast<long long int>(
LOWPART(low));
102 words[1] =
static_cast<long long int>(
HIGHPART(low));
103 words[2] =
static_cast<long long int>(
LOWPART(hi));
104 words[3] =
static_cast<long long int>(
HIGHPART(hi));
110 static void decode(
long long int* words,
unsigned long long int* low,
long long int* hi)
112 *low =
static_cast<unsigned long long int>(words[0] + words[1] *
BASE);
113 *hi = words[2] + words[3] *
BASE;
126 unsigned long long int lnum_orig,
long long int hnum_orig,
128 unsigned long long int lden_orig,
unsigned long long int* lquo,
long long int* hquo)
130 long long int num[4 + 1];
131 long long int den[4], quo[4];
133 unsigned long long int work;
134 unsigned long long int carry = 0;
135 unsigned long long int lnum = lnum_orig;
136 long long int hnum = hnum_orig;
137 unsigned long long int lden = lden_orig;
142 overflow = 1, lden = 1;
161 memset(quo, 0,
sizeof quo);
163 memset(num, 0,
sizeof num);
164 memset(den, 0,
sizeof den);
170 if(lden < static_cast<unsigned long long int>(
BASE))
173 for(i = 4 - 1; i >= 0; i--)
175 work =
static_cast<unsigned long long int>(num[i]) + carry *
BASE;
176 quo[i] =
static_cast<long long int>(work / lden);
184 int num_hi_sig, den_hi_sig;
185 unsigned long long int quo_est, scale;
200 scale =
static_cast<unsigned long long int>(
BASE / (den[den_hi_sig] + 1));
204 for(i = 0; i <= 4 - 1; i++)
206 work = (
static_cast<unsigned long long int>(num[i]) * scale) + carry;
211 num[4] =
static_cast<long long int>(carry);
213 for(i = 0; i <= 4 - 1; i++)
215 work = (
static_cast<unsigned long long int>(den[i]) * scale) + carry;
228 for(i = num_hi_sig - den_hi_sig - 1; i >= 0; i--)
233 unsigned long long int tmp;
235 num_hi_sig = i + den_hi_sig + 1;
236 work =
static_cast<unsigned long long int>(num[num_hi_sig]) *
BASE +
237 static_cast<unsigned long long int>(num[num_hi_sig - 1]);
238 if(num[num_hi_sig] != den[den_hi_sig])
240 quo_est = work /
static_cast<unsigned long long int>(den[den_hi_sig]);
248 tmp = work - quo_est *
static_cast<unsigned long long int>(den[den_hi_sig]);
249 if(tmp <
BASE && (static_cast<unsigned long long int>(den[den_hi_sig - 1]) * quo_est >
250 (tmp *
BASE +
static_cast<unsigned long long int>(num[num_hi_sig - 2]))))
260 for(j = 0; j <= den_hi_sig; j++)
262 work = quo_est *
static_cast<unsigned long long int>(den[j]) + carry;
264 work =
static_cast<unsigned long long int>(num[i + j]) -
LOWPART(work);
271 if(num[num_hi_sig] < static_cast<long long int>(carry))
275 for(j = 0; j <= den_hi_sig; j++)
277 work =
static_cast<unsigned long long int>(num[i + j]) + static_cast<unsigned long long int>(den[j]) +
283 num[num_hi_sig] = num[num_hi_sig] +
static_cast<long long int>(carry);
287 quo[i] =
static_cast<long long int>(quo_est);
314 unsigned long long int* multiplier_ptr,
int* post_shift_ptr,
317 long long int mhigh_hi, mlow_hi;
318 unsigned long long int mhigh_lo, mlow_lo;
319 int lgup, post_shift;
321 unsigned long long int nl;
330 pow2 = n + lgup - precision;
340 nh = 1LL << (pow - 64);
354 nh |= 1LL << (pow2 - 64);
363 THROW_ASSERT(!mhigh_hi || static_cast<unsigned long long int>(nh) - d < d,
"unexpected condition");
364 THROW_ASSERT(mhigh_hi <= 1 && mlow_hi <= 1,
"unexpected condition");
366 THROW_ASSERT(mlow_hi < mhigh_hi || (mlow_hi == mhigh_hi && mlow_lo < mhigh_lo),
"unexpected condition");
372 for(post_shift = lgup; post_shift > 0; post_shift--)
374 unsigned long long int ml_lo =
375 static_cast<unsigned long long int>((
static_cast<unsigned long long int>(mlow_hi)) << (64 - 1)) |
377 unsigned long long int mh_lo =
378 static_cast<unsigned long long int>((
static_cast<unsigned long long int>(mhigh_hi)) << (64 - 1)) |
391 *post_shift_ptr = post_shift;
395 unsigned long long int mask = (1ULL << n) - 1;
396 *multiplier_ptr = mhigh_lo & mask;
397 return mhigh_lo >= mask;
401 *multiplier_ptr = mhigh_lo;
402 return static_cast<unsigned long long int>(mhigh_hi);
407 std::list<tree_nodeRef>::const_iterator& it_los,
gimple_assign* ga,
409 const std::string& srcp_default,
const std::string& step_name)
420 const auto rem_flag = code1 == trunc_mod_expr_K;
422 if(!
AppM->ApplyNewTransformation())
439 restart_analysis =
true;
441 else if(!unsignedp && ext_op1 == -1)
453 restart_analysis =
true;
457 const auto op1_is_pow2 =
461 if(code1 == exact_div_expr_K && op1_is_pow2)
463 code1 = trunc_div_expr_K;
470 case trunc_div_expr_K:
471 case trunc_mod_expr_K:
478 auto d =
static_cast<unsigned long long int>(ext_op1);
495 restart_analysis =
true;
500 if(d < (1ull << (data_bitsize - 1)))
502 unsigned long long int mh, ml;
505 const auto previous_precision = data_bitsize;
507 if(code1 == trunc_mod_expr_K)
520 "---correct rounding: precision=" +
STR(data_bitsize) +
521 " vs precision=" +
STR(precision));
522 if(previous_precision > precision)
525 "-->Decreased precision keeping correct rounding to value " +
STR(precision) +
526 ". Gained " +
STR(previous_precision - precision) +
" bits.");
533 "---ml = " +
STR(ml) +
" mh =" +
STR(mh));
537 if(mh != 0 && (d & 1) == 0)
539 pre_shift =
static_cast<int>(
floor_log2(d & -d));
540 mh =
choose_multiplier(d >> pre_shift, data_bitsize, precision - pre_shift, &ml, &post_shift,
554 block.second, srcp_default);
561 block.second->PushBefore(t2_ga, *it_los,
AppM);
562 const auto t2_ga_var = GetPointer<gimple_assign>(
GET_NODE(t2_ga))->op0;
566 srcp_default, rshift_expr_K);
569 block.second->PushBefore(t3_ga, *it_los,
AppM);
570 const auto t3_ga_var = GetPointer<gimple_assign>(
GET_NODE(t3_ga))->op0;
573 srcp_default, plus_expr_K);
576 block.second->PushBefore(t4_ga, *it_los,
AppM);
577 const auto t4_ga_var = GetPointer<gimple_assign>(
GET_NODE(t4_ga))->op0;
583 const auto post_shift_minusone_node =
586 type_expr, t4_ga_var, post_shift_minusone_node, srcp_default, rshift_expr_K);
590 quotient_expr = t4_ga_var;
595 THROW_ASSERT(pre_shift < data_bitsize && post_shift < data_bitsize,
"fail1");
601 srcp_default, rshift_expr_K);
604 block.second->PushBefore(t1_ga, *it_los,
AppM);
605 t1_ga_var = GetPointer<gimple_assign>(
GET_NODE(t1_ga))->op0;
613 block.second, srcp_default);
619 srcp_default, rshift_expr_K);
623 quotient_expr = t2_ga_var;
626 AppM->RegisterTransformation(step_name, *it_los);
631 block.second->PushBefore(quotient_ga, *it_los,
AppM);
632 const auto quotient_ga_var = GetPointer<gimple_assign>(
GET_NODE(quotient_ga))->op0;
634 srcp_default, mult_expr_K);
637 block.second->PushBefore(mul_ga, *it_los,
AppM);
638 const auto mul_ga_var = GetPointerS<gimple_assign>(
GET_NODE(mul_ga))->op0;
641 if(
AppM->ApplyNewTransformation() &&
647 type_expr, op0, Constmasklow, srcp_default, bit_and_expr_K);
650 block.second->PushBefore(temp_op0_ga, *it_los,
AppM);
651 const auto temp_op0_ga_var = GetPointer<gimple_assign>(
GET_NODE(temp_op0_ga))->op0;
653 type_expr, mul_ga_var, Constmasklow, srcp_default, bit_and_expr_K);
656 block.second->PushBefore(temp_op1_ga, *it_los,
AppM);
657 const auto temp_op1_ga_var = GetPointerS<gimple_assign>(
GET_NODE(temp_op1_ga))->op0;
659 type_expr, temp_op0_ga_var, temp_op1_ga_var, srcp_default, minus_expr_K);
662 AppM->RegisterTransformation(step_name, temp_sub_expr_ga);
663 block.second->PushBefore(temp_sub_expr_ga, *it_los,
AppM);
664 const auto temp_sub_expr_ga_var =
665 GetPointerS<gimple_assign>(
GET_NODE(temp_sub_expr_ga))->op0;
667 Constmasklow, srcp_default, bit_and_expr_K);
678 ga->
op1 = quotient_expr;
680 restart_analysis =
true;
689 unsigned long long abs_d;
694 abs_d = (d >= 0 ?
static_cast<unsigned long long int>(d) : static_cast<unsigned long long int>(-d));
697 if(rem_flag && d < 0)
699 d =
static_cast<long long int>(abs_d);
703 if(abs_d == (1ull << (size - 1)))
705 if(
AppM->ApplyNewTransformation())
708 const auto quotient_expr =
713 block.second->PushBefore(quotient_ga, *it_los,
AppM);
714 const auto quotient_ga_var = GetPointerS<gimple_assign>(
GET_NODE(quotient_ga))->op0;
715 const auto quotient_nop_expr =
722 block.second->PushBefore(quotient_nop, *it_los,
AppM);
723 const auto quotient_nop_var = GetPointerS<gimple_assign>(
GET_NODE(quotient_nop))->op0;
725 srcp_default, mult_expr_K);
727 function_id, srcp_default);
728 block.second->PushBefore(mul_ga, *it_los,
AppM);
729 const auto mul_ga_var = GetPointerS<gimple_assign>(
GET_NODE(mul_ga))->op0;
731 srcp_default, minus_expr_K);
736 ga->
op1 = quotient_nop_expr;
738 AppM->RegisterTransformation(step_name, *it_los);
739 restart_analysis =
true;
744 if(
AppM->ApplyNewTransformation())
748 new_op1 =
expand_smod_pow2(op0, abs_d, *it_los, block.second, type_expr, srcp_default);
753 new_op1 =
expand_sdiv_pow2(op0, abs_d, *it_los, block.second, type_expr, srcp_default);
759 block.second->PushBefore(sdiv_pow2_ga, *it_los,
AppM);
766 AppM->RegisterTransformation(step_name, *it_los);
767 restart_analysis =
true;
773 if(
AppM->ApplyNewTransformation() && data_bitsize <= 64)
775 unsigned long long int ml;
778 choose_multiplier(abs_d, data_bitsize, data_bitsize - 1, &ml, &post_shift, &lgup);
780 THROW_ASSERT(post_shift < 64 && size - 1 < 64,
"unexpected condition");
781 if(ml < (1ULL << (data_bitsize - 1)))
784 block.second, srcp_default);
794 type_expr, t1_ga_var, post_shift_node, srcp_default, rshift_expr_K);
797 block.second->PushBefore(t2_ga, *it_los,
AppM);
798 t2_ga_var = GetPointer<gimple_assign>(
GET_NODE(t2_ga))->op0;
802 t2_ga_var = t1_ga_var;
808 type_expr, op0, data_bitsize_minusone_node, srcp_default, rshift_expr_K);
811 block.second->PushBefore(t3_ga, *it_los,
AppM);
817 srcp_default, minus_expr_K);
822 srcp_default, minus_expr_K);
827 ml |= (~0ULL) << (data_bitsize - 1);
829 block.second, srcp_default);
835 block.second->PushBefore(t2_ga, *it_los,
AppM);
842 type_expr, t2_ga_var, post_shift_node, srcp_default, rshift_expr_K);
845 block.second->PushBefore(t3_ga, *it_los,
AppM);
851 type_expr, op0, data_bitsize_minusone_node, srcp_default, rshift_expr_K);
854 block.second->PushBefore(t4_ga, *it_los,
AppM);
860 srcp_default, minus_expr_K);
865 srcp_default, minus_expr_K);
872 block.second->PushBefore(quotient_ga, *it_los,
AppM);
875 srcp_default, mult_expr_K);
878 block.second->PushBefore(mul_ga, *it_los,
AppM);
881 srcp_default, minus_expr_K);
886 ga->
op1 = quotient_expr;
888 AppM->RegisterTransformation(step_name, *it_los);
889 restart_analysis =
true;
895 case exact_div_expr_K:
898 long long int d = ext_op1;
899 unsigned long long int ml;
902 pre_shift =
static_cast<int>(
floor_log2(static_cast<unsigned long long int>(d & -d)));
903 ml =
invert_mod2n(static_cast<unsigned long long int>(d >> pre_shift), size);
910 block.second->PushBefore(t1_ga, *it_los,
AppM);
915 ga->
op1 = quotient_expr;
916 AppM->RegisterTransformation(step_name, *it_los);
917 restart_analysis =
true;
925 case ceil_div_expr_K:
926 case ceil_mod_expr_K:
928 case compound_expr_K:
929 case eh_filter_expr_K:
932 case floor_div_expr_K:
933 case floor_mod_expr_K:
936 case goto_subroutine_K:
949 case mult_highpart_expr_K:
953 case pointer_plus_expr_K:
954 case postdecrement_expr_K:
955 case postincrement_expr_K:
956 case predecrement_expr_K:
957 case preincrement_expr_K:
961 case round_div_expr_K:
962 case round_mod_expr_K:
966 case truth_and_expr_K:
967 case truth_andif_expr_K:
968 case truth_or_expr_K:
969 case truth_orif_expr_K:
970 case truth_xor_expr_K:
971 case try_catch_expr_K:
980 case unordered_expr_K:
981 case widen_sum_expr_K:
982 case widen_mult_expr_K:
983 case with_size_expr_K:
984 case vec_lshift_expr_K:
985 case vec_rshift_expr_K:
986 case widen_mult_hi_expr_K:
987 case widen_mult_lo_expr_K:
988 case vec_pack_trunc_expr_K:
989 case vec_pack_sat_expr_K:
990 case vec_pack_fix_trunc_expr_K:
991 case vec_extracteven_expr_K:
992 case vec_extractodd_expr_K:
993 case vec_interleavehigh_expr_K:
994 case vec_interleavelow_expr_K:
998 case aggr_init_expr_K:
999 case case_label_expr_K:
1001 case identifier_node_K:
1003 case statement_list_K:
1005 case target_mem_ref_K:
1006 case target_mem_ref461_K:
1010 case extract_bit_expr_K:
1011 case sat_plus_expr_K:
1012 case sat_minus_expr_K:
1013 case extractvalue_expr_K:
1014 case extractelement_expr_K:
1038 auto* fd = GetPointer<function_decl>(tn);
1039 THROW_ASSERT(fd && fd->body,
"Node is not a function or it hasn't a body");
1040 auto*
sl = GetPointer<statement_list>(
GET_NODE(fd->body));
1043 for(
const auto&
block :
sl->list_of_bloc)
1046 for(
const auto&
phi :
block.second->CGetPhiList())
1050 const auto pn = GetPointerS<gimple_phi>(
GET_NODE(
phi));
1051 const auto srcp_default = pn->include_name +
":" +
STR(pn->line_number) +
":" +
STR(pn->column_number);
1053 bool is_virtual = pn->virtual_flag;
1057 for(
const auto& def_edge : pn->CGetDefEdgesList())
1060 const auto def_kind =
GET_NODE(def_edge.first)->get_kind();
1061 if(def_kind == addr_expr_K || def_kind == view_convert_expr_K || def_kind == nop_expr_K ||
1062 def_kind == pointer_plus_expr_K || def_kind == minus_expr_K || def_kind == constructor_K)
1064 to_be_replaced.push_back(def_edge);
1067 for(
const auto& def_edge : to_be_replaced)
1069 const auto ue = GetPointer<unary_expr>(
GET_NODE(def_edge.first));
1074 ue->type, ue->op, srcp_default,
1075 GET_NODE(def_edge.first)->get_kind());
1081 auto op_node =
GET_NODE(def_edge.first);
1082 const auto en_type = GetPointer<expr_node>(op_node) ? GetPointerS<expr_node>(op_node)->type :
1083 GetPointer<constructor>(op_node)->
type;
1089 const auto ue_vd = GetPointerS<gimple_assign>(
GET_NODE(op_ga))->op0;
1090 const auto pred_block =
sl->list_of_bloc.at(def_edge.second);
1091 if(pred_block->CGetStmtList().empty())
1093 pred_block->PushBack(op_ga,
AppM);
1097 const auto last_statement = pred_block->CGetStmtList().back();
1098 const auto last_stmt_kind =
GET_NODE(last_statement)->get_kind();
1099 if(last_stmt_kind == gimple_cond_K || last_stmt_kind == gimple_multi_way_if_K ||
1100 last_stmt_kind == gimple_return_K || last_stmt_kind == gimple_switch_K ||
1101 last_stmt_kind == gimple_goto_K)
1103 pred_block->PushBefore(op_ga, last_statement,
AppM);
1107 pred_block->PushAfter(op_ga, last_statement,
AppM);
1108 GetPointerS<ssa_name>(
GET_NODE(ue_vd))->SetDefStmt(op_ga);
1119 for(
const auto&
block :
sl->list_of_bloc)
1122 const auto& list_of_stmt =
block.second->CGetStmtList();
1123 bool restart_analysis;
1126 restart_analysis =
false;
1127 auto it_los_end = list_of_stmt.end();
1128 auto it_los = list_of_stmt.begin();
1131 while(it_los != it_los_end)
1133 if(GetPointer<gimple_node>(
GET_NODE(*it_los)) && GetPointerS<gimple_node>(
GET_NODE(*it_los))->vdef)
1135 bitfield_vuses.insert(GetPointer<gimple_node>(
GET_NODE(*it_los))->vdef);
1137 if(GetPointer<gimple_node>(
GET_NODE(*it_los)) &&
1138 (GetPointerS<gimple_node>(
GET_NODE(*it_los))->vdef ||
1139 !GetPointerS<gimple_node>(
GET_NODE(*it_los))->vuses.empty()))
1141 for(
const auto& vd : bitfield_vdefs)
1143 GetPointer<gimple_node>(
GET_NODE(*it_los))->AddVuse(vd);
1147 const auto srcp_default = [&]() -> std::string {
1148 const auto gn = GetPointer<gimple_node>(
GET_NODE(*it_los));
1151 return gn->include_name +
":" +
STR(gn->line_number) +
":" +
STR(gn->column_number);
1156 const auto extract_expr = [&](
tree_nodeRef& op,
bool set_temp_addr) {
1158 const auto en_type = GetPointer<expr_node>(op_node) ? GetPointerS<expr_node>(op_node)->type :
1159 GetPointer<constructor>(op_node)->
type;
1162 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
1166 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
1168 block.second->PushBefore(new_ga, *it_los,
AppM);
1171 restart_analysis =
true;
1173 const auto extract_unary_expr = [&](
tree_nodeRef& op,
bool duplicate,
bool set_temp_addr) {
1176 auto* ue = GetPointer<unary_expr>(
GET_NODE(op));
1179 extract_expr(op, set_temp_addr);
1184 const auto nop_ssa = GetPointerS<const gimple_assign>(
GET_CONST_NODE(nop))->op0;
1186 block.second->PushBefore(nop, *it_los,
AppM);
1189 restart_analysis =
true;
1193 "-->Examining statement " +
GET_NODE(*it_los)->ToString());
1194 if(
GET_NODE(*it_los)->get_kind() == gimple_assign_K)
1196 auto* ga = GetPointer<gimple_assign>(
GET_NODE(*it_los));
1198 "---Left part is " +
GET_CONST_NODE(ga->op0)->get_kind_text() +
" - Right part is " +
1200 const auto code0 =
GET_NODE(ga->op0)->get_kind();
1201 const auto code1 =
GET_NODE(ga->op1)->get_kind();
1212 if(GetPointer<unary_expr>(
GET_NODE(ga->op1)) &&
1213 GET_NODE(ga->op1)->get_kind() != addr_expr_K)
1215 auto ue = GetPointer<unary_expr>(
GET_NODE(ga->op1));
1216 if(GetPointer<unary_expr>(
GET_NODE(ue->op)))
1218 extract_unary_expr(ue->op,
1219 GET_NODE(ue->op)->get_kind() == addr_expr_K ||
1220 GET_NODE(ue->op)->get_kind() == nop_expr_K,
1221 ga->temporary_address || code1 == mem_ref_K);
1228 if(GetPointer<binary_expr>(
GET_NODE(ga->op1)))
1230 auto be = GetPointer<binary_expr>(
GET_NODE(ga->op1));
1231 if(GetPointer<unary_expr>(
GET_NODE(be->op0)))
1233 extract_unary_expr(be->op0,
1234 GET_NODE(be->op0)->get_kind() == addr_expr_K ||
1235 GET_NODE(be->op0)->get_kind() == nop_expr_K,
1236 ga->temporary_address || code1 == mem_ref_K);
1238 if(GetPointer<unary_expr>(
GET_NODE(be->op1)))
1240 extract_unary_expr(be->op1,
1241 GET_NODE(be->op0)->get_kind() == addr_expr_K ||
1242 GET_NODE(be->op0)->get_kind() == nop_expr_K,
1245 if(GetPointer<binary_expr>(
GET_NODE(be->op0)) || GetPointer<constructor>(
GET_NODE(be->op0)))
1247 extract_expr(be->op0, ga->temporary_address || code1 == mem_ref_K);
1249 if(GetPointer<binary_expr>(
GET_NODE(be->op1)) || GetPointer<constructor>(
GET_NODE(be->op1)))
1251 extract_expr(be->op1,
false);
1253 const auto be_kind = be->get_kind();
1254 if(be_kind == bit_and_expr_K || be_kind == bit_ior_expr_K || be_kind == bit_xor_expr_K ||
1255 be_kind == plus_expr_K || be_kind == minus_expr_K || be_kind == mult_expr_K ||
1256 be_kind == trunc_div_expr_K || be_kind == trunc_mod_expr_K || be_kind == sat_plus_expr_K ||
1257 be_kind == sat_minus_expr_K)
1261 type_cast(be->op0, be->type);
1265 type_cast(be->op1, be->type);
1269 if(GetPointer<ternary_expr>(
GET_NODE(ga->op1)))
1271 auto op1_kind =
GET_NODE(ga->op1)->get_kind();
1272 if(op1_kind != component_ref_K && op1_kind != bit_field_ref_K)
1274 auto te = GetPointer<ternary_expr>(
GET_NODE(ga->op1));
1275 if(GetPointer<unary_expr>(
GET_NODE(te->op0)) || GetPointer<binary_expr>(
GET_NODE(te->op0)) ||
1276 GetPointer<constructor>(
GET_NODE(te->op0)))
1278 extract_expr(te->op0,
false);
1280 if(GetPointer<unary_expr>(
GET_NODE(te->op1)) || GetPointer<binary_expr>(
GET_NODE(te->op1)) ||
1281 GetPointer<constructor>(
GET_NODE(te->op1)))
1283 extract_expr(te->op1,
false);
1286 (GetPointer<unary_expr>(
GET_NODE(te->op2)) || GetPointer<binary_expr>(
GET_NODE(te->op2)) ||
1287 GetPointer<constructor>(
GET_NODE(te->op2))))
1289 extract_expr(te->op2,
false);
1294 if(GetPointer<binary_expr>(
GET_NODE(ga->op0)))
1296 auto be = GetPointer<binary_expr>(
GET_NODE(ga->op0));
1297 if(GetPointer<unary_expr>(
GET_NODE(be->op0)))
1300 extract_unary_expr(be->op0,
GET_NODE(be->op0)->get_kind() == addr_expr_K, code0 == mem_ref_K);
1302 if(GetPointer<binary_expr>(
GET_NODE(be->op0)))
1304 extract_expr(be->op0, code0 == mem_ref_K);
1306 if(GetPointer<unary_expr>(
GET_NODE(be->op1)) || GetPointer<binary_expr>(
GET_NODE(be->op1)))
1308 extract_expr(be->op1,
false);
1312 auto* rpe = GetPointer<realpart_expr>(
GET_NODE(op));
1316 auto align = size_complex / 2;
1322 const auto ae_cr_vd = GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->op0;
1323 GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->temporary_address = ga->temporary_address;
1324 block.second->PushBefore(ae_cr_ga, *it_los,
AppM);
1327 auto ssa_vd = ae_cr_vd;
1334 block.second->PushBefore(ga_nop, *it_los,
AppM);
1347 auto* ipe = GetPointer<imagpart_expr>(
GET_NODE(op));
1351 auto align = size_complex / 2;
1358 GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->temporary_address = ga->temporary_address;
1359 block.second->PushBefore(ae_cr_ga, *it_los,
AppM);
1362 auto ssa_vd = ae_cr_vd;
1369 block.second->PushBefore(ga_nop, *it_los,
AppM);
1382 if(code1 == array_ref_K)
1386 auto* AR = GetPointer<array_ref>(
GET_NODE(ga->op1));
1388 restart_analysis =
true;
1390 else if(code1 == ssa_name_K && code0 == ssa_name_K)
1396 auto ssa0 = GetPointerS<ssa_name>(
GET_NODE(ga->op0));
1401 const auto nop_vd = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
1402 block.second->PushBefore(ga_nop, *it_los,
AppM);
1404 restart_analysis =
true;
1407 else if(code1 == addr_expr_K)
1409 auto addr_exprNormalize = [&] {
1410 auto* ae = GetPointer<addr_expr>(
GET_NODE(ga->op1));
1412 "---Op of addr expr is " +
GET_CONST_NODE(ae->op)->get_kind_text());
1414 if(ae_code == mem_ref_K)
1417 auto* MR = GetPointer<mem_ref>(
GET_NODE(ae->op));
1418 const auto mem_op0_kind =
GET_NODE(MR->op0)->get_kind();
1419 if(mem_op0_kind == addr_expr_K || mem_op0_kind == pointer_plus_expr_K ||
1420 mem_op0_kind == view_convert_expr_K)
1424 extract_unary_expr(MR->op0, mem_op0_kind == addr_expr_K, ga->temporary_address);
1429 if(mem_op0_kind == integer_cst_K && op1_val == 0)
1433 else if(ga->temporary_address)
1439 pointer_plus_expr_K);
1453 pointer_plus_expr_K);
1458 GetPointer<gimple_assign>(
GET_NODE(pp_ga))->temporary_address =
true;
1459 const auto pp_vd = GetPointer<gimple_assign>(
GET_NODE(pp_ga))->op0;
1460 block.second->PushBefore(pp_ga, *it_los,
AppM);
1473 const auto nop_vd = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
1474 block.second->PushBefore(ga_nop, *it_los,
AppM);
1483 restart_analysis =
true;
1485 else if(ae_code == array_ref_K)
1487 auto* AR = GetPointer<array_ref>(
GET_NODE(ae->op));
1489 restart_analysis =
true;
1491 else if(ae_code == target_mem_ref461_K)
1493 auto* tmr = GetPointer<target_mem_ref461>(
GET_NODE(ae->op));
1500 srcp_default, mem_ref_K);
1502 restart_analysis =
true;
1504 else if(ae_code == component_ref_K)
1506 auto* cr = GetPointer<component_ref>(
GET_NODE(ae->op));
1507 auto* field_d = GetPointer<field_decl>(
GET_NODE(cr->op1));
1508 THROW_ASSERT(field_d,
"expected an field_decl but got something of different");
1514 const auto ae_cr_vd = GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->op0;
1515 GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->temporary_address = ga->temporary_address;
1516 block.second->PushBefore(ae_cr_ga, *it_los,
AppM);
1526 GetPointer<gimple_assign>(
GET_NODE(pp_ga))->temporary_address = ga->temporary_address;
1527 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(pp_ga))->op0;
1528 block.second->PushBefore(pp_ga, *it_los,
AppM);
1535 restart_analysis =
true;
1537 else if(ae_code == bit_field_ref_K)
1539 auto* bfr = GetPointer<bit_field_ref>(
GET_NODE(ae->op));
1545 const auto ae_cr_vd = GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->op0;
1546 GetPointer<gimple_assign>(
GET_NODE(ae_cr_ga))->temporary_address = ga->temporary_address;
1547 block.second->PushBefore(ae_cr_ga, *it_los,
AppM);
1557 GetPointer<gimple_assign>(
GET_NODE(pp_ga))->temporary_address = ga->temporary_address;
1558 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(pp_ga))->op0;
1559 block.second->PushBefore(pp_ga, *it_los,
AppM);
1566 restart_analysis =
true;
1568 else if(ae_code == indirect_ref_K)
1570 auto* ir = GetPointerS<indirect_ref>(
GET_NODE(ae->op));
1571 const auto type = ir->type;
1577 restart_analysis =
true;
1579 else if(ae_code == realpart_expr_K)
1581 ae->op = manage_realpart(ae->op, ae->type);
1582 restart_analysis =
true;
1584 else if(ae_code == imagpart_expr_K)
1586 ae->op = manage_imagpart(ae->op, ae->type);
1587 restart_analysis =
true;
1589 else if(ae_code == var_decl_K || ae_code == parm_decl_K || ae_code == function_decl_K ||
1590 ae_code == string_cst_K)
1592 if(code0 == ssa_name_K && ae_code != function_decl_K && ae_code != parm_decl_K)
1594 auto ssa_var = GetPointerS<const ssa_name>(
GET_NODE(ga->op0));
1595 if(ssa_var->use_set->variables.empty())
1597 ssa_var->use_set->Add(ae->op);
1608 auto* pt_ae = GetPointerS<pointer_type>(
GET_NODE(ae->type));
1611 const auto op_type_id = op_type_node->index;
1612 if(op_type_id != ptd_index)
1616 auto* ae_new = GetPointer<addr_expr>(
GET_NODE(ae_new_node));
1619 GetPointer<gimple_assign>(
GET_NODE(a_ga))->temporary_address = ga->temporary_address;
1620 block.second->PushBefore(a_ga, *it_los,
AppM);
1624 ae->type, GetPointer<gimple_assign>(
GET_NODE(a_ga))->op0, srcp_default, nop_expr_K);
1626 ga->temporary_address =
true;
1629 restart_analysis =
true;
1633 addr_exprNormalize();
1635 else if(code1 == realpart_expr_K)
1637 auto* rpe = GetPointer<realpart_expr>(
GET_NODE(ga->op1));
1638 if(
GET_NODE(rpe->op)->get_kind() != ssa_name_K)
1641 restart_analysis =
true;
1644 else if(code1 == imagpart_expr_K)
1646 auto* ipe = GetPointer<imagpart_expr>(
GET_NODE(ga->op1));
1647 if(
GET_NODE(ipe->op)->get_kind() != ssa_name_K)
1650 restart_analysis =
true;
1653 else if(code1 == target_mem_ref461_K)
1655 auto target_mem_ref1 = [&] {
1656 auto* tmr = GetPointer<target_mem_ref461>(
GET_NODE(ga->op1));
1658 const auto type = tmr->type;
1664 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
1666 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
1672 block.second->PushBefore(new_ga, *it_los,
AppM);
1675 restart_analysis =
true;
1679 else if(code1 == mem_ref_K)
1681 auto mem_ref1 = [&] {
1684 auto* MR = GetPointer<mem_ref>(
GET_NODE(ga->op1));
1685 const auto mem_op0_kind =
GET_NODE(MR->op0)->get_kind();
1686 if(mem_op0_kind == addr_expr_K || mem_op0_kind == pointer_plus_expr_K ||
1687 mem_op0_kind == view_convert_expr_K)
1691 extract_unary_expr(MR->op0, mem_op0_kind == addr_expr_K,
true);
1698 const auto type = MR->type;
1702 auto bram_size =
std::max(8ll, obj_size / 2ll);
1703 if(((op1_val * 8) % bram_size) != 0)
1712 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
1713 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
1720 block.second->PushBefore(new_ga, *it_los,
AppM);
1723 restart_analysis =
true;
1728 else if(code1 == eq_expr_K or code1 == ne_expr_K or code1 == gt_expr_K or code1 == lt_expr_K or
1729 code1 == ge_expr_K or code1 == le_expr_K)
1731 auto rel_expr1 = [&] {
1747 const auto num_elements = vector_size / element_size;
1750 GetPointer<binary_expr>(
GET_NODE(ga->op1))->
type = new_left_type;
1753 block.second->PushBefore(lt_ga, *it_los,
AppM);
1763 restart_analysis =
true;
1768 else if(code1 == truth_not_expr_K)
1770 auto tn_expr1 = [&] {
1771 const auto lhs =
GET_NODE(ga->op1);
1772 auto* e = GetPointer<truth_not_expr>(lhs);
1780 const auto not_zero =
1787 block.second->PushBefore(not_zero_ga, *it_los,
AppM);
1788 e->op = GetPointer<gimple_assign>(
GET_NODE(not_zero_ga))->op0;
1791 restart_analysis =
true;
1800 block.second->PushBefore(lt_ga, *it_los,
AppM);
1810 restart_analysis =
true;
1815 else if(code1 == truth_and_expr_K or code1 == truth_andif_expr_K or code1 == truth_or_expr_K or
1816 code1 == truth_orif_expr_K or code1 == truth_xor_expr_K)
1818 auto tn_expr1 = [&] {
1819 const auto lhs =
GET_NODE(ga->op1);
1820 auto* e = GetPointer<binary_expr>(lhs);
1828 const auto not_zero =
1835 block.second->PushBefore(not_zero_ga, *it_los,
AppM);
1836 e->op0 = GetPointer<gimple_assign>(
GET_NODE(not_zero_ga))->op0;
1839 restart_analysis =
true;
1846 const auto not_zero =
1853 block.second->PushBefore(not_zero_ga, *it_los,
AppM);
1854 e->op1 = GetPointer<gimple_assign>(
GET_NODE(not_zero_ga))->op0;
1857 restart_analysis =
true;
1866 block.second->PushBefore(lt_ga, *it_los,
AppM);
1876 restart_analysis =
true;
1881 else if(code1 == call_expr_K || code1 == aggr_init_expr_K)
1883 auto* ce = GetPointer<call_expr>(
GET_NODE(ga->op1));
1884 for(
auto&
arg : ce->args)
1888 extract_unary_expr(
arg,
GET_NODE(
arg)->get_kind() == addr_expr_K,
false);
1892 else if(code1 == pointer_plus_expr_K)
1894 auto pp_expr1 = [&] {
1895 auto* ppe = GetPointer<pointer_plus_expr>(
GET_NODE(ga->op1));
1896 THROW_ASSERT(ppe->op0 && ppe->op1,
"expected two parameters");
1897 if(GetPointer<addr_expr>(
GET_NODE(ppe->op0)))
1899 extract_expr(ppe->op0, ga->temporary_address);
1901 else if(GetPointer<pointer_plus_expr>(
GET_NODE(ppe->op0)))
1903 extract_expr(ppe->op0, ga->temporary_address);
1905 else if(GetPointer<mult_expr>(
GET_NODE(ppe->op1)))
1907 extract_expr(ppe->op1,
false);
1909 else if(GetPointer<var_decl>(
GET_NODE(ppe->op0)))
1911 auto* vd = GetPointer<var_decl>(
GET_NODE(ppe->op0));
1912 const auto type = vd->type;
1917 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
1918 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
1920 block.second->PushBefore(new_ga, *it_los,
AppM);
1923 restart_analysis =
true;
1925 else if(GetPointer<ssa_name>(
GET_NODE(ppe->op0)) && GetPointer<integer_cst>(
GET_NODE(ppe->op1)))
1927 auto temp_def =
GET_NODE(GetPointer<const ssa_name>(
GET_NODE(ppe->op0))->CGetDefStmt());
1928 if(temp_def->get_kind() == gimple_assign_K)
1930 const auto prev_ga = GetPointer<const gimple_assign>(temp_def);
1931 if(
GET_NODE(prev_ga->op1)->get_kind() == pointer_plus_expr_K)
1933 const auto prev_ppe = GetPointer<const pointer_plus_expr>(
GET_NODE(prev_ga->op1));
1934 if(GetPointer<ssa_name>(
GET_NODE(prev_ppe->op0)) &&
1935 GetPointer<integer_cst>(
GET_NODE(prev_ppe->op1)))
1941 ppe->op0 = prev_ppe->op0;
1942 restart_analysis =
true;
1947 else if(GetPointer<ssa_name>(
GET_NODE(ppe->op0)))
1949 auto temp_def =
GET_NODE(GetPointer<const ssa_name>(
GET_NODE(ppe->op0))->CGetDefStmt());
1950 if(temp_def->get_kind() == gimple_assign_K)
1952 const auto prev_ga = GetPointer<const gimple_assign>(temp_def);
1953 if(
GET_NODE(prev_ga->op1)->get_kind() == addr_expr_K)
1955 auto* prev_ae = GetPointer<addr_expr>(
GET_NODE(prev_ga->op1));
1956 enum kind prev_ae_code =
GET_NODE(prev_ae->op)->get_kind();
1957 if(prev_ae_code == mem_ref_K)
1959 auto* prev_MR = GetPointer<mem_ref>(
GET_NODE(prev_ae->op));
1961 if(prev_op1_val == 0)
1963 if(
GET_NODE(prev_MR->op0)->get_kind() == ssa_name_K)
1965 ppe->op0 = prev_MR->op0;
1966 restart_analysis =
true;
1976 else if(code1 == component_ref_K)
1978 auto cr_expr1 = [&] {
1979 const auto cr = GetPointer<component_ref>(
GET_NODE(ga->op1));
1980 const auto field_d = GetPointer<field_decl>(
GET_NODE(cr->op1));
1982 if(field_d->is_bitfield())
1986 const auto right_shift_val = op1_val % 8;
1987 if(
GET_NODE(cr->type)->get_kind() == boolean_type_K)
1993 const auto it = GetPointer<integer_type>(
GET_NODE(cr->type));
2009 GetPointerS<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2011 const auto ssa_vd = GetPointerS<gimple_assign>(
GET_NODE(new_ga))->op0;
2012 block.second->PushBefore(new_ga, *it_los,
AppM);
2016 if(field_d->packed_flag)
2022 if(field_d->is_bitfield())
2025 const auto right_shift_val = op1_val % 8;
2029 if(right_shift_val == 0 and size_field_decl == size_tp)
2039 GetPointerS<gimple_assign>(
GET_NODE(mr_ga))->memuse = ga->memuse;
2040 GetPointerS<gimple_assign>(
GET_NODE(mr_ga))->vuses = ga->vuses;
2041 GetPointerS<gimple_assign>(
GET_NODE(mr_ga))->vovers = ga->vovers;
2045 block.second->PushBefore(mr_ga, *it_los,
AppM);
2048 const auto mr_vd = GetPointerS<gimple_assign>(
GET_NODE(mr_ga))->op0;
2049 #if HAVE_FROM_DISCREPANCY_BUILT 2057 (!
parameters->isOption(OPT_discrepancy_force) ||
2058 !
parameters->getOption<
bool>(OPT_discrepancy_force)))
2070 srcp_default, rshift_expr_K);
2071 if(size_field_decl == size_tp)
2079 const auto rsh_vd = GetPointerS<gimple_assign>(
GET_NODE(rsh_ga))->op0;
2080 block.second->PushBefore(rsh_ga, *it_los,
AppM);
2083 #if HAVE_FROM_DISCREPANCY_BUILT 2091 parameters->getOption<
bool>(OPT_discrepancy) &&
2092 (!
parameters->isOption(OPT_discrepancy_force) ||
2093 !
parameters->getOption<
bool>(OPT_discrepancy_force)))
2101 const auto and_mask_value =
2109 const auto and_mask_value =
2120 restart_analysis =
true;
2124 else if(code1 == vec_cond_expr_K)
2126 auto vc_expr1 = [&] {
2127 const auto vce = GetPointerS<vec_cond_expr>(
GET_NODE(ga->op1));
2128 THROW_ASSERT(vce->op1 && vce->op2,
"expected three parameters");
2129 if(GetPointer<binary_expr>(
GET_NODE(vce->op0)))
2131 const auto be = GetPointerS<binary_expr>(
GET_NODE(vce->op0));
2132 THROW_ASSERT(be->get_kind() == le_expr_K or be->get_kind() == eq_expr_K or
2133 be->get_kind() == ne_expr_K or be->get_kind() == gt_expr_K or
2134 be->get_kind() == lt_expr_K or be->get_kind() == ge_expr_K,
2135 be->get_kind_text());
2138 const auto ssa_vd = GetPointerS<gimple_assign>(
GET_NODE(new_ga))->op0;
2141 block.second->PushBefore(new_ga, *it_los,
AppM);
2144 restart_analysis =
true;
2149 else if(code1 == view_convert_expr_K || code1 == nop_expr_K)
2151 auto vcne_expr1 = [&] {
2152 auto* ue = GetPointer<unary_expr>(
GET_NODE(ga->op1));
2153 if(
GET_NODE(ue->op)->get_kind() == var_decl_K)
2155 auto vc = GetPointer<view_convert_expr>(
GET_NODE(ga->op1));
2161 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2167 block.second->PushBefore(new_ga, *it_los,
AppM);
2170 restart_analysis =
true;
2172 else if(
GET_NODE(ue->op)->get_kind() != ssa_name_K && !GetPointer<cst_node>(
GET_NODE(ue->op)))
2179 if(ga->temporary_address)
2181 GetPointer<gimple_assign>(
GET_NODE(op_ga))->temporary_address =
true;
2183 block.second->PushBefore(op_ga, *it_los,
AppM);
2187 restart_analysis =
true;
2192 else if(code1 == cond_expr_K)
2194 auto ce_expr1 = [&] {
2195 auto* ce = GetPointer<cond_expr>(
GET_NODE(ga->op1));
2196 THROW_ASSERT(ce->op1 && ce->op2,
"expected three parameters");
2197 if(GetPointer<binary_expr>(
GET_NODE(ce->op0)))
2200 auto* be = GetPointer<binary_expr>(
GET_NODE(ce->op0));
2201 THROW_ASSERT(be->get_kind() == le_expr_K or be->get_kind() == eq_expr_K or
2202 be->get_kind() == ne_expr_K or be->get_kind() == gt_expr_K or
2203 be->get_kind() == lt_expr_K or be->get_kind() == ge_expr_K,
2204 be->get_kind_text());
2213 block.second->PushBefore(new_ga, *it_los,
AppM);
2216 restart_analysis =
true;
2225 block.second->PushBefore(ga_nop, *it_los,
AppM);
2226 ce->op0 = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2228 restart_analysis =
true;
2233 else if(code1 == indirect_ref_K)
2235 auto* ir = GetPointer<indirect_ref>(
GET_NODE(ga->op1));
2240 restart_analysis =
true;
2242 else if(code1 == misaligned_indirect_ref_K)
2244 auto* MIR = GetPointer<misaligned_indirect_ref>(
GET_NODE(ga->op1));
2250 restart_analysis =
true;
2252 else if(code1 == var_decl_K && !ga->init_assignment)
2254 auto vd_expr1 = [&] {
2255 auto* vd = GetPointer<var_decl>(
GET_NODE(ga->op1));
2261 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2263 auto ssa_var_decl = GetPointer<ssa_name>(
GET_NODE(ssa_vd));
2264 ssa_var_decl->use_set->Add(ga->op1);
2269 block.second->PushBefore(new_ga, *it_los,
AppM);
2272 restart_analysis =
true;
2279 "---Reached max cfg transformations (" +
GET_CONST_NODE(ga->op1)->get_kind_text() +
2284 if(code1 == bit_field_ref_K)
2286 auto bfe_expr1 = [&] {
2287 auto* bfr = GetPointer<bit_field_ref>(
GET_NODE(ga->op1));
2288 if(
GET_NODE(bfr->op0)->get_kind() != ssa_name_K)
2292 const auto right_shift_val = op1_val % 8;
2294 if(
GET_NODE(bfr->type)->get_kind() == boolean_type_K)
2300 const auto it = GetPointer<integer_type>(
GET_NODE(bfr->type));
2309 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2312 block.second->PushBefore(new_ga, *it_los,
AppM);
2321 const auto size_field_decl =
2323 if(right_shift_val == 0 && size_field_decl == size_tp)
2334 GetPointer<gimple_assign>(
GET_NODE(mr_ga))->memuse = ga->memuse;
2335 GetPointer<gimple_assign>(
GET_NODE(mr_ga))->vuses = ga->vuses;
2336 GetPointer<gimple_assign>(
GET_NODE(mr_ga))->vovers = ga->vovers;
2340 block.second->PushBefore(mr_ga, *it_los,
AppM);
2343 #if HAVE_FROM_DISCREPANCY_BUILT 2351 parameters->getOption<
bool>(OPT_discrepancy) and
2352 (not
parameters->isOption(OPT_discrepancy_force) or
2353 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
2365 srcp_default, rshift_expr_K);
2366 if(size_field_decl == size_tp)
2375 block.second->PushBefore(rsh_ga, *it_los,
AppM);
2378 #if HAVE_FROM_DISCREPANCY_BUILT 2386 parameters->getOption<
bool>(OPT_discrepancy) and
2387 (not
parameters->isOption(OPT_discrepancy_force) or
2388 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
2397 static_cast<long long int>((1ULL << size_field_decl) - 1), type);
2399 srcp_default, bit_and_expr_K);
2405 static_cast<long long int>((1ULL << size_field_decl) - 1), type);
2410 restart_analysis =
true;
2421 const auto type_vc =
2424 view_convert_expr_K);
2427 block.second->PushBefore(vc_ga, *it_los,
AppM);
2428 const auto vc_ga_var = GetPointer<gimple_assign>(
GET_NODE(vc_ga))->op0;
2430 const auto sel_size =
2433 srcp_default, rshift_expr_K);
2436 block.second->PushBefore(vc_shift_ga, *it_los,
AppM);
2437 const auto vc_shift_ga_var = GetPointer<gimple_assign>(
GET_NODE(vc_shift_ga))->op0;
2438 const auto sel_type =
2440 const auto vc_nop_expr =
2444 block.second->PushBefore(vc_nop_ga, *it_los,
AppM);
2445 const auto vc_nop_ga_var = GetPointer<gimple_assign>(
GET_NODE(vc_nop_ga))->op0;
2447 srcp_default, view_convert_expr_K);
2449 restart_analysis =
true;
2455 else if(code1 == trunc_div_expr_K || code1 == trunc_mod_expr_K || code1 == exact_div_expr_K)
2457 auto be = GetPointer<binary_expr>(
GET_NODE(ga->op1));
2459 if(GetPointer<cst_node>(
GET_NODE(op1)))
2465 else if(code1 == mult_expr_K)
2467 auto me_expr1 = [&] {
2471 if(GetPointer<integer_cst>(
GET_NODE(op1)))
2473 auto* cn = GetPointer<integer_cst>(
GET_NODE(op1));
2480 ga->op1 =
expand_MC(op0, cn, ga->op1, *it_los,
block.second, type_expr, srcp_default);
2481 restart_analysis = restart_analysis || (prev_index !=
GET_INDEX_NODE(ga->op1));
2491 GET_NODE(ga->op1)->get_kind() == mult_expr_K)
2500 auto data_bitsize_out = ceil_pow2(dw_out);
2502 "---data_bitsize_out " +
STR(data_bitsize_out) +
" <- " +
STR(dw_out) +
2505 auto data_bitsize_in0 = ceil_pow2(dw_in0);
2507 "---data_bitsize_in0 " +
STR(data_bitsize_in0) +
" <- " +
STR(dw_in0) +
2510 auto data_bitsize_in1 = ceil_pow2(dw_in1);
2512 "---data_bitsize_in1 " +
STR(data_bitsize_in1) +
" <- " +
STR(dw_in1) +
2514 if(
std::max(data_bitsize_in0, data_bitsize_in1) * 2 == data_bitsize_out)
2519 op0_type, GetPointer<binary_expr>(
GET_NODE(ga->op1))->op0,
2520 GetPointer<binary_expr>(
GET_NODE(ga->op1))->op1, srcp_default, widen_mult_expr_K);
2521 restart_analysis =
true;
2530 else if(code1 == widen_mult_expr_K)
2532 auto wme_expr1 = [&] {
2533 const auto be = GetPointer<binary_expr>(
GET_NODE(ga->op1));
2535 if(GetPointer<cst_node>(
GET_NODE(op1)) && !GetPointer<vector_cst>(
GET_NODE(op1)))
2539 auto* cn = GetPointer<cst_node>(
GET_NODE(op1));
2547 ga->op1 =
expand_MC(op0, static_cast<integer_cst*>(cn), ga->op1, *it_los,
block.second,
2548 type_expr, srcp_default);
2549 restart_analysis = restart_analysis || (prev_index !=
GET_INDEX_NODE(ga->op1));
2563 "Conversion from unsigned to signed is required for first input of " +
2564 STR(ga->op1->index));
2570 be->op0 = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2572 block.second->PushBefore(ga_nop, *it_los,
AppM);
2573 restart_analysis =
true;
2578 THROW_UNREACHABLE(
"Conversion of " + be->op0->ToString() +
" cannot be created");
2580 THROW_WARNING(
"Implicit type conversion for first input of " + ga->ToString());
2588 "Conversion from unsigned to signed is required for first input of " +
2589 STR(ga->op1->index));
2595 be->op1 = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2596 block.second->PushBefore(ga_nop, *it_los,
AppM);
2598 restart_analysis =
true;
2603 THROW_UNREACHABLE(
"Conversion of " + be->op1->ToString() +
" cannot be created");
2605 THROW_WARNING(
"Implicit type conversion for first input of " + ga->ToString());
2613 else if(code1 == lt_expr_K)
2615 auto lt_expr1 = [&] {
2618 auto be = GetPointer<binary_expr>(
GET_NODE(ga->op1));
2624 if(GetPointer<integer_cst>(
GET_NODE(op1)))
2633 op0_type, op0, right_shift_value, srcp_default, rshift_expr_K);
2636 block.second->PushBefore(rshift1_ga, *it_los,
AppM);
2642 op0_type, rshift1_ga_var, bitwise_mask_value, srcp_default, bit_and_expr_K);
2646 block.second->PushBefore(bitwise_masked_ga, *it_los,
AppM);
2650 GetPointer<gimple_assign>(
GET_NODE(bitwise_masked_ga))->op0;
2652 srcp_default, nop_expr_K);
2655 block.second->PushBefore(ga_nop, *it_los,
AppM);
2659 ga->op1 = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2660 restart_analysis =
true;
2679 else if(code1 == ge_expr_K)
2681 auto ge_expr1 = [&] {
2689 if(GetPointer<integer_cst>(
GET_NODE(op1)))
2699 op0_type, op0, right_shift_value, srcp_default, rshift_expr_K);
2702 block.second->PushBefore(rshift1_ga, *it_los,
AppM);
2708 op0_type, rshift1_ga_var, bitwise_mask_value, srcp_default, bit_and_expr_K);
2712 block.second->PushBefore(bitwise_masked_ga, *it_los,
AppM);
2716 GetPointer<gimple_assign>(
GET_NODE(bitwise_masked_ga))->op0;
2719 bitwise_masked_var, srcp_default, nop_expr_K);
2723 block.second->PushBefore(ga_nop, *it_los,
AppM);
2729 booleanType, ga_nop_var, srcp_default, truth_not_expr_K);
2730 ga->op1 = not_masked;
2731 restart_analysis =
true;
2750 else if(code1 == plus_expr_K)
2752 auto pe_expr1 = [&] {
2760 auto ssa0 = GetPointerS<ssa_name>(
GET_NODE(ga->op0));
2765 const auto nop_vd = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2766 block.second->PushBefore(ga_nop, *it_los,
AppM);
2767 GetPointer<binary_expr>(
GET_NODE(ga->op1))->op0 = bop1 = nop_vd;
2768 restart_analysis =
true;
2773 auto ssa0 = GetPointerS<ssa_name>(
GET_NODE(ga->op0));
2778 const auto nop_vd = GetPointer<gimple_assign>(
GET_NODE(ga_nop))->op0;
2779 block.second->PushBefore(ga_nop, *it_los,
AppM);
2780 GetPointer<binary_expr>(
GET_NODE(ga->op1))->op1 = bop1 = nop_vd;
2781 restart_analysis =
true;
2791 srcp_default, lshift_expr_K);
2793 restart_analysis =
true;
2808 else if(code1 == parm_decl_K)
2810 auto* pd = GetPointer<parm_decl>(
GET_NODE(ga->op1));
2816 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2823 block.second->PushBefore(new_ga, *it_los,
AppM);
2827 restart_analysis =
true;
2831 if(code0 == array_ref_K)
2835 auto* AR = GetPointer<array_ref>(
GET_NODE(ga->op0));
2837 restart_analysis =
true;
2839 else if(code0 == mem_ref_K)
2841 auto mem_ref0 = [&] {
2844 auto* MR = GetPointer<mem_ref>(
GET_NODE(ga->op0));
2845 const auto mem_op0_kind =
GET_NODE(MR->op0)->get_kind();
2846 if(mem_op0_kind == addr_expr_K || mem_op0_kind == pointer_plus_expr_K ||
2847 mem_op0_kind == view_convert_expr_K)
2849 extract_unary_expr(MR->op0, mem_op0_kind == addr_expr_K,
true);
2860 auto bram_size =
std::max(8ull, obj_size / 2);
2863 bool implicit_memset =
GET_NODE(ga->op1)->get_kind() == constructor_K &&
2864 GetPointer<constructor>(
GET_NODE(ga->op1)) &&
2865 GetPointer<constructor>(
GET_NODE(ga->op1))->list_of_idx_valu.size() == 0;
2869 implicit_memset = var != 0;
2877 if(!implicit_memset && ((((op1_val * 8)) % static_cast<long long>(bram_size)) != 0))
2886 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2887 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
2894 block.second->PushBefore(new_ga, *it_los,
AppM);
2897 restart_analysis =
true;
2900 auto view_convert_pattern =
GET_CONST_NODE(op1_type)->get_kind() == record_type_K &&
2901 GET_NODE(ga->op1)->get_kind() == view_convert_expr_K;
2902 if(!view_convert_pattern &&
GET_NODE(ga->op1)->get_kind() != ssa_name_K &&
2903 !GetPointer<cst_node>(
GET_NODE(ga->op1)) &&
GET_NODE(ga->op1)->get_kind() != mem_ref_K &&
2904 GET_NODE(ga->op1)->get_kind() != constructor_K)
2910 const auto op_vd = GetPointer<gimple_assign>(
GET_NODE(op_ga))->op0;
2911 block.second->PushBefore(op_ga, *it_los,
AppM);
2915 restart_analysis =
true;
2920 else if(code0 == component_ref_K)
2922 auto component_ref0 = [&] {
2923 auto* cr = GetPointer<component_ref>(
GET_NODE(ga->op0));
2924 auto* field_d = GetPointer<field_decl>(
GET_NODE(cr->op1));
2926 if(field_d->is_bitfield())
2930 auto right_shift_val = op1_val % 8;
2931 if(
GET_NODE(cr->type)->get_kind() == boolean_type_K)
2937 auto* it = GetPointer<integer_type>(
GET_NODE(cr->type));
2951 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
2954 block.second->PushBefore(new_ga, *it_los,
AppM);
2958 if(field_d->packed_flag)
2965 if(field_d->is_bitfield())
2969 auto right_shift_val = op1_val % 8;
2973 if(right_shift_val == 0 and size_field_decl == size_tp)
2984 GetPointer<gimple_assign>(
GET_NODE(load_ga))->memuse = ga->memuse;
2985 GetPointer<gimple_assign>(
GET_NODE(load_ga))->vuses = ga->vuses;
2986 for(
const auto& vd : bitfield_vuses)
2988 GetPointer<gimple_assign>(
GET_NODE(load_ga))->AddVuse(vd);
2991 bitfield_vdefs.insert(ga->vdef);
2992 block.second->PushBefore(load_ga, *it_los,
AppM);
2997 if(size_field_decl != size_tp)
2999 #if HAVE_FROM_DISCREPANCY_BUILT 3007 parameters->getOption<
bool>(OPT_discrepancy) and
3008 (not
parameters->isOption(OPT_discrepancy_force) or
3009 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3018 static_cast<long long int>(~(((1ULL << size_field_decl) - 1) << right_shift_val)),
3021 srcp_default, bit_and_expr_K);
3024 block.second->PushBefore(nmask_ga, *it_los,
AppM);
3027 load_var = GetPointer<gimple_assign>(
GET_NODE(nmask_ga))->op0;
3028 #if HAVE_FROM_DISCREPANCY_BUILT 3036 parameters->getOption<
bool>(OPT_discrepancy) and
3037 (not
parameters->isOption(OPT_discrepancy_force) or
3038 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3049 THROW_ASSERT(right_shift_val == 0,
"unexpected pattern");
3053 if(size_field_decl != size_tp)
3056 static_cast<long long int>((1ULL << size_field_decl) - 1), type);
3058 type, ga->op1, and_mask_value, srcp_default, bit_and_expr_K);
3061 block.second->PushBefore(and_mask_ga, *it_los,
AppM);
3064 written_var = GetPointer<gimple_assign>(
GET_NODE(and_mask_ga))->op0;
3068 written_var = ga->op1;
3075 srcp_default, lshift_expr_K);
3078 block.second->PushBefore(lsh_ga, *it_los,
AppM);
3081 lshifted_var = GetPointer<gimple_assign>(
GET_NODE(lsh_ga))->op0;
3085 lshifted_var = written_var;
3089 srcp_default, bit_ior_expr_K);
3092 block.second->PushBefore(res_ga, *it_los,
AppM);
3098 #if HAVE_FROM_DISCREPANCY_BUILT 3105 if(size_field_decl != size_tp and
parameters->isOption(OPT_discrepancy) and
3106 parameters->getOption<
bool>(OPT_discrepancy) and
3107 (not
parameters->isOption(OPT_discrepancy_force) or
3108 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3122 restart_analysis =
true;
3126 else if(code0 == target_mem_ref461_K)
3132 auto* tmr = GetPointer<target_mem_ref461>(
GET_NODE(ga->op0));
3140 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
3147 block.second->PushBefore(new_ga, *it_los,
AppM);
3150 restart_analysis =
true;
3154 else if(code0 == var_decl_K && !ga->init_assignment)
3156 auto* vd = GetPointer<var_decl>(
GET_NODE(ga->op0));
3163 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
3165 auto ssa_var_decl = GetPointer<ssa_name>(
GET_NODE(ssa_vd));
3166 ssa_var_decl->use_set->Add(ga->op0);
3171 block.second->PushBefore(new_ga, *it_los,
AppM);
3174 restart_analysis =
true;
3190 else if(code0 == indirect_ref_K)
3192 auto* ir = GetPointer<indirect_ref>(
GET_NODE(ga->op0));
3197 restart_analysis =
true;
3199 else if(code0 == misaligned_indirect_ref_K)
3201 auto* MIR = GetPointer<misaligned_indirect_ref>(
GET_NODE(ga->op0));
3208 restart_analysis =
true;
3210 else if(code0 == realpart_expr_K)
3213 restart_analysis =
true;
3215 else if(code0 == imagpart_expr_K)
3218 restart_analysis =
true;
3224 "<--Examined statement " +
GET_NODE(*it_los)->ToString());
3228 if(code0 == bit_field_ref_K)
3230 auto bit_field_ref0 = [&] {
3231 auto* bfr = GetPointer<bit_field_ref>(
GET_NODE(ga->op0));
3235 auto right_shift_val = op1_val % 8;
3237 if(
GET_NODE(bfr->type)->get_kind() == boolean_type_K)
3243 auto* it = GetPointer<integer_type>(
GET_NODE(bfr->type));
3252 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
3255 block.second->PushBefore(new_ga, *it_los,
AppM);
3266 if(right_shift_val == 0 and size_field_decl == size_tp)
3277 GetPointer<gimple_assign>(
GET_NODE(load_ga))->memuse = ga->memuse;
3278 GetPointer<gimple_assign>(
GET_NODE(load_ga))->vuses = ga->vuses;
3279 for(
const auto& vd : bitfield_vuses)
3281 GetPointer<gimple_assign>(
GET_NODE(load_ga))->AddVuse(vd);
3284 bitfield_vdefs.insert(ga->vdef);
3285 block.second->PushBefore(load_ga, *it_los,
AppM);
3290 if(size_field_decl != size_tp)
3292 #if HAVE_FROM_DISCREPANCY_BUILT 3300 (not
parameters->isOption(OPT_discrepancy_force) or
3301 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3310 static_cast<long long int>(~(((1ULL << size_field_decl) - 1) << right_shift_val)), type);
3312 srcp_default, bit_and_expr_K);
3315 block.second->PushBefore(nmask_ga, *it_los,
AppM);
3318 load_var = GetPointer<gimple_assign>(
GET_NODE(nmask_ga))->op0;
3319 #if HAVE_FROM_DISCREPANCY_BUILT 3327 (not
parameters->isOption(OPT_discrepancy_force) or
3328 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3339 THROW_ASSERT(right_shift_val == 0,
"unexpected pattern");
3343 if(size_field_decl != size_tp)
3346 static_cast<long long int>((1ULL << size_field_decl) - 1), type);
3348 srcp_default, bit_and_expr_K);
3351 block.second->PushBefore(and_mask_ga, *it_los,
AppM);
3354 written_var = GetPointer<gimple_assign>(
GET_NODE(and_mask_ga))->op0;
3358 written_var = ga->op1;
3365 srcp_default, lshift_expr_K);
3368 block.second->PushBefore(lsh_ga, *it_los,
AppM);
3371 lshifted_var = GetPointer<gimple_assign>(
GET_NODE(lsh_ga))->op0;
3375 lshifted_var = written_var;
3379 srcp_default, bit_ior_expr_K);
3382 block.second->PushBefore(res_ga, *it_los,
AppM);
3388 #if HAVE_FROM_DISCREPANCY_BUILT 3395 if(size_field_decl != size_tp and
parameters->isOption(OPT_discrepancy) and
3396 parameters->getOption<
bool>(OPT_discrepancy) and
3397 (not
parameters->isOption(OPT_discrepancy_force) or
3398 not
parameters->getOption<
bool>(OPT_discrepancy_force)))
3407 restart_analysis =
true;
3411 else if(code0 == parm_decl_K)
3413 auto* pd = GetPointer<parm_decl>(
GET_NODE(ga->op0));
3419 GetPointer<gimple_assign>(
GET_NODE(new_ga))->temporary_address =
true;
3426 block.second->PushBefore(new_ga, *it_los,
AppM);
3430 restart_analysis =
true;
3432 else if(code0 == result_decl_K && code1 == ssa_name_K)
3438 auto it_los_next = std::next(it_los);
3439 if(it_los_next != it_los_end &&
GET_NODE(*it_los_next)->get_kind() == gimple_return_K)
3441 auto* gr = GetPointer<gimple_return>(
GET_NODE(*it_los_next));
3443 block.second->RemoveStmt(*it_los,
AppM);
3444 it_los = list_of_stmt.begin();
3445 it_los_end = list_of_stmt.end();
3446 bitfield_vuses.clear();
3447 bitfield_vdefs.clear();
3451 else if(code0 == result_decl_K)
3459 block.second->PushBefore(new_ga, *it_los,
AppM);
3461 restart_analysis =
true;
3464 else if(
GET_NODE(*it_los)->get_kind() == gimple_cond_K)
3470 "<--Examined statement " +
GET_NODE(*it_los)->ToString());
3475 auto* gc = GetPointer<gimple_cond>(
GET_NODE(*it_los));
3477 if(GetPointer<binary_expr>(
GET_NODE(gc->op0)))
3479 auto be = GetPointer<binary_expr>(
GET_NODE(gc->op0));
3480 const auto be_kind = be->get_kind();
3481 if(be_kind == eq_expr_K || be_kind == ne_expr_K || be_kind == lt_expr_K || be_kind == le_expr_K ||
3482 be_kind == gt_expr_K || be_kind == ge_expr_K || be_kind == ltgt_expr_K ||
3483 be_kind == truth_and_expr_K || be_kind == truth_andif_expr_K || be_kind == truth_or_expr_K ||
3484 be_kind == truth_orif_expr_K || be_kind == truth_xor_expr_K)
3488 bool changed =
false;
3489 if(
GET_NODE(be->op0)->get_kind() == addr_expr_K)
3491 extract_unary_expr(be->op0,
true,
false);
3493 if(
GET_NODE(be->op1)->get_kind() == addr_expr_K)
3495 extract_unary_expr(be->op1,
true,
false);
3497 if(GetPointer<unary_expr>(
GET_NODE(be->op0)) || GetPointer<binary_expr>(
GET_NODE(be->op0)) ||
3498 GetPointer<ternary_expr>(
GET_NODE(be->op0)))
3501 if(GetPointer<unary_expr>(
GET_NODE(be->op0)))
3503 type = GetPointer<unary_expr>(
GET_NODE(be->op0))->type;
3505 else if(GetPointer<binary_expr>(
GET_NODE(be->op0)))
3507 type = GetPointer<binary_expr>(
GET_NODE(be->op0))->type;
3509 else if(GetPointer<ternary_expr>(
GET_NODE(be->op0)))
3511 type = GetPointer<ternary_expr>(
GET_NODE(be->op0))->type;
3520 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
3522 block.second->PushBefore(new_ga, *it_los,
AppM);
3527 if(GetPointer<unary_expr>(
GET_NODE(be->op1)) || GetPointer<binary_expr>(
GET_NODE(be->op1)) ||
3528 GetPointer<ternary_expr>(
GET_NODE(be->op1)))
3531 if(GetPointer<unary_expr>(
GET_NODE(be->op1)))
3533 type = GetPointer<unary_expr>(
GET_NODE(be->op1))->type;
3535 else if(GetPointer<binary_expr>(
GET_NODE(be->op1)))
3537 type = GetPointer<binary_expr>(
GET_NODE(be->op1))->type;
3539 else if(GetPointer<ternary_expr>(
GET_NODE(be->op1)))
3541 type = GetPointer<ternary_expr>(
GET_NODE(be->op1))->type;
3549 const auto ssa_vd = GetPointer<gimple_assign>(
GET_NODE(new_ga))->op0;
3551 block.second->PushBefore(new_ga, *it_los,
AppM);
3558 restart_analysis =
true;
3568 const auto n_vd = GetPointer<gimple_assign>(
GET_NODE(nga))->op0;
3569 block.second->PushBefore(nga, *it_los,
AppM);
3573 restart_analysis =
true;
3576 if(
GET_NODE(gc->op0)->get_kind() == lt_expr_K ||
GET_NODE(gc->op0)->get_kind() == ge_expr_K)
3578 const auto le = GetPointer<binary_expr>(
GET_NODE(gc->op0));
3581 if(
GET_NODE(le->op1)->get_kind() == integer_cst_K)
3587 block.second->PushBefore(cond_op_ga, *it_los,
AppM);
3588 const auto cond_ga_var = GetPointerS<gimple_assign>(
GET_NODE(cond_op_ga))->op0;
3589 AppM->RegisterTransformation(
GetName(), cond_op_ga);
3590 gc->op0 = cond_ga_var;
3591 restart_analysis =
true;
3599 else if(
GET_NODE(*it_los)->get_kind() == gimple_call_K)
3601 auto* gc = GetPointer<gimple_call>(
GET_NODE(*it_los));
3602 for(
auto&
arg : gc->args)
3607 extract_unary_expr(
arg,
GET_NODE(
arg)->get_kind() == addr_expr_K,
false);
3611 else if(
GET_NODE(*it_los)->get_kind() == gimple_return_K)
3613 auto* gr = GetPointer<gimple_return>(
GET_NODE(*it_los));
3616 if(GetPointer<unary_expr>(
GET_NODE(gr->op)) || GetPointer<binary_expr>(
GET_NODE(gr->op)))
3618 extract_expr(gr->op,
false);
3627 "Control reaches end of non-void function, '" +
3634 "<--Examined statement " +
GET_NODE(*it_los)->ToString());
3637 }
while(restart_analysis);
#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) ...
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
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
File containing functions and utilities to support the printing of debug messagges.
static bool is_int(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of integer type.
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed.
static bool IsConstant(const tree_nodeConstRef &node)
Return if a tree node is a constant object.
tree_nodeRef op1
The second operand of the binary expression.
Definition of the class representing a generic C application.
const int output_level
The output level.
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
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.
static unsigned long long int invert_mod2n(unsigned long long int x, unsigned long long n)
Compute the inverse of X mod 2**n, i.e., find Y such that X * Y is congruent to 1 (mod 2**N)...
tree_nodeRef CreateUnsigned(const tree_nodeConstRef &signed_type) const
Create an unsigned integer type starting from signed type.
mathematical utility function not provided by standard libraries
#define INDENT_OUT_MEX(outLevel, curOutLevel, mex)
tree_nodeRef GetSizeType() const
create a sizetype builtin type in case it has not already been created, otherwise it returns the one ...
static unsigned long long int align(unsigned long long int address, unsigned long long int alignment)
STL includes.
static tree_nodeConstRef CGetElements(const tree_nodeConstRef &type)
Given an array or a vector return the element type.
std::list< DefEdge > DefEdgeList
The type of the def edge list.
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.
tree_nodeRef op0
The first operand of the binary expression.
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
This class contains the base representation for a generic frontend flow step which works on a single ...
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.
#define OUTPUT_LEVEL_MINIMUM
minimum debugging print is performed.
tree_nodeRef CreateAddrExpr(const tree_nodeConstRef &tn, const std::string &srcp) const
Create an addr_expr.
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 THROW_WARNING(str_expr)
helper function used to throw a warning in a standard way: though it uses PRINT_DBG_MEX, the debug level used is such that the message is always printed
#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.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
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.
#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.
T ceil_log2(T x)
Return the smallest n such that 2**n >= X.
static int div_and_round_double_cprop(unsigned long long int lnum_orig, long long int hnum_orig, unsigned long long int lden_orig, unsigned long long int *lquo, long long int *hquo)
static void decode(long long int *words, unsigned long long int *low, long long int *hi)
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
Base class for step of design flow.
tree_nodeRef CreateVectorBooleanType(const unsigned long long number_of_elements) const
Create a vector bool type.
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 ...
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
This struct specifies the gimple_assign node (GCC 4.3 tree node).
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
tree_managerRef TM
The tree manager.
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
This C++ header file contains common macros for the tree structure.
void division_by_a_constant(const std::pair< unsigned int, blocRef > &block, std::list< tree_nodeRef >::const_iterator &it_los, gimple_assign *ga, const tree_nodeRef &op1, enum kind code1, bool &restart_analysis, const std::string &srcp_default, const std::string &step_name)
tree_nodeRef CreateUniqueIntegerCst(integer_cst_t value, const tree_nodeConstRef &type)
memoization of integer constants
std::pair< tree_nodeRef, unsigned int > DefEdge
The type of the def edge.
tree_nodeRef GetTreeReindex(const unsigned int i)
Return a tree_reindex wrapping the i-th tree_node.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
unsigned offset[NUM_VERTICES+1]
#define GET_CONST_NODE(t)
static void encode(long long int *words, unsigned long long int low, long long int hi)
refcount< const tree_node > tree_nodeConstRef
This class contains the base representation for a generic frontend flow step.
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.
DesignFlowStep_Status
The status of a step.
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 ...
This struct specifies the block node.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
This file collects some utility functions.
tree_nodeRef GetTreeNode(const unsigned int index) const
Return the index-th tree_node (modifiable version)
tree_manipulationRef tree_man
The IR manipulation.
tree_nodeRef GetCustomIntegerType(unsigned long long prec, bool unsigned_p) const
create an integer type starting from a given prec
Template definition of refcount.
const unsigned int function_id
The index of the function to be analyzed.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
const application_managerRef AppM
The application manager.
struct definition of the type node structures.
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)
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Decompose some complex gimple statements into set of simple operations.
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)
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 unsigned long long int choose_multiplier(unsigned long long int d, int n, int precision, unsigned long long int *multiplier_ptr, int *post_shift_ptr, int *lgup_ptr)
this class is used to manage the command-line or XML options.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
static unsigned int get_base_index(const tree_managerConstRef &TM, const unsigned int index)
Retrun the base address of a memory access.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
x
Return the smallest n such that 2^n >= _x.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
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.
#define GET_INDEX_CONST_NODE(t)
DesignFlowStep_Status InternalExec() override
traverse the data structure to simplify and make more homogeneous as possible.
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Class specification of the manager of the tree structures extracted from the raw file.
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 CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...