diff options
-rw-r--r-- | src/binaryen-c.cpp | 12 | ||||
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 127 | ||||
-rw-r--r-- | src/passes/Print.cpp | 12 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 18 | ||||
-rw-r--r-- | src/wasm-interpreter.h | 12 | ||||
-rw-r--r-- | src/wasm.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 2 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 2 | ||||
-rw-r--r-- | src/wasm2js.h | 12 |
10 files changed, 96 insertions, 115 deletions
diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 4a9d0594f..64304421c 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -562,12 +562,12 @@ BinaryenOp BinaryenLtFloat64(void) { return LtFloat64; } BinaryenOp BinaryenLeFloat64(void) { return LeFloat64; } BinaryenOp BinaryenGtFloat64(void) { return GtFloat64; } BinaryenOp BinaryenGeFloat64(void) { return GeFloat64; } -BinaryenOp BinaryenAtomicRMWAdd(void) { return AtomicRMWOp::Add; } -BinaryenOp BinaryenAtomicRMWSub(void) { return AtomicRMWOp::Sub; } -BinaryenOp BinaryenAtomicRMWAnd(void) { return AtomicRMWOp::And; } -BinaryenOp BinaryenAtomicRMWOr(void) { return AtomicRMWOp::Or; } -BinaryenOp BinaryenAtomicRMWXor(void) { return AtomicRMWOp::Xor; } -BinaryenOp BinaryenAtomicRMWXchg(void) { return AtomicRMWOp::Xchg; } +BinaryenOp BinaryenAtomicRMWAdd(void) { return RMWAdd; } +BinaryenOp BinaryenAtomicRMWSub(void) { return RMWSub; } +BinaryenOp BinaryenAtomicRMWAnd(void) { return RMWAnd; } +BinaryenOp BinaryenAtomicRMWOr(void) { return RMWOr; } +BinaryenOp BinaryenAtomicRMWXor(void) { return RMWXor; } +BinaryenOp BinaryenAtomicRMWXchg(void) { return RMWXchg; } BinaryenOp BinaryenTruncSatSFloat32ToInt32(void) { return TruncSatSFloat32ToInt32; } diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index cc8048511..982f99a04 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -221,6 +221,7 @@ struct OptimizeInstructions // `using namespace Match` can be hoisted to function scope and this extra // block scope can be removed. using namespace Match; + using namespace Abstract; Builder builder(*getModule()); { // try to get rid of (0 - ..), that is, a zero only used to negate an @@ -240,10 +241,9 @@ struct OptimizeInstructions // Note that this reorders X and Y, so we need to be careful about that. Expression *x, *y; Binary* sub; - if (matches(curr, - binary(Abstract::Add, - binary(&sub, Abstract::Sub, ival(0), any(&x)), - any(&y))) && + if (matches( + curr, + binary(Add, binary(&sub, Sub, ival(0), any(&x)), any(&y))) && canReorder(x, y)) { sub->left = y; sub->right = x; @@ -267,9 +267,7 @@ struct OptimizeInstructions Expression* y; Binary* sub; if (matches(curr, - binary(Abstract::Add, - any(&y), - binary(&sub, Abstract::Sub, ival(0), any())))) { + binary(Add, any(&y), binary(&sub, Sub, ival(0), any())))) { sub->left = y; return sub; } @@ -277,10 +275,8 @@ struct OptimizeInstructions { // eqz(x - y) => x == y Binary* inner; - if (matches(curr, - unary(Abstract::EqZ, - binary(&inner, Abstract::Sub, any(), any())))) { - inner->op = Abstract::getBinary(inner->left->type, Abstract::Eq); + if (matches(curr, unary(EqZ, binary(&inner, Sub, any(), any())))) { + inner->op = Abstract::getBinary(inner->left->type, Eq); inner->type = Type::i32; return inner; } @@ -289,11 +285,9 @@ struct OptimizeInstructions // eqz(x + C) => x == -C Const* c; Binary* inner; - if (matches(curr, - unary(Abstract::EqZ, - binary(&inner, Abstract::Add, any(), ival(&c))))) { + if (matches(curr, unary(EqZ, binary(&inner, Add, any(), ival(&c))))) { c->value = c->value.neg(); - inner->op = Abstract::getBinary(c->type, Abstract::Eq); + inner->op = Abstract::getBinary(c->type, Eq); inner->type = Type::i32; return inner; } @@ -302,12 +296,10 @@ struct OptimizeInstructions // eqz((signed)x % C_pot) => eqz(x & (abs(C_pot) - 1)) Const* c; Binary* inner; - if (matches(curr, - unary(Abstract::EqZ, - binary(&inner, Abstract::RemS, any(), ival(&c)))) && + if (matches(curr, unary(EqZ, binary(&inner, RemS, any(), ival(&c)))) && (c->value.isSignedMin() || Bits::isPowerOf2(c->value.abs().getInteger()))) { - inner->op = Abstract::getBinary(c->type, Abstract::And); + inner->op = Abstract::getBinary(c->type, And); if (c->value.isSignedMin()) { c->value = Literal::makeSignedMax(c->type); } else { @@ -373,9 +365,8 @@ struct OptimizeInstructions return x; } } - if (matches( - curr, - binary(&op, any(&x), binary(Abstract::And, any(&y), ival(&c)))) && + if (matches(curr, + binary(&op, any(&x), binary(And, any(&y), ival(&c)))) && Abstract::hasAnyShift(op)) { // i32(x) <<>> (y & 31) ==> x <<>> y // i64(x) <<>> (y & 63) ==> x <<>> y @@ -390,14 +381,14 @@ struct OptimizeInstructions // unsigned(x) >= 0 => i32(1) Const* c; Expression* x; - if (matches(curr, binary(Abstract::GeU, pure(&x), ival(&c))) && + if (matches(curr, binary(GeU, pure(&x), ival(&c))) && c->value.isZero()) { c->value = Literal::makeOne(Type::i32); c->type = Type::i32; return c; } // unsigned(x) < 0 => i32(0) - if (matches(curr, binary(Abstract::LtU, pure(&x), ival(&c))) && + if (matches(curr, binary(LtU, pure(&x), ival(&c))) && c->value.isZero()) { c->value = Literal::makeZero(Type::i32); c->type = Type::i32; @@ -1471,30 +1462,31 @@ private: // is a constant Expression* optimizeWithConstantOnRight(Binary* curr) { using namespace Match; + using namespace Abstract; Builder builder(*getModule()); Expression* left; auto* right = curr->right->cast<Const>(); auto type = curr->right->type; // Operations on zero - if (matches(curr, binary(Abstract::Shl, any(&left), ival(0))) || - matches(curr, binary(Abstract::ShrU, any(&left), ival(0))) || - matches(curr, binary(Abstract::ShrS, any(&left), ival(0))) || - matches(curr, binary(Abstract::Or, any(&left), ival(0))) || - matches(curr, binary(Abstract::Xor, any(&left), ival(0)))) { + if (matches(curr, binary(Shl, any(&left), ival(0))) || + matches(curr, binary(ShrU, any(&left), ival(0))) || + matches(curr, binary(ShrS, any(&left), ival(0))) || + matches(curr, binary(Or, any(&left), ival(0))) || + matches(curr, binary(Xor, any(&left), ival(0)))) { return left; } - if (matches(curr, binary(Abstract::Mul, pure(&left), ival(0))) || - matches(curr, binary(Abstract::And, pure(&left), ival(0)))) { + if (matches(curr, binary(Mul, pure(&left), ival(0))) || + matches(curr, binary(And, pure(&left), ival(0)))) { return right; } // x == 0 ==> eqz x - if (matches(curr, binary(Abstract::Eq, any(&left), ival(0)))) { - return builder.makeUnary(Abstract::getUnary(type, Abstract::EqZ), left); + if (matches(curr, binary(Eq, any(&left), ival(0)))) { + return builder.makeUnary(Abstract::getUnary(type, EqZ), left); } // Operations on one // (signed)x % 1 ==> 0 - if (matches(curr, binary(Abstract::RemS, pure(&left), ival(1)))) { + if (matches(curr, binary(RemS, pure(&left), ival(1)))) { right->value = Literal::makeZero(type); return right; } @@ -1503,12 +1495,10 @@ private: Const* c; Binary* inner; if (matches(curr, - binary(Abstract::Ne, - binary(&inner, Abstract::RemS, any(), ival(&c)), - ival(0))) && + binary(Ne, binary(&inner, RemS, any(), ival(&c)), ival(0))) && (c->value.isSignedMin() || Bits::isPowerOf2(c->value.abs().getInteger()))) { - inner->op = Abstract::getBinary(c->type, Abstract::And); + inner->op = Abstract::getBinary(c->type, And); if (c->value.isSignedMin()) { c->value = Literal::makeSignedMax(c->type); } else { @@ -1523,7 +1513,7 @@ private: // i64(bool(x)) & 1 ==> i64(bool(x)) if ((matches(curr, binary(EqInt32, any(&left), i32(1))) || matches(curr, binary(NeInt32, any(&left), i32(0))) || - matches(curr, binary(Abstract::And, any(&left), ival(1)))) && + matches(curr, binary(And, any(&left), ival(1)))) && Bits::getMaxBits(left, this) == 1) { return left; } @@ -1535,27 +1525,27 @@ private: return builder.makeUnary(WrapInt64, left); } // bool(x) != 1 ==> !bool(x) - if (matches(curr, binary(Abstract::Ne, any(&left), ival(1))) && + if (matches(curr, binary(Ne, any(&left), ival(1))) && Bits::getMaxBits(left, this) == 1) { - return builder.makeUnary(Abstract::getUnary(type, Abstract::EqZ), left); + return builder.makeUnary(Abstract::getUnary(type, EqZ), left); } // bool(x) | 1 ==> 1 - if (matches(curr, binary(Abstract::Or, pure(&left), ival(1))) && + if (matches(curr, binary(Or, pure(&left), ival(1))) && Bits::getMaxBits(left, this) == 1) { return right; } // Operations on all 1s // x & -1 ==> x - if (matches(curr, binary(Abstract::And, any(&left), ival(-1)))) { + if (matches(curr, binary(And, any(&left), ival(-1)))) { return left; } // x | -1 ==> -1 - if (matches(curr, binary(Abstract::Or, pure(&left), ival(-1)))) { + if (matches(curr, binary(Or, pure(&left), ival(-1)))) { return right; } // (signed)x % -1 ==> 0 - if (matches(curr, binary(Abstract::RemS, pure(&left), ival(-1)))) { + if (matches(curr, binary(RemS, pure(&left), ival(-1)))) { right->value = Literal::makeZero(type); return right; } @@ -1577,7 +1567,7 @@ private: return Builder(*getModule()).makeUnary(ExtendUInt32, curr); } // (unsigned)x > -1 ==> 0 - if (matches(curr, binary(Abstract::GtU, pure(&left), ival(-1)))) { + if (matches(curr, binary(GtU, pure(&left), ival(-1)))) { right->value = Literal::makeZero(Type::i32); right->type = Type::i32; return right; @@ -1585,20 +1575,20 @@ private: // (unsigned)x < -1 ==> x != -1 // Friendlier to JS emitting as we don't need to write an unsigned -1 value // which is large. - if (matches(curr, binary(Abstract::LtU, any(), ival(-1)))) { - curr->op = Abstract::getBinary(type, Abstract::Ne); + if (matches(curr, binary(LtU, any(), ival(-1)))) { + curr->op = Abstract::getBinary(type, Ne); return curr; } // x * -1 ==> 0 - x - if (matches(curr, binary(Abstract::Mul, any(&left), ival(-1)))) { + if (matches(curr, binary(Mul, any(&left), ival(-1)))) { right->value = Literal::makeZero(type); - curr->op = Abstract::getBinary(type, Abstract::Sub); + curr->op = Abstract::getBinary(type, Sub); curr->left = right; curr->right = left; return curr; } // (unsigned)x <= -1 ==> 1 - if (matches(curr, binary(Abstract::LeU, pure(&left), ival(-1)))) { + if (matches(curr, binary(LeU, pure(&left), ival(-1)))) { right->value = Literal::makeOne(Type::i32); right->type = Type::i32; return right; @@ -1606,11 +1596,8 @@ private: { // ~(1 << x) aka (1 << x) ^ -1 ==> rotl(-2, x) Expression* x; - if (matches(curr, - binary(Abstract::Xor, - binary(Abstract::Shl, ival(1), any(&x)), - ival(-1)))) { - curr->op = Abstract::getBinary(type, Abstract::RotL); + if (matches(curr, binary(Xor, binary(Shl, ival(1), any(&x)), ival(-1)))) { + curr->op = Abstract::getBinary(type, RotL); right->value = Literal::makeFromInt32(-2, type); curr->left = right; curr->right = x; @@ -1626,28 +1613,27 @@ private: // subtractions than the more common additions). TODO: Simplify this by // adding an ival matcher than can bind int64_t vars. int64_t value; - if ((matches(curr, binary(Abstract::Add, any(), ival(&value))) || - matches(curr, binary(Abstract::Sub, any(), ival(&value)))) && + if ((matches(curr, binary(Add, any(), ival(&value))) || + matches(curr, binary(Sub, any(), ival(&value)))) && (value == 0x40 || value == 0x2000 || value == 0x100000 || value == 0x8000000 || value == 0x400000000LL || value == 0x20000000000LL || value == 0x1000000000000LL || value == 0x80000000000000LL || value == 0x4000000000000000LL)) { right->value = right->value.neg(); - if (matches(curr, binary(Abstract::Add, any(), constant()))) { - curr->op = Abstract::getBinary(type, Abstract::Sub); + if (matches(curr, binary(Add, any(), constant()))) { + curr->op = Abstract::getBinary(type, Sub); } else { - curr->op = Abstract::getBinary(type, Abstract::Add); + curr->op = Abstract::getBinary(type, Add); } return curr; } } { double value; - if (matches(curr, binary(Abstract::Sub, any(), fval(&value))) && - value == 0.0) { + if (matches(curr, binary(Sub, any(), fval(&value))) && value == 0.0) { // x - (-0.0) ==> x + 0.0 if (std::signbit(value)) { - curr->op = Abstract::getBinary(type, Abstract::Add); + curr->op = Abstract::getBinary(type, Add); right->value = right->value.neg(); return curr; } else if (fastMath) { @@ -1659,19 +1645,18 @@ private: { // x + (-0.0) ==> x double value; - if (fastMath && - matches(curr, binary(Abstract::Add, any(), fval(&value))) && + if (fastMath && matches(curr, binary(Add, any(), fval(&value))) && value == 0.0 && std::signbit(value)) { return curr->left; } } // x * -1.0 ==> -x - if (fastMath && matches(curr, binary(Abstract::Mul, any(), fval(-1.0)))) { - return builder.makeUnary(Abstract::getUnary(type, Abstract::Neg), left); + if (fastMath && matches(curr, binary(Mul, any(), fval(-1.0)))) { + return builder.makeUnary(Abstract::getUnary(type, Neg), left); } - if (matches(curr, binary(Abstract::Mul, any(&left), constant(1))) || - matches(curr, binary(Abstract::DivS, any(&left), constant(1))) || - matches(curr, binary(Abstract::DivU, any(&left), constant(1)))) { + if (matches(curr, binary(Mul, any(&left), constant(1))) || + matches(curr, binary(DivS, any(&left), constant(1))) || + matches(curr, binary(DivU, any(&left), constant(1)))) { if (curr->type.isInteger() || fastMath) { return left; } diff --git a/src/passes/Print.cpp b/src/passes/Print.cpp index 42dccb4bf..baf0a325e 100644 --- a/src/passes/Print.cpp +++ b/src/passes/Print.cpp @@ -274,22 +274,22 @@ struct PrintExpressionContents prepareColor(o); printRMWSize(o, curr->type, curr->bytes); switch (curr->op) { - case Add: + case RMWAdd: o << "add"; break; - case Sub: + case RMWSub: o << "sub"; break; - case And: + case RMWAnd: o << "and"; break; - case Or: + case RMWOr: o << "or"; break; - case Xor: + case RMWXor: o << "xor"; break; - case Xchg: + case RMWXchg: o << "xchg"; break; } diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index d735e48c9..d6ce27b31 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -2438,17 +2438,13 @@ private: auto* ptr = makePointer(); if (oneIn(2)) { auto* value = make(type); - return builder.makeAtomicRMW(pick(AtomicRMWOp::Add, - AtomicRMWOp::Sub, - AtomicRMWOp::And, - AtomicRMWOp::Or, - AtomicRMWOp::Xor, - AtomicRMWOp::Xchg), - bytes, - offset, - ptr, - value, - type); + return builder.makeAtomicRMW( + pick(RMWAdd, RMWSub, RMWAnd, RMWOr, RMWXor, RMWXchg), + bytes, + offset, + ptr, + value, + type); } else { auto* expected = make(type); auto* replacement = make(type); diff --git a/src/wasm-interpreter.h b/src/wasm-interpreter.h index 5ca590208..d84591a00 100644 --- a/src/wasm-interpreter.h +++ b/src/wasm-interpreter.h @@ -2165,22 +2165,22 @@ private: NOTE_EVAL1(loaded); auto computed = value.getSingleValue(); switch (curr->op) { - case Add: + case RMWAdd: computed = loaded.add(computed); break; - case Sub: + case RMWSub: computed = loaded.sub(computed); break; - case And: + case RMWAnd: computed = loaded.and_(computed); break; - case Or: + case RMWOr: computed = loaded.or_(computed); break; - case Xor: + case RMWXor: computed = loaded.xor_(computed); break; - case Xchg: + case RMWXchg: break; } instance.doAtomicStore(addr, curr->bytes, computed); diff --git a/src/wasm.h b/src/wasm.h index e2b97204b..048b6c584 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -432,7 +432,7 @@ enum BinaryOp { InvalidBinary }; -enum AtomicRMWOp { Add, Sub, And, Or, Xor, Xchg }; +enum AtomicRMWOp { RMWAdd, RMWSub, RMWAnd, RMWOr, RMWXor, RMWXchg }; enum SIMDExtractOp { ExtractLaneSVecI8x16, diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index 80f82dd5e..d9ddaa614 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -3416,7 +3416,7 @@ bool WasmBinaryBuilder::maybeVisitAtomicRMW(Expression*& out, uint8_t code) { // Set curr to the given opcode, type and size. #define SET(opcode, optype, size) \ - curr->op = opcode; \ + curr->op = RMW##opcode; \ curr->type = optype; \ curr->bytes = size diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 4e06a75bb..f28ea9f18 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -1409,17 +1409,17 @@ Expression* SExpressionWasmBuilder::makeAtomicRMW(Element& s, ret->type = type; ret->bytes = bytes; if (!strncmp(extra, "add", 3)) { - ret->op = Add; + ret->op = RMWAdd; } else if (!strncmp(extra, "and", 3)) { - ret->op = And; + ret->op = RMWAnd; } else if (!strncmp(extra, "or", 2)) { - ret->op = Or; + ret->op = RMWOr; } else if (!strncmp(extra, "sub", 3)) { - ret->op = Sub; + ret->op = RMWSub; } else if (!strncmp(extra, "xor", 3)) { - ret->op = Xor; + ret->op = RMWXor; } else if (!strncmp(extra, "xchg", 4)) { - ret->op = Xchg; + ret->op = RMWXchg; } else { throw ParseException("bad atomic rmw operator", s.line, s.col); } diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp index 4bc479d15..13ce700a5 100644 --- a/src/wasm/wasm-stack.cpp +++ b/src/wasm/wasm-stack.cpp @@ -351,7 +351,7 @@ void BinaryInstWriter::visitAtomicRMW(AtomicRMW* curr) { o << int8_t(BinaryConsts::AtomicPrefix); #define CASE_FOR_OP(Op) \ - case Op: \ + case RMW##Op: \ switch (curr->type.getBasic()) { \ case Type::i32: \ switch (curr->bytes) { \ diff --git a/src/wasm2js.h b/src/wasm2js.h index 8d7e9d105..53137dd43 100644 --- a/src/wasm2js.h +++ b/src/wasm2js.h @@ -1979,22 +1979,22 @@ Ref Wasm2JSBuilder::processFunctionBody(Module* m, getHeapAndAdjustedPointer(curr->bytes, curr->ptr, curr->offset); IString target; switch (curr->op) { - case AtomicRMWOp::Add: + case RMWAdd: target = IString("add"); break; - case AtomicRMWOp::Sub: + case RMWSub: target = IString("sub"); break; - case AtomicRMWOp::And: + case RMWAnd: target = IString("and"); break; - case AtomicRMWOp::Or: + case RMWOr: target = IString("or"); break; - case AtomicRMWOp::Xor: + case RMWXor: target = IString("xor"); break; - case AtomicRMWOp::Xchg: + case RMWXchg: target = IString("exchange"); break; default: |