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

Side by Side Diff: src/compiler/simd-scalar-lowering.cc

Issue 2843523002: [wasm] Implement simd lowering for I16x8 (Closed)
Patch Set: [wasm] Implement simd lowering for I16x8 Created 3 years, 7 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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 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/simd-scalar-lowering.h" 5 #include "src/compiler/simd-scalar-lowering.h"
6 #include "src/compiler/diamond.h" 6 #include "src/compiler/diamond.h"
7 #include "src/compiler/linkage.h" 7 #include "src/compiler/linkage.h"
8 #include "src/compiler/node-matchers.h" 8 #include "src/compiler/node-matchers.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 10
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
66 } 66 }
67 } 67 }
68 68
69 #define FOREACH_INT32X4_OPCODE(V) \ 69 #define FOREACH_INT32X4_OPCODE(V) \
70 V(I32x4Splat) \ 70 V(I32x4Splat) \
71 V(I32x4ExtractLane) \ 71 V(I32x4ExtractLane) \
72 V(I32x4ReplaceLane) \ 72 V(I32x4ReplaceLane) \
73 V(I32x4SConvertF32x4) \ 73 V(I32x4SConvertF32x4) \
74 V(I32x4UConvertF32x4) \ 74 V(I32x4UConvertF32x4) \
75 V(I32x4Neg) \ 75 V(I32x4Neg) \
76 V(I32x4Shl) \
77 V(I32x4ShrS) \
76 V(I32x4Add) \ 78 V(I32x4Add) \
77 V(I32x4Sub) \ 79 V(I32x4Sub) \
78 V(I32x4Mul) \ 80 V(I32x4Mul) \
79 V(I32x4MinS) \ 81 V(I32x4MinS) \
80 V(I32x4MaxS) \ 82 V(I32x4MaxS) \
83 V(I32x4ShrU) \
81 V(I32x4MinU) \ 84 V(I32x4MinU) \
82 V(I32x4MaxU) \ 85 V(I32x4MaxU) \
83 V(S128And) \ 86 V(S128And) \
84 V(S128Or) \ 87 V(S128Or) \
85 V(S128Xor) \ 88 V(S128Xor) \
86 V(S128Not) 89 V(S128Not)
87 90
88 #define FOREACH_FLOAT32X4_OPCODE(V) \ 91 #define FOREACH_FLOAT32X4_OPCODE(V) \
89 V(F32x4Splat) \ 92 V(F32x4Splat) \
90 V(F32x4ExtractLane) \ 93 V(F32x4ExtractLane) \
(...skipping 21 matching lines...) Expand all
112 V(I32x4Ne) \ 115 V(I32x4Ne) \
113 V(I32x4LtS) \ 116 V(I32x4LtS) \
114 V(I32x4LeS) \ 117 V(I32x4LeS) \
115 V(I32x4GtS) \ 118 V(I32x4GtS) \
116 V(I32x4GeS) \ 119 V(I32x4GeS) \
117 V(I32x4LtU) \ 120 V(I32x4LtU) \
118 V(I32x4LeU) \ 121 V(I32x4LeU) \
119 V(I32x4GtU) \ 122 V(I32x4GtU) \
120 V(I32x4GeU) 123 V(I32x4GeU)
121 124
125 #define FOREACH_INT16X8_OPCODE(V) \
126 V(I16x8Splat) \
127 V(I16x8ExtractLane) \
128 V(I16x8ReplaceLane) \
129 V(I16x8Neg) \
130 V(I16x8Shl) \
131 V(I16x8ShrS) \
132 V(I16x8Add) \
133 V(I16x8AddSaturateS) \
134 V(I16x8Sub) \
135 V(I16x8SubSaturateS) \
136 V(I16x8Mul) \
137 V(I16x8MinS) \
138 V(I16x8MaxS) \
139 V(I16x8ShrU) \
140 V(I16x8AddSaturateU) \
141 V(I16x8SubSaturateU) \
142 V(I16x8MinU) \
143 V(I16x8MaxU)
144
145 #define FOREACH_INT16X8_TO_SIMD1X8OPCODE(V) \
146 V(I16x8Eq) \
147 V(I16x8Ne) \
148 V(I16x8LtS) \
149 V(I16x8LeS) \
150 V(I16x8LtU) \
151 V(I16x8LeU)
152
153 #define FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(V) \
154 V(Float32, Float32) \
155 V(Int32, Int32) \
156 V(Int16, Int16)
157
158 #define FOREACH_SIMD_TYPE_TO_MACHINE_REP(V) \
159 V(Float32, Float32) \
160 V(Int32, Word32) \
161 V(Int16, Word16)
162
122 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { 163 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
123 switch (node->opcode()) { 164 switch (node->opcode()) {
124 #define CASE_STMT(name) case IrOpcode::k##name: 165 #define CASE_STMT(name) case IrOpcode::k##name:
125 FOREACH_INT32X4_OPCODE(CASE_STMT) 166 FOREACH_INT32X4_OPCODE(CASE_STMT)
126 case IrOpcode::kReturn: 167 case IrOpcode::kReturn:
127 case IrOpcode::kParameter: 168 case IrOpcode::kParameter:
128 case IrOpcode::kCall: { 169 case IrOpcode::kCall: {
129 replacements_[node->id()].type = SimdType::kInt32; 170 replacements_[node->id()].type = SimdType::kInt32;
130 break; 171 break;
131 } 172 }
132 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { 173 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) {
133 replacements_[node->id()].type = SimdType::kFloat32; 174 replacements_[node->id()].type = SimdType::kFloat32;
134 break; 175 break;
135 } 176 }
136 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 177 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
137 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) { 178 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) {
138 replacements_[node->id()].type = SimdType::kSimd1x4; 179 replacements_[node->id()].type = SimdType::kSimd1x4;
139 break; 180 break;
140 } 181 }
182 FOREACH_INT16X8_OPCODE(CASE_STMT) {
183 replacements_[node->id()].type = SimdType::kInt16;
184 break;
185 }
186 FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) {
187 replacements_[node->id()].type = SimdType::kSimd1x8;
188 break;
189 }
141 default: { 190 default: {
142 switch (output->opcode()) { 191 switch (output->opcode()) {
143 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 192 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
144 case IrOpcode::kF32x4SConvertI32x4: 193 case IrOpcode::kF32x4SConvertI32x4:
145 case IrOpcode::kF32x4UConvertI32x4: { 194 case IrOpcode::kF32x4UConvertI32x4: {
146 replacements_[node->id()].type = SimdType::kInt32; 195 replacements_[node->id()].type = SimdType::kInt32;
147 break; 196 break;
148 } 197 }
149 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) 198 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
150 case IrOpcode::kI32x4SConvertF32x4: 199 case IrOpcode::kI32x4SConvertF32x4:
151 case IrOpcode::kI32x4UConvertF32x4: { 200 case IrOpcode::kI32x4UConvertF32x4: {
152 replacements_[node->id()].type = SimdType::kFloat32; 201 replacements_[node->id()].type = SimdType::kFloat32;
153 break; 202 break;
154 } 203 }
155 case IrOpcode::kS32x4Select: { 204 case IrOpcode::kS32x4Select: {
156 replacements_[node->id()].type = SimdType::kSimd1x4; 205 replacements_[node->id()].type = SimdType::kSimd1x4;
157 break; 206 break;
158 } 207 }
208 FOREACH_INT16X8_TO_SIMD1X8OPCODE(CASE_STMT) {
209 replacements_[node->id()].type = SimdType::kInt16;
210 break;
211 }
212 case IrOpcode::kS16x8Select: {
213 replacements_[node->id()].type = SimdType::kSimd1x8;
214 break;
215 }
159 default: { 216 default: {
160 replacements_[node->id()].type = replacements_[output->id()].type; 217 replacements_[node->id()].type = replacements_[output->id()].type;
161 } 218 }
162 } 219 }
163 } 220 }
164 #undef CASE_STMT 221 #undef CASE_STMT
165 } 222 }
166 } 223 }
167 224
168 static int GetParameterIndexAfterLowering( 225 static int GetParameterIndexAfterLowering(
(...skipping 23 matching lines...) Expand all
192 Signature<MachineRepresentation>* signature) { 249 Signature<MachineRepresentation>* signature) {
193 int result = static_cast<int>(signature->return_count()); 250 int result = static_cast<int>(signature->return_count());
194 for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) { 251 for (int i = 0; i < static_cast<int>(signature->return_count()); ++i) {
195 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) { 252 if (signature->GetReturn(i) == MachineRepresentation::kSimd128) {
196 result += 3; 253 result += 3;
197 } 254 }
198 } 255 }
199 return result; 256 return result;
200 } 257 }
201 258
202 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices) { 259 int SimdScalarLowering::NumLanes(SimdType type) {
260 int num_lanes = 0;
261 if (type == SimdType::kFloat32 || type == SimdType::kInt32 ||
262 type == SimdType::kSimd1x4) {
263 num_lanes = kNumLanes32;
264 } else if (type == SimdType::kInt16 || type == SimdType::kSimd1x8) {
265 num_lanes = kNumLanes16;
266 } else {
267 UNREACHABLE();
268 }
269 return num_lanes;
270 }
271
272 void SimdScalarLowering::GetIndexNodes(Node* index, Node** new_indices,
273 SimdType type) {
203 new_indices[0] = index; 274 new_indices[0] = index;
204 for (size_t i = 1; i < kMaxLanes; ++i) { 275 int num_lanes = NumLanes(type);
276 int lane_width = kSimd128Size / num_lanes;
277 for (int i = 1; i < num_lanes; ++i) {
205 new_indices[i] = graph()->NewNode(machine()->Int32Add(), index, 278 new_indices[i] = graph()->NewNode(machine()->Int32Add(), index,
206 graph()->NewNode(common()->Int32Constant( 279 graph()->NewNode(common()->Int32Constant(
207 static_cast<int>(i) * kLaneWidth))); 280 static_cast<int>(i) * lane_width)));
208 } 281 }
209 } 282 }
210 283
211 void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node, 284 void SimdScalarLowering::LowerLoadOp(MachineRepresentation rep, Node* node,
212 const Operator* load_op) { 285 const Operator* load_op, SimdType type) {
213 if (rep == MachineRepresentation::kSimd128) { 286 if (rep == MachineRepresentation::kSimd128) {
214 Node* base = node->InputAt(0); 287 Node* base = node->InputAt(0);
215 Node* index = node->InputAt(1); 288 Node* index = node->InputAt(1);
216 Node* indices[kMaxLanes]; 289 int num_lanes = NumLanes(type);
217 GetIndexNodes(index, indices); 290 Node** indices = zone()->NewArray<Node*>(num_lanes);
218 Node* rep_nodes[kMaxLanes]; 291 GetIndexNodes(index, indices, type);
292 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
219 rep_nodes[0] = node; 293 rep_nodes[0] = node;
220 NodeProperties::ChangeOp(rep_nodes[0], load_op); 294 NodeProperties::ChangeOp(rep_nodes[0], load_op);
221 if (node->InputCount() > 2) { 295 if (node->InputCount() > 2) {
222 DCHECK(node->InputCount() > 3); 296 DCHECK(node->InputCount() > 3);
223 Node* effect_input = node->InputAt(2); 297 Node* effect_input = node->InputAt(2);
224 Node* control_input = node->InputAt(3); 298 Node* control_input = node->InputAt(3);
225 rep_nodes[3] = graph()->NewNode(load_op, base, indices[3], effect_input, 299 for (int i = num_lanes - 1; i > 0; --i) {
226 control_input); 300 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i], effect_input,
227 rep_nodes[2] = graph()->NewNode(load_op, base, indices[2], rep_nodes[3], 301 control_input);
228 control_input); 302 effect_input = rep_nodes[i];
229 rep_nodes[1] = graph()->NewNode(load_op, base, indices[1], rep_nodes[2], 303 }
230 control_input);
231 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]); 304 rep_nodes[0]->ReplaceInput(2, rep_nodes[1]);
232 } else { 305 } else {
233 for (size_t i = 1; i < kMaxLanes; ++i) { 306 for (int i = 1; i < num_lanes; ++i) {
234 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]); 307 rep_nodes[i] = graph()->NewNode(load_op, base, indices[i]);
235 } 308 }
236 } 309 }
237 ReplaceNode(node, rep_nodes); 310 ReplaceNode(node, rep_nodes, num_lanes);
238 } else { 311 } else {
239 DefaultLowering(node); 312 DefaultLowering(node);
240 } 313 }
241 } 314 }
242 315
243 void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node, 316 void SimdScalarLowering::LowerStoreOp(MachineRepresentation rep, Node* node,
244 const Operator* store_op, 317 const Operator* store_op,
245 SimdType rep_type) { 318 SimdType rep_type) {
246 if (rep == MachineRepresentation::kSimd128) { 319 if (rep == MachineRepresentation::kSimd128) {
247 Node* base = node->InputAt(0); 320 Node* base = node->InputAt(0);
248 Node* index = node->InputAt(1); 321 Node* index = node->InputAt(1);
249 Node* indices[kMaxLanes]; 322 int num_lanes = NumLanes(rep_type);
250 GetIndexNodes(index, indices); 323 Node** indices = zone()->NewArray<Node*>(num_lanes);
324 GetIndexNodes(index, indices, rep_type);
251 DCHECK(node->InputCount() > 2); 325 DCHECK(node->InputCount() > 2);
252 Node* value = node->InputAt(2); 326 Node* value = node->InputAt(2);
253 DCHECK(HasReplacement(1, value)); 327 DCHECK(HasReplacement(1, value));
254 Node* rep_nodes[kMaxLanes]; 328 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
255 rep_nodes[0] = node; 329 rep_nodes[0] = node;
256 Node** rep_inputs = GetReplacementsWithType(value, rep_type); 330 Node** rep_inputs = GetReplacementsWithType(value, rep_type);
257 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]); 331 rep_nodes[0]->ReplaceInput(2, rep_inputs[0]);
258 NodeProperties::ChangeOp(node, store_op); 332 NodeProperties::ChangeOp(node, store_op);
259 if (node->InputCount() > 3) { 333 if (node->InputCount() > 3) {
260 DCHECK(node->InputCount() > 4); 334 DCHECK(node->InputCount() > 4);
261 Node* effect_input = node->InputAt(3); 335 Node* effect_input = node->InputAt(3);
262 Node* control_input = node->InputAt(4); 336 Node* control_input = node->InputAt(4);
263 rep_nodes[3] = graph()->NewNode(store_op, base, indices[3], rep_inputs[3], 337 for (int i = num_lanes - 1; i > 0; --i) {
264 effect_input, control_input); 338 rep_nodes[i] =
265 rep_nodes[2] = graph()->NewNode(store_op, base, indices[2], rep_inputs[2], 339 graph()->NewNode(store_op, base, indices[i], rep_inputs[i],
266 rep_nodes[3], control_input); 340 effect_input, control_input);
267 rep_nodes[1] = graph()->NewNode(store_op, base, indices[1], rep_inputs[1], 341 effect_input = rep_nodes[i];
268 rep_nodes[2], control_input); 342 }
269 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]); 343 rep_nodes[0]->ReplaceInput(3, rep_nodes[1]);
270 344
271 } else { 345 } else {
272 for (size_t i = 1; i < kMaxLanes; ++i) { 346 for (int i = 1; i < num_lanes; ++i) {
273 rep_nodes[i] = 347 rep_nodes[i] =
274 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]); 348 graph()->NewNode(store_op, base, indices[i], rep_inputs[i]);
275 } 349 }
276 } 350 }
277 351
278 ReplaceNode(node, rep_nodes); 352 ReplaceNode(node, rep_nodes, num_lanes);
279 } else { 353 } else {
280 DefaultLowering(node); 354 DefaultLowering(node);
281 } 355 }
282 } 356 }
283 357
284 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type, 358 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
285 const Operator* op, bool invert_inputs) { 359 const Operator* op, bool invert_inputs) {
286 DCHECK(node->InputCount() == 2); 360 DCHECK(node->InputCount() == 2);
287 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); 361 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
288 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); 362 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
289 Node* rep_node[kMaxLanes]; 363 int num_lanes = NumLanes(input_rep_type);
290 for (int i = 0; i < kMaxLanes; ++i) { 364 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
365 for (int i = 0; i < num_lanes; ++i) {
291 if (invert_inputs) { 366 if (invert_inputs) {
292 rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]); 367 rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]);
293 } else { 368 } else {
294 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); 369 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
295 } 370 }
296 } 371 }
297 ReplaceNode(node, rep_node); 372 ReplaceNode(node, rep_node, num_lanes);
373 }
374
375 Node* SimdScalarLowering::FixUpperBits(Node* input, int32_t shift) {
376 return graph()->NewNode(machine()->Word32Sar(),
377 graph()->NewNode(machine()->Word32Shl(), input,
378 jsgraph_->Int32Constant(shift)),
379 jsgraph_->Int32Constant(shift));
380 }
381
382 void SimdScalarLowering::LowerBinaryOpForSmallInt(Node* node,
383 SimdType input_rep_type,
384 const Operator* op) {
385 DCHECK(node->InputCount() == 2);
386 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
387 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
388 int num_lanes = NumLanes(input_rep_type);
389 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
390 for (int i = 0; i < num_lanes; ++i) {
391 rep_node[i] =
392 FixUpperBits(graph()->NewNode(op, rep_left[i], rep_right[i]), kShift16);
393 }
394 ReplaceNode(node, rep_node, num_lanes);
395 }
396
397 Node* SimdScalarLowering::Mask(Node* input, int32_t mask) {
398 return graph()->NewNode(machine()->Word32And(), input,
399 jsgraph_->Int32Constant(mask));
400 }
401
402 void SimdScalarLowering::LowerSaturateBinaryOp(Node* node,
403 SimdType input_rep_type,
404 const Operator* op,
405 bool is_signed) {
406 DCHECK(node->InputCount() == 2);
407 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
408 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
409 int32_t min = 0;
410 int32_t max = 0;
411 if (is_signed) {
412 min = std::numeric_limits<int16_t>::min();
413 max = std::numeric_limits<int16_t>::max();
414 } else {
415 min = std::numeric_limits<uint16_t>::min();
416 max = std::numeric_limits<uint16_t>::max();
417 }
418 int num_lanes = NumLanes(input_rep_type);
419 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
420 for (int i = 0; i < num_lanes; ++i) {
421 Node* op_result = nullptr;
422 Node* left = is_signed ? rep_left[i] : Mask(rep_left[i], kMask16);
423 Node* right = is_signed ? rep_right[i] : Mask(rep_right[i], kMask16);
424 op_result = graph()->NewNode(op, left, right);
425 Diamond d_min(graph(), common(),
426 graph()->NewNode(machine()->Int32LessThan(), op_result,
427 jsgraph_->Int32Constant(min)));
428 rep_node[i] = d_min.Phi(MachineRepresentation::kWord16,
429 jsgraph_->Int32Constant(min), op_result);
430 Diamond d_max(graph(), common(),
431 graph()->NewNode(machine()->Int32LessThan(),
432 jsgraph_->Int32Constant(max), rep_node[i]));
433 rep_node[i] = d_max.Phi(MachineRepresentation::kWord16,
434 jsgraph_->Int32Constant(max), rep_node[i]);
435 rep_node[i] = is_signed ? rep_node[i] : FixUpperBits(rep_node[i], kShift16);
436 }
437 ReplaceNode(node, rep_node, num_lanes);
298 } 438 }
299 439
300 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, 440 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
301 const Operator* op) { 441 const Operator* op) {
302 DCHECK(node->InputCount() == 1); 442 DCHECK(node->InputCount() == 1);
303 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); 443 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);
304 Node* rep_node[kMaxLanes]; 444 int num_lanes = NumLanes(input_rep_type);
305 for (int i = 0; i < kMaxLanes; ++i) { 445 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
446 for (int i = 0; i < num_lanes; ++i) {
306 rep_node[i] = graph()->NewNode(op, rep[i]); 447 rep_node[i] = graph()->NewNode(op, rep[i]);
307 } 448 }
308 ReplaceNode(node, rep_node); 449 ReplaceNode(node, rep_node, num_lanes);
309 } 450 }
310 451
311 void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op, 452 void SimdScalarLowering::LowerIntMinMax(Node* node, const Operator* op,
312 bool is_max) { 453 bool is_max, SimdType type) {
313 DCHECK(node->InputCount() == 2); 454 DCHECK(node->InputCount() == 2);
314 Node** rep_left = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); 455 Node** rep_left = GetReplacementsWithType(node->InputAt(0), type);
315 Node** rep_right = 456 Node** rep_right = GetReplacementsWithType(node->InputAt(1), type);
316 GetReplacementsWithType(node->InputAt(1), SimdType::kInt32); 457 int num_lanes = NumLanes(type);
317 Node* rep_node[kMaxLanes]; 458 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
318 for (int i = 0; i < kMaxLanes; ++i) { 459 MachineRepresentation rep = MachineRepresentation::kNone;
460 if (type == SimdType::kInt32) {
461 rep = MachineRepresentation::kWord32;
462 } else if (type == SimdType::kInt16) {
463 rep = MachineRepresentation::kWord16;
464 } else {
465 UNREACHABLE();
466 }
467 for (int i = 0; i < num_lanes; ++i) {
319 Diamond d(graph(), common(), 468 Diamond d(graph(), common(),
320 graph()->NewNode(op, rep_left[i], rep_right[i])); 469 graph()->NewNode(op, rep_left[i], rep_right[i]));
321 if (is_max) { 470 if (is_max) {
322 rep_node[i] = 471 rep_node[i] = d.Phi(rep, rep_right[i], rep_left[i]);
323 d.Phi(MachineRepresentation::kWord32, rep_right[i], rep_left[i]);
324 } else { 472 } else {
325 rep_node[i] = 473 rep_node[i] = d.Phi(rep, rep_left[i], rep_right[i]);
326 d.Phi(MachineRepresentation::kWord32, rep_left[i], rep_right[i]);
327 } 474 }
328 } 475 }
329 ReplaceNode(node, rep_node); 476 ReplaceNode(node, rep_node, num_lanes);
330 } 477 }
331 478
332 Node* SimdScalarLowering::BuildF64Trunc(Node* input) { 479 Node* SimdScalarLowering::BuildF64Trunc(Node* input) {
333 if (machine()->Float64RoundTruncate().IsSupported()) { 480 if (machine()->Float64RoundTruncate().IsSupported()) {
334 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input); 481 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input);
335 } else { 482 } else {
336 ExternalReference ref = 483 ExternalReference ref =
337 ExternalReference::wasm_f64_trunc(jsgraph_->isolate()); 484 ExternalReference::wasm_f64_trunc(jsgraph_->isolate());
338 Node* stack_slot = 485 Node* stack_slot =
339 graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64)); 486 graph()->NewNode(machine()->StackSlot(MachineRepresentation::kFloat64));
(...skipping 15 matching lines...) Expand all
355 Node* call = graph()->NewNode(common()->Call(desc), 4, args); 502 Node* call = graph()->NewNode(common()->Call(desc), 4, args);
356 return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()), 503 return graph()->NewNode(machine()->Load(LoadRepresentation::Float64()),
357 stack_slot, jsgraph_->Int32Constant(0), call, 504 stack_slot, jsgraph_->Int32Constant(0), call,
358 graph()->start()); 505 graph()->start());
359 } 506 }
360 } 507 }
361 508
362 void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) { 509 void SimdScalarLowering::LowerConvertFromFloat(Node* node, bool is_signed) {
363 DCHECK(node->InputCount() == 1); 510 DCHECK(node->InputCount() == 1);
364 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32); 511 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kFloat32);
365 Node* rep_node[kMaxLanes]; 512 Node* rep_node[kNumLanes32];
366 Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0)); 513 Node* double_zero = graph()->NewNode(common()->Float64Constant(0.0));
367 Node* min = graph()->NewNode( 514 Node* min = graph()->NewNode(
368 common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0))); 515 common()->Float64Constant(static_cast<double>(is_signed ? kMinInt : 0)));
369 Node* max = graph()->NewNode(common()->Float64Constant( 516 Node* max = graph()->NewNode(common()->Float64Constant(
370 static_cast<double>(is_signed ? kMaxInt : 0xffffffffu))); 517 static_cast<double>(is_signed ? kMaxInt : 0xffffffffu)));
371 for (int i = 0; i < kMaxLanes; ++i) { 518 for (int i = 0; i < kNumLanes32; ++i) {
372 Node* double_rep = 519 Node* double_rep =
373 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]); 520 graph()->NewNode(machine()->ChangeFloat32ToFloat64(), rep[i]);
374 Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(), 521 Diamond nan_d(graph(), common(), graph()->NewNode(machine()->Float64Equal(),
375 double_rep, double_rep)); 522 double_rep, double_rep));
376 Node* temp = 523 Node* temp =
377 nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero); 524 nan_d.Phi(MachineRepresentation::kFloat64, double_rep, double_zero);
378 Diamond min_d(graph(), common(), 525 Diamond min_d(graph(), common(),
379 graph()->NewNode(machine()->Float64LessThan(), temp, min)); 526 graph()->NewNode(machine()->Float64LessThan(), temp, min));
380 temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp); 527 temp = min_d.Phi(MachineRepresentation::kFloat64, min, temp);
381 Diamond max_d(graph(), common(), 528 Diamond max_d(graph(), common(),
382 graph()->NewNode(machine()->Float64LessThan(), max, temp)); 529 graph()->NewNode(machine()->Float64LessThan(), max, temp));
383 temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp); 530 temp = max_d.Phi(MachineRepresentation::kFloat64, max, temp);
384 Node* trunc = BuildF64Trunc(temp); 531 Node* trunc = BuildF64Trunc(temp);
385 if (is_signed) { 532 if (is_signed) {
386 rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc); 533 rep_node[i] = graph()->NewNode(machine()->ChangeFloat64ToInt32(), trunc);
387 } else { 534 } else {
388 rep_node[i] = 535 rep_node[i] =
389 graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc); 536 graph()->NewNode(machine()->TruncateFloat64ToUint32(), trunc);
390 } 537 }
391 } 538 }
392 ReplaceNode(node, rep_node); 539 ReplaceNode(node, rep_node, kNumLanes32);
393 } 540 }
394 541
395 void SimdScalarLowering::LowerShiftOp(Node* node, const Operator* op) { 542 void SimdScalarLowering::LowerShiftOp(Node* node, SimdType type) {
396 static int32_t shift_mask = 0x1f;
397 DCHECK_EQ(1, node->InputCount()); 543 DCHECK_EQ(1, node->InputCount());
398 int32_t shift_amount = OpParameter<int32_t>(node); 544 int32_t shift_amount = OpParameter<int32_t>(node);
399 Node* shift_node = 545 Node* shift_node = graph()->NewNode(common()->Int32Constant(shift_amount));
400 graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); 546 Node** rep = GetReplacementsWithType(node->InputAt(0), type);
401 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); 547 int num_lanes = NumLanes(type);
402 Node* rep_node[kMaxLanes]; 548 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
403 for (int i = 0; i < kMaxLanes; ++i) { 549 for (int i = 0; i < num_lanes; ++i) {
404 rep_node[i] = graph()->NewNode(op, rep[i], shift_node); 550 rep_node[i] = rep[i];
551 switch (node->opcode()) {
552 case IrOpcode::kI16x8ShrU:
553 rep_node[i] = Mask(rep_node[i], kMask16);
bbudge 2017/04/27 18:03:42 Comment that you intend to fall through here, i.e.
aseemgarg 2017/04/28 20:50:41 Done.
554 case IrOpcode::kI32x4ShrU:
555 rep_node[i] =
556 graph()->NewNode(machine()->Word32Shr(), rep_node[i], shift_node);
557 break;
558 case IrOpcode::kI32x4Shl:
559 case IrOpcode::kI16x8Shl:
560 rep_node[i] =
561 graph()->NewNode(machine()->Word32Shl(), rep_node[i], shift_node);
562 break;
563 case IrOpcode::kI32x4ShrS:
564 case IrOpcode::kI16x8ShrS:
565 rep_node[i] =
566 graph()->NewNode(machine()->Word32Sar(), rep_node[i], shift_node);
567 break;
568 default:
569 UNREACHABLE();
570 }
571 if (node->opcode() == IrOpcode::kI16x8Shl) {
bbudge 2017/04/27 18:03:42 Move this up with the shift cases it modifies.
aseemgarg 2017/04/28 20:50:41 removed if and separated cases. Seems cleaner.
572 rep_node[i] = FixUpperBits(rep_node[i], kShift16);
573 }
405 } 574 }
406 ReplaceNode(node, rep_node); 575 ReplaceNode(node, rep_node, num_lanes);
407 } 576 }
408 577
409 void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type, 578 void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
410 const Operator* op) { 579 const Operator* op) {
411 DCHECK(node->InputCount() == 2); 580 DCHECK(node->InputCount() == 2);
412 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); 581 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
413 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); 582 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
414 Node* rep_node[kMaxLanes]; 583 int num_lanes = NumLanes(input_rep_type);
415 for (int i = 0; i < kMaxLanes; ++i) { 584 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
585 for (int i = 0; i < num_lanes; ++i) {
416 Diamond d(graph(), common(), 586 Diamond d(graph(), common(),
417 graph()->NewNode(op, rep_left[i], rep_right[i])); 587 graph()->NewNode(op, rep_left[i], rep_right[i]));
418 rep_node[i] = d.Phi(MachineRepresentation::kWord32, 588 rep_node[i] = d.Phi(MachineRepresentation::kWord32,
419 jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1)); 589 jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1));
420 } 590 }
421 ReplaceNode(node, rep_node); 591 ReplaceNode(node, rep_node, num_lanes);
422 } 592 }
423 593
424 void SimdScalarLowering::LowerNode(Node* node) { 594 void SimdScalarLowering::LowerNode(Node* node) {
425 SimdType rep_type = ReplacementType(node); 595 SimdType rep_type = ReplacementType(node);
596 int num_lanes = NumLanes(rep_type);
426 switch (node->opcode()) { 597 switch (node->opcode()) {
427 case IrOpcode::kStart: { 598 case IrOpcode::kStart: {
428 int parameter_count = GetParameterCountAfterLowering(); 599 int parameter_count = GetParameterCountAfterLowering();
429 // Only exchange the node if the parameter count actually changed. 600 // Only exchange the node if the parameter count actually changed.
430 if (parameter_count != static_cast<int>(signature()->parameter_count())) { 601 if (parameter_count != static_cast<int>(signature()->parameter_count())) {
431 int delta = 602 int delta =
432 parameter_count - static_cast<int>(signature()->parameter_count()); 603 parameter_count - static_cast<int>(signature()->parameter_count());
433 int new_output_count = node->op()->ValueOutputCount() + delta; 604 int new_output_count = node->op()->ValueOutputCount() + delta;
434 NodeProperties::ChangeOp(node, common()->Start(new_output_count)); 605 NodeProperties::ChangeOp(node, common()->Start(new_output_count));
435 } 606 }
436 break; 607 break;
437 } 608 }
438 case IrOpcode::kParameter: { 609 case IrOpcode::kParameter: {
439 DCHECK(node->InputCount() == 1); 610 DCHECK(node->InputCount() == 1);
440 // Only exchange the node if the parameter count actually changed. We do 611 // Only exchange the node if the parameter count actually changed. We do
441 // not even have to do the default lowering because the the start node, 612 // not even have to do the default lowering because the the start node,
442 // the only input of a parameter node, only changes if the parameter count 613 // the only input of a parameter node, only changes if the parameter count
443 // changes. 614 // changes.
444 if (GetParameterCountAfterLowering() != 615 if (GetParameterCountAfterLowering() !=
445 static_cast<int>(signature()->parameter_count())) { 616 static_cast<int>(signature()->parameter_count())) {
446 int old_index = ParameterIndexOf(node->op()); 617 int old_index = ParameterIndexOf(node->op());
447 int new_index = GetParameterIndexAfterLowering(signature(), old_index); 618 int new_index = GetParameterIndexAfterLowering(signature(), old_index);
448 if (old_index == new_index) { 619 if (old_index == new_index) {
449 NodeProperties::ChangeOp(node, common()->Parameter(new_index)); 620 NodeProperties::ChangeOp(node, common()->Parameter(new_index));
450 621
451 Node* new_node[kMaxLanes]; 622 Node* new_node[kNumLanes32];
452 for (int i = 0; i < kMaxLanes; ++i) { 623 for (int i = 0; i < kNumLanes32; ++i) {
453 new_node[i] = nullptr; 624 new_node[i] = nullptr;
454 } 625 }
455 new_node[0] = node; 626 new_node[0] = node;
456 if (signature()->GetParam(old_index) == 627 if (signature()->GetParam(old_index) ==
457 MachineRepresentation::kSimd128) { 628 MachineRepresentation::kSimd128) {
458 for (int i = 1; i < kMaxLanes; ++i) { 629 for (int i = 1; i < kNumLanes32; ++i) {
459 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i), 630 new_node[i] = graph()->NewNode(common()->Parameter(new_index + i),
460 graph()->start()); 631 graph()->start());
461 } 632 }
462 } 633 }
463 ReplaceNode(node, new_node); 634 ReplaceNode(node, new_node, kNumLanes32);
464 } 635 }
465 } 636 }
466 break; 637 break;
467 } 638 }
468 case IrOpcode::kLoad: { 639 case IrOpcode::kLoad: {
469 MachineRepresentation rep = 640 MachineRepresentation rep =
470 LoadRepresentationOf(node->op()).representation(); 641 LoadRepresentationOf(node->op()).representation();
471 const Operator* load_op; 642 const Operator* load_op;
472 if (rep_type == SimdType::kInt32) { 643 #define LOAD_CASE(sType, mType) \
473 load_op = machine()->Load(MachineType::Int32()); 644 case SimdType::k##sType: \
474 } else if (rep_type == SimdType::kFloat32) { 645 load_op = machine()->Load(MachineType::mType()); \
475 load_op = machine()->Load(MachineType::Float32()); 646 break;
647
648 switch (rep_type) {
649 FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(LOAD_CASE)
650 default:
651 UNREACHABLE();
476 } 652 }
477 LowerLoadOp(rep, node, load_op); 653 #undef LOAD_CASE
654 LowerLoadOp(rep, node, load_op, rep_type);
478 break; 655 break;
479 } 656 }
480 case IrOpcode::kUnalignedLoad: { 657 case IrOpcode::kUnalignedLoad: {
481 MachineRepresentation rep = 658 MachineRepresentation rep =
482 UnalignedLoadRepresentationOf(node->op()).representation(); 659 UnalignedLoadRepresentationOf(node->op()).representation();
483 const Operator* load_op; 660 const Operator* load_op;
484 if (rep_type == SimdType::kInt32) { 661 #define UNALIGNED_LOAD_CASE(sType, mType) \
485 load_op = machine()->UnalignedLoad(MachineType::Int32()); 662 case SimdType::k##sType: \
486 } else if (rep_type == SimdType::kFloat32) { 663 load_op = machine()->UnalignedLoad(MachineType::mType()); \
487 load_op = machine()->UnalignedLoad(MachineType::Float32()); 664 break;
665
666 switch (rep_type) {
667 FOREACH_SIMD_TYPE_TO_MACHINE_TYPE(UNALIGNED_LOAD_CASE)
668 default:
669 UNREACHABLE();
488 } 670 }
489 LowerLoadOp(rep, node, load_op); 671 #undef UNALIGHNED_LOAD_CASE
672 LowerLoadOp(rep, node, load_op, rep_type);
490 break; 673 break;
491 } 674 }
492 case IrOpcode::kStore: { 675 case IrOpcode::kStore: {
493 MachineRepresentation rep = 676 MachineRepresentation rep =
494 StoreRepresentationOf(node->op()).representation(); 677 StoreRepresentationOf(node->op()).representation();
495 WriteBarrierKind write_barrier_kind = 678 WriteBarrierKind write_barrier_kind =
496 StoreRepresentationOf(node->op()).write_barrier_kind(); 679 StoreRepresentationOf(node->op()).write_barrier_kind();
497 const Operator* store_op; 680 const Operator* store_op;
498 if (rep_type == SimdType::kInt32) { 681 #define STORE_CASE(sType, mType) \
499 store_op = machine()->Store(StoreRepresentation( 682 case SimdType::k##sType: \
500 MachineRepresentation::kWord32, write_barrier_kind)); 683 store_op = machine()->Store(StoreRepresentation( \
501 } else { 684 MachineRepresentation::k##mType, write_barrier_kind)); \
502 store_op = machine()->Store(StoreRepresentation( 685 break;
503 MachineRepresentation::kFloat32, write_barrier_kind)); 686
687 switch (rep_type) {
688 FOREACH_SIMD_TYPE_TO_MACHINE_REP(STORE_CASE)
689 default:
690 UNREACHABLE();
504 } 691 }
692 #undef STORE_CASE
505 LowerStoreOp(rep, node, store_op, rep_type); 693 LowerStoreOp(rep, node, store_op, rep_type);
506 break; 694 break;
507 } 695 }
508 case IrOpcode::kUnalignedStore: { 696 case IrOpcode::kUnalignedStore: {
509 MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op()); 697 MachineRepresentation rep = UnalignedStoreRepresentationOf(node->op());
510 const Operator* store_op; 698 const Operator* store_op;
511 if (rep_type == SimdType::kInt32) { 699 #define UNALIGNED_STORE_CASE(sType, mType) \
512 store_op = machine()->UnalignedStore(MachineRepresentation::kWord32); 700 case SimdType::k##sType: \
513 } else { 701 store_op = machine()->UnalignedStore(MachineRepresentation::k##mType); \
514 store_op = machine()->UnalignedStore(MachineRepresentation::kFloat32); 702 break;
703
704 switch (rep_type) {
705 FOREACH_SIMD_TYPE_TO_MACHINE_REP(UNALIGNED_STORE_CASE)
706 default:
707 UNREACHABLE();
515 } 708 }
709 #undef UNALIGNED_STORE_CASE
516 LowerStoreOp(rep, node, store_op, rep_type); 710 LowerStoreOp(rep, node, store_op, rep_type);
517 break; 711 break;
518 } 712 }
519 case IrOpcode::kReturn: { 713 case IrOpcode::kReturn: {
520 DefaultLowering(node); 714 DefaultLowering(node);
521 int new_return_count = GetReturnCountAfterLowering(signature()); 715 int new_return_count = GetReturnCountAfterLowering(signature());
522 if (static_cast<int>(signature()->return_count()) != new_return_count) { 716 if (static_cast<int>(signature()->return_count()) != new_return_count) {
523 NodeProperties::ChangeOp(node, common()->Return(new_return_count)); 717 NodeProperties::ChangeOp(node, common()->Return(new_return_count));
524 } 718 }
525 break; 719 break;
526 } 720 }
527 case IrOpcode::kCall: { 721 case IrOpcode::kCall: {
528 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor. 722 // TODO(turbofan): Make WASM code const-correct wrt. CallDescriptor.
529 CallDescriptor* descriptor = 723 CallDescriptor* descriptor =
530 const_cast<CallDescriptor*>(CallDescriptorOf(node->op())); 724 const_cast<CallDescriptor*>(CallDescriptorOf(node->op()));
531 if (DefaultLowering(node) || 725 if (DefaultLowering(node) ||
532 (descriptor->ReturnCount() == 1 && 726 (descriptor->ReturnCount() == 1 &&
533 descriptor->GetReturnType(0) == MachineType::Simd128())) { 727 descriptor->GetReturnType(0) == MachineType::Simd128())) {
534 // We have to adjust the call descriptor. 728 // We have to adjust the call descriptor.
535 const Operator* op = 729 const Operator* op =
536 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd( 730 common()->Call(wasm::ModuleEnv::GetI32WasmCallDescriptorForSimd(
537 zone(), descriptor)); 731 zone(), descriptor));
538 NodeProperties::ChangeOp(node, op); 732 NodeProperties::ChangeOp(node, op);
539 } 733 }
540 if (descriptor->ReturnCount() == 1 && 734 if (descriptor->ReturnCount() == 1 &&
541 descriptor->GetReturnType(0) == MachineType::Simd128()) { 735 descriptor->GetReturnType(0) == MachineType::Simd128()) {
542 // We access the additional return values through projections. 736 // We access the additional return values through projections.
543 Node* rep_node[kMaxLanes]; 737 Node* rep_node[kNumLanes32];
544 for (int i = 0; i < kMaxLanes; ++i) { 738 for (int i = 0; i < kNumLanes32; ++i) {
545 rep_node[i] = 739 rep_node[i] =
546 graph()->NewNode(common()->Projection(i), node, graph()->start()); 740 graph()->NewNode(common()->Projection(i), node, graph()->start());
547 } 741 }
548 ReplaceNode(node, rep_node); 742 ReplaceNode(node, rep_node, kNumLanes32);
549 } 743 }
550 break; 744 break;
551 } 745 }
552 case IrOpcode::kPhi: { 746 case IrOpcode::kPhi: {
553 MachineRepresentation rep = PhiRepresentationOf(node->op()); 747 MachineRepresentation rep = PhiRepresentationOf(node->op());
554 if (rep == MachineRepresentation::kSimd128) { 748 if (rep == MachineRepresentation::kSimd128) {
555 // The replacement nodes have already been created, we only have to 749 // The replacement nodes have already been created, we only have to
556 // replace placeholder nodes. 750 // replace placeholder nodes.
557 Node** rep_node = GetReplacements(node); 751 Node** rep_node = GetReplacements(node);
558 for (int i = 0; i < node->op()->ValueInputCount(); ++i) { 752 for (int i = 0; i < node->op()->ValueInputCount(); ++i) {
559 Node** rep_input = 753 Node** rep_input =
560 GetReplacementsWithType(node->InputAt(i), rep_type); 754 GetReplacementsWithType(node->InputAt(i), rep_type);
561 for (int j = 0; j < kMaxLanes; j++) { 755 for (int j = 0; j < num_lanes; j++) {
562 rep_node[j]->ReplaceInput(i, rep_input[j]); 756 rep_node[j]->ReplaceInput(i, rep_input[j]);
563 } 757 }
564 } 758 }
565 } else { 759 } else {
566 DefaultLowering(node); 760 DefaultLowering(node);
567 } 761 }
568 break; 762 break;
569 } 763 }
570 #define I32X4_BINOP_CASE(opcode, instruction) \ 764 #define I32X4_BINOP_CASE(opcode, instruction) \
571 case IrOpcode::opcode: { \ 765 case IrOpcode::opcode: { \
572 LowerBinaryOp(node, rep_type, machine()->instruction()); \ 766 LowerBinaryOp(node, rep_type, machine()->instruction()); \
573 break; \ 767 break; \
574 } 768 }
575 I32X4_BINOP_CASE(kI32x4Add, Int32Add) 769 I32X4_BINOP_CASE(kI32x4Add, Int32Add)
576 I32X4_BINOP_CASE(kI32x4Sub, Int32Sub) 770 I32X4_BINOP_CASE(kI32x4Sub, Int32Sub)
577 I32X4_BINOP_CASE(kI32x4Mul, Int32Mul) 771 I32X4_BINOP_CASE(kI32x4Mul, Int32Mul)
578 I32X4_BINOP_CASE(kS128And, Word32And) 772 I32X4_BINOP_CASE(kS128And, Word32And)
579 I32X4_BINOP_CASE(kS128Or, Word32Or) 773 I32X4_BINOP_CASE(kS128Or, Word32Or)
580 I32X4_BINOP_CASE(kS128Xor, Word32Xor) 774 I32X4_BINOP_CASE(kS128Xor, Word32Xor)
581 #undef I32X4_BINOP_CASE 775 #undef I32X4_BINOP_CASE
582 case IrOpcode::kI32x4MaxS: { 776 case IrOpcode::kI16x8Add: {
583 LowerIntMinMax(node, machine()->Int32LessThan(), true); 777 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Add());
584 break; 778 break;
585 } 779 }
586 case IrOpcode::kI32x4MinS: { 780 case IrOpcode::kI16x8Sub: {
587 LowerIntMinMax(node, machine()->Int32LessThan(), false); 781 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Sub());
588 break; 782 break;
589 } 783 }
590 case IrOpcode::kI32x4MaxU: { 784 case IrOpcode::kI16x8Mul: {
591 LowerIntMinMax(node, machine()->Uint32LessThan(), true); 785 LowerBinaryOpForSmallInt(node, rep_type, machine()->Int32Mul());
592 break; 786 break;
593 } 787 }
594 case IrOpcode::kI32x4MinU: { 788 case IrOpcode::kI16x8AddSaturateS: {
595 LowerIntMinMax(node, machine()->Uint32LessThan(), false); 789 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), true);
790 break;
791 }
792 case IrOpcode::kI16x8SubSaturateS: {
793 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), true);
794 break;
795 }
796 case IrOpcode::kI16x8AddSaturateU: {
797 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Add(), false);
798 break;
799 }
800 case IrOpcode::kI16x8SubSaturateU: {
801 LowerSaturateBinaryOp(node, rep_type, machine()->Int32Sub(), false);
802 break;
803 }
804 case IrOpcode::kI32x4MaxS:
805 case IrOpcode::kI16x8MaxS: {
806 LowerIntMinMax(node, machine()->Int32LessThan(), true, rep_type);
807 break;
808 }
809 case IrOpcode::kI32x4MinS:
810 case IrOpcode::kI16x8MinS: {
811 LowerIntMinMax(node, machine()->Int32LessThan(), false, rep_type);
812 break;
813 }
814 case IrOpcode::kI32x4MaxU:
815 case IrOpcode::kI16x8MaxU: {
816 LowerIntMinMax(node, machine()->Uint32LessThan(), true, rep_type);
817 break;
818 }
819 case IrOpcode::kI32x4MinU:
820 case IrOpcode::kI16x8MinU: {
821 LowerIntMinMax(node, machine()->Uint32LessThan(), false, rep_type);
596 break; 822 break;
597 } 823 }
598 case IrOpcode::kI32x4Neg: { 824 case IrOpcode::kI32x4Neg: {
599 DCHECK(node->InputCount() == 1); 825 DCHECK(node->InputCount() == 1);
600 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); 826 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
601 Node* rep_node[kMaxLanes]; 827 Node* rep_node[kNumLanes32];
602 Node* zero = graph()->NewNode(common()->Int32Constant(0)); 828 Node* zero = graph()->NewNode(common()->Int32Constant(0));
603 for (int i = 0; i < kMaxLanes; ++i) { 829 for (int i = 0; i < kNumLanes32; ++i) {
604 rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]); 830 rep_node[i] = graph()->NewNode(machine()->Int32Sub(), zero, rep[i]);
605 } 831 }
606 ReplaceNode(node, rep_node); 832 ReplaceNode(node, rep_node, kNumLanes32);
607 break; 833 break;
608 } 834 }
609 case IrOpcode::kS128Not: { 835 case IrOpcode::kS128Not: {
610 DCHECK(node->InputCount() == 1); 836 DCHECK(node->InputCount() == 1);
611 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type); 837 Node** rep = GetReplacementsWithType(node->InputAt(0), rep_type);
612 Node* rep_node[kMaxLanes]; 838 Node* rep_node[kNumLanes32];
613 Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff)); 839 Node* mask = graph()->NewNode(common()->Int32Constant(0xffffffff));
614 for (int i = 0; i < kMaxLanes; ++i) { 840 for (int i = 0; i < kNumLanes32; ++i) {
615 rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask); 841 rep_node[i] = graph()->NewNode(machine()->Word32Xor(), rep[i], mask);
616 } 842 }
617 ReplaceNode(node, rep_node); 843 ReplaceNode(node, rep_node, kNumLanes32);
618 break; 844 break;
619 } 845 }
620 case IrOpcode::kI32x4SConvertF32x4: { 846 case IrOpcode::kI32x4SConvertF32x4: {
621 LowerConvertFromFloat(node, true); 847 LowerConvertFromFloat(node, true);
622 break; 848 break;
623 } 849 }
624 case IrOpcode::kI32x4UConvertF32x4: { 850 case IrOpcode::kI32x4UConvertF32x4: {
625 LowerConvertFromFloat(node, false); 851 LowerConvertFromFloat(node, false);
626 break; 852 break;
627 } 853 }
628 case IrOpcode::kI32x4Shl: { 854 case IrOpcode::kI32x4Shl:
629 LowerShiftOp(node, machine()->Word32Shl()); 855 case IrOpcode::kI16x8Shl:
630 break; 856 case IrOpcode::kI32x4ShrS:
631 } 857 case IrOpcode::kI16x8ShrS:
632 case IrOpcode::kI32x4ShrS: { 858 case IrOpcode::kI32x4ShrU:
633 LowerShiftOp(node, machine()->Word32Sar()); 859 case IrOpcode::kI16x8ShrU: {
634 break; 860 LowerShiftOp(node, rep_type);
635 }
636 case IrOpcode::kI32x4ShrU: {
637 LowerShiftOp(node, machine()->Word32Shr());
638 break; 861 break;
639 } 862 }
640 #define F32X4_BINOP_CASE(name) \ 863 #define F32X4_BINOP_CASE(name) \
641 case IrOpcode::kF32x4##name: { \ 864 case IrOpcode::kF32x4##name: { \
642 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \ 865 LowerBinaryOp(node, rep_type, machine()->Float32##name()); \
643 break; \ 866 break; \
644 } 867 }
645 F32X4_BINOP_CASE(Add) 868 F32X4_BINOP_CASE(Add)
646 F32X4_BINOP_CASE(Sub) 869 F32X4_BINOP_CASE(Sub)
647 F32X4_BINOP_CASE(Mul) 870 F32X4_BINOP_CASE(Mul)
(...skipping 10 matching lines...) Expand all
658 #undef F32x4_UNOP_CASE 881 #undef F32x4_UNOP_CASE
659 case IrOpcode::kF32x4SConvertI32x4: { 882 case IrOpcode::kF32x4SConvertI32x4: {
660 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32()); 883 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundInt32ToFloat32());
661 break; 884 break;
662 } 885 }
663 case IrOpcode::kF32x4UConvertI32x4: { 886 case IrOpcode::kF32x4UConvertI32x4: {
664 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32()); 887 LowerUnaryOp(node, SimdType::kInt32, machine()->RoundUint32ToFloat32());
665 break; 888 break;
666 } 889 }
667 case IrOpcode::kI32x4Splat: 890 case IrOpcode::kI32x4Splat:
668 case IrOpcode::kF32x4Splat: { 891 case IrOpcode::kF32x4Splat:
669 Node* rep_node[kMaxLanes]; 892 case IrOpcode::kI16x8Splat: {
670 for (int i = 0; i < kMaxLanes; ++i) { 893 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
894 for (int i = 0; i < num_lanes; ++i) {
671 if (HasReplacement(0, node->InputAt(0))) { 895 if (HasReplacement(0, node->InputAt(0))) {
672 rep_node[i] = GetReplacements(node->InputAt(0))[0]; 896 rep_node[i] = GetReplacements(node->InputAt(0))[0];
673 } else { 897 } else {
674 rep_node[i] = node->InputAt(0); 898 rep_node[i] = node->InputAt(0);
675 } 899 }
676 } 900 }
677 ReplaceNode(node, rep_node); 901 ReplaceNode(node, rep_node, num_lanes);
678 break; 902 break;
679 } 903 }
680 case IrOpcode::kI32x4ExtractLane: 904 case IrOpcode::kI32x4ExtractLane:
681 case IrOpcode::kF32x4ExtractLane: { 905 case IrOpcode::kF32x4ExtractLane:
906 case IrOpcode::kI16x8ExtractLane: {
682 int32_t lane = OpParameter<int32_t>(node); 907 int32_t lane = OpParameter<int32_t>(node);
683 Node* rep_node[kMaxLanes] = { 908 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
684 GetReplacementsWithType(node->InputAt(0), rep_type)[lane], nullptr, 909 rep_node[0] = GetReplacementsWithType(node->InputAt(0), rep_type)[lane];
685 nullptr, nullptr}; 910 for (int i = 1; i < num_lanes; ++i) {
686 ReplaceNode(node, rep_node); 911 rep_node[i] = nullptr;
912 }
913 ReplaceNode(node, rep_node, num_lanes);
687 break; 914 break;
688 } 915 }
689 case IrOpcode::kI32x4ReplaceLane: 916 case IrOpcode::kI32x4ReplaceLane:
690 case IrOpcode::kF32x4ReplaceLane: { 917 case IrOpcode::kF32x4ReplaceLane:
918 case IrOpcode::kI16x8ReplaceLane: {
691 DCHECK_EQ(2, node->InputCount()); 919 DCHECK_EQ(2, node->InputCount());
692 Node* repNode = node->InputAt(1); 920 Node* repNode = node->InputAt(1);
693 int32_t lane = OpParameter<int32_t>(node); 921 int32_t lane = OpParameter<int32_t>(node);
694 DCHECK(lane >= 0 && lane <= 3);
695 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type); 922 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
696 if (HasReplacement(0, repNode)) { 923 if (HasReplacement(0, repNode)) {
697 rep_node[lane] = GetReplacements(repNode)[0]; 924 rep_node[lane] = GetReplacements(repNode)[0];
698 } else { 925 } else {
699 rep_node[lane] = repNode; 926 rep_node[lane] = repNode;
700 } 927 }
701 ReplaceNode(node, rep_node); 928 ReplaceNode(node, rep_node, num_lanes);
702 break; 929 break;
703 } 930 }
704 #define COMPARISON_CASE(type, simd_op, lowering_op, invert) \ 931 #define COMPARISON_CASE(type, simd_op, lowering_op, invert) \
705 case IrOpcode::simd_op: { \ 932 case IrOpcode::simd_op: { \
706 LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \ 933 LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
707 break; \ 934 break; \
708 } 935 }
709 COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false) 936 COMPARISON_CASE(Float32, kF32x4Eq, Float32Equal, false)
710 COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false) 937 COMPARISON_CASE(Float32, kF32x4Lt, Float32LessThan, false)
711 COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false) 938 COMPARISON_CASE(Float32, kF32x4Le, Float32LessThanOrEqual, false)
712 COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true) 939 COMPARISON_CASE(Float32, kF32x4Gt, Float32LessThan, true)
713 COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true) 940 COMPARISON_CASE(Float32, kF32x4Ge, Float32LessThanOrEqual, true)
714 COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false) 941 COMPARISON_CASE(Int32, kI32x4Eq, Word32Equal, false)
715 COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false) 942 COMPARISON_CASE(Int32, kI32x4LtS, Int32LessThan, false)
716 COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false) 943 COMPARISON_CASE(Int32, kI32x4LeS, Int32LessThanOrEqual, false)
717 COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true) 944 COMPARISON_CASE(Int32, kI32x4GtS, Int32LessThan, true)
718 COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true) 945 COMPARISON_CASE(Int32, kI32x4GeS, Int32LessThanOrEqual, true)
719 COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false) 946 COMPARISON_CASE(Int32, kI32x4LtU, Uint32LessThan, false)
720 COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false) 947 COMPARISON_CASE(Int32, kI32x4LeU, Uint32LessThanOrEqual, false)
721 COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true) 948 COMPARISON_CASE(Int32, kI32x4GtU, Uint32LessThan, true)
722 COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true) 949 COMPARISON_CASE(Int32, kI32x4GeU, Uint32LessThanOrEqual, true)
950 COMPARISON_CASE(Int16, kI16x8Eq, Word32Equal, false)
951 COMPARISON_CASE(Int16, kI16x8LtS, Int32LessThan, false)
952 COMPARISON_CASE(Int16, kI16x8LeS, Int32LessThanOrEqual, false)
953 COMPARISON_CASE(Int16, kI16x8GtS, Int32LessThan, true)
954 COMPARISON_CASE(Int16, kI16x8GeS, Int32LessThanOrEqual, true)
955 COMPARISON_CASE(Int16, kI16x8LtU, Uint32LessThan, false)
956 COMPARISON_CASE(Int16, kI16x8LeU, Uint32LessThanOrEqual, false)
957 COMPARISON_CASE(Int16, kI16x8GtU, Uint32LessThan, true)
958 COMPARISON_CASE(Int16, kI16x8GeU, Uint32LessThanOrEqual, true)
723 #undef COMPARISON_CASE 959 #undef COMPARISON_CASE
724 case IrOpcode::kF32x4Ne: { 960 case IrOpcode::kF32x4Ne: {
725 LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal()); 961 LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal());
726 break; 962 break;
727 } 963 }
728 case IrOpcode::kI32x4Ne: { 964 case IrOpcode::kI32x4Ne: {
729 LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal()); 965 LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal());
730 break; 966 break;
731 } 967 }
732 case IrOpcode::kS32x4Select: { 968 case IrOpcode::kI16x8Ne: {
969 LowerNotEqual(node, SimdType::kInt16, machine()->Word32Equal());
970 break;
971 }
972 case IrOpcode::kS32x4Select:
973 case IrOpcode::kS16x8Select: {
733 DCHECK(node->InputCount() == 3); 974 DCHECK(node->InputCount() == 3);
734 DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4); 975 DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4 ||
976 ReplacementType(node->InputAt(0)) == SimdType::kSimd1x8);
735 Node** boolean_input = GetReplacements(node->InputAt(0)); 977 Node** boolean_input = GetReplacements(node->InputAt(0));
736 Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type); 978 Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type);
737 Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type); 979 Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type);
738 Node* rep_node[kMaxLanes]; 980 Node** rep_node = zone()->NewArray<Node*>(num_lanes);
739 for (int i = 0; i < kMaxLanes; ++i) { 981 for (int i = 0; i < num_lanes; ++i) {
740 Diamond d(graph(), common(), 982 Diamond d(graph(), common(),
741 graph()->NewNode(machine()->Word32Equal(), boolean_input[i], 983 graph()->NewNode(machine()->Word32Equal(), boolean_input[i],
742 jsgraph_->Int32Constant(0))); 984 jsgraph_->Int32Constant(0)));
743 if (rep_type == SimdType::kFloat32) { 985 #define SELECT_CASE(sType, mType) \
744 rep_node[i] = 986 case SimdType::k##sType: \
745 d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]); 987 rep_node[i] = \
746 } else if (rep_type == SimdType::kInt32) { 988 d.Phi(MachineRepresentation::k##mType, rep_right[1], rep_left[0]); \
747 rep_node[i] = 989 break;
748 d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]); 990
749 } else { 991 switch (rep_type) {
750 UNREACHABLE(); 992 FOREACH_SIMD_TYPE_TO_MACHINE_REP(SELECT_CASE)
993 default:
994 UNREACHABLE();
751 } 995 }
996 #undef SELECT_CASE
752 } 997 }
753 ReplaceNode(node, rep_node); 998 ReplaceNode(node, rep_node, num_lanes);
754 break; 999 break;
755 } 1000 }
756 default: { DefaultLowering(node); } 1001 default: { DefaultLowering(node); }
757 } 1002 }
758 } 1003 }
759 1004
760 bool SimdScalarLowering::DefaultLowering(Node* node) { 1005 bool SimdScalarLowering::DefaultLowering(Node* node) {
761 bool something_changed = false; 1006 bool something_changed = false;
762 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 1007 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
763 Node* input = node->InputAt(i); 1008 Node* input = node->InputAt(i);
764 if (HasReplacement(0, input)) { 1009 if (HasReplacement(0, input)) {
765 something_changed = true; 1010 something_changed = true;
766 node->ReplaceInput(i, GetReplacements(input)[0]); 1011 node->ReplaceInput(i, GetReplacements(input)[0]);
767 } 1012 }
768 if (HasReplacement(1, input)) { 1013 if (HasReplacement(1, input)) {
769 something_changed = true; 1014 something_changed = true;
770 for (int j = 1; j < kMaxLanes; j++) { 1015 for (int j = 1; j < ReplacementCount(input); ++j) {
771 node->InsertInput(zone(), i + j, GetReplacements(input)[j]); 1016 node->InsertInput(zone(), i + j, GetReplacements(input)[j]);
772 } 1017 }
773 } 1018 }
774 } 1019 }
775 return something_changed; 1020 return something_changed;
776 } 1021 }
777 1022
778 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node) { 1023 void SimdScalarLowering::ReplaceNode(Node* old, Node** new_node, int count) {
bbudge 2017/04/27 18:03:42 nit: new_nodes, to clarify it's an array.
aseemgarg 2017/04/28 20:50:41 Done.
779 // if new_low == nullptr, then also new_high == nullptr. 1024 replacements_[old->id()].node = zone()->NewArray<Node*>(count);
780 DCHECK(new_node[0] != nullptr || 1025 for (int i = 0; i < count; ++i) {
781 (new_node[1] == nullptr && new_node[2] == nullptr &&
782 new_node[3] == nullptr));
783 for (int i = 0; i < kMaxLanes; ++i) {
784 replacements_[old->id()].node[i] = new_node[i]; 1026 replacements_[old->id()].node[i] = new_node[i];
785 } 1027 }
1028 replacements_[old->id()].num_replacements = count;
786 } 1029 }
787 1030
788 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) { 1031 bool SimdScalarLowering::HasReplacement(size_t index, Node* node) {
789 return replacements_[node->id()].node[index] != nullptr; 1032 return replacements_[node->id()].node != nullptr &&
1033 replacements_[node->id()].node[index] != nullptr;
790 } 1034 }
791 1035
792 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) { 1036 SimdScalarLowering::SimdType SimdScalarLowering::ReplacementType(Node* node) {
793 return replacements_[node->id()].type; 1037 return replacements_[node->id()].type;
794 } 1038 }
795 1039
796 Node** SimdScalarLowering::GetReplacements(Node* node) { 1040 Node** SimdScalarLowering::GetReplacements(Node* node) {
797 Node** result = replacements_[node->id()].node; 1041 Node** result = replacements_[node->id()].node;
798 DCHECK(result); 1042 DCHECK(result);
799 return result; 1043 return result;
800 } 1044 }
801 1045
1046 int SimdScalarLowering::ReplacementCount(Node* node) {
1047 return replacements_[node->id()].num_replacements;
1048 }
1049
1050 void SimdScalarLowering::Int32ToFloat32(Node** replacements, Node** result) {
1051 for (int i = 0; i < kNumLanes32; ++i) {
1052 if (replacements[i] != nullptr) {
1053 result[i] =
1054 graph()->NewNode(machine()->BitcastInt32ToFloat32(), replacements[i]);
1055 } else {
1056 result[i] = nullptr;
1057 }
1058 }
1059 }
1060
1061 void SimdScalarLowering::Float32ToInt32(Node** replacements, Node** result) {
1062 for (int i = 0; i < kNumLanes32; ++i) {
1063 if (replacements[i] != nullptr) {
1064 result[i] =
1065 graph()->NewNode(machine()->BitcastFloat32ToInt32(), replacements[i]);
1066 } else {
1067 result[i] = nullptr;
1068 }
1069 }
1070 }
1071
1072 void SimdScalarLowering::Int16ToInt32(Node** replacements, Node** result) {
1073 UNIMPLEMENTED();
1074 }
1075
1076 void SimdScalarLowering::Int32ToInt16(Node** replacements, Node** result) {
1077 UNIMPLEMENTED();
1078 }
1079
802 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) { 1080 Node** SimdScalarLowering::GetReplacementsWithType(Node* node, SimdType type) {
803 Node** replacements = GetReplacements(node); 1081 Node** replacements = GetReplacements(node);
804 if (ReplacementType(node) == type) { 1082 if (ReplacementType(node) == type) {
805 return GetReplacements(node); 1083 return GetReplacements(node);
806 } 1084 }
807 Node** result = zone()->NewArray<Node*>(kMaxLanes); 1085 int num_lanes = NumLanes(type);
808 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) { 1086 Node** result = zone()->NewArray<Node*>(num_lanes);
809 for (int i = 0; i < kMaxLanes; ++i) { 1087 if (type == SimdType::kInt32) {
810 if (replacements[i] != nullptr) { 1088 if (ReplacementType(node) == SimdType::kFloat32) {
811 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(), 1089 Float32ToInt32(replacements, result);
812 replacements[i]); 1090 } else if (ReplacementType(node) == SimdType::kInt16) {
813 } else { 1091 Int16ToInt32(replacements, result);
bbudge 2017/04/27 18:03:42 It seems strange to call these int conversions if
aseemgarg 2017/04/28 20:50:41 Done.
814 result[i] = nullptr; 1092 } else {
815 } 1093 UNREACHABLE();
816 } 1094 }
817 } else if (ReplacementType(node) == SimdType::kFloat32 && 1095 } else if (type == SimdType::kFloat32) {
818 type == SimdType::kInt32) { 1096 if (ReplacementType(node) == SimdType::kInt32) {
819 for (int i = 0; i < kMaxLanes; ++i) { 1097 Int32ToFloat32(replacements, result);
820 if (replacements[i] != nullptr) { 1098 } else if (ReplacementType(node) == SimdType::kInt16) {
821 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), 1099 Node** temp_result = zone()->NewArray<Node*>(kNumLanes32);
822 replacements[i]); 1100 Int16ToInt32(replacements, temp_result);
823 } else { 1101 Int32ToFloat32(temp_result, result);
824 result[i] = nullptr; 1102 } else {
825 } 1103 UNREACHABLE();
1104 }
1105 } else if (type == SimdType::kInt16) {
1106 if (ReplacementType(node) == SimdType::kInt32) {
1107 Int32ToInt16(replacements, result);
1108 } else if (ReplacementType(node) == SimdType::kFloat32) {
1109 Node** temp_result = zone()->NewArray<Node*>(kNumLanes32);
1110 Float32ToInt32(replacements, temp_result);
1111 Int32ToInt16(temp_result, result);
1112 } else {
1113 UNREACHABLE();
826 } 1114 }
827 } else { 1115 } else {
828 UNREACHABLE(); 1116 UNREACHABLE();
829 } 1117 }
830 return result; 1118 return result;
831 } 1119 }
832 1120
833 void SimdScalarLowering::PreparePhiReplacement(Node* phi) { 1121 void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
834 MachineRepresentation rep = PhiRepresentationOf(phi->op()); 1122 MachineRepresentation rep = PhiRepresentationOf(phi->op());
835 if (rep == MachineRepresentation::kSimd128) { 1123 if (rep == MachineRepresentation::kSimd128) {
836 // We have to create the replacements for a phi node before we actually 1124 // We have to create the replacements for a phi node before we actually
837 // lower the phi to break potential cycles in the graph. The replacements of 1125 // lower the phi to break potential cycles in the graph. The replacements of
838 // input nodes do not exist yet, so we use a placeholder node to pass the 1126 // input nodes do not exist yet, so we use a placeholder node to pass the
839 // graph verifier. 1127 // graph verifier.
840 int value_count = phi->op()->ValueInputCount(); 1128 int value_count = phi->op()->ValueInputCount();
841 SimdType type = ReplacementType(phi); 1129 SimdType type = ReplacementType(phi);
842 Node** inputs_rep[kMaxLanes]; 1130 int num_lanes = NumLanes(type);
843 for (int i = 0; i < kMaxLanes; ++i) { 1131 Node*** inputs_rep = zone()->NewArray<Node**>(num_lanes);
1132 for (int i = 0; i < num_lanes; ++i) {
844 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1); 1133 inputs_rep[i] = zone()->NewArray<Node*>(value_count + 1);
845 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0); 1134 inputs_rep[i][value_count] = NodeProperties::GetControlInput(phi, 0);
846 } 1135 }
847 for (int i = 0; i < value_count; ++i) { 1136 for (int i = 0; i < value_count; ++i) {
848 for (int j = 0; j < kMaxLanes; j++) { 1137 for (int j = 0; j < num_lanes; ++j) {
849 inputs_rep[j][i] = placeholder_; 1138 inputs_rep[j][i] = placeholder_;
850 } 1139 }
851 } 1140 }
852 Node* rep_nodes[kMaxLanes]; 1141 Node** rep_nodes = zone()->NewArray<Node*>(num_lanes);
853 for (int i = 0; i < kMaxLanes; ++i) { 1142 for (int i = 0; i < num_lanes; ++i) {
854 if (type == SimdType::kInt32) { 1143 #define PHI_CASE(sType, mType) \
855 rep_nodes[i] = graph()->NewNode( 1144 case SimdType::k##sType: \
856 common()->Phi(MachineRepresentation::kWord32, value_count), 1145 rep_nodes[i] = graph()->NewNode( \
857 value_count + 1, inputs_rep[i], false); 1146 common()->Phi(MachineRepresentation::k##mType, value_count), \
858 } else if (type == SimdType::kFloat32) { 1147 value_count + 1, inputs_rep[i], false); \
859 rep_nodes[i] = graph()->NewNode( 1148 break;
860 common()->Phi(MachineRepresentation::kFloat32, value_count), 1149
861 value_count + 1, inputs_rep[i], false); 1150 switch (type) {
862 } else { 1151 FOREACH_SIMD_TYPE_TO_MACHINE_REP(PHI_CASE)
863 UNREACHABLE(); 1152 default:
1153 UNREACHABLE();
864 } 1154 }
1155 #undef PHI_CASE
865 } 1156 }
866 ReplaceNode(phi, rep_nodes); 1157 ReplaceNode(phi, rep_nodes, num_lanes);
867 } 1158 }
868 } 1159 }
869 } // namespace compiler 1160 } // namespace compiler
870 } // namespace internal 1161 } // namespace internal
871 } // namespace v8 1162 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698