@@ -23,7 +23,7 @@ const profFileName = "devirt.pprof"
2323const preProfFileName = "devirt.pprof.node_map"
2424
2525// testPGODevirtualize tests that specific PGO devirtualize rewrites are performed.
26- func testPGODevirtualize (t * testing.T , dir string , want []devirtualization , pgoProfileName string ) {
26+ func testPGODevirtualize (t * testing.T , dir string , want , nowant []devirtualization , pgoProfileName string ) {
2727 testenv .MustHaveGoRun (t )
2828 t .Parallel ()
2929
@@ -69,24 +69,32 @@ go 1.21
6969 }
7070
7171 got := make (map [devirtualization ]struct {})
72+ gotNoHot := make (map [devirtualization ]struct {})
7273
7374 devirtualizedLine := regexp .MustCompile (`(.*): PGO devirtualizing \w+ call .* to (.*)` )
75+ noHotLine := regexp .MustCompile (`(.*): call .*: no hot callee` )
7476
7577 scanner := bufio .NewScanner (pr )
7678 for scanner .Scan () {
7779 line := scanner .Text ()
7880 t .Logf ("child: %s" , line )
7981
8082 m := devirtualizedLine .FindStringSubmatch (line )
81- if m == nil {
83+ if m != nil {
84+ d := devirtualization {
85+ pos : m [1 ],
86+ callee : m [2 ],
87+ }
88+ got [d ] = struct {}{}
8289 continue
8390 }
84-
85- d := devirtualization {
86- pos : m [1 ],
87- callee : m [2 ],
91+ m = noHotLine .FindStringSubmatch (line )
92+ if m != nil {
93+ d := devirtualization {
94+ pos : m [1 ],
95+ }
96+ gotNoHot [d ] = struct {}{}
8897 }
89- got [d ] = struct {}{}
9098 }
9199 if err := cmd .Wait (); err != nil {
92100 t .Fatalf ("error running go test: %v" , err )
@@ -104,6 +112,11 @@ go 1.21
104112 }
105113 t .Errorf ("devirtualization %v missing; got %v" , w , got )
106114 }
115+ for _ , nw := range nowant {
116+ if _ , ok := gotNoHot [nw ]; ! ok {
117+ t .Errorf ("unwanted devirtualization %v; got %v" , nw , got )
118+ }
119+ }
107120
108121 // Run test with PGO to ensure the assertions are still true.
109122 cmd = testenv .CleanCmdEnv (testenv .Command (t , out ))
@@ -174,8 +187,18 @@ func TestPGODevirtualize(t *testing.T) {
174187 // callee: "mult.MultClosure.func1",
175188 //},
176189 }
190+ nowant := []devirtualization {
191+ // ExerciseIfaceZeroWeight
192+ {
193+ pos : "./devirt.go:256:29" ,
194+ },
195+ // ExerciseIndirCallZeroWeight
196+ {
197+ pos : "./devirt.go:282:37" ,
198+ },
199+ }
177200
178- testPGODevirtualize (t , dir , want , profFileName )
201+ testPGODevirtualize (t , dir , want , nowant , profFileName )
179202}
180203
181204// TestPGOPreprocessDevirtualize tests that specific functions are devirtualized when PGO
@@ -237,8 +260,18 @@ func TestPGOPreprocessDevirtualize(t *testing.T) {
237260 // callee: "mult.MultClosure.func1",
238261 //},
239262 }
263+ nowant := []devirtualization {
264+ // ExerciseIfaceZeroWeight
265+ {
266+ pos : "./devirt.go:256:29" ,
267+ },
268+ // ExerciseIndirCallZeroWeight
269+ {
270+ pos : "./devirt.go:282:37" ,
271+ },
272+ }
240273
241- testPGODevirtualize (t , dir , want , preProfFileName )
274+ testPGODevirtualize (t , dir , want , nowant , preProfFileName )
242275}
243276
244277// Regression test for https://go.dev/issue/65615. If a target function changes
@@ -303,8 +336,18 @@ func TestLookupFuncGeneric(t *testing.T) {
303336 // callee: "mult.MultClosure.func1",
304337 //},
305338 }
339+ nowant := []devirtualization {
340+ // ExerciseIfaceZeroWeight
341+ {
342+ pos : "./devirt.go:256:29" ,
343+ },
344+ // ExerciseIndirCallZeroWeight
345+ {
346+ pos : "./devirt.go:282:37" ,
347+ },
348+ }
306349
307- testPGODevirtualize (t , dir , want , profFileName )
350+ testPGODevirtualize (t , dir , want , nowant , profFileName )
308351}
309352
310353var multFnRe = regexp .MustCompile (`func MultFn\(a, b int64\) int64` )
0 commit comments