Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(120)

Unified Diff: src/compiler/control-reducer.cc

Issue 875263004: [turbofan] Ensure that NTLs are always properly connected to the end. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/control-reducer.h ('k') | src/compiler/instruction-selector.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/control-reducer.cc
diff --git a/src/compiler/control-reducer.cc b/src/compiler/control-reducer.cc
index 7f4bf317496270ce723f3adf46bd3b5a7e5d02e6..d40d414cfe1785ddb6f41e673af795432ba74a91 100644
--- a/src/compiler/control-reducer.cc
+++ b/src/compiler/control-reducer.cc
@@ -169,44 +169,80 @@ class ControlReducerImpl {
Node* ConnectNTL(Node* loop) {
TRACE(("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic()));
- if (loop->opcode() != IrOpcode::kTerminate) {
- // Insert a {Terminate} node if the loop has effects.
- ZoneDeque<Node*> effects(zone_);
- for (Node* const use : loop->uses()) {
- if (use->opcode() == IrOpcode::kEffectPhi) effects.push_back(use);
- }
- int count = static_cast<int>(effects.size());
- if (count > 0) {
- Node** inputs = zone_->NewArray<Node*>(1 + count);
- for (int i = 0; i < count; i++) inputs[i] = effects[i];
- inputs[count] = loop;
- loop = graph()->NewNode(common_->Terminate(count), 1 + count, inputs);
- TRACE(("AddTerminate: #%d:%s[%d]\n", loop->id(), loop->op()->mnemonic(),
- count));
+ Node* always = graph()->NewNode(common_->Always());
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(always);
+
+ Node* branch = graph()->NewNode(common_->Branch(), always, loop);
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(branch);
+
+ Node* if_true = graph()->NewNode(common_->IfTrue(), branch);
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(if_true);
+
+ Node* if_false = graph()->NewNode(common_->IfFalse(), branch);
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(if_false);
+
+ // Hook up the branch into the loop and collect all loop effects.
+ NodeVector effects(zone_);
+ for (auto edge : loop->use_edges()) {
+ DCHECK_EQ(loop, edge.to());
+ DCHECK(NodeProperties::IsControlEdge(edge));
+ if (edge.from() == branch) continue;
+ switch (edge.from()->opcode()) {
+#define CASE(Opcode) case IrOpcode::k##Opcode:
+ CONTROL_OP_LIST(CASE)
+#undef CASE
+ // Update all control nodes (except {branch}) pointing to the {loop}.
+ edge.UpdateTo(if_true);
+ break;
+ case IrOpcode::kEffectPhi:
+ effects.push_back(edge.from());
+ break;
+ default:
+ break;
}
}
- Node* to_add = loop;
+ // Compute effects for the Return.
+ Node* effect = graph()->start();
+ int const effects_count = static_cast<int>(effects.size());
+ if (effects_count == 1) {
+ effect = effects[0];
+ } else if (effects_count > 1) {
+ effect = graph()->NewNode(common_->EffectSet(effects_count),
+ effects_count, &effects.front());
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(effect);
+ }
+
+ // Add a return to connect the NTL to the end.
+ Node* ret = graph()->NewNode(
+ common_->Return(), jsgraph_->UndefinedConstant(), effect, if_false);
+ // Mark the node as visited so that we can revisit later.
+ MarkAsVisited(ret);
+
Node* end = graph()->end();
CHECK_EQ(IrOpcode::kEnd, end->opcode());
Node* merge = end->InputAt(0);
if (merge == NULL || merge->opcode() == IrOpcode::kDead) {
- // The end node died; just connect end to {loop}.
- end->ReplaceInput(0, loop);
+ // The end node died; just connect end to {ret}.
+ end->ReplaceInput(0, ret);
} else if (merge->opcode() != IrOpcode::kMerge) {
- // Introduce a final merge node for {end->InputAt(0)} and {loop}.
- merge = graph()->NewNode(common_->Merge(2), merge, loop);
+ // Introduce a final merge node for {end->InputAt(0)} and {ret}.
+ merge = graph()->NewNode(common_->Merge(2), merge, ret);
end->ReplaceInput(0, merge);
- to_add = merge;
+ ret = merge;
// Mark the node as visited so that we can revisit later.
- EnsureStateSize(merge->id());
- state_[merge->id()] = kVisited;
+ MarkAsVisited(merge);
} else {
// Append a new input to the final merge at the end.
- merge->AppendInput(graph()->zone(), loop);
+ merge->AppendInput(graph()->zone(), ret);
merge->set_op(common_->Merge(merge->InputCount()));
}
- return to_add;
+ return ret;
}
void AddNodesReachableFromEnd(ReachabilityMarker& marked, NodeVector& nodes) {
@@ -337,6 +373,13 @@ class ControlReducerImpl {
}
}
+ // Mark {node} as visited.
+ void MarkAsVisited(Node* node) {
+ size_t id = static_cast<size_t>(node->id());
+ EnsureStateSize(id);
+ state_[id] = kVisited;
+ }
+
Node* dead() {
if (dead_ == NULL) dead_ = graph()->NewNode(common_->Dead());
return dead_;
« no previous file with comments | « src/compiler/control-reducer.h ('k') | src/compiler/instruction-selector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698