Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/passes/SimplifyGlobals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -738,10 +738,11 @@ struct SimplifyGlobals : public Pass {

void visitGlobalGet(GlobalGet* curr) {
// If this is a get of a global with a single get and no sets, then we
// can fold that code into here.
// can fold that code into here. We must also avoid an export, as it can
// have additional gets and sets that we do not see.
auto name = curr->name;
auto& info = infos[name];
if (info.written == 0 && info.read == 1) {
if (info.written == 0 && info.read == 1 && !info.exported) {
auto* global = wasm.getGlobal(name);
if (global->init) {
// Copy that global's code. For simplicity we copy it as we have to
Expand Down
29 changes: 29 additions & 0 deletions test/lit/passes/simplify-globals-gc.wast
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,32 @@
)
)

;; One global reads another, and should contain the same value. We should not
;; erroneously optimize the global.get to a struct.new, as struct.new generates
;; a new value each time, and the export allows that difference to be noticed.
(module
;; CHECK: (type $struct (struct))
(type $struct (struct))

;; CHECK: (global $A (ref $struct) (struct.new_default $struct))
(global $A (ref $struct) (struct.new_default $struct))

;; CHECK: (global $B (ref $struct) (global.get $A))
(global $B (ref $struct) (global.get $A))

;; CHECK: (export "A" (global $A))
(export "A" (global $A))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could still optimize by exporting $B instead. Maybe worth considering as a follow-up?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a TODO, that might be possible, not sure offhand about corner cases though.

)

;; Without that export, we only use $A once, and can fold it into that use.
(module
;; CHECK: (type $struct (struct))
(type $struct (struct))

;; CHECK: (global $A (ref $struct) (struct.new_default $struct))
(global $A (ref $struct) (struct.new_default $struct))

;; CHECK: (global $B (ref $struct) (struct.new_default $struct))
(global $B (ref $struct) (global.get $A))
)

Loading