OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/compiler/int64-lowering.h" |
| 6 #include "src/compiler/common-operator.h" |
| 7 #include "src/compiler/graph.h" |
| 8 #include "src/compiler/machine-operator.h" |
| 9 #include "src/compiler/node.h" |
| 10 #include "src/zone.h" |
| 11 |
| 12 namespace v8 { |
| 13 namespace internal { |
| 14 namespace compiler { |
| 15 |
| 16 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, |
| 17 CommonOperatorBuilder* common, Zone* zone) |
| 18 : graph_(graph), |
| 19 machine_(machine), |
| 20 common_(common), |
| 21 state_(graph, 4), |
| 22 stack_(zone), |
| 23 replacements_(zone->NewArray<Replacement>(graph->NodeCount())) { |
| 24 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); |
| 25 } |
| 26 |
| 27 void Int64Lowering::ReduceGraph() { |
| 28 stack_.push(graph()->end()); |
| 29 state_.Set(graph()->end(), State::kOnStack); |
| 30 |
| 31 while (!stack_.empty()) { |
| 32 Node* top = stack_.top(); |
| 33 if (state_.Get(top) == State::kInputsPushed) { |
| 34 stack_.pop(); |
| 35 state_.Set(top, State::kVisited); |
| 36 // All inputs of top have already been reduced, now reduce top. |
| 37 ReduceNode(top); |
| 38 } else { |
| 39 // Push all children onto the stack. |
| 40 for (Node* input : top->inputs()) { |
| 41 if (state_.Get(input) == State::kUnvisited) { |
| 42 stack_.push(input); |
| 43 state_.Set(input, State::kOnStack); |
| 44 } |
| 45 } |
| 46 state_.Set(top, State::kInputsPushed); |
| 47 } |
| 48 } |
| 49 } |
| 50 |
| 51 void Int64Lowering::ReduceNode(Node* node) { |
| 52 switch (node->opcode()) { |
| 53 case IrOpcode::kInt64Constant: { |
| 54 int64_t value = OpParameter<int64_t>(node); |
| 55 Node* low_node = graph()->NewNode( |
| 56 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF))); |
| 57 Node* high_node = graph()->NewNode( |
| 58 common()->Int32Constant(static_cast<int32_t>(value >> 32))); |
| 59 replacements_[node->id()].low = low_node; |
| 60 replacements_[node->id()].high = high_node; |
| 61 break; |
| 62 } |
| 63 case IrOpcode::kWord64And: { |
| 64 Node* left = node->InputAt(0); |
| 65 DCHECK(replacements_[left->id()].low); |
| 66 Node* left_low = replacements_[left->id()].low; |
| 67 Node* left_high = replacements_[left->id()].high; |
| 68 |
| 69 Node* right = node->InputAt(1); |
| 70 DCHECK(replacements_[right->id()].low); |
| 71 Node* right_low = replacements_[right->id()].low; |
| 72 Node* right_high = replacements_[right->id()].high; |
| 73 |
| 74 replacements_[node->id()].low = |
| 75 graph()->NewNode(machine()->Word32And(), left_low, right_low); |
| 76 replacements_[node->id()].high = |
| 77 graph()->NewNode(machine()->Word32And(), left_high, right_high); |
| 78 break; |
| 79 } |
| 80 case IrOpcode::kTruncateInt64ToInt32: { |
| 81 Node* input = node->InputAt(0); |
| 82 DCHECK(replacements_[input->id()].low); |
| 83 replacements_[node->id()].low = replacements_[input->id()].low; |
| 84 break; |
| 85 } |
| 86 default: { |
| 87 // Also the inputs of nodes can change which do not expect int64 inputs. |
| 88 for (int i = 0; i < node->InputCount(); i++) { |
| 89 Node* input = node->InputAt(i); |
| 90 // The input has changed altough it was not an int64 input. This can |
| 91 // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We |
| 92 // use the low word replacement as the new input. |
| 93 if (replacements_[input->id()].low) { |
| 94 node->ReplaceInput(i, replacements_[input->id()].low); |
| 95 } |
| 96 } |
| 97 } |
| 98 } |
| 99 } |
| 100 |
| 101 } // namespace compiler |
| 102 } // namespace internal |
| 103 } // namespace v8 |
OLD | NEW |