aboutsummaryrefslogtreecommitdiff
path: root/test/inline.go
AgeCommit message (Collapse)Author
2020-11-06cmd/compile: support inlining of type switchesMatthew Dempsky
This CL adds support for inlining type switches, including exporting and importing them. Type switches are represented mostly the same as expression switches. However, if the type switch guard includes a short variable declaration, then there are two differences: (1) there's an ONONAME (in the OTYPESW's Left) to represent the overall pseudo declaration; and (2) there's an ONAME (in each OCASE's Rlist) to represent the per-case variables. For simplicity, this CL simply writes out each variable separately using iimport/iiexport's normal Vargen mechanism for disambiguating identically named variables within a function. This could be improved somewhat, but inlinable type switches are probably too uncommon to merit the complexity. While here, remove "case OCASE" from typecheck1. We only type check "case" clauses as part of a "select" or "switch" statement, never as standalone statements. Fixes #37837 Change-Id: I8f42f6c9afdd821d6202af4a6bf1dbcbba0ef424 Reviewed-on: https://go-review.googlesource.com/c/go/+/266203 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
2020-10-29cmd/compile: inline functions evaluated in go and defer statementsBranden J Brown
The inlining pass previously bailed upon encountering a go or defer statement, so it would not inline functions e.g. used to provide arguments to the deferred function. This change preserves the behavior of not inlining the deferred function itself, but it allows the inlining walk to proceed into its arguments. Fixes #42194 Change-Id: I4e82029d8dcbe69019cc83ae63a4b29af45ec777 Reviewed-on: https://go-review.googlesource.com/c/go/+/264997 Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-10-20cmd/compile: allowing inlining of functions with OCALLPARTDan Scales
OCALLPART is exported in its original form, which is as an OXDOT. The body of the method value wrapper created in makepartialcall() was not being typechecked, and that was causing a problem during escape analysis, so I added code to typecheck the body. The go executable got slightly bigger with this change (13598111 -> 13598905), because of extra exported methods with OCALLPART (I believe), while the text size got slightly smaller (9686964 -> 9686643). This is mainly part of the work to make sure all function bodies can be exported (for purposes of generics), but might as well fix the OCALLPART inlining bug as well. Fixes #18493 Change-Id: If7aa055ff78ed7a6330c6a1e22f836ec567d04fd Reviewed-on: https://go-review.googlesource.com/c/go/+/263620 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-10-15cmd/compile: use staticValue for inlining logicMatthew Dempsky
This CL replaces the ad hoc and duplicated logic for detecting inlinable calls with a single "inlCallee" function, which uses the "staticValue" helper function introduced in an earlier commit. Updates #41474. Change-Id: I103d4091b10366fce1344ef2501222b7df68f21d Reviewed-on: https://go-review.googlesource.com/c/go/+/256460 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Trust: Matthew Dempsky <mdempsky@google.com>
2020-10-15cmd/compile: allow inlining of "for" loopsMatthew Dempsky
We already allow inlining "if" and "goto" statements, so we might as well allow "for" loops too. The majority of frontend support is already there too. The critical missing feature at the moment is that inlining doesn't properly reassociate OLABEL nodes with their control statement (e.g., OFOR) after inlining. This eventually causes SSA construction to fail. As a workaround, this CL only enables inlining for unlabeled "for" loops. It's left to a (yet unplanned) future CL to add support for labeled "for" loops. The increased opportunity for inlining leads to a small growth in binary size. For example: $ size go.old go.new text data bss dec hex filename 9740163 320064 230656 10290883 9d06c3 go.old 9793399 320064 230656 10344119 9dd6b7 go.new Updates #14768. Fixes #41474. Change-Id: I827db0b2b9d9fa2934db05caf6baa463f0cd032a Reviewed-on: https://go-review.googlesource.com/c/go/+/256459 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2020-09-15test: fix inline.go to pass linux-amd64-nooptMatthew Dempsky
Updates #33485. Change-Id: I3330860cdff1e9797466a7630bcdb7792c465b06 Reviewed-on: https://go-review.googlesource.com/c/go/+/254938 Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
2020-09-14cmd/compile: call fninit earlierMatthew Dempsky
This allows the global initializers function to go through normal mid-end optimizations (e.g., inlining, escape analysis) like any other function. Updates #33485. Change-Id: I9bcfe98b8628d1aca09b4c238d8d3b74c69010a5 Reviewed-on: https://go-review.googlesource.com/c/go/+/254839 Reviewed-by: Keith Randall <khr@golang.org> Trust: Matthew Dempsky <mdempsky@google.com>
2020-04-03cmd/compile: allow mid-stack inlining when there is a cycle of recursionDan Scales
We still disallow inlining for an immediately-recursive function, but allow inlining if a function is in a recursion chain. If all functions in the recursion chain are simple, then we could inline forever down the recursion chain (eventually running out of stack on the compiler), so we add a map to keep track of the functions we have already inlined at a call site. We stop inlining when we reach a function that we have already inlined in the recursive chain. Of course, normally the inlining will have stopped earlier, because of the cost function. We could also limit the depth of inlining by a simple count (say, limit max inlining of 10 at any given site). Would that limit other opportunities too much? Added a test in test/inline.go. runtime.BenchmarkStackCopyNoCache() is also already a good test that triggers the check to stop inlining when we reach the start of the recursive chain again. For the bent benchmark suite, the performance improvement was mostly not statistically significant, but the geomean averaged out to: -0.68%. The text size increase was less than .1% for all bent benchmarks. The cmd/go text size increase was 0.02% and the cmd/compile text size increase was .1%. Fixes #29737 Change-Id: I892fa84bb07a947b3125ec8f25ed0e508bf2bdf5 Reviewed-on: https://go-review.googlesource.com/c/go/+/226818 Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2019-09-16cmd/compile: trim function name prefix from escape diagnosticsMatthew Dempsky
This information is redundant with the position information already provided. Also, no other -m diagnostics print out function name. While here, report parameter leak diagnostics against the parameter declaration position rather than the function, and use Warnl for "moved to heap" messages. Test cases updated programmatically by removing the first word from every "no match for" error emitted by run.go: go run run.go |& \ sed -E -n 's/^(.*):(.*): no match for `([^ ]* (.*))` in:$/\1!\2!\3!\4/p' | \ while IFS='!' read -r fn line before after; do before=$(echo "$before" | sed 's/[.[\*^$()+?{|]/\\&/g') after=$(echo "$after" | sed -E 's/(\&|\\)/\\&/g') fn=$(find . -name "${fn}" | head -1) sed -i -E -e "${line}s/\"${before}\"/\"${after}\"/" "${fn}" done Passes toolstash-check. Change-Id: I6e02486b1409e4a8dbb2b9b816d22095835426b5 Reviewed-on: https://go-review.googlesource.com/c/go/+/195040 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2019-04-02cmd/compile: skip escape analysis diagnostics for OADDRMatthew Dempsky
For most nodes (e.g., OPTRLIT, OMAKESLICE, OCONVIFACE), escape analysis prints "escapes to heap" or "does not escape" to indicate whether that node's allocation can be heap or stack allocated. These messages are also emitted for OADDR, even though OADDR does not actually allocate anything itself. Moreover, it's redundant because escape analysis already prints "moved to heap" diagnostics when an OADDR node like "&x" causes x to require heap allocation. Because OADDR nodes don't allocate memory, my escape analysis rewrite doesn't naturally emit the "escapes to heap" / "does not escape" diagnostics for them. It's also non-trivial to replicate the exact semantics esc.go uses for OADDR. Since there are so many of these messages, I'm disabling them in this CL by themselves. I modified esc.go to suppress the Warnl calls without any other behavior changes, and then used a shell script to automatically remove any ERROR messages mentioned by run.go in "missing error" or "no match for" lines. Fixes #16300. Updates #23109. Change-Id: I3993e2743c3ff83ccd0893f4e73b366ff8871a57 Reviewed-on: https://go-review.googlesource.com/c/go/+/170319 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com> Reviewed-by: David Chase <drchase@google.com>
2018-11-08cmd/compile: encourage inlining of functions with single-call bodiesKeith Randall
This is a simple tweak to allow a bit more mid-stack inlining. In cases like this: func f() { g() } We'd really like to inline f into its callers. It can't hurt. We implement this optimization by making calls a bit cheaper, enough to afford a single call in the function body, but not 2. The remaining budget allows for some argument modification, or perhaps a wrapping conditional: func f(x int) { g(x, 0) } func f(x int) { if x > 0 { g() } } Update #19348 Change-Id: Ifb1ea0dd1db216c3fd5c453c31c3355561fe406f Reviewed-on: https://go-review.googlesource.com/c/147361 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: David Chase <drchase@google.com>
2017-11-05cmd/compile: inline closures with capturesHugues Bruant
When inlining a closure with captured variables, walk up the param chain to find the one that is defined inside the scope into which the function is being inlined, and map occurrences of the captures to temporary inlvars, similarly to what is done for function parameters. No noticeable impact on compilation speed and binary size. Minor improvements to go1 benchmarks on darwin/amd64 name old time/op new time/op delta BinaryTree17-4 2.59s ± 3% 2.58s ± 1% ~ (p=0.470 n=19+19) Fannkuch11-4 3.15s ± 2% 3.15s ± 1% ~ (p=0.647 n=20+19) FmtFprintfEmpty-4 43.7ns ± 3% 43.4ns ± 4% ~ (p=0.178 n=18+20) FmtFprintfString-4 74.0ns ± 2% 77.1ns ± 7% +4.13% (p=0.000 n=20+20) FmtFprintfInt-4 77.2ns ± 3% 79.2ns ± 6% +2.53% (p=0.000 n=20+20) FmtFprintfIntInt-4 112ns ± 4% 112ns ± 2% ~ (p=0.672 n=20+19) FmtFprintfPrefixedInt-4 136ns ± 1% 135ns ± 2% ~ (p=0.827 n=16+20) FmtFprintfFloat-4 232ns ± 2% 233ns ± 1% ~ (p=0.194 n=20+20) FmtManyArgs-4 490ns ± 2% 484ns ± 2% -1.28% (p=0.001 n=20+20) GobDecode-4 6.68ms ± 2% 6.72ms ± 2% ~ (p=0.113 n=20+19) GobEncode-4 5.62ms ± 2% 5.71ms ± 2% +1.64% (p=0.000 n=20+19) Gzip-4 235ms ± 3% 236ms ± 2% ~ (p=0.607 n=20+19) Gunzip-4 37.1ms ± 2% 36.8ms ± 3% ~ (p=0.060 n=20+20) HTTPClientServer-4 61.9µs ± 2% 62.7µs ± 4% +1.24% (p=0.007 n=18+19) JSONEncode-4 12.5ms ± 2% 12.4ms ± 3% ~ (p=0.192 n=20+20) JSONDecode-4 51.6ms ± 3% 51.0ms ± 3% -1.19% (p=0.008 n=20+19) Mandelbrot200-4 4.12ms ± 6% 4.06ms ± 5% ~ (p=0.063 n=20+20) GoParse-4 3.12ms ± 5% 3.10ms ± 2% ~ (p=0.402 n=19+19) RegexpMatchEasy0_32-4 80.7ns ± 2% 75.1ns ± 9% -6.94% (p=0.000 n=17+20) RegexpMatchEasy0_1K-4 197ns ± 2% 186ns ± 2% -5.43% (p=0.000 n=20+20) RegexpMatchEasy1_32-4 77.5ns ± 4% 71.9ns ± 7% -7.25% (p=0.000 n=20+18) RegexpMatchEasy1_1K-4 341ns ± 3% 341ns ± 3% ~ (p=0.732 n=20+20) RegexpMatchMedium_32-4 113ns ± 2% 112ns ± 3% ~ (p=0.102 n=20+20) RegexpMatchMedium_1K-4 36.6µs ± 2% 35.8µs ± 2% -2.26% (p=0.000 n=18+20) RegexpMatchHard_32-4 1.75µs ± 3% 1.74µs ± 2% ~ (p=0.473 n=20+19) RegexpMatchHard_1K-4 52.6µs ± 2% 52.0µs ± 3% -1.15% (p=0.005 n=20+20) Revcomp-4 381ms ± 4% 377ms ± 2% ~ (p=0.067 n=20+18) Template-4 57.3ms ± 2% 57.7ms ± 2% ~ (p=0.108 n=20+20) TimeParse-4 291ns ± 3% 292ns ± 2% ~ (p=0.585 n=20+20) TimeFormat-4 314ns ± 3% 315ns ± 1% ~ (p=0.681 n=20+20) [Geo mean] 47.4µs 47.1µs -0.73% name old speed new speed delta GobDecode-4 115MB/s ± 2% 114MB/s ± 2% ~ (p=0.115 n=20+19) GobEncode-4 137MB/s ± 2% 134MB/s ± 2% -1.63% (p=0.000 n=20+19) Gzip-4 82.5MB/s ± 3% 82.4MB/s ± 2% ~ (p=0.612 n=20+19) Gunzip-4 523MB/s ± 2% 528MB/s ± 3% ~ (p=0.060 n=20+20) JSONEncode-4 155MB/s ± 2% 156MB/s ± 3% ~ (p=0.192 n=20+20) JSONDecode-4 37.6MB/s ± 3% 38.1MB/s ± 3% +1.21% (p=0.007 n=20+19) GoParse-4 18.6MB/s ± 4% 18.7MB/s ± 2% ~ (p=0.405 n=19+19) RegexpMatchEasy0_32-4 396MB/s ± 2% 426MB/s ± 8% +7.56% (p=0.000 n=17+20) RegexpMatchEasy0_1K-4 5.18GB/s ± 2% 5.48GB/s ± 2% +5.79% (p=0.000 n=20+20) RegexpMatchEasy1_32-4 413MB/s ± 4% 444MB/s ± 6% +7.46% (p=0.000 n=20+19) RegexpMatchEasy1_1K-4 3.00GB/s ± 3% 3.00GB/s ± 3% ~ (p=0.678 n=20+20) RegexpMatchMedium_32-4 8.82MB/s ± 2% 8.90MB/s ± 3% +0.99% (p=0.044 n=20+20) RegexpMatchMedium_1K-4 28.0MB/s ± 2% 28.6MB/s ± 2% +2.32% (p=0.000 n=18+20) RegexpMatchHard_32-4 18.3MB/s ± 3% 18.4MB/s ± 2% ~ (p=0.482 n=20+19) RegexpMatchHard_1K-4 19.5MB/s ± 2% 19.7MB/s ± 3% +1.18% (p=0.004 n=20+20) Revcomp-4 668MB/s ± 4% 674MB/s ± 2% ~ (p=0.066 n=20+18) Template-4 33.8MB/s ± 2% 33.6MB/s ± 2% ~ (p=0.104 n=20+20) [Geo mean] 124MB/s 126MB/s +1.54% Updates #15561 Updates #18270 Change-Id: I980086efe28b36aa27f81577065e2a729ff03d4e Reviewed-on: https://go-review.googlesource.com/72490 Reviewed-by: Hugues Bruant <hugues.bruant@gmail.com> Reviewed-by: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-10-11cmd/compile: inline calls to local closuresHugues Bruant
Calls to a closure held in a local, non-escaping, variable can be inlined, provided the closure body can be inlined and the variable is never written to. The current implementation has the following limitations: - closures with captured variables are not inlined because doing so naively triggers invariant violation in the SSA phase - re-assignment check is currently approximated by checking the Addrtaken property of the variable which should be safe but may miss optimization opportunities if the address is not used for a write before the invocation Updates #15561 Change-Id: I508cad5d28f027bd7e933b1f793c14dcfef8b5a1 Reviewed-on: https://go-review.googlesource.com/65071 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Hugues Bruant <hugues.bruant@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
2017-10-10cmd/compile: remove outdated TODO about inliningMatthew Dempsky
We've supported inlining methods called as functions for a while now. Change-Id: I53fba426e45f91d65a38f00456c2ae1527372b50 Reviewed-on: https://go-review.googlesource.com/69530 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
2016-05-02all: make copyright headers consistent with one space after periodEmmanuel Odeke
Follows suit with https://go-review.googlesource.com/#/c/20111. Generated by running $ grep -R 'Go Authors. All' * | cut -d":" -f1 | while read F;do perl -pi -e 's/Go Authors. All/Go Authors. All/g' $F;done The code in cmd/internal/unvendor wasn't changed. Fixes #15213 Change-Id: I4f235cee0a62ec435f9e8540a1ec08ae03b1a75f Reviewed-on: https://go-review.googlesource.com/21819 Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-21cmd/compile: allow inlining of functions with switch statementsTodd Neal
Allow inlining of functions with switch statements as long as they don't contain a break or type switch. Fixes #13071 Change-Id: I057be351ea4584def1a744ee87eafa5df47a7f6d Reviewed-on: https://go-review.googlesource.com/20824 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-03-18cmd/compile: allow inlining of functions that declare a constTodd Neal
Consider functions with an ODCLCONST for inlining and modify exprfmt to ignore those nodes when exporting. Don't add symbols to the export list if there is no definition. This occurs when OLITERAL symbols are looked up via Pkglookup for non-exported symbols. Fixes #7655 Change-Id: I1de827850f4c69e58107447314fe7433e378e069 Reviewed-on: https://go-review.googlesource.com/20773 Run-TryBot: Todd Neal <todd@tneal.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
2015-10-29cmd/compile: add support for a go:noinline directiveTodd Neal
Some tests need to disable inlining of a function. It's currently done in one of a few ways (adding a function call, an empty switch, or a defer). Add support for a less fragile 'go:noinline' directive that prevents inlining. Fixes #12312 Change-Id: Ife444e13361b4a927709d81aa41e448f32eec8d4 Reviewed-on: https://go-review.googlesource.com/13911 Run-TryBot: Todd Neal <todd@tneal.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2015-02-26cmd/internal/gc: transitive inliningRuss Cox
Inlining refuses to inline bodies containing an actual function call, so that if that call or a child uses runtime.Caller it cannot observe the inlining. However, inlining was also refusing to inline bodies that contained function calls that were themselves inlined away. For example: func f() int { return f1() } func f1() int { return f2() } func f2() int { return 2 } The f2 call in f1 would be inlined, but the f1 call in f would not, because f1's call to f2 blocked the inlining, despite itself eventually being inlined away. Account properly for this kind of transitive inlining and enable. Also bump the inlining budget a bit, so that the runtime's heapBits.next is inlined. This reduces the time for '6g *.go' in html/template by around 12% (!). (For what it's worth, closing Chrome reduces the time by about 17%.) Change-Id: If1aa673bf3e583082dcfb5f223e67355c984bfc1 Reviewed-on: https://go-review.googlesource.com/5952 Reviewed-by: Austin Clements <austin@google.com>