1
2
3
4
5 package ssa
6
7 import (
8 "fmt"
9 "iter"
10 "slices"
11 "testing"
12
13 "cmd/compile/internal/ssa/block"
14 )
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 func genCrossLadder(k int) (*Func, []*Block) {
32 f := (&Config{}).NewFunc(nil, &Cache{})
33 entry := f.NewBlock(block.BlockIf)
34 f.Entry = entry
35 exit := f.NewBlock(block.BlockExit)
36 col := make([]*Block, 0, 2*k)
37 prevL, prevR := entry, entry
38 for i := 0; i < k; i++ {
39 kind := block.BlockIf
40 if i == k-1 {
41 kind = block.BlockPlain
42 }
43 l := f.NewBlock(kind)
44 r := f.NewBlock(kind)
45 col = append(col, l, r)
46 prevL.AddEdgeTo(l)
47 prevL.AddEdgeTo(r)
48 prevR.AddEdgeTo(l)
49 prevR.AddEdgeTo(r)
50 prevL, prevR = l, r
51 }
52 col[len(col)-2].AddEdgeTo(exit)
53 col[len(col)-1].AddEdgeTo(exit)
54 return f, col
55 }
56
57
58
59
60 func BenchmarkIterDomFrontierPlus(b *testing.B) {
61 for _, k := range []int{8, 16, 32} {
62 b.Run(fmt.Sprintf("k=%d", k), func(b *testing.B) {
63 f, col := genCrossLadder(k)
64 b.ReportAllocs()
65 b.ResetTimer()
66 var n int
67 for i := 0; i < b.N; i++ {
68 for j := range col {
69 for range f.IterDomFrontierPlus(slices.Values(col[j : j+1])) {
70 n++
71 }
72 }
73 }
74 b.StopTimer()
75 b.ReportMetric(float64(n)/float64(b.N), "blocks/op")
76 if n != 2*k*k*b.N {
77 b.Fatalf("walked %d blocks per round, want %d", n/b.N, 2*k*k)
78 }
79 })
80 }
81 }
82
83
84
85
86
87 func TestIterDomFrontierPlusSeedAtMerge(t *testing.T) {
88
89
90
91
92
93
94
95
96
97
98 f := (&Config{}).NewFunc(nil, &Cache{})
99 b1 := f.NewBlock(block.BlockPlain)
100 f.Entry = b1
101 b2 := f.NewBlock(block.BlockIf)
102 b4 := f.NewBlock(block.BlockPlain)
103 b5 := f.NewBlock(block.BlockIf)
104 b3 := f.NewBlock(block.BlockExit)
105 u := f.NewBlock(block.BlockPlain)
106
107 b1.AddEdgeTo(b2)
108 b2.AddEdgeTo(b4)
109 b2.AddEdgeTo(b5)
110 b4.AddEdgeTo(b2)
111 b5.AddEdgeTo(b3)
112 b5.AddEdgeTo(b2)
113 u.AddEdgeTo(b3)
114
115 got := collectBlockIDs(f.IterDomFrontierPlus(slices.Values([]*Block{b1, b2, u})))
116 if want := []ID{b2.ID}; !slices.Equal(got, want) {
117 t.Errorf("got DF+ = %v, want %v", got, want)
118 }
119 }
120
121 func collectBlockIDs(seq iter.Seq[*Block]) []ID {
122 var ids []ID
123 for b := range seq {
124 ids = append(ids, b.ID)
125 }
126 return ids
127 }
128
View as plain text