Skip to content

Commit e4f855d

Browse files
author
Raj Barik
committed
add dit print
1 parent 31a3026 commit e4f855d

File tree

2 files changed

+121
-41
lines changed

2 files changed

+121
-41
lines changed

src/cmd/compile/internal/inline/inl.go

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ import (
4444

4545
// Inlining budget parameters, gathered in one place
4646
const (
47-
inlineMaxBudget = 80
48-
inlineExtraAppendCost = 0
47+
inlineMaxBudget = 80
48+
inlineExtraAppendCost = 0
4949
// default is to inline if there's at most one call. -l=4 overrides this by using 1 instead.
5050
inlineExtraCallCost = 57 // 57 was benchmarked to provided most benefit with no bad surprises; see https://github.com/golang/go/issues/19348#issuecomment-439370742
5151
inlineExtraPanicCost = 1 // do not penalize inlining panics.
@@ -73,18 +73,6 @@ var (
7373
inlineHotCalleeMaxBudget int32 = 160
7474
)
7575

76-
// weightInPercentage converts profile weights to a percentage.
77-
func weightInPercentage(value int64, total int64) float64 {
78-
var ratio float64
79-
// percentage is computed at the (weight/totalweights) * 100
80-
// e.g. if edge weight is 30 and the sum of all the edges weight is 126
81-
// the percentage will be 23.8%
82-
if total != 0 {
83-
ratio = (float64(value) / float64(total)) * 100
84-
}
85-
return ratio
86-
}
87-
8876
// InlinePrologue records the hot callsites from ir-graph.
8977
func InlinePrologue() {
9078
if s, err := strconv.ParseFloat(base.Flag.InlineHotThreshold, 64); err == nil {
@@ -102,32 +90,37 @@ func InlinePrologue() {
10290
for _, f := range list {
10391
name := ir.PkgFuncName(f)
10492
if n, ok := pgo.WeightedCG.IRNodes[name]; ok {
105-
nodeweight := weightInPercentage(n.Flat, pgo.GlobalTotalNodeWeight)
106-
93+
nodeweight := pgo.WeightInPercentage(n.Flat, pgo.GlobalTotalNodeWeight)
94+
if nodeweight > inlineHotThresholdPercent {
95+
n.HotNode = true
96+
if base.Flag.LowerM > 1 {
97+
fmt.Printf("hot-node=%v\n", name)
98+
}
99+
}
107100
for _, e := range pgo.WeightedCG.OutEdges[n] {
108101
if e.Weight != 0 {
109-
weightpercent := weightInPercentage(e.Weight, pgo.GlobalTotalEdgeWeight)
102+
weightpercent := pgo.WeightInPercentage(e.Weight, pgo.GlobalTotalEdgeWeight)
110103
if weightpercent > inlineHotThresholdPercent {
111104
splits := strings.Split(e.CallSite, ":")
112105
line2, _ := strconv.ParseInt(splits[len(splits)-2], 0, 64)
113106
lineno := fmt.Sprintf("%v", line2)
114107
canonicalName := ir.PkgFuncName(n.AST) + "-" + lineno + "-" + ir.PkgFuncName(e.Dst.AST)
115-
candHotEdgeMap[canonicalName] = struct{}{}
116-
if base.Flag.LowerM != 0 {
117-
fmt.Printf("hot-inline cand=%v\n", canonicalName)
108+
if _, ok := candHotEdgeMap[canonicalName]; !ok {
109+
candHotEdgeMap[canonicalName] = struct{}{}
110+
if base.Flag.LowerM > 1 {
111+
fmt.Printf("hot-inline cand=%v\n", canonicalName)
112+
}
118113
}
119114
}
120115
}
121116
}
122-
if nodeweight > inlineHotThresholdPercent {
123-
n.HotNode = true
124-
if base.Flag.LowerM != 0 {
125-
fmt.Printf("hot-node=%v\n", name)
126-
}
127-
}
128117
}
129118
}
130119
})
120+
if base.Flag.LowerM > 1 {
121+
fmt.Printf("hot-cg before inline in dot:")
122+
pgo.PrintWeightedCallGraphDOT(inlineHotThresholdPercent)
123+
}
131124
}
132125

133126
// InlineEpilogue updates IRGraph after inlining.
@@ -140,6 +133,10 @@ func InlineEpilogue() {
140133
}
141134
}
142135
})
136+
if base.Flag.LowerM > 1 {
137+
fmt.Printf("hot-cg after inline in dot:")
138+
pgo.PrintWeightedCallGraphDOT(inlineHotThresholdPercent)
139+
}
143140
}
144141

145142
// InlinePackage finds functions that can be inlined and clones them before walk expands them.
@@ -349,19 +346,15 @@ func (v *hairyVisitor) tooHairy(fn *ir.Func) bool {
349346
}
350347
if v.budget < 0 {
351348
if pgo.WeightedCG != nil {
352-
// If the cost of hot function is greater than inlineHotCalleeMaxBudget,
353-
// the inliner won't inline this function.
354-
if inlineMaxBudget-v.budget < inlineHotCalleeMaxBudget {
355-
// In some cases, there is no hot calling edges in the function.
356-
// However, if the function is hot function, it is still inline
357-
// candidate.
358-
if n, ok := pgo.WeightedCG.IRNodes[ir.PkgFuncName(fn)]; ok {
359-
if n.HotNode == true {
360-
if base.Flag.LowerM != 0 {
361-
fmt.Printf("hot-node enabled increased budget for func=%v\n", ir.PkgFuncName(fn))
362-
}
363-
return false
349+
// Find the existing node in IRGraph.
350+
if n, ok := pgo.WeightedCG.IRNodes[ir.PkgFuncName(fn)]; ok {
351+
// If the cost of hot function is greater than inlineHotCalleeMaxBudget,
352+
// the inliner won't inline this function.
353+
if inlineMaxBudget-v.budget < inlineHotCalleeMaxBudget && n.HotNode == true {
354+
if base.Flag.LowerM > 1 {
355+
fmt.Printf("hot-node enabled increased budget for func=%v\n", ir.PkgFuncName(fn))
364356
}
357+
return false
365358
}
366359
}
367360
}
@@ -437,6 +430,9 @@ func (v *hairyVisitor) doNode(n ir.Node) bool {
437430
linenum := fmt.Sprintf("%v", l)
438431
canonicalName := ir.PkgFuncName(ir.CurFunc) + "-" + linenum + "-" + ir.PkgFuncName(fn)
439432
if _, o := candHotEdgeMap[canonicalName]; o {
433+
if base.Flag.LowerM > 1 {
434+
fmt.Printf("hot-callsite identified at line=%v for func=%v\n", ir.Line(n), ir.PkgFuncName(ir.CurFunc))
435+
}
440436
listOfHotCallSites[pgo.CallSiteInfo{ir.Line(n), ir.CurFunc}] = struct{}{}
441437
}
442438
}
@@ -848,9 +844,13 @@ func mkinlcall(n *ir.CallExpr, fn *ir.Func, maxCost int32, inlCalls *[]*ir.Inlin
848844

849845
// If the callsite is hot and it is under the inlineHotCalleeMaxBudget budget, then inline it, or else bail.
850846
if _, ok := listOfHotCallSites[pgo.CallSiteInfo{ir.Line(n), ir.CurFunc}]; ok {
847+
851848
if fn.Inl.Cost > inlineHotCalleeMaxBudget {
852849
return n
853850
}
851+
if base.Flag.LowerM > 1 {
852+
fmt.Printf("hot-budget check allows inlining at %v\n", ir.Line(n))
853+
}
854854
} else {
855855
return n
856856
}

src/cmd/compile/internal/pgo/irgraph.go

Lines changed: 83 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ func (g *IRGraph) addEdge(node1 *IRNode, f *ir.Func, n *ir.Node, name string, li
271271
if weights, ok := GlobalNodeMap[nodeinfo]; ok {
272272
node1.Flat = weights.NWeight
273273
node1.Cum = weights.NTotalWeight
274-
if base.Flag.LowerM > 3 {
274+
if base.Flag.LowerM > 4 {
275275
fmt.Printf("addEdge with Src=%v Dst=%v, CallSite=%v, weight=%v\n", ir.PkgFuncName(node1.AST), ir.PkgFuncName(g.IRNodes[name2].AST), line, weights.EWeight)
276276
}
277277
// Add edge in the IRGraph from caller to callee [callee is an interface type here which can have multiple targets].
@@ -284,14 +284,14 @@ func (g *IRGraph) addEdge(node1 *IRNode, f *ir.Func, n *ir.Node, name string, li
284284
if weights, ok := GlobalNodeMap[nodeinfo]; ok {
285285
node1.Flat = weights.NWeight
286286
node1.Cum = weights.NTotalWeight
287-
if base.Flag.LowerM > 3 {
287+
if base.Flag.LowerM > 4 {
288288
fmt.Printf("addEdge with Src=%v Dst=%v, CallSite=%v, weight=%v\n", ir.PkgFuncName(node1.AST), ir.PkgFuncName(g.IRNodes[name2].AST), line, 0)
289289
}
290290
info := &IREdge{Src: node1, Dst: g.IRNodes[name2], DstNode: n, Weight: 0, CallSite: line}
291291
g.OutEdges[node1] = append(g.OutEdges[node1], info)
292292
g.InEdges[g.IRNodes[name2]] = append(g.InEdges[g.IRNodes[name2]], info)
293293
} else {
294-
if base.Flag.LowerM > 3 {
294+
if base.Flag.LowerM > 4 {
295295
fmt.Printf("addEdge with Src=%v Dst=%v, CallSite=%v, weight=%v\n", ir.PkgFuncName(node1.AST), ir.PkgFuncName(g.IRNodes[name2].AST), line, 0)
296296
}
297297
info := &IREdge{Src: node1, Dst: g.IRNodes[name2], DstNode: n, Weight: 0, CallSite: line}
@@ -328,6 +328,86 @@ func (g *IRGraph) createIRGraphEdge(fn *ir.Func, node1 *IRNode, name string) {
328328
doNode(fn)
329329
}
330330

331+
// WeightInPercentage converts profile weights to a percentage.
332+
func WeightInPercentage(value int64, total int64) float64 {
333+
var ratio float64
334+
// percentage is computed at the (weight/totalweights) * 100
335+
// e.g. if edge weight is 30 and the sum of all the edges weight is 126
336+
// the percentage will be 23.8%
337+
if total != 0 {
338+
ratio = (float64(value) / float64(total)) * 100
339+
}
340+
return ratio
341+
}
342+
343+
// PrintWeightedCallGraphDOT prints IRGraph in DOT format..
344+
func PrintWeightedCallGraphDOT(threshold float64) {
345+
fmt.Printf("digraph G {\n")
346+
fmt.Printf("forcelabels=true;\n")
347+
348+
// List of functions in this package.
349+
funcs := make(map[string]struct{})
350+
ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
351+
for _, f := range list {
352+
name := ir.PkgFuncName(f)
353+
funcs[name] = struct{}{}
354+
}
355+
})
356+
357+
// Determine nodes of DOT.
358+
nodes := make(map[string]*ir.Func)
359+
for name, _ := range funcs {
360+
if n, ok := WeightedCG.IRNodes[name]; ok {
361+
nodeweight := WeightInPercentage(n.Flat, GlobalTotalNodeWeight)
362+
for _, e := range WeightedCG.OutEdges[n] {
363+
if e.Weight != 0 {
364+
p := WeightInPercentage(e.Weight, GlobalTotalEdgeWeight)
365+
if p > threshold {
366+
nodes[ir.PkgFuncName(e.Src.AST)] = e.Src.AST
367+
nodes[ir.PkgFuncName(e.Dst.AST)] = e.Dst.AST
368+
}
369+
}
370+
}
371+
if nodeweight > threshold {
372+
nodes[ir.PkgFuncName(n.AST)] = n.AST
373+
}
374+
}
375+
}
376+
377+
// Print nodes.
378+
for name, ast := range nodes {
379+
if n, ok := WeightedCG.IRNodes[name]; ok {
380+
nodeweight := WeightInPercentage(n.Flat, GlobalTotalNodeWeight)
381+
if ast.Inl != nil {
382+
fmt.Printf("\"%v\" [label=\"%v,freq=%.2f,inl_cost=%d\"];\n", ir.PkgFuncName(ast), ir.PkgFuncName(ast), nodeweight, ast.Inl.Cost)
383+
} else {
384+
fmt.Printf("\"%v\" [label=\"%v,freq=%.2f\"];\n", ir.PkgFuncName(ast), ir.PkgFuncName(ast), nodeweight)
385+
}
386+
}
387+
}
388+
// Print edges.
389+
ir.VisitFuncsBottomUp(typecheck.Target.Decls, func(list []*ir.Func, recursive bool) {
390+
for _, f := range list {
391+
name := ir.PkgFuncName(f)
392+
if n, ok := WeightedCG.IRNodes[name]; ok {
393+
for _, e := range WeightedCG.OutEdges[n] {
394+
if e.Weight != 0 {
395+
p := WeightInPercentage(e.Weight, GlobalTotalEdgeWeight)
396+
if p > threshold {
397+
fmt.Printf("edge [color=red, style=solid];\n")
398+
} else {
399+
fmt.Printf("edge [color=black, style=solid];\n")
400+
}
401+
402+
fmt.Printf("\"%v\" -> \"%v\" [label=\"%.2f\"];\n", ir.PkgFuncName(n.AST), ir.PkgFuncName(e.Dst.AST), p)
403+
}
404+
}
405+
}
406+
}
407+
})
408+
fmt.Printf("}\n")
409+
}
410+
331411
// redirectEdges deletes the cur node out-edges and redirect them so now these edges are the parent node out-edges.
332412
func redirectEdges(g *IRGraph, parent *IRNode, cur *IRNode) {
333413
for _, outEdge := range g.OutEdges[cur] {

0 commit comments

Comments
 (0)