cmd/compile: make dse track multiple shadowed ranges

Track multiple shadowed ranges when doing DSE.

Elides zeroing for:

func nozero() (b [5]int64) {
	b[0] = 1
	b[1] = 7
	b[3] = 1
	b[4] = 1
	b[2] = 0
	return b
}

goes from:

 v28   	00003 (7)	LEAQ	main.b(SP), AX
 v5    	00004 (7)	MOVUPS	X15, (AX)
 v5    	00005 (7)	MOVUPS	X15, 16(AX)
 v5    	00006 (7)	MOVUPS	X15, 24(AX)
 v11   	00007 (8)	MOVQ	$1, main.b(SP)
 v16   	00008 (9)	MOVQ	$7, main.b+8(SP)
 v20   	00009 (10)	MOVQ	$1, main.b+24(SP)
 v24   	00010 (11)	MOVQ	$1, main.b+32(SP)
 v29   	00011 (12)	MOVQ	$0, main.b+16(SP)
 b1    	00012 (13)	RET
       	00013 (?)	END

to:

 v11   	00003 (8)	MOVQ	$1, main.b(SP)
 v16   	00004 (9)	MOVQ	$7, main.b+8(SP)
 v20   	00005 (10)	MOVQ	$1, main.b+24(SP)
 v24   	00006 (11)	MOVQ	$1, main.b+32(SP)
 v29   	00007 (12)	MOVQ	$0, main.b+16(SP)
 b1    	00008 (13)	RET
       	00009 (?)	END

regexp linux/amd64:

Find-16                                             89.17n ± ∞ ¹    83.09n ± ∞ ¹   -6.82% (p=0.008 n=5)
FindAllNoMatches-16                                 46.23n ± ∞ ¹    44.26n ± ∞ ¹   -4.26% (p=0.008 n=5)
FindString-16                                       89.77n ± ∞ ¹    82.84n ± ∞ ¹   -7.72% (p=0.008 n=5)
FindSubmatch-16                                     108.9n ± ∞ ¹    101.6n ± ∞ ¹   -6.70% (p=0.008 n=5)
FindStringSubmatch-16                              103.10n ± ∞ ¹    99.98n ± ∞ ¹   -3.03% (p=0.008 n=5)
Literal-16                                          29.61n ± ∞ ¹    29.17n ± ∞ ¹   -1.49% (p=0.008 n=5)
NotLiteral-16                                       590.0n ± ∞ ¹    566.0n ± ∞ ¹   -4.07% (p=0.008 n=5)
MatchClass-16                                       894.7n ± ∞ ¹    814.0n ± ∞ ¹   -9.02% (p=0.008 n=5)
MatchClass_InRange-16                               793.0n ± ∞ ¹    756.3n ± ∞ ¹   -4.63% (p=0.008 n=5)
ReplaceAll-16                                       513.9n ± ∞ ¹    503.6n ± ∞ ¹   -2.00% (p=0.008 n=5)
AnchoredLiteralShortNonMatch-16                     21.70n ± ∞ ¹    21.66n ± ∞ ¹        ~ (p=0.738 n=5)
AnchoredLiteralLongNonMatch-16                      21.74n ± ∞ ¹    21.65n ± ∞ ¹        ~ (p=0.286 n=5)
AnchoredShortMatch-16                               37.71n ± ∞ ¹    37.63n ± ∞ ¹        ~ (p=0.421 n=5)
AnchoredLongMatch-16                                37.75n ± ∞ ¹    37.70n ± ∞ ¹        ~ (p=0.286 n=5)
OnePassShortA-16                                    188.7n ± ∞ ¹    185.7n ± ∞ ¹   -1.59% (p=0.008 n=5)
NotOnePassShortA-16                                 188.0n ± ∞ ¹    190.7n ± ∞ ¹   +1.44% (p=0.008 n=5)
OnePassShortB-16                                    147.9n ± ∞ ¹    154.2n ± ∞ ¹   +4.26% (p=0.008 n=5)
NotOnePassShortB-16                                 141.2n ± ∞ ¹    144.1n ± ∞ ¹   +2.05% (p=0.008 n=5)
OnePassLongPrefix-16                                40.43n ± ∞ ¹    38.45n ± ∞ ¹   -4.90% (p=0.008 n=5)
OnePassLongNotPrefix-16                             100.6n ± ∞ ¹    102.5n ± ∞ ¹   +1.89% (p=0.008 n=5)
MatchParallelShared-16                              9.666n ± ∞ ¹    9.461n ± ∞ ¹        ~ (p=0.056 n=5)
MatchParallelCopied-16                              9.530n ± ∞ ¹    9.540n ± ∞ ¹        ~ (p=0.841 n=5)
QuoteMetaAll-16                                     28.60n ± ∞ ¹    29.52n ± ∞ ¹   +3.22% (p=0.016 n=5)
QuoteMetaNone-16                                    16.73n ± ∞ ¹    16.74n ± ∞ ¹        ~ (p=0.817 n=5)
Compile/Onepass-16                                  2.040µ ± ∞ ¹    2.012µ ± ∞ ¹        ~ (p=0.381 n=5)
Compile/Medium-16                                   4.652µ ± ∞ ¹    4.661µ ± ∞ ¹        ~ (p=0.341 n=5)
Compile/Hard-16                                     37.59µ ± ∞ ¹    37.93µ ± ∞ ¹        ~ (p=0.222 n=5)
Match/Easy0/16-16                                   1.848n ± ∞ ¹    1.847n ± ∞ ¹   -0.05% (p=0.048 n=5)
Match/Easy0/32-16                                   23.81n ± ∞ ¹    24.16n ± ∞ ¹   +1.47% (p=0.008 n=5)
Match/Easy0/1K-16                                   143.2n ± ∞ ¹    148.6n ± ∞ ¹   +3.77% (p=0.008 n=5)
Match/Easy0/32K-16                                  2.023µ ± ∞ ¹    2.008µ ± ∞ ¹   -0.74% (p=0.024 n=5)
Match/Easy0/1M-16                                   135.3µ ± ∞ ¹    136.8µ ± ∞ ¹   +1.10% (p=0.016 n=5)
Match/Easy0/32M-16                                  5.139m ± ∞ ¹    5.123m ± ∞ ¹   -0.29% (p=0.008 n=5)
Match/Easy0i/16-16                                  1.848n ± ∞ ¹    1.847n ± ∞ ¹        ~ (p=0.167 n=5)
Match/Easy0i/32-16                                  438.3n ± ∞ ¹    421.9n ± ∞ ¹   -3.74% (p=0.008 n=5)
Match/Easy0i/1K-16                                  12.93µ ± ∞ ¹    12.25µ ± ∞ ¹   -5.25% (p=0.008 n=5)
Match/Easy0i/32K-16                                 443.3µ ± ∞ ¹    450.6µ ± ∞ ¹   +1.64% (p=0.008 n=5)
Match/Easy0i/1M-16                                  14.26m ± ∞ ¹    14.44m ± ∞ ¹        ~ (p=0.222 n=5)
Match/Easy0i/32M-16                                 454.8m ± ∞ ¹    459.0m ± ∞ ¹        ~ (p=0.056 n=5)
Match/Easy1/16-16                                   1.848n ± ∞ ¹    1.847n ± ∞ ¹        ~ (p=0.206 n=5)
Match/Easy1/32-16                                   20.78n ± ∞ ¹    20.95n ± ∞ ¹        ~ (p=0.841 n=5)
Match/Easy1/1K-16                                   292.0n ± ∞ ¹    278.6n ± ∞ ¹   -4.59% (p=0.008 n=5)
Match/Easy1/32K-16                                  14.19µ ± ∞ ¹    14.31µ ± ∞ ¹   +0.85% (p=0.008 n=5)
Match/Easy1/1M-16                                   513.3µ ± ∞ ¹    517.0µ ± ∞ ¹   +0.72% (p=0.008 n=5)
Match/Easy1/32M-16                                  16.58m ± ∞ ¹    16.69m ± ∞ ¹   +0.64% (p=0.008 n=5)
Match/Medium/16-16                                  1.849n ± ∞ ¹    1.847n ± ∞ ¹   -0.11% (p=0.024 n=5)
Match/Medium/32-16                                  319.8n ± ∞ ¹    312.1n ± ∞ ¹   -2.41% (p=0.008 n=5)
Match/Medium/1K-16                                  12.54µ ± ∞ ¹    12.66µ ± ∞ ¹   +0.97% (p=0.008 n=5)
Match/Medium/32K-16                                 496.9µ ± ∞ ¹    496.0µ ± ∞ ¹        ~ (p=0.056 n=5)
Match/Medium/1M-16                                  16.11m ± ∞ ¹    16.00m ± ∞ ¹   -0.63% (p=0.032 n=5)
Match/Medium/32M-16                                 516.5m ± ∞ ¹    513.1m ± ∞ ¹   -0.65% (p=0.032 n=5)
Match/Hard/16-16                                    1.848n ± ∞ ¹    1.847n ± ∞ ¹        ~ (p=0.238 n=5)
Match/Hard/32-16                                    527.2n ± ∞ ¹    508.4n ± ∞ ¹   -3.57% (p=0.008 n=5)
Match/Hard/1K-16                                    15.53µ ± ∞ ¹    15.42µ ± ∞ ¹   -0.68% (p=0.008 n=5)
Match/Hard/32K-16                                   636.5µ ± ∞ ¹    665.8µ ± ∞ ¹   +4.62% (p=0.008 n=5)
Match/Hard/1M-16                                    20.45m ± ∞ ¹    21.13m ± ∞ ¹   +3.30% (p=0.008 n=5)
Match/Hard/32M-16                                   654.5m ± ∞ ¹    671.9m ± ∞ ¹   +2.66% (p=0.008 n=5)
Match/Hard1/16-16                                   1.538µ ± ∞ ¹    1.499µ ± ∞ ¹   -2.54% (p=0.008 n=5)
Match/Hard1/32-16                                   2.965µ ± ∞ ¹    2.906µ ± ∞ ¹   -1.99% (p=0.008 n=5)
Match/Hard1/1K-16                                   91.28µ ± ∞ ¹    90.09µ ± ∞ ¹   -1.29% (p=0.008 n=5)
Match/Hard1/32K-16                                  2.996m ± ∞ ¹    3.311m ± ∞ ¹  +10.50% (p=0.008 n=5)
Match/Hard1/1M-16                                   95.77m ± ∞ ¹   105.87m ± ∞ ¹  +10.54% (p=0.008 n=5)
Match/Hard1/32M-16                                   3.069 ± ∞ ¹     3.399 ± ∞ ¹  +10.74% (p=0.008 n=5)
Match_onepass_regex/16-16                           120.9n ± ∞ ¹    117.4n ± ∞ ¹   -2.89% (p=0.008 n=5)
Match_onepass_regex/32-16                           211.8n ± ∞ ¹    207.5n ± ∞ ¹   -2.03% (p=0.008 n=5)
Match_onepass_regex/1K-16                           5.602µ ± ∞ ¹    5.548µ ± ∞ ¹        ~ (p=0.421 n=5)
Match_onepass_regex/32K-16                          185.6µ ± ∞ ¹    185.1µ ± ∞ ¹        ~ (p=0.690 n=5)
Match_onepass_regex/1M-16                           5.896m ± ∞ ¹    5.808m ± ∞ ¹   -1.50% (p=0.016 n=5)
Match_onepass_regex/32M-16                          193.4m ± ∞ ¹    185.5m ± ∞ ¹   -4.10% (p=0.008 n=5)
geomean                                             3.815µ          3.796µ         -0.51%

compilecmp linux/amd64:

file                                                                 before   after    Δ       %
runtime.s                                                            673118   672419   -699    -0.104%
runtime [cmd/compile].s                                              720475   719781   -694    -0.096%
math/rand/v2.s                                                       9394     9371     -23     -0.245%
bytes.s                                                              36026    35999    -27     -0.075%
vendor/golang.org/x/net/dns/dnsmessage.s                             76433    76193    -240    -0.314%
math/rand/v2 [cmd/compile].s                                         9394     9371     -23     -0.245%
strings.s                                                            43435    43414    -21     -0.048%
syscall.s                                                            82215    82183    -32     -0.039%
html.s                                                               6010     5949     -61     -1.015%
bytes [cmd/compile].s                                                36615    36588    -27     -0.074%
regexp/syntax.s                                                      81442    81299    -143    -0.176%
syscall [cmd/compile].s                                              82215    82183    -32     -0.039%
time.s                                                               90555    90507    -48     -0.053%
regexp.s                                                             58974    58876    -98     -0.166%
reflect.s                                                            176893   176829   -64     -0.036%
context.s                                                            14298    14234    -64     -0.448%
plugin.s                                                             3879     3847     -32     -0.825%
io/fs.s                                                              29026    29009    -17     -0.059%
strings [cmd/compile].s                                              43446    43425    -21     -0.048%
html [cmd/compile].s                                                 6010     5949     -61     -1.015%
time [cmd/compile].s                                                 90555    90507    -48     -0.053%
os.s                                                                 116321   116249   -72     -0.062%
regexp/syntax [cmd/compile].s                                        81442    81299    -143    -0.176%
context [cmd/compile].s                                              14298    14234    -64     -0.448%
io/fs [cmd/compile].s                                                29026    29009    -17     -0.059%
path/filepath.s                                                      19879    19842    -37     -0.186%
cmd/cgo/internal/cgotest.s                                           1965     1932     -33     -1.679%
reflect [cmd/compile].s                                              176893   176829   -64     -0.036%
regexp [cmd/compile].s                                               58974    58876    -98     -0.166%
crypto/cipher.s                                                      21706    21660    -46     -0.212%
runtime/trace.s                                                      14644    14634    -10     -0.068%
math/big.s                                                           170782   170250   -532    -0.312%
debug/dwarf.s                                                        105214   105141   -73     -0.069%
log.s                                                                15749    15603    -146    -0.927%
encoding/json.s                                                      118965   118933   -32     -0.027%
os/user.s                                                            10367    10326    -41     -0.395%
crypto/dsa.s                                                         4988     4974     -14     -0.281%
crypto/rsa.s                                                         29486    29474    -12     -0.041%
database/sql.s                                                       99574    99403    -171    -0.172%
encoding/gob.s                                                       146507   146475   -32     -0.022%
debug/macho.s                                                        29517    29421    -96     -0.325%
crypto/ed25519.s                                                     8648     8594     -54     -0.624%
internal/goroot.s                                                    3165     3107     -58     -1.833%
testing.s                                                            123472   123438   -34     -0.028%
archive/tar.s                                                        71179    71096    -83     -0.117%
go/doc/comment.s                                                     48429    48397    -32     -0.066%
vendor/golang.org/x/crypto/cryptobyte.s                              31717    31690    -27     -0.085%
internal/cgrouptest.s                                                4760     4686     -74     -1.555%
image/png.s                                                          34484    34479    -5      -0.014%
go/constant.s                                                        29502    29297    -205    -0.695%
internal/testenv.s                                                   22396    22331    -65     -0.290%
internal/pkgbits.s                                                   19609    19598    -11     -0.056%
testing/iotest.s                                                     15070    15018    -52     -0.345%
internal/runtime/gc/internal/gen.s                                   50837    50548    -289    -0.568%
crypto/internal/cryptotest.s                                         58607    58229    -378    -0.645%
crypto/ecdsa.s                                                       43878    43658    -220    -0.501%
cmd/internal/objabi.s                                                20244    20231    -13     -0.064%
math/big/internal/asmgen.s                                           74554    74422    -132    -0.177%
log/slog.s                                                           81620    81617    -3      -0.004%
net.s                                                                299158   299080   -78     -0.026%
cmd/vendor/golang.org/x/telemetry/internal/telemetry.s               4531     4472     -59     -1.302%
testing/fstest.s                                                     73370    73286    -84     -0.114%
log/syslog.s                                                         6457     6426     -31     -0.480%
vendor/golang.org/x/net/http/httpproxy.s                             7674     7666     -8      -0.104%
cmd/vendor/golang.org/x/telemetry/internal/counter.s                 31504    31493    -11     -0.035%
cmd/internal/pkgpath.s                                               4828     4810     -18     -0.373%
internal/trace.s                                                     190495   190463   -32     -0.017%
cmd/internal/telemetry/counter.s                                     1999     1979     -20     -1.001%
net/mail.s                                                           21912    21866    -46     -0.210%
mime/multipart.s                                                     30856    30806    -50     -0.162%
internal/trace/internal/testgen.s                                    12870    12850    -20     -0.155%
go/parser.s                                                          109753   109739   -14     -0.013%
crypto/x509.s                                                        184334   183966   -368    -0.200%
cmd/internal/pgo.s                                                   7886     7850     -36     -0.457%
cmd/internal/browser.s                                               1980     1962     -18     -0.909%
cmd/covdata.s                                                        40197    40180    -17     -0.042%
internal/fuzz.s                                                      90255    90234    -21     -0.023%
go/build.s                                                           74975    74722    -253    -0.337%
cmd/distpack.s                                                       29343    29056    -287    -0.978%
cmd/cover.s                                                          53513    53412    -101    -0.189%
cmd/internal/obj.s                                                   144804   144764   -40     -0.028%
os [cmd/compile].s                                                   116325   116253   -72     -0.062%
cmd/cgo.s                                                            217917   217878   -39     -0.018%
internal/exportdata.s                                                8849     8800     -49     -0.554%
cmd/dist.s                                                           179720   179253   -467    -0.260%
cmd/compile/internal/syntax.s                                        174526   174495   -31     -0.018%
cmd/asm/internal/lex.s                                               21635    21628    -7      -0.032%
cmd/internal/obj/riscv.s                                             149150   149118   -32     -0.021%
path/filepath [cmd/compile].s                                        19879    19842    -37     -0.186%
cmd/internal/obj/wasm.s                                              83633    83569    -64     -0.077%
crypto/tls.s                                                         405459   405103   -356    -0.088%
cmd/internal/obj/loong64.s                                           117422   117392   -30     -0.026%
log [cmd/compile].s                                                  15798    15652    -146    -0.924%
crypto/cipher [cmd/compile].s                                        21706    21660    -46     -0.212%
go/types.s                                                           592053   591930   -123    -0.021%
cmd/vendor/golang.org/x/telemetry/internal/telemetry [cmd/compile].s 4531     4472     -59     -1.302%
cmd/internal/objabi [cmd/compile].s                                  20244    20231    -13     -0.064%
encoding/json [cmd/compile].s                                        119184   119152   -32     -0.027%
go/internal/srcimporter.s                                            9957     9948     -9      -0.090%
internal/goroot [cmd/compile].s                                      3165     3107     -58     -1.833%
runtime/trace [cmd/compile].s                                        14703    14693    -10     -0.068%
go/internal/gccgoimporter.s                                          47218    47189    -29     -0.061%
cmd/vendor/golang.org/x/telemetry/internal/counter [cmd/compile].s   31563    31552    -11     -0.035%
go/doc/comment [cmd/compile].s                                       48488    48456    -32     -0.066%
cmd/compile/internal/base.s                                          44391    44379    -12     -0.027%
cmd/vendor/golang.org/x/tools/internal/analysis/analyzerutil.s       3957     3925     -32     -0.809%
math/big [cmd/compile].s                                             173023   172491   -532    -0.307%
cmd/asm.s                                                            3824     3749     -75     -1.961%
cmd/vendor/golang.org/x/tools/internal/diff/lcs.s                    22413    22289    -124    -0.553%
cmd/internal/telemetry/counter [cmd/compile].s                       1999     1979     -20     -1.001%
cmd/vendor/golang.org/x/tools/go/analysis/passes/buildtag.s          8886     8877     -9      -0.101%
go/constant [cmd/compile].s                                          29673    29468    -205    -0.691%
cmd/internal/obj [cmd/compile].s                                     218137   218102   -35     -0.016%
cmd/internal/pgo [cmd/compile].s                                     7945     7909     -36     -0.453%
internal/pkgbits [cmd/compile].s                                     37142    37115    -27     -0.073%
go/parser [cmd/compile].s                                            109812   109798   -14     -0.013%
cmd/compile/internal/base [cmd/compile].s                            44607    44595    -12     -0.027%
go/build [cmd/compile].s                                             75034    74781    -253    -0.337%
cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags.s   10379    10338    -41     -0.395%
cmd/go/internal/lockedfile.s                                         15477    15473    -4      -0.026%
cmd/internal/obj/loong64 [cmd/compile].s                             117481   117451   -30     -0.026%
cmd/internal/obj/wasm [cmd/compile].s                                83677    83613    -64     -0.076%
cmd/internal/obj/riscv [cmd/compile].s                               148985   148953   -32     -0.021%
cmd/vendor/golang.org/x/tools/internal/analysis/driverutil.s         31164    31100    -64     -0.205%
internal/exportdata [cmd/compile].s                                  8849     8800     -49     -0.554%
cmd/vendor/golang.org/x/mod/sumdb/dirhash.s                          12387    12366    -21     -0.170%
cmd/vendor/golang.org/x/tools/internal/typesinternal.s               24320    24295    -25     -0.103%
cmd/go/internal/fsys.s                                               60108    60040    -68     -0.113%
net/http.s                                                           603320   602752   -568    -0.094%
cmd/compile/internal/syntax [cmd/compile].s                          187371   187340   -31     -0.017%
cmd/cgo/internal/test.s                                              219885   219826   -59     -0.027%
net/http/httptest.s                                                  21757    21754    -3      -0.014%
cmd/compile/internal/types2.s                                        576035   575871   -164    -0.028%
net/http/cgi.s                                                       36196    36146    -50     -0.138%
net/http/httputil.s                                                  45557    45502    -55     -0.121%
cmd/compile/internal/objw.s                                          5710     5672     -38     -0.665%
net/http/pprof.s                                                     32053    32011    -42     -0.131%
internal/trace/traceviewer.s                                         34748    34695    -53     -0.153%
net/rpc.s                                                            44569    44361    -208    -0.467%
cmd/compile/internal/staticdata.s                                    21461    21446    -15     -0.070%
cmd/vendor/golang.org/x/telemetry/internal/crashmonitor.s            6104     6073     -31     -0.508%
cmd/go/internal/cfg.s                                                14419    14303    -116    -0.804%
cmd/vendor/golang.org/x/tools/go/analysis/passes/hostport.s          6834     6802     -32     -0.468%
cmd/vendor/golang.org/x/tools/go/types/objectpath.s                  19228    19118    -110    -0.572%
cmd/go/internal/imports.s                                            15978    15970    -8      -0.050%
cmd/vendor/golang.org/x/tools/internal/facts.s                       15249    15237    -12     -0.079%
cmd/vendor/golang.org/x/telemetry/internal/upload.s                  34546    33957    -589    -1.705%
cmd/vendor/golang.org/x/mod/sumdb.s                                  28991    28941    -50     -0.172%
cmd/vendor/golang.org/x/telemetry.s                                  7555     7420     -135    -1.787%
cmd/gofmt.s                                                          29924    29898    -26     -0.087%
cmd/go/internal/base.s                                               19950    19938    -12     -0.060%
cmd/vendor/golang.org/x/tools/internal/refactor/inline.s             161628   161596   -32     -0.020%
cmd/internal/script.s                                                89932    89811    -121    -0.135%
cmd/vendor/golang.org/x/tools/go/analysis/unitchecker.s              14865    14797    -68     -0.457%
cmd/vendor/golang.org/x/arch/riscv64/riscv64asm.s                    62049    62017    -32     -0.052%
cmd/vendor/golang.org/x/mod/zip.s                                    39525    39428    -97     -0.245%
cmd/compile/internal/typecheck.s                                     170567   170522   -45     -0.026%
cmd/go/internal/cache.s                                              37546    37451    -95     -0.253%
cmd/go/internal/gover.s                                              6733     6726     -7      -0.104%
cmd/vendor/golang.org/x/arch/arm/armasm.s                            30032    29991    -41     -0.137%
cmd/go/internal/auth.s                                               22485    22385    -100    -0.445%
cmd/go/internal/search.s                                             15362    15262    -100    -0.651%
cmd/vendor/golang.org/x/tools/go/analysis/passes/modernize.s         197385   196963   -422    -0.214%
cmd/go/internal/doc.s                                                62764    62590    -174    -0.277%
cmd/compile/internal/compare.s                                       10769    10758    -11     -0.102%
cmd/vendor/golang.org/x/arch/ppc64/ppc64asm.s                        208027   208005   -22     -0.011%
cmd/compile/internal/escape.s                                        72599    72560    -39     -0.054%
cmd/go/internal/mvs.s                                                30363    30339    -24     -0.079%
cmd/go/internal/vcweb.s                                              51575    51334    -241    -0.467%
cmd/go/internal/modindex.s                                           80742    80444    -298    -0.369%
cmd/vendor/golang.org/x/arch/x86/x86asm.s                            72057    72004    -53     -0.074%
cmd/compile/internal/objw [cmd/compile].s                            7408     7345     -63     -0.850%
cmd/go/internal/vcs.s                                                51661    51545    -116    -0.225%
cmd/go/internal/modfetch/codehost.s                                  110786   110689   -97     -0.088%
cmd/nm.s                                                             5055     4981     -74     -1.464%
cmd/pack.s                                                           8826     8804     -22     -0.249%
cmd/compile/internal/types2 [cmd/compile].s                          667403   667271   -132    -0.020%
cmd/internal/script/scripttest.s                                     40383    40149    -234    -0.579%
cmd/compile/internal/typecheck [cmd/compile].s                       196101   196056   -45     -0.023%
cmd/preprofile.s                                                     3127     3107     -20     -0.640%
cmd/compile/internal/staticdata [cmd/compile].s                      31032    31017    -15     -0.048%
cmd/go/internal/modfetch.s                                           134544   134056   -488    -0.363%
cmd/vendor/golang.org/x/tools/go/analysis/passes/atomic.s            2433     2408     -25     -1.028%
cmd/vendor/github.com/google/pprof/profile.s                         155233   155173   -60     -0.039%
cmd/vendor/golang.org/x/tools/go/analysis/passes/asmdecl.s           29779    29182    -597    -2.005%
cmd/link/internal/loader.s                                           91163    91116    -47     -0.052%
cmd/compile/internal/escape [cmd/compile].s                          86596    86592    -4      -0.005%
cmd/go/internal/fips140.s                                            5054     5043     -11     -0.218%
cmd/vendor/github.com/google/pprof/internal/symbolz.s                4726     4674     -52     -1.100%
cmd/vendor/golang.org/x/tools/go/analysis/passes/framepointer.s      3703     3660     -43     -1.161%
cmd/vendor/golang.org/x/tools/go/analysis/passes/loopclosure.s       6869     6844     -25     -0.364%
cmd/vendor/golang.org/x/text/language.s                              46461    46443    -18     -0.039%
cmd/vendor/golang.org/x/text/internal.s                              2514     2502     -12     -0.477%
cmd/trace.s                                                          259231   258558   -673    -0.260%
cmd/vendor/golang.org/x/tools/go/analysis/passes/ctrlflow.s          3996     3987     -9      -0.225%
cmd/vendor/golang.org/x/tools/go/analysis/passes/testinggoroutine.s  9587     9555     -32     -0.334%
cmd/vendor/golang.org/x/text/cases.s                                 38482    38463    -19     -0.049%
cmd/vendor/golang.org/x/tools/go/analysis/passes/unsafeptr.s         3150     3124     -26     -0.825%
cmd/vendor/github.com/ianlancetaylor/demangle.s                      302482   302444   -38     -0.013%
cmd/vendor/github.com/google/pprof/internal/report.s                 90542    90448    -94     -0.104%
cmd/vendor/github.com/google/pprof/internal/binutils.s               37434    37280    -154    -0.411%
cmd/vendor/rsc.io/markdown.s                                         114203   114108   -95     -0.083%
cmd/go/internal/modload.s                                            359362   358159   -1203   -0.335%
cmd/vendor/golang.org/x/build/relnote.s                              31599    31577    -22     -0.070%
cmd/vendor/github.com/google/pprof/internal/driver.s                 178419   177787   -632    -0.354%
cmd/go/internal/load.s                                               186922   186634   -288    -0.154%
cmd/link/internal/ld.s                                               643871   643415   -456    -0.071%
cmd/link/internal/riscv64.s                                          19743    19726    -17     -0.086%
cmd/go/internal/work.s                                               348917   348463   -454    -0.130%
cmd/go/internal/clean.s                                              14815    14755    -60     -0.405%
cmd/go/internal/list.s                                               29662    29630    -32     -0.108%
cmd/go/internal/tool.s                                               27842    27825    -17     -0.061%
cmd/go/internal/envcmd.s                                             49896    49872    -24     -0.048%
cmd/go/internal/test.s                                               72162    72098    -64     -0.089%
cmd/go/internal/bug.s                                                10603    10547    -56     -0.528%
cmd/go/internal/toolchain.s                                          29042    28890    -152    -0.523%
cmd/go/internal/modcmd.s                                             61916    61761    -155    -0.250%
cmd/go/internal/modget.s                                             79559    79358    -201    -0.253%
cmd/go/internal/workcmd.s                                            28612    28481    -131    -0.458%
cmd/go.s                                                             13367    13343    -24     -0.180%
cmd/compile/internal/ssa.s                                           3614387  3614418  +31     +0.001%
cmd/compile/internal/liveness.s                                      96901    96882    -19     -0.020%
cmd/compile/internal/ssa [cmd/compile].s                             3779800  3779973  +173    +0.005%
cmd/compile/internal/liveness [cmd/compile].s                        129898   129895   -3      -0.002%
cmd/compile/internal/ssagen.s                                        436780   436748   -32     -0.007%
cmd/compile/internal/ssagen [cmd/compile].s                          473190   473109   -81     -0.017%
cmd/compile/internal/walk [cmd/compile].s                            347940   347810   -130    -0.037%
cmd/compile/internal/walk.s                                          334528   334382   -146    -0.044%
cmd/compile/internal/noder.s                                         260365   260297   -68     -0.026%
cmd/compile/internal/noder [cmd/compile].s                           296865   296819   -46     -0.015%
cmd/compile/internal/gc.s                                            30442    30346    -96     -0.315%
cmd/compile/internal/gc [cmd/compile].s                              41682    41586    -96     -0.230%
total                                                                38124617 38101256 -23361  -0.061%

Change-Id: Id0b3770da69c6f666b3ff36741f75377001466c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/675335
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Mark Freeman <markfreeman@google.com>
Reviewed-by: Keith Randall <khr@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
This commit is contained in:
Jakub Ciolek 2025-05-21 09:34:48 +02:00 committed by Gopher Robot
parent d0d0a72980
commit d474f1fd21
2 changed files with 395 additions and 35 deletions

View file

@ -10,6 +10,10 @@ import (
"cmd/internal/obj" "cmd/internal/obj"
) )
// maxShadowRanges bounds the number of disjoint byte intervals
// we track per pointer to avoid quadratic behaviour.
const maxShadowRanges = 64
// dse does dead-store elimination on the Function. // dse does dead-store elimination on the Function.
// Dead stores are those which are unconditionally followed by // Dead stores are those which are unconditionally followed by
// another store to the same location, with no intervening load. // another store to the same location, with no intervening load.
@ -24,6 +28,10 @@ func dse(f *Func) {
defer f.retSparseMap(shadowed) defer f.retSparseMap(shadowed)
// localAddrs maps from a local variable (the Aux field of a LocalAddr value) to an instance of a LocalAddr value for that variable in the current block. // localAddrs maps from a local variable (the Aux field of a LocalAddr value) to an instance of a LocalAddr value for that variable in the current block.
localAddrs := map[any]*Value{} localAddrs := map[any]*Value{}
// shadowedRanges stores the actual range data. The 'shadowed' sparseMap stores a 1-based index into this slice.
var shadowedRanges []*shadowRanges
for _, b := range f.Blocks { for _, b := range f.Blocks {
// Find all the stores in this block. Categorize their uses: // Find all the stores in this block. Categorize their uses:
// loadUse contains stores which are used by a subsequent load. // loadUse contains stores which are used by a subsequent load.
@ -89,10 +97,11 @@ func dse(f *Func) {
// Walk backwards looking for dead stores. Keep track of shadowed addresses. // Walk backwards looking for dead stores. Keep track of shadowed addresses.
// A "shadowed address" is a pointer, offset, and size describing a memory region that // A "shadowed address" is a pointer, offset, and size describing a memory region that
// is known to be written. We keep track of shadowed addresses in the shadowed map, // is known to be written. We keep track of shadowed addresses in the shadowed map,
// mapping the ID of the address to a shadowRange where future writes will happen. // mapping the ID of the address to a shadowRanges where future writes will happen.
// Since we're walking backwards, writes to a shadowed region are useless, // Since we're walking backwards, writes to a shadowed region are useless,
// as they will be immediately overwritten. // as they will be immediately overwritten.
shadowed.clear() shadowed.clear()
shadowedRanges = shadowedRanges[:0]
v := last v := last
walkloop: walkloop:
@ -100,6 +109,7 @@ func dse(f *Func) {
// Someone might be reading this memory state. // Someone might be reading this memory state.
// Clear all shadowed addresses. // Clear all shadowed addresses.
shadowed.clear() shadowed.clear()
shadowedRanges = shadowedRanges[:0]
} }
if v.Op == OpStore || v.Op == OpZero { if v.Op == OpStore || v.Op == OpZero {
ptr := v.Args[0] ptr := v.Args[0]
@ -119,9 +129,14 @@ func dse(f *Func) {
ptr = la ptr = la
} }
} }
srNum, _ := shadowed.get(ptr.ID) var si *shadowRanges
sr := shadowRange(srNum) idx, ok := shadowed.get(ptr.ID)
if sr.contains(off, off+sz) { if ok {
// The sparseMap stores a 1-based index, so we subtract 1.
si = shadowedRanges[idx-1]
}
if si != nil && si.contains(off, off+sz) {
// Modify the store/zero into a copy of the memory state, // Modify the store/zero into a copy of the memory state,
// effectively eliding the store operation. // effectively eliding the store operation.
if v.Op == OpStore { if v.Op == OpStore {
@ -136,7 +151,13 @@ func dse(f *Func) {
v.Op = OpCopy v.Op = OpCopy
} else { } else {
// Extend shadowed region. // Extend shadowed region.
shadowed.set(ptr.ID, int32(sr.merge(off, off+sz))) if si == nil {
si = &shadowRanges{}
shadowedRanges = append(shadowedRanges, si)
// Store a 1-based index in the sparseMap.
shadowed.set(ptr.ID, int32(len(shadowedRanges)))
}
si.add(off, off+sz)
} }
} }
// walk to previous store // walk to previous store
@ -156,46 +177,51 @@ func dse(f *Func) {
} }
} }
// A shadowRange encodes a set of byte offsets [lo():hi()] from // shadowRange represents a single byte range [lo,hi] that will be written.
// a given pointer that will be written to later in the block. type shadowRange struct {
// A zero shadowRange encodes an empty shadowed range. lo, hi uint16
type shadowRange int32
func (sr shadowRange) lo() int64 {
return int64(sr & 0xffff)
} }
func (sr shadowRange) hi() int64 { // shadowRanges stores an unordered collection of disjoint byte ranges.
return int64((sr >> 16) & 0xffff) type shadowRanges struct {
ranges []shadowRange
} }
// contains reports whether [lo:hi] is completely within sr. // contains reports whether [lo:hi] is completely within sr.
func (sr shadowRange) contains(lo, hi int64) bool { func (sr *shadowRanges) contains(lo, hi int64) bool {
return lo >= sr.lo() && hi <= sr.hi() for _, r := range sr.ranges {
if lo >= int64(r.lo) && hi <= int64(r.hi) {
return true
}
}
return false
} }
// merge returns the union of sr and [lo:hi]. func (sr *shadowRanges) add(lo, hi int64) {
// merge is allowed to return something smaller than the union. // Ignore the store if:
func (sr shadowRange) merge(lo, hi int64) shadowRange { // - the range doesn't fit in 16 bits, or
if lo < 0 || hi > 0xffff { // - we already track maxShadowRanges intervals.
// Ignore offsets that are too large or small. // The cap prevents a theoretical O(n^2) blow-up.
return sr if lo < 0 || hi > 0xffff || len(sr.ranges) >= maxShadowRanges {
return
} }
if sr.lo() == sr.hi() { nlo := lo
// Old range is empty - use new one. nhi := hi
return shadowRange(lo + hi<<16) out := sr.ranges[:0]
}
if hi < sr.lo() || lo > sr.hi() { for _, r := range sr.ranges {
// The two regions don't overlap or abut, so we would if nhi < int64(r.lo) || nlo > int64(r.hi) {
// have to keep track of multiple disjoint ranges. out = append(out, r)
// Because we can only keep one, keep the larger one. continue
if sr.hi()-sr.lo() >= hi-lo { }
return sr if int64(r.lo) < nlo {
nlo = int64(r.lo)
}
if int64(r.hi) > nhi {
nhi = int64(r.hi)
} }
return shadowRange(lo + hi<<16)
} }
// Regions overlap or abut - compute the union. sr.ranges = append(out, shadowRange{uint16(nlo), uint16(nhi)})
return shadowRange(min(lo, sr.lo()) + max(hi, sr.hi())<<16)
} }
// elimDeadAutosGeneric deletes autos that are never accessed. To achieve this // elimDeadAutosGeneric deletes autos that are never accessed. To achieve this

View file

@ -7,6 +7,8 @@ package ssa
import ( import (
"cmd/compile/internal/types" "cmd/compile/internal/types"
"cmd/internal/src" "cmd/internal/src"
"fmt"
"sort"
"testing" "testing"
) )
@ -172,3 +174,335 @@ func TestDeadStoreSmallStructInit(t *testing.T) {
t.Errorf("dead store not removed") t.Errorf("dead store not removed")
} }
} }
func TestDeadStoreArrayGap(t *testing.T) {
c := testConfig(t)
ptr := c.config.Types.BytePtr
i64 := c.config.Types.Int64
typ := types.NewArray(i64, 5)
tmp := c.Temp(typ)
fun := c.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sp", OpSP, c.config.Types.Uintptr, 0, nil),
Valu("base", OpLocalAddr, ptr, 0, tmp, "sp", "start"),
Valu("p0", OpOffPtr, ptr, 0, nil, "base"),
Valu("p1", OpOffPtr, ptr, 8, nil, "base"),
Valu("p2", OpOffPtr, ptr, 16, nil, "base"),
Valu("p3", OpOffPtr, ptr, 24, nil, "base"),
Valu("p4", OpOffPtr, ptr, 32, nil, "base"),
Valu("one", OpConst64, i64, 1, nil),
Valu("seven", OpConst64, i64, 7, nil),
Valu("zero", OpConst64, i64, 0, nil),
Valu("mem0", OpZero, types.TypeMem, 40, typ, "base", "start"),
Valu("s0", OpStore, types.TypeMem, 0, i64, "p0", "one", "mem0"),
Valu("s1", OpStore, types.TypeMem, 0, i64, "p1", "seven", "s0"),
Valu("s2", OpStore, types.TypeMem, 0, i64, "p3", "one", "s1"),
Valu("s3", OpStore, types.TypeMem, 0, i64, "p4", "one", "s2"),
Valu("s4", OpStore, types.TypeMem, 0, i64, "p2", "zero", "s3"),
Goto("exit")),
Bloc("exit",
Exit("s4")))
CheckFunc(fun.f)
dse(fun.f)
CheckFunc(fun.f)
if op := fun.values["mem0"].Op; op != OpCopy {
t.Fatalf("dead Zero not removed: got %s, want OpCopy", op)
}
}
func TestShadowRanges(t *testing.T) {
t.Run("simple insert & contains", func(t *testing.T) {
var sr shadowRanges
sr.add(10, 20)
wantRanges(t, sr.ranges, [][2]uint16{{10, 20}})
if !sr.contains(12, 18) || !sr.contains(10, 20) {
t.Fatalf("contains failed after simple add")
}
if sr.contains(9, 11) || sr.contains(11, 21) {
t.Fatalf("contains erroneously true for non-contained range")
}
})
t.Run("merge overlapping", func(t *testing.T) {
var sr shadowRanges
sr.add(10, 20)
sr.add(15, 25)
wantRanges(t, sr.ranges, [][2]uint16{{10, 25}})
if !sr.contains(13, 24) {
t.Fatalf("contains should be true after merge")
}
})
t.Run("merge touching boundary", func(t *testing.T) {
var sr shadowRanges
sr.add(100, 150)
// touches at 150 - should coalesce
sr.add(150, 180)
wantRanges(t, sr.ranges, [][2]uint16{{100, 180}})
})
t.Run("union across several ranges", func(t *testing.T) {
var sr shadowRanges
sr.add(10, 20)
sr.add(30, 40)
// bridges second, not first
sr.add(25, 35)
wantRanges(t, sr.ranges, [][2]uint16{{10, 20}, {25, 40}})
// envelops everything
sr.add(5, 50)
wantRanges(t, sr.ranges, [][2]uint16{{5, 50}})
})
t.Run("disjoint intervals stay separate", func(t *testing.T) {
var sr shadowRanges
sr.add(10, 20)
sr.add(22, 30)
wantRanges(t, sr.ranges, [][2]uint16{{10, 20}, {22, 30}})
// spans both
if sr.contains(15, 25) {
t.Fatalf("contains across two disjoint ranges should be false")
}
})
t.Run("large uint16 offsets still work", func(t *testing.T) {
var sr shadowRanges
sr.add(40000, 45000)
if !sr.contains(42000, 43000) {
t.Fatalf("contains failed for large uint16 values")
}
})
t.Run("out-of-bounds inserts ignored", func(t *testing.T) {
var sr shadowRanges
sr.add(10, 20)
sr.add(-5, 5)
sr.add(70000, 70010)
wantRanges(t, sr.ranges, [][2]uint16{{10, 20}})
})
}
// canonicalise order for comparisons
func sortRanges(r []shadowRange) {
sort.Slice(r, func(i, j int) bool { return r[i].lo < r[j].lo })
}
// compare actual slice with expected pairs
func wantRanges(t *testing.T, got []shadowRange, want [][2]uint16) {
t.Helper()
sortRanges(got)
if len(got) != len(want) {
t.Fatalf("len(ranges)=%d, want %d (got=%v)", len(got), len(want), got)
}
for i, w := range want {
if got[i].lo != w[0] || got[i].hi != w[1] {
t.Fatalf("range %d = [%d,%d], want [%d,%d] (full=%v)",
i, got[i].lo, got[i].hi, w[0], w[1], got)
}
}
}
func BenchmarkDeadStore(b *testing.B) {
cfg := testConfig(b)
ptr := cfg.config.Types.BytePtr
f := cfg.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sb", OpSB, cfg.config.Types.Uintptr, 0, nil),
Valu("v", OpConstBool, cfg.config.Types.Bool, 1, nil),
Valu("a1", OpAddr, ptr, 0, nil, "sb"),
Valu("a2", OpAddr, ptr, 0, nil, "sb"),
Valu("a3", OpAddr, ptr, 0, nil, "sb"),
Valu("z1", OpZero, types.TypeMem, 1, cfg.config.Types.Bool, "a3", "start"),
Valu("s1", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a1", "v", "z1"),
Valu("s2", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a2", "v", "s1"),
Valu("s3", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a1", "v", "s2"),
Valu("s4", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a3", "v", "s3"),
Goto("exit")),
Bloc("exit",
Exit("s3")))
runBench(b, func() {
dse(f.f)
})
}
func BenchmarkDeadStorePhi(b *testing.B) {
cfg := testConfig(b)
ptr := cfg.config.Types.BytePtr
f := cfg.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sb", OpSB, cfg.config.Types.Uintptr, 0, nil),
Valu("v", OpConstBool, cfg.config.Types.Bool, 1, nil),
Valu("addr", OpAddr, ptr, 0, nil, "sb"),
Goto("loop")),
Bloc("loop",
Valu("phi", OpPhi, types.TypeMem, 0, nil, "start", "store"),
Valu("store", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "addr", "v", "phi"),
If("v", "loop", "exit")),
Bloc("exit",
Exit("store")))
runBench(b, func() {
dse(f.f)
})
}
func BenchmarkDeadStoreTypes(b *testing.B) {
cfg := testConfig(b)
t1 := cfg.config.Types.UInt64.PtrTo()
t2 := cfg.config.Types.UInt32.PtrTo()
f := cfg.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sb", OpSB, cfg.config.Types.Uintptr, 0, nil),
Valu("v", OpConstBool, cfg.config.Types.Bool, 1, nil),
Valu("a1", OpAddr, t1, 0, nil, "sb"),
Valu("a2", OpAddr, t2, 0, nil, "sb"),
Valu("s1", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a1", "v", "start"),
Valu("s2", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a2", "v", "s1"),
Goto("exit")),
Bloc("exit",
Exit("s2")))
cse(f.f)
runBench(b, func() {
dse(f.f)
})
}
func BenchmarkDeadStoreUnsafe(b *testing.B) {
cfg := testConfig(b)
ptr := cfg.config.Types.UInt64.PtrTo()
f := cfg.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sb", OpSB, cfg.config.Types.Uintptr, 0, nil),
Valu("v", OpConstBool, cfg.config.Types.Bool, 1, nil),
Valu("a1", OpAddr, ptr, 0, nil, "sb"),
Valu("s1", OpStore, types.TypeMem, 0, cfg.config.Types.Int64, "a1", "v", "start"),
Valu("s2", OpStore, types.TypeMem, 0, cfg.config.Types.Bool, "a1", "v", "s1"),
Goto("exit")),
Bloc("exit",
Exit("s2")))
cse(f.f)
runBench(b, func() {
dse(f.f)
})
}
func BenchmarkDeadStoreSmallStructInit(b *testing.B) {
cfg := testConfig(b)
ptr := cfg.config.Types.BytePtr
typ := types.NewStruct([]*types.Field{
types.NewField(src.NoXPos, &types.Sym{Name: "A"}, cfg.config.Types.Int),
types.NewField(src.NoXPos, &types.Sym{Name: "B"}, cfg.config.Types.Int),
})
tmp := cfg.Temp(typ)
f := cfg.Fun("entry",
Bloc("entry",
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sp", OpSP, cfg.config.Types.Uintptr, 0, nil),
Valu("zero", OpConst64, cfg.config.Types.Int, 0, nil),
Valu("v6", OpLocalAddr, ptr, 0, tmp, "sp", "start"),
Valu("v3", OpOffPtr, ptr, 8, nil, "v6"),
Valu("v22", OpOffPtr, ptr, 0, nil, "v6"),
Valu("s1", OpStore, types.TypeMem, 0, cfg.config.Types.Int, "v22", "zero", "start"),
Valu("s2", OpStore, types.TypeMem, 0, cfg.config.Types.Int, "v3", "zero", "s1"),
Valu("v8", OpLocalAddr, ptr, 0, tmp, "sp", "s2"),
Valu("v23", OpOffPtr, ptr, 8, nil, "v8"),
Valu("v25", OpOffPtr, ptr, 0, nil, "v8"),
Valu("s3", OpStore, types.TypeMem, 0, cfg.config.Types.Int, "v25", "zero", "s2"),
Valu("s4", OpStore, types.TypeMem, 0, cfg.config.Types.Int, "v23", "zero", "s3"),
Goto("exit")),
Bloc("exit",
Exit("s4")))
cse(f.f)
runBench(b, func() {
dse(f.f)
})
}
func BenchmarkDeadStoreLargeBlock(b *testing.B) {
// create a very large block with many shadowed stores
const (
addrCount = 128
// first 7 are dead
storesPerAddr = 8
)
cfg := testConfig(b)
ptrType := cfg.config.Types.BytePtr
boolType := cfg.config.Types.Bool
items := []interface{}{
Valu("start", OpInitMem, types.TypeMem, 0, nil),
Valu("sb", OpSB, cfg.config.Types.Uintptr, 0, nil),
Valu("v", OpConstBool, boolType, 1, nil),
}
for i := 0; i < addrCount; i++ {
items = append(items,
Valu(fmt.Sprintf("addr%d", i), OpAddr, ptrType, 0, nil, "sb"),
)
}
prev := "start"
for round := 0; round < storesPerAddr; round++ {
for i := 0; i < addrCount; i++ {
store := fmt.Sprintf("s_%03d_%d", i, round)
addr := fmt.Sprintf("addr%d", i)
items = append(items,
Valu(store, OpStore, types.TypeMem, 0, boolType, addr, "v", prev),
)
prev = store
}
}
items = append(items, Goto("exit"))
entryBlk := Bloc("entry", items...)
exitBlk := Bloc("exit", Exit(prev))
f := cfg.Fun("stress", entryBlk, exitBlk)
runBench(b, func() {
dse(f.f)
})
}
func runBench(b *testing.B, build func()) {
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
build()
}
}