Skip to content

Commit e6f36d9

Browse files
author
kroening
committed
More efficient dominator computation
git-svn-id: svn+ssh://svn.cprover.org/srv/svn/cbmc/trunk@1857 6afb6bc1-c8e4-404c-8f48-9ae832c5b171
1 parent f4c7a69 commit e6f36d9

File tree

1 file changed

+32
-31
lines changed

1 file changed

+32
-31
lines changed

src/goto-instrument/cfg_dominators.cpp

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,6 @@ void cfg_dominatorst::initialise(const goto_programt& program)
3030
for(node_mapt::const_iterator e_it=node_map.begin();
3131
e_it!=node_map.end(); ++e_it)
3232
top.insert(e_it->first);
33-
34-
// initialise all entries to top
35-
for(node_mapt::iterator e_it=node_map.begin();
36-
e_it!=node_map.end(); ++e_it)
37-
e_it->second.dominators.insert(top.begin(), top.end());
3833
}
3934

4035
/*******************************************************************\
@@ -104,50 +99,56 @@ void cfg_dominatorst::fixedpoint(const goto_programt &program)
10499
goto_programt::const_targetst worklist;
105100

106101
entry_node = program.instructions.begin();
107-
worklist.push_back(entry_node);
108-
109-
while(worklist.size())
102+
nodet &n=node_map[entry_node];
103+
n.dominators.insert(entry_node);
104+
for(goto_programt::const_targetst::const_iterator
105+
s_it=n.successors.begin();
106+
s_it!=n.successors.end();
107+
++s_it)
108+
worklist.push_back(*s_it);
109+
110+
while(!worklist.empty())
110111
{
111112
// get node from worklist
112113
goto_programt::const_targett current=worklist.front();
113114
worklist.pop_front();
114115

116+
bool changed=false;
115117
nodet &node=node_map[current];
118+
if(node.dominators.empty())
119+
for(goto_programt::const_targetst::const_iterator
120+
p_it=node.predecessors.begin();
121+
!changed && p_it!=node.predecessors.end();
122+
++p_it)
123+
if(!node_map[*p_it].dominators.empty())
124+
{
125+
node.dominators=node_map[*p_it].dominators;
126+
node.dominators.insert(current);
127+
changed=true;
128+
}
116129

117130
// compute intersection of predecessors
118-
const_target_sett result;
119-
120131
for(goto_programt::const_targetst::const_iterator
121132
p_it=node.predecessors.begin();
122133
p_it!=node.predecessors.end();
123134
++p_it)
124135
{
125-
if(p_it==node.predecessors.begin())
126-
{
127-
result=node_map[*p_it].dominators;
128-
continue;
129-
}
130-
else
131-
{
132-
const const_target_sett &other=node_map[*p_it].dominators;
133-
const_target_sett::const_iterator r_it=result.begin();
134-
const_target_sett::const_iterator o_it=other.begin();
136+
const const_target_sett &other=node_map[*p_it].dominators;
137+
const_target_sett::const_iterator n_it=node.dominators.begin();
138+
const_target_sett::const_iterator o_it=other.begin();
135139

136-
// in-place intersection. not safe to use set_intersect
137-
while(r_it!=result.end() && o_it!=other.end())
138-
{
139-
if(*r_it<*o_it) result.erase(r_it++);
140-
else if(*o_it<*r_it) ++o_it;
141-
else { ++r_it; ++o_it; }
142-
}
140+
// in-place intersection. not safe to use set_intersect
141+
while(n_it!=node.dominators.end() && o_it!=other.end())
142+
{
143+
if(*n_it==current) ++n_it;
144+
else if(*n_it<*o_it) { changed=true; node.dominators.erase(n_it++); }
145+
else if(*o_it<*n_it) ++o_it;
146+
else { ++n_it; ++o_it; }
143147
}
144148
}
145149

146-
result.insert(current);
147-
148-
if(node.dominators!=result) // fixed point for node reached?
150+
if(changed) // fixed point for node reached?
149151
{
150-
node.dominators=result;
151152
for(goto_programt::const_targetst::const_iterator
152153
s_it=node.successors.begin();
153154
s_it!=node.successors.end();

0 commit comments

Comments
 (0)