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
2cef6dcf
Commit
2cef6dcf
authored
3 years ago
by
Patrick Baudin
Browse files
Options
Downloads
Patches
Plain Diff
[Wp] improve Cint simplifier
parent
2ddb7e17
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/plugins/wp/Cint.ml
+50
-24
50 additions, 24 deletions
src/plugins/wp/Cint.ml
with
50 additions
and
24 deletions
src/plugins/wp/Cint.ml
+
50
−
24
View file @
2cef6dcf
...
@@ -1244,7 +1244,8 @@ let is_cint_simplifier =
...
@@ -1244,7 +1244,8 @@ let is_cint_simplifier =
method
infer
=
[]
method
infer
=
[]
end
end
(* Mask Simplifier *)
let
dkey
=
Wp_parameters
.
register_category
"mask-simplifier"
let
dkey
=
Wp_parameters
.
register_category
"mask-simplifier"
module
Masks
=
struct
module
Masks
=
struct
...
@@ -1263,6 +1264,14 @@ module Masks = struct
...
@@ -1263,6 +1264,14 @@ module Masks = struct
let
is_top
v
=
let
is_top
v
=
Integer
.
is_zero
v
.
unset
&&
Integer
.
is_zero
v
.
set
Integer
.
is_zero
v
.
unset
&&
Integer
.
is_zero
v
.
set
let
is_one_set
mask
v
=
if
is_bottom
v
then
false
else
not
(
Integer
.
is_zero
(
Integer
.
logand
mask
v
.
set
))
let
is_one_unset
mask
v
=
if
is_bottom
v
then
false
else
not
(
Integer
.
is_zero
(
Integer
.
logand
mask
v
.
unset
))
[
@@@
warning
"-32"
]
[
@@@
warning
"-32"
]
let
pretty
fmt
v
=
let
pretty
fmt
v
=
let
pretty_mask
fmt
m
=
let
pretty_mask
fmt
m
=
...
@@ -1283,22 +1292,25 @@ module Masks = struct
...
@@ -1283,22 +1292,25 @@ module Masks = struct
let
eval_not
eval
ctx
e
=
let
eval_not
eval
ctx
e
=
let
v
=
eval
ctx
e
in
let
v
=
eval
ctx
e
in
mk
~
set
:
v
.
unset
~
unset
:
v
.
set
if
is_bottom
v
then
v
else
mk
~
set
:
v
.
unset
~
unset
:
v
.
set
let
neutral_land
=
mk
~
set
:
(
Integer
.
minus_one
)
~
unset
:
Integer
.
zero
let
neutral_land
=
mk
~
set
:
(
Integer
.
minus_one
)
~
unset
:
Integer
.
zero
let
eval_land
eval
ctx
es
=
let
eval_land
eval
ctx
es
=
List
.
fold_left
(
fun
{
set
;
unset
}
x
->
List
.
fold_left
(
fun
{
set
;
unset
}
x
->
let
v
=
eval
ctx
x
in
let
v
=
eval
ctx
x
in
mk
~
set
:
(
Integer
.
logand
v
.
set
set
)
if
is_bottom
v
then
v
~
unset
:
(
Integer
.
logor
v
.
unset
unset
))
else
mk
~
set
:
(
Integer
.
logand
v
.
set
set
)
~
unset
:
(
Integer
.
logor
v
.
unset
unset
))
neutral_land
es
neutral_land
es
let
neutral_lor
=
mk
~
set
:
Integer
.
zero
~
unset
:
(
Integer
.
minus_one
)
let
neutral_lor
=
mk
~
set
:
Integer
.
zero
~
unset
:
(
Integer
.
minus_one
)
let
eval_lor
eval
ctx
es
=
let
eval_lor
eval
ctx
es
=
List
.
fold_left
(
fun
{
set
;
unset
}
x
->
List
.
fold_left
(
fun
{
set
;
unset
}
x
->
let
v
=
eval
ctx
x
in
let
v
=
eval
ctx
x
in
mk
~
set
:
(
Integer
.
logor
v
.
set
set
)
if
is_bottom
v
then
v
~
unset
:
(
Integer
.
logand
v
.
unset
unset
))
else
mk
~
set
:
(
Integer
.
logor
v
.
set
set
)
~
unset
:
(
Integer
.
logand
v
.
unset
unset
))
neutral_lor
es
neutral_lor
es
let
of_integer
set
=
mk
~
set
~
unset
:
(
Integer
.
lognot
set
)
let
of_integer
set
=
mk
~
set
~
unset
:
(
Integer
.
lognot
set
)
...
@@ -1359,14 +1371,28 @@ module MasksDomain = struct
...
@@ -1359,14 +1371,28 @@ module MasksDomain = struct
|
Fun
(
f
,
es
)
when
f
==
f_lor
->
Masks
.
eval_lor
get
ctx
es
|
Fun
(
f
,
es
)
when
f
==
f_lor
->
Masks
.
eval_lor
get
ctx
es
|
Fun
(
f
,
[
e
])
when
f
==
f_lnot
->
Masks
.
eval_not
get
ctx
e
|
Fun
(
f
,
[
e
])
when
f
==
f_lnot
->
Masks
.
eval_not
get
ctx
e
|
Fun
(
f
,
[
e
])
->
|
Fun
(
f
,
[
e
])
->
let
iota
=
to_cint
f
in
let
iota
=
to_cint
f
in
(* may raise Not_found *)
let
v
=
get
ctx
e
in
let
v
=
get
ctx
e
in
if
not
(
Ctypes
.
signed
iota
)
then
if
Masks
.
is_bottom
v
then
v
(* The uppest bits are unset *)
else
let
mask
=
snd
(
Ctypes
.
bounds
iota
)
in
let
min
,
max
=
Ctypes
.
bounds
iota
in
Masks
.
mk
~
set
:
(
Integer
.
logand
v
.
Masks
.
set
mask
)
if
not
(
Ctypes
.
signed
iota
)
then
~
unset
:
(
Integer
.
logor
v
.
Masks
.
unset
(
Integer
.
lognot
mask
))
(* the uppest bits are unset *)
else
v
Masks
.
mk
~
set
:
(
Integer
.
logand
v
.
Masks
.
set
max
)
~
unset
:
(
Integer
.
logor
v
.
Masks
.
unset
(
Integer
.
lognot
max
))
else
let
sign_bit_mask
=
Integer
.
succ
max
in
if
Masks
.
is_one_unset
sign_bit_mask
v
then
(* The sign bit is set to 0.
So, the uppest bits are unset *)
Masks
.
mk
~
set
:
(
Integer
.
logand
v
.
Masks
.
set
max
)
~
unset
:
(
Integer
.
logor
v
.
Masks
.
unset
min
)
else
if
Masks
.
is_one_set
sign_bit_mask
v
then
(* The sign bit is set to 1.
So, the uppest bits are set *)
Masks
.
mk
~
set
:
(
Integer
.
logor
v
.
Masks
.
set
min
)
~
unset
:
(
Integer
.
logand
v
.
Masks
.
unset
max
)
else
Masks
.
top
|
_
->
Masks
.
top
|
_
->
Masks
.
top
with
Not_found
->
Masks
.
top
with
Not_found
->
Masks
.
top
in
in
...
@@ -1470,7 +1496,6 @@ module MasksDomain = struct
...
@@ -1470,7 +1496,6 @@ module MasksDomain = struct
end
end
let
mask_simplifier
=
let
mask_simplifier
=
let
rewrite_cst
~
highest
ctx
e
=
(* [r = rewrite ctx e] such that [ctx |- e = r] *)
let
rewrite_cst
~
highest
ctx
e
=
(* [r = rewrite ctx e] such that [ctx |- e = r] *)
...
@@ -1480,17 +1505,18 @@ let mask_simplifier =
...
@@ -1480,17 +1505,18 @@ let mask_simplifier =
f
==
f_bit_positive
->
(* rewrites [bit_test(x,k)] *)
f
==
f_bit_positive
->
(* rewrites [bit_test(x,k)] *)
(
try
let
k
=
match_integer
k
in
(* may raise Not_found *)
(
try
let
k
=
match_integer
k
in
(* may raise Not_found *)
let
v
=
MasksDomain
.
eval
~
level
:
1
ctx
x
in
let
v
=
MasksDomain
.
eval
~
level
:
1
ctx
x
in
let
m
=
two_power_k
k
in
(* may raise Not_found *)
if
Masks
.
is_bottom
v
then
if
Masks
.
is_bottom
v
then
(* Does not rewrite [e] because the polarity is unknown *)
(* Does not rewrite [e] because the polarity is unknown *)
e
e
else
if
not
(
Integer
.
is_zero
(
Integer
.
logand
v
.
Masks
.
set
m
))
then
else
(* [ctx] gives that the bit [k] of [x] is set *)
let
mask
=
two_power_k
k
in
(* may raise Not_found *)
e_true
if
Masks
.
is_one_set
mask
v
then
else
if
not
(
Integer
.
is_zero
(
Integer
.
logand
v
.
Masks
.
unset
m
))
then
(* [ctx] gives that the bit [k] of [x] is set *)
(* [ctx] gives that the bit [k] of [x] is unset *)
e_true
e_false
else
if
Masks
.
is_one_unset
mask
v
then
else
e
(* [ctx] gives that the bit [k] of [x] is unset *)
e_false
else
e
with
_
->
e
)
with
_
->
e
)
|
Eq
(
a
,
b
)
when
highest
->
|
Eq
(
a
,
b
)
when
highest
->
(
try
(
try
...
@@ -1514,10 +1540,10 @@ let mask_simplifier =
...
@@ -1514,10 +1540,10 @@ let mask_simplifier =
if
Masks
.
is_bottom
v
then
if
Masks
.
is_bottom
v
then
(* Does not rewrite [e] because the polarity is unknown *)
(* Does not rewrite [e] because the polarity is unknown *)
e
e
else
if
not
(
Integer
.
is_zero
(
Integer
.
logand
set
v
.
Masks
.
un
set
))
then
else
if
Masks
.
is_one_unset
set
v
then
(* Some bits of [t] that has to be set is unset *)
(* Some bits of [t] that has to be set is unset *)
e_false
e_false
else
if
not
(
Integer
.
is_zero
(
Integer
.
logand
unset
v
.
Masks
.
set
))
then
else
if
Masks
.
is_one_set
unset
v
then
(* Some bits of [t] that has to be unset is set *)
(* Some bits of [t] that has to be unset is set *)
e_false
e_false
else
if
(
Integer
.
equal
(
Integer
.
logand
set
v
.
Masks
.
set
)
set
)
&&
else
if
(
Integer
.
equal
(
Integer
.
logand
set
v
.
Masks
.
set
)
set
)
&&
...
...
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