diff options
| author | Than McIntosh <thanm@google.com> | 2024-04-03 15:51:42 +0000 |
|---|---|---|
| committer | Than McIntosh <thanm@google.com> | 2024-04-09 16:41:23 +0000 |
| commit | 875332b8a26a159b5c6bd715e123fd6bb6086804 (patch) | |
| tree | 6104db351a3c6ab401cd6203febd001ca2cd0096 /src/cmd/compile/internal/base | |
| parent | de3a3c9ebc801c2cd3513a76676f1a26f600b51d (diff) | |
| download | go-875332b8a26a159b5c6bd715e123fd6bb6086804.tar.xz | |
cmd/compile/internal: merge stack slots for selected local auto vars
[This is a partial roll-forward of CL 553055, the main change here
is that the stack slot overlap operation is flagged off by default
(can be enabled by hand with -gcflags=-d=mergelocals=1) ]
Preliminary compiler support for merging/overlapping stack slots of
local variables whose access patterns are disjoint.
This patch includes changes in AllocFrame to do the actual
merging/overlapping based on information returned from a new
liveness.MergeLocals helper. The MergeLocals helper identifies
candidates by looking for sets of AUTO variables that either A) have
the same size and GC shape (if types contain pointers), or B) have the
same size (but potentially different types as long as those types have
no pointers). Variables must be greater than (3*types.PtrSize) in size
to be considered for merging.
After forming candidates, MergeLocals collects variables into "can be
overlapped" equivalence classes or partitions; this process is driven
by an additional liveness analysis pass. Ideally it would be nice to
move the existing stackmap liveness pass up before AllocFrame
and "widen" it to include merge candidates so that we can do just a
single liveness as opposed to two passes, however this may be difficult
given that the merge-locals liveness has to take into account
writes corresponding to dead stores.
This patch also required a change to the way ssa.OpVarDef pseudo-ops
are generated; prior to this point they would only be created for
variables whose type included pointers; if stack slot merging is
enabled then the ssagen code creates OpVarDef ops for all auto vars
that are merge candidates.
Note that some temporaries created late in the compilation process
(e.g. during ssa backend) are difficult to reason about, especially in
cases where we take the address of a temp and pass it to the runtime.
For the time being we mark most of the vars created post-ssagen as
"not a merge candidate".
Stack slot merging for locals/autos is enabled by default if "-N" is
not in effect, and can be disabled via "-gcflags=-d=mergelocals=0".
Fixmes/todos/restrictions:
- try lowering size restrictions
- re-evaluate the various skips that happen in SSA-created autotmps
Updates #62737.
Updates #65532.
Updates #65495.
Change-Id: Ifda26bc48cde5667de245c8a9671b3f0a30bb45d
Reviewed-on: https://go-review.googlesource.com/c/go/+/575415
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/cmd/compile/internal/base')
| -rw-r--r-- | src/cmd/compile/internal/base/debug.go | 4 | ||||
| -rw-r--r-- | src/cmd/compile/internal/base/flag.go | 3 | ||||
| -rw-r--r-- | src/cmd/compile/internal/base/hashdebug.go | 7 |
3 files changed, 11 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go index 420ad1305e..08ccef3065 100644 --- a/src/cmd/compile/internal/base/debug.go +++ b/src/cmd/compile/internal/base/debug.go @@ -41,6 +41,10 @@ type DebugFlags struct { LoopVarHash string `help:"for debugging changes in loop behavior. Overrides experiment and loopvar flag."` LocationLists int `help:"print information about DWARF location list creation"` MaxShapeLen int `help:"hash shape names longer than this threshold (default 500)" concurrent:"ok"` + MergeLocals int `help:"merge together non-interfering local stack slots" concurrent:"ok"` + MergeLocalsDumpFunc string `help:"dump specified func in merge locals"` + MergeLocalsHash string `help:"hash value for debugging stack slot merging of local variables" concurrent:"ok"` + MergeLocalsTrace int `help:"trace debug output for locals merging"` Nil int `help:"print information about nil checks"` NoOpenDefer int `help:"disable open-coded defers" concurrent:"ok"` NoRefName int `help:"do not include referenced symbol names in object file" concurrent:"ok"` diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go index 5b3c3ad8c6..0889c37b0d 100644 --- a/src/cmd/compile/internal/base/flag.go +++ b/src/cmd/compile/internal/base/flag.go @@ -260,6 +260,9 @@ func ParseFlags() { if Debug.PGOHash != "" { PGOHash = NewHashDebug("pgohash", Debug.PGOHash, nil) } + if Debug.MergeLocalsHash != "" { + MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil) + } if Flag.MSan && !platform.MSanSupported(buildcfg.GOOS, buildcfg.GOARCH) { log.Fatalf("%s/%s does not support -msan", buildcfg.GOOS, buildcfg.GOARCH) diff --git a/src/cmd/compile/internal/base/hashdebug.go b/src/cmd/compile/internal/base/hashdebug.go index 4e36c8d549..7a5cc42578 100644 --- a/src/cmd/compile/internal/base/hashdebug.go +++ b/src/cmd/compile/internal/base/hashdebug.go @@ -53,9 +53,10 @@ func (d *HashDebug) SetInlineSuffixOnly(b bool) *HashDebug { // The default compiler-debugging HashDebug, for "-d=gossahash=..." var hashDebug *HashDebug -var FmaHash *HashDebug // for debugging fused-multiply-add floating point changes -var LoopVarHash *HashDebug // for debugging shared/private loop variable changes -var PGOHash *HashDebug // for debugging PGO optimization decisions +var FmaHash *HashDebug // for debugging fused-multiply-add floating point changes +var LoopVarHash *HashDebug // for debugging shared/private loop variable changes +var PGOHash *HashDebug // for debugging PGO optimization decisions +var MergeLocalsHash *HashDebug // for debugging local stack slot merging changes // DebugHashMatchPkgFunc reports whether debug variable Gossahash // |
