Skip to content

cmd/compile: reduce allocations by reusing SSA scratch state #80095

Description

@siutsin

Overall

Seven changes reuse temporary cmd/compile scratch state through the per-worker ssa.Cache or the generated SSA allocator pools.

The stack is split by compiler pass. CL 792805 covers prove scratch reuse, and CL 793640 covers SCCP scratch map reuse.

CL rows are commit-alone isolated allocs/op geomeans. CL 792800 through CL 792803 were measured on linux/amd64 at base fd6f414c65e6; CL 792804, CL 792805, CL 793640, and the full stack were measured on linux/amd64 at base 40f0f8125549.

CL Area Geomean allocs/op
CL 792800 deadcode inline-index set -0.29%
CL 792801 slot canonicalizer -0.19%
CL 792802 edgeState value slices -1.39%
CL 792803 per-block defvars maps -0.82%
CL 792804 regalloc scratch buffers -0.73%
CL 792805 prove scratch -0.50%
CL 793640 SCCP scratch maps -0.34%
Full stack combined -4.28%

Full stack compilebench -alloc, linux/amd64, -count 20, -compileflags=-c=8, base 40f0f8125549:

Benchmark allocs/op vs master
Template 752.8k -4.36%
Unicode 547.4k -0.63%
GoTypes 4.522M -6.37%
Compiler 686.7k -2.54%
SSA 42.89M -6.03%
Flate 754.5k -4.37%
GoParser 723.7k -4.59%
Reflect 2.139M -4.62%
Tar 857.6k -4.69%
XML 1.005M -4.47%
geomean 1.494M -4.28%

The same full-stack run reports B/op geomean -5.27%. A companion linux/amd64 wall-time and IPC study on the revised tail reports, with GOGC=off, instructions -0.52%, cycles -0.92%, and wall -0.83% for -c=1; the wall win strengthens to -2.27% at -c=16.

Validation:

  • Generated code: toolstash -cmp over std reported no diffs.
  • Full suite: cd src && ./all.bash passes.

CL 792800: cmd/compile: reuse deadcode liveInlIdx set across functions

Reuses liveValues' inline-index set in ssa.Cache. Keys are ints, so no *Value or *Block is retained across functions.

Metrics

Commit-alone compilebench -alloc, base fd6f414c65e6:

Benchmark allocs/op vs master
Template 784.9k -0.29%
Unicode 550.8k -0.01%
GoTypes 4.817M -0.28%
Compiler 698.8k -0.30%
SSA 45.53M -0.21%
Flate 786.9k -0.25%
GoParser 755.6k -0.39%
Reflect 2.232M -0.47%
Tar 896.6k -0.35%
XML 1.049M -0.33%
geomean 1.555M -0.29%

CL 792801: cmd/compile: reuse slot canonicalizer across functions

Reuses PopulateABIInRegArgOps' slot canonicalizer through debugState on ssa.Cache. Reset clears LocalSlot values that can hold IR/type pointers.

Metrics

Commit-alone compilebench -alloc, base fd6f414c65e6:

Benchmark allocs/op vs master
Template 785.2k -0.24%
Unicode 550.7k -0.02%
GoTypes 4.819M -0.22%
Compiler 700.1k -0.11%
SSA 45.56M -0.15%
Flate 787.3k -0.20%
GoParser 757.1k -0.19%
Reflect 2.237M -0.28%
Tar 897.3k -0.28%
XML 1.050M -0.22%
geomean 1.557M -0.19%

CL 792802: cmd/compile: reuse edgeState value-slice backing arrays across edges

Reuses edgeState per-vid []*Value backing arrays while shuffling registers. Arrays are returned from the map once, avoiding shared live backing arrays.

Metrics

Commit-alone compilebench -alloc, base fd6f414c65e6:

Benchmark allocs/op vs master
Template 777.6k -1.21%
Unicode 549.1k -0.31%
GoTypes 4.715M -2.37%
Compiler 696.0k -0.70%
SSA 44.66M -2.13%
Flate 777.0k -1.50%
GoParser 745.3k -1.74%
Reflect 2.218M -1.09%
Tar 889.1k -1.18%
XML 1.035M -1.64%
geomean 1.538M -1.39%

CL 792803: cmd/compile: reuse per-block defvars maps across functions

Reuses ssagen startBlock defvars maps through a per-worker free list. Each map is cleared before reuse, so no ir.Node or *Value is retained.

Metrics

Commit-alone compilebench -alloc, base fd6f414c65e6:

Benchmark allocs/op vs master
Template 780.0k -0.90%
Unicode 550.5k -0.06%
GoTypes 4.774M -1.15%
Compiler 697.7k -0.45%
SSA 44.98M -1.42%
Flate 781.8k -0.90%
GoParser 752.9k -0.73%
Reflect 2.223M -0.91%
Tar 891.2k -0.95%
XML 1.045M -0.74%
geomean 1.547M -0.82%

CL 792804: cmd/compile: reuse regalloc scratch buffers across functions

Reuses regalloc register-state, block-state, spill-live, and live/desired scratch buffers. Pointer-bearing register state and outer block/spill slice headers use the generated SSA allocator pools; pointer-free live/desired scratch stays on ssa.Cache.

Metrics

Commit-alone compilebench -alloc, base 40f0f8125549:

Benchmark allocs/op vs master
Template 781.6k -0.70%
Unicode 550.7k -0.04%
GoTypes 4.760M -1.45%
Compiler 702.6k -0.27%
SSA 45.00M -1.43%
Flate 785.0k -0.50%
GoParser 753.7k -0.64%
Reflect 2.226M -0.77%
Tar 892.6k -0.80%
XML 1.045M -0.71%
geomean 1.549M -0.73%

CL 792805: cmd/compile: reuse prove scratch across functions

Reuses prove's orderings map and undo stacks. The pointer-bearing map is cleared before reuse, and the undo stacks use generated SSA allocator pools and pooled append helpers.

Metrics

Commit-alone compilebench -alloc, base 40f0f8125549:

Benchmark allocs/op vs master
Template 782.3k -0.62%
Unicode 550.3k -0.11%
GoTypes 4.806M -0.50%
Compiler 701.8k -0.40%
SSA 45.47M -0.40%
Flate 784.4k -0.58%
GoParser 754.4k -0.54%
Reflect 2.228M -0.66%
Tar 893.8k -0.66%
XML 1.047M -0.49%
geomean 1.553M -0.50%

CL 793640: cmd/compile: reuse sccp scratch maps across functions

Reuses SCCP's visited, def-use, def-block, and lattice maps through ssa.Cache. These maps are pointer-bearing and the cache reuses *Value and *Block addresses across functions, so SCCP clears all four maps on every return path before reuse.

Metrics

Commit-alone compilebench -alloc, base 40f0f8125549:

Benchmark allocs/op vs master
Template 783.9k -0.41%
Unicode 550.6k -0.06%
GoTypes 4.813M -0.37%
Compiler 702.8k -0.25%
SSA 45.52M -0.28%
Flate 785.6k -0.42%
GoParser 755.7k -0.38%
Reflect 2.233M -0.44%
Tar 895.9k -0.43%
XML 1.049M -0.34%
geomean 1.555M -0.34%

Metadata

Metadata

Assignees

Labels

FixPendingIssues that have a fix which has not yet been reviewed or submitted.Performancecompiler/runtimeIssues related to the Go compiler and/or runtime.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
In Progress

Relationships

None yet

Development

No branches or pull requests

Issue actions