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

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

Issue 2728823005: [wasm] Implement simd lowering for F32x4 and I32x4 compare ops (Closed)
Patch Set: rebase Created 3 years, 9 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
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 V(Float32x4Neg) \ 93 V(Float32x4Neg) \
94 V(Float32x4Add) \ 94 V(Float32x4Add) \
95 V(Float32x4Sub) \ 95 V(Float32x4Sub) \
96 V(Float32x4Mul) \ 96 V(Float32x4Mul) \
97 V(Float32x4Div) \ 97 V(Float32x4Div) \
98 V(Float32x4Min) \ 98 V(Float32x4Min) \
99 V(Float32x4Max) \ 99 V(Float32x4Max) \
100 V(Float32x4FromInt32x4) \ 100 V(Float32x4FromInt32x4) \
101 V(Float32x4FromUint32x4) 101 V(Float32x4FromUint32x4)
102 102
103 #define FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(V) \
104 V(Float32x4Equal) \
105 V(Float32x4NotEqual) \
106 V(Float32x4LessThan) \
107 V(Float32x4LessThanOrEqual) \
108 V(Float32x4GreaterThan) \
109 V(Float32x4GreaterThanOrEqual)
110
111 #define FOREACH_INT32X4_TO_SIMD1X4OPCODE(V) \
112 V(Int32x4Equal) \
113 V(Int32x4NotEqual) \
114 V(Int32x4LessThan) \
115 V(Int32x4LessThanOrEqual) \
116 V(Int32x4GreaterThan) \
117 V(Int32x4GreaterThanOrEqual) \
118 V(Uint32x4LessThan) \
119 V(Uint32x4LessThanOrEqual) \
120 V(Uint32x4GreaterThan) \
121 V(Uint32x4GreaterThanOrEqual)
122
103 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) { 123 void SimdScalarLowering::SetLoweredType(Node* node, Node* output) {
104 switch (node->opcode()) { 124 switch (node->opcode()) {
105 #define CASE_STMT(name) case IrOpcode::k##name: 125 #define CASE_STMT(name) case IrOpcode::k##name:
106 FOREACH_INT32X4_OPCODE(CASE_STMT) 126 FOREACH_INT32X4_OPCODE(CASE_STMT)
107 case IrOpcode::kReturn: 127 case IrOpcode::kReturn:
108 case IrOpcode::kParameter: 128 case IrOpcode::kParameter:
109 case IrOpcode::kCall: { 129 case IrOpcode::kCall: {
110 replacements_[node->id()].type = SimdType::kInt32; 130 replacements_[node->id()].type = SimdType::kInt32;
111 break; 131 break;
112 } 132 }
113 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) { 133 FOREACH_FLOAT32X4_OPCODE(CASE_STMT) {
114 replacements_[node->id()].type = SimdType::kFloat32; 134 replacements_[node->id()].type = SimdType::kFloat32;
115 break; 135 break;
116 } 136 }
117 #undef CASE_STMT 137 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
138 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT) {
139 replacements_[node->id()].type = SimdType::kSimd1x4;
140 break;
141 }
118 default: { 142 default: {
119 switch (output->opcode()) { 143 switch (output->opcode()) {
144 FOREACH_FLOAT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
120 case IrOpcode::kFloat32x4FromInt32x4: 145 case IrOpcode::kFloat32x4FromInt32x4:
121 case IrOpcode::kFloat32x4FromUint32x4: { 146 case IrOpcode::kFloat32x4FromUint32x4: {
122 replacements_[node->id()].type = SimdType::kInt32; 147 replacements_[node->id()].type = SimdType::kInt32;
123 break; 148 break;
124 } 149 }
150 FOREACH_INT32X4_TO_SIMD1X4OPCODE(CASE_STMT)
125 case IrOpcode::kInt32x4FromFloat32x4: 151 case IrOpcode::kInt32x4FromFloat32x4:
126 case IrOpcode::kUint32x4FromFloat32x4: { 152 case IrOpcode::kUint32x4FromFloat32x4: {
127 replacements_[node->id()].type = SimdType::kFloat32; 153 replacements_[node->id()].type = SimdType::kFloat32;
128 break; 154 break;
129 } 155 }
156 case IrOpcode::kSimd32x4Select: {
157 replacements_[node->id()].type = SimdType::kSimd1x4;
158 break;
159 }
130 default: { 160 default: {
131 replacements_[node->id()].type = replacements_[output->id()].type; 161 replacements_[node->id()].type = replacements_[output->id()].type;
132 } 162 }
133 } 163 }
134 } 164 }
165 #undef CASE_STMT
135 } 166 }
136 } 167 }
137 168
138 static int GetParameterIndexAfterLowering( 169 static int GetParameterIndexAfterLowering(
139 Signature<MachineRepresentation>* signature, int old_index) { 170 Signature<MachineRepresentation>* signature, int old_index) {
140 // In function calls, the simd128 types are passed as 4 Int32 types. The 171 // In function calls, the simd128 types are passed as 4 Int32 types. The
141 // parameters are typecast to the types as needed for various operations. 172 // parameters are typecast to the types as needed for various operations.
142 int result = old_index; 173 int result = old_index;
143 for (int i = 0; i < old_index; ++i) { 174 for (int i = 0; i < old_index; ++i) {
144 if (signature->GetParam(i) == MachineRepresentation::kSimd128) { 175 if (signature->GetParam(i) == MachineRepresentation::kSimd128) {
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 } 276 }
246 } 277 }
247 278
248 ReplaceNode(node, rep_nodes); 279 ReplaceNode(node, rep_nodes);
249 } else { 280 } else {
250 DefaultLowering(node); 281 DefaultLowering(node);
251 } 282 }
252 } 283 }
253 284
254 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type, 285 void SimdScalarLowering::LowerBinaryOp(Node* node, SimdType input_rep_type,
255 const Operator* op) { 286 const Operator* op, bool invert_inputs) {
256 DCHECK(node->InputCount() == 2); 287 DCHECK(node->InputCount() == 2);
257 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type); 288 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
258 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type); 289 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
259 Node* rep_node[kMaxLanes]; 290 Node* rep_node[kMaxLanes];
260 for (int i = 0; i < kMaxLanes; ++i) { 291 for (int i = 0; i < kMaxLanes; ++i) {
261 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]); 292 if (invert_inputs) {
293 rep_node[i] = graph()->NewNode(op, rep_right[i], rep_left[i]);
294 } else {
295 rep_node[i] = graph()->NewNode(op, rep_left[i], rep_right[i]);
296 }
262 } 297 }
263 ReplaceNode(node, rep_node); 298 ReplaceNode(node, rep_node);
264 } 299 }
265 300
266 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type, 301 void SimdScalarLowering::LowerUnaryOp(Node* node, SimdType input_rep_type,
267 const Operator* op) { 302 const Operator* op) {
268 DCHECK(node->InputCount() == 1); 303 DCHECK(node->InputCount() == 1);
269 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type); 304 Node** rep = GetReplacementsWithType(node->InputAt(0), input_rep_type);
270 Node* rep_node[kMaxLanes]; 305 Node* rep_node[kMaxLanes];
271 for (int i = 0; i < kMaxLanes; ++i) { 306 for (int i = 0; i < kMaxLanes; ++i) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 Node* shift_node = 400 Node* shift_node =
366 graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask)); 401 graph()->NewNode(common()->Int32Constant(shift_amount & shift_mask));
367 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32); 402 Node** rep = GetReplacementsWithType(node->InputAt(0), SimdType::kInt32);
368 Node* rep_node[kMaxLanes]; 403 Node* rep_node[kMaxLanes];
369 for (int i = 0; i < kMaxLanes; ++i) { 404 for (int i = 0; i < kMaxLanes; ++i) {
370 rep_node[i] = graph()->NewNode(op, rep[i], shift_node); 405 rep_node[i] = graph()->NewNode(op, rep[i], shift_node);
371 } 406 }
372 ReplaceNode(node, rep_node); 407 ReplaceNode(node, rep_node);
373 } 408 }
374 409
410 void SimdScalarLowering::LowerNotEqual(Node* node, SimdType input_rep_type,
411 const Operator* op) {
412 DCHECK(node->InputCount() == 2);
413 Node** rep_left = GetReplacementsWithType(node->InputAt(0), input_rep_type);
414 Node** rep_right = GetReplacementsWithType(node->InputAt(1), input_rep_type);
415 Node* rep_node[kMaxLanes];
416 for (int i = 0; i < kMaxLanes; ++i) {
417 Diamond d(graph(), common(),
418 graph()->NewNode(op, rep_left[i], rep_right[i]));
419 rep_node[i] = d.Phi(MachineRepresentation::kWord32,
420 jsgraph_->Int32Constant(0), jsgraph_->Int32Constant(1));
421 }
422 ReplaceNode(node, rep_node);
423 }
424
375 void SimdScalarLowering::LowerNode(Node* node) { 425 void SimdScalarLowering::LowerNode(Node* node) {
376 SimdType rep_type = ReplacementType(node); 426 SimdType rep_type = ReplacementType(node);
377 switch (node->opcode()) { 427 switch (node->opcode()) {
378 case IrOpcode::kStart: { 428 case IrOpcode::kStart: {
379 int parameter_count = GetParameterCountAfterLowering(); 429 int parameter_count = GetParameterCountAfterLowering();
380 // Only exchange the node if the parameter count actually changed. 430 // Only exchange the node if the parameter count actually changed.
381 if (parameter_count != static_cast<int>(signature()->parameter_count())) { 431 if (parameter_count != static_cast<int>(signature()->parameter_count())) {
382 int delta = 432 int delta =
383 parameter_count - static_cast<int>(signature()->parameter_count()); 433 parameter_count - static_cast<int>(signature()->parameter_count());
384 int new_output_count = node->op()->ValueOutputCount() + delta; 434 int new_output_count = node->op()->ValueOutputCount() + delta;
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 DCHECK(lane >= 0 && lane <= 3); 697 DCHECK(lane >= 0 && lane <= 3);
648 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type); 698 Node** rep_node = GetReplacementsWithType(node->InputAt(0), rep_type);
649 if (HasReplacement(0, repNode)) { 699 if (HasReplacement(0, repNode)) {
650 rep_node[lane] = GetReplacements(repNode)[0]; 700 rep_node[lane] = GetReplacements(repNode)[0];
651 } else { 701 } else {
652 rep_node[lane] = repNode; 702 rep_node[lane] = repNode;
653 } 703 }
654 ReplaceNode(node, rep_node); 704 ReplaceNode(node, rep_node);
655 break; 705 break;
656 } 706 }
707 #define COMPARISON_CASE(type, simd_op, lowering_op, invert) \
708 case IrOpcode::simd_op: { \
709 LowerBinaryOp(node, SimdType::k##type, machine()->lowering_op(), invert); \
710 break; \
711 }
712 COMPARISON_CASE(Float32, kFloat32x4Equal, Float32Equal, false)
713 COMPARISON_CASE(Float32, kFloat32x4LessThan, Float32LessThan, false)
714 COMPARISON_CASE(Float32, kFloat32x4LessThanOrEqual,
715 Float32LessThanOrEqual, false)
716 COMPARISON_CASE(Float32, kFloat32x4GreaterThan, Float32LessThan, true)
717 COMPARISON_CASE(Float32, kFloat32x4GreaterThanOrEqual,
718 Float32LessThanOrEqual, true)
719 COMPARISON_CASE(Int32, kInt32x4Equal, Word32Equal, false)
720 COMPARISON_CASE(Int32, kInt32x4LessThan, Int32LessThan, false)
721 COMPARISON_CASE(Int32, kInt32x4LessThanOrEqual, Int32LessThanOrEqual,
722 false)
723 COMPARISON_CASE(Int32, kInt32x4GreaterThan, Int32LessThan, true)
724 COMPARISON_CASE(Int32, kInt32x4GreaterThanOrEqual, Int32LessThanOrEqual,
725 true)
726 COMPARISON_CASE(Int32, kUint32x4LessThan, Uint32LessThan, false)
727 COMPARISON_CASE(Int32, kUint32x4LessThanOrEqual, Uint32LessThanOrEqual,
728 false)
729 COMPARISON_CASE(Int32, kUint32x4GreaterThan, Uint32LessThan, true)
730 COMPARISON_CASE(Int32, kUint32x4GreaterThanOrEqual, Uint32LessThanOrEqual,
731 true)
732 #undef COMPARISON_CASE
733 case IrOpcode::kFloat32x4NotEqual: {
734 LowerNotEqual(node, SimdType::kFloat32, machine()->Float32Equal());
735 break;
736 }
737 case IrOpcode::kInt32x4NotEqual: {
738 LowerNotEqual(node, SimdType::kInt32, machine()->Word32Equal());
739 break;
740 }
741 case IrOpcode::kSimd32x4Select: {
742 DCHECK(node->InputCount() == 3);
743 DCHECK(ReplacementType(node->InputAt(0)) == SimdType::kSimd1x4);
744 Node** boolean_input = GetReplacements(node->InputAt(0));
745 Node** rep_left = GetReplacementsWithType(node->InputAt(1), rep_type);
746 Node** rep_right = GetReplacementsWithType(node->InputAt(2), rep_type);
747 Node* rep_node[kMaxLanes];
748 for (int i = 0; i < kMaxLanes; ++i) {
749 Diamond d(graph(), common(),
750 graph()->NewNode(machine()->Word32Equal(), boolean_input[i],
751 jsgraph_->Int32Constant(0)));
752 if (rep_type == SimdType::kFloat32) {
753 rep_node[i] =
754 d.Phi(MachineRepresentation::kFloat32, rep_right[1], rep_left[0]);
755 } else if (rep_type == SimdType::kInt32) {
756 rep_node[i] =
757 d.Phi(MachineRepresentation::kWord32, rep_right[1], rep_left[0]);
758 } else {
759 UNREACHABLE();
760 }
761 }
762 ReplaceNode(node, rep_node);
763 break;
764 }
657 default: { DefaultLowering(node); } 765 default: { DefaultLowering(node); }
658 } 766 }
659 } 767 }
660 768
661 bool SimdScalarLowering::DefaultLowering(Node* node) { 769 bool SimdScalarLowering::DefaultLowering(Node* node) {
662 bool something_changed = false; 770 bool something_changed = false;
663 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) { 771 for (int i = NodeProperties::PastValueIndex(node) - 1; i >= 0; i--) {
664 Node* input = node->InputAt(i); 772 Node* input = node->InputAt(i);
665 if (HasReplacement(0, input)) { 773 if (HasReplacement(0, input)) {
666 something_changed = true; 774 something_changed = true;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 Node** result = zone()->NewArray<Node*>(kMaxLanes); 816 Node** result = zone()->NewArray<Node*>(kMaxLanes);
709 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) { 817 if (ReplacementType(node) == SimdType::kInt32 && type == SimdType::kFloat32) {
710 for (int i = 0; i < kMaxLanes; ++i) { 818 for (int i = 0; i < kMaxLanes; ++i) {
711 if (replacements[i] != nullptr) { 819 if (replacements[i] != nullptr) {
712 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(), 820 result[i] = graph()->NewNode(machine()->BitcastInt32ToFloat32(),
713 replacements[i]); 821 replacements[i]);
714 } else { 822 } else {
715 result[i] = nullptr; 823 result[i] = nullptr;
716 } 824 }
717 } 825 }
718 } else { 826 } else if (ReplacementType(node) == SimdType::kFloat32 &&
827 type == SimdType::kInt32) {
719 for (int i = 0; i < kMaxLanes; ++i) { 828 for (int i = 0; i < kMaxLanes; ++i) {
720 if (replacements[i] != nullptr) { 829 if (replacements[i] != nullptr) {
721 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(), 830 result[i] = graph()->NewNode(machine()->BitcastFloat32ToInt32(),
722 replacements[i]); 831 replacements[i]);
723 } else { 832 } else {
724 result[i] = nullptr; 833 result[i] = nullptr;
725 } 834 }
726 } 835 }
836 } else {
837 UNREACHABLE();
727 } 838 }
728 return result; 839 return result;
729 } 840 }
730 841
731 void SimdScalarLowering::PreparePhiReplacement(Node* phi) { 842 void SimdScalarLowering::PreparePhiReplacement(Node* phi) {
732 MachineRepresentation rep = PhiRepresentationOf(phi->op()); 843 MachineRepresentation rep = PhiRepresentationOf(phi->op());
733 if (rep == MachineRepresentation::kSimd128) { 844 if (rep == MachineRepresentation::kSimd128) {
734 // We have to create the replacements for a phi node before we actually 845 // We have to create the replacements for a phi node before we actually
735 // lower the phi to break potential cycles in the graph. The replacements of 846 // lower the phi to break potential cycles in the graph. The replacements of
736 // input nodes do not exist yet, so we use a placeholder node to pass the 847 // input nodes do not exist yet, so we use a placeholder node to pass the
(...skipping 23 matching lines...) Expand all
760 } else { 871 } else {
761 UNREACHABLE(); 872 UNREACHABLE();
762 } 873 }
763 } 874 }
764 ReplaceNode(phi, rep_nodes); 875 ReplaceNode(phi, rep_nodes);
765 } 876 }
766 } 877 }
767 } // namespace compiler 878 } // namespace compiler
768 } // namespace internal 879 } // namespace internal
769 } // namespace v8 880 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simd-scalar-lowering.h ('k') | src/compiler/wasm-compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698