66 : TM(_TM), bl_debug_level(_bl_debug_level)
102 const size_t out_type_size,
const bool out_is_signed,
103 const bool out_is_bool)
108 THROW_ASSERT(!out_is_bool || (out_type_size == 1),
"boolean with type size != 1");
109 std::deque<bit_lattice> res;
112 res.push_back(
bit_sup(_a.back(), _b.back()));
116 std::deque<bit_lattice> longer = (_a.size() >= _b.size()) ? _a : _b;
117 std::deque<bit_lattice> shorter = (_a.size() >= _b.size()) ? _b : _a;
118 while(longer.size() > out_type_size)
122 while(shorter.size() > out_type_size)
126 if(longer.size() < out_type_size)
130 if(shorter.size() < out_type_size)
161 auto a_it = longer.crbegin();
162 auto b_it = shorter.crbegin();
163 const auto a_end = longer.crend();
164 const auto b_end = shorter.crend();
165 for(; a_it != a_end && b_it != b_end; a_it++, b_it++)
167 res.push_front(
bit_sup(*a_it, *b_it));
178 auto sign_bit = res.front();
183 ((a_sign_is_x == b_sign_is_x ||
187 (a_sign_is_x ? _a.size() : _b.size())));
188 THROW_ASSERT(final_size,
"final size of sup cannot be 0");
192 final_size =
std::min(out_type_size, (a_sign_is_x == b_sign_is_x) ?
194 (a_sign_is_x ? (_a.size() < _b.size() ? _a.size() : 1 + _b.size()) :
195 (_a.size() < _b.size() ? 1 + _a.size() : _b.size())));
196 sign_bit = (a_sign_is_x == b_sign_is_x) ? sign_bit :
199 THROW_ASSERT(final_size,
"final size of sup cannot be 0");
201 while(res.size() > final_size)
208 res.push_front(sign_bit);
219 const unsigned int output_uid)
const 221 return sup(a, b,
TM->CGetTreeNode(output_uid));
227 THROW_ASSERT(!a.empty() && !b.empty(),
"a.size() = " +
STR(a.size()) +
" b.size() = " +
STR(b.size()));
234 size_t out_type_size = 0;
235 if(
kind == ssa_name_K ||
kind == parm_decl_K ||
kind == integer_cst_K)
237 out_type_size =
static_cast<size_t>(
Size(node_type));
239 else if(
kind == function_decl_K)
243 "node " +
STR(out_node) +
" is " + node_type->get_kind_text());
244 const auto ft = GetPointerS<const function_type>(
GET_CONST_NODE(node_type));
245 out_type_size =
static_cast<size_t>(
Size(ft->retn));
253 THROW_ASSERT(!out_is_bool || (out_type_size == 1),
"boolean with type size != 1");
255 return sup(a, b, out_type_size, out_is_signed, out_is_bool);
283 const size_t out_type_size,
const bool out_is_signed,
284 const bool out_is_bool)
286 THROW_ASSERT(!(a.empty() && b.empty()),
"a.size() = " +
STR(a.size()) +
" b.size() = " +
STR(b.size()));
288 THROW_ASSERT(!out_is_bool || (out_type_size == 1),
"boolean with type size != 1");
289 std::deque<bit_lattice> res;
292 res.push_back(
bit_inf(a.back(), b.back()));
296 std::deque<bit_lattice> a_copy = a;
297 std::deque<bit_lattice> b_copy = b;
302 std::deque<bit_lattice> a_tmp = (a_copy.size() >= b_copy.size()) ? a_copy : b_copy;
303 std::deque<bit_lattice> b_tmp = (a_copy.size() >= b_copy.size()) ? b_copy : a_copy;
305 if(a_tmp.size() > b_tmp.size())
310 auto a_it = a_tmp.crbegin();
311 auto b_it = b_tmp.crbegin();
312 const auto a_end = a_tmp.crend();
313 const auto b_end = b_tmp.crend();
314 for(; a_it != a_end && b_it != b_end; a_it++, b_it++)
316 res.push_front(
bit_inf(*a_it, *b_it));
326 while(res.size() > out_type_size)
334 const unsigned int output_uid)
const 336 return inf(a, b,
TM->CGetTreeNode(output_uid));
342 THROW_ASSERT(!(a.empty() && b.empty()),
"a.size() = " +
STR(a.size()) +
" b.size() = " +
STR(b.size()));
347 size_t out_type_size = 0;
348 if(
kind == ssa_name_K ||
kind == parm_decl_K ||
kind == integer_cst_K)
350 out_type_size =
static_cast<size_t>(
Size(node_type));
352 else if(
kind == function_decl_K)
356 "node " +
STR(out_node) +
" is " + node_type->get_kind_text());
357 const auto ft = GetPointerS<const function_type>(
GET_CONST_NODE(node_type));
358 out_type_size =
static_cast<size_t>(
Size(ft->retn));
366 THROW_ASSERT(!out_is_bool || (out_type_size == 1),
"boolean with type size != 1");
368 return inf(a, b, out_type_size, out_is_signed, out_is_bool);
375 while(bitstring.size() > 1)
377 if(bitstring_is_signed)
379 if(bitstring.at(0) !=
bit_lattice::U && bitstring.at(0) == bitstring.at(1))
381 bitstring.pop_front();
393 bitstring.pop_front();
397 bitstring.pop_front();
398 bitstring.pop_front();
410 bool bitstring_is_signed,
size_t final_size)
412 THROW_ASSERT(final_size,
"cannot sign extend a bitstring to final_size 0");
413 THROW_ASSERT(final_size > bitstring.size(),
"useless sign extension");
414 std::deque<bit_lattice> res = bitstring;
420 while(res.size() < final_size)
422 res.push_front(sign_bit);
428 unsigned int ssa_node_id)
const 432 auto* c = GetPointerS<const constructor>(ctor_tn);
433 std::vector<unsigned long long> array_dims;
434 unsigned long long elements_bitsize;
436 unsigned int initialized_elements = 0;
437 std::deque<bit_lattice> current_inf;
439 std::deque<bit_lattice> cur_bitstring;
440 for(
const auto& i : c->list_of_idx_valu)
445 if(
el->get_kind() == integer_cst_K)
450 else if(
el->get_kind() == real_cst_K)
452 THROW_ASSERT(elements_bitsize == 64 || elements_bitsize == 32,
453 "Unhandled real type size (" +
STR(elements_bitsize) +
")");
454 const auto real_const = GetPointerS<const real_cst>(
el);
455 if(real_const->valx.front() ==
'-' && real_const->valr.front() != real_const->valx.front())
465 else if(
el->get_kind() == constructor_K &&
469 "invalid nested constructors:" + ctor_tn->
ToString() +
" " +
STR(array_dims.size()));
477 current_inf =
inf(current_inf, cur_bitstring, ssa_node_id);
478 initialized_elements++;
480 if(initialized_elements < array_dims.front())
488 unsigned int ssa_node_id)
const 491 auto* sc = GetPointerS<string_cst>(strcst_tn);
492 const std::string
str = sc->strg;
495 for(
const auto c : str)
498 current_inf =
inf(current_inf, current_el, ssa_node_id);
512 auto updated =
false;
515 const auto c =
current.find(b.first);
518 const auto cur_lattice = c->second;
519 const auto best_lattice = b.second;
520 const auto sup_lattice =
sup(cur_lattice, best_lattice, b.first);
521 if(best_lattice != sup_lattice)
523 b.second = sup_lattice;
526 const auto tn =
TM->CGetTreeNode(b.first);
530 STR(tn->get_kind() == function_decl_K ?
556 if(cur_lattice != sup_lattice)
558 cur_lattice = sup_lattice;
584 std::deque<bit_lattice> res;
591 for(bit = 0; bit < len && value != 0; bit++, value >>= 1)
595 if(bit < len && signed_value)
605 for(
const auto bit : bitstring)
631 std::deque<bit_lattice> res;
632 for(
const auto bit : s)
649 THROW_ERROR(std::string(
"unexpected char in bitvalue string: ") + bit);
659 for(
const auto i : a)
685 THROW_ASSERT(GetPointerS<const decl_node>(t)->
type,
"expected a var decl type");
686 if(t->
get_kind() == function_decl_K)
694 const auto sa = GetPointerS<const ssa_name>(t);
700 const auto at = GetPointerS<const array_type>(t);
707 return static_cast<unsigned long long>(val);
719 case enumeral_type_K:
720 case function_type_K:
726 case reference_type_K:
727 case type_pack_expansion_K:
728 case type_argument_pack_K:
732 const auto tn = GetPointer<const type_node>(t);
736 return static_cast<unsigned long long>(val);
740 const auto it = GetPointer<const integer_type>(t);
741 if(it->prec != it->algn && it->prec % it->algn)
748 return static_cast<unsigned long long>(val);
755 case aggr_init_expr_K:
757 const auto ce = GetPointerS<const call_expr>(t);
764 const auto te = GetPointerS<const expr_node>(t);
773 const auto ar = GetPointerS<const array_ref>(t);
778 const auto sc = GetPointerS<const cst_node>(t);
783 const auto c = GetPointerS<const constructor>(t);
786 case target_mem_ref461_K:
788 const auto tmr = GetPointerS<const target_mem_ref461>(t);
795 case array_range_ref_K:
798 case case_label_expr_K:
799 case identifier_node_K:
802 case qual_union_type_K:
804 case statement_list_K:
806 case target_mem_ref_K:
807 case template_type_parm_K:
810 case typename_type_K:
814 case placeholder_expr_K:
816 case gimple_assign_K:
822 case gimple_multi_way_if_K:
825 case gimple_pragma_K:
826 case gimple_predict_K:
828 case gimple_return_K:
829 case gimple_switch_K:
846 auto a_it = av.crbegin();
847 auto b_it = bv.crbegin();
848 const auto a_end = av.crend();
849 const auto b_end = bv.crend();
850 for(; a_it != a_end && b_it != b_end; a_it++, b_it++)
857 return a_string.size() < b_string.size();
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
std::deque< bit_lattice > string_cst_bitstring(const tree_nodeRef &strcst_tn, unsigned int ssa_node_id) const
auxiliary function used to build the bitstring lattice for read-only string_cst
std::string convert_fp_to_string(std::string num, unsigned long long precision)
convert a real number stored in a string into a string of bits with a given precision ...
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
#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.
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.
std::string ToString() const
Print this node as string in gimple format.
static bool IsConstant(const tree_nodeConstRef &node)
Return if a tree node is a constant object.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
std::deque< bit_lattice > create_x_bitstring(size_t lenght)
Create a bitstring containing bits initialized at <X>
#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 bool isBetter(const std::string &a_string, const std::string &b_string)
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
bool bitstring_constant(const std::deque< bit_lattice > &a)
Checks if a bitstring is constant.
bool IsHandledByBitvalue(const tree_nodeConstRef &tn) const
Returns true if the type identified by type_id is handled by bitvalue analysis.
static bit_lattice bit_inf(const bit_lattice a, const bit_lattice b)
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static void sign_reduce_bitstring(std::deque< bit_lattice > &bitstring, bool bitstring_is_signed)
Reduce the size of a bitstring erasing all but one most significant zeros in unsigned bitstring and a...
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
CustomSet< unsigned int > signed_var
Set storing the signed ssa.
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
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
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.
const int bl_debug_level
The debug level of methods of this class - it cannot be named debug_level because of ambiguity of Fro...
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
std::deque< bit_lattice > create_u_bitstring(size_t lenght)
Creates a bitstring containing bits initialized at <U>
static bit_lattice bit_sup(const bit_lattice a, const bit_lattice b)
CustomMap< unsigned int, std::deque< bit_lattice > > current
Map of the current bit-values of each variable.
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 unsigned long long size(const tree_managerConstRef tm, unsigned int index)
BitLatticeManipulator(const tree_managerConstRef TM, const int debug_level)
Constructor.
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
#define GET_CONST_NODE(t)
static unsigned long long Size(const tree_nodeConstRef &t)
Classes specification of the tree_node data structures.
This file collects some utility functions and macros.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
const tree_managerConstRef TM
This file collects some utility functions.
bool mix()
Mixes the content of current and best using the sup operation, storing the result in the best map...
std::deque< bit_lattice > string_to_bitstring(const std::string &s)
inverse of bitstring_to_string
std::deque< bit_lattice > sup(const std::deque< bit_lattice > &a, const std::deque< bit_lattice > &b, const unsigned int output_uid) const
Computes the sup between two bitstrings.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Class specification of the tree_reindex support class.
CustomMap< unsigned int, std::deque< bit_lattice > > best
Map of the best bit-values of each variable.
std::deque< bit_lattice > constructor_bitstring(const tree_nodeRef &ctor_tn, unsigned int ssa_node_id) const
auxiliary function used to build the bitstring lattice for read-only arrays
void clear()
Clean up the internal data structures.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
static bool IsStructType(const tree_nodeConstRef &type)
Return true if treenode is a record.
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.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
#define GET_INDEX_CONST_NODE(t)
bool IsSignedIntegerType(const tree_nodeConstRef &tn) const
~BitLatticeManipulator()
Destructor.
#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.
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
static void get_array_dim_and_bitsize(const tree_managerConstRef &TM, const unsigned int index, std::vector< unsigned long long > &dims, unsigned long long &elts_bitsize)
Return the dimension of the array.
#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 ...