summaryrefslogtreecommitdiff
path: root/src/wasm/wasm-stack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm/wasm-stack.cpp')
-rw-r--r--src/wasm/wasm-stack.cpp57
1 files changed, 56 insertions, 1 deletions
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 1ed60abed..3cdd1f718 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -2737,6 +2737,45 @@ int32_t BinaryInstWriter::getBreakIndex(Name name) { // -1 if not found
WASM_UNREACHABLE("break index not found");
}
+// Queues the expressions linearly in Stack IR (SIR)
+class StackIRGenerator : public BinaryenIRWriter<StackIRGenerator> {
+public:
+ StackIRGenerator(Module& module, Function* func)
+ : BinaryenIRWriter<StackIRGenerator>(func), module(module) {}
+
+ void emit(Expression* curr);
+ void emitScopeEnd(Expression* curr);
+ void emitHeader() {}
+ void emitIfElse(If* curr) {
+ stackIR.push_back(makeStackInst(StackInst::IfElse, curr));
+ }
+ void emitCatch(Try* curr, Index i) {
+ stackIR.push_back(makeStackInst(StackInst::Catch, curr));
+ }
+ void emitCatchAll(Try* curr) {
+ stackIR.push_back(makeStackInst(StackInst::CatchAll, curr));
+ }
+ void emitDelegate(Try* curr) {
+ stackIR.push_back(makeStackInst(StackInst::Delegate, curr));
+ }
+ void emitFunctionEnd() {}
+ void emitUnreachable() {
+ stackIR.push_back(makeStackInst(Builder(module).makeUnreachable()));
+ }
+ void emitDebugLocation(Expression* curr) {}
+
+ StackIR& getStackIR() { return stackIR; }
+
+private:
+ StackInst* makeStackInst(StackInst::Op op, Expression* origin);
+ StackInst* makeStackInst(Expression* origin) {
+ return makeStackInst(StackInst::Basic, origin);
+ }
+
+ Module& module;
+ StackIR stackIR; // filled in write()
+};
+
void StackIRGenerator::emit(Expression* curr) {
StackInst* stackInst = nullptr;
if (curr->is<Block>()) {
@@ -2798,6 +2837,22 @@ StackInst* StackIRGenerator::makeStackInst(StackInst::Op op,
return ret;
}
+ModuleStackIR::ModuleStackIR(Module& wasm, const PassOptions& options)
+ : analysis(wasm, [&](Function* func, StackIR& stackIR) {
+ if (func->imported()) {
+ return;
+ }
+
+ StackIRGenerator stackIRGen(wasm, func);
+ stackIRGen.write();
+ stackIR = std::move(stackIRGen.getStackIR());
+
+ if (options.optimizeStackIR) {
+ StackIROptimizer optimizer(func, stackIR, options, wasm.features);
+ optimizer.run();
+ }
+ }) {}
+
void StackIRToBinaryWriter::write() {
if (func->prologLocation.size()) {
parent.writeDebugLocation(*func->prologLocation.begin());
@@ -2805,7 +2860,7 @@ void StackIRToBinaryWriter::write() {
writer.mapLocalsAndEmitHeader();
// Stack to track indices of catches within a try
SmallVector<Index, 4> catchIndexStack;
- for (auto* inst : *func->stackIR) {
+ for (auto* inst : stackIR) {
if (!inst) {
continue; // a nullptr is just something we can skip
}