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
40b68462
Commit
40b68462
authored
2 years ago
by
Valentin Perrelle
Committed by
David Bühler
2 years ago
Browse files
Options
Downloads
Patches
Plain Diff
[Eva] Add a module to compute and export stats
parent
614c8171
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/eva/utils/statistics.ml
+184
-0
184 additions, 0 deletions
src/plugins/eva/utils/statistics.ml
src/plugins/eva/utils/statistics.mli
+40
-0
40 additions, 0 deletions
src/plugins/eva/utils/statistics.mli
with
224 additions
and
0 deletions
src/plugins/eva/utils/statistics.ml
0 → 100644
+
184
−
0
View file @
40b68462
(**************************************************************************)
(* *)
(* This file is part of Frama-C. *)
(* *)
(* Copyright (C) 2007-2022 *)
(* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1. *)
(* *)
(* It is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the GNU Lesser General Public License version 2.1 *)
(* for more details (enclosed in the file licenses/LGPLv2.1). *)
(* *)
(**************************************************************************)
(* Statistics are stored in a dictonary, implemented as an hashtable from
keys to integers.
[Key] is the representation of the dictionnary keys: a registered
['a t] statistic accompagnied by the function or the statement the stat is
about
Statistics must be registered before usage. The registry keeps track of the
registered statistics and allow the reloading of projects by matching the
previous stats to the current ones.
*)
(* --- Type --- *)
type
_
kind
=
|
Global
:
unit
kind
|
Function
:
Cil_types
.
kernel_function
kind
|
Statement
:
Cil_types
.
stmt
kind
type
'
a
t
=
{
id
:
int
;
name
:
string
;
kind
:
'
a
kind
;
}
(* --- Registry --- *)
type
registered_stat
=
Registered
:
'
a
t
->
registered_stat
let
kind_to_string
:
type
a
.
a
kind
->
string
=
function
|
Global
->
"global"
|
Function
->
"function"
|
Statement
->
"statement"
let
registry
=
Hashtbl
.
create
13
let
last_id
=
ref
0
let
register
(
type
a
)
(
name
:
string
)
(
kind
:
a
kind
)
:
a
t
=
try
let
Registered
stat
=
Hashtbl
.
find
registry
name
in
match
stat
.
kind
,
kind
with
|
Global
,
Global
->
stat
|
Function
,
Function
->
stat
|
Statement
,
Statement
->
stat
|
_
->
Self
.
fatal
"%s statistic
\"
%s
\"
was already registered with as a %s statistic"
name
(
kind_to_string
kind
)
(
kind_to_string
stat
.
kind
)
with
Not_found
->
incr
last_id
;
let
stat
=
{
id
=
!
last_id
;
name
;
kind
}
in
Hashtbl
.
add
registry
name
(
Registered
stat
);
stat
let
register_global_stat
name
=
register
name
Global
let
register_function_stat
name
=
register
name
Function
let
register_statement_stat
name
=
register
name
Statement
(* --- Keys --- *)
type
key
=
Key
:
'
a
t
*
'
a
->
key
module
Key
=
Datatype
.
Make_with_collections
(
struct
include
Datatype
.
Serializable_undefined
type
t
=
key
let
name
=
"Statistics.Key"
let
rehash
(
Key
(
s
,
x
))
=
(
Key
(
register
s
.
name
s
.
kind
,
x
))
let
reprs
=
[]
let
equal
(
Key
(
s1
,
x1
))
(
Key
(
s2
,
x2
))
=
match
s1
.
kind
,
s2
.
kind
with
|
Global
,
Global
->
true
|
Function
,
Function
->
Kernel_function
.
equal
x1
x2
|
Statement
,
Statement
->
Cil_datatype
.
Stmt
.
equal
x1
x2
|
_
,
_
->
false
let
compare
(
Key
(
s1
,
x1
))
(
Key
(
s2
,
x2
))
=
let
c
=
s1
.
id
-
s2
.
id
in
if
c
<>
0
then
c
else
match
s1
.
kind
,
s2
.
kind
with
|
Global
,
Global
->
0
|
Function
,
Function
->
Kernel_function
.
compare
x1
x2
|
Statement
,
Statement
->
Cil_datatype
.
Stmt
.
compare
x1
x2
|
Global
,
(
Function
|
Statement
)
->
-
1
|
(
Function
|
Statement
)
,
Global
->
1
|
Function
,
Statement
->
-
1
|
Statement
,
Function
->
1
let
hash
(
Key
(
s
,
x
))
=
let
h
=
match
s
.
kind
with
|
Global
->
0
|
Function
->
Kernel_function
.
hash
x
|
Statement
->
Cil_datatype
.
Stmt
.
hash
x
in
Hashtbl
.
hash
(
s
.
id
,
h
)
let
copy
k
=
k
let
pretty
fmt
(
Key
(
s
,
x
))
=
match
s
.
kind
with
|
Global
->
Format
.
fprintf
fmt
"%s"
s
.
name
|
Function
->
Format
.
fprintf
fmt
"%s:%a"
s
.
name
Kernel_function
.
pretty
x
|
Statement
->
Format
.
fprintf
fmt
"%s:%a"
s
.
name
Cil_datatype
.
Stmt
.
pretty
x
end
)
(* --- Projectified state --- *)
module
State
=
State_builder
.
Hashtbl
(
Key
.
Hashtbl
)
(
Datatype
.
Int
)
(
struct
let
name
=
"Eva.Statistics.State"
let
dependencies
=
[
Self
.
state
]
let
size
=
17
end
)
(* --- Statistics update --- *)
let
set
(
type
a
)
(
stat
:
a
t
)
(
x
:
a
)
value
=
let
k
=
Key
(
stat
,
x
)
in
State
.
replace
k
value
let
update
(
type
a
)
(
stat
:
a
t
)
(
x
:
a
)
(
f
:
int
->
int
)
=
let
k
=
Key
(
stat
,
x
)
in
State
.
replace
k
(
f
(
State
.
find_opt
k
|>
Option
.
value
~
default
:
0
))
let
incr
(
type
a
)
(
stat
:
a
t
)
(
x
:
a
)
=
update
stat
x
(
fun
v
->
v
+
1
)
let
grow
(
type
a
)
(
stat
:
a
t
)
(
x
:
a
)
value
=
update
stat
x
(
fun
v
->
max
v
value
)
(* -- Export --- *)
let
export_as_list
()
=
State
.
to_seq
()
|>
List
.
of_seq
|>
List
.
sort
(
fun
(
k1
,_
v1
)
(
k2
,_
v2
)
->
Key
.
compare
k1
k2
)
let
export_as_csv_to_channel
out_channel
=
let
fmt
=
Format
.
formatter_of_out_channel
out_channel
in
let
l
=
export_as_list
()
in
let
pp_stat
fmt
(
k
,
v
)
=
Format
.
fprintf
fmt
"%a
\t
%d
\n
"
Key
.
pretty
k
v
in
List
.
iter
(
pp_stat
fmt
)
l
let
export_as_csv
?
filename
()
=
let
filename
=
(
filename
:
Filepath
.
Normalized
.
t
option
:>
string
option
)
in
let
filename
=
Option
.
value
~
default
:
"stats.json"
filename
in
let
out_channel
=
open_out
(
filename
:>
string
)
in
export_as_csv_to_channel
out_channel
This diff is collapsed.
Click to expand it.
src/plugins/eva/utils/statistics.mli
0 → 100644
+
40
−
0
View file @
40b68462
(**************************************************************************)
(* *)
(* This file is part of Frama-C. *)
(* *)
(* Copyright (C) 2007-2022 *)
(* CEA (Commissariat à l'énergie atomique et aux énergies *)
(* alternatives) *)
(* *)
(* you can redistribute it and/or modify it under the terms of the GNU *)
(* Lesser General Public License as published by the Free Software *)
(* Foundation, version 2.1. *)
(* *)
(* It is distributed in the hope that it will be useful, *)
(* but WITHOUT ANY WARRANTY; without even the implied warranty of *)
(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *)
(* GNU Lesser General Public License for more details. *)
(* *)
(* See the GNU Lesser General Public License version 2.1 *)
(* for more details (enclosed in the file licenses/LGPLv2.1). *)
(* *)
(**************************************************************************)
type
'
a
t
(* Register a statistic class *)
val
register_global_stat
:
string
->
unit
t
val
register_function_stat
:
string
->
Cil_types
.
kernel_function
t
val
register_statement_stat
:
string
->
Cil_types
.
stmt
t
(* Set the stat to the given value *)
val
set
:
'
a
t
->
'
a
->
int
->
unit
(* Adds 1 to the stat or set it to 1 if undefined *)
val
incr
:
'
a
t
->
'
a
->
unit
(* Set the stat to the maximum between the current value and the given value *)
val
grow
:
'
a
t
->
'
a
->
int
->
unit
(* Export the computed statistics as CSV *)
val
export_as_csv
:
?
filename
:
Filepath
.
Normalized
.
t
->
unit
->
unit
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