| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
| 6 #include "src/compiler/control-reducer.h" | 6 #include "src/compiler/control-reducer.h" |
| 7 #include "src/compiler/graph.h" | 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/graph-reducer.h" | 8 #include "src/compiler/graph-reducer.h" |
| 9 #include "src/compiler/js-graph.h" | 9 #include "src/compiler/js-graph.h" |
| 10 #include "src/compiler/node-marker.h" | 10 #include "src/compiler/node-marker.h" |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 Node* dead() { return jsgraph_->DeadControl(); } | 40 Node* dead() { return jsgraph_->DeadControl(); } |
| 41 | 41 |
| 42 //=========================================================================== | 42 //=========================================================================== |
| 43 // Reducer implementation: perform reductions on a node. | 43 // Reducer implementation: perform reductions on a node. |
| 44 //=========================================================================== | 44 //=========================================================================== |
| 45 Reduction Reduce(Node* node) override { | 45 Reduction Reduce(Node* node) override { |
| 46 if (node->op()->ControlInputCount() == 1 || | 46 if (node->op()->ControlInputCount() == 1 || |
| 47 node->opcode() == IrOpcode::kLoop) { | 47 node->opcode() == IrOpcode::kLoop) { |
| 48 // If a node has only one control input and it is dead, replace with dead. | 48 // If a node has only one control input and it is dead, replace with dead. |
| 49 Node* control = NodeProperties::GetControlInput(node); | 49 Node* control = NodeProperties::GetControlInput(node); |
| 50 if (control->opcode() == IrOpcode::kDead) { | 50 if (control->opcode() == IrOpcode::kDeadControl) { |
| 51 TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()); | 51 TRACE("ControlDead: #%d:%s\n", node->id(), node->op()->mnemonic()); |
| 52 return Replace(control); | 52 return Replace(control); |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 | 55 |
| 56 Node* result = node; | 56 Node* result = node; |
| 57 // Reduce branches, phis, and merges. | 57 // Reduce branches, phis, and merges. |
| 58 switch (node->opcode()) { | 58 switch (node->opcode()) { |
| 59 case IrOpcode::kBranch: | 59 case IrOpcode::kBranch: |
| 60 result = ReduceBranch(node); | 60 result = ReduceBranch(node); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 // Reduce redundant phis. | 131 // Reduce redundant phis. |
| 132 Node* ReducePhi(Node* node) { | 132 Node* ReducePhi(Node* node) { |
| 133 int n = node->InputCount(); | 133 int n = node->InputCount(); |
| 134 if (n <= 1) return dead(); // No non-control inputs. | 134 if (n <= 1) return dead(); // No non-control inputs. |
| 135 if (n == 2) return node->InputAt(0); // Only one non-control input. | 135 if (n == 2) return node->InputAt(0); // Only one non-control input. |
| 136 | 136 |
| 137 Node* replacement = NULL; | 137 Node* replacement = NULL; |
| 138 auto const inputs = node->inputs(); | 138 auto const inputs = node->inputs(); |
| 139 for (auto it = inputs.begin(); n > 1; --n, ++it) { | 139 for (auto it = inputs.begin(); n > 1; --n, ++it) { |
| 140 Node* input = *it; | 140 Node* input = *it; |
| 141 if (input->opcode() == IrOpcode::kDead) continue; // ignore dead inputs. | 141 // Ignore dead inputs. |
| 142 if (input != node && input != replacement) { // non-redundant input. | 142 if (input->opcode() == IrOpcode::kDeadControl) continue; |
| 143 // Non-redundant input. |
| 144 if (input != node && input != replacement) { |
| 143 if (replacement != NULL) return node; | 145 if (replacement != NULL) return node; |
| 144 replacement = input; | 146 replacement = input; |
| 145 } | 147 } |
| 146 } | 148 } |
| 147 return replacement == NULL ? dead() : replacement; | 149 return replacement == NULL ? dead() : replacement; |
| 148 } | 150 } |
| 149 | 151 |
| 150 // Reduce branches. | 152 // Reduce branches. |
| 151 Node* ReduceBranch(Node* branch) { | 153 Node* ReduceBranch(Node* branch) { |
| 152 if (DecideCondition(branch->InputAt(0)) != kUnknown) { | 154 if (DecideCondition(branch->InputAt(0)) != kUnknown) { |
| 153 for (Node* use : branch->uses()) Revisit(use); | 155 for (Node* use : branch->uses()) Revisit(use); |
| 154 } | 156 } |
| 155 return branch; | 157 return branch; |
| 156 } | 158 } |
| 157 | 159 |
| 158 // Reduce end by trimming away dead inputs. | 160 // Reduce end by trimming away dead inputs. |
| 159 Node* ReduceEnd(Node* node) { | 161 Node* ReduceEnd(Node* node) { |
| 160 // Count the number of live inputs. | 162 // Count the number of live inputs. |
| 161 int live = 0; | 163 int live = 0; |
| 162 for (int index = 0; index < node->InputCount(); ++index) { | 164 for (int index = 0; index < node->InputCount(); ++index) { |
| 163 // Skip dead inputs. | 165 // Skip dead inputs. |
| 164 if (node->InputAt(index)->opcode() == IrOpcode::kDead) continue; | 166 if (node->InputAt(index)->opcode() == IrOpcode::kDeadControl) continue; |
| 165 // Compact live inputs. | 167 // Compact live inputs. |
| 166 if (index != live) node->ReplaceInput(live, node->InputAt(index)); | 168 if (index != live) node->ReplaceInput(live, node->InputAt(index)); |
| 167 ++live; | 169 ++live; |
| 168 } | 170 } |
| 169 | 171 |
| 170 TRACE("ReduceEnd: #%d:%s (%d of %d live)\n", node->id(), | 172 TRACE("ReduceEnd: #%d:%s (%d of %d live)\n", node->id(), |
| 171 node->op()->mnemonic(), live, node->InputCount()); | 173 node->op()->mnemonic(), live, node->InputCount()); |
| 172 | 174 |
| 173 if (live == 0) return dead(); // No remaining inputs. | 175 if (live == 0) return dead(); // No remaining inputs. |
| 174 | 176 |
| 175 if (live < node->InputCount()) { | 177 if (live < node->InputCount()) { |
| 176 node->set_op(common()->End(live)); | 178 node->set_op(common()->End(live)); |
| 177 node->TrimInputCount(live); | 179 node->TrimInputCount(live); |
| 178 } | 180 } |
| 179 | 181 |
| 180 return node; | 182 return node; |
| 181 } | 183 } |
| 182 | 184 |
| 183 // Reduce merges by trimming away dead inputs from the merge and phis. | 185 // Reduce merges by trimming away dead inputs from the merge and phis. |
| 184 Node* ReduceMerge(Node* node) { | 186 Node* ReduceMerge(Node* node) { |
| 185 // Count the number of live inputs. | 187 // Count the number of live inputs. |
| 186 int live = 0; | 188 int live = 0; |
| 187 int index = 0; | 189 int index = 0; |
| 188 int live_index = 0; | 190 int live_index = 0; |
| 189 for (Node* const input : node->inputs()) { | 191 for (Node* const input : node->inputs()) { |
| 190 if (input->opcode() != IrOpcode::kDead) { | 192 if (input->opcode() != IrOpcode::kDeadControl) { |
| 191 live++; | 193 live++; |
| 192 live_index = index; | 194 live_index = index; |
| 193 } | 195 } |
| 194 index++; | 196 index++; |
| 195 } | 197 } |
| 196 | 198 |
| 197 TRACE("ReduceMerge: #%d:%s (%d of %d live)\n", node->id(), | 199 TRACE("ReduceMerge: #%d:%s (%d of %d live)\n", node->id(), |
| 198 node->op()->mnemonic(), live, index); | 200 node->op()->mnemonic(), live, index); |
| 199 | 201 |
| 200 if (live == 0) return dead(); // no remaining inputs. | 202 if (live == 0) return dead(); // no remaining inputs. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 } | 296 } |
| 295 return result == kUnknown ? node : dead(); | 297 return result == kUnknown ? node : dead(); |
| 296 } | 298 } |
| 297 | 299 |
| 298 // Remove inputs to {node} corresponding to the dead inputs to {merge} | 300 // Remove inputs to {node} corresponding to the dead inputs to {merge} |
| 299 // and compact the remaining inputs, updating the operator. | 301 // and compact the remaining inputs, updating the operator. |
| 300 void RemoveDeadInputs(Node* merge, Node* node) { | 302 void RemoveDeadInputs(Node* merge, Node* node) { |
| 301 int live = 0; | 303 int live = 0; |
| 302 for (int i = 0; i < merge->InputCount(); i++) { | 304 for (int i = 0; i < merge->InputCount(); i++) { |
| 303 // skip dead inputs. | 305 // skip dead inputs. |
| 304 if (merge->InputAt(i)->opcode() == IrOpcode::kDead) continue; | 306 if (merge->InputAt(i)->opcode() == IrOpcode::kDeadControl) continue; |
| 305 // compact live inputs. | 307 // compact live inputs. |
| 306 if (live != i) node->ReplaceInput(live, node->InputAt(i)); | 308 if (live != i) node->ReplaceInput(live, node->InputAt(i)); |
| 307 live++; | 309 live++; |
| 308 } | 310 } |
| 309 // compact remaining inputs. | 311 // compact remaining inputs. |
| 310 int total = live; | 312 int total = live; |
| 311 for (int i = merge->InputCount(); i < node->InputCount(); i++) { | 313 for (int i = merge->InputCount(); i < node->InputCount(); i++) { |
| 312 if (total != i) node->ReplaceInput(total, node->InputAt(i)); | 314 if (total != i) node->ReplaceInput(total, node->InputAt(i)); |
| 313 total++; | 315 total++; |
| 314 } | 316 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 373 case IrOpcode::kIfFalse: | 375 case IrOpcode::kIfFalse: |
| 374 return impl.ReduceIfProjection(node, kFalse); | 376 return impl.ReduceIfProjection(node, kFalse); |
| 375 default: | 377 default: |
| 376 return node; | 378 return node; |
| 377 } | 379 } |
| 378 } | 380 } |
| 379 | 381 |
| 380 } // namespace compiler | 382 } // namespace compiler |
| 381 } // namespace internal | 383 } // namespace internal |
| 382 } // namespace v8 | 384 } // namespace v8 |
| OLD | NEW |