import (
"fmt"
"go/constant"
+ "internal/goexperiment"
"sort"
"strconv"
base.Fatalf("CanInline no nname %+v", fn)
}
+ canInline := func(fn *ir.Func) { CanInline(fn, profile) }
+
+ var funcProps *inlheur.FuncProps
+ if goexperiment.NewInliner {
+ funcProps = inlheur.AnalyzeFunc(fn, canInline)
+ }
+
if base.Debug.DumpInlFuncProps != "" {
- inlheur.DumpFuncProps(fn, base.Debug.DumpInlFuncProps,
- func(fn *ir.Func) {
- CanInline(fn, profile)
- })
+ inlheur.DumpFuncProps(fn, base.Debug.DumpInlFuncProps, canInline)
}
var reason string // reason, if any, that the function was not inlined
CanDelayResults: canDelayResults(fn),
}
+ if goexperiment.NewInliner {
+ n.Func.Inl.Properties = funcProps.SerializeToString()
+ }
if base.Flag.LowerM > 1 {
fmt.Printf("%v: can inline %v with cost %d as: %v { %v }\n", ir.Line(fn), n, budget-visitor.budget, fn.Type(), ir.Nodes(fn.Body))
"cmd/compile/internal/ir"
"encoding/json"
"fmt"
+ "internal/goexperiment"
"io"
"os"
"path/filepath"
props *FuncProps
}
+var fpmap = map[*ir.Func]fnInlHeur{}
+
+func AnalyzeFunc(fn *ir.Func, canInline func(*ir.Func)) *FuncProps {
+ if fih, ok := fpmap[fn]; ok {
+ return fih.props
+ }
+ fp := computeFuncProps(fn, canInline)
+ file, line := fnFileLine(fn)
+ entry := fnInlHeur{
+ fname: fn.Sym().Name,
+ file: file,
+ line: line,
+ props: fp,
+ }
+ fpmap[fn] = entry
+ return fp
+}
+
// computeFuncProps examines the Go function 'fn' and computes for it
// a function "properties" object, to be used to drive inlining
// heuristics. See comments on the FuncProps type for more info.
if strings.HasPrefix(fn.Sym().Name, ".eq.") {
return
}
+ fih, ok := fpmap[fn]
+ if goexperiment.NewInliner {
+ // Props object should already be present.
+ if !ok {
+ panic("unexpected missing props")
+ }
+ } else {
+ AnalyzeFunc(fn, canInline)
+ fih = fpmap[fn]
+ }
if dumpBuffer == nil {
dumpBuffer = make(map[*ir.Func]fnInlHeur)
}
// so don't add them more than once.
return
}
- fp := computeFuncProps(fn, canInline)
- file, line := fnFileLine(fn)
- entry := fnInlHeur{
- fname: fn.Sym().Name,
- file: file,
- line: line,
- props: fp,
- }
- dumpBuffer[fn] = entry
+ dumpBuffer[fn] = fih
}
// dumpFilePreamble writes out a file-level preamble for a given
Dcl []*Name
HaveDcl bool // whether we've loaded Dcl
+ // Function properties, encoded as a string (these are used for
+ // making inlining decisions). See cmd/compile/internal/inline/inlheur.
+ Properties string
+
// CanDelayResults reports whether it's safe for the inliner to delay
// initializing the result parameters until immediately before the
// "return" statement.
import (
"internal/buildcfg"
+ "internal/goexperiment"
"internal/pkgbits"
"io"
if inl := name.Func.Inl; w.Bool(inl != nil) {
w.Len(int(inl.Cost))
w.Bool(inl.CanDelayResults)
+ if goexperiment.NewInliner {
+ w.String(inl.Properties)
+ }
}
w.Sync(pkgbits.SyncEOF)
"fmt"
"go/constant"
"internal/buildcfg"
+ "internal/goexperiment"
"internal/pkgbits"
"path/filepath"
"strings"
Cost: int32(r.Len()),
CanDelayResults: r.Bool(),
}
+ if goexperiment.NewInliner {
+ fn.Inl.Properties = r.String()
+ }
}
} else {
r.addBody(name.Func, method)