summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--src/abi/abi.h33
-rw-r--r--src/abi/stack.h144
-rw-r--r--src/passes/CMakeLists.txt1
-rw-r--r--src/passes/SpillPointers.cpp206
-rw-r--r--src/passes/pass.cpp3
-rw-r--r--src/passes/passes.h1
-rw-r--r--test/passes/spill-pointers.txt1291
-rw-r--r--test/passes/spill-pointers.wast338
9 files changed, 4 insertions, 2017 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 491163aba..bfae16e89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,10 @@ full changeset diff at the end of each section.
Current Trunk
-------------
+- Remove old/broken SpollPointers pass. This pass: Spills values that might be
+ pointers to the C stack. This allows Boehm-style GC to see them properly.
+ This can be revived if needed from git history (#3261).
+
v98
---
diff --git a/src/abi/abi.h b/src/abi/abi.h
deleted file mode 100644
index 239efd3f3..000000000
--- a/src/abi/abi.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2017 WebAssembly Community Group participants
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef wasm_abi_abi_h
-#define wasm_abi_abi_h
-
-#include "wasm.h"
-
-namespace wasm {
-
-namespace ABI {
-
-// The pointer type. Will need to update this for wasm64
-const static Type PointerType = Type::i32;
-
-} // namespace ABI
-
-} // namespace wasm
-
-#endif // wasm_abi_abi_h
diff --git a/src/abi/stack.h b/src/abi/stack.h
deleted file mode 100644
index e217d7caa..000000000
--- a/src/abi/stack.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright 2017 WebAssembly Community Group participants
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef wasm_abi_stack_h
-#define wasm_abi_stack_h
-
-#include "abi.h"
-#include "asmjs/shared-constants.h"
-#include "ir/find_all.h"
-#include "ir/global-utils.h"
-#include "shared-constants.h"
-#include "wasm-builder.h"
-#include "wasm.h"
-
-namespace wasm {
-
-namespace ABI {
-
-enum { StackAlign = 16 };
-
-inline Index stackAlign(Index size) {
- return (size + StackAlign - 1) & -StackAlign;
-}
-
-// Allocate some space on the stack, and assign it to a local.
-// The local will have the same constant value in all the function, so you can
-// just local.get it anywhere there.
-//
-// FIXME: This function assumes that the stack grows upward, per the convention
-// used by fastcomp. The stack grows downward when using the WASM backend.
-
-inline void
-getStackSpace(Index local, Function* func, Index size, Module& wasm) {
- // Attempt to locate the stack pointer by recognizing code idioms
- // used by Emscripten. First, look for a global initialized to an
- // imported variable named "STACKTOP" in environment "env".
- auto* stackPointer =
- GlobalUtils::getGlobalInitializedToImport(wasm, ENV, "STACKTOP");
- // Starting with Emscripten 1.38.24, the stack pointer variable is
- // initialized with a literal constant, eliminating the import that
- // we used to locate the stack pointer by name. We must match a more
- // complicated idiom, expecting to see the module structured as follows:
- //
- //(module
- // ...
- // (export "stackSave" (func $stackSave))
- // ...
- // (func $stackSave (; 410 ;) (; has Stack IR ;) (result i32)
- // (global.get $STACKTOP)
- // )
- // ...
- //)
- if (!stackPointer) {
- auto* stackSaveFunctionExport = wasm.getExportOrNull("stackSave");
- if (stackSaveFunctionExport &&
- stackSaveFunctionExport->kind == ExternalKind::Function) {
- auto* stackSaveFunction =
- wasm.getFunction(stackSaveFunctionExport->value);
- assert(!stackSaveFunction->imported());
- auto* globalGet = stackSaveFunction->body->dynCast<GlobalGet>();
- if (globalGet) {
- stackPointer = wasm.getGlobal(globalGet->name);
- }
- }
- }
- if (!stackPointer) {
- Fatal() << "getStackSpace: failed to find the stack pointer";
- }
- // align the size
- size = stackAlign(size);
- // TODO: find existing stack usage, and add on top of that - carefully
- Builder builder(wasm);
- auto* block = builder.makeBlock();
- block->list.push_back(builder.makeLocalSet(
- local, builder.makeGlobalGet(stackPointer->name, PointerType)));
- // TODO: add stack max check
- Expression* added;
- if (PointerType == Type::i32) {
- added = builder.makeBinary(AddInt32,
- builder.makeLocalGet(local, PointerType),
- builder.makeConst(int32_t(size)));
- } else {
- WASM_UNREACHABLE("unhandled PointerType");
- }
- block->list.push_back(builder.makeGlobalSet(stackPointer->name, added));
- auto makeStackRestore = [&]() {
- return builder.makeGlobalSet(stackPointer->name,
- builder.makeLocalGet(local, PointerType));
- };
- // add stack restores to the returns
- FindAllPointers<Return> finder(func->body);
- for (auto** ptr : finder.list) {
- auto* ret = (*ptr)->cast<Return>();
- if (ret->value && ret->value->type != Type::unreachable) {
- // handle the returned value
- auto* block = builder.makeBlock();
- auto temp = builder.addVar(func, ret->value->type);
- block->list.push_back(builder.makeLocalSet(temp, ret->value));
- block->list.push_back(makeStackRestore());
- block->list.push_back(
- builder.makeReturn(builder.makeLocalGet(temp, ret->value->type)));
- block->finalize();
- *ptr = block;
- } else {
- // restore, then return
- *ptr = builder.makeSequence(makeStackRestore(), ret);
- }
- }
- // add stack restores to the body
- if (func->body->type == Type::none) {
- block->list.push_back(func->body);
- block->list.push_back(makeStackRestore());
- } else if (func->body->type == Type::unreachable) {
- block->list.push_back(func->body);
- // no need to restore the old stack value, we're gone anyhow
- } else {
- // save the return value
- auto temp = builder.addVar(func, func->sig.results);
- block->list.push_back(builder.makeLocalSet(temp, func->body));
- block->list.push_back(makeStackRestore());
- block->list.push_back(builder.makeLocalGet(temp, func->sig.results));
- }
- block->finalize();
- func->body = block;
-}
-
-} // namespace ABI
-
-} // namespace wasm
-
-#endif // wasm_abi_stack_h
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt
index 1551ba256..00cbaa526 100644
--- a/src/passes/CMakeLists.txt
+++ b/src/passes/CMakeLists.txt
@@ -76,7 +76,6 @@ set(passes_SOURCES
SimplifyGlobals.cpp
SimplifyLocals.cpp
Souperify.cpp
- SpillPointers.cpp
StackCheck.cpp
SSAify.cpp
Untee.cpp
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
deleted file mode 100644
index 453510592..000000000
--- a/src/passes/SpillPointers.cpp
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright 2017 WebAssembly Community Group participants
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-//
-// Spills values that might be pointers to the C stack. This allows
-// Boehm-style GC to see them properly.
-//
-// To reduce the overhead of the extra operations added here, you
-// should probably run optimizations after doing it.
-// TODO: add a dead store elimination pass, which would help here
-//
-// * There is currently no check that there is enough stack space.
-//
-
-#include "abi/abi.h"
-#include "abi/stack.h"
-#include "cfg/liveness-traversal.h"
-#include "pass.h"
-#include "wasm-builder.h"
-#include "wasm.h"
-
-namespace wasm {
-
-struct SpillPointers
- : public WalkerPass<LivenessWalker<SpillPointers, Visitor<SpillPointers>>> {
- bool isFunctionParallel() override { return true; }
-
- Pass* create() override { return new SpillPointers; }
-
- // a mapping of the pointers to all the spillable things. We need to know
- // how to replace them, and as we spill we may modify them. This map
- // gives us, for an Expression** seen during the walk (and placed in the
- // basic block, which is what we iterate on for efficiency) => the
- // current actual pointer, which may have moded
- std::unordered_map<Expression**, Expression**> actualPointers;
-
- // note calls in basic blocks
- template<typename T> void visitSpillable(T* curr) {
- // if in unreachable code, ignore
- if (!currBasicBlock) {
- return;
- }
- auto* pointer = getCurrentPointer();
- currBasicBlock->contents.actions.emplace_back(pointer);
- // starts out as correct, may change later
- actualPointers[pointer] = pointer;
- }
-
- void visitCall(Call* curr) { visitSpillable(curr); }
- void visitCallIndirect(CallIndirect* curr) { visitSpillable(curr); }
-
- // main entry point
-
- void doWalkFunction(Function* func) {
- if (!canRun(func)) {
- return;
- }
- super::doWalkFunction(func);
- spillPointers();
- }
-
- // map pointers to their offset in the spill area
- typedef std::unordered_map<Index, Index> PointerMap;
-
- void spillPointers() {
- // we only care about possible pointers
- auto* func = getFunction();
- PointerMap pointerMap;
- for (Index i = 0; i < func->getNumLocals(); i++) {
- if (func->getLocalType(i) == ABI::PointerType) {
- auto offset = pointerMap.size() * ABI::PointerType.getByteSize();
- pointerMap[i] = offset;
- }
- }
- // find calls and spill around them
- bool spilled = false;
- Index spillLocal = -1;
- for (auto& curr : basicBlocks) {
- if (liveBlocks.count(curr.get()) == 0) {
- continue; // ignore dead blocks
- }
- auto& liveness = curr->contents;
- auto& actions = liveness.actions;
- Index lastCall = -1;
- for (Index i = 0; i < actions.size(); i++) {
- auto& action = liveness.actions[i];
- if (action.isOther()) {
- lastCall = i;
- }
- }
- if (lastCall == Index(-1)) {
- continue; // nothing to see here
- }
- // scan through the block, spilling around the calls
- // TODO: we can filter on pointerMap everywhere
- SetOfLocals live = liveness.end;
- for (int i = int(actions.size()) - 1; i >= 0; i--) {
- auto& action = actions[i];
- if (action.isGet()) {
- live.insert(action.index);
- } else if (action.isSet()) {
- live.erase(action.index);
- } else if (action.isOther()) {
- std::vector<Index> toSpill;
- for (auto index : live) {
- if (pointerMap.count(index) > 0) {
- toSpill.push_back(index);
- }
- }
- if (!toSpill.empty()) {
- // we now have a call + the information about which locals
- // should be spilled
- if (!spilled) {
- // prepare stack support: get a pointer to stack space big enough
- // for all our data
- spillLocal = Builder::addVar(func, ABI::PointerType);
- spilled = true;
- }
- // the origin was seen at walk, but the thing may have moved
- auto* pointer = actualPointers[action.origin];
- spillPointersAroundCall(
- pointer, toSpill, spillLocal, pointerMap, func, getModule());
- }
- } else {
- WASM_UNREACHABLE("unexpected action");
- }
- }
- }
- if (spilled) {
- // get the stack space, and set the local to it
- ABI::getStackSpace(spillLocal,
- func,
- ABI::PointerType.getByteSize() * pointerMap.size(),
- *getModule());
- }
- }
-
- void spillPointersAroundCall(Expression** origin,
- std::vector<Index>& toSpill,
- Index spillLocal,
- PointerMap& pointerMap,
- Function* func,
- Module* module) {
- auto* call = *origin;
- if (call->type == Type::unreachable) {
- return; // the call is never reached anyhow, ignore
- }
- Builder builder(*module);
- auto* block = builder.makeBlock();
- // move the operands into locals, as we must spill after they are executed
- auto handleOperand = [&](Expression*& operand) {
- auto temp = builder.addVar(func, operand->type);
- auto* set = builder.makeLocalSet(temp, operand);
- block->list.push_back(set);
- block->finalize();
- if (actualPointers.count(&operand) > 0) {
- // this is something we track, and it's moving - update
- actualPointers[&operand] = &set->value;
- }
- operand = builder.makeLocalGet(temp, operand->type);
- };
- if (call->is<Call>()) {
- for (auto*& operand : call->cast<Call>()->operands) {
- handleOperand(operand);
- }
- } else if (call->is<CallIndirect>()) {
- for (auto*& operand : call->cast<CallIndirect>()->operands) {
- handleOperand(operand);
- }
- handleOperand(call->cast<CallIndirect>()->target);
- } else {
- WASM_UNREACHABLE("unexpected expr");
- }
- // add the spills
- for (auto index : toSpill) {
- block->list.push_back(
- builder.makeStore(ABI::PointerType.getByteSize(),
- pointerMap[index],
- ABI::PointerType.getByteSize(),
- builder.makeLocalGet(spillLocal, ABI::PointerType),
- builder.makeLocalGet(index, ABI::PointerType),
- ABI::PointerType));
- }
- // add the (modified) call
- block->list.push_back(call);
- block->finalize();
- *origin = block;
- }
-};
-
-Pass* createSpillPointersPass() { return new SpillPointers(); }
-
-} // namespace wasm
diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp
index 67e1ca53b..c6d479dfb 100644
--- a/src/passes/pass.cpp
+++ b/src/passes/pass.cpp
@@ -339,9 +339,6 @@ void PassRegistry::registerPasses() {
registerPass("souperify-single-use",
"emit Souper IR in text form (single-use nodes only)",
createSouperifySingleUsePass);
- registerPass("spill-pointers",
- "spill pointers to the C stack (useful for Boehm-style GC)",
- createSpillPointersPass);
registerPass("stub-unsupported-js",
"stub out unsupported JS operations",
createStubUnsupportedJSOpsPass);
diff --git a/src/passes/passes.h b/src/passes/passes.h
index a36aeb7c3..e88dc835d 100644
--- a/src/passes/passes.h
+++ b/src/passes/passes.h
@@ -118,7 +118,6 @@ Pass* createStripProducersPass();
Pass* createStripTargetFeaturesPass();
Pass* createSouperifyPass();
Pass* createSouperifySingleUsePass();
-Pass* createSpillPointersPass();
Pass* createStubUnsupportedJSOpsPass();
Pass* createSSAifyPass();
Pass* createSSAifyNoMergePass();
diff --git a/test/passes/spill-pointers.txt b/test/passes/spill-pointers.txt
deleted file mode 100644
index fd7683fda..000000000
--- a/test/passes/spill-pointers.txt
+++ /dev/null
@@ -1,1291 +0,0 @@
-(module
- (type $none_=>_none (func))
- (type $i32_=>_i32 (func (param i32) (result i32)))
- (type $none_=>_i32 (func (result i32)))
- (type $i32_i32_=>_none (func (param i32 i32)))
- (type $i32_=>_none (func (param i32)))
- (type $f64_=>_none (func (param f64)))
- (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))
- (import "env" "segfault" (func $segfault (param i32)))
- (memory $0 10)
- (table $0 1 1 funcref)
- (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))
- (func $nothing
- (nop)
- )
- (func $not-alive
- (local $x i32)
- (local.set $x
- (i32.const 1)
- )
- (call $nothing)
- )
- (func $spill
- (local $x i32)
- (local $1 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
- (func $ignore-non-pointers
- (local $x i32)
- (local $y i64)
- (local $z f32)
- (local $w f64)
- (local $4 i32)
- (local.set $4
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $4)
- (i32.const 16)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i64.const 1)
- )
- (local.set $z
- (f32.const 1)
- )
- (local.set $w
- (f64.const 1)
- )
- (block
- (i32.store
- (local.get $4)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- )
- (global.set $stack_ptr
- (local.get $4)
- )
- )
- (func $spill4
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $4 i32)
- (local.set $4
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $4)
- (i32.const 16)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i32.const 1)
- )
- (local.set $z
- (i32.const 1)
- )
- (local.set $w
- (i32.const 1)
- )
- (block
- (i32.store
- (local.get $4)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $4)
- (local.get $y)
- )
- (i32.store offset=8
- (local.get $4)
- (local.get $z)
- )
- (i32.store offset=12
- (local.get $4)
- (local.get $w)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- )
- (global.set $stack_ptr
- (local.get $4)
- )
- )
- (func $spill5
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $a i32)
- (local $5 i32)
- (local.set $5
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $5)
- (i32.const 32)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i32.const 1)
- )
- (local.set $z
- (i32.const 1)
- )
- (local.set $w
- (i32.const 1)
- )
- (local.set $a
- (i32.const 1)
- )
- (block
- (i32.store
- (local.get $5)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $5)
- (local.get $y)
- )
- (i32.store offset=8
- (local.get $5)
- (local.get $z)
- )
- (i32.store offset=12
- (local.get $5)
- (local.get $w)
- )
- (i32.store offset=16
- (local.get $5)
- (local.get $a)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- (drop
- (local.get $a)
- )
- )
- (global.set $stack_ptr
- (local.get $5)
- )
- )
- (func $some-alive
- (local $x i32)
- (local $y i32)
- (local $2 i32)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (block
- (block
- (i32.store
- (local.get $2)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- )
- (func $spill-args (param $p i32) (param $q i32)
- (local $x i32)
- (local $3 i32)
- (local $4 i32)
- (local $5 i32)
- (local.set $3
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $3)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $4
- (i32.const 1)
- )
- (local.set $5
- (i32.const 2)
- )
- (i32.store offset=8
- (local.get $3)
- (local.get $x)
- )
- (call $spill-args
- (local.get $4)
- (local.get $5)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $3)
- )
- )
- (func $spill-ret (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $4
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (if
- (i32.const 1)
- (block
- (local.set $2
- (i32.const 2)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $2)
- )
- )
- (block
- (local.set $3
- (i32.const 3)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $3)
- )
- )
- )
- (i32.const 4)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $4)
- )
- (func $spill-unreachable (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $2
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (unreachable)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $2)
- )
- (func $spill-call-call0 (param $p i32) (result i32)
- (unreachable)
- )
- (func $spill-call-call1 (param $p i32) (result i32)
- (local $x i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local $5 i32)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (local.set $5
- (block (result i32)
- (drop
- (block (result i32)
- (local.set $3
- (block (result i32)
- (local.set $4
- (i32.const 1)
- )
- (i32.store offset=4
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-call1
- (local.get $4)
- )
- )
- )
- (i32.store offset=4
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-call0
- (local.get $3)
- )
- )
- )
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- (local.get $5)
- )
- (func $spill-call-ret (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (return
- (i32.const 1)
- )
- )
- )
- (i32.const 0)
- )
- (func $spill-ret-call (param $p i32) (result i32)
- (local $x i32)
- (drop
- (return
- (call $spill-call-call0
- (i32.const 1)
- )
- )
- )
- (i32.const 0)
- )
- (func $spill-ret-ret (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $3
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (block
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (block
- (local.set $2
- (i32.const 1)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $2)
- )
- )
- )
- )
- )
- (i32.const 0)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $3)
- )
- (func $spill-call-othertype (param $y f64)
- (local $x i32)
- (local $2 i32)
- (local $3 f64)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $3
- (f64.const 1)
- )
- (i32.store
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-othertype
- (local.get $3)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- )
- (func $spill-call_indirect
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $2
- (i32.const 123)
- )
- (local.set $3
- (i32.const 456)
- )
- (local.set $4
- (i32.const 789)
- )
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call_indirect (type $i32_i32_=>_none)
- (local.get $2)
- (local.get $3)
- (local.get $4)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
- (func $spill-call_import
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $2
- (i32.const 200)
- )
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $segfault
- (local.get $2)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
-)
-(module
- (type $none_=>_none (func))
- (type $none_=>_i32 (func (result i32)))
- (type $i32_=>_i32 (func (param i32) (result i32)))
- (type $i32_i32_=>_none (func (param i32 i32)))
- (type $i32_=>_none (func (param i32)))
- (type $f64_=>_none (func (param f64)))
- (import "env" "segfault" (func $segfault (param i32)))
- (memory $0 10)
- (table $0 1 1 funcref)
- (global $stack_ptr (mut i32) (i32.const 1716592))
- (export "stackSave" (func $stack_save))
- (func $stack_save (result i32)
- (global.get $stack_ptr)
- )
- (func $nothing
- (nop)
- )
- (func $not-alive
- (local $x i32)
- (local.set $x
- (i32.const 1)
- )
- (call $nothing)
- )
- (func $spill
- (local $x i32)
- (local $1 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
- (func $ignore-non-pointers
- (local $x i32)
- (local $y i64)
- (local $z f32)
- (local $w f64)
- (local $4 i32)
- (local.set $4
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $4)
- (i32.const 16)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i64.const 1)
- )
- (local.set $z
- (f32.const 1)
- )
- (local.set $w
- (f64.const 1)
- )
- (block
- (i32.store
- (local.get $4)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- )
- (global.set $stack_ptr
- (local.get $4)
- )
- )
- (func $spill4
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $4 i32)
- (local.set $4
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $4)
- (i32.const 16)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i32.const 1)
- )
- (local.set $z
- (i32.const 1)
- )
- (local.set $w
- (i32.const 1)
- )
- (block
- (i32.store
- (local.get $4)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $4)
- (local.get $y)
- )
- (i32.store offset=8
- (local.get $4)
- (local.get $z)
- )
- (i32.store offset=12
- (local.get $4)
- (local.get $w)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- )
- (global.set $stack_ptr
- (local.get $4)
- )
- )
- (func $spill5
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $a i32)
- (local $5 i32)
- (local.set $5
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $5)
- (i32.const 32)
- )
- )
- (block
- (local.set $x
- (i32.const 1)
- )
- (local.set $y
- (i32.const 1)
- )
- (local.set $z
- (i32.const 1)
- )
- (local.set $w
- (i32.const 1)
- )
- (local.set $a
- (i32.const 1)
- )
- (block
- (i32.store
- (local.get $5)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $5)
- (local.get $y)
- )
- (i32.store offset=8
- (local.get $5)
- (local.get $z)
- )
- (i32.store offset=12
- (local.get $5)
- (local.get $w)
- )
- (i32.store offset=16
- (local.get $5)
- (local.get $a)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (local.get $y)
- )
- (drop
- (local.get $z)
- )
- (drop
- (local.get $w)
- )
- (drop
- (local.get $a)
- )
- )
- (global.set $stack_ptr
- (local.get $5)
- )
- )
- (func $some-alive
- (local $x i32)
- (local $y i32)
- (local $2 i32)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (block
- (block
- (i32.store
- (local.get $2)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- )
- (func $spill-args (param $p i32) (param $q i32)
- (local $x i32)
- (local $3 i32)
- (local $4 i32)
- (local $5 i32)
- (local.set $3
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $3)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $4
- (i32.const 1)
- )
- (local.set $5
- (i32.const 2)
- )
- (i32.store offset=8
- (local.get $3)
- (local.get $x)
- )
- (call $spill-args
- (local.get $4)
- (local.get $5)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $3)
- )
- )
- (func $spill-ret (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $4
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (if
- (i32.const 1)
- (block
- (local.set $2
- (i32.const 2)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $2)
- )
- )
- (block
- (local.set $3
- (i32.const 3)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $3)
- )
- )
- )
- (i32.const 4)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $4)
- )
- (func $spill-unreachable (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $2
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (unreachable)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $2)
- )
- (func $spill-call-call0 (param $p i32) (result i32)
- (unreachable)
- )
- (func $spill-call-call1 (param $p i32) (result i32)
- (local $x i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local $5 i32)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (local.set $5
- (block (result i32)
- (drop
- (block (result i32)
- (local.set $3
- (block (result i32)
- (local.set $4
- (i32.const 1)
- )
- (i32.store offset=4
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-call1
- (local.get $4)
- )
- )
- )
- (i32.store offset=4
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-call0
- (local.get $3)
- )
- )
- )
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- (local.get $5)
- )
- (func $spill-call-ret (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (return
- (i32.const 1)
- )
- )
- )
- (i32.const 0)
- )
- (func $spill-ret-call (param $p i32) (result i32)
- (local $x i32)
- (drop
- (return
- (call $spill-call-call0
- (i32.const 1)
- )
- )
- )
- (i32.const 0)
- )
- (func $spill-ret-ret (result i32)
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (local.set $3
- (block (result i32)
- (block
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $nothing)
- )
- (drop
- (local.get $x)
- )
- (drop
- (block
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (block
- (local.set $2
- (i32.const 1)
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (return
- (local.get $2)
- )
- )
- )
- )
- )
- (i32.const 0)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- (local.get $3)
- )
- (func $spill-call-othertype (param $y f64)
- (local $x i32)
- (local $2 i32)
- (local $3 f64)
- (local.set $2
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $2)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $3
- (f64.const 1)
- )
- (i32.store
- (local.get $2)
- (local.get $x)
- )
- (call $spill-call-othertype
- (local.get $3)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $2)
- )
- )
- (func $spill-call_indirect
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local $3 i32)
- (local $4 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $2
- (i32.const 123)
- )
- (local.set $3
- (i32.const 456)
- )
- (local.set $4
- (i32.const 789)
- )
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call_indirect (type $i32_i32_=>_none)
- (local.get $2)
- (local.get $3)
- (local.get $4)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
- (func $spill-call_import
- (local $x i32)
- (local $1 i32)
- (local $2 i32)
- (local.set $1
- (global.get $stack_ptr)
- )
- (global.set $stack_ptr
- (i32.add
- (local.get $1)
- (i32.const 16)
- )
- )
- (block
- (block
- (local.set $2
- (i32.const 200)
- )
- (i32.store
- (local.get $1)
- (local.get $x)
- )
- (call $segfault
- (local.get $2)
- )
- )
- (drop
- (local.get $x)
- )
- )
- (global.set $stack_ptr
- (local.get $1)
- )
- )
-)
diff --git a/test/passes/spill-pointers.wast b/test/passes/spill-pointers.wast
deleted file mode 100644
index 4eb05a721..000000000
--- a/test/passes/spill-pointers.wast
+++ /dev/null
@@ -1,338 +0,0 @@
-(module
- (memory 10)
- (type $ii (func (param i32 i32)))
- (table 1 1 funcref)
- (elem (i32.const 0))
- (import "env" "STACKTOP" (global $STACKTOP$asm2wasm$import i32))
- (import "env" "segfault" (func $segfault (param i32)))
- (global $stack_ptr (mut i32) (global.get $STACKTOP$asm2wasm$import))
-
- (func $nothing
- )
- (func $not-alive
- (local $x i32)
- (local.set $x (i32.const 1))
- (call $nothing)
- )
- (func $spill
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- )
- (func $ignore-non-pointers
- (local $x i32)
- (local $y i64)
- (local $z f32)
- (local $w f64)
- (local.set $x (i32.const 1))
- (local.set $y (i64.const 1))
- (local.set $z (f32.const 1))
- (local.set $w (f64.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- )
- (func $spill4
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local.set $x (i32.const 1))
- (local.set $y (i32.const 1))
- (local.set $z (i32.const 1))
- (local.set $w (i32.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- )
- (func $spill5
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $a i32)
- (local.set $x (i32.const 1))
- (local.set $y (i32.const 1))
- (local.set $z (i32.const 1))
- (local.set $w (i32.const 1))
- (local.set $a (i32.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- (drop (local.get $a))
- )
- (func $some-alive
- (local $x i32)
- (local $y i32)
- (call $nothing)
- (drop (local.get $x))
- )
- (func $spill-args (param $p i32) (param $q i32)
- (local $x i32)
- (call $spill-args (i32.const 1) (i32.const 2))
- (drop (local.get $x))
- )
- (func $spill-ret (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (if (i32.const 1)
- (return (i32.const 2))
- (return (i32.const 3))
- )
- (i32.const 4)
- )
- (func $spill-unreachable (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (unreachable)
- )
- (func $spill-call-call0 (param $p i32) (result i32)
- (unreachable)
- )
- (func $spill-call-call1 (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (call $spill-call-call1
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-call-ret (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (return
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-ret-call (param $p i32) (result i32)
- (local $x i32)
- (drop
- (return
- (call $spill-call-call0
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-ret-ret (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (drop
- (return
- (return
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-call-othertype (param $y f64)
- (local $x i32)
- (call $spill-call-othertype (f64.const 1))
- (drop (local.get $x))
- )
- (func $spill-call_indirect
- (local $x i32)
- (call_indirect (type $ii)
- (i32.const 123)
- (i32.const 456)
- (i32.const 789)
- )
- (drop (local.get $x))
- )
- (func $spill-call_import
- (local $x i32)
- (call $segfault
- (i32.const 200)
- )
- (drop (local.get $x))
- )
-)
-
-(module
- (memory 10)
- (type $ii (func (param i32 i32)))
- (table 1 1 funcref)
- (elem (i32.const 0))
- (global $stack_ptr (mut i32) (i32.const 1716592))
- (export "stackSave" (func $stack_save))
- (import "env" "segfault" (func $segfault (param i32)))
- (func $stack_save (result i32)
- (global.get $stack_ptr)
- )
-
- (func $nothing
- )
- (func $not-alive
- (local $x i32)
- (local.set $x (i32.const 1))
- (call $nothing)
- )
- (func $spill
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- )
- (func $ignore-non-pointers
- (local $x i32)
- (local $y i64)
- (local $z f32)
- (local $w f64)
- (local.set $x (i32.const 1))
- (local.set $y (i64.const 1))
- (local.set $z (f32.const 1))
- (local.set $w (f64.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- )
- (func $spill4
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local.set $x (i32.const 1))
- (local.set $y (i32.const 1))
- (local.set $z (i32.const 1))
- (local.set $w (i32.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- )
- (func $spill5
- (local $x i32)
- (local $y i32)
- (local $z i32)
- (local $w i32)
- (local $a i32)
- (local.set $x (i32.const 1))
- (local.set $y (i32.const 1))
- (local.set $z (i32.const 1))
- (local.set $w (i32.const 1))
- (local.set $a (i32.const 1))
- (call $nothing)
- (drop (local.get $x))
- (drop (local.get $y))
- (drop (local.get $z))
- (drop (local.get $w))
- (drop (local.get $a))
- )
- (func $some-alive
- (local $x i32)
- (local $y i32)
- (call $nothing)
- (drop (local.get $x))
- )
- (func $spill-args (param $p i32) (param $q i32)
- (local $x i32)
- (call $spill-args (i32.const 1) (i32.const 2))
- (drop (local.get $x))
- )
- (func $spill-ret (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (if (i32.const 1)
- (return (i32.const 2))
- (return (i32.const 3))
- )
- (i32.const 4)
- )
- (func $spill-unreachable (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (unreachable)
- )
- (func $spill-call-call0 (param $p i32) (result i32)
- (unreachable)
- )
- (func $spill-call-call1 (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (call $spill-call-call1
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-call-ret (param $p i32) (result i32)
- (local $x i32)
- (drop
- (call $spill-call-call0
- (return
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-ret-call (param $p i32) (result i32)
- (local $x i32)
- (drop
- (return
- (call $spill-call-call0
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-ret-ret (result i32)
- (local $x i32)
- (call $nothing)
- (drop (local.get $x))
- (drop
- (return
- (return
- (i32.const 1)
- )
- )
- )
- (local.get $x)
- )
- (func $spill-call-othertype (param $y f64)
- (local $x i32)
- (call $spill-call-othertype (f64.const 1))
- (drop (local.get $x))
- )
- (func $spill-call_indirect
- (local $x i32)
- (call_indirect (type $ii)
- (i32.const 123)
- (i32.const 456)
- (i32.const 789)
- )
- (drop (local.get $x))
- )
- (func $spill-call_import
- (local $x i32)
- (call $segfault
- (i32.const 200)
- )
- (drop (local.get $x))
- )
-)