Skip to content
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

Refactor the "TraverseState" out to make it easier to review future CL for performance improvement. This is (almost) a no-op change. #1854

Merged
merged 1 commit into from
Dec 17, 2024
Merged
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
61 changes: 36 additions & 25 deletions pytype/typegraph/solver.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,20 @@ struct RemoveResult {
removed_goals(removed_goals), new_goals(new_goals) {}
};

struct TraverseState {
GoalSet goals_to_remove;
GoalSet seen_goals;
GoalSet removed_goals;
GoalSet new_goals;
TraverseState() {}
TraverseState(GoalSet goals_to_remove, GoalSet seen_goals,
GoalSet removed_goals, GoalSet new_goals)
: goals_to_remove(goals_to_remove),
seen_goals(seen_goals),
removed_goals(removed_goals),
new_goals(new_goals) {}
};

// Remove all goals that can be fulfilled at the current CFG node.
// Generates all possible sets of new goals obtained by replacing a goal that
// originates at the current node with one of its source sets, iteratively,
Expand All @@ -39,51 +53,48 @@ struct RemoveResult {
// avoiding bugs related to transmitting state information across calls.
static std::vector<RemoveResult> remove_finished_goals(const CFGNode* pos,
const GoalSet& goals) {
GoalSet goals_to_remove;
TraverseState state;
// We can't use set_intersection here because pos->bindings() is a vector.
for (const auto* goal : pos->bindings()) {
if (goals.count(goal)) {
goals_to_remove.insert(goal);
state.goals_to_remove.insert(goal);
}
}
GoalSet seen_goals;
GoalSet removed_goals;
GoalSet new_goals;
std::set_difference(goals.begin(), goals.end(),
goals_to_remove.begin(), goals_to_remove.end(),
std::inserter(new_goals, new_goals.begin()),
std::set_difference(goals.begin(), goals.end(), state.goals_to_remove.begin(),
state.goals_to_remove.end(),
std::inserter(state.new_goals, state.new_goals.begin()),
pointer_less<Binding>());
std::deque<std::tuple<GoalSet, GoalSet, GoalSet, GoalSet>> queue;
queue.emplace_back(goals_to_remove, seen_goals, removed_goals, new_goals);
std::deque<TraverseState> queue;
queue.emplace_back(state);
std::vector<RemoveResult> results;
while (!queue.empty()) {
std::tie(goals_to_remove, seen_goals, removed_goals, new_goals) =
queue.front();
state = std::move(queue.front());
queue.pop_front();
if (goals_to_remove.empty()) {
results.push_back(RemoveResult(removed_goals, new_goals));
if (state.goals_to_remove.empty()) {
results.push_back(RemoveResult(state.removed_goals, state.new_goals));
continue;
}
const auto* goal = *goals_to_remove.begin();
goals_to_remove.erase(goals_to_remove.begin());
if (seen_goals.count(goal)) {
const auto* goal = *state.goals_to_remove.begin();
state.goals_to_remove.erase(state.goals_to_remove.begin());
if (state.seen_goals.count(goal)) {
// Only process a goal once, to prevent infinite loops.
queue.emplace_back(goals_to_remove, seen_goals, removed_goals, new_goals);
queue.emplace_back(std::move(state));
continue;
}
seen_goals.insert(goal);
state.seen_goals.insert(goal);
const auto* origin = goal->FindOrigin(pos);
if (!origin) {
new_goals.insert(goal);
queue.emplace_back(goals_to_remove, seen_goals, removed_goals, new_goals);
state.new_goals.insert(goal);
queue.emplace_back(std::move(state));
continue;
}
removed_goals.insert(goal);
state.removed_goals.insert(goal);
for (const auto& source_set : origin->source_sets) {
GoalSet next_goals_to_remove(goals_to_remove);
GoalSet next_goals_to_remove(state.goals_to_remove);
next_goals_to_remove.insert(source_set.begin(), source_set.end());
queue.emplace_back(std::move(next_goals_to_remove), seen_goals,
removed_goals, new_goals);
queue.push_back(TraverseState(std::move(next_goals_to_remove),
state.seen_goals, state.removed_goals,
state.new_goals));
}
}
return results;
Expand Down
Loading