@@ -31,6 +31,20 @@ struct RemoveResult {
31
31
removed_goals (removed_goals), new_goals(new_goals) {}
32
32
};
33
33
34
+ struct TraverseState {
35
+ GoalSet goals_to_remove;
36
+ GoalSet seen_goals;
37
+ GoalSet removed_goals;
38
+ GoalSet new_goals;
39
+ TraverseState () {}
40
+ TraverseState (GoalSet goals_to_remove, GoalSet seen_goals,
41
+ GoalSet removed_goals, GoalSet new_goals)
42
+ : goals_to_remove(goals_to_remove),
43
+ seen_goals (seen_goals),
44
+ removed_goals(removed_goals),
45
+ new_goals(new_goals) {}
46
+ };
47
+
34
48
// Remove all goals that can be fulfilled at the current CFG node.
35
49
// Generates all possible sets of new goals obtained by replacing a goal that
36
50
// originates at the current node with one of its source sets, iteratively,
@@ -39,51 +53,48 @@ struct RemoveResult {
39
53
// avoiding bugs related to transmitting state information across calls.
40
54
static std::vector<RemoveResult> remove_finished_goals (const CFGNode* pos,
41
55
const GoalSet& goals) {
42
- GoalSet goals_to_remove ;
56
+ TraverseState state ;
43
57
// We can't use set_intersection here because pos->bindings() is a vector.
44
58
for (const auto * goal : pos->bindings ()) {
45
59
if (goals.count (goal)) {
46
- goals_to_remove.insert (goal);
60
+ state. goals_to_remove .insert (goal);
47
61
}
48
62
}
49
- GoalSet seen_goals;
50
- GoalSet removed_goals;
51
- GoalSet new_goals;
52
- std::set_difference (goals.begin (), goals.end (),
53
- goals_to_remove.begin (), goals_to_remove.end (),
54
- std::inserter (new_goals, new_goals.begin ()),
63
+ std::set_difference (goals.begin (), goals.end (), state.goals_to_remove .begin (),
64
+ state.goals_to_remove .end (),
65
+ std::inserter (state.new_goals , state.new_goals .begin ()),
55
66
pointer_less<Binding>());
56
- std::deque<std::tuple<GoalSet, GoalSet, GoalSet, GoalSet> > queue;
57
- queue.emplace_back (goals_to_remove, seen_goals, removed_goals, new_goals );
67
+ std::deque<TraverseState > queue;
68
+ queue.emplace_back (state );
58
69
std::vector<RemoveResult> results;
59
70
while (!queue.empty ()) {
60
- std::tie (goals_to_remove, seen_goals, removed_goals, new_goals) =
61
- queue.front ();
71
+ state = std::move (queue.front ());
62
72
queue.pop_front ();
63
- if (goals_to_remove.empty ()) {
64
- results.push_back (RemoveResult (removed_goals, new_goals));
73
+ if (state. goals_to_remove .empty ()) {
74
+ results.push_back (RemoveResult (state. removed_goals , state. new_goals ));
65
75
continue ;
66
76
}
67
- const auto * goal = *goals_to_remove.begin ();
68
- goals_to_remove.erase (goals_to_remove.begin ());
69
- if (seen_goals.count (goal)) {
77
+ const auto * goal = *state. goals_to_remove .begin ();
78
+ state. goals_to_remove .erase (state. goals_to_remove .begin ());
79
+ if (state. seen_goals .count (goal)) {
70
80
// Only process a goal once, to prevent infinite loops.
71
- queue.emplace_back (goals_to_remove, seen_goals, removed_goals, new_goals );
81
+ queue.emplace_back (std::move (state) );
72
82
continue ;
73
83
}
74
- seen_goals.insert (goal);
84
+ state. seen_goals .insert (goal);
75
85
const auto * origin = goal->FindOrigin (pos);
76
86
if (!origin) {
77
- new_goals.insert (goal);
78
- queue.emplace_back (goals_to_remove, seen_goals, removed_goals, new_goals );
87
+ state. new_goals .insert (goal);
88
+ queue.emplace_back (std::move (state) );
79
89
continue ;
80
90
}
81
- removed_goals.insert (goal);
91
+ state. removed_goals .insert (goal);
82
92
for (const auto & source_set : origin->source_sets ) {
83
- GoalSet next_goals_to_remove (goals_to_remove);
93
+ GoalSet next_goals_to_remove (state. goals_to_remove );
84
94
next_goals_to_remove.insert (source_set.begin (), source_set.end ());
85
- queue.emplace_back (std::move (next_goals_to_remove), seen_goals,
86
- removed_goals, new_goals);
95
+ queue.push_back (TraverseState (std::move (next_goals_to_remove),
96
+ state.seen_goals , state.removed_goals ,
97
+ state.new_goals ));
87
98
}
88
99
}
89
100
return results;
0 commit comments