OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/loop-variable-optimizer.h" | 5 #include "src/compiler/loop-variable-optimizer.h" |
6 | 6 |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
9 #include "src/compiler/node-marker.h" | 9 #include "src/compiler/node-marker.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 NodeProperties::GetControlInput(constraint->left()) == loop) { | 181 NodeProperties::GetControlInput(constraint->left()) == loop) { |
182 auto var = induction_vars_.find(constraint->left()->id()); | 182 auto var = induction_vars_.find(constraint->left()->id()); |
183 if (var != induction_vars_.end()) { | 183 if (var != induction_vars_.end()) { |
184 var->second->AddUpperBound(constraint->right(), constraint->kind()); | 184 var->second->AddUpperBound(constraint->right(), constraint->kind()); |
185 } | 185 } |
186 } | 186 } |
187 if (constraint->right()->opcode() == IrOpcode::kPhi && | 187 if (constraint->right()->opcode() == IrOpcode::kPhi && |
188 NodeProperties::GetControlInput(constraint->right()) == loop) { | 188 NodeProperties::GetControlInput(constraint->right()) == loop) { |
189 auto var = induction_vars_.find(constraint->right()->id()); | 189 auto var = induction_vars_.find(constraint->right()->id()); |
190 if (var != induction_vars_.end()) { | 190 if (var != induction_vars_.end()) { |
191 var->second->AddUpperBound(constraint->left(), constraint->kind()); | 191 var->second->AddLowerBound(constraint->left(), constraint->kind()); |
192 } | 192 } |
193 } | 193 } |
194 } | 194 } |
195 } | 195 } |
196 | 196 |
197 void LoopVariableOptimizer::VisitNode(Node* node) { | 197 void LoopVariableOptimizer::VisitNode(Node* node) { |
198 switch (node->opcode()) { | 198 switch (node->opcode()) { |
199 case IrOpcode::kMerge: | 199 case IrOpcode::kMerge: |
200 return VisitMerge(node); | 200 return VisitMerge(node); |
201 case IrOpcode::kLoop: | 201 case IrOpcode::kLoop: |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 return var->second; | 296 return var->second; |
297 } | 297 } |
298 return nullptr; | 298 return nullptr; |
299 } | 299 } |
300 | 300 |
301 InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) { | 301 InductionVariable* LoopVariableOptimizer::TryGetInductionVariable(Node* phi) { |
302 DCHECK_EQ(2, phi->op()->ValueInputCount()); | 302 DCHECK_EQ(2, phi->op()->ValueInputCount()); |
303 DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(phi)->opcode()); | 303 DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(phi)->opcode()); |
304 Node* initial = phi->InputAt(0); | 304 Node* initial = phi->InputAt(0); |
305 Node* arith = phi->InputAt(1); | 305 Node* arith = phi->InputAt(1); |
306 // TODO(jarin) Support subtraction. | 306 InductionVariable::ArithmeticType arithmeticType; |
307 if (arith->opcode() != IrOpcode::kJSAdd) { | 307 if (arith->opcode() == IrOpcode::kJSAdd) { |
| 308 arithmeticType = InductionVariable::ArithmeticType::kAddition; |
| 309 } else if (arith->opcode() == IrOpcode::kJSSubtract) { |
| 310 arithmeticType = InductionVariable::ArithmeticType::kSubtraction; |
| 311 } else { |
308 return nullptr; | 312 return nullptr; |
309 } | 313 } |
| 314 |
310 // TODO(jarin) Support both sides. | 315 // TODO(jarin) Support both sides. |
311 if (arith->InputAt(0) != phi) { | 316 if (arith->InputAt(0) != phi) { |
312 if (arith->InputAt(0)->opcode() != IrOpcode::kJSToNumber || | 317 if (arith->InputAt(0)->opcode() != IrOpcode::kJSToNumber || |
313 arith->InputAt(0)->InputAt(0) != phi) { | 318 arith->InputAt(0)->InputAt(0) != phi) { |
314 return nullptr; | 319 return nullptr; |
315 } | 320 } |
316 } | 321 } |
317 Node* incr = arith->InputAt(1); | 322 Node* incr = arith->InputAt(1); |
318 return new (zone()) InductionVariable(phi, arith, incr, initial, zone()); | 323 return new (zone()) |
| 324 InductionVariable(phi, arith, incr, initial, zone(), arithmeticType); |
319 } | 325 } |
320 | 326 |
321 void LoopVariableOptimizer::DetectInductionVariables(Node* loop) { | 327 void LoopVariableOptimizer::DetectInductionVariables(Node* loop) { |
322 if (loop->op()->ControlInputCount() != 2) return; | 328 if (loop->op()->ControlInputCount() != 2) return; |
323 TRACE("Loop variables for loop %i:", loop->id()); | 329 TRACE("Loop variables for loop %i:", loop->id()); |
324 for (Edge edge : loop->use_edges()) { | 330 for (Edge edge : loop->use_edges()) { |
325 if (NodeProperties::IsControlEdge(edge) && | 331 if (NodeProperties::IsControlEdge(edge) && |
326 edge.from()->opcode() == IrOpcode::kPhi) { | 332 edge.from()->opcode() == IrOpcode::kPhi) { |
327 Node* phi = edge.from(); | 333 Node* phi = edge.from(); |
328 InductionVariable* induction_var = TryGetInductionVariable(phi); | 334 InductionVariable* induction_var = TryGetInductionVariable(phi); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 backedge_value, backedge_control); | 397 backedge_value, backedge_control); |
392 induction_var->phi()->ReplaceInput(1, rename); | 398 induction_var->phi()->ReplaceInput(1, rename); |
393 } | 399 } |
394 } | 400 } |
395 } | 401 } |
396 } | 402 } |
397 | 403 |
398 } // namespace compiler | 404 } // namespace compiler |
399 } // namespace internal | 405 } // namespace internal |
400 } // namespace v8 | 406 } // namespace v8 |
OLD | NEW |