diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/DeadCodeElimination.cpp | 23 | ||||
-rw-r--r-- | src/wasm-validator.h | 14 | ||||
-rw-r--r-- | src/wasm.h | 2 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 29 |
4 files changed, 43 insertions, 25 deletions
diff --git a/src/passes/DeadCodeElimination.cpp b/src/passes/DeadCodeElimination.cpp index 33a52a09a..0555ff1f0 100644 --- a/src/passes/DeadCodeElimination.cpp +++ b/src/passes/DeadCodeElimination.cpp @@ -81,7 +81,11 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.resize(2); block->list[0] = drop(curr->value); block->list[1] = curr->condition; - block->finalize(); + // if we previously returned a value, then this block + // must have the same type, so it fits in the ast + // properly. it ends in an unreachable + // anyhow, so that is ok. + block->finalize(curr->type); replaceCurrent(block); } else { replaceCurrent(curr->condition); @@ -105,7 +109,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.resize(2); block->list[0] = drop(curr->value); block->list[1] = curr->condition; - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); } else { replaceCurrent(curr->condition); @@ -271,8 +275,9 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> // other things + // we don't need to drop unreachable nodes Expression* drop(Expression* toDrop) { - if (toDrop->is<Unreachable>()) return toDrop; + if (toDrop->type == unreachable) return toDrop; return Builder(*getModule()).makeDrop(toDrop); } @@ -288,7 +293,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> for (; j < newSize; j++) { block->list[j] = drop(curr->operands[j]); } - block->finalize(); + block->finalize(curr->type); return replaceCurrent(block); } else { return replaceCurrent(curr->operands[i]); @@ -314,7 +319,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.push_back(drop(operand)); } block->list.push_back(curr->target); - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); } } @@ -341,7 +346,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.resize(2); block->list[0] = drop(curr->ptr); block->list[1] = curr->value; - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); } } @@ -362,7 +367,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.resize(2); block->list[0] = drop(curr->left); block->list[1] = curr->right; - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); } } @@ -377,7 +382,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list.resize(2); block->list[0] = drop(curr->ifTrue); block->list[1] = curr->ifFalse; - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); return; } @@ -387,7 +392,7 @@ struct DeadCodeElimination : public WalkerPass<PostWalker<DeadCodeElimination>> block->list[0] = drop(curr->ifTrue); block->list[1] = drop(curr->ifFalse); block->list[2] = curr->condition; - block->finalize(); + block->finalize(curr->type); replaceCurrent(block); return; } diff --git a/src/wasm-validator.h b/src/wasm-validator.h index 29787a510..b657b67a6 100644 --- a/src/wasm-validator.h +++ b/src/wasm-validator.h @@ -390,15 +390,7 @@ public: } void visitUnary(Unary *curr) { shouldBeUnequal(curr->value->type, none, curr, "unaries must not receive a none as their input"); - switch (curr->op) { - case EqZInt32: - case EqZInt64: { - shouldBeEqual(curr->type, i32, curr, "eqz must return i32"); - break; - } - default: {} - } - if (curr->value->type == unreachable) return; + if (curr->value->type == unreachable) return; // nothing to check switch (curr->op) { case ClzInt32: case CtzInt32: @@ -420,9 +412,7 @@ public: case TruncFloat64: case NearestFloat64: case SqrtFloat64: { - if (curr->value->type != unreachable) { - shouldBeEqual(curr->value->type, curr->type, curr, "non-conversion unaries must return the same type"); - } + shouldBeEqual(curr->value->type, curr->type, curr, "non-conversion unaries must return the same type"); break; } case EqZInt32: { diff --git a/src/wasm.h b/src/wasm.h index 4804322b6..b23dab918 100644 --- a/src/wasm.h +++ b/src/wasm.h @@ -299,6 +299,8 @@ public: Name default_; Expression* condition; Expression* value; + + void finalize(); }; class Call : public SpecificExpression<Expression::CallId> { diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp index 36eff681f..96ca8fbc8 100644 --- a/src/wasm/wasm.cpp +++ b/src/wasm/wasm.cpp @@ -248,7 +248,9 @@ void Loop::finalize() { void Break::finalize() { if (condition) { - if (value) { + if (condition->type == unreachable) { + type = unreachable; + } else if (value) { type = value->type; } else { type = none; @@ -258,6 +260,10 @@ void Break::finalize() { } } +void Switch::finalize() { + type = unreachable; +} + bool FunctionType::structuralComparison(FunctionType& b) { if (result != b.result) return false; if (params.size() != b.params.size()) return false; @@ -286,6 +292,11 @@ void SetLocal::setTee(bool is) { void Store::finalize() { assert(valueType != none); // must be set + if (ptr->type == unreachable || value->type == unreachable) { + type = unreachable; + } else { + type = none; + } } Const* Const::set(Literal value_) { @@ -299,6 +310,10 @@ bool Unary::isRelational() { } void Unary::finalize() { + if (value->type == unreachable) { + type = unreachable; + return; + } switch (op) { case ClzInt32: case CtzInt32: @@ -390,16 +405,22 @@ bool Binary::isRelational() { void Binary::finalize() { assert(left && right); - if (isRelational()) { + if (left->type == unreachable || right->type == unreachable) { + type = unreachable; + } else if (isRelational()) { type = i32; } else { - type = getReachableWasmType(left->type, right->type); + type = left->type; } } void Select::finalize() { assert(ifTrue && ifFalse); - type = getReachableWasmType(ifTrue->type, ifFalse->type); + if (ifTrue->type == unreachable || ifFalse->type == unreachable || condition->type == unreachable) { + type = unreachable; + } else { + type = ifTrue->type; + } } void Host::finalize() { |