Commit 5602ce8b authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[compiler] Have one traversal container for SimplifiedLowering's phases

Since now all phases have the same order (or the reverse) we can share
only one container that would specify the traversal order.

We still need a queue that will be used for revisiting purposes in
PROPAGATE and RETYPE.

Bug: v8:10424
Change-Id: Iab1e3c3cf6ffd342240d43be3b8ac77812aff211
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2154201
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68008}
parent 1ccb6d10
...@@ -291,11 +291,10 @@ class RepresentationSelector { ...@@ -291,11 +291,10 @@ class RepresentationSelector {
#ifdef DEBUG #ifdef DEBUG
node_input_use_infos_(count_, InputUseInfos(zone), zone), node_input_use_infos_(count_, InputUseInfos(zone), zone),
#endif #endif
nodes_(zone),
replacements_(zone), replacements_(zone),
changer_(changer), changer_(changer),
queue_(zone), revisit_queue_(zone),
typing_stack_(zone), traversal_nodes_(zone),
source_positions_(source_positions), source_positions_(source_positions),
node_origins_(node_origins), node_origins_(node_origins),
type_cache_(TypeCache::Get()), type_cache_(TypeCache::Get()),
...@@ -308,13 +307,11 @@ class RepresentationSelector { ...@@ -308,13 +307,11 @@ class RepresentationSelector {
// Run type propagation. // Run type propagation.
TRACE("--{Type propagation phase}--\n"); TRACE("--{Type propagation phase}--\n");
ResetNodeInfoState(); ResetNodeInfoState();
DCHECK(revisit_queue_.empty());
while (!typing_stack_.empty()) { for (auto it = traversal_nodes_.cbegin(); it != traversal_nodes_.cend();
NodeState& current = typing_stack_.front(); ++it) {
Node* node = *it;
// Process the top of the stack.
Node* node = current.node;
typing_stack_.pop_front();
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
info->set_visited(); info->set_visited();
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
...@@ -324,23 +321,23 @@ class RepresentationSelector { ...@@ -324,23 +321,23 @@ class RepresentationSelector {
PrintOutputInfo(info); PrintOutputInfo(info);
TRACE("\n"); TRACE("\n");
if (updated) { if (updated) {
auto it = might_need_revisit_.find(node); auto revisit_it = might_need_revisit_.find(node);
if (it == might_need_revisit_.end()) continue; if (revisit_it == might_need_revisit_.end()) continue;
for (Node* const user : it->second) { for (Node* const user : revisit_it->second) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
TRACE(" QUEUEING #%d: %s\n", user->id(), user->op()->mnemonic()); TRACE(" QUEUEING #%d: %s\n", user->id(), user->op()->mnemonic());
GetInfo(user)->set_queued(); GetInfo(user)->set_queued();
queue_.push_back(user); revisit_queue_.push(user);
} }
} }
} }
} }
// Process the revisit queue. // Process the revisit queue.
while (!queue_.empty()) { while (!revisit_queue_.empty()) {
Node* node = queue_.front(); Node* node = revisit_queue_.front();
queue_.pop_front(); revisit_queue_.pop();
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
info->set_visited(); info->set_visited();
bool updated = UpdateFeedbackType(node); bool updated = UpdateFeedbackType(node);
...@@ -350,14 +347,14 @@ class RepresentationSelector { ...@@ -350,14 +347,14 @@ class RepresentationSelector {
PrintOutputInfo(info); PrintOutputInfo(info);
TRACE("\n"); TRACE("\n");
if (updated) { if (updated) {
// Here we need to check all uses since we can't easily know which nodes // Here we need to check all uses since we can't easily know which
// will need to be revisited due to having an input which was a // nodes will need to be revisited due to having an input which was
// revisited node. // a revisited node.
for (Node* const user : node->uses()) { for (Node* const user : node->uses()) {
if (GetInfo(user)->visited()) { if (GetInfo(user)->visited()) {
TRACE(" QUEUEING #%d: %s\n", user->id(), user->op()->mnemonic()); TRACE(" QUEUEING #%d: %s\n", user->id(), user->op()->mnemonic());
GetInfo(user)->set_queued(); GetInfo(user)->set_queued();
queue_.push_back(user); revisit_queue_.push(user);
} }
} }
} }
...@@ -586,11 +583,24 @@ class RepresentationSelector { ...@@ -586,11 +583,24 @@ class RepresentationSelector {
// Run propagation phase to a fixpoint. // Run propagation phase to a fixpoint.
TRACE("--{Propagation phase}--\n"); TRACE("--{Propagation phase}--\n");
ResetNodeInfoState(); ResetNodeInfoState();
// Process nodes from the queue until it is empty. DCHECK(revisit_queue_.empty());
while (!queue_.empty()) {
Node* node = queue_.front(); // Process nodes in reverse post order, with End as the root.
for (auto it = traversal_nodes_.crbegin(); it != traversal_nodes_.crend();
++it) {
Node* node = *it;
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
queue_.pop_front(); info->set_visited();
TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
info->truncation().description());
VisitNode<PROPAGATE>(node, info->truncation(), nullptr);
}
// Revisit queue
while (!revisit_queue_.empty()) {
Node* node = revisit_queue_.front();
NodeInfo* info = GetInfo(node);
revisit_queue_.pop();
info->set_visited(); info->set_visited();
TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(), TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
info->truncation().description()); info->truncation().description());
...@@ -598,19 +608,20 @@ class RepresentationSelector { ...@@ -598,19 +608,20 @@ class RepresentationSelector {
} }
} }
// Generates a pre-order traversal of the nodes, starting with End.
void GenerateTraversal() { void GenerateTraversal() {
// Temporary stack
ZoneStack<NodeState> stack(zone_); ZoneStack<NodeState> stack(zone_);
stack.push({graph()->end(), 0}); stack.push({graph()->end(), 0});
GetInfo(graph()->end())->set_pushed(); GetInfo(graph()->end())->set_pushed();
while (!stack.empty()) { while (!stack.empty()) {
NodeState& current = stack.top(); NodeState& current = stack.top();
Node* node = current.node;
// If there is an unvisited input, push it and continue. // If there is an unvisited input, push it and continue with that node.
bool pushed_unvisited = false; bool pushed_unvisited = false;
while (current.input_index < current.node->InputCount()) { while (current.input_index < node->InputCount()) {
Node* input = current.node->InputAt(current.input_index); Node* input = node->InputAt(current.input_index);
NodeInfo* input_info = GetInfo(input); NodeInfo* input_info = GetInfo(input);
current.input_index++; current.input_index++;
if (input_info->unvisited()) { if (input_info->unvisited()) {
...@@ -619,24 +630,23 @@ class RepresentationSelector { ...@@ -619,24 +630,23 @@ class RepresentationSelector {
pushed_unvisited = true; pushed_unvisited = true;
break; break;
} else if (input_info->pushed()) { } else if (input_info->pushed()) {
// Optimization for the Retype phase.
// If we had already pushed (and not visited) an input, it means that // If we had already pushed (and not visited) an input, it means that
// the current node will be visited before one of its inputs. If this // the current node will be visited in the Retype phase before one of
// happens, the current node might need to be revisited. // its inputs. If this happens, the current node might need to be
MarkAsPossibleRevisit(current.node, input); // revisited.
MarkAsPossibleRevisit(node, input);
} }
} }
if (pushed_unvisited) continue; if (pushed_unvisited) continue;
Node* node = current.node;
stack.pop(); stack.pop();
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
info->set_visited(); info->set_visited();
// Generate the traversal // Generate the traversal
typing_stack_.push_back({node, 0}); traversal_nodes_.push_back(node);
queue_.push_front(node);
nodes_.push_back(node);
} }
} }
...@@ -649,9 +659,9 @@ class RepresentationSelector { ...@@ -649,9 +659,9 @@ class RepresentationSelector {
// Run lowering and change insertion phase. // Run lowering and change insertion phase.
TRACE("--{Simplified lowering phase}--\n"); TRACE("--{Simplified lowering phase}--\n");
// Process nodes from the collected {nodes_} vector. for (auto it = traversal_nodes_.cbegin(); it != traversal_nodes_.cend();
for (NodeVector::iterator i = nodes_.begin(); i != nodes_.end(); ++i) { ++it) {
Node* node = *i; Node* node = *it;
NodeInfo* info = GetInfo(node); NodeInfo* info = GetInfo(node);
TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
// Reuse {VisitNode()} so the representation rules are in one place. // Reuse {VisitNode()} so the representation rules are in one place.
...@@ -3807,16 +3817,15 @@ class RepresentationSelector { ...@@ -3807,16 +3817,15 @@ class RepresentationSelector {
ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about
// requirements on inputs. // requirements on inputs.
#endif // DEBUG #endif // DEBUG
NodeVector nodes_; // collected nodes
NodeVector replacements_; // replacements to be done after lowering NodeVector replacements_; // replacements to be done after lowering
RepresentationChanger* changer_; // for inserting representation changes RepresentationChanger* changer_; // for inserting representation changes
ZoneDeque<Node*> queue_; // Deque for revisiting nodes. ZoneQueue<Node*> revisit_queue_; // Queue for revisiting nodes.
struct NodeState { struct NodeState {
Node* node; Node* node;
int input_index; int input_index;
}; };
ZoneDeque<NodeState> typing_stack_; // Deque for graph typing. NodeVector traversal_nodes_; // Order in which to traverse the nodes.
// TODO(danno): RepresentationSelector shouldn't know anything about the // TODO(danno): RepresentationSelector shouldn't know anything about the
// source positions table, but must for now since there currently is no other // source positions table, but must for now since there currently is no other
// way to pass down source position information to nodes created during // way to pass down source position information to nodes created during
...@@ -3839,8 +3848,7 @@ class RepresentationSelector { ...@@ -3839,8 +3848,7 @@ class RepresentationSelector {
// Template specializations // Template specializations
// Enqueue {use_node}'s {index} input if the {use_info} contains new information // Enqueue {use_node}'s {index} input if the {use_info} contains new information
// for that input node. Add the input to {nodes_} if this is the first time it's // for that input node.
// been visited.
template <> template <>
void RepresentationSelector::EnqueueInput<PROPAGATE>(Node* use_node, int index, void RepresentationSelector::EnqueueInput<PROPAGATE>(Node* use_node, int index,
UseInfo use_info) { UseInfo use_info) {
...@@ -3865,7 +3873,7 @@ void RepresentationSelector::EnqueueInput<PROPAGATE>(Node* use_node, int index, ...@@ -3865,7 +3873,7 @@ void RepresentationSelector::EnqueueInput<PROPAGATE>(Node* use_node, int index,
// New usage information for the node is available. // New usage information for the node is available.
if (!info->queued()) { if (!info->queued()) {
DCHECK(info->visited()); DCHECK(info->visited());
queue_.push_back(node); revisit_queue_.push(node);
info->set_queued(); info->set_queued();
TRACE(" added: "); TRACE(" added: ");
} else { } else {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment