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())) {} | |
titzer
2016/02/03 15:36:29
Maybe we should zero-initialize the replacements a
ahaas
2016/02/03 15:48:40
I will do this in a later CL.
ahaas
2016/02/04 09:08:06
Done
| |
24 | |
25 void Int64Lowering::ReduceGraph() { | |
26 stack_.push(graph()->end()); | |
27 state_.Set(graph()->end(), State::kOnStack); | |
28 | |
29 while (!stack_.empty()) { | |
30 Node* top = stack_.top(); | |
31 if (state_.Get(top) == State::kInputsPushed) { | |
32 stack_.pop(); | |
33 state_.Set(top, State::kVisited); | |
34 // All inputs of top have already been reduced, now reduce top. | |
35 ReduceNode(top); | |
36 } else { | |
37 // Push all children onto the stack. | |
38 for (Node* input : top->inputs()) { | |
39 if (state_.Get(input) == State::kUnvisited) { | |
40 stack_.push(input); | |
41 state_.Set(input, State::kOnStack); | |
42 replacements_[input->id()].low = nullptr; | |
43 } | |
44 } | |
45 state_.Set(top, State::kInputsPushed); | |
46 } | |
47 } | |
48 } | |
49 | |
50 void Int64Lowering::ReduceNode(Node* node) { | |
51 switch (node->opcode()) { | |
52 case IrOpcode::kInt64Constant: { | |
53 int64_t value = OpParameter<int64_t>(node); | |
54 Node* low_node = graph()->NewNode( | |
55 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF))); | |
56 Node* high_node = graph()->NewNode( | |
57 common()->Int32Constant(static_cast<int32_t>(value >> 32))); | |
58 replacements_[node->id()].low = low_node; | |
59 replacements_[node->id()].high = high_node; | |
60 break; | |
61 } | |
62 case IrOpcode::kWord64And: { | |
63 Node* left = node->InputAt(0); | |
64 DCHECK(replacements_[left->id()].low); | |
65 Node* left_low = replacements_[left->id()].low; | |
66 Node* left_high = replacements_[left->id()].high; | |
67 | |
68 Node* right = node->InputAt(1); | |
69 DCHECK(replacements_[right->id()].low); | |
70 Node* right_low = replacements_[right->id()].low; | |
71 Node* right_high = replacements_[right->id()].high; | |
72 | |
73 replacements_[node->id()].low = | |
74 graph()->NewNode(machine()->Word32And(), left_low, right_low); | |
75 replacements_[node->id()].high = | |
76 graph()->NewNode(machine()->Word32And(), left_high, right_high); | |
77 break; | |
78 } | |
79 case IrOpcode::kTruncateInt64ToInt32: { | |
80 Node* input = node->InputAt(0); | |
81 DCHECK(replacements_[input->id()].low); | |
82 replacements_[node->id()].low = replacements_[input->id()].low; | |
83 break; | |
84 } | |
85 default: { | |
86 // Also the inputs of nodes can change which do not expect int64 inputs. | |
87 for (int i = 0; i < node->InputCount(); i++) { | |
88 Node* input = node->InputAt(i); | |
89 // The input has changed altough it was not an int64 input. This can | |
90 // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We | |
91 // use the low word replacement as the new input. | |
92 if (replacements_[input->id()].low) { | |
93 node->ReplaceInput(i, replacements_[input->id()].low); | |
94 } | |
95 } | |
96 } | |
97 } | |
98 } | |
99 | |
100 } // namespace compiler | |
101 } // namespace internal | |
102 } // namespace v8 | |
OLD | NEW |