From: matevos Date: Fri, 23 Dec 2022 15:12:36 +0000 (+0400) Subject: sym-exec v10 - Added sign number support - Done a fix in XOR optimization - Done... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=44821463a1b54bb451169e856272b70e19ee6c01;p=thirdparty%2Fgcc.git sym-exec v10 - Added sign number support - Done a fix in XOR optimization - Done some refactoring --- diff --git a/gcc/gimple-crc-optimization.cc b/gcc/gimple-crc-optimization.cc index fe9e4beeff49..26e45f5ae56b 100644 --- a/gcc/gimple-crc-optimization.cc +++ b/gcc/gimple-crc-optimization.cc @@ -939,7 +939,7 @@ crc_optimization::execute (function *fun) } crc_symb_execution execute_loop; - vec * lfsr + value * lfsr = execute_loop.extract_poly_and_create_lfsr (crc_loop, first_phi_for_crc, data, is_left_shift); @@ -954,7 +954,7 @@ crc_optimization::execute (function *fun) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "\nLFSR value is \n"); - state::print_bits (lfsr); + state::print_value (lfsr); } } diff --git a/gcc/sym-exec/condition.cc b/gcc/sym-exec/condition.cc index dffb13620c1d..0e7dacdf4f46 100644 --- a/gcc/sym-exec/condition.cc +++ b/gcc/sym-exec/condition.cc @@ -1,7 +1,8 @@ #include "condition.h" -bit_condition::bit_condition (value* left, value* right, condition_type type) +bit_condition::bit_condition (value_bit* left, value_bit* right, + condition_type type) { this->left = left; this->right = right; @@ -54,7 +55,7 @@ bit_condition::get_cond_type () const } -value * +value_bit * bit_condition::copy () const { return new bit_condition (*this); diff --git a/gcc/sym-exec/condition.h b/gcc/sym-exec/condition.h index 7ecdde7ad323..3cb32381d7db 100644 --- a/gcc/sym-exec/condition.h +++ b/gcc/sym-exec/condition.h @@ -29,10 +29,10 @@ class bit_condition : public bit_expression condition_type type; public: - bit_condition (value* left, value* right, condition_type type); + bit_condition (value_bit* left, value_bit* right, condition_type type); bit_condition (const bit_condition &expr); condition_type get_cond_type () const; - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; diff --git a/gcc/sym-exec/expression-is-a-helper.h b/gcc/sym-exec/expression-is-a-helper.h index dafc91c1597b..ab9b56030eed 100644 --- a/gcc/sym-exec/expression-is-a-helper.h +++ b/gcc/sym-exec/expression-is-a-helper.h @@ -9,7 +9,7 @@ template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::SYMBOLIC_BIT; } @@ -18,7 +18,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT; } @@ -27,7 +27,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { value_type type = ptr->get_type (); return type == value_type::BIT_AND_EXPRESSION @@ -45,7 +45,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT_AND_EXPRESSION; } @@ -54,7 +54,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT_OR_EXPRESSION; } @@ -63,7 +63,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT_XOR_EXPRESSION; } @@ -72,7 +72,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT_COMPLEMENT_EXPRESSION; } @@ -81,7 +81,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::SHIFT_LEFT_EXPRESSION; } @@ -90,7 +90,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::SHIFT_RIGHT_EXPRESSION; } @@ -99,7 +99,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::ADD_EXPRESSION; } @@ -108,7 +108,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::SUB_EXPRESSION; } @@ -117,7 +117,7 @@ is_a_helper ::test (value * ptr) template <> template <> inline bool -is_a_helper ::test (value * ptr) +is_a_helper ::test (value_bit * ptr) { return ptr->get_type () == value_type::BIT_CONDITION; } diff --git a/gcc/sym-exec/expression.cc b/gcc/sym-exec/expression.cc index d980315fd74a..71a9081c9385 100644 --- a/gcc/sym-exec/expression.cc +++ b/gcc/sym-exec/expression.cc @@ -5,14 +5,14 @@ #include "expression-is-a-helper.h" -value * +value_bit * bit_expression::get_left () { return left; } -value * +value_bit * bit_expression::get_right () { return right; @@ -20,21 +20,21 @@ bit_expression::get_right () void -bit_expression::set_left (value *expr) +bit_expression::set_left (value_bit *expr) { left = expr; } void -bit_expression::set_right (value *expr) +bit_expression::set_right (value_bit *expr) { right = expr; } size_t -value::get_index () const +value_bit::get_index () const { return index; } @@ -54,7 +54,7 @@ bit::set_val (unsigned char new_val) } -bit_complement_expression::bit_complement_expression (value *right) +bit_complement_expression::bit_complement_expression (value_bit *right) { this->left = nullptr; this->right = right; @@ -79,14 +79,14 @@ bit_expression::~bit_expression () } -value* +value_bit* symbolic_bit::copy () const { return new symbolic_bit (*this); } -value * +value_bit * bit::copy () const { return new bit (*this); @@ -107,63 +107,63 @@ bit_expression::copy (const bit_expression *expr) } -value * +value_bit * bit_xor_expression::copy () const { return new bit_xor_expression (*this); } -value * +value_bit * bit_and_expression::copy () const { return new bit_and_expression (*this); } -value * +value_bit * bit_or_expression::copy () const { return new bit_or_expression (*this); } -value * +value_bit * shift_right_expression::copy () const { return new shift_right_expression (*this); } -value * +value_bit * shift_left_expression::copy () const { return new shift_left_expression (*this); } -value * +value_bit * add_expression::copy () const { return new add_expression (*this); } -value * +value_bit * sub_expression::copy () const { return new sub_expression (*this); } -value * +value_bit * bit_complement_expression::copy () const { return new bit_complement_expression (*this); } -bit_xor_expression::bit_xor_expression (value *left, value *right) +bit_xor_expression::bit_xor_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; @@ -178,7 +178,7 @@ bit_xor_expression::bit_xor_expression (const bit_xor_expression &expr) } -bit_and_expression::bit_and_expression (value *left, value *right) +bit_and_expression::bit_and_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; @@ -193,7 +193,7 @@ bit_and_expression::bit_and_expression (const bit_and_expression& expr) } -bit_or_expression::bit_or_expression (value *left, value *right) +bit_or_expression::bit_or_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; @@ -208,7 +208,8 @@ bit_or_expression::bit_or_expression (const bit_or_expression& expr) } -shift_right_expression::shift_right_expression (value *left, value *right) +shift_right_expression::shift_right_expression (value_bit *left, + value_bit *right) { this->left = left; this->right = right; @@ -224,7 +225,7 @@ shift_right_expression::shift_right_expression ( } -shift_left_expression::shift_left_expression (value *left, value *right) +shift_left_expression::shift_left_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; @@ -239,7 +240,7 @@ shift_left_expression::shift_left_expression (const shift_left_expression& expr) } -add_expression::add_expression (value *left, value *right) +add_expression::add_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; @@ -254,7 +255,7 @@ add_expression::add_expression (const add_expression& expr) } -sub_expression::sub_expression (value *left, value *right) +sub_expression::sub_expression (value_bit *left, value_bit *right) { this->left = left; this->right = right; diff --git a/gcc/sym-exec/expression.h b/gcc/sym-exec/expression.h index 9d03a4e24675..254d62ebdb83 100644 --- a/gcc/sym-exec/expression.h +++ b/gcc/sym-exec/expression.h @@ -44,43 +44,42 @@ enum value_type { /* Base class for single bit value. */ -class value { +class value_bit { protected: /* This will help us to understand where is moved the bit from its initial position. */ const size_t index; public: - value () : index (0) + value_bit () : index (0) {}; - value (size_t i) : index (i) + value_bit (size_t i) : index (i) {}; - value (value &val) : index (val.index) + value_bit (value_bit &val) : index (val.index) {}; size_t get_index () const; /* This will support deep copy of objects' values. */ - virtual value *copy () const = 0; + virtual value_bit *copy () const = 0; virtual value_type get_type () const = 0; virtual void print () = 0; - virtual ~value () + virtual ~value_bit () {}; }; - /* Represents value of a single bit of symbolic marked variables. */ -class symbolic_bit : public value { +class symbolic_bit : public value_bit { tree origin = nullptr; public: - symbolic_bit (size_t i, tree orig) : value (i), origin (orig) + symbolic_bit (size_t i, tree orig) : value_bit (i), origin (orig) {}; symbolic_bit (const symbolic_bit &sym_bit) : symbolic_bit (sym_bit.index, sym_bit.origin) {}; - value *copy () const; + value_bit *copy () const; void print (); value_type get_type () const; tree get_origin (); @@ -89,7 +88,7 @@ class symbolic_bit : public value { /* Represents value of a single bit. */ -class bit : public value { +class bit : public value_bit { private: /* This is the value of a bit. It must be either 1 or 0. */ unsigned char val = 0; @@ -101,7 +100,7 @@ class bit : public value { {}; unsigned char get_val () const; void set_val (unsigned char new_val); - value *copy () const; + value_bit *copy () const; value_type get_type () const; void print (); }; @@ -110,23 +109,23 @@ class bit : public value { /* Bit-level base expression class. In general expressions consist of two operands. Here we named them left and right. */ -class bit_expression : public value { +class bit_expression : public value_bit { protected: - value *left = nullptr; - value *right = nullptr; + value_bit *left = nullptr; + value_bit *right = nullptr; char op_sign[2]; void copy (const bit_expression *expr); public: - value *get_left (); - value *get_right (); + value_bit *get_left (); + value_bit *get_right (); ~bit_expression (); - void set_left (value *expr); - void set_right (value *expr); - value *copy () const = 0; + void set_left (value_bit *expr); + void set_right (value_bit *expr); + value_bit *copy () const = 0; value_type get_type () const = 0; void print (); }; @@ -138,9 +137,9 @@ class bit_expression : public value { class bit_xor_expression : public bit_expression { public: - bit_xor_expression (value *left, value *right); + bit_xor_expression (value_bit *left, value_bit *right); bit_xor_expression (const bit_xor_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -151,9 +150,9 @@ class bit_xor_expression : public bit_expression { class bit_and_expression : public bit_expression { public: - bit_and_expression (value *left, value *right); + bit_and_expression (value_bit *left, value_bit *right); bit_and_expression (const bit_and_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -164,9 +163,9 @@ class bit_and_expression : public bit_expression { class bit_or_expression : public bit_expression { public: - bit_or_expression (value *left, value *right); + bit_or_expression (value_bit *left, value_bit *right); bit_or_expression (const bit_or_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -175,9 +174,9 @@ class bit_or_expression : public bit_expression { class shift_right_expression : public bit_expression { public: - shift_right_expression (value *left, value *right); + shift_right_expression (value_bit *left, value_bit *right); shift_right_expression (const shift_right_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -186,9 +185,9 @@ class shift_right_expression : public bit_expression { class shift_left_expression : public bit_expression { public: - shift_left_expression (value *left, value *right); + shift_left_expression (value_bit *left, value_bit *right); shift_left_expression (const shift_left_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -197,9 +196,9 @@ class shift_left_expression : public bit_expression { class add_expression : public bit_expression { public: - add_expression (value *left, value *right); + add_expression (value_bit *left, value_bit *right); add_expression (const add_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -208,9 +207,9 @@ class add_expression : public bit_expression { class sub_expression : public bit_expression { public: - sub_expression (value *left, value *right); + sub_expression (value_bit *left, value_bit *right); sub_expression (const sub_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; }; @@ -218,9 +217,9 @@ class sub_expression : public bit_expression { class bit_complement_expression : public bit_expression { public: - bit_complement_expression (value *right); + bit_complement_expression (value_bit *right); bit_complement_expression (const bit_complement_expression &expr); - value *copy () const; + value_bit *copy () const; value_type get_type () const; void print (); }; diff --git a/gcc/sym-exec/state.cc b/gcc/sym-exec/state.cc index 02b433133d67..1d8fe643798e 100644 --- a/gcc/sym-exec/state.cc +++ b/gcc/sym-exec/state.cc @@ -9,17 +9,15 @@ state::state () { } - state::state (const state& s) { for (auto iter = s.var_states.begin (); iter != s.var_states.end (); ++iter) { - vec < value * > bits; - bits.create ((*iter).second.length ()); + value val ((*iter).second.length (), (*iter).second.is_unsigned); for (size_t i = 0; i < (*iter).second.length (); i++) - bits.quick_push ((*iter).second[i]->copy ()); + val.push ((*iter).second[i]->copy ()); - var_states.put ((*iter).first, bits); + var_states.put ((*iter).first, val); } for (auto iter = s.conditions.begin (); iter != s.conditions.end (); ++iter) @@ -44,23 +42,27 @@ state::is_declared (tree var) } -void +bool state::declare_if_needed (tree var, size_t size) { if (TREE_CODE (var) != INTEGER_CST && !is_declared (var)) - make_symbolic (var, size); + { + make_symbolic (var, size); + return true; + } + return false; } -vec * -state::get_bits (tree var) +value * +state::get_value (tree var) { return var_states.get (var); } /* Get the value of the tree, which is in the beginning of the var_states. */ -vec * +value * state::get_first_value () { return &(*(var_states.begin ())).second; @@ -94,29 +96,35 @@ state::check_args_compatibility (tree arg1, tree arg2, tree dest) } -/* Creates bit sequence of given constant tree. */ +/* Creates value for given constant tree. */ -vec -state::create_bits_for_const (tree var, size_t size) +value +state::create_val_for_const (tree var, size_t size) { HOST_WIDE_INT val = tree_to_shwi (var); - vec bits; - bits.create (size); + value result (size, TYPE_UNSIGNED (TREE_TYPE (var))); for (size_t i = 0; i < size; i++) { - bits.quick_push (new bit (val & 1)); + result.push (new bit (val & 1)); val >>= 1; } - return bits; + return result; } -/* Removes given sequence of bits. */ +/* Removes given value. */ void -state::free_bits (vec * bits) +state::free_val (value * val) +{ + free_bits (&val->number); +} + + +void +state::free_bits (vec * bits) { if (bits == nullptr || !bits->exists ()) return; @@ -130,15 +138,15 @@ state::free_bits (vec * bits) bool -state::add_var_state (tree var, vec * vstate) +state::add_var_state (tree var, value * vstate) { - vec bits; - bits.create (vstate->length ()); - for (size_t i = 0; i < vstate->length (); i++) - bits.quick_push ((*vstate)[i]->copy ()); + size_t size = vstate->length (); + value val (size, vstate->is_unsigned); + for (size_t i = 0; i < size; i++) + val.push ((*vstate)[i]->copy ()); - free_bits (var_states.get (var)); - return var_states.put (var, bits); + free_val (var_states.get (var)); + return var_states.put (var, val); } @@ -165,11 +173,10 @@ state::clear_states () { for (auto iter = var_states.begin (); iter != var_states.end (); ++iter) { - vec < value * > *bits = &(*iter).second; - for (size_t i = 0; i < bits->length (); i++) - delete (*bits)[i]; + value * var = &(*iter).second; + for (size_t i = 0; i < var->length (); i++) + delete (*var)[i]; } - var_states.empty (); } @@ -185,8 +192,8 @@ state::clear_conditions () /* Performs AND operation for 2 symbolic_bit operands. */ -value * -state::and_sym_bits (const value * var1, const value * var2) +value_bit * +state::and_sym_bits (const value_bit * var1, const value_bit * var2) { return new bit_and_expression (var1->copy (), var2->copy ()); } @@ -194,8 +201,8 @@ state::and_sym_bits (const value * var1, const value * var2) /* Performs AND operation for a symbolic_bit and const_bit operands. */ -value * -state::and_var_const (const value * var1, const bit * const_bit) +value_bit * +state::and_var_const (const value_bit * var1, const bit * const_bit) { if (const_bit->get_val () == 1) return var1->copy (); @@ -218,8 +225,8 @@ state::and_const_bits (const bit * const_bit1, const bit * const_bit2) /* Performs OR operation for 2 symbolic_bit operands. */ -value * -state::or_sym_bits (const value * var1, const value * var2) +value_bit * +state::or_sym_bits (const value_bit * var1, const value_bit * var2) { return new bit_or_expression (var1->copy (), var2->copy ()); } @@ -227,8 +234,8 @@ state::or_sym_bits (const value * var1, const value * var2) /* Performs OR operation for a symbolic_bit and a constant bit operands. */ -value * -state::or_var_const (const value * var1, const bit * const_bit) +value_bit * +state::or_var_const (const value_bit * var1, const bit * const_bit) { if (const_bit->get_val () == 0) return var1->copy (); @@ -257,12 +264,11 @@ state::decl_var (tree var, unsigned size) if (is_declared (var)) return false; - vec < value * > content; - content.create (size); + value val (size, TYPE_UNSIGNED (TREE_TYPE (var))); for (unsigned i = 0; i < size; i++) - content.quick_push (nullptr); + val.push (nullptr); - return var_states.put (var, content); + return var_states.put (var, val); } @@ -271,7 +277,7 @@ state::decl_var (tree var, unsigned size) unsigned state::get_var_size (tree var) { - vec < value * > *content = var_states.get (var); + value *content = var_states.get (var); if (content == NULL) return 0; @@ -288,45 +294,42 @@ state::make_symbolic (tree var, unsigned size) if (is_declared (var)) return false; - vec < value * > bits; - bits.create (size); - + value val (size, TYPE_UNSIGNED (TREE_TYPE (var))); /* Initialize each bit of a variable with unknown value. */ for (size_t i = 0; i < size; i++) - bits.quick_push (new symbolic_bit (i, var)); + val.push (new symbolic_bit (i, var)); - return var_states.put (var, bits); + return var_states.put (var, val); } -/* Performs AND operation on two bits. */ +/* Performs AND operation on two values. */ -value * -state::and_two_bits (value *arg1_bit, value* arg2_bit) +value_bit * +state::and_two_bits (value_bit *arg1, value_bit* arg2) { - value *result = nullptr; + value_bit *result = nullptr; - if (is_a (arg1_bit) && is_a (arg2_bit)) - result = and_const_bits (as_a (arg1_bit), as_a (arg2_bit)); + if (is_a (arg1) && is_a (arg2)) + result = and_const_bits (as_a (arg1), as_a (arg2)); - else if (is_a (arg1_bit) && (is_a (arg2_bit) - || (is_a (arg2_bit)))) - result = and_var_const (arg2_bit, as_a (arg1_bit)); + else if (is_a (arg1) && (is_a (arg2) + || (is_a (arg2)))) + result = and_var_const (arg2, as_a (arg1)); - else if ((is_a (arg1_bit) - || (is_a (arg1_bit))) && is_a (arg2_bit)) - result = and_var_const (arg1_bit, as_a (arg2_bit)); + else if ((is_a (arg1) + || (is_a (arg1))) && is_a (arg2)) + result = and_var_const (arg1, as_a (arg2)); else - result = and_sym_bits (arg1_bit, arg2_bit); + result = and_sym_bits (arg1, arg2); return result; } /* Does preprocessing and postprocessing for expressions with tree operands. - Handles bit sequence creation for constant values - and their removement in the end. */ + Handles value creation for constant and their removement in the end. */ bool state::do_binary_operation (tree arg1, tree arg2, tree dest, @@ -339,29 +342,29 @@ state::do_binary_operation (tree arg1, tree arg2, tree dest, if (!check_args_compatibility (arg1, arg2, dest)) return false; - vec * arg1_bits = var_states.get (arg1); - vec arg1_const_bits (vNULL); - if (arg1_bits == NULL && TREE_CODE (arg1) == INTEGER_CST) + size_t dest_size = var_states.get (dest)->length (); + + value *arg1_val = var_states.get (arg1); + value arg1_const_val (dest_size, false); + if (arg1_val == NULL && TREE_CODE (arg1) == INTEGER_CST) { - arg1_const_bits = create_bits_for_const (arg1, - var_states.get (dest)->length ()); - arg1_bits = &arg1_const_bits; + arg1_const_val = create_val_for_const (arg1, dest_size); + arg1_val = &arg1_const_val; } - vec * arg2_bits = var_states.get (arg2); - vec arg2_const_bits (vNULL); - if (arg2_bits == NULL && TREE_CODE (arg2) == INTEGER_CST) + value *arg2_val = var_states.get (arg2); + value arg2_const_val (dest_size, false); + if (arg2_val == NULL && TREE_CODE (arg2) == INTEGER_CST) { - arg2_const_bits = create_bits_for_const (arg2, - var_states.get (dest)->length ()); - arg2_bits = &arg2_const_bits; + arg2_const_val = create_val_for_const (arg2, dest_size); + arg2_val = &arg2_const_val; } - (this->*bin_func)(arg1_bits, arg2_bits, dest); - free_bits (&arg1_const_bits); - free_bits (&arg2_const_bits); + (this->*bin_func)(arg1_val, arg2_val, dest); + free_val (&arg1_const_val); + free_val (&arg2_const_val); - print_bits (var_states.get (dest)); + print_value (var_states.get (dest)); return true; } @@ -376,16 +379,15 @@ state::do_and (tree arg1, tree arg2, tree dest) void -state::do_and (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_and (value * arg1, value * arg2, tree dest) { /* Creating AND expressions for every bit pair of given arguments and store them as a new state for given destination. */ for (size_t i = 0; i < get_var_size (dest); i++) { - value* temp = (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = and_two_bits ((*arg1_bits)[i], - (*arg2_bits)[i]); + value_bit* temp = (*var_states.get (dest))[i]; + (*var_states.get (dest))[i] = and_two_bits ((*arg1)[i], (*arg2)[i]); delete temp; } } @@ -393,20 +395,21 @@ state::do_and (vec * arg1_bits, vec * arg2_bits, tree dest) /* Performs OR operation on two bits. */ -value * -state::or_two_bits (value *arg1_bit, value* arg2_bit) +value_bit * +state::or_two_bits (value_bit *arg1_bit, value_bit* arg2_bit) { - value *result = nullptr; + value_bit *result = nullptr; if (is_a (arg1_bit) && is_a (arg2_bit)) result = or_const_bits (as_a (arg1_bit), as_a (arg2_bit)); else if (is_a (arg1_bit) && (is_a (arg2_bit) - || (is_a (arg2_bit)))) + || is_a (arg2_bit))) result = or_var_const (arg2_bit, as_a (arg1_bit)); else if ((is_a (arg1_bit) - || (is_a (arg1_bit))) && is_a (arg2_bit)) + || is_a (arg1_bit)) + && is_a (arg2_bit)) result = or_var_const (arg1_bit, as_a (arg2_bit)); else @@ -426,15 +429,14 @@ state::do_or (tree arg1, tree arg2, tree dest) void -state::do_or (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_or (value * arg1, value * arg2, tree dest) { /* Creating OR expressions for every bit pair of given arguments and store them as a new state for given destination. */ for (size_t i = 0; i < get_var_size (dest); i++) { - value * temp = (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = or_two_bits ((*arg1_bits)[i], - (*arg2_bits)[i]); + value_bit * temp = (*var_states.get (dest))[i]; + (*var_states.get (dest))[i] = or_two_bits ((*arg1)[i], (*arg2)[i]); delete temp; } } @@ -442,20 +444,21 @@ state::do_or (vec * arg1_bits, vec * arg2_bits, tree dest) /* Performs XOR operation on two bits. */ -value * -state::xor_two_bits (value *arg1_bit, value* arg2_bit) +value_bit * +state::xor_two_bits (value_bit *arg1_bit, value_bit* arg2_bit) { - value *result = nullptr; + value_bit *result = nullptr; if (is_a (arg1_bit) && is_a (arg2_bit)) result = xor_const_bits (as_a (arg1_bit), as_a (arg2_bit)); else if (is_a (arg1_bit) && (is_a (arg2_bit) - || (is_a (arg2_bit)))) + || is_a (arg2_bit))) result = xor_var_const (arg2_bit, as_a (arg1_bit)); else if ((is_a (arg1_bit) - || (is_a (arg1_bit))) && is_a (arg2_bit)) + || is_a (arg1_bit)) + && is_a (arg2_bit)) result = xor_var_const (arg1_bit, as_a (arg2_bit)); else @@ -475,68 +478,66 @@ state::do_xor (tree arg1, tree arg2, tree dest) void -state::do_xor (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_xor (value * arg1, value * arg2, tree dest) { for (size_t i = 0; i < get_var_size (dest); i++) { - value * temp = (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = xor_two_bits ((*arg1_bits)[i], - (*arg2_bits)[i]); + value_bit * temp = (*var_states.get (dest))[i]; + (*var_states.get (dest))[i] = xor_two_bits ((*arg1)[i], (*arg2)[i]); delete temp; } } -/* Shifts value_vector right by shift_value bits. */ +/* Shifts value right by size of shift_value. */ -vec -state::shift_right_by_const (const vec * number, - size_t shift_value) +value * +state::shift_right_by_const (value * var, size_t shift_value) { - vec shift_result; - shift_result.create (number->length ()); - if (number->length () <= shift_value) - for (size_t i = 0; i < number->length (); i++) - shift_result.quick_push (new bit (0)); + value * shift_result = new value (var->length (), var->is_unsigned); + if (var->length () <= shift_value) + for (size_t i = 0; i < var->length (); i++) + shift_result->push (new bit (0)); else { size_t i = 0; - for (; i < number->length () - shift_value; ++i) - shift_result.quick_push (((*number)[shift_value + i])->copy ()); + for (; i < var->length () - shift_value; ++i) + shift_result->push (((*var)[shift_value + i])->copy ()); - for (; i < number->length (); ++i) - shift_result.quick_push (new bit (0)); + for (; i < var->length (); ++i) + shift_result->push (var->is_unsigned ? new bit (0) + : var->last ()->copy ()); } return shift_result; } -/* Checks if all vector elements are const_bit_expressions. */ +/* Checks if all bits of the given value have constant bit type. */ bool -state::is_bit_vector (const vec * bits) +state::is_bit_vector (const value* var) { - if (bits == nullptr) + if (var == nullptr || !var->exists ()) return false; - for (size_t i = 0; i < bits->length (); i++) - if (!(is_a ((*bits)[i]))) - return false; + for (size_t i = 0; i < var->length (); i++) + if (!(is_a ((*var)[i]))) + return false; return true; } -/* Returns the value of the number represented as a bit vector. */ +/* Returns the number represented by the value. */ unsigned HOST_WIDE_INT -state::get_value (const vec * bits_value) +state::make_number (const value * var) { unsigned HOST_WIDE_INT number = 0; - int bits_value_size = bits_value->length (); - for (int i = bits_value_size - 1; i >= 0; i--) + int value_size = var->length (); + for (int i = value_size - 1; i >= 0; i--) { - if (is_a ((*bits_value)[i])) - number = (number << 1) | as_a ((*bits_value)[i])->get_val (); + if (is_a ((*var)[i])) + number = (number << 1) | as_a ((*var)[i])->get_val (); else return 0; } @@ -544,20 +545,19 @@ state::get_value (const vec * bits_value) } -/* Shift_left operation. Case: var2 is a sym_bit. */ +/* Shift_left operation. Case: var2 is a symbolic value. */ void -state::shift_left_sym_bits (vec * arg1_bits, vec * arg2_bits, - tree dest) +state::shift_left_sym_values (value * arg1, value * arg2, tree dest) { for (size_t i = 0; i < get_var_size (dest); i++) { - value *var1_elem = (*arg1_bits)[i]; - value *var2_elem = (*arg2_bits)[i]; - value *new_elem = new shift_left_expression (var1_elem->copy (), - var2_elem->copy ()); + value_bit *var1_bit = (*arg1)[i]; + value_bit *var2_bit = (*arg2)[i]; + value_bit *new_bit = new shift_left_expression (var1_bit->copy (), + var2_bit->copy ()); delete (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = new_elem; + (*var_states.get (dest))[i] = new_bit; } } @@ -572,13 +572,12 @@ state::do_shift_left (tree arg1, tree arg2, tree dest) void -state::do_shift_left (vec * arg1_bits, vec * arg2_bits, - tree dest) +state::do_shift_left (value * arg1, value * arg2, tree dest) { - if (is_bit_vector (arg2_bits)) + if (is_bit_vector (arg2)) { - size_t shift_value = get_value (arg2_bits); - vec * result = shift_left_by_const (arg1_bits, shift_value); + size_t shift_value = make_number (arg2); + value * result = shift_left_by_const (arg1, shift_value); for (size_t i = 0; i < get_var_size (dest); i++) { delete (*var_states.get (dest))[i]; @@ -587,7 +586,7 @@ state::do_shift_left (vec * arg1_bits, vec * arg2_bits, delete result; } else - shift_left_sym_bits (arg1_bits, arg2_bits, dest); + shift_left_sym_values (arg1, arg2, dest); } @@ -602,36 +601,34 @@ state::do_shift_right (tree arg1, tree arg2, tree dest) void -state::do_shift_right (vec * arg1_bits, vec * arg2_bits, - tree dest) +state::do_shift_right (value * arg1, value * arg2, tree dest) { - /* TODO: Add support for signed var shift. */ - if (is_bit_vector (arg2_bits)) + if (is_bit_vector (arg2)) { - size_t shift_value = get_value (arg2_bits); - vec < value * > result = shift_right_by_const (arg1_bits, shift_value); + size_t shift_value = make_number (arg2); + value *result = shift_right_by_const (arg1, shift_value); for (size_t i = 0; i < get_var_size (dest); i++) { delete (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = result[i]; + (*var_states.get (dest))[i] = (*result)[i]; } } else - shift_right_sym_bits (arg1_bits, arg2_bits, dest); + shift_right_sym_values (arg1, arg2, dest); } /* Adds two bits and carry value. Resturn result and stores new carry bit in "carry". */ -value* -state::full_adder (value* var1, value* var2, value*& carry) +value_bit* +state::full_adder (value_bit* var1, value_bit* var2, value_bit*& carry) { - value * new_carry = and_two_bits (var1, var2); - value * sum = xor_two_bits (var1, var2); + value_bit * new_carry = and_two_bits (var1, var2); + value_bit * sum = xor_two_bits (var1, var2); - value* result = xor_two_bits (sum, carry); - value * sum_and_carry = and_two_bits (sum, carry); + value_bit * result = xor_two_bits (sum, carry); + value_bit * sum_and_carry = and_two_bits (sum, carry); delete carry; delete sum; @@ -655,47 +652,43 @@ state::do_add (tree arg1, tree arg2, tree dest) void -state::do_add (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_add (value * arg1, value * arg2, tree dest) { - value * carry = new bit (0); + value_bit * carry = new bit (0); for (size_t i = 0; i < get_var_size (dest); ++i) { - value * temp = (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = full_adder ((*arg1_bits)[i], - (*arg2_bits)[i], - carry); + value_bit * temp = (*var_states.get (dest))[i]; + (*var_states.get (dest))[i] = full_adder ((*arg1)[i], (*arg2)[i], carry); delete temp; } delete carry; } -/* Returns the additive inverse of the number stored in number verctor. */ +/* Returns the additive inverse of the given number. */ -vec < value * > * -state::additive_inverse (const vec *number) +value * +state::additive_inverse (const value *number) { - vec * result = new vec (); - vec * one = new vec (); - - result->create (number->length ()); - one->create (number -> length ()); + value * result = new value (number->length (), number->is_unsigned); + value one (number->length (), number->is_unsigned); - size_t vec_len = number->length (); - one->quick_push (new bit (1)); - result->quick_push (complement_a_bit ((*number)[0]->copy ())); + size_t size = number->length (); + one.push (new bit (1)); + result->push (complement_a_bit ((*number)[0]->copy ())); - for (size_t i = 1; i < vec_len; i++) + for (size_t i = 1; i < size; i++) { - one->quick_push (new bit (0)); - result->quick_push (complement_a_bit ((*number)[i]->copy ())); + one.push (new bit (0)); + result->push (complement_a_bit ((*number)[i]->copy ())); } - value * carry = new bit (0); - for (size_t i = 0; i < vec_len; ++i) - (*result)[i] = full_adder ((*result)[i], (*one)[i], carry); + value_bit * carry = new bit (0); + for (size_t i = 0; i < size; ++i) + (*result)[i] = full_adder ((*result)[i], one[i], carry); delete carry; + free_val (&one); return result; } @@ -710,22 +703,22 @@ state::do_sub (tree arg1, tree arg2, tree dest) void -state::do_sub (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_sub (value * arg1, value * arg2, tree dest) { - vec < value * > * neg_arg2 = additive_inverse (arg2_bits); - do_add (arg1_bits, neg_arg2, dest); + value * neg_arg2 = additive_inverse (arg2); + do_add (arg1, neg_arg2, dest); - free_bits (neg_arg2); + free_val (neg_arg2); delete neg_arg2; } /* Performs complement operation on a bit. */ -value * -state::complement_a_bit (value *var) +value_bit * +state::complement_a_bit (value_bit *var) { - value *result = nullptr; + value_bit *result = nullptr; bit* const_bit = dyn_cast (var); if (const_bit) result = complement_const_bit (const_bit); @@ -757,13 +750,13 @@ state::do_complement (tree arg, tree dest) and store it as a new state for given destination. */ for (size_t i = 0; i < get_var_size (dest); i++) { - value *result = complement_a_bit ((*var_states.get (arg))[i]); + value_bit *result = complement_a_bit ((*var_states.get (arg))[i]); delete (*var_states.get (dest))[i]; (*var_states.get (dest))[i] = result; } - print_bits (var_states.get (dest)); + print_value (var_states.get (dest)); return true; } @@ -771,34 +764,38 @@ state::do_complement (tree arg, tree dest) bool state::do_assign (tree arg, tree dest) { - declare_if_needed (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest)))); + bool dest_declared + = declare_if_needed (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest)))); declare_if_needed (arg, var_states.get (dest)->allocated ()); - vec * dest_bits = var_states.get (dest); + + value * dest_val = var_states.get (dest); /* If the argument is already defined, then we must just copy its bits. */ - if (auto bits = var_states.get (arg)) + if (auto arg_val = var_states.get (arg)) { - for (size_t i = 0; i < dest_bits->length (); i++) + for (size_t i = 0; i < dest_val->length (); i++) { - value *new_val = nullptr; - if (i < bits->length ()) - new_val = (*bits)[i]->copy (); + value_bit *new_val = nullptr; + if (i < arg_val->length ()) + new_val = (*arg_val)[i]->copy (); else new_val = new bit (0); - delete (*dest_bits)[i]; - (*dest_bits)[i] = new_val; + delete (*dest_val)[i]; + (*dest_val)[i] = new_val; } + if (dest_declared) + dest_val->is_unsigned = arg_val->is_unsigned; } /* If the argument is a constant, we must save it as sequence of bits. */ else if (TREE_CODE (arg) == INTEGER_CST) { - vec arg_bits - = create_bits_for_const (arg, dest_bits->length ()); - for (size_t i = 0; i < dest_bits->length (); i++) + value arg_val + = create_val_for_const (arg, dest_val->length ()); + for (size_t i = 0; i < dest_val->length (); i++) { - delete (*dest_bits)[i]; - (*dest_bits)[i] = arg_bits[i]; + delete (*dest_val)[i]; + (*dest_val)[i] = arg_val[i]; } } else @@ -810,7 +807,7 @@ state::do_assign (tree arg, tree dest) return false; } - print_bits (var_states.get (dest)); + print_value (var_states.get (dest)); return true; } @@ -820,9 +817,9 @@ state::do_assign (tree arg, tree dest) bool state::do_assign_pow2 (tree dest, unsigned pow) { - vec * dest_bits = var_states.get (dest); - unsigned dest_size = dest_bits ? dest_bits->allocated () - : tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest))); + value * dest_val = var_states.get (dest); + unsigned dest_size = dest_val ? dest_val->allocated () + : tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest))); if (pow > dest_size) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -831,20 +828,20 @@ state::do_assign_pow2 (tree dest, unsigned pow) return false; } - if (!dest_bits) + if (!dest_val) { decl_var (dest, tree_to_uhwi (TYPE_SIZE (TREE_TYPE (dest)))); - dest_bits = var_states.get (dest); + dest_val = var_states.get (dest); } else - free_bits (dest_bits); + free_val (dest_val); - for (unsigned i = 0; i < dest_bits->length (); i++) + for (unsigned i = 0; i < dest_val->length (); i++) { if (i == pow) - (*dest_bits)[i] = new bit (1); + (*dest_val)[i] = new bit (1); else - (*dest_bits)[i] = new bit (0); + (*dest_val)[i] = new bit (0); } return true; @@ -862,8 +859,8 @@ state::complement_const_bit (const bit * const_bit) /* Performs NOT operation for symbolic_bit. */ -value * -state::complement_sym_bit (const value * var) +value_bit * +state::complement_sym_bit (const value_bit * var) { return new bit_complement_expression (var->copy ()); } @@ -871,10 +868,10 @@ state::complement_sym_bit (const value * var) /* Performs XOR operation for 2 symbolic_bit operands. */ -value * -state::xor_sym_bits (const value * var1, const value * var2) +value_bit * +state::xor_sym_bits (const value_bit * var1, const value_bit * var2) { - value * var2_copy = var2->copy (); + value_bit * var2_copy = var2->copy (); bit_expression * node2_with_const_child = nullptr; bit_expression * parent_of_node2_with_child = nullptr; get_parent_with_const_child (var2_copy, node2_with_const_child, @@ -882,7 +879,7 @@ state::xor_sym_bits (const value * var1, const value * var2) if (node2_with_const_child != nullptr) { - value *var1_copy = var1->copy (); + value_bit *var1_copy = var1->copy (); bit_expression * node1_with_const_child = nullptr; bit_expression * parent_of_node1_with_child = nullptr; get_parent_with_const_child (var1_copy, node1_with_const_child, @@ -892,82 +889,62 @@ state::xor_sym_bits (const value * var1, const value * var2) we can merge them together. */ if (node1_with_const_child != nullptr) { + value_bit *var1_reformed = nullptr; + value_bit *var2_reformed = nullptr; + /* If var1's const bit is in its left subtree. */ - value *var1_left = node1_with_const_child->get_left (); + value_bit *var1_left = node1_with_const_child->get_left (); if (var1_left != nullptr && is_a (var1_left)) { + var1_reformed = node1_with_const_child->get_right ()->copy (); + value_bit *var2_left = node2_with_const_child->get_left (); + /* If var2's const bit is in its left subtree. */ - value *var2_left = node2_with_const_child->get_left (); if (var2_left != nullptr && is_a (var2_left)) - { - bit *new_left = xor_const_bits (as_a (var1_left), - as_a (var2_left)); - - value* reformed_elem = node2_with_const_child->get_right () - ->copy (); - parent_of_node2_with_child->get_left () - == node2_with_const_child - ? parent_of_node2_with_child->set_left (reformed_elem) - : parent_of_node2_with_child->set_right (reformed_elem); - - delete var1_left; - node1_with_const_child->set_left (new_left); - } + var2_reformed = node2_with_const_child->get_right ()->copy (); else /* Var2's const bit is in its right subtree. */ - { - value *var2_right = node2_with_const_child->get_right (); - bit *new_left = xor_const_bits (as_a (var1_left), - as_a (var2_right)); - - value* reformed_elem = node2_with_const_child->get_left () - ->copy (); - parent_of_node2_with_child->get_left () - == node2_with_const_child - ? parent_of_node2_with_child->set_left (reformed_elem) - : parent_of_node2_with_child->set_right (reformed_elem); - - delete var1_left; - node1_with_const_child->set_left (new_left); - } + var2_reformed = node2_with_const_child->get_left ()->copy (); } else /* Var1's const bit is in its right subtree. */ { - value *var1_right = node1_with_const_child->get_right (); - value *var2_left = node2_with_const_child->get_left (); + var1_reformed = node1_with_const_child->get_left ()->copy (); + value_bit *var2_left = node2_with_const_child->get_left (); + /* If var2's const bit is in its left subtree. */ if (var2_left != nullptr && is_a (var2_left)) - { - bit *new_right = xor_const_bits (as_a (var1_left), - as_a (var2_left)); - - value* reformed_elem = node2_with_const_child->get_right () - ->copy (); - parent_of_node2_with_child->get_left () - == node2_with_const_child - ? parent_of_node2_with_child->set_left (reformed_elem) - : parent_of_node2_with_child->set_right (reformed_elem); - - delete var1_right; - node1_with_const_child->set_right (new_right); - } + var2_reformed = node2_with_const_child->get_right ()->copy (); else /* Var2's const bit is in its right subtree. */ - { - value *var2_right = node2_with_const_child->get_right (); - bit *new_right = xor_const_bits (as_a (var1_right), - as_a (var2_right)); - - value* reformed_elem = node2_with_const_child->get_left () - ->copy (); - parent_of_node2_with_child->get_left () - == node2_with_const_child - ? parent_of_node2_with_child->set_left (reformed_elem) - : parent_of_node2_with_child->set_right (reformed_elem); - - delete var1_right; - node1_with_const_child->set_right (new_right); - } + var2_reformed = node2_with_const_child->get_left ()->copy (); } - delete node2_with_const_child; + + if (parent_of_node1_with_child) + { + parent_of_node1_with_child->get_left () + == node1_with_const_child + ? parent_of_node1_with_child->set_left (var1_reformed) + : parent_of_node1_with_child->set_right (var1_reformed); + delete node1_with_const_child; + } + else + { + delete var1_copy; + var1_copy = var1_reformed; + } + + if (parent_of_node2_with_child) + { + parent_of_node2_with_child->get_left () + == node2_with_const_child + ? parent_of_node2_with_child->set_left (var2_reformed) + : parent_of_node2_with_child->set_right (var2_reformed); + delete node2_with_const_child; + } + else + { + delete var2_copy; + var2_copy = var2_reformed; + } + return new bit_xor_expression (var1_copy, var2_copy); } delete var1_copy; @@ -989,10 +966,10 @@ state::xor_const_bits (const bit * const_bit1, const bit * const_bit2) /* Performs XOR operation for a symbolic_bit and const_bit operands. */ -value * -state::xor_var_const (const value * var, const bit * const_bit) +value_bit * +state::xor_var_const (const value_bit * var, const bit * const_bit) { - value *var_copy = var->copy (); + value_bit *var_copy = var->copy (); bit_expression *node_with_const_child = nullptr; bit_expression *tmp = nullptr; get_parent_with_const_child (var_copy, node_with_const_child, tmp); @@ -1001,7 +978,7 @@ state::xor_var_const (const value * var, const bit * const_bit) return var->copy (); else if (node_with_const_child != nullptr) { - value *left = node_with_const_child->get_left (); + value_bit *left = node_with_const_child->get_left (); if (left != nullptr && is_a (left)) { bit *new_left = xor_const_bits (as_a (left), const_bit); @@ -1010,7 +987,7 @@ state::xor_var_const (const value * var, const bit * const_bit) } else { - value *right = node_with_const_child->get_right (); + value_bit *right = node_with_const_child->get_right (); bit *new_right = xor_const_bits (as_a (right), const_bit); delete right; node_with_const_child->set_right (new_right); @@ -1027,7 +1004,7 @@ state::xor_var_const (const value * var, const bit * const_bit) on safe branching. */ void -state::get_parent_with_const_child (value* root, bit_expression*& parent, +state::get_parent_with_const_child (value_bit* root, bit_expression*& parent, bit_expression*& parent_of_parent) { parent_of_parent = nullptr; @@ -1050,8 +1027,8 @@ state::get_parent_with_const_child (value* root, bit_expression*& parent, bit_expression *cur_element = *nodes_to_consider.begin (); nodes_to_consider.remove (cur_element); - value *left = cur_element->get_left (); - value *right = cur_element->get_right (); + value_bit *left = cur_element->get_left (); + value_bit *right = cur_element->get_right (); if ((left != nullptr && is_a (left)) || (right != nullptr && is_a (right))) @@ -1060,14 +1037,14 @@ state::get_parent_with_const_child (value* root, bit_expression*& parent, parent_of_parent = *node_to_parent.get (cur_element); } - if (left != nullptr && is_safe_branching (left)) + if (left != nullptr && is_a (left)) { nodes_to_consider.add (as_a (left)); node_to_parent.put (as_a (left), cur_element); } - if (right != nullptr && is_safe_branching (right)) + if (right != nullptr && is_a (left)) { nodes_to_consider.add (as_a (right)); node_to_parent.put (as_a (right), cur_element); @@ -1076,67 +1053,54 @@ state::get_parent_with_const_child (value* root, bit_expression*& parent, } -/* Checks if node is AND, OR or XOR expression as they are comutative. */ +/* Shifts number left by size of shift_value. */ -bool -state::is_safe_branching (value* node) -{ - return is_a (node) || is_a (node) - || is_a (node); -} - - -/* Shifts number left by shift_value bits. */ - -vec * -state::shift_left_by_const (const vec * number, - size_t shift_value) +value * +state::shift_left_by_const (const value * number, size_t shift_value) { - vec *shift_result = new vec< value * > (); - shift_result->create (number->length ()); - + value * shift_result = new value (number->length (), number->is_unsigned); if (number->length () <= shift_value) for (size_t i = 0; i < number->length (); i++) - shift_result->quick_push (new bit (0)); + shift_result->push (new bit (0)); + else { size_t i = 0; for ( ; i < shift_value; ++i) - shift_result->quick_push (new bit (0)); + shift_result->push (new bit (0)); for (size_t j = 0; i < number->length (); ++i, j++) - shift_result->quick_push (((*number)[j])->copy ()); + shift_result->push (((*number)[j])->copy ()); } return shift_result; } -/* shift_right operation. Case: var2 is a sym_bit. */ +/* Shift_right operation. Case: var2 is a symbolic value. */ void -state::shift_right_sym_bits (vec * arg1_bits, vec * arg2_bits, - tree dest) +state::shift_right_sym_values (value * arg1, value * arg2, tree dest) { for (size_t i = 0; i < get_var_size (dest); i++) { - value *var1_elem = (*arg1_bits)[i]; - value *var2_elem = (*arg2_bits)[i]; - value *new_elem = new shift_right_expression (var1_elem->copy (), - var2_elem->copy ()); + value_bit *var1_bit = (*arg1)[i]; + value_bit *var2_bit = (*arg2)[i]; + value_bit *new_bit = new shift_right_expression (var1_bit->copy (), + var2_bit->copy ()); delete (*var_states.get (dest))[i]; - (*var_states.get (dest))[i] = new_elem; + (*var_states.get (dest))[i] = new_bit; } } -/* Adds two variables, stores the result in the first one. */ +/* Adds two values, stores the result in the first one. */ void -state::add_numbers (vec *var1, const vec *var2) +state::add_numbers (value *var1, const value *var2) { - value * carry = new bit (0); + value_bit * carry = new bit (0); for (unsigned i = 0; i < var1->length (); i++) { - value *temp = (*var1)[i]; + value_bit *temp = (*var1)[i]; (*var1)[i] = full_adder ((*var1)[i], (*var2)[i], carry); delete temp; } @@ -1147,11 +1111,11 @@ state::add_numbers (vec *var1, const vec *var2) /* ANDs every bit of the vector with var_bit, stroes the result in var1. */ void -state::and_number_bit (vec< value * > *var1, value *var_bit) +state::and_number_bit (value *var1, value_bit *var_bit) { for (unsigned i = 0; i < var1->length (); i++) { - value *tmp = (*var1)[i]; + value_bit *tmp = (*var1)[i]; (*var1)[i] = and_two_bits ((*var1)[i], var_bit); delete tmp; } @@ -1169,44 +1133,44 @@ state::do_mul (tree arg1, tree arg2, tree dest) void -state::do_mul (vec * arg1_bits, vec * arg2_bits, tree dest) +state::do_mul (value * arg1, value * arg2, tree dest) { - vec * dest_bits = var_states.get (dest); - vec * shifted = make_copy (arg1_bits); + value *shifted = new value (*arg1); + value *dest_val = var_states.get (dest); - for (unsigned i = 0; i < dest_bits->length (); i++) + for (unsigned i = 0; i < dest_val->length (); i++) { - delete (*dest_bits)[i]; - (*dest_bits)[i] = new bit (0); + delete (*dest_val)[i]; + (*dest_val)[i] = new bit (0); } - for (unsigned i = arg2_bits->length (); i != 0; --i) + for (unsigned i = arg2->length (); i != 0; --i) { - if (is_a ((*arg2_bits)[i - 1]) - && as_a ((*arg2_bits)[i - 1])->get_val () != 0) - add_numbers (dest_bits, shifted); - else if (is_a ((*arg2_bits)[i - 1])) + if (is_a ((*arg2)[i - 1]) + && as_a ((*arg2)[i - 1])->get_val () != 0) + add_numbers (dest_val, shifted); + else if (is_a ((*arg2)[i - 1])) { - and_number_bit (shifted, as_a ((*arg2_bits)[i - 1])); - add_numbers (dest_bits, shifted); + and_number_bit (shifted, as_a ((*arg2)[i - 1])); + add_numbers (dest_val, shifted); } - vec * temp = shifted; + + value * temp = shifted; shifted = shift_left_by_const (shifted, 1); - free_bits (temp); + free_val (temp); delete temp; } - free_bits (shifted); + free_val (shifted); delete shifted; } bool -state::check_const_bit_equality (vec * arg1_bits, - vec * arg2_bits) +state::check_const_value_equality (value * arg1, value * arg2) { - for (size_t i = 1; i < arg1_bits->length (); i++) - if (as_a((*arg1_bits)[i])->get_val () - != as_a((*arg2_bits)[i])->get_val ()) + for (size_t i = 1; i < arg1->length (); i++) + if (as_a((*arg1)[i])->get_val () + != as_a((*arg2)[i])->get_val ()) return false; return true; } @@ -1219,16 +1183,16 @@ state::add_equal_cond (tree arg1, tree arg2) } -/* Adds equality condition for two sequences of bits. */ +/* Adds equality condition for two values. */ void -state::add_equal_cond (vec * arg1_bits, vec * arg2_bits) +state::add_equal_cond (value * arg1, value * arg2) { /* If both arguments are constants then we can evaluate it. */ - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits)) + if (is_bit_vector (arg1) && is_bit_vector (arg2)) { - bool result = check_const_bit_equality (arg1_bits, arg2_bits); + bool result = check_const_value_equality (arg1, arg2); last_cond_status = result ? condition_status::CS_TRUE : condition_status::CS_FALSE; return; @@ -1236,26 +1200,26 @@ state::add_equal_cond (vec * arg1_bits, vec * arg2_bits) /* When some of bits are constants and they differ by value, then we can evalate it to be false. */ - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i]) - && as_a ((*arg1_bits)[i])->get_val () - != as_a ((*arg2_bits)[i])->get_val ()) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i]) + && as_a ((*arg1)[i])->get_val () + != as_a ((*arg2)[i])->get_val ()) { last_cond_status = condition_status::CS_FALSE; return; } } - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { /* If there is a constant bit pair, then they are equal as we checked not equality above. */ - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i])) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i])) continue; - conditions.add (new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + conditions.add (new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::EQUAL)); } last_cond_status = condition_status::CS_SYM; @@ -1263,12 +1227,11 @@ state::add_equal_cond (vec * arg1_bits, vec * arg2_bits) bool -state::check_const_bit_are_not_equal (vec * arg1_bits, - vec * arg2_bits) +state::check_const_value_are_not_equal (value * arg1, value * arg2) { - for (size_t i = 0; i < arg1_bits->length (); i++) - if (as_a((*arg1_bits)[i])->get_val () - != as_a((*arg2_bits)[i])->get_val ()) + for (size_t i = 0; i < arg1->length (); i++) + if (as_a((*arg1)[i])->get_val () + != as_a((*arg2)[i])->get_val ()) return true; return false; } @@ -1281,14 +1244,14 @@ state::add_not_equal_cond (tree arg1, tree arg2) } -/* Adds not equal condition for two sequences of bits. */ +/* Adds not equal condition for two values. */ void -state::add_not_equal_cond (vec * arg1_bits, vec * arg2_bits) +state::add_not_equal_cond (value * arg1, value * arg2) { - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits)) + if (is_bit_vector (arg1) && is_bit_vector (arg2)) { - bool result = check_const_bit_are_not_equal (arg1_bits, arg2_bits); + bool result = check_const_value_are_not_equal (arg1, arg2); last_cond_status = result ? condition_status::CS_TRUE : condition_status::CS_FALSE; return; @@ -1296,11 +1259,11 @@ state::add_not_equal_cond (vec * arg1_bits, vec * arg2_bits) /* When some of bits are constants and they differ by value, then we can evalate it to be true. */ - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i]) - && as_a ((*arg1_bits)[i])->get_val () - != as_a ((*arg2_bits)[i])->get_val ()) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i]) + && as_a ((*arg1)[i])->get_val () + != as_a ((*arg2)[i])->get_val ()) { last_cond_status = condition_status::CS_TRUE; return; @@ -1308,15 +1271,15 @@ state::add_not_equal_cond (vec * arg1_bits, vec * arg2_bits) } bit_expression * prev = nullptr; - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { /* If there is a constant bit pair, then they are equal as we checked not equality above. */ - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i])) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i])) continue; - bit_condition* new_cond = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + bit_condition* new_cond = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::NOT_EQUAL); if (prev) prev = new bit_or_expression (prev, new_cond); @@ -1330,16 +1293,15 @@ state::add_not_equal_cond (vec * arg1_bits, vec * arg2_bits) bool -state::check_const_bit_is_greater_than (vec * arg1_bits, - vec * arg2_bits) +state::check_const_value_is_greater_than (value * arg1, value * arg2) { - for (int i = arg1_bits->length () - 1; i >= 0; i--) + for (int i = arg1->length () - 1; i >= 0; i--) { - if (as_a((*arg1_bits)[i])->get_val () - > as_a((*arg2_bits)[i])->get_val ()) + if (as_a((*arg1)[i])->get_val () + > as_a((*arg2)[i])->get_val ()) return true; - else if (as_a((*arg1_bits)[i])->get_val () - < as_a((*arg2_bits)[i])->get_val ()) + else if (as_a((*arg1)[i])->get_val () + < as_a((*arg2)[i])->get_val ()) return false; } return false; @@ -1353,30 +1315,29 @@ state::add_greater_than_cond (tree arg1, tree arg2) } -/* Adds greater than condition for two sequences of bits. */ +/* Adds greater than condition for two values. */ void -state::add_greater_than_cond (vec * arg1_bits, - vec * arg2_bits) +state::add_greater_than_cond (value * arg1, value * arg2) { - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits)) + if (is_bit_vector (arg1) && is_bit_vector (arg2)) { - bool result = check_const_bit_is_greater_than (arg1_bits, arg2_bits); + bool result = check_const_value_is_greater_than (arg1, arg2); last_cond_status = result ? condition_status::CS_TRUE : condition_status::CS_FALSE; return; } - if (is_bit_vector (arg2_bits) && is_a (arg1_bits->last ()) - && get_value (arg2_bits) == 0 /* && is_signed (arg1_bits). */) + if (is_bit_vector (arg2) && is_a (arg1->last ()) + && make_number (arg2) == 0 && !arg1->is_unsigned) { - if (as_a (arg1_bits->last ())->get_val () == 1) + if (as_a (arg1->last ())->get_val () == 1) last_cond_status = condition_status::CS_FALSE; else { - for (size_t i = 0; i < arg1_bits->length (); i++) - if (is_a ((*arg1_bits)[i]) - && as_a ((*arg1_bits)[i])->get_val ()) + for (size_t i = 0; i < arg1->length (); i++) + if (is_a ((*arg1)[i]) + && as_a ((*arg1)[i])->get_val ()) { last_cond_status = condition_status::CS_TRUE; return; @@ -1384,7 +1345,7 @@ state::add_greater_than_cond (vec * arg1_bits, } } - bit_expression * gt_cond = construct_great_than_cond (arg1_bits, arg2_bits); + bit_expression * gt_cond = construct_great_than_cond (arg1, arg2); if (gt_cond) { /* Otherwise its status is already set. */ @@ -1394,28 +1355,26 @@ state::add_greater_than_cond (vec * arg1_bits, } -/* Constructs expression trees of greater than condition - for given sequences of bits. */ +/* Constructs expression trees of greater than condition for given values. */ bit_expression* -state::construct_great_than_cond (vec * arg1_bits, - vec * arg2_bits) +state::construct_great_than_cond (value * arg1, value * arg2) { bit_expression* prev = nullptr; - int i = arg1_bits->length () - 1; + int i = arg1->length () - 1; for ( ; i >= 0; i--) { - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i])) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i])) { - if (as_a ((*arg1_bits)[i])->get_val () - > as_a ((*arg2_bits)[i])->get_val ()) + if (as_a ((*arg1)[i])->get_val () + > as_a ((*arg2)[i])->get_val ()) { if (!prev) last_cond_status = condition_status::CS_TRUE; return prev; } - else if (as_a ((*arg1_bits)[i])->get_val () - < as_a ((*arg2_bits)[i])->get_val ()) + else if (as_a ((*arg1)[i])->get_val () + < as_a ((*arg2)[i])->get_val ()) { if (prev) { @@ -1434,15 +1393,15 @@ state::construct_great_than_cond (vec * arg1_bits, else { bit_condition* gt_cond - = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::GREAT_THAN); bit_expression* expr = nullptr; if (i) { bit_condition* eq_cond - = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::EQUAL); expr = new bit_or_expression (gt_cond, eq_cond); } @@ -1461,16 +1420,15 @@ state::construct_great_than_cond (vec * arg1_bits, bool -state::check_const_bit_is_less_than (vec * arg1_bits, - vec * arg2_bits) +state::check_const_value_is_less_than (value * arg1, value * arg2) { - for (int i = arg1_bits->length () - 1; i >= 0; i--) + for (int i = arg1->length () - 1; i >= 0; i--) { - if (as_a((*arg1_bits)[i])->get_val () - < as_a((*arg2_bits)[i])->get_val ()) + if (as_a((*arg1)[i])->get_val () + < as_a((*arg2)[i])->get_val ()) return true; - else if (as_a((*arg1_bits)[i])->get_val () - > as_a((*arg2_bits)[i])->get_val ()) + else if (as_a((*arg1)[i])->get_val () + > as_a((*arg2)[i])->get_val ()) return false; } return false; @@ -1484,68 +1442,64 @@ state::add_less_than_cond (tree arg1, tree arg2) } -/* Adds less than condition for two sequences of bits. */ +/* Adds less than condition for two values. */ void -state::add_less_than_cond (vec * arg1_bits, vec * arg2_bits) +state::add_less_than_cond (value * arg1, value * arg2) { - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits) - /* Fix this after adding signed numbers support. */ - && get_value (arg2_bits) != 0) + if (is_bit_vector (arg1) && is_bit_vector (arg2) + && (make_number (arg2) != 0 || arg1->is_unsigned)) { - bool result = check_const_bit_is_less_than (arg1_bits, arg2_bits); + bool result = check_const_value_is_less_than (arg1, arg2); last_cond_status = result ? condition_status::CS_TRUE : condition_status::CS_FALSE; return; } last_cond_status = condition_status::CS_SYM; - if (is_bit_vector (arg2_bits) && get_value (arg2_bits) == 0) + if (is_bit_vector (arg2) && make_number (arg2) == 0 && !arg1->is_unsigned) { - /* TODO: handle is_signed (arg1_bits) case properly. */ - if (is_a (arg1_bits->last ())) + if (is_a (arg1->last ())) { - if (as_a (arg1_bits->last ())->get_val () == 1) + if (as_a (arg1->last ())->get_val () == 1) last_cond_status = condition_status::CS_TRUE; else last_cond_status = condition_status::CS_FALSE; } else - conditions.add (new bit_condition (arg1_bits->last ()->copy (), + conditions.add (new bit_condition (arg1->last ()->copy (), new bit (1), condition_type::EQUAL)); return; } - bit_expression * lt_cond = construct_less_than_cond (arg1_bits, arg2_bits); + bit_expression * lt_cond = construct_less_than_cond (arg1, arg2); if (lt_cond) /* Otherwise its status is already set. */ conditions.add (lt_cond); } -/* Constructs expression trees of less than condition - for given sequences of bits. */ +/* Constructs expression trees of less than condition for given values. */ bit_expression* -state::construct_less_than_cond (vec * arg1_bits, - vec * arg2_bits) +state::construct_less_than_cond (value * arg1, value * arg2) { bit_expression* prev = nullptr; - int i = arg1_bits->length () - 1; + int i = arg1->length () - 1; for ( ; i >= 0; i--) { - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i])) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i])) { - if (as_a ((*arg1_bits)[i])->get_val () - < as_a ((*arg2_bits)[i])->get_val ()) + if (as_a ((*arg1)[i])->get_val () + < as_a ((*arg2)[i])->get_val ()) { if (!prev) last_cond_status = condition_status::CS_TRUE; return prev; } - else if (as_a ((*arg1_bits)[i])->get_val () - > as_a ((*arg2_bits)[i])->get_val ()) + else if (as_a ((*arg1)[i])->get_val () + > as_a ((*arg2)[i])->get_val ()) { if (prev) { @@ -1564,15 +1518,15 @@ state::construct_less_than_cond (vec * arg1_bits, else { bit_condition* lt_cond - = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::LESS_THAN); bit_expression* expr = nullptr; if (i) { bit_condition* eq_cond - = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::EQUAL); expr = new bit_or_expression (lt_cond, eq_cond); } @@ -1597,19 +1551,17 @@ state::add_greater_or_equal_cond (tree arg1, tree arg2) } -/* Adds greater or equal condition for two sequences of bits. */ +/* Adds greater or equal condition for two values. */ void -state::add_greater_or_equal_cond (vec * arg1_bits, - vec * arg2_bits) +state::add_greater_or_equal_cond (value* arg1, value* arg2) { - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits) - /* Fix this after adding signed numbers support. */ - && get_value (arg2_bits) == 0) + if (is_bit_vector (arg1) && is_bit_vector (arg2) + && (make_number (arg2) != 0 || arg1->is_unsigned)) { - bool is_greater_than = check_const_bit_is_greater_than (arg1_bits, - arg2_bits); - bool is_equal = check_const_bit_equality (arg1_bits, arg2_bits); + bool is_greater_than = check_const_value_is_greater_than (arg1, + arg2); + bool is_equal = check_const_value_equality (arg1, arg2); last_cond_status = (is_greater_than | is_equal) ? condition_status::CS_TRUE : condition_status::CS_FALSE; @@ -1617,28 +1569,27 @@ state::add_greater_or_equal_cond (vec * arg1_bits, } last_cond_status = condition_status::CS_SYM; - if (is_bit_vector (arg2_bits) && get_value (arg2_bits) == 0) + if (is_bit_vector (arg2) && make_number (arg2) == 0 && !arg1->is_unsigned) { - /* TODO: handle is_signed (arg1_bits) case properly. */ - if (is_a (arg1_bits->last ())) + if (is_a (arg1->last ())) { - if (as_a (arg1_bits->last ())->get_val () == 1) + if (as_a (arg1->last ())->get_val () == 1) last_cond_status = condition_status::CS_FALSE; else last_cond_status = condition_status::CS_TRUE; } else - conditions.add (new bit_condition (arg1_bits->last ()->copy (), + conditions.add (new bit_condition (arg1->last ()->copy (), new bit (0), condition_type::EQUAL)); return; } - bit_expression * eq_cond = construct_equal_cond (arg1_bits, arg2_bits); + bit_expression * eq_cond = construct_equal_cond (arg1, arg2); if (!eq_cond) return; - bit_expression * gt_cond = construct_great_than_cond (arg1_bits, arg2_bits); + bit_expression * gt_cond = construct_great_than_cond (arg1, arg2); if (gt_cond) /* Otherwise its status is already set. */ conditions.add (new bit_or_expression (eq_cond, gt_cond)); @@ -1654,14 +1605,15 @@ state::add_less_or_equal_cond (tree arg1, tree arg2) } +/* Adds less or equal condition for two values. */ + void -state::add_less_or_equal_cond (vec * arg1_bits, - vec * arg2_bits) +state::add_less_or_equal_cond (value * arg1, value * arg2) { - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits)) + if (is_bit_vector (arg1) && is_bit_vector (arg2)) { - bool is_less_than = check_const_bit_is_less_than (arg1_bits, arg2_bits); - bool is_equal = check_const_bit_equality (arg1_bits, arg2_bits); + bool is_less_than = check_const_value_is_less_than (arg1, arg2); + bool is_equal = check_const_value_equality (arg1, arg2); last_cond_status = (is_less_than | is_equal) ? condition_status::CS_TRUE : condition_status::CS_FALSE; @@ -1669,11 +1621,11 @@ state::add_less_or_equal_cond (vec * arg1_bits, } last_cond_status = condition_status::CS_SYM; - bit_expression * eq_cond = construct_equal_cond (arg1_bits, arg2_bits); + bit_expression * eq_cond = construct_equal_cond (arg1, arg2); if (!eq_cond) return; - bit_expression * lt_cond = construct_less_than_cond (arg1_bits, arg2_bits); + bit_expression * lt_cond = construct_less_than_cond (arg1, arg2); if (lt_cond) /* Otherwise its status is already set. */ conditions.add (new bit_or_expression (eq_cond, lt_cond)); @@ -1692,7 +1644,7 @@ state::add_bool_cond (tree arg) return false; } - vec * arg_bits = var_states.get (arg); + value* arg_bits = var_states.get (arg); for (size_t i = 0; i < arg_bits->length (); i++) if (is_a((*arg_bits)[i]) && as_a((*arg_bits)[i])->get_val () != 0) @@ -1732,8 +1684,7 @@ state::add_bool_cond (tree arg) /* Does preprocessing and postprocessing for condition adding. - Handles bit sequence creation for constant values - and their removement in the end. */ + Handles value creation for constants and their removement in the end. */ bool state::add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func) @@ -1756,43 +1707,42 @@ state::add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func) if (arg2_is_declared) declare_if_needed (arg1, var_states.get (arg2)->length ()); - vec * arg1_bits = var_states.get (arg1); - vec arg1_const_bits (vNULL); - if (arg1_bits == NULL && TREE_CODE (arg1) == INTEGER_CST) + value *arg1_val = var_states.get (arg1); + value arg1_const_val (MAX_VALUE_SIZE, false); + + if (arg1_val == NULL && TREE_CODE (arg1) == INTEGER_CST) { - arg1_const_bits = create_bits_for_const (arg1, + arg1_const_val = create_val_for_const (arg1, var_states.get (arg2)->length ()); - arg1_bits = &arg1_const_bits; + arg1_val = &arg1_const_val; } - vec * arg2_bits = var_states.get (arg2); - vec arg2_const_bits (vNULL); - if (arg2_bits == NULL && TREE_CODE (arg2) == INTEGER_CST) + value *arg2_val = var_states.get (arg2); + value arg2_const_val (MAX_VALUE_SIZE, false); + if (arg2_val == NULL && TREE_CODE (arg2) == INTEGER_CST) { - arg2_const_bits = create_bits_for_const (arg2, + arg2_const_val = create_val_for_const (arg2, var_states.get (arg1)->length ()); - arg2_bits = &arg2_const_bits; + arg2_val = &arg2_const_val; } - (this->*cond_func)(arg1_bits, arg2_bits); - free_bits (&arg1_const_bits); - free_bits (&arg2_const_bits); + (this->*cond_func)(arg1_val, arg2_val); + free_val (&arg1_const_val); + free_val (&arg2_const_val); print_conditions (); return true; } -/* Constructs expression trees of equal condition - for given sequences of bits. */ +/* Constructs expression trees of equal condition for given values. */ bit_expression* -state::construct_equal_cond (vec * arg1_bits, - vec * arg2_bits) +state::construct_equal_cond (value * arg1, value * arg2) { /* If both arguments are constants then we can evaluate it. */ - if (is_bit_vector (arg1_bits) && is_bit_vector (arg2_bits)) + if (is_bit_vector (arg1) && is_bit_vector (arg2)) { - bool result = check_const_bit_equality (arg1_bits, arg2_bits); + bool result = check_const_value_equality (arg1, arg2); last_cond_status = result ? condition_status::CS_TRUE : condition_status::CS_FALSE; return nullptr; @@ -1800,11 +1750,11 @@ state::construct_equal_cond (vec * arg1_bits, /* When some of bits are constants and they differ by value, then we can evalate it to be false. */ - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { - if (is_a ((*arg1_bits)[i]) && is_a ((*arg2_bits)[i]) - && as_a ((*arg1_bits)[i])->get_val () - != as_a ((*arg2_bits)[i])->get_val ()) + if (is_a ((*arg1)[i]) && is_a ((*arg2)[i]) + && as_a ((*arg1)[i])->get_val () + != as_a ((*arg2)[i])->get_val ()) { last_cond_status = condition_status::CS_FALSE; return nullptr; @@ -1812,10 +1762,10 @@ state::construct_equal_cond (vec * arg1_bits, } bit_expression* prev = nullptr; - for (size_t i = 0; i < arg1_bits->length (); i++) + for (size_t i = 0; i < arg1->length (); i++) { - bit_condition* eq_expr = new bit_condition ((*arg1_bits)[i]->copy (), - (*arg2_bits)[i]->copy (), + bit_condition* eq_expr = new bit_condition ((*arg1)[i]->copy (), + (*arg2)[i]->copy (), condition_type::EQUAL); if (prev) prev = new bit_and_expression (eq_expr, prev); @@ -1849,7 +1799,7 @@ state::do_mem_ref (tree arg1, tree dest) (*var_states.get (dest))[i] = new symbolic_bit (i, arg1); } - print_bits (var_states.get (dest)); + print_value (var_states.get (dest)); return true; } @@ -1874,10 +1824,101 @@ state::do_pointer_diff (tree arg1, tree arg2, tree dest) } -vec * -state::make_copy (vec *bits) + +value::value (unsigned size, bool is_unsigned) : is_unsigned (is_unsigned) +{ + number.create (size); +} + + +value::value (const value &other) +{ + this->is_unsigned = other.is_unsigned; + number.create (other.length ()); + for (size_t i = 0; i < other.length (); ++i) + { + value_bit *temp = other[i] ? other[i]->copy () : other[i]; + number.quick_push (temp); + } +} + + +size_t +value::length () const +{ + return number.length (); +} + + +value_bit*& +value::operator[] (unsigned i) +{ + return number[i]; +} + + +value& +value::operator= (const value &other) +{ + unsigned smallest = number.allocated () < other.length () + ? number.allocated () : other.length (); + + for (size_t i = 0; i < smallest; i++) + if (i < number.length ()) + { + delete number[i]; + number[i] = other[i]->copy (); + } + else + number.quick_push (other[i]->copy ()); + + for (size_t i = smallest; i < number.allocated (); i++) + if (i < number.length ()) + { + delete number[i]; + number[i] = other.is_unsigned ? new bit (0) + : other[other.length () - 1]->copy (); + } + else + number.quick_push (other.is_unsigned + ? new bit (0) : other[other.length () - 1]->copy ()); + + return (*this); +} + + +value_bit* +value::operator[] (unsigned i) const +{ + return number[i]; +} + + +bool +value::exists () const { - vec * copied_bits = new vec (); + return number.exists (); +} + + +unsigned +value::allocated () const +{ + return number.allocated (); +} + + +value_bit*& +value::last () +{ + return number.last (); +} + + +vec * +state::make_copy (vec *bits) +{ + vec * copied_bits = new vec (); copied_bits->create (bits->length ()); for (size_t i = 0; i < bits->length (); i++) copied_bits->quick_push ((*bits)[i]->copy ()); @@ -1895,18 +1936,18 @@ state::get_last_cond_status () } -/* Prints given bits as expressions. */ +/* Prints the given value. */ void -state::print_bits (vec * bits) +state::print_value (value * var) { if (!dump_file || !(dump_flags & TDF_DETAILS)) return; fprintf (dump_file, "{"); - for (int i = bits->length () - 1; i >= 0; i--) + for (int i = var->length () - 1; i >= 0; i--) { - (*bits)[i]->print (); + (*var)[i]->print (); if (i) fprintf (dump_file, ", "); @@ -1915,7 +1956,6 @@ state::print_bits (vec * bits) } - size_t min (size_t a, size_t b, size_t c) { size_t min = (a < b ? a : b); @@ -1923,7 +1963,7 @@ size_t min (size_t a, size_t b, size_t c) } -/* Casts arg_bits to cast_size size, stores value in dest. */ +/* Casts arg to cast_size size, stores value in dest. */ bool state::do_cast (tree var, tree dest, size_t cast_size) @@ -1938,34 +1978,36 @@ state::do_cast (tree var, tree dest, size_t cast_size) return false; } - //TODO: add case for signed numbers - - vec *arg = var_states.get (var); - vec *dest_bits = var_states.get (dest); + value *arg = var_states.get (var); + value *dest_val = var_states.get (dest); - size_t arg_size = min (arg->length (), dest_bits->length (), cast_size); + size_t arg_size = min (arg->length (), dest_val->length (), cast_size); for (size_t i = 0; i < arg_size; i++) { - value *temp = (*dest_bits)[i]; - (*dest_bits)[i] = (*arg)[i]->copy (); + value_bit *temp = (*dest_val)[i]; + (*dest_val)[i] = (*arg)[i]->copy (); delete temp; } - value * sign_bit = arg->last (); - for (size_t i = arg_size; i < dest_bits->length (); i++) + value_bit *sign_bit = arg->is_unsigned + ? new bit (0) : arg->last ()->copy (); + for (size_t i = arg_size; i < dest_val->length (); i++) { - value *temp = (*dest_bits)[i]; - (*dest_bits)[i] = sign_bit->copy (); + value_bit *temp = (*dest_val)[i]; + (*dest_val)[i] = sign_bit->copy (); delete temp; } + delete sign_bit; return true; } + /* Create LFSR value for the reversed CRC. */ + void -state::create_reversed_lfsr (vec &lfsr, const vec &crc, - const vec &polynomial) +state::create_reversed_lfsr (value &lfsr, const value &crc, + const value &polynomial) { size_t size = crc.length (); @@ -1973,44 +2015,48 @@ state::create_reversed_lfsr (vec &lfsr, const vec &crc, for (size_t i = 0; i < size - 1; i++) { if (as_a (polynomial[i])->get_val ()) - lfsr.quick_push (state::xor_two_bits (crc[i + 1], crc[0])); + lfsr.push (state::xor_two_bits (crc[i + 1], crc[0])); else - lfsr.quick_push (crc[i+1]->copy ()); + lfsr.push (crc[i+1]->copy ()); } /* Determine value of MSB. */ if (as_a (polynomial[size-1])->get_val ()) - lfsr.quick_push (crc[0]->copy ()); + lfsr.push (crc[0]->copy ()); else - lfsr.quick_push (new bit (0)); + lfsr.push (new bit (0)); } + /* Create LFSR value for the forward CRC. */ + void -state::create_forward_lfsr (vec &lfsr, const vec &crc, - const vec &polynomial) +state::create_forward_lfsr (value& lfsr, const value &crc, + const value &polynomial) { size_t size = crc.length (); /* Determine value of LSB. */ if (as_a (polynomial[0])->get_val ()) - lfsr.quick_push (crc[size - 1]->copy ()); + lfsr.push (crc[size - 1]->copy ()); else - lfsr.quick_push (new bit (0)); + lfsr.push (new bit (0)); /* Determine values of remaining bits. */ for (size_t i = 1; i < size; i++) { if (as_a (polynomial[i])->get_val ()) - lfsr.quick_push (state::xor_two_bits (crc[i - 1], crc[size - 1])); + lfsr.push (state::xor_two_bits (crc[i - 1], crc[size - 1])); else - lfsr.quick_push (crc[i - 1]->copy ()); + lfsr.push (crc[i - 1]->copy ()); } } + /* Create LFSR value. */ -vec * -state::create_lfsr (tree crc, vec *polynomial, bool is_bit_forward) + +value * +state::create_lfsr (tree crc, value *polynomial, bool is_bit_forward) { /* Check size compatibility․ */ unsigned HOST_WIDE_INT size = polynomial->length (); @@ -2025,15 +2071,13 @@ state::create_lfsr (tree crc, vec *polynomial, bool is_bit_forward) } /* Create vector of symbolic bits for crc. */ - vec *crc_value = new vec (); - crc_value->create (size); + value * crc_value = new value (size, TYPE_UNSIGNED (TREE_TYPE (crc))); for (unsigned HOST_WIDE_INT i = 0; i < size; i++) - crc_value->quick_push (new symbolic_bit (i, crc)); + crc_value->push (new symbolic_bit (i, crc)); /* create LFSR vector. */ - vec *lfsr = new vec (); - lfsr->create (size); + value *lfsr = new value (size, TYPE_UNSIGNED (TREE_TYPE (crc))); /* Calculate values for LFSR. */ if (is_bit_forward) @@ -2042,7 +2086,7 @@ state::create_lfsr (tree crc, vec *polynomial, bool is_bit_forward) create_reversed_lfsr (*lfsr, *crc_value, *polynomial); /* crc_value is no more needed, delete. */ - free_bits (crc_value); + free_val (crc_value); delete crc_value; return lfsr; @@ -2074,3 +2118,10 @@ state::print_conditions () } fprintf (dump_file, "}\n"); } + + +value_bit ** +value::push (value_bit * elem) +{ + return number.quick_push (elem); +} \ No newline at end of file diff --git a/gcc/sym-exec/state.h b/gcc/sym-exec/state.h index 45766ec9b4a1..7f251463f9c5 100644 --- a/gcc/sym-exec/state.h +++ b/gcc/sym-exec/state.h @@ -6,21 +6,38 @@ #ifndef SYM_EXEC_STATE_H #define SYM_EXEC_STATE_H +#define MAX_VALUE_SIZE 64 + #include "expression-is-a-helper.h" +struct value { + vec number; + bool is_unsigned; + + value (unsigned size, bool is_unsigned); + value (const value &other); + value_bit ** push (value_bit * elem); + size_t length () const; + value_bit*& last (); + unsigned allocated () const; + bool exists () const; + value_bit* &operator[] (unsigned i); + value& operator= (const value &other); + value_bit* operator[] (unsigned i) const; +}; + /* Stores states of variables' values on bit-level. */ class state { - typedef void (state::*binary_func) (vec * arg1_bits, - vec * arg2_bits, tree dest); + typedef void (state::*binary_func) (value * arg1, value * arg2, tree dest); - typedef void (state::*binary_cond_func) (vec * arg1_bits, - vec * arg2_bits); + typedef void (state::*binary_cond_func) (value* arg1, value* arg2); private: - /* Here is stored values of bit of each variable. */ - hash_map> var_states; + + /* Here is stored values by bits of each variable. */ + hash_map var_states; /* Here is stored conditions of symbolic bits. */ hash_set conditions; @@ -28,185 +45,175 @@ class state { /* The result of last added condition. */ condition_status last_cond_status = condition_status::CS_NO_COND; - /* Creates bit sequence of given constant tree. */ - vec create_bits_for_const (tree var, size_t size); + /* Removes given value. */ + static void free_val (value * val); + + /* Creates value for given constant tree. */ + static value create_val_for_const (tree var, size_t size); /* Removes given sequence of bits. */ - static void free_bits (vec * bits); + static void free_bits (vec * bits); /* Checks if sizes of arguments and destination are compatible. */ bool check_args_compatibility (tree arg1, tree arg2, tree dest); - /* Adds equality condition for two sequences of bits. */ - void add_equal_cond (vec * arg1_bits, vec * arg2_bits); + /* Adds equality condition for two values. */ + void add_equal_cond (value * arg1, value * arg2); - /* Adds not equal condition for two sequences of bits. */ - void add_not_equal_cond (vec * arg1_bits, vec * arg2_bits); + /* Adds not equal condition for two values. */ + void add_not_equal_cond (value * arg1, value * arg2); - /* Adds greater than condition for two sequences of bits. */ - void add_greater_than_cond (vec * arg1_bits, vec * arg2_bits); + /* Adds greater than condition for two values. */ + void add_greater_than_cond (value * arg1, value * arg2); - /* Adds less than condition for two sequences of bits. */ - void add_less_than_cond (vec * arg1_bits, vec * arg2_bits); + /* Adds less than condition for two values. */ + void add_less_than_cond (value * arg1, value * arg2); - /* Adds greater or equal condition for two sequences of bits. */ - void add_greater_or_equal_cond (vec * arg1_bits, - vec * arg2_bits); + /* Adds greater or equal condition for two values. */ + void add_greater_or_equal_cond (value * arg1, value * arg2); - /* Adds less or equal condition for two sequences of bits. */ - void add_less_or_equal_cond (vec * arg1_bits, - vec * arg2_bits); + /* Adds less or equal condition for two values. */ + void add_less_or_equal_cond (value * arg1, value * arg2); /* Does preprocessing and postprocessing for condition adding. - Handles bit sequence creation for constant values - and their removement in the end. */ + Handles value creation for constants and their removement in the end. */ bool add_binary_cond (tree arg1, tree arg2, binary_cond_func cond_func); - /* Constructs expression trees of greater than condition - for given sequences of bits. */ - bit_expression* construct_great_than_cond (vec * arg1_bits, - vec * arg2_bits); + /* Constructs expression trees of greater than condition for given values. */ + bit_expression* construct_great_than_cond (value * arg1, value * arg2); - /* Constructs expression trees of less than condition - for given sequences of bits. */ - bit_expression* construct_less_than_cond (vec * arg1_bits, - vec * arg2_bits); + /* Constructs expression trees of less than condition for given values. */ + bit_expression* construct_less_than_cond (value * arg1, value * arg2); - /* Constructs expression trees of equal condition - for given sequences of bits. */ - bit_expression* construct_equal_cond (vec * arg1_bits, - vec * arg2_bits); + /* Constructs expression trees of equal condition for given values. */ + bit_expression* construct_equal_cond (value * arg1, value * arg2); /* Does preprocessing and postprocessing for expressions with tree operands. - Handles bit sequence creation for constant values - and their removement in the end. */ + Handles value creation for constant and their removement in the end. */ bool do_binary_operation (tree arg1, tree arg2, tree dest, binary_func bin_func); - void do_and (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_and (value * arg1, value * arg2, tree dest); - void do_or (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_or (value * arg1, value * arg2, tree dest); - void do_xor (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_xor (value * arg1, value * arg2, tree dest); - void do_shift_right (vec * arg1_bits, vec * arg2_bits, - tree dest); + void do_shift_right (value * arg1, value * arg2, tree dest); - void do_shift_left (vec * arg1_bits, vec * arg2_bits, - tree dest); + void do_shift_left (value * arg1, value * arg2, tree dest); - void do_add (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_add (value * arg1, value * arg2, tree dest); - void do_sub (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_sub (value * arg1, value * arg2, tree dest); - /* Casts arg_bits to cast_size size, stores value in dest. */ + /* Casts arg to cast_size size, stores value in dest. */ bool do_cast (tree arg, tree dest, size_t cast_size); - /* Performs AND operation on two bits. */ - static value *and_two_bits (value *arg1_bit, value* arg2_bit); + /* Performs AND operation on two values. */ + static value_bit *and_two_bits (value_bit *arg1, value_bit* arg2); - /* ANDs every bit of the vector with var_bit, stroes the result in var1. */ - void and_number_bit (vec *var1, value *var_bit); + /* ANDs every bit of the value with var_bit, stroes the result in var1. */ + void and_number_bit (value *var1, value_bit *var_bit); - void do_mul (vec * arg1_bits, vec * arg2_bits, tree dest); + void do_mul (value * arg1, value * arg2, tree dest); /* Performs AND operation for 2 symbolic_bit operands. */ - static value *and_sym_bits (const value * var1, const value * var2); + static value_bit *and_sym_bits (const value_bit * var1, + const value_bit * var2); /* Performs AND operation for a symbolic_bit and const_bit operands. */ - static value *and_var_const (const value * var1, const bit * const_bit); + static value_bit *and_var_const (const value_bit * var1, + const bit * const_bit); /* Performs AND operation for 2 constant bit operands. */ static bit *and_const_bits (const bit * const_bit1, const bit * const_bit2); /* Performs OR operation on two bits. */ - static value *or_two_bits (value *arg1_bit, value* arg2_bit); + static value_bit *or_two_bits (value_bit *arg1_bit, value_bit* arg2_bit); /* Performs OR operation for 2 symbolic_bit operands. */ - static value *or_sym_bits (const value * var1, const value * var2); + static value_bit *or_sym_bits (const value_bit * var1, + const value_bit * var2); /* Performs OR operation for a symbolic_bit and a constant bit operands. */ - static value *or_var_const (const value * var1, const bit * const_bit); + static value_bit *or_var_const (const value_bit * var1, + const bit * const_bit); /* Performs OR operation for 2 constant bit operands. */ static bit *or_const_bits (const bit * const_bit1, const bit * const_bit2); /* Performs complement operation on a bit. */ - static value * complement_a_bit (value *var); + static value_bit * complement_a_bit (value_bit *var); /* Performs NOT operation for constant bit. */ static bit *complement_const_bit (const bit * const_bit); /* Performs NOT operation for symbolic_bit. */ - static value *complement_sym_bit (const value * var); + static value_bit *complement_sym_bit (const value_bit * var); /* Performs XOR operation on two bits. */ - static value * xor_two_bits (value *var1, value* var2); + static value_bit * xor_two_bits (value_bit *var1, value_bit* var2); /* Performs XOR operation for 2 symbolic_bit operands. */ - static value *xor_sym_bits (const value * var1, const value * var2); + static value_bit *xor_sym_bits (const value_bit * var1, + const value_bit * var2); /* Performs XOR operation for 2 constant bit operands. */ static bit *xor_const_bits (const bit * const_bit1, const bit * const_bit2); /* Performs XOR operation for a symbolic_bit and const_bit operands. */ - static value *xor_var_const (const value * var, const bit * const_bit); + static value_bit *xor_var_const (const value_bit * var, + const bit * const_bit); - /* Shift_right operation. Case: var2 is a sym_bit. */ - void shift_right_sym_bits (vec * arg1_bits, vec * arg2_bits, - tree dest); + /* Shift_right operation. Case: var2 is a symbolic value. */ + void shift_right_sym_values (value * arg1, value * arg2, tree dest); - /* Shift_left operation. Case: var2 is a sym_bit. */ - void shift_left_sym_bits (vec * arg1_bits, vec * arg2_bits, - tree dest); + /* Shift_left operation. Case: var2 is a symbolic value. */ + void shift_left_sym_values (value * arg1, value * arg2, tree dest); - /* Shifts value_vector right by shift_value bits. */ - vec shift_right_by_const (const vec * value_vector, - size_t shift_value); + /* Shifts var right by size of shift_value. */ + value *shift_right_by_const (value * var, size_t shift_value); /* Return node which has a const bit child. Traversal is done based on safe branching. */ - static void get_parent_with_const_child (value* root, bit_expression*& parent, + static void get_parent_with_const_child (value_bit* root, + bit_expression*& parent, bit_expression*& parent_of_parent); - /* Checks if node is AND, OR or XOR expression. */ - static bool is_safe_branching (value* node); - /* Checks whether state for variable with specified name already exists or not. */ bool is_declared (tree var); - void declare_if_needed (tree var, size_t size); + bool declare_if_needed (tree var, size_t size); - /* Shifts value_vector left by shift_value bits. */ - vec *shift_left_by_const (const vec * number, - size_t shift_value); + /* Shifts number left by size of shift_value. */ + value *shift_left_by_const (const value * number, size_t shift_value); - /* Checks if all vector elements are const_bit_expressions. */ - bool is_bit_vector (const vec *bits); + /* Checks if all bits of the given value have constant bit type. */ + bool is_bit_vector (const value *var); /* Adds two bits and carry value. Resturn result and stores new carry bit in "carry". */ - value* full_adder (value* var1, value* var2, value*& carry); - - /* Returns the additive inverse of the number stored in number verctor. */ - vec * additive_inverse (const vec *number); + value_bit* full_adder (value_bit* var1, value_bit* var2, value_bit*& carry); - /* Adds two vectors, stores the result in the first one. */ - void add_numbers (vec *var1, const vec *var2); + /* Returns the additive inverse of the given number. */ + value * additive_inverse (const value *number); - static vec * make_copy (vec *bits); + /* Adds two values, stores the result in the first one. */ + void add_numbers (value *var1, const value *var2); + static vec * make_copy (vec *bits); /* Create LFSR value for the reversed CRC. */ static void - create_reversed_lfsr (vec &lfsr, const vec &crc, - const vec &polynomial); + create_reversed_lfsr (value &lfsr, const value &crc, + const value &polynomial); /* Create LFSR value for the forward CRC. */ static void - create_forward_lfsr (vec &lfsr, const vec &crc, - const vec &polynomial); + create_forward_lfsr (value &lfsr, const value &crc, + const value &polynomial); public: state (); @@ -218,7 +225,7 @@ class state { state (const state& s); - bool add_var_state (tree var, vec * state); + bool add_var_state (tree var, value * state); void clear_states (); @@ -228,10 +235,10 @@ class state { bool bulk_add_conditions (const hash_set& conds); - vec * get_bits (tree var); + value * get_value (tree var); /* Get the value of the tree, which is in the beginning of the var_states. */ - vec * get_first_value (); + value * get_first_value (); const hash_set& get_conditions (); @@ -242,14 +249,14 @@ class state { /* Returns size of the given variable. */ unsigned get_var_size (tree var); - /* Prints given bits as expressions. */ - static void print_bits (vec * bits); + /* Prints the given value. */ + static void print_value (value * var); /* Prints added conditions. */ void print_conditions (); - /* Returns the value of the number represented as a bit vector. */ - static unsigned HOST_WIDE_INT get_value (const vec *bit_vector); + /* Returns the number represented by the value. */ + static unsigned HOST_WIDE_INT make_number (const value *var); /* Does bit-level XOR operation for given variables. */ bool do_xor (tree arg1, tree arg2, tree dest); @@ -306,24 +313,19 @@ class state { bool add_bool_cond (tree arg); - static bool check_const_bit_equality (vec * arg1_bits, - vec * arg2_bits); + static bool check_const_value_equality (value * arg1, value * arg2); - static bool check_const_bit_are_not_equal (vec * arg1_bits, - vec * arg2_bits); + static bool check_const_value_are_not_equal (value * arg1, value * arg2); - static bool check_const_bit_is_greater_than (vec * arg1_bits, - vec * arg2_bits); + static bool check_const_value_is_greater_than (value * arg1, value * arg2); - static bool check_const_bit_is_less_than (vec * arg1_bits, - vec * arg2_bits); + static bool check_const_value_is_less_than (value * arg1, value * arg2); /* Returns status of last added condition. */ condition_status get_last_cond_status (); /* Create LFSR value. */ - static vec * create_lfsr (tree crc, vec *polynomial, - bool is_bit_forward); + static value * create_lfsr (tree crc, value *polynomial, bool is_bit_forward); }; #endif /* SYM_EXEC_STATE_H. */ diff --git a/gcc/symb-execute-all-paths.cc b/gcc/symb-execute-all-paths.cc index cb428bfb766d..524aab55d002 100644 --- a/gcc/symb-execute-all-paths.cc +++ b/gcc/symb-execute-all-paths.cc @@ -409,7 +409,7 @@ crc_symb_execution::keep_return_val_and_conditions (const greturn* ret) /* Get calculated return value. */ state * curr_state = states.last (); - vec * return_value = curr_state->get_bits (return_op); + value * return_value = curr_state->get_value (return_op); if (!return_value) { @@ -421,7 +421,7 @@ crc_symb_execution::keep_return_val_and_conditions (const greturn* ret) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Return value is "); - state::print_bits (return_value); + state::print_value (return_value); } state * final_state = new state; @@ -728,18 +728,19 @@ crc_symb_execution::execute_crc_loop (class loop *crc_loop, gphi *crc, /* Return true if all bits of the polynomial are constants (0 or 1). Otherwise return false. */ -bool polynomial_is_known (const vec &polynomial) +bool polynomial_is_known (const value * polynomial) { - for (size_t i = 0; i < polynomial.length (); i++) + for (size_t i = 0; i < polynomial->length (); i++) { - if (!is_a (polynomial[i])) + if (!is_a ((*polynomial)[i])) return false; } return true; } + /* Execute the loop, which is expected to calculate CRC, to extract polynomial, assigning real numbers to crc and data. */ -vec * +value * crc_symb_execution::extract_poly_and_create_lfsr (class loop *crc_loop, gphi *crc, gphi *data, bool is_shift_left) @@ -761,7 +762,7 @@ crc_symb_execution::extract_poly_and_create_lfsr (class loop *crc_loop, } /* Get the value (bit vector) of the tree (it may be the polynomial). */ - vec *polynomial = polynomial_state->get_bits (calculated_crc); + value * polynomial = polynomial_state->get_value (calculated_crc); if (!polynomial) { if (dump_file && (dump_flags & TDF_DETAILS)) @@ -776,11 +777,11 @@ crc_symb_execution::extract_poly_and_create_lfsr (class loop *crc_loop, then to get a real polynomial, it must be reflected and 1 bit added. */ fprintf (dump_file, "Polynomial's value is "); - state::print_bits (polynomial); + state::print_value (polynomial); } /* Check that polynomial's all bits are constants. */ - if (!polynomial_is_known (*polynomial)) + if (!polynomial_is_known (polynomial)) { if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -806,7 +807,7 @@ bool acceptable_diff (size_t index1, size_t index2) } /* Check whether the condition_exp and refernce_exp match. */ -bool may_be_xors_condition (value *reference_exp, value *condition_exp) +bool may_be_xors_condition (value_bit *reference_exp, value_bit *condition_exp) { if (is_a (reference_exp) && is_a (condition_exp)) @@ -847,13 +848,13 @@ bool may_be_xors_condition (value *reference_exp, value *condition_exp) /* Check whether there is a condition containing symb_exp and the value is 1. */ bool -crc_symb_execution::condition_is_true (value *symb_exp) +crc_symb_execution::condition_is_true (value_bit *symb_exp) { state *final_state = final_states.last (); for (auto iter = final_state->get_conditions ().begin (); iter != final_state->get_conditions ().end (); ++iter) { - value *cond_exp = (*iter)->get_left (); + value_bit *cond_exp = (*iter)->get_left (); if (may_be_xors_condition (symb_exp, cond_exp)) { //todo check is true @@ -867,13 +868,13 @@ crc_symb_execution::condition_is_true (value *symb_exp) /* Check whether there is a condition containing symb_exp and the value is 0. */ bool -crc_symb_execution::condition_is_false (value *symb_exp) +crc_symb_execution::condition_is_false (value_bit *symb_exp) { state *final_state = final_states.last (); for (auto iter = final_state->get_conditions ().begin (); iter != final_state->get_conditions ().end (); ++iter) { - value *cond_exp = (*iter)->get_left (); + value_bit *cond_exp = (*iter)->get_left (); if (may_be_xors_condition (symb_exp, cond_exp)) { //todo check is false @@ -887,7 +888,7 @@ crc_symb_execution::condition_is_false (value *symb_exp) /* Returns true if the symb_exp is a bit_xor_expression and const_bit equals 1. Otherwise, returns false. */ bool -is_one (value *const_bit) +is_one (value_bit *const_bit) { return is_a (const_bit) && (as_a (const_bit))->get_val () == 1; @@ -899,7 +900,7 @@ is_one (value *const_bit) Sometimes calculated crc value is returned after being shifted by 8's factor. */ bool -is_a_valid_symb (value *bit, size_t lfsr_bit_index) +is_a_valid_symb (value_bit *bit, size_t lfsr_bit_index) { if (!is_a (bit)) return false; @@ -913,7 +914,7 @@ is_a_valid_symb (value *bit, size_t lfsr_bit_index) and xor-ed values are valid symbolic bits. Otherwise, returns false. */ bool -is_a_valid_xor (value *bit, size_t index) +is_a_valid_xor (value_bit *bit, size_t index) { return is_a (bit) && is_a_valid_symb ((as_a (bit))->get_left (), @@ -926,11 +927,11 @@ is_a_valid_xor (value *bit, size_t index) /* Returns true if the bit is a valid bit_xor_expression with 1. Otherwise, returns false. */ bool -is_a_valid_xor_one (value *bit, size_t index) +is_a_valid_xor_one (value_bit *bit, size_t index) { if (is_a (bit)) { - value *symb_exp = nullptr; + value_bit *symb_exp = nullptr; bit_xor_expression *xor_exp = as_a (bit); if (is_one (xor_exp->get_right ())) symb_exp = xor_exp->get_left (); @@ -946,8 +947,8 @@ is_a_valid_xor_one (value *bit, size_t index) } -bool crc_symb_execution::marginal_case_matches (value *crc, value *lfsr, - value *conditions_crc) +bool crc_symb_execution::marginal_case_matches (value_bit *crc, value_bit *lfsr, + value_bit *conditions_crc) { if (is_a (lfsr)) { @@ -992,8 +993,8 @@ bool crc_symb_execution::marginal_case_matches (value *crc, value *lfsr, 3. When data is xor-ed with crc only for the condition. xor is done on crc only. */ bool -crc_symb_execution::match_lfsr_case1 (const vec &lfsr, - const vec &crc_state, +crc_symb_execution::match_lfsr_case1 (const value * lfsr, + const value * crc_state, bool is_left_shift, symbolic_bit *symb_val, size_t i, size_t it_end) @@ -1004,7 +1005,7 @@ crc_symb_execution::match_lfsr_case1 (const vec &lfsr, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking 0 bit.\n"); - if (!marginal_case_matches (crc_state[0], lfsr[0], symb_val)) + if (!marginal_case_matches ((*crc_state)[0], (*lfsr)[0], symb_val)) return false; } else @@ -1012,8 +1013,8 @@ crc_symb_execution::match_lfsr_case1 (const vec &lfsr, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking %lu bit.\n", it_end); - if (!marginal_case_matches (crc_state[it_end], - lfsr[it_end], symb_val)) + if (!marginal_case_matches ((*crc_state)[it_end], + (*lfsr)[it_end], symb_val)) return false; } @@ -1022,22 +1023,22 @@ crc_symb_execution::match_lfsr_case1 (const vec &lfsr, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking %lu bit.\n", i); - if (is_a (lfsr[i])) + if (is_a ((*lfsr)[i])) { - size_t index = (as_a (lfsr[i]))->get_left () + size_t index = (as_a ((*lfsr)[i]))->get_left () ->get_index (); - if (!((is_a_valid_xor_one (crc_state[i], index) + if (!((is_a_valid_xor_one ((*crc_state)[i], index) && condition_is_true ( - as_a (crc_state[i])->get_left ())) - || (is_a_valid_symb (crc_state[i], index) - && condition_is_false (crc_state[i])))) + as_a ((*crc_state)[i])->get_left ())) + || (is_a_valid_symb ((*crc_state)[i], index) + && condition_is_false ((*crc_state)[i])))) return false; } - else if (is_a (lfsr[i])) + else if (is_a ((*lfsr)[i])) { - size_t index = (as_a (lfsr[i]))->get_index (); - if (!(is_a_valid_symb (crc_state[i], index) - && condition_is_false (crc_state[i]))) + size_t index = (as_a ((*lfsr)[i]))->get_index (); + if (!(is_a_valid_symb ((*crc_state)[i], index) + && condition_is_false ((*crc_state)[i]))) return false; } else @@ -1053,19 +1054,19 @@ crc_symb_execution::match_lfsr_case1 (const vec &lfsr, /* Returns true if the state matches the LFSR, otherwise - false. */ bool -crc_symb_execution::state_matches_lfsr_all_cases (const vec &lfsr, - const vec &crc_state, +crc_symb_execution::state_matches_lfsr_all_cases (const value * lfsr, + const value * crc_state, bool is_left_shift) { - size_t i = 0, it_end = lfsr.length () < crc_state.length () - ? lfsr.length () : crc_state.length (); + size_t i = 0, it_end = lfsr->length () < crc_state->length () + ? lfsr->length () : crc_state->length (); if (is_left_shift) { if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking 0 bit.\n"); i = 1; - if (!marginal_case_matches (crc_state[0], lfsr[0], crc_state[1])) + if (!marginal_case_matches ((*crc_state)[0], (*lfsr)[0], (*crc_state)[1])) return false; } else @@ -1074,8 +1075,8 @@ crc_symb_execution::state_matches_lfsr_all_cases (const vec &lfsr, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking %lu bit.\n", it_end); - if (!marginal_case_matches (crc_state[it_end], - lfsr[it_end], crc_state[it_end - 1])) + if (!marginal_case_matches ((*crc_state)[it_end], + (*lfsr)[it_end], (*crc_state)[it_end - 1])) return false; } @@ -1084,27 +1085,27 @@ crc_symb_execution::state_matches_lfsr_all_cases (const vec &lfsr, if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Checking %lu bit.\n", i); - if (is_a (lfsr[i])) + if (is_a ((*lfsr)[i])) { - size_t index = (as_a (lfsr[i]))->get_left () + size_t index = (as_a ((*lfsr)[i]))->get_left () ->get_index (); - if (!(((is_a_valid_xor_one (crc_state[i], index) - && condition_is_true (crc_state[i])) - || (is_a_valid_symb (crc_state[i], index) - && condition_is_false (crc_state[i]))) - || ((is_a_valid_xor_one (crc_state[i], index) - && condition_is_true (crc_state[i])) - || (is_a_valid_xor (crc_state[i], index) - && condition_is_false (crc_state[i]))))) + if (!(((is_a_valid_xor_one ((*crc_state)[i], index) + && condition_is_true ((*crc_state)[i])) + || (is_a_valid_symb ((*crc_state)[i], index) + && condition_is_false ((*crc_state)[i]))) + || ((is_a_valid_xor_one ((*crc_state)[i], index) + && condition_is_true ((*crc_state)[i])) + || (is_a_valid_xor ((*crc_state)[i], index) + && condition_is_false ((*crc_state)[i]))))) return false; } - else if (is_a (lfsr[i])) + else if (is_a ((*lfsr)[i])) { - size_t index = (as_a (lfsr[i]))->get_index (); + size_t index = (as_a ((*lfsr)[i]))->get_index (); // TODO: check the case when calculated crc is constant. - if (!((is_a_valid_symb (crc_state[i], index) - || is_a_valid_xor (crc_state[i], index)) - && condition_is_false (crc_state[i]))) + if (!((is_a_valid_symb ((*crc_state)[i], index) + || is_a_valid_xor ((*crc_state)[i], index)) + && condition_is_false ((*crc_state)[i]))) return false; } else @@ -1120,41 +1121,41 @@ crc_symb_execution::state_matches_lfsr_all_cases (const vec &lfsr, /* Returns true if the state matches the LFSR, otherwise - false. */ bool -crc_symb_execution::state_matches_lfsr (const vec &lfsr, - const vec &crc_state, +crc_symb_execution::state_matches_lfsr (const value * lfsr, + const value * crc_state, bool is_left_shift) { unsigned constant = 0; symbolic_bit *symb_bit = nullptr; - value *simple_xor_left = nullptr, *simple_xor_right = nullptr; + value_bit *simple_xor_left = nullptr, *simple_xor_right = nullptr; bit_xor_expression *xor_exp = nullptr, *complicated_xor = nullptr; bool has_const = false, has_other_val = false; - size_t it_beg = 0, it_end = lfsr.length () < crc_state.length () - ? lfsr.length () : crc_state.length (); + size_t it_beg = 0, it_end = lfsr->length () < crc_state->length () + ? lfsr->length () : crc_state->length (); if (is_left_shift) it_beg = 1; else --it_end; - for (unsigned j = it_beg; j < crc_state.length (); ++j) + for (unsigned j = it_beg; j < crc_state->length (); ++j) { - (crc_state[j])->print (); - switch (crc_state[j]->get_type ()) + ((*crc_state)[j])->print (); + switch ((*crc_state)[j]->get_type ()) { case SYMBOLIC_BIT: - symb_bit = as_a (crc_state[j]); + symb_bit = as_a ((*crc_state)[j]); break; case BIT: has_const = true; - constant = as_a (crc_state[j])->get_val (); + constant = as_a ((*crc_state)[j])->get_val (); break; case BIT_XOR_EXPRESSION: { /* Calculated CRC may contain crc[]^data[], or crc[]^1, or crc[]^data[]^1. */ xor_exp - = as_a (crc_state[j]); + = as_a ((*crc_state)[j]); if (is_a (xor_exp->get_left ())) simple_xor_left = xor_exp->get_left (); @@ -1187,7 +1188,7 @@ crc_symb_execution::state_matches_lfsr (const vec &lfsr, /* Returns true if all states match the LFSR, otherwise - false. */ bool -crc_symb_execution::states_match_lfsr (vec *lfsr, bool is_left_shift) +crc_symb_execution::states_match_lfsr (value *lfsr, bool is_left_shift) { while (!final_states.is_empty ()) { @@ -1195,10 +1196,10 @@ crc_symb_execution::states_match_lfsr (vec *lfsr, bool is_left_shift) if (dump_file && (dump_flags & TDF_DETAILS)) { fprintf (dump_file, "Matching LFSR and following returned state.\n"); - state::print_bits (final_state->get_first_value ()); + state::print_value (final_state->get_first_value ()); final_state->print_conditions (); } - if (!state_matches_lfsr (*lfsr, *(final_state->get_first_value ()), + if (!state_matches_lfsr (lfsr, final_state->get_first_value (), is_left_shift)) return false; final_states.pop (); diff --git a/gcc/symb-execute-all-paths.h b/gcc/symb-execute-all-paths.h index 71e42c002b65..2223ea24bdf3 100644 --- a/gcc/symb-execute-all-paths.h +++ b/gcc/symb-execute-all-paths.h @@ -95,20 +95,19 @@ class crc_symb_execution { bool execute_crc_loop (class loop *, gphi *, gphi *, bool); /* Returns true if the state matches the LFSR, otherwise - false. */ - bool state_matches_lfsr_all_cases (const vec &, const vec &, - bool); + bool state_matches_lfsr_all_cases (const value *, const value *, bool); /* Returns true if the state matches the LFSR, otherwise - false. */ - bool match_lfsr_case1 (const vec &, const vec &, + bool match_lfsr_case1 (const value *, const value *, bool, symbolic_bit *, size_t, size_t); - bool state_matches_lfsr (const vec &, const vec &, bool); + bool state_matches_lfsr (const value *, const value *, bool); - bool condition_is_true (value *); + bool condition_is_true (value_bit *); - bool condition_is_false (value *); + bool condition_is_false (value_bit *); - bool marginal_case_matches (value *, value *, value *); + bool marginal_case_matches (value_bit *, value_bit *, value_bit *); public: @@ -117,11 +116,10 @@ class crc_symb_execution { /* Returns calculated polynomial by executing the loop with concrete values. */ - vec *extract_poly_and_create_lfsr (class loop *, gphi *, - gphi *, bool); + value * extract_poly_and_create_lfsr (class loop *, gphi *, gphi *, bool); /* Returns true if all states match the LFSR, otherwise - false. */ - bool states_match_lfsr (vec *, bool); + bool states_match_lfsr (value *, bool); crc_symb_execution () { diff --git a/gcc/testsuite/gcc.dg/crc-1.c b/gcc/testsuite/gcc.dg/crc-1.c index 9027ecd3dfeb..d65763b2b2a8 100644 --- a/gcc/testsuite/gcc.dg/crc-1.c +++ b/gcc/testsuite/gcc.dg/crc-1.c @@ -53,4 +53,4 @@ uint16_t gen_crc16(const uint8_t *data, uint16_t size) { /* { dg-final { scan-tree-dump "Loop iteration number is 15" "crc"} } */ /* { dg-final { scan-tree-dump "Bit forward" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+(\(\[a-zA-Z\]\))?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-10.c b/gcc/testsuite/gcc.dg/crc-10.c index bfea6bdc1b88..29ee5686e42c 100644 --- a/gcc/testsuite/gcc.dg/crc-10.c +++ b/gcc/testsuite/gcc.dg/crc-10.c @@ -22,4 +22,4 @@ u8 crc8(u16 data) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit forward" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-2.c b/gcc/testsuite/gcc.dg/crc-2.c index 57bb9231392b..e1d342d09d1b 100644 --- a/gcc/testsuite/gcc.dg/crc-2.c +++ b/gcc/testsuite/gcc.dg/crc-2.c @@ -26,4 +26,4 @@ unsigned int crc16(unsigned int crcValue, unsigned char newByte) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit forward" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-23.c b/gcc/testsuite/gcc.dg/crc-23.c index 141fe0d328ec..a0d1d9c4c273 100644 --- a/gcc/testsuite/gcc.dg/crc-23.c +++ b/gcc/testsuite/gcc.dg/crc-23.c @@ -20,4 +20,4 @@ uint16_t crc16(uint16_t crc, uint8_t a, uint16_t polynom) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit reversed" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-3.c b/gcc/testsuite/gcc.dg/crc-3.c index fe0cbf808eb1..0186d36bb5da 100644 --- a/gcc/testsuite/gcc.dg/crc-3.c +++ b/gcc/testsuite/gcc.dg/crc-3.c @@ -31,4 +31,4 @@ unsigned short crc16(char *data_p, unsigned short length) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit reversed" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-4.c b/gcc/testsuite/gcc.dg/crc-4.c index 2bbc68e60c43..7cc18f77102d 100644 --- a/gcc/testsuite/gcc.dg/crc-4.c +++ b/gcc/testsuite/gcc.dg/crc-4.c @@ -20,4 +20,4 @@ uint16_t crc16_update(uint16_t crc, uint8_t a) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit reversed" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-5.c b/gcc/testsuite/gcc.dg/crc-5.c index d01669a210a9..257e70b51823 100644 --- a/gcc/testsuite/gcc.dg/crc-5.c +++ b/gcc/testsuite/gcc.dg/crc-5.c @@ -27,4 +27,4 @@ ee_u16 crcu8(ee_u8 data, ee_u16 crc) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit reversed" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ diff --git a/gcc/testsuite/gcc.dg/crc-6.c b/gcc/testsuite/gcc.dg/crc-6.c index ebeb373ee15e..9802ab35b02e 100644 --- a/gcc/testsuite/gcc.dg/crc-6.c +++ b/gcc/testsuite/gcc.dg/crc-6.c @@ -31,4 +31,4 @@ crcSlow(uint8_t const message[], int nBytes) { /* { dg-final { scan-tree-dump "Loop iteration number is 7" "crc"} } */ /* { dg-final { scan-tree-dump "Bit forward" "crc"} } */ /* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \\\^ \[a-zA-Z0-9_\]+\(\\\(\[a-zA-Z\]\\\)\)?;" "crc" } } */ -/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */ \ No newline at end of file +/* { dg-final { scan-tree-dump "Executing \[a-zA-Z_\]\[a-zA-Z0-9_\]* = \[a-zA-Z_\]\[a-zA-Z0-9_\]* \(<<|>>\) \[0-9]+;" "crc" } } */