)
var (
- // List of all hot ndes.
+ // List of all hot nodes.
+ // TODO(prattmic): Make this non-global.
candHotNodeMap = make(map[*pgo.IRNode]struct{})
- // List of all hot call sites.
+ // List of all hot call sites. CallSiteInfo.Callee is always nil.
+ // TODO(prattmic): Make this non-global.
candHotEdgeMap = make(map[pgo.CallSiteInfo]struct{})
- // List of inlined call sites.
+ // List of inlined call sites. CallSiteInfo.Callee is always nil.
+ // TODO(prattmic): Make this non-global.
inlinedCallSites = make(map[pgo.CallSiteInfo]struct{})
// Threshold in percentage for hot function inlining.
if e.Weight != 0 {
edgeweightpercent := pgo.WeightInPercentage(e.Weight, p.TotalEdgeWeight)
if edgeweightpercent > inlineHotCallSiteThresholdPercent {
- csi := pgo.CallSiteInfo{Line: e.CallSite, Caller: n.AST, Callee: e.Dst.AST}
+ csi := pgo.CallSiteInfo{Line: e.CallSite, Caller: n.AST}
if _, ok := candHotEdgeMap[csi]; !ok {
candHotEdgeMap[csi] = struct{}{}
}
base.Fatalf("CanInline no nname %+v", fn)
}
- // Initialize an empty list of hot callsites for this caller.
- pgo.ListOfHotCallSites = make(map[pgo.CallSiteInfo]struct{})
-
var reason string // reason, if any, that the function was not inlined
if base.Flag.LowerM > 1 || logopt.Enabled() {
defer func() {
}
}
- // Determine if the callee edge is a for hot callee or not.
+ // Determine if the callee edge is for an inlinable hot callee or not.
if v.profile != nil && v.curFunc != nil {
if fn := inlCallee(n.X, v.profile); fn != nil && typecheck.HaveInlineBody(fn) {
line := int(base.Ctxt.InnermostPos(n.Pos()).RelLine())
- csi := pgo.CallSiteInfo{Line: line, Caller: v.curFunc, Callee: fn}
+ csi := pgo.CallSiteInfo{Line: line, Caller: v.curFunc}
if _, o := candHotEdgeMap[csi]; o {
- pgo.ListOfHotCallSites[pgo.CallSiteInfo{Line: line, Caller: v.curFunc}] = struct{}{}
if base.Debug.PGOInline > 0 {
fmt.Printf("hot-callsite identified at line=%v for func=%v\n", ir.Line(n), ir.PkgFuncName(v.curFunc))
}
// If the callsite is hot and it is under the inlineHotMaxBudget budget, then try to inline it, or else bail.
line := int(base.Ctxt.InnermostPos(n.Pos()).RelLine())
csi := pgo.CallSiteInfo{Line: line, Caller: ir.CurFunc}
- if _, ok := pgo.ListOfHotCallSites[csi]; ok {
+ if _, ok := candHotEdgeMap[csi]; ok {
if fn.Inl.Cost > inlineHotMaxBudget {
if logopt.Enabled() {
logopt.LogOpt(n.Pos(), "cannotInlineCall", "inline", ir.FuncName(ir.CurFunc),
WeightedCG *IRGraph
}
-var (
- // Per-caller data structure to track the list of hot call sites. This
- // gets rewritten every caller leaving it to GC for cleanup.
- //
- // TODO(prattmic): Make this non-global. Use of this seems to assume
- // inline.CanInline is called immediately before inline.InlineCalls,
- // which isn't necessarily true?
- ListOfHotCallSites = make(map[CallSiteInfo]struct{})
-)
-
// New generates a profile-graph from the profile.
func New(profileFile string) *Profile {
f, err := os.Open(profileFile)
fmt.Printf("}\n")
}
-// RedirectEdges deletes and redirects out-edges from node cur based on inlining information via inlinedCallSites.
+// RedirectEdges deletes and redirects out-edges from node cur based on
+// inlining information via inlinedCallSites.
+//
+// CallSiteInfo.Callee must be nil.
func (p *Profile) RedirectEdges(cur *IRNode, inlinedCallSites map[CallSiteInfo]struct{}) {
g := p.WeightedCG