Skip to content

Commit ed7bf9e

Browse files
Ctor-eval: Don't stop evaluating when an imported global isn't used (#8168)
Resolves the TODO is global-get-init.wast. Previously if a global was imported it would stop us from evaluating almost anything. After this change, an imported global doesn't prevent us from optimizing as long as the global isn't referenced in the constructor that we're targeting. Part of #8180.
1 parent bf3302d commit ed7bf9e

File tree

4 files changed

+30
-12
lines changed

4 files changed

+30
-12
lines changed

src/tools/wasm-ctor-eval.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,17 @@ class EvallingModuleRunner;
7171

7272
class EvallingImportResolver : public ImportResolver {
7373
public:
74-
EvallingImportResolver() = default;
74+
EvallingImportResolver() : stubLiteral({Literal(0)}){};
7575

76+
// Return an unused stub value. We throw FailToEvalException on reading any
77+
// imported globals. We ignore the type and return an i32 literal since some
78+
// types can't be created anyway (e.g. ref none).
7679
Literals* getGlobalOrNull(ImportNames name, Type type) const override {
77-
throw FailToEvalException("Accessed imported global");
80+
return &stubLiteral;
7881
}
82+
83+
private:
84+
mutable Literals stubLiteral;
7985
};
8086

8187
class EvallingModuleRunner : public ModuleRunnerBase<EvallingModuleRunner> {
@@ -557,6 +563,9 @@ struct CtorEvalExternalInterface : EvallingModuleRunner::ExternalInterface {
557563
wasm->updateMaps();
558564

559565
for (auto& oldGlobal : oldGlobals) {
566+
if (oldGlobal->imported()) {
567+
continue;
568+
}
560569
// Serialize the global's value. While doing so, pass in the name of this
561570
// global, as we may be able to reuse the global as the defining global
562571
// for the value. See getSerialization() for more details.
Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
(module
2-
(import "import" "global" (global $imported i32))
3-
(func $test1 (export "test1")
4-
;; This should be safe to eval in theory, but the imported global stops us,
5-
;; so this function will not be optimized out.
6-
;; TODO: perhaps if we never use that global that is ok?
2+
;; an imported global that isn't accessed doesn't stop us from optimizing
3+
(import "import" "global" (global $imported (ref i31)))
4+
(global $g (mut i32) (i32.const 0))
5+
(func $setg (export "setg")
6+
(drop (i32.const 1))
7+
(global.set $g
8+
(i32.add (i32.const 1) (i32.const 2))
9+
)
10+
)
11+
12+
(func $keepalive (export "keepalive") (result i32)
13+
;; Keep the global alive so we can see its value.
14+
(global.get $g)
715
)
816
)
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
test1
1+
setg
Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
(module
2-
(type $0 (func))
3-
(export "test1" (func $test1))
4-
(func $test1 (type $0)
5-
(nop)
2+
(type $0 (func (result i32)))
3+
(global $g (mut i32) (i32.const 3))
4+
(export "keepalive" (func $keepalive))
5+
(func $keepalive (type $0) (result i32)
6+
(global.get $g)
67
)
78
)

0 commit comments

Comments
 (0)