-
Notifications
You must be signed in to change notification settings - Fork 274
Use sharing_mapt as container in value_sett #4463
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use sharing_mapt as container in value_sett #4463
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 442b500).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/106434546
Some stats for SV-COMP's ReachSafety-ECA (which barely uses pointers, i.e., the value set would mostly be near-empty):
So adding new values to the value set has become more expensive (which is not unexpected), but merging and cloning is a lot cheaper (as intended). @romainbrenguier @smowton would you be able to contribute some benchmarking on Java code, which makes a lot more use of value sets? |
src/pointer-analysis/value_set.h
Outdated
@@ -297,11 +295,7 @@ class value_sett | |||
/// | |||
/// The components of the ID are thus duplicated in the `valuest` key and in | |||
/// `entryt` fields. | |||
#ifdef USE_DSTRING |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we reaching the point of saying that USE_DSTRING
should always be on?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, we do still build with USE_DSTRING
disabled, but I don't think the regression tests even pass. Though this change might be a step towards making that more likely, as it makes the code more uniform.
Remove value_sett::idt [blocks: #4463]
442b500
to
441eb6c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: 441eb6c).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/106528011
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/pointer-analysis/value_set.cpp
Outdated
{ | ||
entryt replacement = *existing_entry; | ||
if(add_to_sets) | ||
make_union(replacement.object_map, new_values); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could check the return value of make_union()
and only do the replacement when the object map has changed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
if(add_to_sets) | ||
make_union(replacement.object_map, new_values); | ||
else | ||
replacement.object_map = new_values; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We could check whether new_values.read() != existing_entry->object_map.read()
before doing the replacement. Not sure about the impact on performance though. We might avoid breaking sharing in some cases but there'd be additional cost for the comparisons.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's a risk this is way too expensive and thus I'd rather not add this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's ok, we'd probably have to specifically benchmark this. My hunch is that the map comparisons could be cheap on average if it's likely that they differ in size or that we find a mismatch quickly.
src/goto-symex/symex_main.cpp
Outdated
@@ -676,14 +676,14 @@ void goto_symext::try_filter_value_sets( | |||
} | |||
if(jump_taken_value_set && !erase_from_jump_taken_value_set.empty()) | |||
{ | |||
value_sett::entryt *entry = jump_taken_value_set->get_entry_for_symbol( | |||
auto entry = jump_taken_value_set->get_index_of_symbol( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rename entry
to entry_name
or entry_index
🍌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/goto-symex/symex_main.cpp
Outdated
symbol_expr->get_identifier(), symbol_type, "", ns); | ||
jump_taken_value_set->erase_values_from_entry( | ||
*entry, erase_from_jump_taken_value_set); | ||
} | ||
if(jump_not_taken_value_set && !erase_from_jump_not_taken_value_set.empty()) | ||
{ | ||
value_sett::entryt *entry = jump_not_taken_value_set->get_entry_for_symbol( | ||
auto entry = jump_not_taken_value_set->get_index_of_symbol( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
src/pointer-analysis/value_set.cpp
Outdated
@@ -491,11 +472,11 @@ void value_sett::get_value_set_rec( | |||
} | |||
else if(expr.id()==ID_symbol) | |||
{ | |||
const entryt *entry = get_entry_for_symbol( | |||
auto entry = get_index_of_symbol( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍌
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
Evaluated this on one of our medium-sized Java applications (a particular WebGoat lesson) -- JBMC execution time down from ~30s to ~15s. |
goto-symex copies a state, which contains a value set, at each branching point. The paths originating at that branch point typically share most of the points-to information. Thus the copy is unnecessarily expensive, and so is the merge at the next join point, which will also result in one of the value sets to be destroyed. With sharing_mapt, the copy has constant cost, merging can make use of the delta view, and the cost of destruction only depends on the size of the delta.
441eb6c
to
d4b811b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✔️
Passed Diffblue compatibility checks (cbmc commit: d4b811b).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/106864446
goto-symex copies a state, which contains a value set, at each branching
point. The paths originating at that branch point typically share most
of the points-to information. Thus the copy is unnecessarily expensive,
and so is the merge at the next join point, which will also result in
one of the value sets to be destroyed. With sharing_mapt, the copy has
constant cost, merging can make use of the delta view, and the cost of
destruction only depends on the size of the delta.
Includes the cleanup-commit from #4462.
Performance evaluation to be done.