1
2
3
4
5 package ssa
6
7
8
9
10
11
12
13
14 func tightenTupleSelectors(f *Func) {
15 selectors := make(map[struct {
16 id ID
17 which int
18 }]*Value)
19 for _, b := range f.Blocks {
20 for _, selector := range b.Values {
21
22 var tuple *Value
23 idx := 0
24 switch selector.Op {
25 default:
26 continue
27 case OpSelect1:
28 idx = 1
29 fallthrough
30 case OpSelect0:
31 tuple = selector.Args[0]
32 if !tuple.Type.IsTuple() {
33 f.Fatalf("arg of tuple selector %s is not a tuple: %s", selector.String(), tuple.LongString())
34 }
35 case OpSelectN:
36 tuple = selector.Args[0]
37 idx = int(selector.AuxInt)
38 if !tuple.Type.IsResults() {
39 f.Fatalf("arg of result selector %s is not a results: %s", selector.String(), tuple.LongString())
40 }
41 }
42
43
44
45
46 key := struct {
47 id ID
48 which int
49 }{tuple.ID, idx}
50 if t := selectors[key]; t != nil {
51 if selector != t {
52 selector.copyOf(t)
53 }
54 continue
55 }
56
57
58
59 if selector.Block != tuple.Block {
60 t := selector.copyInto(tuple.Block)
61 selector.copyOf(t)
62 selectors[key] = t
63 continue
64 }
65
66
67
68 selectors[key] = selector
69 }
70 }
71 }
72
View as plain text