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

Side by Side Diff: src/wasm/function-body-decoder.cc

Issue 2923103003: [WASM] Simplify SIMD shuffle opcodes. (Closed)
Patch Set: Mircea's review comments. Created 3 years, 6 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/wasm-compiler.cc ('k') | src/wasm/function-body-decoder-impl.h » ('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 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/signature.h" 5 #include "src/signature.h"
6 6
7 #include "src/base/platform/elapsed-timer.h" 7 #include "src/base/platform/elapsed-timer.h"
8 #include "src/bit-vector.h" 8 #include "src/bit-vector.h"
9 #include "src/flags.h" 9 #include "src/flags.h"
10 #include "src/handles.h" 10 #include "src/handles.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 139
140 static Control Try(const byte* pc, size_t stack_depth, SsaEnv* end_env, 140 static Control Try(const byte* pc, size_t stack_depth, SsaEnv* end_env,
141 Zone* zone, SsaEnv* catch_env, int32_t previous_catch) { 141 Zone* zone, SsaEnv* catch_env, int32_t previous_catch) {
142 DCHECK_NOT_NULL(catch_env); 142 DCHECK_NOT_NULL(catch_env);
143 TryInfo* try_info = new (zone) TryInfo(catch_env); 143 TryInfo* try_info = new (zone) TryInfo(catch_env);
144 return {pc, kControlTry, stack_depth, end_env, nullptr, 144 return {pc, kControlTry, stack_depth, end_env, nullptr,
145 try_info, previous_catch, false, {0, {NO_VALUE}}}; 145 try_info, previous_catch, false, {0, {NO_VALUE}}};
146 } 146 }
147 }; 147 };
148 148
149 namespace {
150 inline unsigned GetShuffleMaskSize(WasmOpcode opcode) {
151 switch (opcode) {
152 case kExprS32x4Shuffle:
153 return 4;
154 case kExprS16x8Shuffle:
155 return 8;
156 case kExprS8x16Shuffle:
157 return 16;
158 default:
159 UNREACHABLE();
160 }
161 }
162 } // namespace
163
164 // Macros that build nodes only if there is a graph and the current SSA 149 // Macros that build nodes only if there is a graph and the current SSA
165 // environment is reachable from start. This avoids problems with malformed 150 // environment is reachable from start. This avoids problems with malformed
166 // TF graphs when decoding inputs that have unreachable code. 151 // TF graphs when decoding inputs that have unreachable code.
167 #define BUILD(func, ...) \ 152 #define BUILD(func, ...) \
168 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr) 153 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr)
169 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr) 154 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr)
170 155
171 // Generic Wasm bytecode decoder with utilities for decoding operands, 156 // Generic Wasm bytecode decoder with utilities for decoding operands,
172 // lengths, etc. 157 // lengths, etc.
173 class WasmDecoder : public Decoder { 158 class WasmDecoder : public Decoder {
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 break; 399 break;
415 } 400 }
416 if (operand.shift < 0 || operand.shift >= max_shift) { 401 if (operand.shift < 0 || operand.shift >= max_shift) {
417 error(pc_ + 2, "invalid shift amount"); 402 error(pc_ + 2, "invalid shift amount");
418 return false; 403 return false;
419 } else { 404 } else {
420 return true; 405 return true;
421 } 406 }
422 } 407 }
423 408
424 inline bool Validate(const byte* pc, WasmOpcode opcode, 409 inline bool Validate(const byte* pc, Simd8x16ShuffleOperand<true>& operand) {
425 SimdShuffleOperand<true>& operand) {
426 unsigned lanes = GetShuffleMaskSize(opcode);
427 uint8_t max_lane = 0; 410 uint8_t max_lane = 0;
428 for (unsigned i = 0; i < lanes; i++) 411 for (uint32_t i = 0; i < kSimd128Size; ++i)
429 max_lane = std::max(max_lane, operand.shuffle[i]); 412 max_lane = std::max(max_lane, operand.shuffle[i]);
430 if (operand.lanes != lanes || max_lane > 2 * lanes) { 413 // Shuffle indices must be in [0..31] for a 16 lane shuffle.
414 if (max_lane > 2 * kSimd128Size) {
431 error(pc_ + 2, "invalid shuffle mask"); 415 error(pc_ + 2, "invalid shuffle mask");
432 return false; 416 return false;
433 } else { 417 } else {
434 return true; 418 return true;
435 } 419 }
436 } 420 }
437 421
438 static unsigned OpcodeLength(Decoder* decoder, const byte* pc) { 422 static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
439 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); 423 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
440 switch (opcode) { 424 switch (opcode) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 #undef DECLARE_OPCODE_CASE 497 #undef DECLARE_OPCODE_CASE
514 { 498 {
515 return 2; 499 return 2;
516 } 500 }
517 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 501 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
518 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) 502 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
519 #undef DECLARE_OPCODE_CASE 503 #undef DECLARE_OPCODE_CASE
520 { 504 {
521 return 3; 505 return 3;
522 } 506 }
523 // Shuffles contain a byte array to determine the shuffle. 507 // Shuffles require a byte per lane, or 16 immediate bytes.
524 case kExprS32x4Shuffle:
525 case kExprS16x8Shuffle:
526 case kExprS8x16Shuffle: 508 case kExprS8x16Shuffle:
527 return 2 + GetShuffleMaskSize(opcode); 509 return 2 + kSimd128Size;
528 default: 510 default:
529 decoder->error(pc, "invalid SIMD opcode"); 511 decoder->error(pc, "invalid SIMD opcode");
530 return 2; 512 return 2;
531 } 513 }
532 } 514 }
533 default: 515 default:
534 return 1; 516 return 1;
535 } 517 }
536 } 518 }
537 519
(...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 SimdShiftOperand<true> operand(this, pc_); 1533 SimdShiftOperand<true> operand(this, pc_);
1552 if (Validate(pc_, opcode, operand)) { 1534 if (Validate(pc_, opcode, operand)) {
1553 compiler::NodeVector inputs(1, zone_); 1535 compiler::NodeVector inputs(1, zone_);
1554 inputs[0] = Pop(0, ValueType::kSimd128).node; 1536 inputs[0] = Pop(0, ValueType::kSimd128).node;
1555 TFNode* node = BUILD(SimdShiftOp, opcode, operand.shift, inputs); 1537 TFNode* node = BUILD(SimdShiftOp, opcode, operand.shift, inputs);
1556 Push(ValueType::kSimd128, node); 1538 Push(ValueType::kSimd128, node);
1557 } 1539 }
1558 return operand.length; 1540 return operand.length;
1559 } 1541 }
1560 1542
1561 unsigned SimdShuffleOp(WasmOpcode opcode) { 1543 unsigned Simd8x16ShuffleOp() {
1562 SimdShuffleOperand<true> operand(this, pc_, GetShuffleMaskSize(opcode)); 1544 Simd8x16ShuffleOperand<true> operand(this, pc_);
1563 if (Validate(pc_, opcode, operand)) { 1545 if (Validate(pc_, operand)) {
1564 compiler::NodeVector inputs(2, zone_); 1546 compiler::NodeVector inputs(2, zone_);
1565 inputs[1] = Pop(1, ValueType::kSimd128).node; 1547 inputs[1] = Pop(1, ValueType::kSimd128).node;
1566 inputs[0] = Pop(0, ValueType::kSimd128).node; 1548 inputs[0] = Pop(0, ValueType::kSimd128).node;
1567 TFNode* node = 1549 TFNode* node = BUILD(Simd8x16ShuffleOp, operand.shuffle, inputs);
1568 BUILD(SimdShuffleOp, operand.shuffle, operand.lanes, inputs);
1569 Push(ValueType::kSimd128, node); 1550 Push(ValueType::kSimd128, node);
1570 } 1551 }
1571 return operand.lanes; 1552 return 16;
1572 } 1553 }
1573 1554
1574 unsigned DecodeSimdOpcode(WasmOpcode opcode) { 1555 unsigned DecodeSimdOpcode(WasmOpcode opcode) {
1575 unsigned len = 0; 1556 unsigned len = 0;
1576 switch (opcode) { 1557 switch (opcode) {
1577 case kExprF32x4ExtractLane: { 1558 case kExprF32x4ExtractLane: {
1578 len = SimdExtractLane(opcode, ValueType::kFloat32); 1559 len = SimdExtractLane(opcode, ValueType::kFloat32);
1579 break; 1560 break;
1580 } 1561 }
1581 case kExprI32x4ExtractLane: 1562 case kExprI32x4ExtractLane:
(...skipping 17 matching lines...) Expand all
1599 case kExprI32x4ShrU: 1580 case kExprI32x4ShrU:
1600 case kExprI16x8Shl: 1581 case kExprI16x8Shl:
1601 case kExprI16x8ShrS: 1582 case kExprI16x8ShrS:
1602 case kExprI16x8ShrU: 1583 case kExprI16x8ShrU:
1603 case kExprI8x16Shl: 1584 case kExprI8x16Shl:
1604 case kExprI8x16ShrS: 1585 case kExprI8x16ShrS:
1605 case kExprI8x16ShrU: { 1586 case kExprI8x16ShrU: {
1606 len = SimdShiftOp(opcode); 1587 len = SimdShiftOp(opcode);
1607 break; 1588 break;
1608 } 1589 }
1609 case kExprS32x4Shuffle:
1610 case kExprS16x8Shuffle:
1611 case kExprS8x16Shuffle: { 1590 case kExprS8x16Shuffle: {
1612 len = SimdShuffleOp(opcode); 1591 len = Simd8x16ShuffleOp();
1613 break; 1592 break;
1614 } 1593 }
1615 default: { 1594 default: {
1616 FunctionSig* sig = WasmOpcodes::Signature(opcode); 1595 FunctionSig* sig = WasmOpcodes::Signature(opcode);
1617 if (sig != nullptr) { 1596 if (sig != nullptr) {
1618 compiler::NodeVector inputs(sig->parameter_count(), zone_); 1597 compiler::NodeVector inputs(sig->parameter_count(), zone_);
1619 for (size_t i = sig->parameter_count(); i > 0; i--) { 1598 for (size_t i = sig->parameter_count(); i > 0; i--) {
1620 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); 1599 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1));
1621 inputs[i - 1] = val.node; 1600 inputs[i - 1] = val.node;
1622 } 1601 }
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2284 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 2263 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
2285 const byte* start, const byte* end) { 2264 const byte* start, const byte* end) {
2286 Decoder decoder(start, end); 2265 Decoder decoder(start, end);
2287 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, 2266 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start,
2288 static_cast<int>(num_locals), zone); 2267 static_cast<int>(num_locals), zone);
2289 } 2268 }
2290 2269
2291 } // namespace wasm 2270 } // namespace wasm
2292 } // namespace internal 2271 } // namespace internal
2293 } // namespace v8 2272 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/wasm-compiler.cc ('k') | src/wasm/function-body-decoder-impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698