in include/MonotonicFixpointIterator.h [288:319]
void analyze_scc(Context* context, const WtoComponent<NodeId>& scc) {
NodeId head = scc.head_node();
bool iterate = true;
for (context->reset_local_iteration_count_for(head); iterate;
context->increase_iteration_count_for(head)) {
this->analyze_vertex(context, head);
for (const auto& component : scc) {
analyze_component(context, component);
}
// The current state of the iteration is represented by a pointer to the
// slot associated with the head node in the hash table of entry states.
// The state is updated in place within the hash table via side effects,
// which avoids costly copies and allocations.
Domain* current_state = &this->m_entry_states[head];
Domain new_state = Domain::bottom();
this->compute_entry_state(context, head, &new_state);
if (new_state.leq(*current_state)) {
// At this point we know that the monotonic iteration sequence has
// converged and current_state is a post-fixpoint. However, since all
// the node and edge transformers are monotonic, new_state is also a
// post-fixpoint (this is essentially the argument for performing a
// decreasing iteration sequence with narrowing after a post-fixpoint
// has been reached using an increasing iteration sequence with
// widening). Since new_state may be more precise than current_state,
// it's better to use it as the final result of the iteration sequence.
*current_state = std::move(new_state);
iterate = false;
} else {
this->extrapolate(*context, head, current_state, new_state);
}
}
}