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