Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
frama-c
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
pub
frama-c
Commits
1630079c
Commit
1630079c
authored
4 years ago
by
David Bühler
Browse files
Options
Downloads
Patches
Plain Diff
[Eva] Slightly better heuristic for automatic loop unroll on some conditions.
parent
c81253b8
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/plugins/value/partitioning/auto_loop_unroll.ml
+32
-20
32 additions, 20 deletions
src/plugins/value/partitioning/auto_loop_unroll.ml
tests/value/oracle/auto_loop_unroll.1.res.oracle
+4
-8
4 additions, 8 deletions
tests/value/oracle/auto_loop_unroll.1.res.oracle
with
36 additions
and
28 deletions
src/plugins/value/partitioning/auto_loop_unroll.ml
+
32
−
20
View file @
1630079c
...
@@ -51,6 +51,10 @@
...
@@ -51,6 +51,10 @@
open
Cil_types
open
Cil_types
let
is_true
=
function
|
`True
|
`TrueReduced
_
->
true
|
_
->
false
(* Is a statement a loop exit condition? If so, returns the condition and
(* Is a statement a loop exit condition? If so, returns the condition and
whether the condition must hold to exit the loop. Otherwise, returns None. *)
whether the condition must hold to exit the loop. Otherwise, returns None. *)
let
is_conditional_break
stmt
=
let
is_conditional_break
stmt
=
...
@@ -262,9 +266,23 @@ module Make (Abstract: Abstractions.Eva) = struct
...
@@ -262,9 +266,23 @@ module Make (Abstract: Abstractions.Eva) = struct
(* If the new value of [expr] is top, no reduction has been performed. *)
(* If the new value of [expr] is top, no reduction has been performed. *)
if
Val
.(
equal
top
value
)
then
None
else
Some
(
value
,
record
)
if
Val
.(
equal
top
value
)
then
None
else
Some
(
value
,
record
)
in
in
(* Different strategies whether cvalue is present. *)
(* Assumes that [condition] is [positive]. Returns an over-approximation
match
Val
.
get
Main_values
.
CVal
.
key
with
of the values for which [condition] is [positive]. *)
|
Some
get_cvalue
->
reduce
positive
>>=
fun
(
value
,
record
)
->
(* Evaluates [condition] with the hypothesis [expr] ∈ [value], to check
whether [expr] ∈ [value] ⇒ [condition] = [positive]. *)
let
valuation
=
Valuation
.
add
valuation
expr
record
in
fst
(
Eval
.
evaluate
~
valuation
~
reduction
:
false
state
condition
)
>>
fun
(
_valuation
,
v
)
->
let
satisfied
=
if
positive
then
not
Val
.(
is_included
zero
v
)
else
Val
.(
equal
zero
v
)
in
(* If the condition is satisfied, returns [value]. Otherwise, uses a
specific feature to cvalue (if possible) to compute a better value. *)
if
satisfied
then
Some
value
else
Val
.
get
Main_values
.
CVal
.
key
>>=
fun
get_cvalue
->
(* Assumes that [condition] is NOT [positive]. *)
(* Assumes that [condition] is NOT [positive]. *)
reduce
(
not
positive
)
>>=
fun
(
value
,
_record
)
->
reduce
(
not
positive
)
>>=
fun
(
value
,
_record
)
->
(* [value] is an over-approximation of the values of [expr] for which
(* [value] is an over-approximation of the values of [expr] for which
...
@@ -273,21 +291,6 @@ module Make (Abstract: Abstractions.Eva) = struct
...
@@ -273,21 +291,6 @@ module Make (Abstract: Abstractions.Eva) = struct
let
cvalue
=
get_cvalue
value
in
let
cvalue
=
get_cvalue
value
in
cvalue_complement
(
Cil
.
typeOf
expr
)
cvalue
>>=
fun
cvalue
->
cvalue_complement
(
Cil
.
typeOf
expr
)
cvalue
>>=
fun
cvalue
->
Some
(
Val
.
set
Main_values
.
CVal
.
key
cvalue
Val
.
top
)
Some
(
Val
.
set
Main_values
.
CVal
.
key
cvalue
Val
.
top
)
|
None
->
(* Assumes that [condition] is [positive]. Returns an over-approximation
of the values for which [condition] is [positive]. *)
reduce
positive
>>=
fun
(
value
,
record
)
->
(* Evaluates [condition] with the hypothesis [expr] ∈ [value], to check
whether [expr] ∈ [value] ⇒ [condition] = [positive]. *)
let
valuation
=
Valuation
.
add
valuation
expr
record
in
fst
(
Eval
.
evaluate
~
valuation
~
reduction
:
false
state
condition
)
>>
fun
(
_valuation
,
v
)
->
let
satisfied
=
if
positive
then
not
Val
.(
is_included
zero
v
)
else
Val
.(
equal
zero
v
)
in
if
satisfied
then
Some
value
else
None
(* Same as [reduce_to_expr] above, but builds the proper valuation from the
(* Same as [reduce_to_expr] above, but builds the proper valuation from the
[state]. [state] is the entry state of the loop, and [expr] is the only
[state]. [state] is the entry state of the loop, and [expr] is the only
...
@@ -431,9 +434,18 @@ module Make (Abstract: Abstractions.Eva) = struct
...
@@ -431,9 +434,18 @@ module Make (Abstract: Abstractions.Eva) = struct
in one iteration of the loop. *)
in one iteration of the loop. *)
compute_delta
lval
loop_block
>>=
fun
v_delta
->
compute_delta
lval
loop_block
>>=
fun
v_delta
->
let
typ
=
Cil
.
typeOfLval
lval
in
let
typ
=
Cil
.
typeOfLval
lval
in
let
limit
=
Val
.
inject_int
typ
(
Integer
.
of_int
limit
)
in
(* Checks whether [v_init] + [limit] × [v_delta] ⊂ [v_exit]. *)
let
binop
op
v1
v2
=
Bottom
.
non_bottom
(
Val
.
forward_binop
typ
op
v1
v2
)
in
let
binop
op
v1
v2
=
Bottom
.
non_bottom
(
Val
.
forward_binop
typ
op
v1
v2
)
in
(* Possible iterations numbers to exit the loop. *)
let
iter_nb
=
binop
Div
(
binop
MinusA
v_exit
v_init
)
v_delta
in
let
bound
=
Abstract_value
.
Int
(
Integer
.
of_int
limit
)
in
(* Use the iteration number if it is always smaller than the [limit].
Otherwise use [limit]. *)
let
limit
=
if
is_true
(
Val
.
assume_bounded
Alarms
.
Upper_bound
bound
iter_nb
)
then
iter_nb
else
Val
.
inject_int
typ
(
Integer
.
of_int
limit
)
in
(* Checks whether [v_init] + [limit] × [v_delta] ⊂ [v_exit]. *)
let
value
=
binop
PlusA
v_init
(
binop
Mult
limit
v_delta
)
in
let
value
=
binop
PlusA
v_init
(
binop
Mult
limit
v_delta
)
in
Some
(
Val
.
is_included
value
v_exit
)
Some
(
Val
.
is_included
value
v_exit
)
...
...
This diff is collapsed.
Click to expand it.
tests/value/oracle/auto_loop_unroll.1.res.oracle
+
4
−
8
View file @
1630079c
...
@@ -341,14 +341,10 @@
...
@@ -341,14 +341,10 @@
[eva] Done for function complex_loops
[eva] Done for function complex_loops
[eva] computing for function various_conditions <- main.
[eva] computing for function various_conditions <- main.
Called from tests/value/auto_loop_unroll.c:251.
Called from tests/value/auto_loop_unroll.c:251.
[eva] tests/value/auto_loop_unroll.c:192: starting to merge loop iterations
[eva:loop-unroll] tests/value/auto_loop_unroll.c:192: Automatic loop unrolling.
[eva:alarm] tests/value/auto_loop_unroll.c:193: Warning:
[eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: {11}
signed overflow. assert res + 1 ≤ 2147483647;
[eva:loop-unroll] tests/value/auto_loop_unroll.c:197: Automatic loop unrolling.
[eva] tests/value/auto_loop_unroll.c:195: Frama_C_show_each_11: [0..2147483647]
[eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: {12}
[eva] tests/value/auto_loop_unroll.c:197: starting to merge loop iterations
[eva:alarm] tests/value/auto_loop_unroll.c:198: Warning:
signed overflow. assert res + 1 ≤ 2147483647;
[eva] tests/value/auto_loop_unroll.c:200: Frama_C_show_each_12: [0..2147483647]
[eva] tests/value/auto_loop_unroll.c:203: starting to merge loop iterations
[eva] tests/value/auto_loop_unroll.c:203: starting to merge loop iterations
[eva:alarm] tests/value/auto_loop_unroll.c:204: Warning:
[eva:alarm] tests/value/auto_loop_unroll.c:204: Warning:
signed overflow. assert res + 1 ≤ 2147483647;
signed overflow. assert res + 1 ≤ 2147483647;
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment