| 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/graph-inl.h" | 5 #include "src/compiler/graph-inl.h" |
| 6 #include "src/compiler/js-typed-lowering.h" | 6 #include "src/compiler/js-typed-lowering.h" |
| 7 #include "src/compiler/node-aux-data-inl.h" | 7 #include "src/compiler/node-aux-data-inl.h" |
| 8 #include "src/compiler/node-properties-inl.h" | 8 #include "src/compiler/node-properties-inl.h" |
| 9 #include "src/types.h" | 9 #include "src/types.h" |
| 10 | 10 |
| 11 namespace v8 { | 11 namespace v8 { |
| 12 namespace internal { | 12 namespace internal { |
| 13 namespace compiler { | 13 namespace compiler { |
| 14 | 14 |
| 15 // TODO(turbofan): js-typed-lowering improvements possible | 15 // TODO(turbofan): js-typed-lowering improvements possible |
| 16 // - immediately put in type bounds for all new nodes | 16 // - immediately put in type bounds for all new nodes |
| 17 // - relax effects from generic but not-side-effecting operations | 17 // - relax effects from generic but not-side-effecting operations |
| 18 // - relax effects for ToNumber(mixed) | 18 // - relax effects for ToNumber(mixed) |
| 19 | 19 |
| 20 // Replace value uses of {node} with {value} and effect uses of {node} with | |
| 21 // {effect}. If {effect == NULL}, then use the effect input to {node}. | |
| 22 // TODO(titzer): move into a GraphEditor? | |
| 23 static void ReplaceUses(Node* node, Node* value, Node* effect) { | |
| 24 if (value == effect) { | |
| 25 // Effect and value updates are the same; no special iteration needed. | |
| 26 if (value != node) node->ReplaceUses(value); | |
| 27 return; | |
| 28 } | |
| 29 | |
| 30 if (effect == NULL) effect = NodeProperties::GetEffectInput(node); | |
| 31 | |
| 32 // The iteration requires distinguishing between value and effect edges. | |
| 33 UseIter iter = node->uses().begin(); | |
| 34 while (iter != node->uses().end()) { | |
| 35 if (NodeProperties::IsEffectEdge(iter.edge())) { | |
| 36 iter = iter.UpdateToAndIncrement(effect); | |
| 37 } else { | |
| 38 iter = iter.UpdateToAndIncrement(value); | |
| 39 } | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 | 20 |
| 44 // Relax the effects of {node} by immediately replacing effect uses of {node} | 21 // Relax the effects of {node} by immediately replacing effect uses of {node} |
| 45 // with the effect input to {node}. | 22 // with the effect input to {node}. |
| 46 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. | 23 // TODO(turbofan): replace the effect input to {node} with {graph->start()}. |
| 47 // TODO(titzer): move into a GraphEditor? | 24 // TODO(titzer): move into a GraphEditor? |
| 48 static void RelaxEffects(Node* node) { ReplaceUses(node, node, NULL); } | 25 static void RelaxEffects(Node* node) { |
| 26 NodeProperties::ReplaceWithValue(node, node, NULL); |
| 27 } |
| 49 | 28 |
| 50 | 29 |
| 51 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { | 30 Reduction JSTypedLowering::ReplaceEagerly(Node* old, Node* node) { |
| 52 ReplaceUses(old, node, node); | 31 NodeProperties::ReplaceWithValue(old, node, node); |
| 53 return Reducer::Changed(node); | 32 return Reducer::Changed(node); |
| 54 } | 33 } |
| 55 | 34 |
| 56 | 35 |
| 57 // A helper class to simplify the process of reducing a single binop node with a | 36 // A helper class to simplify the process of reducing a single binop node with a |
| 58 // JSOperator. This class manages the rewriting of context, control, and effect | 37 // JSOperator. This class manages the rewriting of context, control, and effect |
| 59 // dependencies during lowering of a binop and contains numerous helper | 38 // dependencies during lowering of a binop and contains numerous helper |
| 60 // functions for matching the types of inputs to an operation. | 39 // functions for matching the types of inputs to an operation. |
| 61 class JSBinopReduction { | 40 class JSBinopReduction { |
| 62 public: | 41 public: |
| (...skipping 452 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 515 cmp->ReplaceInput(0, input); | 494 cmp->ReplaceInput(0, input); |
| 516 return Changed(inv); | 495 return Changed(inv); |
| 517 } | 496 } |
| 518 // TODO(turbofan): js-typed-lowering of ToBoolean(string) | 497 // TODO(turbofan): js-typed-lowering of ToBoolean(string) |
| 519 return NoChange(); | 498 return NoChange(); |
| 520 } | 499 } |
| 521 | 500 |
| 522 | 501 |
| 523 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { | 502 static Reduction ReplaceWithReduction(Node* node, Reduction reduction) { |
| 524 if (reduction.Changed()) { | 503 if (reduction.Changed()) { |
| 525 ReplaceUses(node, reduction.replacement(), NULL); | 504 NodeProperties::ReplaceWithValue(node, reduction.replacement()); |
| 526 return reduction; | 505 return reduction; |
| 527 } | 506 } |
| 528 return Reducer::NoChange(); | 507 return Reducer::NoChange(); |
| 529 } | 508 } |
| 530 | 509 |
| 531 | 510 |
| 532 Reduction JSTypedLowering::Reduce(Node* node) { | 511 Reduction JSTypedLowering::Reduce(Node* node) { |
| 533 switch (node->opcode()) { | 512 switch (node->opcode()) { |
| 534 case IrOpcode::kJSEqual: | 513 case IrOpcode::kJSEqual: |
| 535 return ReduceJSEqual(node, false); | 514 return ReduceJSEqual(node, false); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 566 return ReduceNumberBinop(node, simplified()->NumberDivide()); | 545 return ReduceNumberBinop(node, simplified()->NumberDivide()); |
| 567 case IrOpcode::kJSModulus: | 546 case IrOpcode::kJSModulus: |
| 568 return ReduceNumberBinop(node, simplified()->NumberModulus()); | 547 return ReduceNumberBinop(node, simplified()->NumberModulus()); |
| 569 case IrOpcode::kJSUnaryNot: { | 548 case IrOpcode::kJSUnaryNot: { |
| 570 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); | 549 Reduction result = ReduceJSToBooleanInput(node->InputAt(0)); |
| 571 Node* value; | 550 Node* value; |
| 572 if (result.Changed()) { | 551 if (result.Changed()) { |
| 573 // !x => BooleanNot(x) | 552 // !x => BooleanNot(x) |
| 574 value = | 553 value = |
| 575 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); | 554 graph()->NewNode(simplified()->BooleanNot(), result.replacement()); |
| 576 ReplaceUses(node, value, NULL); | 555 NodeProperties::ReplaceWithValue(node, value); |
| 577 return Changed(value); | 556 return Changed(value); |
| 578 } else { | 557 } else { |
| 579 // !x => BooleanNot(JSToBoolean(x)) | 558 // !x => BooleanNot(JSToBoolean(x)) |
| 580 value = graph()->NewNode(simplified()->BooleanNot(), node); | 559 value = graph()->NewNode(simplified()->BooleanNot(), node); |
| 581 node->set_op(javascript()->ToBoolean()); | 560 node->set_op(javascript()->ToBoolean()); |
| 582 ReplaceUses(node, value, node); | 561 NodeProperties::ReplaceWithValue(node, value, node); |
| 583 // Note: ReplaceUses() smashes all uses, so smash it back here. | 562 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 584 value->ReplaceInput(0, node); | 563 value->ReplaceInput(0, node); |
| 585 return ReplaceWith(value); | 564 return ReplaceWith(value); |
| 586 } | 565 } |
| 587 } | 566 } |
| 588 case IrOpcode::kJSToBoolean: | 567 case IrOpcode::kJSToBoolean: |
| 589 return ReplaceWithReduction(node, | 568 return ReplaceWithReduction(node, |
| 590 ReduceJSToBooleanInput(node->InputAt(0))); | 569 ReduceJSToBooleanInput(node->InputAt(0))); |
| 591 case IrOpcode::kJSToNumber: | 570 case IrOpcode::kJSToNumber: |
| 592 return ReplaceWithReduction(node, | 571 return ReplaceWithReduction(node, |
| 593 ReduceJSToNumberInput(node->InputAt(0))); | 572 ReduceJSToNumberInput(node->InputAt(0))); |
| 594 case IrOpcode::kJSToString: | 573 case IrOpcode::kJSToString: |
| 595 return ReplaceWithReduction(node, | 574 return ReplaceWithReduction(node, |
| 596 ReduceJSToStringInput(node->InputAt(0))); | 575 ReduceJSToStringInput(node->InputAt(0))); |
| 597 default: | 576 default: |
| 598 break; | 577 break; |
| 599 } | 578 } |
| 600 return NoChange(); | 579 return NoChange(); |
| 601 } | 580 } |
| 602 } | 581 } |
| 603 } | 582 } |
| 604 } // namespace v8::internal::compiler | 583 } // namespace v8::internal::compiler |
| OLD | NEW |