...
1
2
3
4
5
6
7 package interleaved
8
9 import (
10 "cmd/compile/internal/base"
11 "cmd/compile/internal/devirtualize"
12 "cmd/compile/internal/inline"
13 "cmd/compile/internal/inline/inlheur"
14 "cmd/compile/internal/ir"
15 "cmd/compile/internal/pgo"
16 "cmd/compile/internal/typecheck"
17 "fmt"
18 )
19
20
21
22 func DevirtualizeAndInlinePackage(pkg *ir.Package, profile *pgo.Profile) {
23 if profile != nil && base.Debug.PGODevirtualize > 0 {
24
25 ir.VisitFuncsBottomUp(typecheck.Target.Funcs, func(list []*ir.Func, recursive bool) {
26 for _, fn := range list {
27 devirtualize.ProfileGuided(fn, profile)
28 }
29 })
30 ir.CurFunc = nil
31 }
32
33 if base.Flag.LowerL != 0 {
34 inlheur.SetupScoreAdjustments()
35 }
36
37 var inlProfile *pgo.Profile
38 if base.Debug.PGOInline != 0 {
39 inlProfile = profile
40 }
41 if inlProfile != nil {
42 inline.PGOInlinePrologue(inlProfile, pkg.Funcs)
43 }
44
45 ir.VisitFuncsBottomUp(pkg.Funcs, func(funcs []*ir.Func, recursive bool) {
46
47
48
49
50
51
52
53 inline.CanInlineSCC(funcs, recursive, inlProfile)
54
55
56
57 for _, fn := range funcs {
58 DevirtualizeAndInlineFunc(fn, inlProfile)
59 }
60 })
61
62 if base.Flag.LowerL != 0 {
63
64
65
66 inline.GarbageCollectUnreferencedHiddenClosures()
67
68 if base.Debug.DumpInlFuncProps != "" {
69 inlheur.DumpFuncProps(nil, base.Debug.DumpInlFuncProps)
70 }
71 if inlheur.Enabled() {
72 inline.PostProcessCallSites(inlProfile)
73 inlheur.TearDown()
74 }
75 }
76 }
77
78
79
80 func DevirtualizeAndInlineFunc(fn *ir.Func, profile *pgo.Profile) {
81 ir.WithFunc(fn, func() {
82 if base.Flag.LowerL != 0 {
83 if inlheur.Enabled() && !fn.Wrapper() {
84 inlheur.ScoreCalls(fn)
85 defer inlheur.ScoreCallsCleanup()
86 }
87 if base.Debug.DumpInlFuncProps != "" && !fn.Wrapper() {
88 inlheur.DumpFuncProps(fn, base.Debug.DumpInlFuncProps)
89 }
90 }
91
92 bigCaller := base.Flag.LowerL != 0 && inline.IsBigFunc(fn)
93 if bigCaller && base.Flag.LowerM > 1 {
94 fmt.Printf("%v: function %v considered 'big'; reducing max cost of inlinees\n", ir.Line(fn), fn)
95 }
96
97
98 var inlCalls []*ir.InlinedCallExpr
99 var edit func(ir.Node) ir.Node
100 edit = func(n ir.Node) ir.Node {
101 switch n := n.(type) {
102 case *ir.TailCallStmt:
103 n.Call.NoInline = true
104 }
105
106 ir.EditChildren(n, edit)
107
108 if call, ok := n.(*ir.CallExpr); ok {
109 devirtualize.StaticCall(call)
110
111 if inlCall := inline.TryInlineCall(fn, call, bigCaller, profile); inlCall != nil {
112 inlCalls = append(inlCalls, inlCall)
113 n = inlCall
114 }
115 }
116
117 return n
118 }
119 ir.EditChildren(fn, edit)
120
121
122
123
124
125
126 for len(inlCalls) > 0 {
127 call := inlCalls[0]
128 inlCalls = inlCalls[1:]
129 ir.EditChildren(call, edit)
130 }
131 })
132 }
133
View as plain text