mirror of
https://github.com/golang/go
synced 2024-11-07 09:36:11 -07:00
cmd/compile: tighten for huge functions in -N mode
Currently, in -N mode we skip the tighten pass. However, for very large functions, many values live across blocks can cause pathological behavior in the register allocator, which could use a huge amount of memory or cause the program to hang. For functions that large, debugging using a debugger is unlikely to be very useful (the function is probably generated anyway). So we do a little optimization to make fewer values live across blocks and make it easier for the compiler. Fixes #52180. Change-Id: I355fe31bb87ea5d0870bb52dd06405dd5d791dab Reviewed-on: https://go-review.googlesource.com/c/go/+/475339 Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Cherry Mui <cherryyz@google.com> Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org>
This commit is contained in:
parent
7f38067acb
commit
40a6e2dae5
@ -496,7 +496,7 @@ var passes = [...]pass{
|
||||
{name: "checkLower", fn: checkLower, required: true},
|
||||
{name: "late phielim", fn: phielim},
|
||||
{name: "late copyelim", fn: copyelim},
|
||||
{name: "tighten", fn: tighten}, // move values closer to their uses
|
||||
{name: "tighten", fn: tighten, required: true}, // move values closer to their uses
|
||||
{name: "late deadcode", fn: deadcode},
|
||||
{name: "critical", fn: critical, required: true}, // remove critical edges
|
||||
{name: "phi tighten", fn: phiTighten}, // place rematerializable phi args near uses to reduce value lifetimes
|
||||
|
@ -4,12 +4,21 @@
|
||||
|
||||
package ssa
|
||||
|
||||
import "cmd/compile/internal/base"
|
||||
|
||||
// tighten moves Values closer to the Blocks in which they are used.
|
||||
// This can reduce the amount of register spilling required,
|
||||
// if it doesn't also create more live values.
|
||||
// A Value can be moved to any block that
|
||||
// dominates all blocks in which it is used.
|
||||
func tighten(f *Func) {
|
||||
if base.Flag.N != 0 && len(f.Blocks) < 10000 {
|
||||
// Skip the optimization in -N mode, except for huge functions.
|
||||
// Too many values live across blocks can cause pathological
|
||||
// behavior in the register allocator (see issue 52180).
|
||||
return
|
||||
}
|
||||
|
||||
canMove := f.Cache.allocBoolSlice(f.NumValues())
|
||||
defer f.Cache.freeBoolSlice(canMove)
|
||||
for _, b := range f.Blocks {
|
||||
|
Loading…
Reference in New Issue
Block a user