-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Closed
Description
-s ASYNCIFY=1 in Emscripten 3.1.60 and later generates more local variables than before.
test.c:
#include <emscripten.h>
EM_ASYNC_JS(int, some_async_func, (int x), {
return x;
});
int main() {
int a = 0;
a = some_async_func(a);
a = some_async_func(a);
a = some_async_func(a);
a = some_async_func(a);
a = some_async_func(a);
return a;
}Command line to build:
emcc -O3 -sASYNCIFY=1 -o test.js test.c
main() compiled with emscripten 3.1.60 has two params and six locals, where locals 3 through 7 are used only once each to temporarily hold the result of each some_async_func().
`main()` compiled with emscripten 3.1.60
(func (;10;) (type 3) (param i32 i32) (result i32)
(local i32 i32 i32 i32 i32 i32)
global.get 1
i32.const 2
i32.eq
if ;; label = @1
global.get 2
global.get 2
i32.load
i32.const 4
i32.sub
i32.store
global.get 2
i32.load
i32.load
local.set 0
end
block (result i32) ;; label = @1
global.get 1
i32.const 2
i32.eq
if ;; label = @2
global.get 2
global.get 2
i32.load
i32.const 4
i32.sub
i32.store
global.get 2
i32.load
i32.load
local.set 2
end
global.get 1
i32.eqz
local.get 2
i32.eqz
i32.or
if ;; label = @2
i32.const 0
call 0
local.set 3
i32.const 0
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 3
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 1
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 4
i32.const 1
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 4
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 2
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 5
i32.const 2
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 5
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 3
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 6
i32.const 3
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 6
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 4
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 7
i32.const 4
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 7
local.set 0
end
global.get 1
i32.eqz
if ;; label = @2
local.get 0
return
end
unreachable
end
local.set 1
global.get 2
i32.load
local.get 1
i32.store
global.get 2
global.get 2
i32.load
i32.const 4
i32.add
i32.store
global.get 2
i32.load
local.get 0
i32.store
global.get 2
global.get 2
i32.load
i32.const 4
i32.add
i32.store
i32.const 0)When built with Emscripten 3.1.59, these temp locals are coalesced and main() has only one local.
`main()` compiled with emscripten 3.1.59
(func (;10;) (type 3) (param i32 i32) (result i32)
(local i32)
global.get 1
i32.const 2
i32.eq
if ;; label = @1
global.get 2
global.get 2
i32.load
i32.const 4
i32.sub
i32.store
global.get 2
i32.load
i32.load
local.set 0
end
block (result i32) ;; label = @1
global.get 1
i32.const 2
i32.eq
if ;; label = @2
global.get 2
global.get 2
i32.load
i32.const 4
i32.sub
i32.store
global.get 2
i32.load
i32.load
local.set 2
end
global.get 1
i32.eqz
local.get 2
i32.eqz
i32.or
if ;; label = @2
i32.const 0
call 0
local.set 1
i32.const 0
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 1
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 1
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 1
i32.const 1
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 1
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 2
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 1
i32.const 2
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 1
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 3
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 1
i32.const 3
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 1
local.set 0
end
global.get 1
i32.eqz
local.get 2
i32.const 4
i32.eq
i32.or
if ;; label = @2
local.get 0
call 0
local.set 1
i32.const 4
global.get 1
i32.const 1
i32.eq
br_if 1 (;@1;)
drop
local.get 1
local.set 0
end
global.get 1
i32.eqz
if ;; label = @2
local.get 0
return
end
unreachable
end
local.set 1
global.get 2
i32.load
local.get 1
i32.store
global.get 2
global.get 2
i32.load
i32.const 4
i32.add
i32.store
global.get 2
i32.load
local.get 0
i32.store
global.get 2
global.get 2
i32.load
i32.const 4
i32.add
i32.store
i32.const 0)I noticed this because a function that previously had 34 local variables now has 444 locals when compiled with the latest Emscripten (3.1.62).
Metadata
Metadata
Assignees
Labels
No labels