35 std::dynamic_pointer_cast<const data_dependency_contextt>(before);
46 std::set_intersection(
49 cast_before->data_deps.cbegin(),
50 cast_before->data_deps.cend(),
60 std::set_intersection(
63 cast_before->data_dominators.cbegin(),
64 cast_before->data_dominators.cend(),
69 intersection.size() == cast_before->data_dominators.size();
87 const bool first_write =
data_deps.empty();
93 new_dependencies = dependencies;
102 std::inserter(new_dependencies, new_dependencies.begin()),
107 if(new_dependencies.empty())
108 return shared_from_this();
111 std::dynamic_pointer_cast<data_dependency_contextt>(
mutable_clone());
113 for(
auto l : new_dependencies)
115 result->data_deps.insert(l);
122 for(
auto l : new_dependencies)
124 result->data_dominators.insert(l);
135 std::dynamic_pointer_cast<data_dependency_contextt>(
mutable_clone());
136 result->set_last_written_locations(locations);
137 result->set_data_deps(locations);
149 dependenciest dependencies(locations.begin(), locations.end());
162 std::set_intersection(
165 dependencies.cbegin(),
197 const std::stack<exprt> &stack,
198 const exprt &specifier,
200 bool merging_write)
const
202 auto updated_parent =
203 std::dynamic_pointer_cast<data_dependency_contextt>(
mutable_clone());
204 const auto cast_value =
205 std::dynamic_pointer_cast<const data_dependency_contextt>(value);
207 updated_parent->set_data_deps(cast_value->data_deps);
209 return updated_parent->write_location_contextt::write(
210 environment, ns, stack, specifier, value, merging_write);
228 std::dynamic_pointer_cast<const data_dependency_contextt>(other);
232 const auto merged_parent =
233 std::dynamic_pointer_cast<const data_dependency_contextt>(
236 return combine(cast_other, merged_parent);
246 std::dynamic_pointer_cast<const data_dependency_contextt>(other);
250 const auto meet_parent =
251 std::dynamic_pointer_cast<const data_dependency_contextt>(
254 return combine(cast_other, meet_parent);
264 const auto updated_parent =
265 std::dynamic_pointer_cast<const data_dependency_contextt>(
266 parent->insert_data_deps(other->data_deps));
268 const auto &result = std::dynamic_pointer_cast<data_dependency_contextt>(
269 updated_parent->mutable_clone());
275 result->data_dominators.clear();
276 std::set_intersection(
279 other->data_dominators.begin(),
280 other->data_dominators.end(),
281 std::inserter(result->data_dominators, result->data_dominators.end()),
287 bool value_change =
get_child() != result->get_child();
291 return shared_from_this();
312 std::dynamic_pointer_cast<const data_dependency_contextt>(other);
316 const auto merged_parent =
317 std::dynamic_pointer_cast<const data_dependency_contextt>(
320 return merged_parent->insert_data_deps(other_context->data_deps);
322 return shared_from_this();
330 std::set<goto_programt::const_targett, goto_programt::target_less_than>
333 std::set<goto_programt::const_targett, goto_programt::target_less_than>
345 std::set<goto_programt::const_targett, goto_programt::target_less_than>
348 std::set<goto_programt::const_targett, goto_programt::target_less_than>
362 out <<
"[Data dependencies: ";
367 out << (comma ?
", " :
"") << d->location_number;
372 out <<
"[Data dominators: ";
377 out << (comma ?
", " :
"") << d->location_number;
sharing_ptrt< class abstract_objectt > abstract_object_pointert
static combine_result merge(const abstract_object_pointert &op1, const abstract_object_pointert &op2, const locationt &merge_location, const widen_modet &widen_mode)
static combine_result meet(const abstract_object_pointert &op1, const abstract_object_pointert &op2)
Interface method for the meet operation.
This is the basic interface of the abstract interpreter with default implementations of the core func...
std::shared_ptr< context_abstract_objectt > context_abstract_object_ptrt
std::set< locationt, goto_programt::target_less_than > locationst
abstract_object_pointert get_child() const
std::set< goto_programt::const_targett, goto_programt::target_less_than > get_data_dominators() const
Return the set of data dominators associated with this node.
abstract_object_pointert merge(const abstract_object_pointert &other, const widen_modet &widen_mode) const override
Create a new abstract object that is the result of merging this abstract object with a given abstract...
internal_abstract_object_pointert mutable_clone() const override
dependenciest data_dominators
bool has_been_modified(const abstract_object_pointert &before) const override
Determine whether 'this' abstract_object has been modified in comparison to a previous 'before' state...
void output(std::ostream &out, const class ai_baset &ai, const namespacet &ns) const override
Output a representation of the value of this abstract object.
abstract_object_pointert insert_data_deps(const dependenciest &dependencies) const
Insert the given set of data dependencies into the data dependencies set for this data_dependency_con...
std::set< goto_programt::const_targett, goto_programt::target_less_than > get_data_dependencies() const
Return the set of data dependencies associated with this node.
abstract_object_pointert abstract_object_merge_internal(const abstract_object_pointert &other) const override
Helper function for abstract_objectt::abstract_object_merge to perform any additional actions after t...
std::shared_ptr< const data_dependency_contextt > data_dependency_context_ptrt
abstract_object_pointert write(abstract_environmentt &environment, const namespacet &ns, const std::stack< exprt > &stack, const exprt &specifier, const abstract_object_pointert &value, bool merging_write) const override
A helper function to evaluate writing to a component of an abstract object.
context_abstract_object_ptrt update_location_context_internal(const locationst &locations) const override
abstract_object_pointert combine(const data_dependency_context_ptrt &other, const data_dependency_context_ptrt &parent) const
void set_data_deps(const locationst &locations)
Set the given set of data dependencies for from the locations.
abstract_object_pointert meet(const abstract_object_pointert &other) const override
Base implementation of the meet operation: only used if no more precise abstraction can be used,...
std::set< goto_programt::const_targett, location_ordert > dependenciest
Base class for all expressions.
A namespacet is essentially one or two symbol tables bound together, to allow for symbol lookups in t...
abstract_object_pointert merge(const abstract_object_pointert &other, const widen_modet &widen_mode) const override
Create a new abstract object that is the result of merging this abstract object with a given abstract...
abstract_object_pointert abstract_object_merge_internal(const abstract_object_pointert &other) const override
Helper function for abstract_objectt::abstract_object_merge to perform any additional actions after t...
void output(std::ostream &out, const class ai_baset &ai, const namespacet &ns) const override
Output a representation of the value of this abstract object.
abstract_object_pointert meet(const abstract_object_pointert &other) const override
Base implementation of the meet operation: only used if no more precise abstraction can be used,...
bool has_been_modified(const abstract_object_pointert &before) const override
Determine whether 'this' abstract_object has been modified in comparison to a previous 'before' state...
Maintain data dependencies as a context in the variable sensitivity domain.
void intersection(const typename graph_nodet< E >::edgest &a, const typename graph_nodet< E >::edgest &b, typename graph_nodet< E >::edgest &dest)
Compute intersection of two edge sets, in linear time.