summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSam Clegg <sbc@chromium.org>2020-10-20 18:24:54 -0500
committerGitHub <noreply@github.com>2020-10-20 16:24:54 -0700
commitc61cb6f07a244067a7964d0d99c0fef0a068a3bf (patch)
tree823c77416384911be496d1fb119d99a1d89ada30 /src
parent2927d92a0df05512649629084d9b0013e002ae89 (diff)
downloadbinaryen-c61cb6f07a244067a7964d0d99c0fef0a068a3bf.tar.gz
binaryen-c61cb6f07a244067a7964d0d99c0fef0a068a3bf.tar.bz2
binaryen-c61cb6f07a244067a7964d0d99c0fef0a068a3bf.zip
Remove old/non-working SpillPointers pass (#3261)
And associated stack.h. The current stack.h clearly doesn't work with the llvm back as it assumes the stack grows up, which means non of these has been working or used in a long time. Rather than trying to fix this unused features its probably cleaner to just remove it for now and restore it rom git history if its someone that anyone actually wants to use in the future.
Diffstat (limited to 'src')
-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
6 files changed, 0 insertions, 388 deletions
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();