Skip to content

Commit 89d5ba2

Browse files
committed
Refine data dependency across function calls
1 parent aa7ebbc commit 89d5ba2

File tree

6 files changed

+119
-6
lines changed

6 files changed

+119
-6
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#include <assert.h>
2+
3+
void bar(int a, int b)
4+
{
5+
int result = b;
6+
}
7+
8+
void main()
9+
{
10+
int a = 1;
11+
int b = 2;
12+
int c = 3;
13+
bar(a, b + c);
14+
}
15+
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
CORE
2+
main.c
3+
--dependence-graph --show
4+
activate-multi-line-match
5+
^EXIT=0$
6+
^SIGNAL=0$
7+
// Assignment has a data dependency on the assignment of b
8+
\/\/ ([0-9]+).*\n.*b = 2;(.*\n)*Data dependencies: (([0-9]+,\1)|(\1,[0-9]+))\n(.*\n){2,3}.*result = b
9+
// Assignment has a data dependency on the assignment of c
10+
\/\/ ([0-9]+).*\n.*c = 3;(.*\n)*Data dependencies: (([0-9]+,\1)|(\1,[0-9]+))\n(.*\n){2,3}.*result = b
11+
--
12+
^warning: ignoring
13+
--
14+
15+
The two regex above matches output portions like shown below (with <N> being a
16+
location number). The intention is to check whether an function parameter in the
17+
callee correctly depends on the caller provided argument.
18+
19+
// 3 file main.c line 11 function main
20+
b = 2;
21+
...
22+
**** 12 file main.c line 5 function bar
23+
Data dependencies: (<N>,...)|(...,<N>)
24+
25+
// 12 file main.c line 5 function bar
26+
result = b;
27+
28+
The second regex matches for c.

src/analyses/dependence_graph.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Date: August 2013
2121
#include <util/json_expr.h>
2222

2323
#include "goto_rw.h"
24+
#include <iostream>
2425

2526
bool dep_graph_domaint::merge(
2627
const dep_graph_domaint &src,
@@ -164,13 +165,14 @@ void dep_graph_domaint::data_dependencies(
164165
dep_graph.reaching_definitions().get_value_sets();
165166
rw_range_set_value_sett rw_set(ns, value_sets);
166167
goto_rw(to, rw_set);
168+
std::cerr << "\ndata_deps from " << from->location_number << " to " << to->location_number << "\n";
167169

168170
forall_rw_range_set_r_objects(it, rw_set)
169171
{
172+
std::cerr << "Checking for symbol : " << it->first << "\n";
170173
const range_domaint &r_ranges=rw_set.get_ranges(it);
171174
const rd_range_domaint::ranges_at_loct &w_ranges=
172175
dep_graph.reaching_definitions()[to].get(it->first);
173-
174176
for(const auto &w_range : w_ranges)
175177
{
176178
bool found=false;
@@ -182,6 +184,7 @@ void dep_graph_domaint::data_dependencies(
182184
{
183185
// found a def-use pair
184186
data_deps.insert(w_range.first);
187+
std::cerr << " insert data_deps " << w_range.first->location_number << "\n";
185188
found=true;
186189
}
187190
}

src/analyses/goto_rw.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,22 @@ void rw_range_sett::add(
480480

481481
static_cast<range_domaint&>(*entry->second).push_back(
482482
{range_start, range_end});
483+
484+
// add to the single expression read set
485+
if(mode==get_modet::READ && is_get_expr_r_set)
486+
{
487+
objectst::iterator expr_entry=
488+
expr_r_range_set.insert(
489+
std::pair<const irep_idt &, std::unique_ptr<range_domain_baset>>(
490+
identifier, nullptr))
491+
.first;
492+
493+
if(expr_entry->second==nullptr)
494+
expr_entry->second=util_make_unique<range_domaint>();
495+
496+
static_cast<range_domaint&>(*expr_entry->second).push_back(
497+
{range_start, range_end});
498+
}
483499
}
484500

485501
void rw_range_sett::get_objects_rec(

src/analyses/goto_rw.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class rw_range_sett
120120
explicit rw_range_sett(const namespacet &_ns):
121121
ns(_ns)
122122
{
123+
is_get_expr_r_set = false;
123124
}
124125

125126
const objectst &get_r_set() const
@@ -132,6 +133,18 @@ class rw_range_sett
132133
return w_range_set;
133134
}
134135

136+
objectst &get_expr_r_set()
137+
{
138+
is_get_expr_r_set = false;
139+
return expr_r_range_set;
140+
}
141+
142+
void set_expr_r_set()
143+
{
144+
is_get_expr_r_set = true;
145+
expr_r_range_set.clear();
146+
}
147+
135148
const range_domaint &get_ranges(objectst::const_iterator it) const
136149
{
137150
PRECONDITION(dynamic_cast<range_domaint*>(it->second.get())!=nullptr);
@@ -156,6 +169,9 @@ class rw_range_sett
156169
const namespacet &ns;
157170

158171
objectst r_range_set, w_range_set;
172+
// the read set for a single expression
173+
objectst expr_r_range_set;
174+
bool is_get_expr_r_set;
159175

160176
virtual void get_objects_rec(
161177
get_modet mode,

src/analyses/reaching_definitions.cpp

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@ Date: February 2013
2020
#include <util/pointer_offset_size.h>
2121
#include <util/prefix.h>
2222
#include <util/make_unique.h>
23+
#include <util/find_symbols.h>
2324

2425
#include <pointer-analysis/value_set_analysis_fi.h>
2526

2627
#include "is_threaded.h"
2728
#include "dirty.h"
29+
#include <iostream>
2830

2931
reaching_definitions_analysist::reaching_definitions_analysist(
3032
const namespacet &_ns):
@@ -172,6 +174,7 @@ void rd_range_domaint::transform_function_call(
172174
reaching_definitions_analysist &rd)
173175
{
174176
const code_function_callt &code=to_code_function_call(from->code);
177+
std::cerr << "\ntransform function call from " << from->location_number << " to " << to->location_number << "\n";
175178

176179
// only if there is an actual call, i.e., we have a body
177180
if(from->function != to->function)
@@ -203,16 +206,46 @@ void rd_range_domaint::transform_function_call(
203206
const code_typet &code_type=
204207
to_code_type(ns.lookup(fn_symbol_expr.get_identifier()).type);
205208

206-
for(const auto &param : code_type.parameters())
209+
std::cerr << "function name :" << fn_symbol_expr.get_identifier() << "\n";
210+
211+
rw_range_set_value_sett rw_set(ns, rd.get_value_sets());
212+
//goto_rw(from, rw_set);
213+
rw_set.output(std::cout);
214+
//const rw_range_sett::objectst r_objects = rw_set.get_r_set();
215+
216+
PRECONDITION(code_type.parameters().size() == code.arguments().size());
217+
auto param = code_type.parameters().begin();
218+
auto arg = code.arguments().begin();
219+
// iterate through argument/parameter pairs
220+
while(param != code_type.parameters().end() &&
221+
arg != code.arguments().end())
207222
{
208-
const irep_idt &identifier=param.get_identifier();
223+
const irep_idt &identifier=param->get_identifier();
209224

210225
if(identifier.empty())
211226
continue;
212227

213-
range_spect size=
214-
to_range_spect(pointer_offset_bits(param.type(), ns));
215-
gen(from, identifier, 0, size);
228+
std::cout << " param name: " << identifier << "\n";
229+
// get read set of the argument
230+
rw_set.set_expr_r_set();
231+
rw_set.get_objects_rec(from, rw_range_sett::get_modet::READ, *arg);
232+
std::cout << " argument set: \n";
233+
for(rw_range_sett::objectst::const_iterator
234+
it=(rw_set).get_expr_r_set().begin();
235+
it!=(rw_set).get_expr_r_set().end(); ++it)
236+
{
237+
std::cout << it->first << ":";
238+
const rd_range_domaint::ranges_at_loct &w_ranges = rd[from].get(it->first);
239+
for(const auto &w_range : w_ranges)
240+
{
241+
std::cerr << " further dep on: " << w_range.first->location_number << "\n";
242+
for(const auto &wr : w_range.second)
243+
gen(w_range.first, identifier, wr.first, wr.second);
244+
}
245+
}
246+
// next argument/parameter pair
247+
++param;
248+
++arg;
216249
}
217250
}
218251
else
@@ -299,8 +332,10 @@ void rd_range_domaint::transform_assign(
299332
locationt to,
300333
reaching_definitions_analysist &rd)
301334
{
335+
std::cerr << "\ntransform assign from " << from->location_number << " to " << to->location_number << "\n";
302336
rw_range_set_value_sett rw_set(ns, rd.get_value_sets());
303337
goto_rw(to, rw_set);
338+
rw_set.output(std::cerr);
304339
const bool is_must_alias=rw_set.get_w_set().size()==1;
305340

306341
forall_rw_range_set_w_objects(it, rw_set)

0 commit comments

Comments
 (0)