Skip to content

Commit 1215d7f

Browse files
author
Daniel Kroening
authored
Merge pull request #487 from danpoe/dependence-graph-dominator-use-fix
Dependency graph fix to compute dominators per function
2 parents 88b87d3 + 21b049e commit 1215d7f

File tree

6 files changed

+80
-31
lines changed

6 files changed

+80
-31
lines changed

regression/goto-instrument/slice16/test.desc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CORE
1+
KNOWNBUG
22
main.c
33
--full-slice --unwind 2
44
^EXIT=0$

src/analyses/dependence_graph.cpp

+33-19
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ void dep_graph_domaint::control_dependencies(
9494
from->is_assume())
9595
control_deps.insert(from);
9696

97+
const irep_idt id=goto_programt::get_function_id(from);
98+
const cfg_post_dominatorst &pd=dep_graph.cfg_post_dominators().at(id);
99+
97100
// check all candidates for M
98101
for(depst::iterator
99102
it=control_deps.begin();
@@ -111,15 +114,17 @@ void dep_graph_domaint::control_dependencies(
111114
// we could hard-code assume and goto handling here to improve
112115
// performance
113116
cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e=
114-
dep_graph.cfg_post_dominators().cfg.entry_map.find(*it);
115-
assert(e!=dep_graph.cfg_post_dominators().cfg.entry_map.end());
117+
pd.cfg.entry_map.find(*it);
118+
119+
assert(e!=pd.cfg.entry_map.end());
120+
116121
const cfg_post_dominatorst::cfgt::nodet &m=
117-
dep_graph.cfg_post_dominators().cfg[e->second];
122+
pd.cfg[e->second];
118123

119124
for(const auto &edge : m.out)
120125
{
121126
const cfg_post_dominatorst::cfgt::nodet &m_s=
122-
dep_graph.cfg_post_dominators().cfg[edge.first];
127+
pd.cfg[edge.first];
123128

124129
if(m_s.dominators.find(to)!=m_s.dominators.end())
125130
post_dom_one=true;
@@ -252,30 +257,39 @@ void dep_graph_domaint::transform(
252257
const namespacet &ns)
253258
{
254259
dependence_grapht *dep_graph=dynamic_cast<dependence_grapht*>(&ai);
255-
assert(dep_graph!=0);
260+
assert(dep_graph!=nullptr);
256261

257262
// propagate control dependencies across function calls
258263
if(from->is_function_call())
259264
{
260265
goto_programt::const_targett next=from;
261266
++next;
262267

263-
dep_graph_domaint *s=
264-
dynamic_cast<dep_graph_domaint*>(&(dep_graph->get_state(next)));
265-
assert(s!=0);
266-
267-
depst::iterator it=s->control_deps.begin();
268-
for(const auto &c_dep : control_deps)
268+
if(next==to)
269269
{
270-
while(it!=s->control_deps.end() && *it<c_dep)
271-
++it;
272-
if(it==s->control_deps.end() || c_dep<*it)
273-
s->control_deps.insert(it, c_dep);
274-
else if(it!=s->control_deps.end())
275-
++it;
270+
control_dependencies(from, to, *dep_graph);
271+
}
272+
else
273+
{
274+
// edge to function entry point
275+
276+
dep_graph_domaint *s=
277+
dynamic_cast<dep_graph_domaint*>(&(dep_graph->get_state(next)));
278+
assert(s!=nullptr);
279+
280+
depst::iterator it=s->control_deps.begin();
281+
for(const auto &c_dep : control_deps)
282+
{
283+
while(it!=s->control_deps.end() && *it<c_dep)
284+
++it;
285+
if(it==s->control_deps.end() || c_dep<*it)
286+
s->control_deps.insert(it, c_dep);
287+
else if(it!=s->control_deps.end())
288+
++it;
289+
}
290+
291+
control_deps.clear();
276292
}
277-
278-
control_dependencies(from, next, *dep_graph);
279293
}
280294
else
281295
control_dependencies(from, to, *dep_graph);

src/analyses/dependence_graph.h

+11-3
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ class dependence_grapht:
154154
using ait<dep_graph_domaint>::operator[];
155155
using grapht<dep_nodet>::operator[];
156156

157+
typedef std::map<irep_idt, cfg_post_dominatorst> post_dominators_mapt;
158+
157159
explicit dependence_grapht(const namespacet &_ns):
158160
ns(_ns),
159161
rd(ns)
@@ -169,15 +171,21 @@ class dependence_grapht:
169171
void initialize(const goto_programt &goto_program)
170172
{
171173
ait<dep_graph_domaint>::initialize(goto_program);
172-
post_dominators(goto_program);
174+
175+
if(!goto_program.empty())
176+
{
177+
const irep_idt id=goto_programt::get_function_id(goto_program);
178+
cfg_post_dominatorst &pd=post_dominators[id];
179+
pd(goto_program);
180+
}
173181
}
174182

175183
void add_dep(
176184
dep_edget::kindt kind,
177185
goto_programt::const_targett from,
178186
goto_programt::const_targett to);
179187

180-
const cfg_post_dominatorst &cfg_post_dominators() const
188+
const post_dominators_mapt &cfg_post_dominators() const
181189
{
182190
return post_dominators;
183191
}
@@ -205,7 +213,7 @@ class dependence_grapht:
205213
protected:
206214
const namespacet &ns;
207215

208-
cfg_post_dominatorst post_dominators;
216+
post_dominators_mapt post_dominators;
209217
reaching_definitions_analysist rd;
210218
};
211219

src/goto-instrument/full_slicer.cpp

+17-7
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ Function: full_slicert::add_jumps
140140
void full_slicert::add_jumps(
141141
queuet &queue,
142142
jumpst &jumps,
143-
const cfg_post_dominatorst &cfg_post_dominators)
143+
const dependence_grapht::post_dominators_mapt &post_dominators)
144144
{
145145
// Based on:
146146
// On slicing programs with jump statements
@@ -197,11 +197,16 @@ void full_slicert::add_jumps(
197197
continue;
198198
}
199199

200+
const irep_idt id=goto_programt::get_function_id(j.PC);
201+
const cfg_post_dominatorst &pd=post_dominators.at(id);
202+
200203
cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e=
201-
cfg_post_dominators.cfg.entry_map.find(j.PC);
202-
assert(e!=cfg_post_dominators.cfg.entry_map.end());
204+
pd.cfg.entry_map.find(j.PC);
205+
206+
assert(e!=pd.cfg.entry_map.end());
207+
203208
const cfg_post_dominatorst::cfgt::nodet &n=
204-
cfg_post_dominators.cfg[e->second];
209+
pd.cfg[e->second];
205210

206211
// find the nearest post-dominator in slice
207212
if(n.dominators.find(lex_succ)==n.dominators.end())
@@ -226,11 +231,16 @@ void full_slicert::add_jumps(
226231

227232
if(cfg[entry->second].node_required)
228233
{
234+
const irep_idt id2=goto_programt::get_function_id(*d_it);
235+
assert(id==id2);
236+
229237
cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e2=
230-
cfg_post_dominators.cfg.entry_map.find(*d_it);
231-
assert(e2!=cfg_post_dominators.cfg.entry_map.end());
238+
pd.cfg.entry_map.find(*d_it);
239+
240+
assert(e2!=pd.cfg.entry_map.end());
241+
232242
const cfg_post_dominatorst::cfgt::nodet &n2=
233-
cfg_post_dominators.cfg[e2->second];
243+
pd.cfg[e2->second];
234244

235245
if(n2.dominators.size()>post_dom_size)
236246
{

src/goto-instrument/full_slicer_class.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class full_slicert
9595
void add_jumps(
9696
queuet &queue,
9797
jumpst &jumps,
98-
const cfg_post_dominatorst &cfg_post_dominators);
98+
const dependence_grapht::post_dominators_mapt &post_dominators);
9999

100100
void add_to_queue(
101101
queuet &queue,

src/goto-programs/goto_program_template.h

+17
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,23 @@ class goto_program_templatet
288288
return t;
289289
}
290290

291+
static const irep_idt get_function_id(
292+
const_targett l)
293+
{
294+
while(!l->is_end_function())
295+
l++;
296+
297+
return l->function;
298+
}
299+
300+
static const irep_idt get_function_id(
301+
const goto_program_templatet<codeT, guardT> &p)
302+
{
303+
assert(!p.empty());
304+
305+
return get_function_id(--p.instructions.end());
306+
}
307+
291308
void get_successors(
292309
targett target,
293310
targetst &successors);

0 commit comments

Comments
 (0)