Skip to content

Expand the documentation for goto-inline #6136

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

Merged
merged 1 commit into from
Jun 15, 2021

Conversation

martin-cs
Copy link
Collaborator

Some comments I wrote while working out the interfaces to the inlining code and how it can be used.

@codecov
Copy link

codecov bot commented May 24, 2021

Codecov Report

Merging #6136 (2bd6f72) into develop (0002950) will increase coverage by 8.18%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop    #6136      +/-   ##
===========================================
+ Coverage    67.40%   75.59%   +8.18%     
===========================================
  Files         1157     1454     +297     
  Lines        95236   159745   +64509     
===========================================
+ Hits         64197   120757   +56560     
- Misses       31039    38988    +7949     
Flag Coverage Δ
cproversmt2 ?
regression ?
unit ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
src/util/string_container.cpp 52.94% <0.00%> (-47.06%) ⬇️
src/ansi-c/gcc_types.cpp 41.86% <0.00%> (-46.38%) ⬇️
src/solvers/prop/prop.cpp 42.85% <0.00%> (-41.76%) ⬇️
src/solvers/flattening/boolbv_member.cpp 53.65% <0.00%> (-38.65%) ⬇️
src/cpp/cpp_storage_spec.cpp 65.00% <0.00%> (-35.00%) ⬇️
src/util/cmdline.h 66.66% <0.00%> (-33.34%) ⬇️
src/solvers/strings/array_pool.h 66.66% <0.00%> (-33.34%) ⬇️
src/solvers/strings/string_refinement.h 66.66% <0.00%> (-33.34%) ⬇️
...rs/strings/string_concatenation_builtin_function.h 0.00% <0.00%> (-33.34%) ⬇️
src/ansi-c/c_typecheck_base.cpp 50.54% <0.00%> (-30.35%) ⬇️
... and 1433 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1ff5344...2bd6f72. Read the comment docs.

Copy link
Contributor

@TGWDB TGWDB left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good pending the fixes for the checks.

@martin-cs martin-cs force-pushed the fix/inline-documentation branch 2 times, most recently from e4209b3 to fdc3f54 Compare May 24, 2021 17:14
@martin-cs
Copy link
Collaborator Author

Only CI failure is the incremental diff which I don't think is a problem.

However I have run into a question -- should inlining be before or after return removal?

if(it->is_return())

checks for return instructions which implies that can be run before return removal. However not jumping to the end of the inlined function feels like a bug, likewise generating an OTHER instruction is a bit suspect. So I am not sure this code actually works correctly without return removal.

The code-base seems inconsistent on the matter, in some places inlining is before return removal:

goto_partial_inline(goto_model, log.get_message_handler());

but in others it is not:

goto_inline(goto_model, ui_message_handler, true);

goto_partial_inline(goto_model, ui_message_handler);

I would very much appreciate your thoughts on this.

@TGWDB
Copy link
Contributor

TGWDB commented May 25, 2021

I would very much appreciate your thoughts on this.

I'm adding some thoughts and observations here as invited. I am not sure I understand all of the subtleties enough to be considered an authority on this though (caveats end here).

I've also rearranged and cut parts of the original to make my thoughts clearer.

However I have run into a question -- should inlining be before or after return removal?

if(it->is_return())

checks for return instructions which implies that can be run before return removal. However not jumping to the end of the inlined function feels like a bug, likewise generating an OTHER instruction is a bit suspect. So I am not sure this code actually works correctly without return removal.

I agree this looks suspect and the creation of the new OTHER instructions does not inspire much confidence. I guess it would be nice to try and find an example that can demonstrate a bug (or in the process discover there is no bug/error).

The code-base seems inconsistent on the matter, in some places inlining is before return removal:

goto_partial_inline(goto_model, log.get_message_handler());

I don't recall exactly what happened before unifying the code path between different programs. I know some parts were changed (hence the bug on the instrument_preconditions locations). This might be an artefact from that unification rather than the "correct" approach. That said, returns are always removed after inlining even if they are (also) removed before inlining.

but in others it is not:

goto_inline(goto_model, ui_message_handler, true);

This one is under another condition and so (I guess) not always done before the "full inlining".

goto_partial_inline(goto_model, ui_message_handler);

This one does remove all the returns but is only doing partial inlining. Here this appears to be related to the escape-analysis flag rather than explicit inlining.

Regardless of the above, there is always a call to goto_model.goto_functions.update() (line 1609) that also does the removal of returns, so it appears to always happen regardless of whether an earlier pass may (also) do this.

@martin-cs
Copy link
Collaborator Author

martin-cs commented May 25, 2021 via email

@TGWDB
Copy link
Contributor

TGWDB commented May 26, 2021

All thoughts appreciated :-) There is a long-standing issue with there being undocumented assumptions made about which of the transformed / normal forms for goto-programs various transformations work on.

I guess we're finding the assumptions, or maybe the bugs that indicate the assumptions. :)

Inlining something like... inline int f00(int x) { int ret = 0; if (x == 0) { return ret; } ret = 1; return ret; } ... assert(f00(0) == 0); ... /before/ return removal should show if there is an issue with the inlining not processing returns correctly. What is harder is finding the set of options / paths that will trigger this problem in an externally visible way.

I was mostly hoping there was an easy way to find those flags/conditions.

I tried to be very careful to respect ordering when unifying the processing, so if it is possible now it should have been possible in at least one of the tools before.

It may be that these are subtle bugs that always existed and we're finding them now. I didn't see any mistakes in that re-arrangement (but was focusing on the locations at the time), and that bug was significantly more complex than simply merging the code paths alone would easily expose.

That said, returns are always removed after inlining even if they are (also) removed before inlining.
My concern is not about whether it happens, it is when it happens. I /think/ that inlining is buggy if it is done before return removal. If this is the case then it should really be documented and the places that it is done should be fixed OR we should fix goto-inline so it works with either.

Agree on all of the above.

Partial inlining uses the same code and thus should have the same issue (assuming that it is triggered).
Here this appears to be related to the escape-analysis flag rather than explicit inlining.
Yeah; this is what makes it hard to come up with a concrete bug.
Regardless of the above, there is always a call to goto_model.goto_functions.update() (line 1609) that also does the removal of returns, so it appears to always happen regardless of whether an earlier pass may (also) do this.
I don't think that does return removal:

Correct, my mistake. I was still thinking of locations and other goto_model updates.

@martin-cs
Copy link
Collaborator Author

martin-cs commented May 26, 2021 via email

@martin-cs martin-cs force-pushed the fix/inline-documentation branch from fdc3f54 to 65034b8 Compare June 14, 2021 18:48
@martin-cs
Copy link
Collaborator Author

( I haven't had time to dig into the ordering issues. I am inclined to merge this PR without comments about ordering and then have a go at sorting out the ordering of passes another time. )

@martin-cs martin-cs force-pushed the fix/inline-documentation branch from 65034b8 to 2bd6f72 Compare June 15, 2021 12:05
@martin-cs martin-cs merged commit f847fcd into diffblue:develop Jun 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants