Skip to content

Commit fdd4cb7

Browse files
authored
LocalCSE: Consider pass options, both size and cost (#1840)
With this we can optimize redundant global accesses fairly well (at least locally; licm also works), see #1831
1 parent 0f41b07 commit fdd4cb7

File tree

8 files changed

+85
-2
lines changed

8 files changed

+85
-2
lines changed

src/ir/cost.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#ifndef wasm_ir_cost_h
1818
#define wasm_ir_cost_h
1919

20+
#include <wasm.h>
21+
#include <wasm-traversal.h>
22+
2023
namespace wasm {
2124

2225
// Measure the execution cost of an AST. Very handwave-ey

src/passes/LocalCSE.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
#include <wasm-traversal.h>
4343
#include <pass.h>
4444
#include <ir/effects.h>
45+
#include <ir/cost.h>
4546
#include <ir/equivalent_sets.h>
4647
#include <ir/hashed.h>
4748

@@ -208,8 +209,19 @@ struct LocalCSE : public WalkerPass<LinearExecutionWalker<LocalCSE>> {
208209
if (EffectAnalyzer(getPassOptions(), value).hasSideEffects()) {
209210
return false; // we can't combine things with side effects
210211
}
211-
// check what we care about TODO: use optimize/shrink levels?
212-
return Measurer::measure(value) > 1;
212+
auto& options = getPassRunner()->options;
213+
// If the size is at least 3, then if we have two of them we have 6,
214+
// and so adding one set+two gets and removing one of the items itself
215+
// is not detrimental, and may be beneficial.
216+
if (options.shrinkLevel > 0 && Measurer::measure(value) >= 3) {
217+
return true;
218+
}
219+
// If we focus on speed, any reduction in cost is beneficial, as the
220+
// cost of a get is essentially free.
221+
if (options.shrinkLevel == 0 && CostAnalyzer(value).cost > 0) {
222+
return true;
223+
}
224+
return false;
213225
}
214226
};
215227

test/example/cpp-unit.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// test multiple uses of the threadPool
2+
3+
#include <assert.h>
4+
5+
#include <wasm.h>
6+
#include <ir/cost.h>
7+
8+
using namespace wasm;
9+
10+
int main()
11+
{
12+
// Some optimizations assume that the cost of a get is zero, e.g. local-cse.
13+
GetLocal get;
14+
assert(CostAnalyzer(&get).cost == 0);
15+
16+
std::cout << "Success.\n";
17+
return 0;
18+
}

test/example/cpp-unit.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Success.

test/passes/licm.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
(type $2 (func (result i64)))
55
(type $3 (func (param i32)))
66
(type $4 (func (param i32) (result i32)))
7+
(global $glob (mut i32) (i32.const 1))
78
(func $loop1 (; 0 ;) (type $0)
89
(drop
910
(i32.const 10)
@@ -674,4 +675,20 @@
674675
)
675676
)
676677
)
678+
(func $global (; 40 ;) (type $0)
679+
(local $x i32)
680+
(set_local $x
681+
(get_global $glob)
682+
)
683+
(drop
684+
(get_local $x)
685+
)
686+
(loop $loop
687+
(nop)
688+
(nop)
689+
(br_if $loop
690+
(get_local $x)
691+
)
692+
)
693+
)
677694
)

test/passes/licm.wast

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
(module
2+
(global $glob (mut i32) (i32.const 1))
23
(func $loop1
34
(loop $loop
45
(drop (i32.const 10))
@@ -388,5 +389,13 @@
388389
(br_if $loop (i32.const 1))
389390
)
390391
)
392+
(func $global
393+
(local $x i32)
394+
(loop $loop
395+
(set_local $x (get_global $glob))
396+
(drop (get_local $x))
397+
(br_if $loop (get_local $x))
398+
)
399+
)
391400
)
392401

test/passes/local-cse.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
(module
22
(type $0 (func (result i64)))
3+
(type $1 (func))
4+
(global $glob (mut i32) (i32.const 1))
35
(func $i64-shifts (; 0 ;) (type $0) (result i64)
46
(local $temp i64)
57
(set_local $temp
@@ -19,4 +21,17 @@
1921
)
2022
(get_local $temp)
2123
)
24+
(func $global (; 1 ;) (type $1)
25+
(local $x i32)
26+
(local $y i32)
27+
(set_local $x
28+
(get_global $glob)
29+
)
30+
(set_local $y
31+
(get_local $x)
32+
)
33+
(set_local $y
34+
(get_local $x)
35+
)
36+
)
2237
)

test/passes/local-cse.wast

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
(module
2+
(global $glob (mut i32) (i32.const 1))
23
(func $i64-shifts (result i64)
34
(local $temp i64)
45
(set_local $temp
@@ -18,4 +19,11 @@
1819
)
1920
(get_local $temp)
2021
)
22+
(func $global
23+
(local $x i32)
24+
(local $y i32)
25+
(set_local $x (get_global $glob))
26+
(set_local $y (get_global $glob))
27+
(set_local $y (get_global $glob))
28+
)
2129
)

0 commit comments

Comments
 (0)