diff --git a/src/cmd/compile/internal/base/debug.go b/src/cmd/compile/internal/base/debug.go index d42e11b2fa..7bcbcb3e2c 100644 --- a/src/cmd/compile/internal/base/debug.go +++ b/src/cmd/compile/internal/base/debug.go @@ -72,6 +72,8 @@ type DebugFlags struct { PGOInlineBudget int `help:"inline budget for hot functions" concurrent:"ok"` PGODevirtualize int `help:"enable profile-guided devirtualization; 0 to disable, 1 to enable interface devirtualization, 2 to enable function devirtualization" concurrent:"ok"` RangeFuncCheck int `help:"insert code to check behavior of range iterator functions" concurrent:"ok"` + VariableMakeHash string `help:"hash value for debugging stack allocation of variable-sized make results" concurrent:"ok"` + VariableMakeThreshold int `help:"threshold in bytes for possible stack allocation of variable-sized make results" concurrent:"ok"` WrapGlobalMapDbg int `help:"debug trace output for global map init wrapping"` WrapGlobalMapCtl int `help:"global map init wrap control (0 => default, 1 => off, 2 => stress mode, no size cutoff)"` ZeroCopy int `help:"enable zero-copy string->[]byte conversions" concurrent:"ok"` diff --git a/src/cmd/compile/internal/base/flag.go b/src/cmd/compile/internal/base/flag.go index 31ea8622b9..abf85c7e78 100644 --- a/src/cmd/compile/internal/base/flag.go +++ b/src/cmd/compile/internal/base/flag.go @@ -183,7 +183,8 @@ func ParseFlags() { Debug.InlStaticInit = 1 Debug.PGOInline = 1 Debug.PGODevirtualize = 2 - Debug.SyncFrames = -1 // disable sync markers by default + Debug.SyncFrames = -1 // disable sync markers by default + Debug.VariableMakeThreshold = 32 // 32 byte default for stack allocated make results Debug.ZeroCopy = 1 Debug.RangeFuncCheck = 1 Debug.MergeLocals = 1 @@ -270,6 +271,9 @@ func ParseFlags() { if Debug.MergeLocalsHash != "" { MergeLocalsHash = NewHashDebug("mergelocals", Debug.MergeLocalsHash, nil) } + if Debug.VariableMakeHash != "" { + VariableMakeHash = NewHashDebug("variablemake", Debug.VariableMakeHash, 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 7a5cc42578..c54b6e17aa 100644 --- a/src/cmd/compile/internal/base/hashdebug.go +++ b/src/cmd/compile/internal/base/hashdebug.go @@ -53,10 +53,11 @@ 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 MergeLocalsHash *HashDebug // for debugging local stack slot merging changes +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 +var VariableMakeHash *HashDebug // for debugging variable-sized make optimizations // DebugHashMatchPkgFunc reports whether debug variable Gossahash // diff --git a/src/cmd/compile/internal/walk/builtin.go b/src/cmd/compile/internal/walk/builtin.go index 018782211b..2e13daf879 100644 --- a/src/cmd/compile/internal/walk/builtin.go +++ b/src/cmd/compile/internal/walk/builtin.go @@ -568,7 +568,8 @@ func walkMakeSlice(n *ir.MakeExpr, init *ir.Nodes) ir.Node { // The conv is necessary in case n.Type is named. return walkExpr(typecheck.Expr(typecheck.Conv(s, n.Type())), init) } - tryStack = base.Flag.N == 0 + // Check that this optimization is enabled in general and for this node. + tryStack = base.Flag.N == 0 && base.VariableMakeHash.MatchPos(n.Pos(), nil) } // The final result is assigned to this variable. @@ -582,7 +583,7 @@ func walkMakeSlice(n *ir.MakeExpr, init *ir.Nodes) ir.Node { // } else { // slice = makeslice(elemType, len, cap) // } - const maxStackSize = 32 + maxStackSize := int64(base.Debug.VariableMakeThreshold) K := maxStackSize / t.Elem().Size() // rounds down if K > 0 { // skip if elem size is too big. nif := ir.NewIfStmt(base.Pos, ir.NewBinaryExpr(base.Pos, ir.OLE, typecheck.Conv(cap, types.Types[types.TUINT64]), ir.NewInt(base.Pos, K)), nil, nil)