@@ -37,6 +37,7 @@ bool dep_graph_domaint::merge(
37
37
}
38
38
39
39
changed |= util_set_union (control_deps, src.control_deps );
40
+ changed |= util_set_union (control_dep_candidates, src.control_dep_candidates );
40
41
41
42
return changed;
42
43
}
@@ -48,42 +49,54 @@ void dep_graph_domaint::control_dependencies(
48
49
{
49
50
// Better Slicing of Programs with Jumps and Switches
50
51
// Kumar and Horwitz, FASE'02:
51
- // Node N is control dependent on node M iff N postdominates one
52
- // but not all of M's CFG successors.
52
+ // " Node N is control dependent on node M iff N postdominates, in
53
+ // the CFG, one but not all of M's CFG successors."
53
54
//
54
- // candidates for M are from and all existing control-depended on
55
- // nodes; from is added if it is a goto or assume instruction
56
- if (from->is_goto () ||
57
- from->is_assume ())
58
- control_deps.insert (from);
55
+ // The "successor" above refers to an immediate successor of M.
56
+ //
57
+ // When computing the control dependencies of a node N (i.e., "to"
58
+ // being N), candidates for M are all control statements (gotos or
59
+ // assumes) from which there is a path in the CFG to N.
60
+
61
+ // Add new candidates
62
+
63
+ if (from->is_goto () || from->is_assume ())
64
+ control_dep_candidates.insert (from);
65
+ else if (from->is_end_function ())
66
+ {
67
+ control_dep_candidates.clear ();
68
+ return ;
69
+ }
70
+
71
+ if (control_dep_candidates.empty ())
72
+ return ;
73
+
74
+ // Get postdominators
59
75
60
76
const irep_idt id=from->function ;
61
77
const cfg_post_dominatorst &pd=dep_graph.cfg_post_dominators ().at (id);
62
78
63
- // check all candidates for M
64
- for (depst::iterator
65
- it=control_deps.begin ();
66
- it!=control_deps.end ();
67
- ) // no ++it
68
- {
69
- depst::iterator next=it;
70
- ++next;
79
+ // Check all candidates
71
80
72
- // check all CFG successors
81
+ for (const auto &control_dep_candidate : control_dep_candidates)
82
+ {
83
+ // check all CFG successors of M
73
84
// special case: assumptions also introduce a control dependency
74
- bool post_dom_all=!(*it) ->is_assume ();
85
+ bool post_dom_all = !control_dep_candidate ->is_assume ();
75
86
bool post_dom_one=false ;
76
87
77
88
// we could hard-code assume and goto handling here to improve
78
89
// performance
79
- cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e=
80
- pd.cfg .entry_map .find (*it );
90
+ cfg_post_dominatorst::cfgt::entry_mapt::const_iterator e =
91
+ pd.cfg .entry_map .find (control_dep_candidate );
81
92
82
- assert (e!=pd.cfg .entry_map .end ());
93
+ INVARIANT (
94
+ e != pd.cfg .entry_map .end (), " cfg must have an entry for every location" );
83
95
84
96
const cfg_post_dominatorst::cfgt::nodet &m=
85
97
pd.cfg [e->second ];
86
98
99
+ // successors of M
87
100
for (const auto &edge : m.out )
88
101
{
89
102
const cfg_post_dominatorst::cfgt::nodet &m_s=
@@ -95,11 +108,14 @@ void dep_graph_domaint::control_dependencies(
95
108
post_dom_all=false ;
96
109
}
97
110
98
- if (post_dom_all ||
99
- !post_dom_one)
100
- control_deps.erase (it);
101
-
102
- it=next;
111
+ if (post_dom_all || !post_dom_one)
112
+ {
113
+ control_deps.erase (control_dep_candidate);
114
+ }
115
+ else
116
+ {
117
+ control_deps.insert (control_dep_candidate);
118
+ }
103
119
}
104
120
}
105
121
@@ -190,7 +206,10 @@ void dep_graph_domaint::transform(
190
206
assert (s!=nullptr );
191
207
192
208
util_set_union (s->control_deps , control_deps);
209
+ util_set_union (s->control_dep_candidates , control_dep_candidates);
210
+
193
211
control_deps.clear ();
212
+ control_dep_candidates.clear ();
194
213
}
195
214
}
196
215
else
0 commit comments