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

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

Issue 2847663005: [WASM SIMD] Replace primitive shuffles with general Shuffle. (Closed)
Patch Set: Rebase. 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
« 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 return 0;
161 }
162 }
163 } // namespace
164
149 // Macros that build nodes only if there is a graph and the current SSA 165 // Macros that build nodes only if there is a graph and the current SSA
150 // environment is reachable from start. This avoids problems with malformed 166 // environment is reachable from start. This avoids problems with malformed
151 // TF graphs when decoding inputs that have unreachable code. 167 // TF graphs when decoding inputs that have unreachable code.
152 #define BUILD(func, ...) \ 168 #define BUILD(func, ...) \
153 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr) 169 (build() ? CheckForException(builder_->func(__VA_ARGS__)) : nullptr)
154 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr) 170 #define BUILD0(func) (build() ? CheckForException(builder_->func()) : nullptr)
155 171
156 // Generic Wasm bytecode decoder with utilities for decoding operands, 172 // Generic Wasm bytecode decoder with utilities for decoding operands,
157 // lengths, etc. 173 // lengths, etc.
158 class WasmDecoder : public Decoder { 174 class WasmDecoder : public Decoder {
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 } 421 }
406 if (operand.shift < 0 || operand.shift >= max_shift) { 422 if (operand.shift < 0 || operand.shift >= max_shift) {
407 error(pc_ + 2, "invalid shift amount"); 423 error(pc_ + 2, "invalid shift amount");
408 return false; 424 return false;
409 } else { 425 } else {
410 return true; 426 return true;
411 } 427 }
412 } 428 }
413 429
414 inline bool Validate(const byte* pc, WasmOpcode opcode, 430 inline bool Validate(const byte* pc, WasmOpcode opcode,
415 SimdConcatOperand<true>& operand) { 431 SimdShuffleOperand<true>& operand) {
416 DCHECK_EQ(wasm::kExprS8x16Concat, opcode); 432 unsigned lanes = GetShuffleMaskSize(opcode);
417 if (operand.bytes <= 0 || operand.bytes >= kSimd128Size) { 433 uint8_t max_lane = 0;
418 error(pc_ + 2, "invalid byte amount"); 434 for (unsigned i = 0; i < lanes; i++)
435 max_lane = std::max(max_lane, operand.shuffle[i]);
436 if (operand.lanes != lanes || max_lane > 2 * lanes) {
437 error(pc_ + 2, "invalid shuffle mask");
419 return false; 438 return false;
420 } else { 439 } else {
421 return true; 440 return true;
422 } 441 }
423 } 442 }
424 443
425 static unsigned OpcodeLength(Decoder* decoder, const byte* pc) { 444 static unsigned OpcodeLength(Decoder* decoder, const byte* pc) {
426 switch (static_cast<byte>(*pc)) { 445 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
446 switch (opcode) {
427 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 447 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
428 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) 448 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
429 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) 449 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
430 #undef DECLARE_OPCODE_CASE 450 #undef DECLARE_OPCODE_CASE
431 { 451 {
432 MemoryAccessOperand<true> operand(decoder, pc, UINT32_MAX); 452 MemoryAccessOperand<true> operand(decoder, pc, UINT32_MAX);
433 return 1 + operand.length; 453 return 1 + operand.length;
434 } 454 }
435 case kExprBr: 455 case kExprBr:
436 case kExprBrIf: { 456 case kExprBrIf: {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 #undef DECLARE_OPCODE_CASE 519 #undef DECLARE_OPCODE_CASE
500 { 520 {
501 return 2; 521 return 2;
502 } 522 }
503 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 523 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
504 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) 524 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE)
505 #undef DECLARE_OPCODE_CASE 525 #undef DECLARE_OPCODE_CASE
506 { 526 {
507 return 3; 527 return 3;
508 } 528 }
529 // Shuffles contain a byte array to determine the shuffle.
530 case kExprS32x4Shuffle:
531 case kExprS16x8Shuffle:
532 case kExprS8x16Shuffle:
533 return 2 + GetShuffleMaskSize(opcode);
509 default: 534 default:
510 decoder->error(pc, "invalid SIMD opcode"); 535 decoder->error(pc, "invalid SIMD opcode");
511 return 2; 536 return 2;
512 } 537 }
513 } 538 }
514 default: 539 default:
515 return 1; 540 return 1;
516 } 541 }
517 } 542 }
518 543
(...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 SimdShiftOperand<true> operand(this, pc_); 1566 SimdShiftOperand<true> operand(this, pc_);
1542 if (Validate(pc_, opcode, operand)) { 1567 if (Validate(pc_, opcode, operand)) {
1543 compiler::NodeVector inputs(1, zone_); 1568 compiler::NodeVector inputs(1, zone_);
1544 inputs[0] = Pop(0, ValueType::kSimd128).node; 1569 inputs[0] = Pop(0, ValueType::kSimd128).node;
1545 TFNode* node = BUILD(SimdShiftOp, opcode, operand.shift, inputs); 1570 TFNode* node = BUILD(SimdShiftOp, opcode, operand.shift, inputs);
1546 Push(ValueType::kSimd128, node); 1571 Push(ValueType::kSimd128, node);
1547 } 1572 }
1548 return operand.length; 1573 return operand.length;
1549 } 1574 }
1550 1575
1551 unsigned SimdConcatOp(WasmOpcode opcode) { 1576 unsigned SimdShuffleOp(WasmOpcode opcode) {
1552 DCHECK_EQ(wasm::kExprS8x16Concat, opcode); 1577 SimdShuffleOperand<true> operand(this, pc_, GetShuffleMaskSize(opcode));
1553 SimdConcatOperand<true> operand(this, pc_);
1554 if (Validate(pc_, opcode, operand)) { 1578 if (Validate(pc_, opcode, operand)) {
1555 compiler::NodeVector inputs(2, zone_); 1579 compiler::NodeVector inputs(2, zone_);
1556 inputs[1] = Pop(1, ValueType::kSimd128).node; 1580 inputs[1] = Pop(1, ValueType::kSimd128).node;
1557 inputs[0] = Pop(0, ValueType::kSimd128).node; 1581 inputs[0] = Pop(0, ValueType::kSimd128).node;
1558 TFNode* node = BUILD(SimdConcatOp, operand.bytes, inputs); 1582 TFNode* node =
1583 BUILD(SimdShuffleOp, operand.shuffle, operand.lanes, inputs);
1559 Push(ValueType::kSimd128, node); 1584 Push(ValueType::kSimd128, node);
1560 } 1585 }
1561 return operand.length; 1586 return operand.lanes;
1562 } 1587 }
1563 1588
1564 unsigned DecodeSimdOpcode(WasmOpcode opcode) { 1589 unsigned DecodeSimdOpcode(WasmOpcode opcode) {
1565 unsigned len = 0; 1590 unsigned len = 0;
1566 switch (opcode) { 1591 switch (opcode) {
1567 case kExprF32x4ExtractLane: { 1592 case kExprF32x4ExtractLane: {
1568 len = SimdExtractLane(opcode, ValueType::kFloat32); 1593 len = SimdExtractLane(opcode, ValueType::kFloat32);
1569 break; 1594 break;
1570 } 1595 }
1571 case kExprI32x4ExtractLane: 1596 case kExprI32x4ExtractLane:
(...skipping 17 matching lines...) Expand all
1589 case kExprI32x4ShrU: 1614 case kExprI32x4ShrU:
1590 case kExprI16x8Shl: 1615 case kExprI16x8Shl:
1591 case kExprI16x8ShrS: 1616 case kExprI16x8ShrS:
1592 case kExprI16x8ShrU: 1617 case kExprI16x8ShrU:
1593 case kExprI8x16Shl: 1618 case kExprI8x16Shl:
1594 case kExprI8x16ShrS: 1619 case kExprI8x16ShrS:
1595 case kExprI8x16ShrU: { 1620 case kExprI8x16ShrU: {
1596 len = SimdShiftOp(opcode); 1621 len = SimdShiftOp(opcode);
1597 break; 1622 break;
1598 } 1623 }
1599 case kExprS8x16Concat: { 1624 case kExprS32x4Shuffle:
1600 len = SimdConcatOp(opcode); 1625 case kExprS16x8Shuffle:
1626 case kExprS8x16Shuffle: {
1627 len = SimdShuffleOp(opcode);
1601 break; 1628 break;
1602 } 1629 }
1603 default: { 1630 default: {
1604 FunctionSig* sig = WasmOpcodes::Signature(opcode); 1631 FunctionSig* sig = WasmOpcodes::Signature(opcode);
1605 if (sig != nullptr) { 1632 if (sig != nullptr) {
1606 compiler::NodeVector inputs(sig->parameter_count(), zone_); 1633 compiler::NodeVector inputs(sig->parameter_count(), zone_);
1607 for (size_t i = sig->parameter_count(); i > 0; i--) { 1634 for (size_t i = sig->parameter_count(); i > 0; i--) {
1608 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); 1635 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1));
1609 inputs[i - 1] = val.node; 1636 inputs[i - 1] = val.node;
1610 } 1637 }
(...skipping 661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2272 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 2299 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
2273 const byte* start, const byte* end) { 2300 const byte* start, const byte* end) {
2274 Decoder decoder(start, end); 2301 Decoder decoder(start, end);
2275 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, 2302 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start,
2276 static_cast<int>(num_locals), zone); 2303 static_cast<int>(num_locals), zone);
2277 } 2304 }
2278 2305
2279 } // namespace wasm 2306 } // namespace wasm
2280 } // namespace internal 2307 } // namespace internal
2281 } // namespace v8 2308 } // 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