diff --git a/src/ir/module-splitting.cpp b/src/ir/module-splitting.cpp index 6105e81c664..35408d63c45 100644 --- a/src/ir/module-splitting.cpp +++ b/src/ir/module-splitting.cpp @@ -1182,8 +1182,18 @@ void ModuleSplitter::shareImportableItems() { auto usingSecondaries = getUsingSecondaries(global->name, &UsedNames::globals); - bool usedInPrimary = primaryUsed.globals.count(global->name); - if (!usedInPrimary && usingSecondaries.size() == 1) { + bool inPrimary = primaryUsed.globals.count(global->name); + + if (!inPrimary && usingSecondaries.empty()) { + // It's not used anywhere, so delete it. Unlike other unused module items + // (memories, tables, and tags) that can just sit in the primary module + // and later be DCE'ed by another pass, we should remove it here, because + // an unused global can contain an initialier that refers to another + // global that will be moved to a secondary module, like + // (global $unused i32 (global.get $a)) // $a is moved to a secondary + globalsToRemove.push_back(global->name); + + } else if (!inPrimary && usingSecondaries.size() == 1) { // We are moving this global to this secondary module auto* secondary = usingSecondaries[0]; auto* secondaryGlobal = ModuleUtils::copyGlobal(global.get(), *secondary); @@ -1213,6 +1223,7 @@ void ModuleSplitter::shareImportableItems() { // function. } } + } else { // We are NOT moving this global to the secondary module if (global->init) { for (auto* ref : FindAll(global->init).list) { diff --git a/test/example/module-splitting.txt b/test/example/module-splitting.txt index 88de5da0a4e..5f03322b7fe 100644 --- a/test/example/module-splitting.txt +++ b/test/example/module-splitting.txt @@ -22,7 +22,6 @@ Keeping: After: (module (type $0 (func (param i32))) - (global $glob (mut i32) (i32.const 7)) (memory $mem 3 42 shared) (table $tab 3 42 funcref) (tag $e (type $0) (param i32)) @@ -46,7 +45,6 @@ After: (type $0 (func (param i32))) (import "env" "mem" (memory $mem 3 42 shared)) (import "env" "tab" (table $tab 3 42 funcref)) - (import "env" "glob" (global $glob (mut i32))) (import "env" "e" (tag $e (type $0) (param i32))) ) Secondary: diff --git a/test/lit/wasm-split/ref.func.wast b/test/lit/wasm-split/ref.func.wast index 11007235ffe..38eea498d72 100644 --- a/test/lit/wasm-split/ref.func.wast +++ b/test/lit/wasm-split/ref.func.wast @@ -45,6 +45,12 @@ ;; PRIMARY-NEXT: (drop ;; PRIMARY-NEXT: (ref.func $trampoline_second) ;; PRIMARY-NEXT: ) + ;; PRIMARY-NEXT: (drop + ;; PRIMARY-NEXT: (global.get $glob1) + ;; PRIMARY-NEXT: ) + ;; PRIMARY-NEXT: (drop + ;; PRIMARY-NEXT: (global.get $glob2) + ;; PRIMARY-NEXT: ) ;; PRIMARY-NEXT: ) (func $prime (drop @@ -53,6 +59,12 @@ (drop (ref.func $second) ) + (drop + (global.get $glob1) + ) + (drop + (global.get $glob2) + ) ) ;; SECONDARY: (type $0 (func)) diff --git a/test/lit/wasm-split/transitive-globals.wast b/test/lit/wasm-split/transitive-globals.wast index 6bf5ce6636f..a0bac6c3364 100644 --- a/test/lit/wasm-split/transitive-globals.wast +++ b/test/lit/wasm-split/transitive-globals.wast @@ -34,6 +34,11 @@ ;; SECONDARY: (global $d i32 (global.get $e)) + ;; This dead global is referring to a global ($a) that's moved to the + ;; secondary module. This should be deleted. + ;; PRIMARY-NOT: (global (global $dead i32 (global.get $a)) + (global $dead i32 (global.get $a)) + ;; PRIMARY: (func $keep ;; PRIMARY-NEXT: (drop ;; PRIMARY-NEXT: (global.get $e)