-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathis_threaded.cpp
114 lines (88 loc) · 2.43 KB
/
is_threaded.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*******************************************************************\
Module: Over-approximate Concurrency for Threaded Goto Programs
Author: Daniel Kroening
Date: October 2012
\*******************************************************************/
/// \file
/// Over-approximate Concurrency for Threaded Goto Programs
#include "is_threaded.h"
#include "ai.h"
class is_threaded_domaint:public ai_domain_baset
{
public:
bool reachable;
bool is_threaded;
is_threaded_domaint():
reachable(false),
is_threaded(false)
{
// this is bottom
}
bool merge(const is_threaded_domaint &src, trace_ptrt, trace_ptrt)
{
INVARIANT(src.reachable,
"Abstract states are only merged at reachable locations");
bool old_reachable=reachable;
bool old_is_threaded=is_threaded;
reachable=true;
is_threaded|=src.is_threaded;
return old_reachable!=reachable ||
old_is_threaded!=is_threaded;
}
void transform(
const irep_idt &,
trace_ptrt trace_from,
const irep_idt &,
trace_ptrt,
ai_baset &,
const namespacet &) override
{
locationt from{trace_from->current_location()};
INVARIANT(reachable,
"Transformers are only applied at reachable locations");
if(from->is_start_thread())
is_threaded=true;
}
void make_bottom() final override
{
reachable=false;
is_threaded=false;
}
void make_top() final override
{
reachable=true;
is_threaded=true;
}
void make_entry() final override
{
reachable=true;
is_threaded=false;
}
bool is_bottom() const override final
{
DATA_INVARIANT(reachable || !is_threaded,
"A location cannot be threaded if it is not reachable.");
return !reachable;
}
bool is_top() const override final
{
return reachable && is_threaded;
}
};
void is_threadedt::compute(const goto_functionst &goto_functions)
{
// the analysis doesn't actually use the namespace, fake one
symbol_tablet symbol_table;
const namespacet ns(symbol_table);
ait<is_threaded_domaint> is_threaded_analysis;
is_threaded_analysis(goto_functions, ns);
for(const auto &gf_entry : goto_functions.function_map)
{
forall_goto_program_instructions(i_it, gf_entry.second.body)
{
auto domain_ptr = is_threaded_analysis.abstract_state_before(i_it);
if(static_cast<const is_threaded_domaint &>(*domain_ptr).is_threaded)
is_threaded_set.insert(i_it);
}
}
}