diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/asm2wasm.h | 6 | ||||
-rw-r--r-- | src/binaryen-c.cpp | 9 | ||||
-rw-r--r-- | src/binaryen-c.h | 6 | ||||
-rw-r--r-- | src/ir/ExpressionManipulator.cpp | 2 | ||||
-rw-r--r-- | src/ir/localize.h | 2 | ||||
-rw-r--r-- | src/js/binaryen.js-post.js | 7 | ||||
-rw-r--r-- | src/passes/Flatten.cpp | 5 | ||||
-rw-r--r-- | src/passes/LocalCSE.cpp | 3 | ||||
-rw-r--r-- | src/passes/MergeLocals.cpp | 2 | ||||
-rw-r--r-- | src/passes/RemoveUnusedBrs.cpp | 4 | ||||
-rw-r--r-- | src/passes/SSAify.cpp | 2 | ||||
-rw-r--r-- | src/passes/SimplifyLocals.cpp | 9 | ||||
-rw-r--r-- | src/passes/Untee.cpp | 7 | ||||
-rw-r--r-- | src/passes/Vacuum.cpp | 2 | ||||
-rw-r--r-- | src/tools/fuzzing.h | 2 | ||||
-rw-r--r-- | src/wasm-builder.h | 5 | ||||
-rw-r--r-- | src/wasm.h | 5 | ||||
-rw-r--r-- | src/wasm/wasm-binary.cpp | 7 | ||||
-rw-r--r-- | src/wasm/wasm-emscripten.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 4 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 14 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 21 |
22 files changed, 71 insertions, 57 deletions
diff --git a/src/asm2wasm.h b/src/asm2wasm.h index fc841e634..319116a42 100644 --- a/src/asm2wasm.h +++ b/src/asm2wasm.h @@ -1907,7 +1907,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { auto ret = allocator.alloc<LocalSet>(); ret->index = function->getLocalIndex(assign->target()); ret->value = process(assign->value()); - ret->setTee(false); + ret->makeSet(); ret->finalize(); return ret; } @@ -2158,7 +2158,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { auto set = allocator.alloc<LocalSet>(); set->index = function->getLocalIndex(I32_TEMP); set->value = value; - set->setTee(false); + set->makeSet(); set->finalize(); auto get = [&]() { auto ret = allocator.alloc<LocalGet>(); @@ -2264,7 +2264,7 @@ Function* Asm2WasmBuilder::processFunction(Ref ast) { view.bytes, 0, processUnshifted(ast[2][1], view.bytes), - builder.makeLocalTee(temp, process(ast[2][2])), + builder.makeLocalTee(temp, process(ast[2][2]), type), type), builder.makeLocalGet(temp, type)); } else if (name == Atomics_exchange) { diff --git a/src/binaryen-c.cpp b/src/binaryen-c.cpp index 35f394fd1..70712d4d4 100644 --- a/src/binaryen-c.cpp +++ b/src/binaryen-c.cpp @@ -1197,22 +1197,23 @@ BinaryenExpressionRef BinaryenLocalSet(BinaryenModuleRef module, ret->index = index; ret->value = (Expression*)value; - ret->setTee(false); + ret->makeSet(); ret->finalize(); return static_cast<Expression*>(ret); } BinaryenExpressionRef BinaryenLocalTee(BinaryenModuleRef module, BinaryenIndex index, - BinaryenExpressionRef value) { + BinaryenExpressionRef value, + BinaryenType type) { auto* ret = ((Module*)module)->allocator.alloc<LocalSet>(); if (tracing) { - traceExpression(ret, "BinaryenLocalTee", index, value); + traceExpression(ret, "BinaryenLocalTee", index, value, type); } ret->index = index; ret->value = (Expression*)value; - ret->setTee(true); + ret->makeTee(Type(type)); ret->finalize(); return static_cast<Expression*>(ret); } diff --git a/src/binaryen-c.h b/src/binaryen-c.h index ab3210644..9bbca29f8 100644 --- a/src/binaryen-c.h +++ b/src/binaryen-c.h @@ -650,8 +650,10 @@ BINARYEN_API BinaryenExpressionRef BinaryenLocalGet(BinaryenModuleRef module, BinaryenType type); BINARYEN_API BinaryenExpressionRef BinaryenLocalSet( BinaryenModuleRef module, BinaryenIndex index, BinaryenExpressionRef value); -BINARYEN_API BinaryenExpressionRef BinaryenLocalTee( - BinaryenModuleRef module, BinaryenIndex index, BinaryenExpressionRef value); +BINARYEN_API BinaryenExpressionRef BinaryenLocalTee(BinaryenModuleRef module, + BinaryenIndex index, + BinaryenExpressionRef value, + BinaryenType type); BINARYEN_API BinaryenExpressionRef BinaryenGlobalGet(BinaryenModuleRef module, const char* name, BinaryenType type); diff --git a/src/ir/ExpressionManipulator.cpp b/src/ir/ExpressionManipulator.cpp index fd0e6fd75..fbee9f9c1 100644 --- a/src/ir/ExpressionManipulator.cpp +++ b/src/ir/ExpressionManipulator.cpp @@ -91,7 +91,7 @@ flexibleCopy(Expression* original, Module& wasm, CustomCopier custom) { } Expression* visitLocalSet(LocalSet* curr) { if (curr->isTee()) { - return builder.makeLocalTee(curr->index, copy(curr->value)); + return builder.makeLocalTee(curr->index, copy(curr->value), curr->type); } else { return builder.makeLocalSet(curr->index, copy(curr->value)); } diff --git a/src/ir/localize.h b/src/ir/localize.h index ff454382d..733e7bdec 100644 --- a/src/ir/localize.h +++ b/src/ir/localize.h @@ -36,7 +36,7 @@ struct Localizer { index = set->index; } else { index = Builder::addVar(func, expr->type); - expr = Builder(*wasm).makeLocalTee(index, expr); + expr = Builder(*wasm).makeLocalTee(index, expr, expr->type); } } }; diff --git a/src/js/binaryen.js-post.js b/src/js/binaryen.js-post.js index 65a4e15dc..918d205cf 100644 --- a/src/js/binaryen.js-post.js +++ b/src/js/binaryen.js-post.js @@ -540,8 +540,11 @@ function wrapModule(module, self) { 'set': function(index, value) { return Module['_BinaryenLocalSet'](module, index, value); }, - 'tee': function(index, value) { - return Module['_BinaryenLocalTee'](module, index, value); + 'tee': function(index, value, type) { + if (typeof type === 'undefined') { + throw new Error("local.tee's type should be defined"); + } + return Module['_BinaryenLocalTee'](module, index, value, type); } } diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 6f698367f..74788afb5 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -172,9 +172,10 @@ struct Flatten replaceCurrent(set->value); // trivial, no set happens } else { // use a set in a prelude + a get - set->setTee(false); + set->makeSet(); ourPreludes.push_back(set); - replaceCurrent(builder.makeLocalGet(set->index, set->value->type)); + Type localType = getFunction()->getLocalType(set->index); + replaceCurrent(builder.makeLocalGet(set->index, localType)); } } } else if (auto* br = curr->dynCast<Break>()) { diff --git a/src/passes/LocalCSE.cpp b/src/passes/LocalCSE.cpp index afd30c040..0816bf6ea 100644 --- a/src/passes/LocalCSE.cpp +++ b/src/passes/LocalCSE.cpp @@ -184,8 +184,9 @@ struct LocalCSE : public WalkerPass<LinearExecutionWalker<LocalCSE>> { if (iter != usables.end()) { // already exists in the table, this is good to reuse auto& info = iter->second; + Type localType = getFunction()->getLocalType(info.index); set->value = - Builder(*getModule()).makeLocalGet(info.index, value->type); + Builder(*getModule()).makeLocalGet(info.index, localType); anotherPass = true; } else { // not in table, add this, maybe we can help others later diff --git a/src/passes/MergeLocals.cpp b/src/passes/MergeLocals.cpp index c20105621..0116753f1 100644 --- a/src/passes/MergeLocals.cpp +++ b/src/passes/MergeLocals.cpp @@ -88,7 +88,7 @@ struct MergeLocals if (auto* get = curr->value->dynCast<LocalGet>()) { if (get->index != curr->index) { Builder builder(*getModule()); - auto* trivial = builder.makeLocalTee(get->index, get); + auto* trivial = builder.makeLocalTee(get->index, get, get->type); curr->value = trivial; copies.push_back(curr); } diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp index 55f57302d..e0174934a 100644 --- a/src/passes/RemoveUnusedBrs.cpp +++ b/src/passes/RemoveUnusedBrs.cpp @@ -287,7 +287,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { Expression* z; replaceCurrent( z = builder.makeIf( - builder.makeLocalTee(temp, curr->condition), + builder.makeLocalTee(temp, curr->condition, i32), builder.makeIf(builder.makeBinary(EqInt32, builder.makeLocalGet(temp, i32), builder.makeConst(Literal(int32_t( @@ -1074,7 +1074,7 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs>> { iff->finalize(); Expression* replacement = iff; if (tee) { - set->setTee(false); + set->makeSet(); // We need a block too. replacement = builder.makeSequence(iff, get // reuse the get diff --git a/src/passes/SSAify.cpp b/src/passes/SSAify.cpp index bcafb2784..df32fc77b 100644 --- a/src/passes/SSAify.cpp +++ b/src/passes/SSAify.cpp @@ -154,7 +154,7 @@ struct SSAify : public Pass { if (set) { // a set exists, just add a tee of its value auto* value = set->value; - auto* tee = builder.makeLocalTee(new_, value); + auto* tee = builder.makeLocalTee(new_, value, get->type); set->value = tee; // the value may have been something we tracked the location // of. if so, update that, since we moved it into the tee diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 6b76faed3..a3fa4a34d 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -256,7 +256,7 @@ struct SimplifyLocals } else { this->replaceCurrent(set); assert(!set->isTee()); - set->setTee(true); + set->makeTee(this->getFunction()->getLocalType(set->index)); } // reuse the local.get that is dying *found->second.item = curr; @@ -271,7 +271,7 @@ struct SimplifyLocals auto* set = curr->value->dynCast<LocalSet>(); if (set) { assert(set->isTee()); - set->setTee(false); + set->makeSet(); this->replaceCurrent(set); } } @@ -559,7 +559,7 @@ struct SimplifyLocals auto* set = (*breakLocalSetPointer)->template cast<LocalSet>(); if (br->condition) { br->value = set; - set->setTee(true); + set->makeTee(this->getFunction()->getLocalType(set->index)); *breakLocalSetPointer = this->getModule()->allocator.template alloc<Nop>(); // in addition, as this is a conditional br that now has a value, it now @@ -728,7 +728,8 @@ struct SimplifyLocals ifTrueBlock->finalize(); assert(ifTrueBlock->type != none); // Update the ifFalse side. - iff->ifFalse = builder.makeLocalGet(set->index, set->value->type); + iff->ifFalse = builder.makeLocalGet( + set->index, this->getFunction()->getLocalType(set->index)); iff->finalize(); // update type // Update the get count. getCounter.num[set->index]++; diff --git a/src/passes/Untee.cpp b/src/passes/Untee.cpp index 79c76b988..6e5fb489b 100644 --- a/src/passes/Untee.cpp +++ b/src/passes/Untee.cpp @@ -41,9 +41,10 @@ struct Untee : public WalkerPass<PostWalker<Untee>> { } else { // a normal tee. replace with set and get Builder builder(*getModule()); - replaceCurrent(builder.makeSequence( - curr, builder.makeLocalGet(curr->index, curr->value->type))); - curr->setTee(false); + LocalGet* get = builder.makeLocalGet( + curr->index, getFunction()->getLocalType(curr->index)); + replaceCurrent(builder.makeSequence(curr, get)); + curr->makeSet(); } } } diff --git a/src/passes/Vacuum.cpp b/src/passes/Vacuum.cpp index 26fd2bd0e..48a55ed89 100644 --- a/src/passes/Vacuum.cpp +++ b/src/passes/Vacuum.cpp @@ -346,7 +346,7 @@ struct Vacuum : public WalkerPass<ExpressionStackWalker<Vacuum>> { // a drop of a tee is a set if (auto* set = curr->value->dynCast<LocalSet>()) { assert(set->isTee()); - set->setTee(false); + set->makeSet(); replaceCurrent(set); return; } diff --git a/src/tools/fuzzing.h b/src/tools/fuzzing.h index 3dcb5c665..ce302fac6 100644 --- a/src/tools/fuzzing.h +++ b/src/tools/fuzzing.h @@ -1277,7 +1277,7 @@ private: } auto* value = make(valueType); if (tee) { - return builder.makeLocalTee(pick(locals), value); + return builder.makeLocalTee(pick(locals), value, valueType); } else { return builder.makeLocalSet(pick(locals), value); } diff --git a/src/wasm-builder.h b/src/wasm-builder.h index 22fa0e642..918e6a4ab 100644 --- a/src/wasm-builder.h +++ b/src/wasm-builder.h @@ -232,14 +232,15 @@ public: auto* ret = allocator.alloc<LocalSet>(); ret->index = index; ret->value = value; + ret->makeSet(); ret->finalize(); return ret; } - LocalSet* makeLocalTee(Index index, Expression* value) { + LocalSet* makeLocalTee(Index index, Expression* value, Type type) { auto* ret = allocator.alloc<LocalSet>(); ret->index = index; ret->value = value; - ret->setTee(true); + ret->makeTee(type); return ret; } GlobalGet* makeGlobalGet(Name name, Type type) { diff --git a/src/wasm.h b/src/wasm.h index fba962bdb..cc2070eb2 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -709,8 +709,9 @@ public: Index index; Expression* value; - bool isTee(); - void setTee(bool is); + bool isTee() const; + void makeTee(Type type); + void makeSet(); }; class GlobalGet : public SpecificExpression<Expression::GlobalGetId> { diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp index d86eea8f5..2787725a6 100644 --- a/src/wasm/wasm-binary.cpp +++ b/src/wasm/wasm-binary.cpp @@ -2459,8 +2459,11 @@ void WasmBinaryBuilder::visitLocalSet(LocalSet* curr, uint8_t code) { throwError("bad local.set index"); } curr->value = popNonVoidExpression(); - curr->type = curr->value->type; - curr->setTee(code == BinaryConsts::LocalTee); + if (code == BinaryConsts::LocalTee) { + curr->makeTee(currFunction->getLocalType(curr->index)); + } else { + curr->makeSet(); + } curr->finalize(); } diff --git a/src/wasm/wasm-emscripten.cpp b/src/wasm/wasm-emscripten.cpp index 9a0b145da..be4e51b9e 100644 --- a/src/wasm/wasm-emscripten.cpp +++ b/src/wasm/wasm-emscripten.cpp @@ -112,7 +112,7 @@ inline Expression* stackBoundsCheck(Builder& builder, auto check = builder.makeIf(builder.makeBinary( BinaryOp::LtUInt32, - builder.makeLocalTee(newSP, value), + builder.makeLocalTee(newSP, value, stackPointer->type), builder.makeGlobalGet(stackLimit->name, stackLimit->type)), builder.makeCall(handler, {}, none)); // (global.set $__stack_pointer (local.get $newSP)) @@ -172,7 +172,7 @@ void EmscriptenGlueGenerator::generateStackAllocFunction() { const static uint32_t bitMask = bitAlignment - 1; Const* subConst = builder.makeConst(Literal(~bitMask)); Binary* maskedSub = builder.makeBinary(AndInt32, sub, subConst); - LocalSet* teeStackLocal = builder.makeLocalTee(1, maskedSub); + LocalSet* teeStackLocal = builder.makeLocalTee(1, maskedSub, i32); Expression* storeStack = generateStoreStackPointer(function, teeStackLocal); Block* block = builder.makeBlock(); diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp index 10b6aead7..1319d80fc 100644 --- a/src/wasm/wasm-s-parser.cpp +++ b/src/wasm/wasm-s-parser.cpp @@ -997,7 +997,7 @@ Expression* SExpressionWasmBuilder::makeLocalTee(Element& s) { auto ret = allocator.alloc<LocalSet>(); ret->index = getLocalIndex(*s[1]); ret->value = parseExpression(s[2]); - ret->setTee(true); + ret->makeTee(currFunction->getLocalType(ret->index)); ret->finalize(); return ret; } @@ -1006,7 +1006,7 @@ Expression* SExpressionWasmBuilder::makeLocalSet(Element& s) { auto ret = allocator.alloc<LocalSet>(); ret->index = getLocalIndex(*s[1]); ret->value = parseExpression(s[2]); - ret->setTee(false); + ret->makeSet(); ret->finalize(); return ret; } diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp index c6de444c1..0efc8cf4f 100644 --- a/src/wasm/wasm-validator.cpp +++ b/src/wasm/wasm-validator.cpp @@ -718,15 +718,15 @@ void FunctionValidator::visitLocalSet(LocalSet* curr) { "local.set index must be small enough")) { if (curr->value->type != unreachable) { if (curr->type != none) { // tee is ok anyhow - shouldBeEqualOrFirstIsUnreachable(curr->value->type, - curr->type, - curr, - "local.set type must be correct"); + shouldBeEqual(getFunction()->getLocalType(curr->index), + curr->type, + curr, + "local.set type must be correct"); } - shouldBeEqual(getFunction()->getLocalType(curr->index), - curr->value->type, + shouldBeEqual(curr->value->type, + getFunction()->getLocalType(curr->index), curr, - "local.set type must match function"); + "local.set's value type must be correct"); } } } diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 83829418e..783d51e0f 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -442,24 +442,23 @@ void CallIndirect::finalize() { } } -bool LocalSet::isTee() { return type != none; } +bool LocalSet::isTee() const { return type != none; } -void LocalSet::setTee(bool is) { - if (is) { - type = value->type; - } else { - type = none; - } +// Changes to local.tee. The type of the local should be given. +void LocalSet::makeTee(Type type_) { + type = type_; + finalize(); // type may need to be unreachable +} + +// Changes to local.set. +void LocalSet::makeSet() { + type = none; finalize(); // type may need to be unreachable } void LocalSet::finalize() { if (value->type == unreachable) { type = unreachable; - } else if (isTee()) { - type = value->type; - } else { - type = none; } } |