aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/deadcode/deadcode.go
AgeCommit message (Collapse)Author
2023-08-11cmd/compile: move early deadcode into unified writerMatthew Dempsky
This CL moves the early deadcode elimination pass into the unified writer. This allows shrinking the export data, by simplifying expressions and removing unreachable statements. It also means we don't need to repeatedly apply deadcode elimination on inlined calls or instantiated generics. Change-Id: I19bdb04861e50815fccdab39790f4aaa076121fd Reviewed-on: https://go-review.googlesource.com/c/go/+/517775 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Than McIntosh <thanm@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2023-04-14cmd/compile: better code generation for constant-fold switchCuong Manh Le
CL 399694 added constant-fold switch early in compilation. So function: func f() string { switch intSize { case 32: return "32" case 64: return "64" default: panic("unreachable") } } will be constant-fold to: func f() string { switch intSize { case 64: return "64" } } When this function get inlined, there is a check whether we can delay declaring the result parameter until the "return" statement. For the original function, we can't delay the result, because there's more than one return statement. However, the constant-fold one can, because there's on one return statement in the body now. The result parameter ~R0 ends up declaring inside the switch statement scope. Now, when walking the switch statement, it's re-written into if-else statement. Without typecheck.EvalConst, the if condition "if 64 == 64" is passed as-is to the ssa generation pass. Because "64 == 64" is not a constant, the ssagen creates normal blocks for branching the results. This confuses the liveness analysis, because ~R0 is only live inside the if block. With typecheck.EvalConst, "64 == 64" is evaluated to "true", so ssagen can branch the result without emitting conditional blocks. Instead, the constant-fold can be re-written as: switch { case true: // Body } So it does not depend on the delay results check during inlining. Adding a test, which will fail when typecheck.EvalConst is removed, so we can do the cleanup without breaking things. Change-Id: I638730bb147140de84260653741431b807ff2f15 Reviewed-on: https://go-review.googlesource.com/c/go/+/484316 Reviewed-by: Keith Randall <khr@google.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Keith Randall <khr@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-04-14cmd/compile: constant-fold switches early in compilationKeith Randall
So that the inliner knows all the other cases are dead and doesn't accumulate any cost for them. The canonical case for this is switching on runtime.GOOS, which occurs several places in the stdlib. Fixes #50253 Change-Id: I44823aaebb6c1b03c9b0c12d10086db81954350f Reviewed-on: https://go-review.googlesource.com/c/go/+/399694 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Russ Cox <rsc@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org>
2022-03-21cmd/compile: fix panic with nested dead hidden closuresCuong Manh Le
CL 342350 fixed deadcode panic with dead hidden closures. However, a closure may contains nested dead hidden closures, so we need to mark them dead as well. Fixes #51839 Change-Id: Ib54581adfc1bdea60e74d733cd30fd8e783da983 Reviewed-on: https://go-review.googlesource.com/c/go/+/394079 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com>
2021-09-19cmd/compile: fix missing markHiddenClosureDead in deadcode passCuong Manh Le
CL 342350 fixed panic with dead hidden closures, by marking discarded hidden closure as dead, and won't compile them. However, the fix is incomplete. In case the "if" or "else" block end with panic or return statement: if true { return } # All nodes starts from here are dead the dead nodes must be processed with markHiddenClosureDead, but they are not, causing the compiler crashes. This CL adds that missing part. Fixes #48459 Change-Id: Ibdd10a61fc6459d139bbf4a66b0893b523ac6b67 Reviewed-on: https://go-review.googlesource.com/c/go/+/350695 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2021-08-16cmd/compile: fix panic with dead hidden closuresCuong Manh Le
Currently, for hidden closures, we always push them to compile queue during typechecking. If the hidden closure is discarded from the outer function body during deadcode, any desugaring phase after deadcode won't be applied to the closure. Thus, some un-expected OPs are passed to downstream passes, which they can't handle, the compiler goes boom! To fix this, we keep track of discarded hidden closures during deadcode pass, and won't compile them then. Fixes #47712 Change-Id: I078717d5d1f4f2fa39cbaf610cfffbb042e70ceb Reviewed-on: https://go-review.googlesource.com/c/go/+/342350 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2021-01-17[dev.regabi] cmd/compile: add ir.TailCallStmtMatthew Dempsky
This CL splits out ORETJMP as a new TailCallStmt node, separate from the other BranchStmt nodes. In doing so, this allows us to change it from identifying a function by *types.Sym to identifying one by directly pointing to the *ir.Func. While here, also rename the operation to OTAILCALL. Passes toolstash -cmp. Change-Id: I273e6ea5d92bf3005ae02fb59b3240a190a6cf1b Reviewed-on: https://go-review.googlesource.com/c/go/+/284227 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-02[dev.regabi] cmd/compile: remove Nodes.Set [generated]Matthew Dempsky
Just "=". It's cleaner. Passes toolstash -cmp. [git-generate] cd src/cmd/compile/internal/ir pkgs=$(go list . ../...) rf ' ex '"$(echo $pkgs)"' { var l Nodes var p *Nodes p.Set(l) -> *p = l } ex '"$(echo $pkgs)"' { var n InitNode var l Nodes *n.PtrInit() = l -> n.SetInit(l) } rm Nodes.Set ' Change-Id: Ic97219792243667146a02776553942ae1189ff7d Reviewed-on: https://go-review.googlesource.com/c/go/+/281002 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-02[dev.regabi] cmd/compile: remove {Ptr,Set}Init from Node interfaceMatthew Dempsky
This CL separates out PtrInit and SetInit into a new InitNode extension interface, and adds a new TakeInit helper function for taking and clearing the Init list (if any) from a Node. This allows removing miniNode.SetInit and miniNode.PtrInit, which in turn allow getting rid of immutableEmptyNodes, and will allow simplification of the Nodes API. It would be nice to get rid of the default Init method too, but there's way more code that expects to be able to call that at the moment, so that'll have to wait. Passes toolstash -cmp. Change-Id: Ia8c18fab9555b774376f7f43eeecfde4f07b5946 Reviewed-on: https://go-review.googlesource.com/c/go/+/281001 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
2021-01-01[dev.regabi] cmd/compile: reshuffle type-checking code [generated]Matthew Dempsky
This commit splits up typecheck.Package and moves the code elsewhere. The type-checking code is moved into noder, so that it can eventually be interleaved with the noding process. The non-type-checking code is moved back into package gc, so that it can be incorporated into appropriate compiler backend phases. While here, deadcode removal is moved into its own package. Passes toolstash -cmp. [git-generate] cd src/cmd/compile/internal/typecheck : Split into two functions. sed -i -e '/Phase 6/i}\n\nfunc postTypecheck() {' typecheck.go rf ' # Export needed identifiers. mv deadcode Deadcode mv loadsys InitRuntime mv declareUniverse DeclareUniverse mv dirtyAddrtaken DirtyAddrtaken mv computeAddrtaken ComputeAddrtaken mv incrementalAddrtaken IncrementalAddrtaken # Move into new package. mv Deadcode deadcodeslice deadcodeexpr deadcode.go mv deadcode.go cmd/compile/internal/deadcode # Move top-level type-checking code into noder. # Move DeclVars there too, now that nothing else uses it. mv DeclVars Package noder.go mv noder.go cmd/compile/internal/noder # Move non-type-checking code back into gc. mv postTypecheck main.go mv main.go cmd/compile/internal/gc ' cd ../deadcode rf ' # Destutter names. mv Deadcode Func mv deadcodeslice stmts mv deadcodeexpr expr ' cd ../noder rf ' # Move functions up, next to their related code. mv noder.go:/func Package/-1,$ \ noder.go:/makeSrcPosBase translates/-1 mv noder.go:/func DeclVars/-3,$ \ noder.go:/constState tracks/-1 ' cd ../gc rf ' # Inline postTypecheck code back into gc.Main. mv main.go:/func postTypecheck/+0,/AllImportedBodies/+1 \ main.go:/Build init task/-1 rm postTypecheck ' Change-Id: Ie5e992ece4a42204cce6aa98dd6eb52112d098c8 Reviewed-on: https://go-review.googlesource.com/c/go/+/280974 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>