cprover
Toggle main menu visibility
Loading...
Searching...
No Matches
remove_skip.cpp
Go to the documentation of this file.
1
/*******************************************************************\
2
3
Module: Program Transformation
4
5
Author: Daniel Kroening, kroening@kroening.com
6
7
\*******************************************************************/
8
11
12
#include "
remove_skip.h
"
13
#include "
goto_model.h
"
14
15
#include <
util/std_code.h
>
16
27
bool
is_skip
(
28
const
goto_programt
&body,
29
goto_programt::const_targett
it,
30
bool
ignore_labels)
31
{
32
if
(!ignore_labels && !it->labels.empty())
33
return
false
;
34
35
if
(it->is_skip())
36
return
!it->code().get_bool(ID_explicit);
37
38
if
(it->is_goto())
39
{
40
if
(it->condition() ==
false
)
41
return
true
;
42
43
goto_programt::const_targett
next_it = it;
44
next_it++;
45
46
if
(next_it == body.
instructions
.end())
47
return
false
;
48
49
// A branch to the next instruction is a skip
50
// We also require the guard to be 'true'
51
return
it->condition() ==
true
&& it->get_target() == next_it;
52
}
53
54
if
(it->is_other())
55
{
56
if
(it->get_other().is_nil())
57
return
true
;
58
59
const
irep_idt
&statement = it->get_other().get_statement();
60
61
if
(statement==ID_skip)
62
return
true
;
63
else
if
(statement==ID_expression)
64
{
65
const
code_expressiont
&code_expression =
to_code_expression
(it->code());
66
const
exprt
&expr=code_expression.
expression
();
67
if
(expr.
id
()==ID_typecast &&
68
expr.
type
().
id
()==ID_empty &&
69
to_typecast_expr
(expr).op().
is_constant
())
70
{
71
// something like (void)0
72
return
true
;
73
}
74
}
75
76
return
false
;
77
}
78
79
return
false
;
80
}
81
87
void
remove_skip
(
88
goto_programt
&goto_program,
89
goto_programt::targett
begin,
90
goto_programt::targett
end)
91
{
92
// This needs to be a fixed-point, as
93
// removing a skip can turn a goto into a skip.
94
std::size_t old_size;
95
96
do
97
{
98
old_size=goto_program.
instructions
.size();
99
100
// maps deleted instructions to their replacement
101
typedef
std::map<
102
goto_programt::targett
,
103
goto_programt::targett
,
104
goto_programt::target_less_than
>
105
new_targetst;
106
new_targetst new_targets;
107
108
// remove skip statements
109
110
for
(goto_programt::instructionst::iterator it = begin; it != end;)
111
{
112
goto_programt::targett
old_target=it;
113
114
// for collecting labels
115
std::list<irep_idt> labels;
116
117
while
(
is_skip
(goto_program, it,
true
))
118
{
119
// don't remove the last skip statement,
120
// it could be a target
121
if
(
122
it == std::prev(end) ||
123
(std::next(it)->is_end_function() &&
124
(!labels.empty() || !it->labels.empty())))
125
{
126
break
;
127
}
128
129
// save labels
130
labels.splice(labels.end(), it->labels);
131
it++;
132
}
133
134
goto_programt::targett
new_target=it;
135
136
// save labels
137
it->labels.splice(it->labels.begin(), labels);
138
139
if
(new_target!=old_target)
140
{
141
for
(; old_target!=new_target; ++old_target)
142
new_targets[old_target]=new_target;
// remember the old targets
143
}
144
else
145
it++;
146
}
147
148
// adjust gotos across the full goto program body
149
for
(
auto
&ins : goto_program.
instructions
)
150
{
151
if
(ins.is_goto() || ins.is_start_thread() || ins.is_catch())
152
{
153
for
(
auto
&target : ins.targets)
154
{
155
new_targetst::const_iterator result = new_targets.find(target);
156
157
if
(result!=new_targets.end())
158
target = result->second;
159
}
160
}
161
}
162
163
while
(new_targets.find(begin) != new_targets.end())
164
++begin;
165
166
// now delete the skips -- we do so after adjusting the
167
// gotos to avoid dangling targets
168
for
(
const
auto
&new_target : new_targets)
169
goto_program.
instructions
.erase(new_target.first);
170
171
// remove the last skip statement unless it's a target
172
goto_program.
compute_target_numbers
();
173
174
if
(begin != end)
175
{
176
goto_programt::targett
last = std::prev(end);
177
if
(begin == last)
178
++begin;
179
180
if
(
is_skip
(goto_program, last) && !last->is_target())
181
goto_program.
instructions
.erase(last);
182
}
183
}
184
while
(goto_program.
instructions
.size()<old_size);
185
}
186
188
void
remove_skip
(
goto_programt
&goto_program)
189
{
190
remove_skip
(
191
goto_program,
192
goto_program.
instructions
.begin(),
193
goto_program.
instructions
.end());
194
195
goto_program.
update
();
196
}
197
199
void
remove_skip
(
goto_functionst
&goto_functions)
200
{
201
for
(
auto
&gf_entry : goto_functions.
function_map
)
202
{
203
remove_skip
(
204
gf_entry.second.body,
205
gf_entry.second.body.instructions.begin(),
206
gf_entry.second.body.instructions.end());
207
}
208
209
// we may remove targets
210
goto_functions.
update
();
211
}
212
213
void
remove_skip
(
goto_modelt
&goto_model)
214
{
215
remove_skip
(goto_model.
goto_functions
);
216
}
code_expressiont
codet representation of an expression statement.
Definition
std_code.h:1394
code_expressiont::expression
const exprt & expression() const
Definition
std_code.h:1401
exprt
Base class for all expressions.
Definition
expr.h:57
exprt::type
typet & type()
Return the type of the expression.
Definition
expr.h:85
goto_functionst
A collection of goto functions.
Definition
goto_functions.h:25
goto_functionst::function_map
function_mapt function_map
Definition
goto_functions.h:29
goto_functionst::update
void update()
Definition
goto_functions.h:88
goto_modelt
Definition
goto_model.h:27
goto_modelt::goto_functions
goto_functionst goto_functions
GOTO functions.
Definition
goto_model.h:34
goto_programt
A generic container class for the GOTO intermediate representation of one function.
Definition
goto_program.h:72
goto_programt::instructions
instructionst instructions
The list of instructions in the goto program.
Definition
goto_program.h:621
goto_programt::update
void update()
Update all indices.
Definition
goto_program.cpp:619
goto_programt::targett
instructionst::iterator targett
Definition
goto_program.h:613
goto_programt::const_targett
instructionst::const_iterator const_targett
Definition
goto_program.h:614
goto_programt::target_less_than
instructiont::target_less_than target_less_than
Definition
goto_program.h:618
goto_programt::compute_target_numbers
void compute_target_numbers()
Compute the target numbers.
Definition
goto_program.cpp:647
irept::id
const irep_idt & id() const
Definition
irep.h:388
goto_model.h
Symbol Table + CFG.
remove_skip
void remove_skip(goto_programt &goto_program, goto_programt::targett begin, goto_programt::targett end)
remove unnecessary skip statements
Definition
remove_skip.cpp:87
is_skip
bool is_skip(const goto_programt &body, goto_programt::const_targett it, bool ignore_labels)
Determine whether the instruction is semantically equivalent to a skip (no-op).
Definition
remove_skip.cpp:27
remove_skip.h
Program Transformation.
std_code.h
to_code_expression
code_expressiont & to_code_expression(codet &code)
Definition
std_code.h:1428
to_typecast_expr
const typecast_exprt & to_typecast_expr(const exprt &expr)
Cast an exprt to a typecast_exprt.
Definition
std_expr.h:2014
is_constant
bool is_constant(const typet &type)
This method tests, if the given typet is a constant.
Definition
std_types.h:29
irep_idt
dstringt irep_idt
Definition
verification_result.h:16
goto-programs
remove_skip.cpp
Generated by
1.17.0