diff options
-rw-r--r-- | src/cfg/liveness-traversal.h | 16 | ||||
-rw-r--r-- | src/passes/CoalesceLocals.cpp | 3 | ||||
-rw-r--r-- | src/passes/SpillPointers.cpp | 3 | ||||
-rw-r--r-- | test/passes/too_much_for_liveness.bin.txt | 35 | ||||
-rw-r--r-- | test/passes/too_much_for_liveness.passes | 1 | ||||
-rw-r--r-- | test/passes/too_much_for_liveness.wasm | bin | 0 -> 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 Binary files differnew file mode 100644 index 000000000..88929243d --- /dev/null +++ b/test/passes/too_much_for_liveness.wasm |