summaryrefslogtreecommitdiff
path: root/src/wasm-stack.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm-stack.h')
-rw-r--r--src/wasm-stack.h96
1 files changed, 58 insertions, 38 deletions
diff --git a/src/wasm-stack.h b/src/wasm-stack.h
index 5858d6f88..ae453f9de 100644
--- a/src/wasm-stack.h
+++ b/src/wasm-stack.h
@@ -18,6 +18,7 @@
#define wasm_stack_h
#include "ir/branch-utils.h"
+#include "ir/module-utils.h"
#include "ir/properties.h"
#include "pass.h"
#include "support/insert_ordered.h"
@@ -85,6 +86,8 @@ public:
Type type;
};
+using StackIR = std::vector<StackInst*>;
+
class BinaryInstWriter : public OverriddenVisitor<BinaryInstWriter> {
public:
BinaryInstWriter(WasmBinaryWriter& parent,
@@ -468,44 +471,24 @@ private:
bool sourceMap;
};
-// Binaryen IR to stack IR converter
-// 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; }
+// Binaryen IR to stack IR converter for an entire module. Generates all the
+// StackIR in parallel, and then allows querying for the StackIR of individual
+// functions.
+class ModuleStackIR {
+ ModuleUtils::ParallelFunctionAnalysis<StackIR> analysis;
-private:
- StackInst* makeStackInst(StackInst::Op op, Expression* origin);
- StackInst* makeStackInst(Expression* origin) {
- return makeStackInst(StackInst::Basic, origin);
+public:
+ ModuleStackIR(Module& wasm, const PassOptions& options);
+
+ // Get StackIR for a function, if it exists. (This allows some functions to
+ // have it and others not, if we add such capability in the future.)
+ StackIR* getStackIROrNull(Function* func) {
+ auto iter = analysis.map.find(func);
+ if (iter == analysis.map.end()) {
+ return nullptr;
+ }
+ return &iter->second;
}
-
- Module& module;
- StackIR stackIR; // filled in write()
};
// Stack IR to binary writer
@@ -514,10 +497,11 @@ public:
StackIRToBinaryWriter(WasmBinaryWriter& parent,
BufferWithRandomAccess& o,
Function* func,
+ StackIR& stackIR,
bool sourceMap = false,
bool DWARF = false)
: parent(parent), writer(parent, o, func, sourceMap, DWARF), func(func),
- sourceMap(sourceMap) {}
+ stackIR(stackIR), sourceMap(sourceMap) {}
void write();
@@ -527,11 +511,47 @@ private:
WasmBinaryWriter& parent;
BinaryInstWriter writer;
Function* func;
+ StackIR& stackIR;
bool sourceMap;
};
-std::ostream& printStackIR(std::ostream& o, Module* module, bool optimize);
+// Stack IR optimizer
+class StackIROptimizer {
+ Function* func;
+ StackIR& insts;
+ const PassOptions& passOptions;
+ FeatureSet features;
+
+public:
+ StackIROptimizer(Function* func,
+ StackIR& insts,
+ const PassOptions& passOptions,
+ FeatureSet features);
+
+ void run();
+
+private:
+ void dce();
+ void vacuum();
+ void local2Stack();
+ void removeUnneededBlocks();
+ bool isControlFlowBarrier(StackInst* inst);
+ bool isControlFlowBegin(StackInst* inst);
+ bool isControlFlowEnd(StackInst* inst);
+ bool isControlFlow(StackInst* inst);
+ void removeAt(Index i);
+ Index getNumConsumedValues(StackInst* inst);
+ bool canRemoveSetGetPair(Index setIndex, Index getIndex);
+};
+
+// Generate and emit StackIR.
+std::ostream&
+printStackIR(std::ostream& o, Module* module, const PassOptions& options);
} // namespace wasm
+namespace std {
+std::ostream& operator<<(std::ostream& o, wasm::StackInst& inst);
+} // namespace std
+
#endif // wasm_stack_h