Skip to content

Commit 0d61327

Browse files
zhixing-xutautschnig
authored andcommitted
Refine data dependency across function calls
1 parent bbb1ce8 commit 0d61327

File tree

6 files changed

+119
-8
lines changed

6 files changed

+119
-8
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
@@ -20,6 +20,7 @@ Date: August 2013
2020
#include <util/json_irep.h>
2121

2222
#include "goto_rw.h"
23+
#include <iostream>
2324

2425
bool dep_graph_domaint::merge(
2526
const dep_graph_domaint &src,
@@ -165,13 +166,14 @@ void dep_graph_domaint::data_dependencies(
165166
dep_graph.reaching_definitions().get_value_sets();
166167
rw_range_set_value_sett rw_set(ns, value_sets);
167168
goto_rw(function_to, to, rw_set);
169+
std::cerr << "\ndata_deps from " << from->location_number << " to " << to->location_number << "\n";
168170

169171
forall_rw_range_set_r_objects(it, rw_set)
170172
{
173+
std::cerr << "Checking for symbol : " << it->first << "\n";
171174
const range_domaint &r_ranges=rw_set.get_ranges(it);
172175
const rd_range_domaint::ranges_at_loct &w_ranges=
173176
dep_graph.reaching_definitions()[to].get(it->first);
174-
175177
for(const auto &w_range : w_ranges)
176178
{
177179
bool found=false;
@@ -183,6 +185,7 @@ void dep_graph_domaint::data_dependencies(
183185
{
184186
// found a def-use pair
185187
data_deps.insert(w_range.first);
188+
std::cerr << " insert data_deps " << w_range.first->location_number << "\n";
186189
found=true;
187190
}
188191
}

src/analyses/goto_rw.cpp

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

494494
static_cast<range_domaint&>(*entry->second).push_back(
495495
{range_start, range_end});
496+
497+
// add to the single expression read set
498+
if(mode==get_modet::READ && is_get_expr_r_set)
499+
{
500+
objectst::iterator expr_entry=
501+
expr_r_range_set.insert(
502+
std::pair<const irep_idt &, std::unique_ptr<range_domain_baset>>(
503+
identifier, nullptr))
504+
.first;
505+
506+
if(expr_entry->second==nullptr)
507+
expr_entry->second=util_make_unique<range_domaint>();
508+
509+
static_cast<range_domaint&>(*expr_entry->second).push_back(
510+
{range_start, range_end});
511+
}
496512
}
497513

498514
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
@@ -124,6 +124,7 @@ class rw_range_sett
124124
explicit rw_range_sett(const namespacet &_ns):
125125
ns(_ns)
126126
{
127+
is_get_expr_r_set = false;
127128
}
128129

129130
const objectst &get_r_set() const
@@ -136,6 +137,18 @@ class rw_range_sett
136137
return w_range_set;
137138
}
138139

140+
objectst &get_expr_r_set()
141+
{
142+
is_get_expr_r_set = false;
143+
return expr_r_range_set;
144+
}
145+
146+
void set_expr_r_set()
147+
{
148+
is_get_expr_r_set = true;
149+
expr_r_range_set.clear();
150+
}
151+
139152
const range_domaint &get_ranges(objectst::const_iterator it) const
140153
{
141154
PRECONDITION(dynamic_cast<range_domaint*>(it->second.get())!=nullptr);
@@ -167,6 +180,9 @@ class rw_range_sett
167180
const namespacet &ns;
168181

169182
objectst r_range_set, w_range_set;
183+
// the read set for a single expression
184+
objectst expr_r_range_set;
185+
bool is_get_expr_r_set;
170186

171187
virtual void get_objects_rec(
172188
get_modet mode,

src/analyses/reaching_definitions.cpp

Lines changed: 40 additions & 7 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):
@@ -184,6 +186,7 @@ void rd_range_domaint::transform_function_call(
184186
reaching_definitions_analysist &rd)
185187
{
186188
const code_function_callt &code=to_code_function_call(from->code);
189+
std::cerr << "\ntransform function call from " << from->location_number << " to " << to->location_number << "\n";
187190

188191
// only if there is an actual call, i.e., we have a body
189192
if(function_from != function_to)
@@ -215,18 +218,46 @@ void rd_range_domaint::transform_function_call(
215218
const code_typet &code_type=
216219
to_code_type(ns.lookup(fn_symbol_expr.get_identifier()).type);
217220

218-
for(const auto &param : code_type.parameters())
221+
std::cerr << "function name :" << fn_symbol_expr.get_identifier() << "\n";
222+
223+
rw_range_set_value_sett rw_set(ns, rd.get_value_sets());
224+
//goto_rw(from, rw_set);
225+
rw_set.output(std::cout);
226+
//const rw_range_sett::objectst r_objects = rw_set.get_r_set();
227+
228+
PRECONDITION(code_type.parameters().size() == code.arguments().size());
229+
auto param = code_type.parameters().begin();
230+
auto arg = code.arguments().begin();
231+
// iterate through argument/parameter pairs
232+
while(param != code_type.parameters().end() &&
233+
arg != code.arguments().end())
219234
{
220-
const irep_idt &identifier=param.get_identifier();
235+
const irep_idt &identifier=param->get_identifier();
221236

222237
if(identifier.empty())
223238
continue;
224239

225-
auto param_bits = pointer_offset_bits(param.type(), ns);
226-
if(param_bits.has_value())
227-
gen(from, identifier, 0, to_range_spect(*param_bits));
228-
else
229-
gen(from, identifier, 0, -1);
240+
std::cout << " param name: " << identifier << "\n";
241+
// get read set of the argument
242+
rw_set.set_expr_r_set();
243+
rw_set.get_objects_rec(from, rw_range_sett::get_modet::READ, *arg);
244+
std::cout << " argument set: \n";
245+
for(rw_range_sett::objectst::const_iterator
246+
it=(rw_set).get_expr_r_set().begin();
247+
it!=(rw_set).get_expr_r_set().end(); ++it)
248+
{
249+
std::cout << it->first << ":";
250+
const rd_range_domaint::ranges_at_loct &w_ranges = rd[from].get(it->first);
251+
for(const auto &w_range : w_ranges)
252+
{
253+
std::cerr << " further dep on: " << w_range.first->location_number << "\n";
254+
for(const auto &wr : w_range.second)
255+
gen(w_range.first, identifier, wr.first, wr.second);
256+
}
257+
}
258+
// next argument/parameter pair
259+
++param;
260+
++arg;
230261
}
231262
}
232263
else
@@ -313,8 +344,10 @@ void rd_range_domaint::transform_assign(
313344
locationt to,
314345
reaching_definitions_analysist &rd)
315346
{
347+
std::cerr << "\ntransform assign from " << from->location_number << " to " << to->location_number << "\n";
316348
rw_range_set_value_sett rw_set(ns, rd.get_value_sets());
317349
goto_rw(function_to, to, rw_set);
350+
rw_set.output(std::cerr);
318351
const bool is_must_alias=rw_set.get_w_set().size()==1;
319352

320353
forall_rw_range_set_w_objects(it, rw_set)

0 commit comments

Comments
 (0)