diff options
-rw-r--r-- | src/passes/CoalesceLocals.cpp | 14 | ||||
-rw-r--r-- | test/passes/coalesce-locals-learning.txt | 3 | ||||
-rw-r--r-- | test/passes/coalesce-locals.txt | 3 | ||||
-rw-r--r-- | test/unit.asm.js | 13 | ||||
-rw-r--r-- | test/unit.fromasm | 28 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise | 28 | ||||
-rw-r--r-- | test/unit.fromasm.imprecise.no-opts | 28 | ||||
-rw-r--r-- | test/unit.fromasm.no-opts | 28 |
8 files changed, 139 insertions, 6 deletions
diff --git a/src/passes/CoalesceLocals.cpp b/src/passes/CoalesceLocals.cpp index 39c480107..c36371ec0 100644 --- a/src/passes/CoalesceLocals.cpp +++ b/src/passes/CoalesceLocals.cpp @@ -183,7 +183,7 @@ struct CoalesceLocals : public WalkerPass<CFGWalker<CoalesceLocals, Visitor<Coal void calculateInterferences(); - void calculateInterferences(LocalSet& locals); + void calculateInterferences(const LocalSet& locals); // merge starts of a list of blocks, adding new interferences as necessary. return // whether anything changed vs an old state (which indicates further processing is necessary). @@ -282,8 +282,6 @@ void CoalesceLocals::flowLiveness() { queue.insert(in); } } - // live locals at the entry block include params, obviously, but also - // vars, in which case the 0-init value is actually used. #ifdef CFG_DEBUG std::hash<std::vector<bool>> hasher; std::cout << getFunction()->name << ": interference hash: " << hasher(*(std::vector<bool>*)&interferences) << "\n"; @@ -347,9 +345,17 @@ void CoalesceLocals::calculateInterferences() { } } } + // Params have a value on entry, so mark them as live, as variables + // live at the entry expect their zero-init value. + LocalSet start = entry->contents.start; + auto numParams = getFunction()->getNumParams(); + for (Index i = 0; i < numParams; i++) { + start.insert(i); + } + calculateInterferences(start); } -void CoalesceLocals::calculateInterferences(LocalSet& locals) { +void CoalesceLocals::calculateInterferences(const LocalSet& locals) { size_t size = locals.size(); for (size_t i = 0; i < size; i++) { for (size_t j = i + 1; j < size; j++) { diff --git a/test/passes/coalesce-locals-learning.txt b/test/passes/coalesce-locals-learning.txt index 14091cb98..aa3c8c9c0 100644 --- a/test/passes/coalesce-locals-learning.txt +++ b/test/passes/coalesce-locals-learning.txt @@ -318,9 +318,10 @@ (func $params (param $0 i32) (param $1 f32) (local $2 i32) (local $3 i32) - (get_local $0) + (local $4 i32) (get_local $2) (get_local $3) + (get_local $4) ) (func $interfere-in-dead (local $0 i32) diff --git a/test/passes/coalesce-locals.txt b/test/passes/coalesce-locals.txt index 3c1632f68..d0edbd71d 100644 --- a/test/passes/coalesce-locals.txt +++ b/test/passes/coalesce-locals.txt @@ -318,9 +318,10 @@ (func $params (param $0 i32) (param $1 f32) (local $2 i32) (local $3 i32) - (get_local $0) + (local $4 i32) (get_local $2) (get_local $3) + (get_local $4) ) (func $interfere-in-dead (local $0 i32) diff --git a/test/unit.asm.js b/test/unit.asm.js index 5b958a111..2f307e085 100644 --- a/test/unit.asm.js +++ b/test/unit.asm.js @@ -234,6 +234,19 @@ function asm(global, env, buffer) { -3.14159; } + function zeroInit(x) { + x = x | 0; + var y = 0; // reusing this with x is dangerous - x has a value, and y needs to start at 0! + if (lb(0) | 0) { + if (lb(1) | 0) y = 3; + } else { + y = 3; + } + if ((y | 0) == 3) { + lb(2) | 0; + } + } + function z() { } function w() { diff --git a/test/unit.fromasm b/test/unit.fromasm index 7ee15cd05..3fb76981d 100644 --- a/test/unit.fromasm +++ b/test/unit.fromasm @@ -425,4 +425,32 @@ ) (i32.const 0) ) + (func $zeroInit (param $0 i32) + (local $1 i32) + (if + (call $lb + (i32.const 0) + ) + (if + (call $lb + (i32.const 1) + ) + (set_local $1 + (i32.const 3) + ) + ) + (set_local $1 + (i32.const 3) + ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 3) + ) + (call $lb + (i32.const 2) + ) + ) + ) ) diff --git a/test/unit.fromasm.imprecise b/test/unit.fromasm.imprecise index 293fc490a..a4716941d 100644 --- a/test/unit.fromasm.imprecise +++ b/test/unit.fromasm.imprecise @@ -417,4 +417,32 @@ ) (i32.const 0) ) + (func $zeroInit (param $0 i32) + (local $1 i32) + (if + (call $lb + (i32.const 0) + ) + (if + (call $lb + (i32.const 1) + ) + (set_local $1 + (i32.const 3) + ) + ) + (set_local $1 + (i32.const 3) + ) + ) + (if + (i32.eq + (get_local $1) + (i32.const 3) + ) + (call $lb + (i32.const 2) + ) + ) + ) ) diff --git a/test/unit.fromasm.imprecise.no-opts b/test/unit.fromasm.imprecise.no-opts index 2f7665622..c3da01359 100644 --- a/test/unit.fromasm.imprecise.no-opts +++ b/test/unit.fromasm.imprecise.no-opts @@ -693,6 +693,34 @@ (func $exportMe (f64.const -3.14159) ) + (func $zeroInit (param $x i32) + (local $y i32) + (if + (call $lb + (i32.const 0) + ) + (if + (call $lb + (i32.const 1) + ) + (set_local $y + (i32.const 3) + ) + ) + (set_local $y + (i32.const 3) + ) + ) + (if + (i32.eq + (get_local $y) + (i32.const 3) + ) + (call $lb + (i32.const 2) + ) + ) + ) (func $z (nop) ) diff --git a/test/unit.fromasm.no-opts b/test/unit.fromasm.no-opts index 19c13f29f..92d2d2add 100644 --- a/test/unit.fromasm.no-opts +++ b/test/unit.fromasm.no-opts @@ -697,6 +697,34 @@ (func $exportMe (f64.const -3.14159) ) + (func $zeroInit (param $x i32) + (local $y i32) + (if + (call $lb + (i32.const 0) + ) + (if + (call $lb + (i32.const 1) + ) + (set_local $y + (i32.const 3) + ) + ) + (set_local $y + (i32.const 3) + ) + ) + (if + (i32.eq + (get_local $y) + (i32.const 3) + ) + (call $lb + (i32.const 2) + ) + ) + ) (func $z (nop) ) |