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/int64-lowering.h" | 5 #include "src/compiler/int64-lowering.h" |
6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
7 #include "src/compiler/diamond.h" | 7 #include "src/compiler/diamond.h" |
8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
12 | 12 |
13 #include "src/compiler/node.h" | 13 #include "src/compiler/node.h" |
14 #include "src/wasm/wasm-module.h" | 14 #include "src/wasm/wasm-module.h" |
15 #include "src/zone.h" | 15 #include "src/zone.h" |
16 | 16 |
17 namespace v8 { | 17 namespace v8 { |
18 namespace internal { | 18 namespace internal { |
19 namespace compiler { | 19 namespace compiler { |
20 | 20 |
21 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, | 21 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, |
22 CommonOperatorBuilder* common, Zone* zone, | 22 CommonOperatorBuilder* common, Zone* zone, |
23 Signature<MachineRepresentation>* signature) | 23 Signature<MachineRepresentation>* signature) |
24 : zone_(zone), | 24 : zone_(zone), |
25 graph_(graph), | 25 graph_(graph), |
26 machine_(machine), | 26 machine_(machine), |
27 common_(common), | 27 common_(common), |
28 state_(graph, 3), | 28 state_(graph, 3), |
29 stack_(zone), | 29 stack_(zone), |
30 replacements_(zone->NewArray<Replacement>(graph->NodeCount())), | 30 replacements_(nullptr), |
31 signature_(signature) { | 31 signature_(signature), |
| 32 placeholder_(graph->NewNode(common->Parameter(-2, "placeholder"), |
| 33 graph->start())) { |
| 34 replacements_ = zone->NewArray<Replacement>(graph->NodeCount()); |
32 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); | 35 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); |
33 } | 36 } |
34 | 37 |
35 void Int64Lowering::LowerGraph() { | 38 void Int64Lowering::LowerGraph() { |
36 if (!machine()->Is32()) { | 39 if (!machine()->Is32()) { |
37 return; | 40 return; |
38 } | 41 } |
39 stack_.push({graph()->end(), 0}); | 42 stack_.push_back({graph()->end(), 0}); |
40 state_.Set(graph()->end(), State::kOnStack); | 43 state_.Set(graph()->end(), State::kOnStack); |
41 | 44 |
42 while (!stack_.empty()) { | 45 while (!stack_.empty()) { |
43 NodeState& top = stack_.top(); | 46 NodeState& top = stack_.back(); |
44 if (top.input_index == top.node->InputCount()) { | 47 if (top.input_index == top.node->InputCount()) { |
45 // All inputs of top have already been lowered, now lower top. | 48 // All inputs of top have already been lowered, now lower top. |
46 stack_.pop(); | 49 stack_.pop_back(); |
47 state_.Set(top.node, State::kVisited); | 50 state_.Set(top.node, State::kVisited); |
48 LowerNode(top.node); | 51 LowerNode(top.node); |
49 } else { | 52 } else { |
50 // Push the next input onto the stack. | 53 // Push the next input onto the stack. |
51 Node* input = top.node->InputAt(top.input_index++); | 54 Node* input = top.node->InputAt(top.input_index++); |
52 if (state_.Get(input) == State::kUnvisited) { | 55 if (state_.Get(input) == State::kUnvisited) { |
53 stack_.push({input, 0}); | 56 if (input->opcode() == IrOpcode::kPhi) { |
| 57 // To break cycles with phi nodes we push phis on a separate stack so |
| 58 // that they are processed after all other nodes. |
| 59 PreparePhiReplacement(input); |
| 60 stack_.push_front({input, 0}); |
| 61 } else { |
| 62 stack_.push_back({input, 0}); |
| 63 } |
54 state_.Set(input, State::kOnStack); | 64 state_.Set(input, State::kOnStack); |
55 } | 65 } |
56 } | 66 } |
57 } | 67 } |
58 } | 68 } |
59 | 69 |
60 static int GetParameterIndexAfterLowering( | 70 static int GetParameterIndexAfterLowering( |
61 Signature<MachineRepresentation>* signature, int old_index) { | 71 Signature<MachineRepresentation>* signature, int old_index) { |
62 int result = old_index; | 72 int result = old_index; |
63 for (int i = 0; i < old_index; i++) { | 73 for (int i = 0; i < old_index; i++) { |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
570 DCHECK(machine()->Word32Popcnt().IsSupported()); | 580 DCHECK(machine()->Word32Popcnt().IsSupported()); |
571 ReplaceNode(node, graph()->NewNode( | 581 ReplaceNode(node, graph()->NewNode( |
572 machine()->Int32Add(), | 582 machine()->Int32Add(), |
573 graph()->NewNode(machine()->Word32Popcnt().op(), | 583 graph()->NewNode(machine()->Word32Popcnt().op(), |
574 GetReplacementLow(input)), | 584 GetReplacementLow(input)), |
575 graph()->NewNode(machine()->Word32Popcnt().op(), | 585 graph()->NewNode(machine()->Word32Popcnt().op(), |
576 GetReplacementHigh(input))), | 586 GetReplacementHigh(input))), |
577 graph()->NewNode(common()->Int32Constant(0))); | 587 graph()->NewNode(common()->Int32Constant(0))); |
578 break; | 588 break; |
579 } | 589 } |
| 590 case IrOpcode::kPhi: { |
| 591 MachineRepresentation rep = PhiRepresentationOf(node->op()); |
| 592 if (rep == MachineRepresentation::kWord64) { |
| 593 // The replacement nodes have already been created, we only have to |
| 594 // replace placeholder nodes. |
| 595 Node* low_node = GetReplacementLow(node); |
| 596 Node* high_node = GetReplacementHigh(node); |
| 597 for (int i = 0; i < node->op()->ValueInputCount(); i++) { |
| 598 low_node->ReplaceInput(i, GetReplacementLow(node->InputAt(i))); |
| 599 high_node->ReplaceInput(i, GetReplacementHigh(node->InputAt(i))); |
| 600 } |
| 601 } else { |
| 602 DefaultLowering(node); |
| 603 } |
| 604 break; |
| 605 } |
580 | 606 |
581 default: { DefaultLowering(node); } | 607 default: { DefaultLowering(node); } |
582 } | 608 } |
583 } | 609 } |
584 | 610 |
585 void Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op, | 611 void Int64Lowering::LowerComparison(Node* node, const Operator* high_word_op, |
586 const Operator* low_word_op) { | 612 const Operator* low_word_op) { |
587 DCHECK(node->InputCount() == 2); | 613 DCHECK(node->InputCount() == 2); |
588 Node* left = node->InputAt(0); | 614 Node* left = node->InputAt(0); |
589 Node* right = node->InputAt(1); | 615 Node* right = node->InputAt(1); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 | 662 |
637 bool Int64Lowering::HasReplacementHigh(Node* node) { | 663 bool Int64Lowering::HasReplacementHigh(Node* node) { |
638 return replacements_[node->id()].high != nullptr; | 664 return replacements_[node->id()].high != nullptr; |
639 } | 665 } |
640 | 666 |
641 Node* Int64Lowering::GetReplacementHigh(Node* node) { | 667 Node* Int64Lowering::GetReplacementHigh(Node* node) { |
642 Node* result = replacements_[node->id()].high; | 668 Node* result = replacements_[node->id()].high; |
643 DCHECK(result); | 669 DCHECK(result); |
644 return result; | 670 return result; |
645 } | 671 } |
| 672 |
| 673 void Int64Lowering::PreparePhiReplacement(Node* phi) { |
| 674 MachineRepresentation rep = PhiRepresentationOf(phi->op()); |
| 675 if (rep == MachineRepresentation::kWord64) { |
| 676 // We have to create the replacements for a phi node before we actually |
| 677 // lower the phi to break potential cycles in the graph. The replacements of |
| 678 // input nodes do not exist yet, so we use a placeholder node to pass the |
| 679 // graph verifier. |
| 680 int value_count = phi->op()->ValueInputCount(); |
| 681 Node** inputs_low = zone()->NewArray<Node*>(value_count + 1); |
| 682 Node** inputs_high = zone()->NewArray<Node*>(value_count + 1); |
| 683 for (int i = 0; i < value_count; i++) { |
| 684 inputs_low[i] = placeholder_; |
| 685 inputs_high[i] = placeholder_; |
| 686 } |
| 687 inputs_low[value_count] = NodeProperties::GetControlInput(phi, 0); |
| 688 inputs_high[value_count] = NodeProperties::GetControlInput(phi, 0); |
| 689 ReplaceNode(phi, |
| 690 graph()->NewNode( |
| 691 common()->Phi(MachineRepresentation::kWord32, value_count), |
| 692 value_count + 1, inputs_low, false), |
| 693 graph()->NewNode( |
| 694 common()->Phi(MachineRepresentation::kWord32, value_count), |
| 695 value_count + 1, inputs_high, false)); |
| 696 } |
| 697 } |
646 } // namespace compiler | 698 } // namespace compiler |
647 } // namespace internal | 699 } // namespace internal |
648 } // namespace v8 | 700 } // namespace v8 |
OLD | NEW |