File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -22,6 +22,8 @@ Current Trunk
2222- Reject non-natural alignment for atomic memory operations at parse time (#8962 )
2323- Note that fast-math mode can ignore the difference between negative zero and
2424 zero (like clang and gcc). (#9056 )
25+ - reorder-functions now counts ref.func uses in function bodies and global
26+ initializers. (#9160 )
2527
2628v132
2729----
Original file line number Diff line number Diff line change 3030#include < memory>
3131
3232#include < ir/element-utils.h>
33+ #include < ir/find_all.h>
3334#include < pass.h>
3435#include < wasm.h>
3536
@@ -54,6 +55,12 @@ struct CallCountScanner : public WalkerPass<PostWalker<CallCountScanner>> {
5455 (*counts)[curr->target ]++;
5556 }
5657
58+ void visitRefFunc (RefFunc* curr) {
59+ // can't add a new element in parallel
60+ assert (counts->count (curr->func ) > 0 );
61+ (*counts)[curr->func ]++;
62+ }
63+
5764private:
5865 NameCountMap* counts;
5966};
@@ -82,7 +89,16 @@ struct ReorderFunctions : public Pass {
8289 }
8390 ElementUtils::iterAllElementFunctionNames (
8491 module , [&](Name name) { counts[name]++; });
85- // TODO: count all RefFunc as well
92+ // find counts on ref.funcs in globals (those in element segments are
93+ // counted above, and those in functions by the scanner)
94+ for (auto & global : module ->globals ) {
95+ if (!global->init ) {
96+ continue ;
97+ }
98+ for (auto * refFunc : FindAll<RefFunc>(global->init ).list ) {
99+ counts[refFunc->func ]++;
100+ }
101+ }
86102 // TODO: count the declaration section as well, which adds another mention
87103 // sort
88104 std::sort (module ->functions .begin (),
Original file line number Diff line number Diff line change 1+ ;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+ ;; RUN: foreach %s %t wasm-opt --all-features --reorder-functions -S -o - | filecheck %s
3+
4+ ;; Check that ref.func references count towards a function's usage, both in
5+ ;; function bodies and in global initializers. The expected order is $c (two
6+ ;; ref.func uses and a call), $a (one ref.func use in a function and one in a
7+ ;; global), then $b (a single call).
8+
9+ (module
10+ ;; CHECK: (type $0 (func (result i32)))
11+
12+ ;; CHECK: (global $g funcref (ref.func $a))
13+
14+ ;; CHECK: (elem declare func $a $c)
15+
16+ ;; CHECK: (func $c (type $0) (result i32)
17+ ;; CHECK-NEXT: (i32.const 3)
18+ ;; CHECK-NEXT: )
19+
20+ ;; CHECK: (func $a (type $0) (result i32)
21+ ;; CHECK-NEXT: (i32.const 1)
22+ ;; CHECK-NEXT: )
23+ (func $a (result i32 )
24+ (i32.const 1 )
25+ )
26+ ;; CHECK: (func $b (type $0) (result i32)
27+ ;; CHECK-NEXT: (i32.const 2)
28+ ;; CHECK-NEXT: )
29+ (func $b (result i32 )
30+ (i32.const 2 )
31+ )
32+ (func $c (result i32 )
33+ (i32.const 3 )
34+ )
35+ (global $g funcref
36+ (ref.func $a )
37+ )
38+ ;; CHECK: (func $use (type $0) (result i32)
39+ ;; CHECK-NEXT: (drop
40+ ;; CHECK-NEXT: (ref.func $a)
41+ ;; CHECK-NEXT: )
42+ ;; CHECK-NEXT: (drop
43+ ;; CHECK-NEXT: (ref.func $c)
44+ ;; CHECK-NEXT: )
45+ ;; CHECK-NEXT: (drop
46+ ;; CHECK-NEXT: (ref.func $c)
47+ ;; CHECK-NEXT: )
48+ ;; CHECK-NEXT: (drop
49+ ;; CHECK-NEXT: (call $c)
50+ ;; CHECK-NEXT: )
51+ ;; CHECK-NEXT: (call $b)
52+ ;; CHECK-NEXT: )
53+ (func $use (result i32 )
54+ (drop (ref.func $a ))
55+ (drop (ref.func $c ))
56+ (drop (ref.func $c ))
57+ (drop (call $c ))
58+ (call $b )
59+ )
60+ )
You can’t perform that action at this time.
0 commit comments