Skip to content

Dependency graph fix to compute dominators per function #487

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 18, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion regression/goto-instrument/slice16/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CORE
KNOWNBUG
main.c
--full-slice --unwind 2
^EXIT=0$
Expand Down
52 changes: 33 additions & 19 deletions src/analyses/dependence_graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,9 @@ void dep_graph_domaint::control_dependencies(
from->is_assume())
control_deps.insert(from);

const irep_idt id=goto_programt::get_function_id(from);
const cfg_post_dominatorst &pd=dep_graph.cfg_post_dominators().at(id);

// check all candidates for M
for(depst::iterator
it=control_deps.begin();
Expand All @@ -111,15 +114,17 @@ void dep_graph_domaint::control_dependencies(
// we could hard-code assume and goto handling here to improve
// performance
cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e=
dep_graph.cfg_post_dominators().cfg.entry_map.find(*it);
assert(e!=dep_graph.cfg_post_dominators().cfg.entry_map.end());
pd.cfg.entry_map.find(*it);

assert(e!=pd.cfg.entry_map.end());

const cfg_post_dominatorst::cfgt::nodet &m=
dep_graph.cfg_post_dominators().cfg[e->second];
pd.cfg[e->second];

for(const auto &edge : m.out)
{
const cfg_post_dominatorst::cfgt::nodet &m_s=
dep_graph.cfg_post_dominators().cfg[edge.first];
pd.cfg[edge.first];

if(m_s.dominators.find(to)!=m_s.dominators.end())
post_dom_one=true;
Expand Down Expand Up @@ -252,30 +257,39 @@ void dep_graph_domaint::transform(
const namespacet &ns)
{
dependence_grapht *dep_graph=dynamic_cast<dependence_grapht*>(&ai);
assert(dep_graph!=0);
assert(dep_graph!=nullptr);

// propagate control dependencies across function calls
if(from->is_function_call())
{
goto_programt::const_targett next=from;
++next;

dep_graph_domaint *s=
dynamic_cast<dep_graph_domaint*>(&(dep_graph->get_state(next)));
assert(s!=0);

depst::iterator it=s->control_deps.begin();
for(const auto &c_dep : control_deps)
if(next==to)
{
while(it!=s->control_deps.end() && *it<c_dep)
++it;
if(it==s->control_deps.end() || c_dep<*it)
s->control_deps.insert(it, c_dep);
else if(it!=s->control_deps.end())
++it;
control_dependencies(from, to, *dep_graph);
}
else
{
// edge to function entry point

dep_graph_domaint *s=
dynamic_cast<dep_graph_domaint*>(&(dep_graph->get_state(next)));
assert(s!=nullptr);

depst::iterator it=s->control_deps.begin();
for(const auto &c_dep : control_deps)
{
while(it!=s->control_deps.end() && *it<c_dep)
++it;
if(it==s->control_deps.end() || c_dep<*it)
s->control_deps.insert(it, c_dep);
else if(it!=s->control_deps.end())
++it;
}

control_deps.clear();
}

control_dependencies(from, next, *dep_graph);
}
else
control_dependencies(from, to, *dep_graph);
Expand Down
14 changes: 11 additions & 3 deletions src/analyses/dependence_graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ class dependence_grapht:
using ait<dep_graph_domaint>::operator[];
using grapht<dep_nodet>::operator[];

typedef std::map<irep_idt, cfg_post_dominatorst> post_dominators_mapt;

explicit dependence_grapht(const namespacet &_ns):
ns(_ns),
rd(ns)
Expand All @@ -169,15 +171,21 @@ class dependence_grapht:
void initialize(const goto_programt &goto_program)
{
ait<dep_graph_domaint>::initialize(goto_program);
post_dominators(goto_program);

if(!goto_program.empty())
{
const irep_idt id=goto_programt::get_function_id(goto_program);
cfg_post_dominatorst &pd=post_dominators[id];
pd(goto_program);
}
}

void add_dep(
dep_edget::kindt kind,
goto_programt::const_targett from,
goto_programt::const_targett to);

const cfg_post_dominatorst &cfg_post_dominators() const
const post_dominators_mapt &cfg_post_dominators() const
{
return post_dominators;
}
Expand Down Expand Up @@ -205,7 +213,7 @@ class dependence_grapht:
protected:
const namespacet &ns;

cfg_post_dominatorst post_dominators;
post_dominators_mapt post_dominators;
reaching_definitions_analysist rd;
};

Expand Down
24 changes: 17 additions & 7 deletions src/goto-instrument/full_slicer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Function: full_slicert::add_jumps
void full_slicert::add_jumps(
queuet &queue,
jumpst &jumps,
const cfg_post_dominatorst &cfg_post_dominators)
const dependence_grapht::post_dominators_mapt &post_dominators)
{
// Based on:
// On slicing programs with jump statements
Expand Down Expand Up @@ -197,11 +197,16 @@ void full_slicert::add_jumps(
continue;
}

const irep_idt id=goto_programt::get_function_id(j.PC);
const cfg_post_dominatorst &pd=post_dominators.at(id);

cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e=
cfg_post_dominators.cfg.entry_map.find(j.PC);
assert(e!=cfg_post_dominators.cfg.entry_map.end());
pd.cfg.entry_map.find(j.PC);

assert(e!=pd.cfg.entry_map.end());

const cfg_post_dominatorst::cfgt::nodet &n=
cfg_post_dominators.cfg[e->second];
pd.cfg[e->second];

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

if(cfg[entry->second].node_required)
{
const irep_idt id2=goto_programt::get_function_id(*d_it);
assert(id==id2);

cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e2=
cfg_post_dominators.cfg.entry_map.find(*d_it);
assert(e2!=cfg_post_dominators.cfg.entry_map.end());
pd.cfg.entry_map.find(*d_it);

assert(e2!=pd.cfg.entry_map.end());

const cfg_post_dominatorst::cfgt::nodet &n2=
cfg_post_dominators.cfg[e2->second];
pd.cfg[e2->second];

if(n2.dominators.size()>post_dom_size)
{
Expand Down
2 changes: 1 addition & 1 deletion src/goto-instrument/full_slicer_class.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class full_slicert
void add_jumps(
queuet &queue,
jumpst &jumps,
const cfg_post_dominatorst &cfg_post_dominators);
const dependence_grapht::post_dominators_mapt &post_dominators);

void add_to_queue(
queuet &queue,
Expand Down
17 changes: 17 additions & 0 deletions src/goto-programs/goto_program_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,23 @@ class goto_program_templatet
return t;
}

static const irep_idt get_function_id(
const_targett l)
{
while(!l->is_end_function())
l++;

return l->function;
}

static const irep_idt get_function_id(
const goto_program_templatet<codeT, guardT> &p)
{
assert(!p.empty());

return get_function_id(--p.instructions.end());
}

void get_successors(
targett target,
targetst &successors);
Expand Down