Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Side by Side Diff: src/compiler/int64-lowering.cc

Issue 1704033002: [wasm] WasmRunner can run tests with I64 parameters and return value. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@new_wasm_runner
Patch Set: Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/linkage.h"
8 #include "src/compiler/machine-operator.h" 9 #include "src/compiler/machine-operator.h"
10 #include "src/compiler/node-properties.h"
11
9 #include "src/compiler/node.h" 12 #include "src/compiler/node.h"
13 #include "src/wasm/wasm-module.h"
10 #include "src/zone.h" 14 #include "src/zone.h"
11 15
12 namespace v8 { 16 namespace v8 {
13 namespace internal { 17 namespace internal {
14 namespace compiler { 18 namespace compiler {
15 19
16 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine, 20 Int64Lowering::Int64Lowering(Graph* graph, MachineOperatorBuilder* machine,
17 CommonOperatorBuilder* common, Zone* zone) 21 CommonOperatorBuilder* common, Zone* zone,
18 : graph_(graph), 22 Signature<MachineRepresentation>* signature)
23 : zone_(zone),
24 graph_(graph),
19 machine_(machine), 25 machine_(machine),
20 common_(common), 26 common_(common),
21 state_(graph, 4), 27 state_(graph, 4),
22 stack_(zone), 28 stack_(zone),
23 replacements_(zone->NewArray<Replacement>(graph->NodeCount())) { 29 replacements_(zone->NewArray<Replacement>(graph->NodeCount())),
30 signature_(signature) {
24 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount()); 31 memset(replacements_, 0, sizeof(Replacement) * graph->NodeCount());
25 } 32 }
26 33
27 void Int64Lowering::ReduceGraph() { 34 void Int64Lowering::LowerGraph() {
35 #if WASM_64
36 UNREACHABLE();
37 #endif
28 stack_.push(graph()->end()); 38 stack_.push(graph()->end());
29 state_.Set(graph()->end(), State::kOnStack); 39 state_.Set(graph()->end(), State::kOnStack);
30 40
31 while (!stack_.empty()) { 41 while (!stack_.empty()) {
32 Node* top = stack_.top(); 42 Node* top = stack_.top();
33 if (state_.Get(top) == State::kInputsPushed) { 43 if (state_.Get(top) == State::kInputsPushed) {
34 stack_.pop(); 44 stack_.pop();
35 state_.Set(top, State::kVisited); 45 state_.Set(top, State::kVisited);
36 // All inputs of top have already been reduced, now reduce top. 46 // All inputs of top have already been reduced, now reduce top.
37 ReduceNode(top); 47 LowerNode(top);
38 } else { 48 } else {
39 // Push all children onto the stack. 49 // Push all children onto the stack.
40 for (Node* input : top->inputs()) { 50 for (Node* input : top->inputs()) {
41 if (state_.Get(input) == State::kUnvisited) { 51 if (state_.Get(input) == State::kUnvisited) {
42 stack_.push(input); 52 stack_.push(input);
43 state_.Set(input, State::kOnStack); 53 state_.Set(input, State::kOnStack);
44 } 54 }
45 } 55 }
46 state_.Set(top, State::kInputsPushed); 56 state_.Set(top, State::kInputsPushed);
47 } 57 }
48 } 58 }
49 } 59 }
50 60
51 void Int64Lowering::ReduceNode(Node* node) { 61 static int GetParameterIndexAfterLowering(
62 Signature<MachineRepresentation>* signature, int old_index) {
63 int result = old_index;
64 for (int i = 0; i < old_index; i++) {
65 if (signature->GetParam(i) == MachineRepresentation::kWord64) {
66 result++;
67 }
68 }
69 return result;
70 }
71
72 static int GetParameterCountAfterLowering(
73 Signature<MachineRepresentation>* signature) {
74 int result = static_cast<int>(signature->parameter_count());
75 for (int i = 0; i < static_cast<int>(signature->parameter_count()); i++) {
76 if (signature->GetParam(i) == MachineRepresentation::kWord64) {
77 result++;
78 }
79 }
80 return result;
81 }
82
83 static int GetReturnCountAfterLowering(
84 Signature<MachineRepresentation>* signature) {
85 int result = static_cast<int>(signature->return_count());
86 for (int i = 0; i < static_cast<int>(signature->return_count()); i++) {
87 if (signature->GetReturn(i) == MachineRepresentation::kWord64) {
88 result++;
89 }
90 }
91 return result;
92 }
93
94 void Int64Lowering::LowerNode(Node* node) {
52 switch (node->opcode()) { 95 switch (node->opcode()) {
53 case IrOpcode::kInt64Constant: { 96 case IrOpcode::kInt64Constant: {
54 int64_t value = OpParameter<int64_t>(node); 97 int64_t value = OpParameter<int64_t>(node);
55 Node* low_node = graph()->NewNode( 98 Node* low_node = graph()->NewNode(
56 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF))); 99 common()->Int32Constant(static_cast<int32_t>(value & 0xFFFFFFFF)));
57 Node* high_node = graph()->NewNode( 100 Node* high_node = graph()->NewNode(
58 common()->Int32Constant(static_cast<int32_t>(value >> 32))); 101 common()->Int32Constant(static_cast<int32_t>(value >> 32)));
59 replacements_[node->id()].low = low_node; 102 ReplaceNode(node, low_node, high_node);
60 replacements_[node->id()].high = high_node; 103 break;
104 }
105 case IrOpcode::kLoad: {
106 LoadRepresentation load_rep = LoadRepresentationOf(node->op());
107
108 if (load_rep.representation() == MachineRepresentation::kWord64) {
109 Node* base = node->InputAt(0);
110 Node* index = node->InputAt(1);
111 Node* index_high =
112 graph()->NewNode(machine()->Int32Add(), index,
113 graph()->NewNode(common()->Int32Constant(4)));
114
115 const Operator* load_op = machine()->Load(MachineType::Int32());
116 Node* high_node;
117 if (node->InputCount() > 2) {
118 Node* effect_high = node->InputAt(2);
119 Node* control_high = node->InputAt(3);
120 high_node = graph()->NewNode(load_op, base, index_high, effect_high,
121 control_high);
122 // change the effect change from old_node --> old_effect to
123 // old_node --> high_node --> old_effect.
124 node->ReplaceInput(2, high_node);
125 } else {
126 high_node = graph()->NewNode(load_op, base, index_high);
127 }
128 NodeProperties::ChangeOp(node, load_op);
129 ReplaceNode(node, node, high_node);
130 }
131 break;
132 }
133 case IrOpcode::kStore: {
134 StoreRepresentation store_rep = StoreRepresentationOf(node->op());
135 if (store_rep.representation() == MachineRepresentation::kWord64) {
136 // We change the original store node to store the low word, and create
137 // a new store node to store the high word. The effect and control edges
138 // are copied from the original store to the new store node, the effect
139 // edge of the original store is redirected to the new store.
140 WriteBarrierKind write_barrier_kind = store_rep.write_barrier_kind();
141
142 Node* base = node->InputAt(0);
143 Node* index = node->InputAt(1);
144 Node* index_high =
145 graph()->NewNode(machine()->Int32Add(), index,
146 graph()->NewNode(common()->Int32Constant(4)));
147
148 Node* value = node->InputAt(2);
149 DCHECK(HasReplacementLow(value));
150 DCHECK(HasReplacementHigh(value));
151
152 const Operator* store_op = machine()->Store(StoreRepresentation(
153 MachineRepresentation::kWord32, write_barrier_kind));
154
155 Node* high_node;
156 if (node->InputCount() > 3) {
157 Node* effect_high = node->InputAt(3);
158 Node* control_high = node->InputAt(4);
159 high_node = graph()->NewNode(store_op, base, index_high,
160 GetReplacementHigh(value), effect_high,
161 control_high);
162 node->ReplaceInput(3, high_node);
163
164 } else {
165 high_node = graph()->NewNode(store_op, base, index_high,
166 GetReplacementHigh(value));
167 }
168
169 node->ReplaceInput(2, GetReplacementLow(value));
170 NodeProperties::ChangeOp(node, store_op);
171 ReplaceNode(node, node, high_node);
172 }
61 break; 173 break;
62 } 174 }
63 case IrOpcode::kWord64And: { 175 case IrOpcode::kWord64And: {
176 DCHECK(node->InputCount() == 2);
64 Node* left = node->InputAt(0); 177 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); 178 Node* right = node->InputAt(1);
70 DCHECK(replacements_[right->id()].low); 179
71 Node* right_low = replacements_[right->id()].low; 180 Node* low_node =
72 Node* right_high = replacements_[right->id()].high; 181 graph()->NewNode(machine()->Word32And(), GetReplacementLow(left),
73 182 GetReplacementLow(right));
74 replacements_[node->id()].low = 183 Node* high_node =
75 graph()->NewNode(machine()->Word32And(), left_low, right_low); 184 graph()->NewNode(machine()->Word32And(), GetReplacementHigh(left),
76 replacements_[node->id()].high = 185 GetReplacementHigh(right));
77 graph()->NewNode(machine()->Word32And(), left_high, right_high); 186 ReplaceNode(node, low_node, high_node);
78 break; 187 break;
79 } 188 }
80 case IrOpcode::kTruncateInt64ToInt32: { 189 case IrOpcode::kTruncateInt64ToInt32: {
190 DCHECK(node->InputCount() == 1);
81 Node* input = node->InputAt(0); 191 Node* input = node->InputAt(0);
82 DCHECK(replacements_[input->id()].low); 192 ReplaceNode(node, GetReplacementLow(input), nullptr);
83 replacements_[node->id()].low = replacements_[input->id()].low; 193 node->NullAllInputs();
84 break; 194 break;
85 } 195 }
86 default: { 196 case IrOpcode::kStart: {
87 // Also the inputs of nodes can change which do not expect int64 inputs. 197 int parameter_count = GetParameterCountAfterLowering(signature());
88 for (int i = 0; i < node->InputCount(); i++) { 198 // Only exchange the node if the parameter count actually changed.
89 Node* input = node->InputAt(i); 199 if (parameter_count != signature()->parameter_count()) {
90 // The input has changed altough it was not an int64 input. This can 200 int delta =
91 // happen e.g. if the input node is IrOpcode::kTruncateInt64ToInt32. We 201 parameter_count - static_cast<int>(signature()->parameter_count());
92 // use the low word replacement as the new input. 202 int new_output_count = node->op()->ValueOutputCount() + delta;
93 if (replacements_[input->id()].low) { 203 NodeProperties::ChangeOp(node, common()->Start(new_output_count));
94 node->ReplaceInput(i, replacements_[input->id()].low); 204 }
205 break;
206 }
207 case IrOpcode::kParameter: {
208 DCHECK(node->InputCount() == 1);
209 // Only exchange the node if the parameter count actually changed. We do
210 // not even have to do the default lowering because the the start node,
211 // the only input of a parameter node, only changes if the parameter count
212 // changes.
213 if (GetParameterCountAfterLowering(signature()) !=
214 signature()->parameter_count()) {
215 int old_index = ParameterIndexOf(node->op());
216 int new_index = GetParameterIndexAfterLowering(signature(), old_index);
217 Node* low_node =
218 graph()->NewNode(common()->Parameter(new_index), graph()->start());
219
220 Node* high_node = nullptr;
221 if (signature()->GetParam(old_index) ==
222 MachineRepresentation::kWord64) {
223 high_node = graph()->NewNode(common()->Parameter(new_index + 1),
224 graph()->start());
95 } 225 }
96 } 226 ReplaceNode(node, low_node, high_node);
97 } 227 }
228 break;
229 }
230 case IrOpcode::kReturn: {
231 DefaultLowering(node);
232 int new_return_count = GetReturnCountAfterLowering(signature());
233 if (signature()->return_count() != new_return_count) {
234 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
235 }
236 break;
237 }
238 case IrOpcode::kCall: {
239 CallDescriptor* const descriptor =
240 OpParameter<CallDescriptor* const>(node);
241 if (DefaultLowering(node) ||
242 (descriptor->ReturnCount() == 1 &&
243 descriptor->GetReturnType(0) == MachineType::Int64())) {
244 // We have to adjust the call descriptor.
245 const Operator* op = common()->Call(
246 wasm::ModuleEnv::GetI32WasmCallDescriptor(zone(), descriptor));
247 NodeProperties::ChangeOp(node, op);
248 }
249 if (descriptor->ReturnCount() == 1 &&
250 descriptor->GetReturnType(0) == MachineType::Int64()) {
251 // We access the additional return values through projections.
252 Node* low_node = graph()->NewNode(common()->Projection(0), node);
253 Node* high_node = graph()->NewNode(common()->Projection(1), node);
254 ReplaceNode(node, low_node, high_node);
255 }
256 break;
257 }
258 default: { DefaultLowering(node); }
98 } 259 }
99 } 260 }
100 261
262 bool Int64Lowering::DefaultLowering(Node* node) {
263 bool something_changed = false;
264 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
265 Node* input = node->InputAt(i);
266 if (HasReplacementLow(input)) {
267 something_changed = true;
268 node->ReplaceInput(i, GetReplacementLow(input));
269 }
270 if (HasReplacementHigh(input)) {
271 something_changed = true;
272 node->InsertInput(zone(), i + 1, GetReplacementHigh(input));
273 }
274 }
275 return something_changed;
276 }
277
278 void Int64Lowering::ReplaceNode(Node* old, Node* new_low, Node* new_high) {
279 // if new_low == nullptr, then also new_high == nullptr.
280 DCHECK(new_low != nullptr || new_high == nullptr);
281 replacements_[old->id()].low = new_low;
282 replacements_[old->id()].high = new_high;
283 }
284
285 bool Int64Lowering::HasReplacementLow(Node* node) {
286 return replacements_[node->id()].low != nullptr;
287 }
288
289 Node* Int64Lowering::GetReplacementLow(Node* node) {
290 Node* result = replacements_[node->id()].low;
291 DCHECK(result);
292 return result;
293 }
294
295 bool Int64Lowering::HasReplacementHigh(Node* node) {
296 return replacements_[node->id()].high != nullptr;
297 }
298
299 Node* Int64Lowering::GetReplacementHigh(Node* node) {
300 Node* result = replacements_[node->id()].high;
301 DCHECK(result);
302 return result;
303 }
101 } // namespace compiler 304 } // namespace compiler
102 } // namespace internal 305 } // namespace internal
103 } // namespace v8 306 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/int64-lowering.h ('k') | src/compiler/linkage.h » ('j') | src/compiler/linkage.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698