summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/cfg/liveness-traversal.h16
-rw-r--r--src/passes/CoalesceLocals.cpp3
-rw-r--r--src/passes/SpillPointers.cpp3
-rw-r--r--test/passes/too_much_for_liveness.bin.txt35
-rw-r--r--test/passes/too_much_for_liveness.passes1
-rw-r--r--test/passes/too_much_for_liveness.wasmbin0 -> 44 bytes
6 files changed, 58 insertions, 0 deletions
diff --git a/src/cfg/liveness-traversal.h b/src/cfg/liveness-traversal.h
index d665c07af..6deab2fd6 100644
--- a/src/cfg/liveness-traversal.h
+++ b/src/cfg/liveness-traversal.h
@@ -171,10 +171,26 @@ struct LivenessWalker : public CFGWalker<SubType, VisitorType, Liveness> {
return nullptr;
}
+ // If there are too many locals, we cannot run currently as
+ // numLocals * numLocals might overflow. We may want to add an option for
+ // a sparse matrix at some point TODO
+ bool canRun(Function* func) {
+ Index numLocals = func->getNumLocals();
+ if (uint64_t(numLocals) * uint64_t(numLocals) <=
+ std::numeric_limits<Index>::max()) {
+ return true;
+ }
+ std::cerr << "warning: too many locals (" << numLocals
+ << ") to run liveness analysis in " << this->getFunction()->name
+ << '\n';
+ return false;
+ }
+
// main entry point
void doWalkFunction(Function* func) {
numLocals = func->getNumLocals();
+ assert(canRun(func));
copies.resize(numLocals * numLocals);
std::fill(copies.begin(), copies.end(), 0);
totalCopies.resize(numLocals);
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp
index 9bc635f80..232685001 100644
--- a/src/passes/CoalesceLocals.cpp
+++ b/src/passes/CoalesceLocals.cpp
@@ -92,6 +92,9 @@ struct CoalesceLocals
};
void CoalesceLocals::doWalkFunction(Function* func) {
+ if (!canRun(func)) {
+ return;
+ }
super::doWalkFunction(func);
// prioritize back edges
increaseBackEdgePriorities();
diff --git a/src/passes/SpillPointers.cpp b/src/passes/SpillPointers.cpp
index 758ca3223..7458f5fbd 100644
--- a/src/passes/SpillPointers.cpp
+++ b/src/passes/SpillPointers.cpp
@@ -65,6 +65,9 @@ struct SpillPointers
// main entry point
void doWalkFunction(Function* func) {
+ if (!canRun(func)) {
+ return;
+ }
super::doWalkFunction(func);
spillPointers();
}
diff --git a/test/passes/too_much_for_liveness.bin.txt b/test/passes/too_much_for_liveness.bin.txt
new file mode 100644
index 000000000..29433a77c
--- /dev/null
+++ b/test/passes/too_much_for_liveness.bin.txt
@@ -0,0 +1,35 @@
+total
+ [events] : 0
+ [exports] : 1
+ [funcs] : 1
+ [globals] : 0
+ [imports] : 0
+ [total] : 4
+ [vars] : 65536
+ block : 1
+ const : 1
+ local.get : 1
+ local.set : 1
+total
+ [events] : 0
+ [exports] : 1
+ [funcs] : 1
+ [globals] : 0
+ [imports] : 0
+ [total] : 4
+ [vars] : 65536
+ block : 1
+ const : 1
+ local.get : 1
+ local.set : 1
+(module
+ (type $none_=>_i32 (func (result i32)))
+ (export "foo" (func $0))
+ (func $0 (; 0 ;) (result i32)
+ (local $0 i32)
+ (local.set $0
+ (i32.const 0)
+ )
+ (local.get $0)
+ )
+)
diff --git a/test/passes/too_much_for_liveness.passes b/test/passes/too_much_for_liveness.passes
new file mode 100644
index 000000000..719d0bbcd
--- /dev/null
+++ b/test/passes/too_much_for_liveness.passes
@@ -0,0 +1 @@
+metrics_coalesce-locals_metrics_reorder-locals
diff --git a/test/passes/too_much_for_liveness.wasm b/test/passes/too_much_for_liveness.wasm
new file mode 100644
index 000000000..88929243d
--- /dev/null
+++ b/test/passes/too_much_for_liveness.wasm
Binary files differ