-
Notifications
You must be signed in to change notification settings - Fork 273
Split the rename function according to the level and pass expression by copy instead of reference #3996
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
Split the rename function according to the level and pass expression by copy instead of reference #3996
Conversation
src/goto-symex/goto_symex_state.cpp
Outdated
@@ -280,14 +280,12 @@ static void set_l2_indices( | |||
ssa_expr.set_level_2(level2.current_count(ssa_expr.get_identifier())); | |||
} | |||
|
|||
void goto_symex_statet::rename_level0(exprt &expr, const namespacet &ns) | |||
exprt goto_symex_statet::rename_level0(exprt expr, const namespacet &ns) |
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.
The parameter should be const exprt &expr
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.
In the follow up PR I will make this return another type, and then having the argument passed by copy allow to move the argument, potentially saving a copy. I also refactored the code so that this will not get called recursively.
src/goto-symex/goto_symex_state.cpp
Outdated
@@ -280,6 +280,46 @@ static void set_l2_indices( | |||
ssa_expr.set_level_2(level2.current_count(ssa_expr.get_identifier())); | |||
} | |||
|
|||
void goto_symex_statet::rename_level0(exprt &expr, const namespacet &ns) |
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 would expect that adding this function goes together with removing the same code from another function. As-is, it's difficult to assess whether this code does the same as the old one.
ea30965
to
4fe31a8
Compare
4fe31a8
to
eee9d61
Compare
db16730
to
d52823b
Compare
@tautschnig @smowton this is ready for review |
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: 3333db0).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/102350102
Isn't it possible to delete a specialization? I think you should be able to do template<> ssa_exprt rename<L2>(ssa_exprt, const namespacet &) = delete; and the compiler should then happily use |
The rename<L0> function will normally be used with ssa symbols, we add that function to avoid unecessary decision making.
The level argument is always known from the call site (except for rename recursive calls), and there are only 3 possible values, so it makes sense to have it as a template argument. This will be useful in particular, when we want the return type to depend on the level.
This can be useful when we now from the caller that the expression is already is in SSA form.
In places where rename<L1> is known to be called on an ssa_exprt, we replace the call by a call to rename_level1_ssa to avoid unecessary decision making and show more information in the return type.
This makes the interface clearer as there is no argument that is both an input and an output. This also corresponds to how the function was used in a lot of occurences, in which case the code is now simpler. In the cases where we actually want the transformation to happen in-place, we can use std::move.
template<> ssa_exprt rename<L2>(ssa_exprt, const namespacet &) = delete;
In that case I get the error: |
Hmm, too bad. Maybe we should just not use templates here at all? Just have functions |
The goal in having a template for the non SSA case was to avoid code duplication, because the version for three levels have a lot in common. |
Ok, that's probably the best approach. It makes functions that do the same (though slightly more performant for |
3333db0
to
44f1d42
Compare
@tautschnig @smowton I added a commit to merge the SSA function into one template |
44f1d42
to
a3fe467
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: a3fe467).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/102488874
src/goto-symex/goto_symex_state.cpp
Outdated
expr=ssa_exprt(expr); | ||
rename<level>(expr, ns); | ||
else | ||
expr = rename<level>(ssa_exprt(expr), ns); |
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.
Nit pick: you otherwise aim to use {...}
in constructor calls, so do ssa_exprt{expr}
here as well.
else if(level == L1) | ||
set_l1_indices(ssa, ns); | ||
else | ||
UNREACHABLE; |
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.
How about doing a full specialization here? It would do away with the static_assert
and all the branching (that really isn't one, because the compiler has to remove it anyway). But that's a nit-pick, up to you.
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.
This version avoids a bit a code duplication, so I would leave it like that. I think the static assert gives an error message that is clearer than getting a linker error.
src/goto-symex/goto_symex_state.cpp
Outdated
expr = rename<level>(ssa_exprt(expr), ns); | ||
else // No SSA version for level2 | ||
expr = rename<level>((exprt)ssa_exprt(expr), ns); |
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.
Is this still necessary, given they ssa vs. non-ssa functions have different names? It if is, use static_cast
, not (exprt)
.
ssa_exprt ssa = | ||
state.rename_level0_ssa(ssa_exprt(ns.lookup(*it).symbol_expr()), ns); | ||
ssa_exprt ssa = state.rename_ssa<goto_symex_statet::L0>( | ||
ssa_exprt(ns.lookup(*it).symbol_expr()), ns); |
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.
Use ssa_exprt{...}
Any idea about performance differences (if any)? |
We merge rename_level0_ssa and rename_level1_ssa in one template rename_ssa<level> since the code is similar and their usage would be similar.
a3fe467
to
7da918f
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: 7da918f).
Build URL: https://travis-ci.com/diffblue/test-gen/builds/102504151
I ran symex on 70 functions, the time before the changes was |
This is based on #3988 andThis is an intermediary step towards #3986We split the rename functions according to there level, so that we can later make them return types which reflects the transformation.