60 #include <boost/range/adaptors.hpp>    61 #include <unordered_set>    67    if(node->get_kind() == ssa_name_K || node->get_kind() == parm_decl_K)
    72    else if(GetPointer<const cst_node>(node))
    78    return std::deque<bit_lattice>();
    83    std::deque<tree_nodeConstRef> working_list, return_list;
    86       const auto stmt_kind = stmt->get_kind();
    87       if(!working_list_idx.count(stmt->index) && (stmt_kind == gimple_assign_K || stmt_kind == gimple_phi_K ||
    88                                                   stmt_kind == gimple_return_K || stmt_kind == gimple_asm_K))
    90          working_list.push_back(stmt);
    91          working_list_idx.insert(stmt->index);
    95       const auto stmt = working_list.front();
    96       working_list.pop_front();
    97       working_list_idx.erase(stmt->index);
   102       for(
const auto& 
phi : bb->CGetPhiList())
   105          const auto gp = GetPointerS<const gimple_phi>(phi_node);
   106          if(!gp->virtual_flag)
   114       for(
const auto& stmt : bb->CGetStmtList())
   117          if(stmt_node->get_kind() == gimple_assign_K)
   119             const auto ga = GetPointerS<const gimple_assign>(stmt_node);
   122                push_back(stmt_node);
   125          else if(stmt_node->get_kind() == gimple_return_K)
   127             return_list.push_back(stmt_node);
   132    const auto is_root_function = 
AppM->CGetCallGraphManager()->GetRootFunctions().count(
function_id);
   133    while(!working_list.empty())
   135       const auto stmt_node = pop_front();
   136       const auto stmt_kind = stmt_node->get_kind();
   138       if(stmt_kind == gimple_assign_K)
   140          const auto ga = GetPointerS<const gimple_assign>(stmt_node);
   142          const auto ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(ga->op0));
   152             bool hasRequiredValues = 
true;
   153             std::vector<std::tuple<unsigned int, unsigned int>> vars_read;
   156             for(
const auto& var_pair : vars_read)
   158                const auto use_node_id = std::get<0>(var_pair);
   163                const auto use_node = 
TM->CGetTreeNode(use_node_id);
   168                const auto ssa_use = GetPointer<const ssa_name>(use_node);
   170                if(ssa_use && !
current.count(use_node_id))
   172                   const auto def_stmt = ssa_use->CGetDefStmt();
   176                                   "Function parameter bitvalue must be defined before");
   184                                     "---Input " + ssa_use->ToString() + 
" definition has not been analyzed yet");
   188                      hasRequiredValues = 
false;
   193             if(hasRequiredValues)
   196                current.insert(std::make_pair(output_nid, 
best.at(output_nid)));
   201                   for(
const auto& next_node : ssa->CGetUseStmts())
   210                               "---Inputs not fully analyzed by the forward Bit Value Analysis. Operation  " +
   211                                   GET_NODE(ga->op0)->ToString() + 
" postponed");
   212                push_back(stmt_node);
   216       else if(stmt_kind == gimple_phi_K)
   218          const auto gp = GetPointerS<const gimple_phi>(stmt_node);
   222          const auto ssa = GetPointerS<const ssa_name>(
GET_CONST_NODE(gp->res));
   234          bool atLeastOne = 
false;
   235          bool allInputs = 
true;
   239          for(
const auto& def_edge : gp->CGetDefEdgesList())
   242             if(def_id == output_nid)
   245                               "---Skipping " + 
STR(def_edge.first) + 
" coming from BB" + 
STR(def_edge.second) +
   246                                   " because of ssa cycle");
   252                const auto def_ssa = GetPointer<const ssa_name>(def_node);
   255                   const auto def_stmt = def_ssa->CGetDefStmt();
   259                                   "Function parameter bitvalue must be defined before");
   267                                     "---Skipping " + 
STR(def_node) +
   268                                         " no current has been yet computed for this ssa var");
   279                   current.insert(std::make_pair(def_id, 
best.at(def_id)));
   296             const auto ins = 
current.insert(std::make_pair(output_nid, res));
   297             auto current_updated = ins.second;
   306                for(
const auto& next_node : ssa->CGetUseStmts())
   308                   push_back(
GET_NODE(next_node.first));
   314             push_back(stmt_node);
   317       else if(stmt_kind == gimple_return_K)
   319          if(!is_root_function)
   321             const auto gr = GetPointerS<const gimple_return>(stmt_node);
   322             THROW_ASSERT(gr->op, 
"Empty return should not be a use of any ssa");
   329                output_current = output_current.size() ? 
inf(res, output_current, 
function_id) : res;
   334       else if(stmt_kind == gimple_asm_K)
   336          const auto ga = GetPointerS<const gimple_asm>(stmt_node);
   340             THROW_ASSERT(tl->valu, 
"only the first output and so only single output gimple_asm are supported");
   341             const auto ssa = GetPointer<const ssa_name>(
GET_CONST_NODE(tl->valu));
   367    std::deque<bit_lattice> res;
   368    const auto& lhs = ga->
op0;
   369    const auto& rhs = ga->
op1;
   383          const auto ae = GetPointerS<const addr_expr>(
GET_CONST_NODE(rhs));
   384          const auto address_size = 
AppM->get_address_bitsize();
   385          const auto is_pretty_print_used =
   388          const auto lt0 = 
lsb_to_zero(ae, is_pretty_print_used);
   390                         "---address_size: " + 
STR(address_size) + 
" lt0: " + 
STR(lt0));
   391          if(lt0 && address_size > lt0)
   406       case truth_not_expr_K:
   407       case view_convert_expr_K:
   426          if(rhs_kind == abs_expr_K)
   429             const auto sign_bit = op_bitstring.front();
   440                   for(
const auto bit : boost::adaptors::reverse(op_bitstring))
   443                      res.push_front(borrow_and_bit_pair.back());
   444                      borrow = borrow_and_bit_pair.front();
   446                   if(res.size() < op_size)
   455                   std::deque<bit_lattice> negated_bitstring;
   457                   for(
const auto& bit : boost::adaptors::reverse(op_bitstring))
   460                      negated_bitstring.push_front(borrow_and_bit_pair.back());
   461                      borrow = borrow_and_bit_pair.front();
   463                   if(negated_bitstring.size() < op_size)
   465                      negated_bitstring.push_front(
   468                   res = 
inf(op_bitstring, negated_bitstring, lhs);
   477             THROW_ASSERT(lhs_signed && op_signed, 
"lhs and rhs of an abs_expr must be signed");
   479          else if(rhs_kind == bit_not_expr_K)
   481             if(op_bitstring.size() == 1 && op_bitstring.at(0) == 
bit_lattice::X &&
   486             if(op_bitstring.size() < lhs_size)
   491             auto op_it = op_bitstring.rbegin();
   492             for(
unsigned bit_index = 0; bit_index < lhs_size && op_it != op_bitstring.rend(); ++op_it, ++bit_index)
   497          else if(rhs_kind == convert_expr_K || rhs_kind == nop_expr_K || rhs_kind == view_convert_expr_K)
   501             if((lhs_signed != op_signed && !do_not_extend) && res.size() < lhs_size)
   505             while(res.size() > lhs_size)
   510          else if(rhs_kind == negate_expr_K)
   513             if(!lhs_signed && lhs_size > op_bitstring.size())
   517             auto op_it = op_bitstring.rbegin();
   518             for(
unsigned bit_index = 0; bit_index < lhs_size && op_it != op_bitstring.rend(); ++op_it, ++bit_index)
   523             if(lhs_signed && res.size() < lhs_size)
   528          else if(rhs_kind == truth_not_expr_K)
   532             for(
auto current_bit : op_bitstring)
   557       case exact_div_expr_K:
   570       case pointer_plus_expr_K:
   573       case trunc_div_expr_K:
   574       case trunc_mod_expr_K:
   575       case truth_and_expr_K:
   576       case truth_andif_expr_K:
   577       case truth_or_expr_K:
   578       case truth_orif_expr_K:
   579       case truth_xor_expr_K:
   580       case widen_mult_expr_K:
   581       case extract_bit_expr_K:
   618          if(rhs_kind == bit_and_expr_K)
   620             if(lhs_size > op0_bitstring.size())
   624             if(lhs_size > op1_bitstring.size())
   629             auto op0_it = op0_bitstring.rbegin();
   630             auto op1_it = op1_bitstring.rbegin();
   631             for(
auto bit_index = 0u;
   632                 bit_index < lhs_size && op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
   633                 ++op0_it, ++op1_it, ++bit_index)
   638          else if(rhs_kind == bit_ior_expr_K)
   640             if(op0_bitstring.size() == 1 && op0_bitstring.at(0) == 
bit_lattice::X &&
   645             if(op1_bitstring.size() == 1 && op1_bitstring.at(0) == 
bit_lattice::X &&
   650             if(lhs_size > op1_bitstring.size())
   654             if(lhs_size > op0_bitstring.size())
   659             auto op0_it = op0_bitstring.rbegin();
   660             auto op1_it = op1_bitstring.rbegin();
   661             for(
auto bit_index = 0u;
   662                 bit_index < lhs_size && op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
   663                 ++op0_it, ++op1_it, ++bit_index)
   668          else if(rhs_kind == bit_xor_expr_K)
   670             if(op0_bitstring.size() == 1 && op0_bitstring.at(0) == 
bit_lattice::X &&
   675             if(op1_bitstring.size() == 1 && op1_bitstring.at(0) == 
bit_lattice::X &&
   681             if(lhs_size > op1_bitstring.size())
   685             if(lhs_size > op0_bitstring.size())
   690             auto op0_it = op0_bitstring.rbegin();
   691             auto op1_it = op1_bitstring.rbegin();
   692             for(
auto bit_index = 0u;
   693                 bit_index < lhs_size && op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
   694                 ++op0_it, ++op1_it, ++bit_index)
   699          else if(rhs_kind == eq_expr_K)
   701             if(op0_bitstring.size() > op1_bitstring.size())
   705             if(op1_bitstring.size() > op0_bitstring.size())
   710             auto op0_bitstring_it = op0_bitstring.begin();
   711             auto op1_bitstring_it = op1_bitstring.begin();
   712             auto computed_result = 
false;
   713             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
   714                 ++op0_bitstring_it, ++op1_bitstring_it)
   720                   computed_result = 
true;
   728                   computed_result = 
true;
   739          else if(rhs_kind == exact_div_expr_K || rhs_kind == trunc_div_expr_K)
   749             while(res.size() > lhs_size)
   754          else if(rhs_kind == ge_expr_K)
   756             if(op0_bitstring.size() > op1_bitstring.size())
   760             if(op1_bitstring.size() > op0_bitstring.size())
   765             const auto is_signed_var = op0_signed || op1_signed;
   766             auto op0_bitstring_it = op0_bitstring.begin();
   767             auto op1_bitstring_it = op1_bitstring.begin();
   768             auto computed_result = 
false;
   769             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
   770                 ++op0_bitstring_it, ++op1_bitstring_it)
   776                   computed_result = 
true;
   781                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   791                   computed_result = 
true;
   796                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   806                   computed_result = 
true;
   817          else if(rhs_kind == gt_expr_K)
   819             if(op0_bitstring.size() > op1_bitstring.size())
   823             if(op1_bitstring.size() > op0_bitstring.size())
   828             const auto is_signed_var = op0_signed || op1_signed;
   829             auto op0_bitstring_it = op0_bitstring.begin();
   830             auto op1_bitstring_it = op1_bitstring.begin();
   831             auto computed_result = 
false;
   832             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
   833                 ++op0_bitstring_it, ++op1_bitstring_it)
   839                   computed_result = 
true;
   844                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   854                   computed_result = 
true;
   859                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   869                   computed_result = 
true;
   880          else if(rhs_kind == le_expr_K)
   882             if(op0_bitstring.size() > op1_bitstring.size())
   886             if(op1_bitstring.size() > op0_bitstring.size())
   891             const auto is_signed_var = op0_signed || op1_signed;
   892             auto op0_bitstring_it = op0_bitstring.begin();
   893             auto op1_bitstring_it = op1_bitstring.begin();
   894             auto computed_result = 
false;
   895             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
   896                 ++op0_bitstring_it, ++op1_bitstring_it)
   902                   computed_result = 
true;
   907                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   917                   computed_result = 
true;
   922                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
   932                   computed_result = 
true;
   943          else if(rhs_kind == lrotate_expr_K)
   953                if(lhs_size > op0_bitstring.size())
   962                   res.push_back(cur_bit);
   970          else if(rhs_kind == lshift_expr_K)
   974                const auto bsize_elev2 = 1ULL << op1_bitstring.size();
   975                if(lhs_size < bsize_elev2 || lhs_size < bsize_elev2 + op0_bitstring.size())
   981                   res = 
create_u_bitstring(static_cast<unsigned int>(op0_bitstring.size() + bsize_elev2));
   994                if(lhs_size <= static_cast<size_t>(cst_val))
  1000                   res = op0_bitstring;
  1001                   while(res.size() > op0_bitsize)
  1008                      if(res.size() > lhs_size)
  1020          else if(rhs_kind == lt_expr_K)
  1022             if(op0_bitstring.size() > op1_bitstring.size())
  1026             if(op1_bitstring.size() > op0_bitstring.size())
  1031             const auto is_signed_var = op0_signed || op1_signed;
  1032             auto op0_bitstring_it = op0_bitstring.begin();
  1033             auto op1_bitstring_it = op1_bitstring.begin();
  1034             auto computed_result = 
false;
  1035             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
  1036                 ++op0_bitstring_it, ++op1_bitstring_it)
  1042                   computed_result = 
true;
  1047                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
  1057                   computed_result = 
true;
  1062                   if(op0_bitstring_it == op0_bitstring.begin() && is_signed_var)
  1072                   computed_result = 
true;
  1076             if(!computed_result)
  1083          else if(rhs_kind == max_expr_K || rhs_kind == min_expr_K)
  1085             if(op0_bitstring.size() > op1_bitstring.size())
  1089             if(op1_bitstring.size() > op0_bitstring.size())
  1095             res = 
inf(op0_bitstring, op1_bitstring, 
operation->op0);
  1097          else if(rhs_kind == minus_expr_K)
  1099             const auto arg_size_max = 
std::max(op0_bitstring.size(), op1_bitstring.size());
  1100             if(arg_size_max > op1_bitstring.size())
  1104             if(arg_size_max > op0_bitstring.size())
  1109             auto op0_it = op0_bitstring.rbegin();
  1110             auto op1_it = op1_bitstring.rbegin();
  1112             for(
auto bit_index = 0u;
  1113                 bit_index < lhs_size && op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
  1114                 ++op0_it, ++op1_it, ++bit_index)
  1116                res.push_front(
minus_expr_map.at(*op0_it).at(*op1_it).at(borrow).back());
  1117                borrow = 
minus_expr_map.at(*op0_it).at(*op1_it).at(borrow).front();
  1119             if(lhs_signed && res.size() < lhs_size)
  1121                res.push_front(
minus_expr_map.at(op0_bitstring.front()).at(op1_bitstring.front()).at(borrow).back());
  1123             else if(!lhs_signed)
  1125                while(res.size() < lhs_size)
  1127                   res.push_front(borrow);
  1131          else if(rhs_kind == mult_expr_K || rhs_kind == widen_mult_expr_K)
  1188             const auto lenght_op0 = op0_bitstring.size();
  1189             const auto lenght_op1 = op1_bitstring.size();
  1190             const auto res_bitsize = 
std::min(lenght_op0 + lenght_op1, static_cast<size_t>(lhs_size));
  1191             if(res_bitsize > op0_bitstring.size())
  1195             if(res_bitsize > op1_bitstring.size())
  1199             while(op0_bitstring.size() > res_bitsize)
  1201                op0_bitstring.pop_front();
  1203             while(op1_bitstring.size() > res_bitsize)
  1205                op1_bitstring.pop_front();
  1208             while(res.size() < res_bitsize)
  1212             auto op1_it = op1_bitstring.crbegin();
  1213             for(
auto pos = 0u; op1_it != op1_bitstring.crend() && pos < res_bitsize; ++op1_it, ++pos)
  1215                std::deque<bit_lattice> temp_op1;
  1216                while(temp_op1.size() < pos)
  1220                auto op0_it = op0_bitstring.crbegin();
  1221                for(
size_t idx = 0; (idx + pos) < res_bitsize; ++idx, ++op0_it)
  1226                std::deque<bit_lattice> temp_res;
  1227                auto temp_op1_it = temp_op1.crbegin();
  1228                const auto temp_op1_end = temp_op1.crend();
  1229                auto res_it = res.crbegin();
  1230                const auto res_end = res.crend();
  1231                for(
auto bit_index = 0u; bit_index < res_bitsize && temp_op1_it != temp_op1_end && res_it != res_end;
  1232                    temp_op1_it++, res_it++, bit_index++)
  1234                   temp_res.push_front(
plus_expr_map.at(*temp_op1_it).at(*res_it).at(carry1).back());
  1235                   carry1 = 
plus_expr_map.at(*temp_op1_it).at(*res_it).at(carry1).front();
  1240          else if(rhs_kind == ne_expr_K)
  1242             if(op0_bitstring.size() > op1_bitstring.size())
  1246             if(op1_bitstring.size() > op0_bitstring.size())
  1251             auto op0_bitstring_it = op0_bitstring.begin();
  1252             auto op1_bitstring_it = op1_bitstring.begin();
  1253             auto computed_result = 
false;
  1254             for(; op0_bitstring_it != op0_bitstring.end() && op1_bitstring_it != op1_bitstring.end();
  1255                 ++op0_bitstring_it, ++op1_bitstring_it)
  1261                   computed_result = 
true;
  1269                   computed_result = 
true;
  1273             if(!computed_result)
  1280          else if(rhs_kind == plus_expr_K || rhs_kind == pointer_plus_expr_K)
  1282             if(op0_bitstring.size() > op1_bitstring.size())
  1286             if(op1_bitstring.size() > op0_bitstring.size())
  1291             auto op0_it = op0_bitstring.rbegin();
  1292             auto op1_it = op1_bitstring.rbegin();
  1294             for(
auto bit_index = 0u;
  1295                 bit_index < lhs_size && op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
  1296                 ++op0_it, ++op1_it, ++bit_index)
  1300                res.push_front(
plus_expr_map.at(*op0_it).at(*op1_it).at(carry1).back());
  1301                carry1 = 
plus_expr_map.at(*op0_it).at(*op1_it).at(carry1).front();
  1304             if(lhs_signed && res.size() < lhs_size)
  1306                res.push_front(
plus_expr_map.at(op0_bitstring.front()).at(op1_bitstring.front()).at(carry1).back());
  1308             else if(!lhs_signed)
  1310                while(res.size() < lhs_size)
  1317          else if(rhs_kind == rrotate_expr_K)
  1327                if(lhs_size > op0_bitstring.size())
  1331                res = op0_bitstring;
  1334                   const auto cur_bit = res.back();
  1336                   res.push_front(cur_bit);
  1344          else if(rhs_kind == rshift_expr_K)
  1356                                  "---forward_transfer, negative right shift is undefined behavior");
  1361                if(op0_bitstring.size() <= 
static_cast<size_t>(cst_val))
  1365                      res.push_front(op0_bitstring.front());
  1374                   const auto new_lenght = op0_bitstring.size() - 
static_cast<size_t>(cst_val);
  1375                   auto op0_it = op0_bitstring.begin();
  1376                   while(res.size() < new_lenght)
  1378                      res.push_back(*op0_it);
  1388          else if(rhs_kind == trunc_mod_expr_K)
  1393                    1 + static_cast<unsigned int>(
std::min(op0_bitstring.size(), op1_bitstring.size())));
  1400             while(res.size() > lhs_size)
  1405          else if(rhs_kind == truth_and_expr_K || rhs_kind == truth_andif_expr_K || rhs_kind == truth_or_expr_K ||
  1406                  rhs_kind == truth_orif_expr_K || rhs_kind == truth_xor_expr_K)
  1408             if(op0_bitstring.size() > op1_bitstring.size())
  1412             if(op1_bitstring.size() > op0_bitstring.size())
  1418             for(
const auto& current_bit : op0_bitstring)
  1431             for(
const auto& current_bit : op1_bitstring)
  1443             if(rhs_kind == truth_and_expr_K || rhs_kind == truth_andif_expr_K)
  1447             else if(rhs_kind == truth_or_expr_K || rhs_kind == truth_orif_expr_K)
  1451             else if(rhs_kind == truth_xor_expr_K)
  1460          else if(rhs_kind == extract_bit_expr_K)
  1466             if(op0_bitstring.size() <= 
static_cast<size_t>(cst_val))
  1470                   res.push_front(op0_bitstring.front());
  1479                const auto new_lenght = op0_bitstring.size() - 
static_cast<size_t>(cst_val);
  1480                auto op0_it = op0_bitstring.begin();
  1481                while(res.size() < new_lenght)
  1483                   res.push_back(*op0_it);
  1486                while(res.size() > 1)
  1499       case bit_ior_concat_expr_K:
  1501       case ternary_plus_expr_K:
  1502       case ternary_pm_expr_K:
  1503       case ternary_mp_expr_K:
  1504       case ternary_mm_expr_K:
  1557          if(rhs_kind == bit_ior_concat_expr_K)
  1561             if(op0_bitstring.size() > op1_bitstring.size())
  1565             if(op1_bitstring.size() > op0_bitstring.size())
  1570             auto op0_it = op0_bitstring.rbegin();
  1571             auto op1_it = op1_bitstring.rbegin();
  1572             for(
integer_cst_t index = 0; op0_it != op0_bitstring.rend() && op1_it != op1_bitstring.rend();
  1573                 ++op0_it, ++op1_it, ++
index)
  1577                   res.push_front(*op1_it);
  1581                   res.push_front(*op0_it);
  1585          else if(rhs_kind == cond_expr_K)
  1588             for(
const auto& current_bit : op0_bitstring)
  1604                res = op2_bitstring;
  1609                res = op1_bitstring;
  1623                const auto inf_size = 
std::max(op1_bitstring.size(), op2_bitstring.size());
  1624                if(op1_bitstring.size() < inf_size)
  1628                if(op2_bitstring.size() < inf_size)
  1632                res = 
inf(op1_bitstring, op2_bitstring, lhs);
  1635          else if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_pm_expr_K || rhs_kind == ternary_mp_expr_K ||
  1636                  rhs_kind == ternary_mm_expr_K)
  1638             const auto arg_size_max = 
std::max({op0_bitstring.size(), op1_bitstring.size(), op2_bitstring.size()});
  1639             if(op0_bitstring.size() < arg_size_max)
  1643             if(op1_bitstring.size() < arg_size_max)
  1647             if(op2_bitstring.size() < arg_size_max)
  1652             auto op0_it = op0_bitstring.crbegin();
  1653             auto op1_it = op1_bitstring.crbegin();
  1654             const auto op0_end = op0_bitstring.crend();
  1655             const auto op1_end = op1_bitstring.crend();
  1657             std::deque<bit_lattice> res_int;
  1658             for(
auto bit_index = 0u; bit_index < lhs_size && op0_it != op0_end && op1_it != op1_end;
  1659                 op0_it++, op1_it++, bit_index++)
  1661                if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_pm_expr_K)
  1663                   res_int.push_front(
plus_expr_map.at(*op0_it).at(*op1_it).at(carry1).back());
  1664                   carry1 = 
plus_expr_map.at(*op0_it).at(*op1_it).at(carry1).front();
  1668                   res_int.push_front(
minus_expr_map.at(*op0_it).at(*op1_it).at(carry1).back());
  1669                   carry1 = 
minus_expr_map.at(*op0_it).at(*op1_it).at(carry1).front();
  1673             if(lhs_signed && res_int.size() < lhs_size)
  1675                if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_pm_expr_K)
  1678                       plus_expr_map.at(op0_bitstring.front()).at(op1_bitstring.front()).at(carry1).back());
  1683                       minus_expr_map.at(op0_bitstring.front()).at(op1_bitstring.front()).at(carry1).back());
  1686             else if(!lhs_signed)
  1688                while(res_int.size() < lhs_size)
  1690                   if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_pm_expr_K)
  1704             if(res_int.size() > op2_bitstring.size())
  1709             auto op2_it = op2_bitstring.crbegin();
  1710             auto res_int_it = res_int.crbegin();
  1711             const auto op2_end = op2_bitstring.crend();
  1712             const auto res_int_end = res_int.crend();
  1714             for(
auto bit_index = 0u; bit_index < lhs_size && op2_it != op2_end && res_int_it != res_int_end;
  1715                 op2_it++, res_int_it++, bit_index++)
  1717                if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_mp_expr_K)
  1719                   res.push_front(
plus_expr_map.at(*res_int_it).at(*op2_it).at(carry1).back());
  1720                   carry1 = 
plus_expr_map.at(*res_int_it).at(*op2_it).at(carry1).front();
  1724                   res.push_front(
minus_expr_map.at(*res_int_it).at(*op2_it).at(carry1).back());
  1725                   carry1 = 
minus_expr_map.at(*res_int_it).at(*op2_it).at(carry1).front();
  1729             if(lhs_signed && res.size() < lhs_size)
  1731                if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_mp_expr_K)
  1733                   res.push_front(
plus_expr_map.at(res_int.front()).at(op2_bitstring.front()).at(carry1).back());
  1737                   res.push_front(
minus_expr_map.at(res_int.front()).at(op2_bitstring.front()).at(carry1).back());
  1740             else if(!lhs_signed)
  1742                while(res.size() < lhs_size)
  1744                   if(rhs_kind == ternary_plus_expr_K || rhs_kind == ternary_mp_expr_K)
  1757          else if(rhs_kind == fshl_expr_K)
  1767                                                              static_cast<unsigned int>(lhs_size));
  1769                if(lhs_size > op0_bitstring.size())
  1773                if(lhs_size > op1_bitstring.size())
  1777                res.insert(res.end(), op0_bitstring.begin() + 
offset, op0_bitstring.end());
  1778                res.insert(res.end(), op1_bitstring.begin(), op1_bitstring.begin() + 
offset);
  1786          else if(rhs_kind == fshr_expr_K)
  1796                                                              static_cast<unsigned int>(lhs_size));
  1798                if(lhs_size > op0_bitstring.size())
  1802                if(lhs_size > op1_bitstring.size())
  1806                res.insert(res.end(), op0_bitstring.begin() + 
offset, op0_bitstring.end());
  1807                res.insert(res.end(), op1_bitstring.begin(), op1_bitstring.begin() + 
offset);
  1823       case fix_ceil_expr_K:
  1824       case fix_floor_expr_K:
  1825       case fix_round_expr_K:
  1826       case fix_trunc_expr_K:
  1827       case imagpart_expr_K:
  1828       case realpart_expr_K:
  1829       case alignof_expr_K:
  1833       case ordered_expr_K:
  1834       case sat_minus_expr_K:
  1835       case sat_plus_expr_K:
  1841       case unordered_expr_K:
  1842       case extractvalue_expr_K:
  1843       case extractelement_expr_K:
  1845       case bit_field_ref_K:
  1846       case component_ref_K:
  1847       case insertvalue_expr_K:
  1848       case insertelement_expr_K:
  1855       case aggr_init_expr_K:
  1861             const auto called_id = call_it->second;
  1862             const auto tn = 
TM->CGetTreeNode(called_id);
  1863             THROW_ASSERT(tn->get_kind() == function_decl_K, 
"node " + 
STR(called_id) + 
" is not a function_decl");
  1864             const auto* fd = GetPointerS<const function_decl>(tn);
  1865             if(fd->bit_values.empty())
  1886       case cleanup_point_expr_K:
  1890       case indirect_ref_K:
  1891       case misaligned_indirect_ref_K:
  1893       case non_lvalue_expr_K:
  1894       case reference_expr_K:
  1895       case reinterpret_cast_expr_K:
  1897       case static_cast_expr_K:
  1902       case reduc_max_expr_K:
  1903       case reduc_min_expr_K:
  1904       case reduc_plus_expr_K:
  1905       case vec_unpack_hi_expr_K:
  1906       case vec_unpack_lo_expr_K:
  1907       case vec_unpack_float_hi_expr_K:
  1908       case vec_unpack_float_lo_expr_K:
  1912       case ceil_div_expr_K:
  1913       case ceil_mod_expr_K:
  1914       case complex_expr_K:
  1915       case compound_expr_K:
  1916       case eh_filter_expr_K:
  1918       case floor_div_expr_K:
  1919       case floor_mod_expr_K:
  1920       case goto_subroutine_K:
  1924       case mult_highpart_expr_K:
  1925       case postdecrement_expr_K:
  1926       case postincrement_expr_K:
  1927       case predecrement_expr_K:
  1928       case preincrement_expr_K:
  1932       case round_div_expr_K:
  1933       case round_mod_expr_K:
  1935       case try_catch_expr_K:
  1937       case widen_sum_expr_K:
  1938       case with_size_expr_K:
  1939       case vec_lshift_expr_K:
  1940       case vec_rshift_expr_K:
  1941       case widen_mult_hi_expr_K:
  1942       case widen_mult_lo_expr_K:
  1943       case vec_pack_trunc_expr_K:
  1944       case vec_pack_sat_expr_K:
  1945       case vec_pack_fix_trunc_expr_K:
  1946       case vec_extracteven_expr_K:
  1947       case vec_extractodd_expr_K:
  1948       case vec_interleavehigh_expr_K:
  1949       case vec_interleavelow_expr_K:
  1952       case with_cleanup_expr_K:
  1953       case obj_type_ref_K:
  1955       case vec_cond_expr_K:
  1956       case vec_perm_expr_K:
  1957       case dot_prod_expr_K:
  1959       case array_range_ref_K:
  1974       case case_label_expr_K:
  1977       case identifier_node_K:
  1978       case statement_list_K:
  1980       case target_mem_ref_K:
  1981       case target_mem_ref461_K:
 #define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed. 
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;. 
std::deque< bit_lattice > create_bitstring_from_constant(integer_cst_t value, unsigned long long len, bool signed_value)
Creates a bitstring from a constant input. 
static const std::map< bit_lattice, std::map< bit_lattice, std::map< bit_lattice, std::deque< bit_lattice > > > > plus_expr_map
Map storing the implementation of the forward_transfer's plus_expr. 
File containing functions and utilities to support the printing of debug messagges. 
std::string ToString() const
Print this node as string in gimple format. 
#define DEBUG_LEVEL_PEDANTIC
very verbose debugging print is performed. 
std::deque< bit_lattice > create_x_bitstring(size_t lenght)
Create a bitstring containing bits initialized at <X> 
tree_nodeRef op1
The second operand of the binary expression. 
Definition of the class representing a generic C application. 
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string. 
Full implementation of Bit Value analysis as described in BitValue Inference: Detecting and Exploitin...
tree_nodeRef op0
The first operand of the binary expression. 
bool IsHandledByBitvalue(const tree_nodeConstRef &tn) const
Returns true if the type identified by type_id is handled by bitvalue analysis. 
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Data structure describing a basic block at tree level. 
static void get_required_values(std::vector< std::tuple< unsigned int, unsigned int >> &required, const tree_nodeRef &tn)
#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 const std::map< bit_lattice, std::map< bit_lattice, std::map< bit_lattice, std::deque< bit_lattice > > > > minus_expr_map
Map storing the implementation of the forward_transfer's minus_expr. 
void forward()
Applies the forward algorithm, as described in the paper, analyzing each assignment statement followi...
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type. 
std::string bitstring_to_string(const std::deque< bit_lattice > &bitstring)
Translates a bitstring ( expressed as an std::deque of bit_lattice ) into a string of characters...
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached 
std::deque< bit_lattice > inf(const std::deque< bit_lattice > &a, const std::deque< bit_lattice > &b, const unsigned int output_uid) const
Computes the inf between two bitstrings. 
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type. 
This class specifies the characteristic of a particular operation working on a given functional unit...
This struct specifies the gimple_assign node (GCC 4.3 tree node). 
std::deque< bit_lattice > create_u_bitstring(size_t lenght)
Creates a bitstring containing bits initialized at <U> 
unsigned int lsb_to_zero(const addr_expr *ae, bool safe) const
CustomMap< unsigned int, std::deque< bit_lattice > > current
Map of the current bit-values of each variable. 
static const std::map< bit_lattice, std::map< bit_lattice, bit_lattice > > bit_and_expr_map
Map storing the implementation of the forward_transfer's bit_and_expr_map. 
bool update_current(std::deque< bit_lattice > &res, const tree_nodeConstRef &tn)
Given a bitstring res, and the id of a tree node ouput_uid, this functions checks if it is necessary ...
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
static const std::map< bit_lattice, std::map< bit_lattice, bit_lattice > > bit_ior_expr_map
Map storing the implementation of the forward_transfer's bit_ior_expr_map. 
std::deque< bit_lattice > get_current(const tree_nodeConstRef &tn) const
Given an operand, returns its current bitvalue. 
unsigned offset[NUM_VERTICES+1]
#define GET_CONST_NODE(t)
static unsigned long long Size(const tree_nodeConstRef &t)
Classes specification of the tree_node data structures. 
const ParameterConstRef parameters
Set of input parameters. 
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way 
const tree_managerConstRef TM
#define CASE_TYPE_NODES
This macro collects all case labels for type objects. 
This file collects some utility functions. 
std::deque< bit_lattice > string_to_bitstring(const std::string &s)
inverse of bitstring_to_string 
CustomUnorderedMapUnstable< unsigned int, unsigned int > direct_call_id_to_called_id
Maps the id of a gimple statement to the id of the function called in that statement. 
const unsigned int function_id
The index of the function to be analyzed. 
std::deque< bit_lattice > forward_transfer(const gimple_assign *ga) const
Takes a gimple assignment, analyzes the operation performed from the rhs and its input bitstring...
const application_managerRef AppM
The application manager. 
Class specification of the tree_reindex support class. 
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes. 
std::vector< blocRef > bb_topological
Topologically ordered basic blocks. 
Class specification of the basic_block structure. 
CustomMap< unsigned int, std::deque< bit_lattice > > best
Map of the best bit-values of each variable. 
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node. 
static std::deque< bit_lattice > sign_extend_bitstring(const std::deque< bit_lattice > &bitstring, bool bitstring_is_signed, size_t final_size)
Extends a bitstring. 
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. 
#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 GET_INDEX_CONST_NODE(t)
bool IsSignedIntegerType(const tree_nodeConstRef &tn) const
static const std::map< bit_lattice, std::map< bit_lattice, bit_lattice > > bit_xor_expr_map
Map storing the implementation of the forward_transfer's bit_xor_expr_map. 
Class specification of the manager of the tree structures extracted from the raw file. 
A brief description of the C++ Header File. 
#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 ...