-
Notifications
You must be signed in to change notification settings - Fork 76
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
Loop Unrolling for the first exp.unrolling-factor
Iterations
#563
Conversation
Could you maybe also add tests for this feature? One should be able to observe a precision increase for some programs even without the modified array domain. |
exp.unrolling-factor
Iterations
…ues are handled automatically
…d continues are handled automatically" This reverts commit e37c29d.
I just started another sv-comp run with an unrolling of 5. If there are no abnormalities there, I think we can merge this. |
I would still be hesitant about that, regarding the unresolved points above. Not handling gotos like |
Also, this is a bit laughable considering Frama-C-SV used loop unrolling of 1024 according to their tool paper. |
A run with an unrolling of 5 reveals ~48 cases where Goblint now succeeds (including these An interesting class of programs for which we newly fail contain loops of the flavor: int main()
{
int current_execution_context;
unsigned short random;
do
{
random = __VERIFIER_nondet_ushort();
switch (random)
{
case 1:
current_execution_context = 1;
break;
default:
break;
}
} while (random);
} Without unrolling, everything works. With it Goblint fails with:
Any idea what's happening there @mikcp? |
The corresponding tables if anyone is interested: |
More natural example of the same issue int main(void) {
for (int i = 0; i < 2; ++i) {
switch (i) {
case 0:
break;
case 1:
}
}
return 0;
} |
I wouldn't be the least surprised if the crash was due to the lacking goto handling, because the invariants here come from CIL itself: analyzer/src/framework/cfgTools.ml Lines 195 to 209 in a0bb640
If the AST is additionally screwed with without maintaining those, things are bound to be wrong. |
I have now re-implemented it. They key idea now is: We still do the transformation before This comes at the price of putting each replicated body into a fake The resulting C code after the transformation is a bit ugly, but the unnecessary loops will hopefully not lead to widening as there is no back edge, and the OCaml code is cleaner than the approach originally taken for the thesis. |
Ok, I made one (hopefully last) rewrite. Now, it no longer inserts pointless loops but instead simply replaces top-level Also, I discovered that in order to benefit from switches in unrolled loops, one needs to do more with labels. We now replace all labels with fresh labels, remembering the old and the new statement. Then, once we are done copying and renaming labels, we path all gotos that are internal to the unrolling under consideration to refer to the new copy of the label. That way, all external gotos still go into the non-unrolled code, but gotos that are within one iteration of the loop stay so. |
CHANGES: Goblint "lean" release after a lot of cleanup. * Remove unmaintained analyses: OSEK, ARINC, shapes, containment, deadlocksByRaces (goblint/analyzer#460, goblint/analyzer#736, goblint/analyzer#812, goblint/analyzer#474). * Add interactive analysis (goblint/analyzer#391). * Add server mode (goblint/analyzer#522). * Add Compilation Database support (goblint/analyzer#406, goblint/analyzer#448). * Add floating point domain, unrolled array domain and improved struct domains (goblint/analyzer#734, goblint/analyzer#761, goblint/analyzer#577, goblint/analyzer#419). * Add static loop unrolling and heap variable unrolling (goblint/analyzer#563, goblint/analyzer#722). * Improve race detection with may-happen-in-parallel analysis (goblint/analyzer#529, goblint/analyzer#518, goblint/analyzer#595). * Reimplement lockset and deadlock analyses (goblint/analyzer#659, goblint/analyzer#662, goblint/analyzer#650, goblint/analyzer#655). * Add pthread extraction to Promela (goblint/analyzer#220). * Add location spans to output (goblint/analyzer#428, goblint/analyzer#449). * Improve race reporting (goblint/analyzer#550, goblint/analyzer#551). * Improve dead code reporting (goblint/analyzer#94, goblint/analyzer#353, goblint/analyzer#785). * Refactor warnings (goblint/analyzer#55, goblint/analyzer#783). * Add JSON schema for configuration (goblint/analyzer#476, goblint/analyzer#499). * Refactor option names (goblint/analyzer#28, goblint/analyzer#192, goblint/analyzer#516, goblint/analyzer#675). * Add bash completion (goblint/analyzer#669). * Add OCaml 4.13 and 4.14 support, remove OCaml 4.09 support (goblint/analyzer#503, goblint/analyzer#672).
CHANGES: Goblint "lean" release after a lot of cleanup. * Remove unmaintained analyses: OSEK, ARINC, shapes, containment, deadlocksByRaces (goblint/analyzer#460, goblint/analyzer#736, goblint/analyzer#812, goblint/analyzer#474). * Add interactive analysis (goblint/analyzer#391). * Add server mode (goblint/analyzer#522). * Add Compilation Database support (goblint/analyzer#406, goblint/analyzer#448). * Add floating point domain, unrolled array domain and improved struct domains (goblint/analyzer#734, goblint/analyzer#761, goblint/analyzer#577, goblint/analyzer#419). * Add static loop unrolling and heap variable unrolling (goblint/analyzer#563, goblint/analyzer#722). * Improve race detection with may-happen-in-parallel analysis (goblint/analyzer#529, goblint/analyzer#518, goblint/analyzer#595). * Reimplement lockset and deadlock analyses (goblint/analyzer#659, goblint/analyzer#662, goblint/analyzer#650, goblint/analyzer#655). * Add pthread extraction to Promela (goblint/analyzer#220). * Add location spans to output (goblint/analyzer#428, goblint/analyzer#449). * Improve race reporting (goblint/analyzer#550, goblint/analyzer#551). * Improve dead code reporting (goblint/analyzer#94, goblint/analyzer#353, goblint/analyzer#785). * Refactor warnings (goblint/analyzer#55, goblint/analyzer#783). * Add JSON schema for configuration (goblint/analyzer#476, goblint/analyzer#499). * Refactor option names (goblint/analyzer#28, goblint/analyzer#192, goblint/analyzer#516, goblint/analyzer#675). * Add bash completion (goblint/analyzer#669). * Add OCaml 4.13 and 4.14 support, remove OCaml 4.09 support (goblint/analyzer#503, goblint/analyzer#672).
Implementation of the loop unrolling functionality.
exp.unrolling-factor
is 0 by default, case in which the unrolling does not take place.exp.unrolling-factor
>0, all loops will be unrolled factor times.This is the first part of a precision optimization. Unrolling the loop's body k times outside the loop, will allow us to see those k iterations more precisely.