diff options
author | matevos <matevosmehrabyan@gmail.com> | 2023-01-20 17:48:42 +0400 |
---|---|---|
committer | Jeff Law <jlaw@ventanamicro> | 2023-03-21 09:03:21 -0600 |
commit | a02983b70f2c980d18e63ce69601d491b75687a2 (patch) | |
tree | b11472f96a5474657760a8a568ac86547726557e | |
parent | a03a032ab877b5af72f3b6fb352c4a4d642fd2ec (diff) | |
download | gcc-a02983b70f2c980d18e63ce69601d491b75687a2.tar.gz |
sym-exec v14 - Added utilities for complementing bits of value which has specified origin
-rw-r--r-- | gcc/sym-exec/state.cc | 125 | ||||
-rw-r--r-- | gcc/sym-exec/state.h | 10 |
2 files changed, 135 insertions, 0 deletions
diff --git a/gcc/sym-exec/state.cc b/gcc/sym-exec/state.cc index ab92f5bc86f..95702af9c98 100644 --- a/gcc/sym-exec/state.cc +++ b/gcc/sym-exec/state.cc @@ -2104,4 +2104,129 @@ value::free_bits () delete number[i]; number[i] = nullptr; } +} + + +value_bit * +state::complement_bits_with_origin (value_bit *root, tree origin) +{ + /* Be careful. This function doesn't make a full copy of the bit. */ + if (!is_a<bit_expression *> (root)) + { + if (is_a<symbolic_bit *> (root) + && as_a<symbolic_bit *> (root)->get_origin () == origin) + root = new bit_complement_expression (root); + + return root; + } + + bit_expression *expr_root = as_a<bit_expression *> (root); + hash_set <value_bit *> nodes_to_consider; + nodes_to_consider.add (expr_root); + hash_map <value_bit *, value_bit *> node_to_parent; + node_to_parent.put (expr_root, nullptr); + + /* Traversing expression tree. */ + while (!nodes_to_consider.is_empty ()) + { + value_bit *cur_element = *nodes_to_consider.begin (); + nodes_to_consider.remove (cur_element); + + if (is_a<symbolic_bit *> (cur_element)) + { + if (as_a<symbolic_bit *> (cur_element)->get_origin () != origin) + continue; + + bit_expression *parent + = as_a<bit_expression *> (*node_to_parent.get (cur_element)); + if (is_a<bit_complement_expression *> (parent)) + { + value_bit *parent_of_parent = *node_to_parent.get (parent); + if (parent_of_parent) + { + bit_expression *parent_of_parent_expr + = as_a<bit_expression *> (parent_of_parent); + parent->set_right (nullptr); + delete parent; + parent_of_parent_expr->get_left () == parent + ? parent_of_parent_expr->set_left (cur_element) + : parent_of_parent_expr->set_right (cur_element); + } + else + { + /* Parent is our root. */ + as_a<bit_expression *> (root)->set_right (nullptr); + delete root; + root = cur_element; + } + } + else + { + value_bit* new_bit = new bit_complement_expression (cur_element); + parent->get_left () == cur_element ? parent->set_left (new_bit) + : parent->set_right (new_bit); + } + continue; + } + + bit_expression* cur_elem_expr = as_a<bit_expression *> (cur_element); + value_bit *left = cur_elem_expr->get_left (); + value_bit *right = cur_elem_expr->get_right (); + if (left != nullptr && !is_a<bit *> (left)) + { + nodes_to_consider.add (left); + node_to_parent.put (left, cur_element); + } + + if (right != nullptr && !is_a<bit *> (right)) + { + nodes_to_consider.add (right); + node_to_parent.put (right, cur_element); + } + } + + return root; +} + + +void +state::complement_val_bits_with_origin (value *val, tree origin) +{ + for (size_t i = 0; i < val->length (); i++) + { + (*val)[i] = complement_bits_with_origin ((*val)[i], origin); + } +} + + +void +state::complement_all_vars_bits_with_origin (tree origin) +{ + for (auto iter = var_states.begin (); iter != var_states.end (); ++iter) + { + complement_val_bits_with_origin (&(*iter).second, origin); + } +} + + +void +state::complement_conditions_with_origin (tree origin) +{ + hash_set<bit_expression *> updated_conditions; + for (auto iter = conditions.begin (); iter != conditions.end (); ++iter) + updated_conditions.add (as_a<bit_expression *> ( + complement_bits_with_origin (*iter, origin))); + + conditions.empty (); + for (auto iter = updated_conditions.begin (); + iter != updated_conditions.end (); ++iter) + conditions.add (*iter); +} + + +void +state::complement_state_with_origin (tree origin) +{ + complement_all_vars_bits_with_origin (origin); + complement_conditions_with_origin (origin); }
\ No newline at end of file diff --git a/gcc/sym-exec/state.h b/gcc/sym-exec/state.h index a7d289b91b7..1fe85f85805 100644 --- a/gcc/sym-exec/state.h +++ b/gcc/sym-exec/state.h @@ -337,6 +337,16 @@ class state { static bool check_const_value_is_less_than (value *arg1, value *arg2); + static value_bit *complement_bits_with_origin (value_bit *root, tree origin); + + static void complement_val_bits_with_origin (value *val, tree origin); + + void complement_all_vars_bits_with_origin (tree origin); + + void complement_conditions_with_origin (tree origin); + + void complement_state_with_origin (tree origin); + /* Returns status of last added condition. */ condition_status get_last_cond_status (); |