]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/inline/inl.go
cmd/compile/internal/inline: tweak "returns inlinable func" heuristic
[gostls13.git] / src / cmd / compile / internal / inline / inl.go
index 7576b4371a784265bac489fced693a2c0455399e..992ae632e272c0dab23a4bab4770cca24a79a248 100644 (file)
@@ -30,7 +30,6 @@ import (
        "fmt"
        "go/constant"
        "internal/goexperiment"
-       "sort"
        "strconv"
 
        "cmd/compile/internal/base"
@@ -87,7 +86,7 @@ func pgoInlinePrologue(p *pgo.Profile, funcs []*ir.Func) {
                        base.Fatalf("invalid PGOInlineCDFThreshold, must be between 0 and 100")
                }
        }
-       var hotCallsites []pgo.NodeMapKey
+       var hotCallsites []pgo.NamedCallEdge
        inlineHotCallSiteThresholdPercent, hotCallsites = hotNodesFromCDF(p)
        if base.Debug.PGODebug > 0 {
                fmt.Printf("hot-callsite-thres-from-CDF=%v\n", inlineHotCallSiteThresholdPercent)
@@ -121,39 +120,19 @@ func pgoInlinePrologue(p *pgo.Profile, funcs []*ir.Func) {
 // (currently only used in debug prints) (in case of equal weights,
 // comparing with the threshold may not accurately reflect which nodes are
 // considiered hot).
-func hotNodesFromCDF(p *pgo.Profile) (float64, []pgo.NodeMapKey) {
-       nodes := make([]pgo.NodeMapKey, len(p.NodeMap))
-       i := 0
-       for n := range p.NodeMap {
-               nodes[i] = n
-               i++
-       }
-       sort.Slice(nodes, func(i, j int) bool {
-               ni, nj := nodes[i], nodes[j]
-               if wi, wj := p.NodeMap[ni].EWeight, p.NodeMap[nj].EWeight; wi != wj {
-                       return wi > wj // want larger weight first
-               }
-               // same weight, order by name/line number
-               if ni.CallerName != nj.CallerName {
-                       return ni.CallerName < nj.CallerName
-               }
-               if ni.CalleeName != nj.CalleeName {
-                       return ni.CalleeName < nj.CalleeName
-               }
-               return ni.CallSiteOffset < nj.CallSiteOffset
-       })
+func hotNodesFromCDF(p *pgo.Profile) (float64, []pgo.NamedCallEdge) {
        cum := int64(0)
-       for i, n := range nodes {
-               w := p.NodeMap[n].EWeight
+       for i, n := range p.NamedEdgeMap.ByWeight {
+               w := p.NamedEdgeMap.Weight[n]
                cum += w
-               if pgo.WeightInPercentage(cum, p.TotalEdgeWeight) > inlineCDFHotCallSiteThresholdPercent {
+               if pgo.WeightInPercentage(cum, p.TotalWeight) > inlineCDFHotCallSiteThresholdPercent {
                        // nodes[:i+1] to include the very last node that makes it to go over the threshold.
                        // (Say, if the CDF threshold is 50% and one hot node takes 60% of weight, we want to
                        // include that node instead of excluding it.)
-                       return pgo.WeightInPercentage(w, p.TotalEdgeWeight), nodes[:i+1]
+                       return pgo.WeightInPercentage(w, p.TotalWeight), p.NamedEdgeMap.ByWeight[:i+1]
                }
        }
-       return 0, nodes
+       return 0, p.NamedEdgeMap.ByWeight
 }
 
 // InlinePackage finds functions that can be inlined and clones them before walk expands them.
@@ -170,7 +149,7 @@ func InlinePackage(p *pgo.Profile) {
        garbageCollectUnreferencedHiddenClosures()
 
        if base.Debug.DumpInlFuncProps != "" {
-               inlheur.DumpFuncProps(nil, base.Debug.DumpInlFuncProps, nil)
+               inlheur.DumpFuncProps(nil, base.Debug.DumpInlFuncProps, nil, inlineMaxBudget)
        }
        if goexperiment.NewInliner {
                postProcessCallSites(p)
@@ -304,8 +283,8 @@ func CanInline(fn *ir.Func, profile *pgo.Profile) {
 
        var funcProps *inlheur.FuncProps
        if goexperiment.NewInliner || inlheur.UnitTesting() {
-               funcProps = inlheur.AnalyzeFunc(fn,
-                       func(fn *ir.Func) { CanInline(fn, profile) })
+               callCanInline := func(fn *ir.Func) { CanInline(fn, profile) }
+               funcProps = inlheur.AnalyzeFunc(fn, callCanInline, inlineMaxBudget)
        }
 
        var reason string // reason, if any, that the function was not inlined
@@ -823,7 +802,7 @@ func InlineCalls(fn *ir.Func, profile *pgo.Profile) {
        }
        if base.Debug.DumpInlFuncProps != "" && !fn.Wrapper() {
                inlheur.DumpFuncProps(fn, base.Debug.DumpInlFuncProps,
-                       func(fn *ir.Func) { CanInline(fn, profile) })
+                       func(fn *ir.Func) { CanInline(fn, profile) }, inlineMaxBudget)
        }
        savefn := ir.CurFunc
        ir.CurFunc = fn