...
Source file src/pkg/cmd/compile/internal/ssa/layout.go
1
2
3
4
5 package ssa
6
7
8
9
10 func layout(f *Func) {
11 f.Blocks = layoutOrder(f)
12 }
13
14
15
16
17 func layoutRegallocOrder(f *Func) []*Block {
18
19 switch f.pass.test {
20 case 0:
21 return layoutOrder(f)
22 case 1:
23 return f.Blocks
24 case 2:
25 po := f.postorder()
26 visitOrder := make([]*Block, len(po))
27 for i, b := range po {
28 j := len(po) - i - 1
29 visitOrder[j] = b
30 }
31 return visitOrder
32 }
33
34 return nil
35 }
36
37 func layoutOrder(f *Func) []*Block {
38 order := make([]*Block, 0, f.NumBlocks())
39 scheduled := make([]bool, f.NumBlocks())
40 idToBlock := make([]*Block, f.NumBlocks())
41 indegree := make([]int, f.NumBlocks())
42 posdegree := f.newSparseSet(f.NumBlocks())
43 defer f.retSparseSet(posdegree)
44 zerodegree := f.newSparseSet(f.NumBlocks())
45 defer f.retSparseSet(zerodegree)
46 exit := f.newSparseSet(f.NumBlocks())
47 defer f.retSparseSet(exit)
48
49
50 for _, b := range f.Blocks {
51 idToBlock[b.ID] = b
52 if b.Kind == BlockExit {
53
54
55 exit.add(b.ID)
56 continue
57 }
58 indegree[b.ID] = len(b.Preds)
59 if len(b.Preds) == 0 {
60 zerodegree.add(b.ID)
61 } else {
62 posdegree.add(b.ID)
63 }
64 }
65
66 bid := f.Entry.ID
67 blockloop:
68 for {
69
70 b := idToBlock[bid]
71 order = append(order, b)
72 scheduled[bid] = true
73 if len(order) == len(f.Blocks) {
74 break
75 }
76
77 for _, e := range b.Succs {
78 c := e.b
79 indegree[c.ID]--
80 if indegree[c.ID] == 0 {
81 posdegree.remove(c.ID)
82 zerodegree.add(c.ID)
83 }
84 }
85
86
87
88
89
90 var likely *Block
91 switch b.Likely {
92 case BranchLikely:
93 likely = b.Succs[0].b
94 case BranchUnlikely:
95 likely = b.Succs[1].b
96 }
97 if likely != nil && !scheduled[likely.ID] {
98 bid = likely.ID
99 continue
100 }
101
102
103 bid = 0
104 mindegree := f.NumBlocks()
105 for _, e := range order[len(order)-1].Succs {
106 c := e.b
107 if scheduled[c.ID] || c.Kind == BlockExit {
108 continue
109 }
110 if indegree[c.ID] < mindegree {
111 mindegree = indegree[c.ID]
112 bid = c.ID
113 }
114 }
115 if bid != 0 {
116 continue
117 }
118
119
120
121 for zerodegree.size() > 0 {
122 cid := zerodegree.pop()
123 if !scheduled[cid] {
124 bid = cid
125 continue blockloop
126 }
127 }
128
129 for posdegree.size() > 0 {
130 cid := posdegree.pop()
131 if !scheduled[cid] {
132 bid = cid
133 continue blockloop
134 }
135 }
136
137
138 for {
139 cid := exit.pop()
140 if !scheduled[cid] {
141 bid = cid
142 continue blockloop
143 }
144 }
145 }
146 f.laidout = true
147 return order
148
149 }
150
View as plain text