Skip to content

Commit f1b6174

Browse files
author
Daniel Kroening
committed
use unwindsett in goto-instrument
1 parent dcc907a commit f1b6174

File tree

6 files changed

+53
-134
lines changed

6 files changed

+53
-134
lines changed

regression/goto-instrument/unwind-unwindset3/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
CORE
22
main.c
3-
--unwind 10 --unwindset main.0:-1
3+
--unwind 10 --unwindset main.0:
44
^Unwinding loop
55
^EXIT=0$
66
^SIGNAL=0$

src/goto-instrument/goto_instrument_parse_options.cpp

+13-30
Original file line numberDiff line numberDiff line change
@@ -139,43 +139,26 @@ int goto_instrument_parse_optionst::doit()
139139
instrument_goto_program();
140140

141141
{
142-
bool unwind=cmdline.isset("unwind");
143-
bool unwindset=cmdline.isset("unwindset");
144-
bool unwindset_file=cmdline.isset("unwindset-file");
142+
bool unwind_given=cmdline.isset("unwind");
143+
bool unwindset_given=cmdline.isset("unwindset");
144+
bool unwindset_file_given=cmdline.isset("unwindset-file");
145145

146-
if(unwindset && unwindset_file)
146+
if(unwindset_given && unwindset_file_given)
147147
throw "only one of --unwindset and --unwindset-file supported at a "
148148
"time";
149149

150-
if(unwind || unwindset || unwindset_file)
150+
if(unwind_given || unwindset_given || unwindset_file_given)
151151
{
152-
int k=-1;
152+
unwindsett unwindset;
153153

154-
if(unwind)
155-
k=std::stoi(cmdline.get_value("unwind"));
154+
if(unwind_given)
155+
unwindset.parse_unwind(cmdline.get_value("unwind"));
156156

157-
unwind_sett unwind_set;
157+
if(unwindset_file_given)
158+
unwindset.parse_unwindset_file(cmdline.get_value("unwindset-file"));
158159

159-
if(unwindset_file)
160-
{
161-
std::string us;
162-
std::string fn=cmdline.get_value("unwindset-file");
163-
164-
#ifdef _MSC_VER
165-
std::ifstream file(widen(fn));
166-
#else
167-
std::ifstream file(fn);
168-
#endif
169-
if(!file)
170-
throw "cannot open file "+fn;
171-
172-
std::stringstream buffer;
173-
buffer << file.rdbuf();
174-
us=buffer.str();
175-
parse_unwindset(us, unwind_set);
176-
}
177-
else if(unwindset)
178-
parse_unwindset(cmdline.get_value("unwindset"), unwind_set);
160+
if(unwindset_given)
161+
unwindset.parse_unwindset(cmdline.get_value("unwindset"));
179162

180163
bool unwinding_assertions=cmdline.isset("unwinding-assertions");
181164
bool partial_loops=cmdline.isset("partial-loops");
@@ -202,7 +185,7 @@ int goto_instrument_parse_optionst::doit()
202185
}
203186

204187
goto_unwindt goto_unwind;
205-
goto_unwind(goto_model, unwind_set, k, unwind_strategy);
188+
goto_unwind(goto_model, unwindset, unwind_strategy);
206189

207190
goto_model.goto_functions.update();
208191
goto_model.goto_functions.compute_loop_numbers();

src/goto-instrument/unwind.cpp

+9-70
Original file line numberDiff line numberDiff line change
@@ -22,40 +22,6 @@ Author: Daniel Kroening, [email protected]
2222

2323
#include "loop_utils.h"
2424

25-
void parse_unwindset(const std::string &us, unwind_sett &unwind_set)
26-
{
27-
assert(unwind_set.empty());
28-
29-
std::vector<std::string> result;
30-
split_string(us, ',', result, true, true);
31-
assert(!result.empty());
32-
33-
if(result.front().empty()) // allow empty string as unwindset
34-
return;
35-
36-
for(std::vector<std::string>::const_iterator it=result.begin();
37-
it!=result.end(); it++)
38-
{
39-
std::string loop;
40-
std::string bound;
41-
42-
split_string(*it, ':', loop, bound, true);
43-
44-
std::string func;
45-
std::string id;
46-
47-
split_string(loop, '.', func, id, true);
48-
49-
unsigned loop_id=std::stoi(id);
50-
int loop_bound=std::stoi(bound);
51-
52-
if(loop_bound<-1)
53-
throw "given unwind bound < -1";
54-
55-
unwind_set[func][loop_id]=loop_bound;
56-
}
57-
}
58-
5925
void goto_unwindt::copy_segment(
6026
const goto_programt::const_targett start,
6127
const goto_programt::const_targett end, // exclusive
@@ -290,37 +256,11 @@ void goto_unwindt::unwind(
290256
goto_program.destructive_insert(loop_exit, copies);
291257
}
292258

293-
int goto_unwindt::get_k(
294-
const irep_idt func,
295-
const unsigned loop_id,
296-
const int global_k,
297-
const unwind_sett &unwind_set) const
298-
{
299-
assert(global_k>=-1);
300-
301-
unwind_sett::const_iterator f_it=unwind_set.find(func);
302-
if(f_it==unwind_set.end())
303-
return global_k;
304-
305-
const std::map<unsigned, int> &m=f_it->second;
306-
std::map<unsigned, int>::const_iterator l_it=m.find(loop_id);
307-
if(l_it==m.end())
308-
return global_k;
309-
310-
int k=l_it->second;
311-
assert(k>=-1);
312-
313-
return k;
314-
}
315-
316259
void goto_unwindt::unwind(
317260
goto_programt &goto_program,
318-
const unwind_sett &unwind_set,
319-
const int k,
261+
const unwindsett &unwindset,
320262
const unwind_strategyt unwind_strategy)
321263
{
322-
assert(k>=-1);
323-
324264
for(goto_programt::const_targett i_it=goto_program.instructions.begin();
325265
i_it!=goto_program.instructions.end();)
326266
{
@@ -340,12 +280,14 @@ void goto_unwindt::unwind(
340280
const irep_idt func=i_it->function;
341281
assert(!func.empty());
342282

343-
unsigned loop_number=i_it->loop_number;
283+
const irep_idt loop_id=
284+
id2string(func) + "." + std::to_string(i_it->loop_number);
344285

345-
int final_k=get_k(func, loop_number, k, unwind_set);
286+
auto limit=unwindset.get_limit(loop_id, 0);
346287

347-
if(final_k==-1)
288+
if(!limit.has_value())
348289
{
290+
// no unwinding given
349291
i_it++;
350292
continue;
351293
}
@@ -355,7 +297,7 @@ void goto_unwindt::unwind(
355297
loop_exit++;
356298
assert(loop_exit!=goto_program.instructions.end());
357299

358-
unwind(goto_program, loop_head, loop_exit, final_k, unwind_strategy);
300+
unwind(goto_program, loop_head, loop_exit, *limit, unwind_strategy);
359301

360302
// necessary as we change the goto program in the previous line
361303
i_it=loop_exit;
@@ -364,12 +306,9 @@ void goto_unwindt::unwind(
364306

365307
void goto_unwindt::operator()(
366308
goto_functionst &goto_functions,
367-
const unwind_sett &unwind_set,
368-
const int k,
309+
const unwindsett &unwindset,
369310
const unwind_strategyt unwind_strategy)
370311
{
371-
assert(k>=-1);
372-
373312
Forall_goto_functions(it, goto_functions)
374313
{
375314
goto_functionst::goto_functiont &goto_function=it->second;
@@ -383,7 +322,7 @@ void goto_unwindt::operator()(
383322

384323
goto_programt &goto_program=goto_function.body;
385324

386-
unwind(goto_program, unwind_set, k, unwind_strategy);
325+
unwind(goto_program, unwindset, unwind_strategy);
387326
}
388327
}
389328

src/goto-instrument/unwind.h

+7-33
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@ Author: Daniel Kroening, [email protected]
1313
#ifndef CPROVER_GOTO_INSTRUMENT_UNWIND_H
1414
#define CPROVER_GOTO_INSTRUMENT_UNWIND_H
1515

16+
#include "unwindset.h"
17+
1618
#include <util/json.h>
1719
#include <util/json_expr.h>
1820
#include <goto-programs/goto_model.h>
1921

2022
class goto_modelt;
2123

22-
// -1: do not unwind loop
23-
typedef std::map<irep_idt, std::map<unsigned, int>> unwind_sett;
24-
25-
void parse_unwindset(const std::string &us, unwind_sett &unwind_set);
26-
2724
class goto_unwindt
2825
{
2926
public:
@@ -50,44 +47,22 @@ class goto_unwindt
5047

5148
void unwind(
5249
goto_programt &goto_program,
53-
const unwind_sett &unwind_set,
54-
const int k=-1, // -1: no global bound
50+
const unwindsett &unwindset,
5551
const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL);
5652

5753
// unwind all functions
58-
59-
void operator()(
60-
goto_functionst &goto_functions,
61-
const unsigned k, // global bound
62-
const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL)
63-
{
64-
const unwind_sett unwind_set;
65-
operator()(goto_functions, unwind_set, k, unwind_strategy);
66-
}
67-
6854
void operator()(
6955
goto_functionst &,
70-
const unwind_sett &unwind_set,
71-
const int k=-1, // -1: no global bound
56+
const unwindsett &unwindset,
7257
const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL);
7358

7459
void operator()(
7560
goto_modelt &goto_model,
76-
const unsigned k, // global bound
77-
const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL)
78-
{
79-
const unwind_sett unwind_set;
80-
operator()(goto_model.goto_functions, unwind_set, k, unwind_strategy);
81-
}
82-
83-
void operator()(
84-
goto_modelt &goto_model,
85-
const unwind_sett &unwind_set,
86-
const int k=-1, // -1: no global bound
61+
const unwindsett &unwindset,
8762
const unwind_strategyt unwind_strategy=unwind_strategyt::PARTIAL)
8863
{
8964
operator()(
90-
goto_model.goto_functions, unwind_set, k, unwind_strategy);
65+
goto_model.goto_functions, unwindset, unwind_strategy);
9166
}
9267

9368
// unwind log
@@ -132,8 +107,7 @@ class goto_unwindt
132107
int get_k(
133108
const irep_idt func,
134109
const unsigned loop_id,
135-
const int global_k,
136-
const unwind_sett &unwind_set) const;
110+
const unwindsett &unwindset) const;
137111

138112
// copy goto program segment and redirect internal edges
139113
void copy_segment(

src/goto-instrument/unwindset.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ Author: Daniel Kroening, [email protected]
1010

1111
#include <util/string2int.h>
1212
#include <util/string_utils.h>
13+
#include <util/unicode.h>
14+
15+
#include <fstream>
16+
#include <sstream>
1317

1418
void unwindsett::parse_unwind(const std::string &unwind)
1519
{
@@ -77,3 +81,19 @@ unwindsett::get_limit(const irep_idt &loop_id, unsigned thread_nr) const
7781
// global, if any
7882
return global_limit;
7983
}
84+
85+
void unwindsett::parse_unwindset_file(const std::string &file_name)
86+
{
87+
#ifdef _MSC_VER
88+
std::ifstream file(widen(file_name));
89+
#else
90+
std::ifstream file(file_name);
91+
#endif
92+
93+
if(!file)
94+
throw "cannot open file "+file_name;
95+
96+
std::stringstream buffer;
97+
buffer << file.rdbuf();
98+
parse_unwindset(buffer.str());
99+
}

src/goto-instrument/unwindset.h

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ class unwindsett
3636
// queries
3737
optionalt<unsigned> get_limit(const irep_idt &loop, unsigned thread_id) const;
3838

39+
// read unwindset directives from a file
40+
void parse_unwindset_file(const std::string &file_name);
41+
3942
protected:
4043
optionalt<unsigned> global_limit;
4144

0 commit comments

Comments
 (0)