#include <pass.h>
#include <wasm.h>
#include "wasm-builder.h"
#include <ir/abstract.h>
#include <ir/literal-utils.h>
#include <ir/localize.h>
#include <ir/match.h>
namespace wasm {
struct OptimizeForJSPass : public WalkerPass<PostWalker<OptimizeForJSPass>> {
bool isFunctionParallel() override { return true; }
std::unique_ptr<Pass> create() override {
return std::make_unique<OptimizeForJSPass>();
}
void visitBinary(Binary* curr) {
using namespace Abstract;
using namespace Match;
{
Expression* x;
if (matches(curr, binary(Eq, unary(Popcnt, any(&x)), ival(1)))) {
rewritePopcntEqualOne(x);
}
}
}
void rewritePopcntEqualOne(Expression* expr) {
using namespace Abstract;
Type type = expr->type;
UnaryOp eqzOp = getUnary(type, EqZ);
Localizer temp(expr, getFunction(), getModule());
Builder builder(*getModule());
replaceCurrent(builder.makeBinary(
AndInt32,
builder.makeUnary(EqZInt32, builder.makeUnary(eqzOp, temp.expr)),
builder.makeUnary(
eqzOp,
builder.makeBinary(
getBinary(type, And),
builder.makeLocalGet(temp.index, type),
builder.makeBinary(
getBinary(type, Sub),
builder.makeLocalGet(temp.index, type),
builder.makeConst(Literal::makeOne(type.getBasic())))))));
}
};
Pass* createOptimizeForJSPass() { return new OptimizeForJSPass(); }
}