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

Unified Diff: src/compiler/wasm-compiler.cc

Issue 2045943002: [compiler] [wasm] Introduce Word32/64ReverseBytes as TF Optional Opcode (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix according to titzer Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/verifier.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/wasm-compiler.cc
diff --git a/src/compiler/wasm-compiler.cc b/src/compiler/wasm-compiler.cc
index 71f450f0743cc6ba6a2d6bdafb2d1e8cab77064d..d2ab271c183a68910e907c9a51ec17c4b5e823ff 100644
--- a/src/compiler/wasm-compiler.cc
+++ b/src/compiler/wasm-compiler.cc
@@ -1007,14 +1007,23 @@ Node* WasmGraphBuilder::MaskShiftCount64(Node* node) {
return node;
}
+static bool ReverseBytesSupported(MachineOperatorBuilder* m,
+ size_t size_in_bytes) {
+ switch (size_in_bytes) {
+ case 4:
+ return m->Word32ReverseBytes().IsSupported();
+ case 8:
+ return m->Word64ReverseBytes().IsSupported();
+ default:
+ break;
+ }
+ return false;
+}
+
Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
wasm::LocalType wasmtype) {
Node* result;
Node* value = node;
- const Operator* shiftLeftOpcode;
- const Operator* shiftRightOpcode;
- const Operator* andOpcode;
- const Operator* orOpcode;
MachineOperatorBuilder* m = jsgraph()->machine();
int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation());
int valueSizeInBits = 8 * valueSizeInBytes;
@@ -1025,10 +1034,6 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
value = graph()->NewNode(m->BitcastFloat64ToInt64(), node);
isFloat = true;
case MachineRepresentation::kWord64:
- shiftLeftOpcode = m->Word64Shl();
- shiftRightOpcode = m->Word64Shr();
- andOpcode = m->Word64And();
- orOpcode = m->Word64Or();
result = jsgraph()->Int64Constant(0);
break;
case MachineRepresentation::kFloat32:
@@ -1036,10 +1041,6 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
isFloat = true;
case MachineRepresentation::kWord32:
case MachineRepresentation::kWord16:
- shiftLeftOpcode = m->Word32Shl();
- shiftRightOpcode = m->Word32Shr();
- andOpcode = m->Word32And();
- orOpcode = m->Word32Or();
result = jsgraph()->Int32Constant(0);
break;
case MachineRepresentation::kWord8:
@@ -1054,44 +1055,64 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
int i;
uint32_t shiftCount;
- for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
- i += 8, shiftCount -= 16) {
- Node* shiftLower;
- Node* shiftHigher;
- Node* lowerByte;
- Node* higherByte;
-
- DCHECK(shiftCount > 0);
- DCHECK((shiftCount + 8) % 16 == 0);
-
- if (valueSizeInBits > 32) {
- shiftLower = graph()->NewNode(shiftLeftOpcode, value,
- jsgraph()->Int64Constant(shiftCount));
- shiftHigher = graph()->NewNode(shiftRightOpcode, value,
- jsgraph()->Int64Constant(shiftCount));
- lowerByte = graph()->NewNode(
- andOpcode, shiftLower,
- jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF)
- << (valueSizeInBits - 8 - i)));
- higherByte = graph()->NewNode(
- andOpcode, shiftHigher,
- jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i));
- } else {
- shiftLower = graph()->NewNode(shiftLeftOpcode, value,
- jsgraph()->Int32Constant(shiftCount));
- shiftHigher = graph()->NewNode(shiftRightOpcode, value,
- jsgraph()->Int32Constant(shiftCount));
- lowerByte = graph()->NewNode(
- andOpcode, shiftLower,
- jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF)
- << (valueSizeInBits - 8 - i)));
- higherByte = graph()->NewNode(
- andOpcode, shiftHigher,
- jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i));
+ if (ReverseBytesSupported(m, valueSizeInBytes < 4 ? 4 : valueSizeInBytes)) {
+ switch (valueSizeInBytes) {
+ case 2:
+ result =
+ graph()->NewNode(m->Word32ReverseBytes().op(),
+ graph()->NewNode(m->Word32Shl(), value,
+ jsgraph()->Int32Constant(16)));
+ break;
+ case 4:
+ result = graph()->NewNode(m->Word32ReverseBytes().op(), value);
+ break;
+ case 8:
+ result = graph()->NewNode(m->Word64ReverseBytes().op(), value);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ } else {
+ for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2;
+ i += 8, shiftCount -= 16) {
+ Node* shiftLower;
+ Node* shiftHigher;
+ Node* lowerByte;
+ Node* higherByte;
+
+ DCHECK(shiftCount > 0);
+ DCHECK((shiftCount + 8) % 16 == 0);
+
+ if (valueSizeInBits > 32) {
+ shiftLower = graph()->NewNode(m->Word64Shl(), value,
+ jsgraph()->Int64Constant(shiftCount));
+ shiftHigher = graph()->NewNode(m->Word64Shr(), value,
+ jsgraph()->Int64Constant(shiftCount));
+ lowerByte = graph()->NewNode(
+ m->Word64And(), shiftLower,
+ jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF)
+ << (valueSizeInBits - 8 - i)));
+ higherByte = graph()->NewNode(
+ m->Word64And(), shiftHigher,
+ jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i));
+ result = graph()->NewNode(m->Word64Or(), result, lowerByte);
+ result = graph()->NewNode(m->Word64Or(), result, higherByte);
+ } else {
+ shiftLower = graph()->NewNode(m->Word32Shl(), value,
+ jsgraph()->Int32Constant(shiftCount));
+ shiftHigher = graph()->NewNode(m->Word32Shr(), value,
+ jsgraph()->Int32Constant(shiftCount));
+ lowerByte = graph()->NewNode(
+ m->Word32And(), shiftLower,
+ jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF)
+ << (valueSizeInBits - 8 - i)));
+ higherByte = graph()->NewNode(
+ m->Word32And(), shiftHigher,
+ jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i));
+ result = graph()->NewNode(m->Word32Or(), result, lowerByte);
+ result = graph()->NewNode(m->Word32Or(), result, higherByte);
+ }
}
-
- result = graph()->NewNode(orOpcode, result, lowerByte);
- result = graph()->NewNode(orOpcode, result, higherByte);
}
if (isFloat) {
@@ -1120,7 +1141,9 @@ Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype,
shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits);
result = graph()->NewNode(
m->Word64Sar(),
- graph()->NewNode(m->Word64Shl(), result, shiftBitCount),
+ graph()->NewNode(m->Word64Shl(),
+ graph()->NewNode(m->ChangeInt32ToInt64(), result),
+ shiftBitCount),
shiftBitCount);
} else if (wasmtype == wasm::kAstI32) {
shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits);
@@ -2983,8 +3006,6 @@ Node* WasmGraphBuilder::LoadMem(wasm::LocalType type, MachineType memtype,
*effect_ = load;
#if defined(V8_TARGET_BIG_ENDIAN)
- // TODO(john.yan) Implement byte swap turbofan operator
- // and use it if available for better performance
load = BuildChangeEndianness(load, memtype, type);
#endif
@@ -3013,12 +3034,11 @@ Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index,
// WASM semantics throw on OOB. Introduce explicit bounds check.
BoundsCheckMem(memtype, index, offset, position);
StoreRepresentation rep(memtype.representation(), kNoWriteBarrier);
+
bool aligned = static_cast<int>(alignment) >=
ElementSizeLog2Of(memtype.representation());
#if defined(V8_TARGET_BIG_ENDIAN)
- // TODO(john.yan) Implement byte swap turbofan operator
- // and use it if available for better performance
val = BuildChangeEndianness(val, memtype);
#endif
« no previous file with comments | « src/compiler/verifier.cc ('k') | src/compiler/x64/instruction-selector-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698