diff options
author | Thomas Lively <7121787+tlively@users.noreply.github.com> | 2022-05-11 11:23:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-11 11:23:55 -0700 |
commit | 57bef0d2f9a38a2add940e07fc422fd532574013 (patch) | |
tree | 0e93c4aaa08985d631ea87bfbee452825d93c405 /src | |
parent | bad3f9e8f058cfdaefb3d7d76a93e842665f8435 (diff) | |
download | binaryen-57bef0d2f9a38a2add940e07fc422fd532574013.tar.gz binaryen-57bef0d2f9a38a2add940e07fc422fd532574013.tar.bz2 binaryen-57bef0d2f9a38a2add940e07fc422fd532574013.zip |
Add ref.cast_nop_static (#4656)
This unsafe experimental instruction is semantically equivalent to
ref.cast_static, but V8 will unsafely turn it into a nop. This is meant to help
us measure cast overhead more precisely than we can by globally turning all
casts into nops.
Diffstat (limited to 'src')
-rw-r--r-- | src/gen-s-parser.inc | 14 | ||||
-rw-r--r-- | src/passes/Print.cpp | 6 | ||||
-rw-r--r-- | src/wasm-binary.h | 1 | ||||
-rw-r--r-- | src/wasm-builder.h | 5 | ||||
-rw-r--r-- | src/wasm-s-parser.h | 1 | ||||
-rw-r--r-- | src/wasm.h | 5 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 8 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 6 |
9 files changed, 44 insertions, 9 deletions
diff --git a/src/gen-s-parser.inc b/src/gen-s-parser.inc index d9505bcdd..411196986 100644 --- a/src/gen-s-parser.inc +++ b/src/gen-s-parser.inc @@ -3027,9 +3027,17 @@ switch (op[0]) { case '\0': if (strcmp(op, "ref.cast") == 0) { return makeRefCast(s); } goto parse_error; - case '_': - if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); } - goto parse_error; + case '_': { + switch (op[9]) { + case 'n': + if (strcmp(op, "ref.cast_nop_static") == 0) { return makeRefCastNopStatic(s); } + goto parse_error; + case 's': + if (strcmp(op, "ref.cast_static") == 0) { return makeRefCastStatic(s); } + goto parse_error; + default: goto parse_error; + } + } default: goto parse_error; } } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 9a4235cbf..ce70f50fd 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -1984,7 +1984,11 @@ struct PrintExpressionContents if (curr->rtt) { printMedium(o, "ref.cast"); } else { - printMedium(o, "ref.cast_static "); + if (curr->safety == RefCast::Unsafe) { + printMedium(o, "ref.cast_nop_static "); + } else { + printMedium(o, "ref.cast_static "); + } printHeapType(o, curr->intendedType, wasm); } } diff --git a/src/wasm-binary.h b/src/wasm-binary.h index 12deeacab..58dcd2224 100644 --- a/src/wasm-binary.h +++ b/src/wasm-binary.h @@ -1112,6 +1112,7 @@ enum ASTNodes { RefCastStatic = 0x45, BrOnCastStatic = 0x46, BrOnCastStaticFail = 0x47, + RefCastNopStatic = 0x48, RefIsFunc = 0x50, RefIsData = 0x51, RefIsI31 = 0x52, diff --git a/src/wasm-builder.h b/src/wasm-builder.h index de26886a4..86de1f7db 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -810,10 +810,13 @@ public: ret->finalize(); return ret; } - RefCast* makeRefCast(Expression* ref, HeapType intendedType) { + + RefCast* + makeRefCast(Expression* ref, HeapType intendedType, RefCast::Safety safety) { auto* ret = wasm.allocator.alloc<RefCast>(); ret->ref = ref; ret->intendedType = intendedType; + ret->safety = safety; ret->finalize(); return ret; } diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h index d6f3b2f4e..61383f084 100644 --- a/src/wasm-s-parser.h +++ b/src/wasm-s-parser.h @@ -282,6 +282,7 @@ private: Expression* makeRefTestStatic(Element& s); Expression* makeRefCast(Element& s); Expression* makeRefCastStatic(Element& s); + Expression* makeRefCastNopStatic(Element& s); Expression* makeBrOn(Element& s, BrOnOp op); Expression* makeBrOnStatic(Element& s, BrOnOp op); Expression* makeRttCanon(Element& s); diff --git a/src/wasm.h b/src/wasm.h index 3b736fcbc..b8e3d6704 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -1457,6 +1457,11 @@ public: Expression* rtt = nullptr; HeapType intendedType; + // Support the unsafe `ref.cast_nop_static` to enable precise cast overhead + // measurements. + enum Safety { Safe, Unsafe }; + Safety safety; + void finalize(); // Returns the type we intend to cast to. diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 60a4bad77..9cd7e79a7 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -6712,10 +6712,13 @@ bool WasmBinaryBuilder::maybeVisitRefCast(Expression*& out, uint32_t code) { auto* ref = popNonVoidExpression(); out = Builder(wasm).makeRefCast(ref, rtt); return true; - } else if (code == BinaryConsts::RefCastStatic) { + } else if (code == BinaryConsts::RefCastStatic || + code == BinaryConsts::RefCastNopStatic) { auto intendedType = getIndexedHeapType(); auto* ref = popNonVoidExpression(); - out = Builder(wasm).makeRefCast(ref, intendedType); + auto safety = + code == BinaryConsts::RefCastNopStatic ? RefCast::Unsafe : RefCast::Safe; + out = Builder(wasm).makeRefCast(ref, intendedType, safety); return true; } return false; diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 02da4f909..8680ff8cc 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -2702,7 +2702,13 @@ Expression* SExpressionWasmBuilder::makeRefCast(Element& s) { Expression* SExpressionWasmBuilder::makeRefCastStatic(Element& s) { auto heapType = parseHeapType(*s[1]); auto* ref = parseExpression(*s[2]); - return Builder(wasm).makeRefCast(ref, heapType); + return Builder(wasm).makeRefCast(ref, heapType, RefCast::Safe); +} + +Expression* SExpressionWasmBuilder::makeRefCastNopStatic(Element& s) { + auto heapType = parseHeapType(*s[1]); + auto* ref = parseExpression(*s[2]); + return Builder(wasm).makeRefCast(ref, heapType, RefCast::Unsafe); } Expression* SExpressionWasmBuilder::makeBrOn(Element& s, BrOnOp op) { diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 8afeb6779..8588a049f 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -2051,7 +2051,11 @@ void BinaryInstWriter::visitRefCast(RefCast* curr) { if (curr->rtt) { o << U32LEB(BinaryConsts::RefCast); } else { - o << U32LEB(BinaryConsts::RefCastStatic); + if (curr->safety == RefCast::Unsafe) { + o << U32LEB(BinaryConsts::RefCastNopStatic); + } else { + o << U32LEB(BinaryConsts::RefCastStatic); + } parent.writeIndexedHeapType(curr->intendedType); } } |