summaryrefslogtreecommitdiff
path: root/src/ir
diff options
context:
space:
mode:
authorThomas Lively <7121787+tlively@users.noreply.github.com>2018-12-13 17:40:27 -0800
committerGitHub <noreply@github.com>2018-12-13 17:40:27 -0800
commit3325a9cc203932e58b6e85dfefe5feb6e72839a4 (patch)
tree1d969ab30854fd773fdc615d799c9a9ed7e9c0be /src/ir
parent0fd96e6b07f0a0907737c0f44e55060e057c2bb9 (diff)
downloadbinaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.tar.gz
binaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.tar.bz2
binaryen-3325a9cc203932e58b6e85dfefe5feb6e72839a4.zip
SIMD (#1820)
Implement and test the following functionality for SIMD. - Parsing and printing - Assembling and disassembling - Interpretation - C API - JS API
Diffstat (limited to 'src/ir')
-rw-r--r--src/ir/ExpressionAnalyzer.cpp71
-rw-r--r--src/ir/ReFinalize.cpp6
-rw-r--r--src/ir/cost.h109
-rw-r--r--src/ir/literal-utils.h19
-rw-r--r--src/ir/utils.h10
5 files changed, 190 insertions, 25 deletions
diff --git a/src/ir/ExpressionAnalyzer.cpp b/src/ir/ExpressionAnalyzer.cpp
index 7788f7cde..7248691a9 100644
--- a/src/ir/ExpressionAnalyzer.cpp
+++ b/src/ir/ExpressionAnalyzer.cpp
@@ -248,6 +248,37 @@ bool ExpressionAnalyzer::flexibleEqual(Expression* left, Expression* right, Expr
PUSH(AtomicWake, wakeCount);
break;
}
+ case Expression::Id::SIMDExtractId: {
+ CHECK(SIMDExtract, op);
+ CHECK(SIMDExtract, idx);
+ PUSH(SIMDExtract, vec);
+ break;
+ }
+ case Expression::Id::SIMDReplaceId: {
+ CHECK(SIMDReplace, op);
+ CHECK(SIMDReplace, idx);
+ PUSH(SIMDReplace, vec);
+ PUSH(SIMDReplace, value);
+ break;
+ }
+ case Expression::Id::SIMDShuffleId: {
+ CHECK(SIMDShuffle, mask);
+ PUSH(SIMDShuffle, left);
+ PUSH(SIMDShuffle, right);
+ break;
+ }
+ case Expression::Id::SIMDBitselectId: {
+ PUSH(SIMDBitselect, left);
+ PUSH(SIMDBitselect, right);
+ PUSH(SIMDBitselect, cond);
+ break;
+ }
+ case Expression::Id::SIMDShiftId: {
+ CHECK(SIMDShift, op);
+ PUSH(SIMDShift, vec);
+ PUSH(SIMDShift, shift);
+ break;
+ }
case Expression::Id::ConstId: {
if (left->cast<Const>()->value != right->cast<Const>()->value) {
return false;
@@ -496,15 +527,43 @@ HashType ExpressionAnalyzer::hash(Expression* curr) {
PUSH(AtomicWake, wakeCount);
break;
}
+ case Expression::Id::SIMDExtractId: {
+ HASH(SIMDExtract, op);
+ HASH(SIMDExtract, idx);
+ PUSH(SIMDExtract, vec);
+ break;
+ }
+ case Expression::Id::SIMDReplaceId: {
+ HASH(SIMDReplace, op);
+ HASH(SIMDReplace, idx);
+ PUSH(SIMDReplace, vec);
+ PUSH(SIMDReplace, value);
+ break;
+ }
+ case Expression::Id::SIMDShuffleId: {
+ for (size_t i = 0; i < 16; ++i) {
+ HASH(SIMDShuffle, mask[i]);
+ }
+ PUSH(SIMDShuffle, left);
+ PUSH(SIMDShuffle, right);
+ break;
+ }
+ case Expression::Id::SIMDBitselectId: {
+ PUSH(SIMDBitselect, left);
+ PUSH(SIMDBitselect, right);
+ PUSH(SIMDBitselect, cond);
+ break;
+ }
+ case Expression::Id::SIMDShiftId: {
+ HASH(SIMDShift, op);
+ PUSH(SIMDShift, vec);
+ PUSH(SIMDShift, shift);
+ break;
+ }
case Expression::Id::ConstId: {
auto* c = curr->cast<Const>();
hash(c->type);
- auto bits = c->value.getBits();
- if (getTypeSize(c->type) == 4) {
- hash(HashType(bits));
- } else {
- hash64(bits);
- }
+ hash(std::hash<Literal>()(c->value));
break;
}
case Expression::Id::UnaryId: {
diff --git a/src/ir/ReFinalize.cpp b/src/ir/ReFinalize.cpp
index 31140837f..68526678a 100644
--- a/src/ir/ReFinalize.cpp
+++ b/src/ir/ReFinalize.cpp
@@ -137,6 +137,11 @@ void ReFinalize::visitAtomicRMW(AtomicRMW* curr) { curr->finalize(); }
void ReFinalize::visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }
void ReFinalize::visitAtomicWait(AtomicWait* curr) { curr->finalize(); }
void ReFinalize::visitAtomicWake(AtomicWake* curr) { curr->finalize(); }
+void ReFinalize::visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
+void ReFinalize::visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
+void ReFinalize::visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
+void ReFinalize::visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); }
+void ReFinalize::visitSIMDShift(SIMDShift* curr) { curr->finalize(); }
void ReFinalize::visitConst(Const* curr) { curr->finalize(); }
void ReFinalize::visitUnary(Unary* curr) { curr->finalize(); }
void ReFinalize::visitBinary(Binary* curr) { curr->finalize(); }
@@ -195,4 +200,3 @@ void ReFinalize::replaceUntaken(Expression* value, Expression* condition) {
}
} // namespace wasm
-
diff --git a/src/ir/cost.h b/src/ir/cost.h
index e28f535e7..354f663e1 100644
--- a/src/ir/cost.h
+++ b/src/ir/cost.h
@@ -152,6 +152,39 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case TruncSatUFloat64ToInt64: ret = 1; break;
case SqrtFloat32:
case SqrtFloat64: ret = 2; break;
+ case SplatVecI8x16:
+ case SplatVecI16x8:
+ case SplatVecI32x4:
+ case SplatVecI64x2:
+ case SplatVecF32x4:
+ case SplatVecF64x2:
+ case NotVec128:
+ case NegVecI8x16:
+ case AnyTrueVecI8x16:
+ case AllTrueVecI8x16:
+ case NegVecI16x8:
+ case AnyTrueVecI16x8:
+ case AllTrueVecI16x8:
+ case NegVecI32x4:
+ case AnyTrueVecI32x4:
+ case AllTrueVecI32x4:
+ case NegVecI64x2:
+ case AnyTrueVecI64x2:
+ case AllTrueVecI64x2:
+ case AbsVecF32x4:
+ case NegVecF32x4:
+ case SqrtVecF32x4:
+ case AbsVecF64x2:
+ case NegVecF64x2:
+ case SqrtVecF64x2:
+ case TruncSatSVecF32x4ToVecI32x4:
+ case TruncSatUVecF32x4ToVecI32x4:
+ case TruncSatSVecF64x2ToVecI64x2:
+ case TruncSatUVecF64x2ToVecI64x2:
+ case ConvertSVecI32x4ToVecF32x4:
+ case ConvertUVecI32x4ToVecF32x4:
+ case ConvertSVecI64x2ToVecF64x2:
+ case ConvertUVecI64x2ToVecF64x2: assert(false && "v128 not implemented yet");
case InvalidUnary: WASM_UNREACHABLE();
}
return ret + visit(curr->value);
@@ -235,6 +268,82 @@ struct CostAnalyzer : public Visitor<CostAnalyzer, Index> {
case NeFloat32: ret = 1; break;
case EqFloat64: ret = 1; break;
case NeFloat64: ret = 1; break;
+ case EqVecI8x16:
+ case NeVecI8x16:
+ case LtSVecI8x16:
+ case LtUVecI8x16:
+ case LeSVecI8x16:
+ case LeUVecI8x16:
+ case GtSVecI8x16:
+ case GtUVecI8x16:
+ case GeSVecI8x16:
+ case GeUVecI8x16:
+ case EqVecI16x8:
+ case NeVecI16x8:
+ case LtSVecI16x8:
+ case LtUVecI16x8:
+ case LeSVecI16x8:
+ case LeUVecI16x8:
+ case GtSVecI16x8:
+ case GtUVecI16x8:
+ case GeSVecI16x8:
+ case GeUVecI16x8:
+ case EqVecI32x4:
+ case NeVecI32x4:
+ case LtSVecI32x4:
+ case LtUVecI32x4:
+ case LeSVecI32x4:
+ case LeUVecI32x4:
+ case GtSVecI32x4:
+ case GtUVecI32x4:
+ case GeSVecI32x4:
+ case GeUVecI32x4:
+ case EqVecF32x4:
+ case NeVecF32x4:
+ case LtVecF32x4:
+ case LeVecF32x4:
+ case GtVecF32x4:
+ case GeVecF32x4:
+ case EqVecF64x2:
+ case NeVecF64x2:
+ case LtVecF64x2:
+ case LeVecF64x2:
+ case GtVecF64x2:
+ case GeVecF64x2:
+ case AndVec128:
+ case OrVec128:
+ case XorVec128:
+ case AddVecI8x16:
+ case AddSatSVecI8x16:
+ case AddSatUVecI8x16:
+ case SubVecI8x16:
+ case SubSatSVecI8x16:
+ case SubSatUVecI8x16:
+ case MulVecI8x16:
+ case AddVecI16x8:
+ case AddSatSVecI16x8:
+ case AddSatUVecI16x8:
+ case SubVecI16x8:
+ case SubSatSVecI16x8:
+ case SubSatUVecI16x8:
+ case MulVecI16x8:
+ case AddVecI32x4:
+ case SubVecI32x4:
+ case MulVecI32x4:
+ case AddVecI64x2:
+ case SubVecI64x2:
+ case AddVecF32x4:
+ case SubVecF32x4:
+ case MulVecF32x4:
+ case DivVecF32x4:
+ case MinVecF32x4:
+ case MaxVecF32x4:
+ case AddVecF64x2:
+ case SubVecF64x2:
+ case MulVecF64x2:
+ case DivVecF64x2:
+ case MinVecF64x2:
+ case MaxVecF64x2: assert(false && "v128 not implemented yet");
case InvalidBinary: WASM_UNREACHABLE();
}
return ret + visit(curr->left) + visit(curr->right);
diff --git a/src/ir/literal-utils.h b/src/ir/literal-utils.h
index e00f05c52..543c34e9f 100644
--- a/src/ir/literal-utils.h
+++ b/src/ir/literal-utils.h
@@ -23,26 +23,9 @@ namespace wasm {
namespace LiteralUtils {
-inline Literal makeLiteralFromInt32(int32_t x, Type type) {
- switch (type) {
- case i32: return Literal(int32_t(x)); break;
- case i64: return Literal(int64_t(x)); break;
- case f32: return Literal(float(x)); break;
- case f64: return Literal(double(x)); break;
- case v128: assert(false && "v128 not implemented yet");
- case none:
- case unreachable: WASM_UNREACHABLE();
- }
- WASM_UNREACHABLE();
-}
-
-inline Literal makeLiteralZero(Type type) {
- return makeLiteralFromInt32(0, type);
-}
-
inline Expression* makeFromInt32(int32_t x, Type type, Module& wasm) {
auto* ret = wasm.allocator.alloc<Const>();
- ret->value = makeLiteralFromInt32(x, type);
+ ret->value = Literal::makeFromInt32(x, type);
ret->type = type;
return ret;
}
diff --git a/src/ir/utils.h b/src/ir/utils.h
index a4082b6bc..afb63b01c 100644
--- a/src/ir/utils.h
+++ b/src/ir/utils.h
@@ -129,6 +129,11 @@ struct ReFinalize : public WalkerPass<PostWalker<ReFinalize, OverriddenVisitor<R
void visitAtomicCmpxchg(AtomicCmpxchg* curr);
void visitAtomicWait(AtomicWait* curr);
void visitAtomicWake(AtomicWake* curr);
+ void visitSIMDExtract(SIMDExtract* curr);
+ void visitSIMDReplace(SIMDReplace* curr);
+ void visitSIMDShuffle(SIMDShuffle* curr);
+ void visitSIMDBitselect(SIMDBitselect* curr);
+ void visitSIMDShift(SIMDShift* curr);
void visitConst(Const* curr);
void visitUnary(Unary* curr);
void visitBinary(Binary* curr);
@@ -176,6 +181,11 @@ struct ReFinalizeNode : public OverriddenVisitor<ReFinalizeNode> {
void visitAtomicCmpxchg(AtomicCmpxchg* curr) { curr->finalize(); }
void visitAtomicWait(AtomicWait* curr) { curr->finalize(); }
void visitAtomicWake(AtomicWake* curr) { curr->finalize(); }
+ void visitSIMDExtract(SIMDExtract* curr) { curr->finalize(); }
+ void visitSIMDReplace(SIMDReplace* curr) { curr->finalize(); }
+ void visitSIMDShuffle(SIMDShuffle* curr) { curr->finalize(); }
+ void visitSIMDBitselect(SIMDBitselect* curr) { curr->finalize(); }
+ void visitSIMDShift(SIMDShift* curr) { curr->finalize(); }
void visitConst(Const* curr) { curr->finalize(); }
void visitUnary(Unary* curr) { curr->finalize(); }
void visitBinary(Binary* curr) { curr->finalize(); }