1
2
3
4
5 package inlheur
6
7 import (
8 "cmd/compile/internal/base"
9 "cmd/compile/internal/ir"
10 "cmd/internal/src"
11 "fmt"
12 "io"
13 "path/filepath"
14 "sort"
15 "strings"
16 )
17
18
19
20
21
22
23
24
25
26
27 type CallSite struct {
28 Callee *ir.Func
29 Call *ir.CallExpr
30 parent *CallSite
31 Assign ir.Node
32 Flags CSPropBits
33
34 ArgProps []ActualExprPropBits
35 Score int
36 ScoreMask scoreAdjustTyp
37 ID uint
38 aux uint8
39 }
40
41
42
43
44
45
46 type CallSiteTab map[*ir.CallExpr]*CallSite
47
48
49
50 type ActualExprPropBits uint8
51
52 const (
53 ActualExprConstant ActualExprPropBits = 1 << iota
54 ActualExprIsConcreteConvIface
55 ActualExprIsFunc
56 ActualExprIsInlinableFunc
57 )
58
59 type CSPropBits uint32
60
61 const (
62 CallSiteInLoop CSPropBits = 1 << iota
63 CallSiteOnPanicPath
64 CallSiteInInitFunc
65 )
66
67 type csAuxBits uint8
68
69 const (
70 csAuxInlined = 1 << iota
71 )
72
73
74
75
76 type encodedCallSiteTab map[string]propsAndScore
77
78 type propsAndScore struct {
79 props CSPropBits
80 score int
81 mask scoreAdjustTyp
82 }
83
84 func (pas propsAndScore) String() string {
85 return fmt.Sprintf("P=%s|S=%d|M=%s", pas.props.String(),
86 pas.score, pas.mask.String())
87 }
88
89 func (cst CallSiteTab) merge(other CallSiteTab) error {
90 for k, v := range other {
91 if prev, ok := cst[k]; ok {
92 return fmt.Errorf("internal error: collision during call site table merge, fn=%s callsite=%s", prev.Callee.Sym().Name, fmtFullPos(prev.Call.Pos()))
93 }
94 cst[k] = v
95 }
96 return nil
97 }
98
99 func fmtFullPos(p src.XPos) string {
100 var sb strings.Builder
101 sep := ""
102 base.Ctxt.AllPos(p, func(pos src.Pos) {
103 fmt.Fprintf(&sb, sep)
104 sep = "|"
105 file := filepath.Base(pos.Filename())
106 fmt.Fprintf(&sb, "%s:%d:%d", file, pos.Line(), pos.Col())
107 })
108 return sb.String()
109 }
110
111 func EncodeCallSiteKey(cs *CallSite) string {
112 var sb strings.Builder
113
114 sb.WriteString(fmtFullPos(cs.Call.Pos()))
115 fmt.Fprintf(&sb, "|%d", cs.ID)
116 return sb.String()
117 }
118
119 func buildEncodedCallSiteTab(tab CallSiteTab) encodedCallSiteTab {
120 r := make(encodedCallSiteTab)
121 for _, cs := range tab {
122 k := EncodeCallSiteKey(cs)
123 r[k] = propsAndScore{
124 props: cs.Flags,
125 score: cs.Score,
126 mask: cs.ScoreMask,
127 }
128 }
129 return r
130 }
131
132
133
134
135 func dumpCallSiteComments(w io.Writer, tab CallSiteTab, ecst encodedCallSiteTab) {
136 if ecst == nil {
137 ecst = buildEncodedCallSiteTab(tab)
138 }
139 tags := make([]string, 0, len(ecst))
140 for k := range ecst {
141 tags = append(tags, k)
142 }
143 sort.Strings(tags)
144 for _, s := range tags {
145 v := ecst[s]
146 fmt.Fprintf(w, "// callsite: %s flagstr %q flagval %d score %d mask %d maskstr %q\n", s, v.props.String(), v.props, v.score, v.mask, v.mask.String())
147 }
148 fmt.Fprintf(w, "// %s\n", csDelimiter)
149 }
150
View as plain text