Skip to content

Commit 6505fcb

Browse files
randall77gopherbot
authored andcommitted
cmd/compile: use generics for sparse map
So it is easier to reuse this code with different key/value types. Change-Id: I5a9e669769cf359b32f2fe784594868acdee4d02 Reviewed-on: https://go-review.googlesource.com/c/go/+/681175 Reviewed-by: Keith Randall <[email protected]> Reviewed-by: David Chase <[email protected]> Auto-Submit: Keith Randall <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Cherry Mui <[email protected]>
1 parent 14f5eb7 commit 6505fcb

File tree

3 files changed

+39
-39
lines changed

3 files changed

+39
-39
lines changed

src/cmd/compile/internal/ssa/biasedsparsemap.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,11 @@ func (s *biasedSparseMap) get(x uint) int32 {
6868
if int(x) >= s.cap() {
6969
return -1
7070
}
71-
return s.s.get(ID(int(x) - s.first))
71+
k := ID(int(x) - s.first)
72+
if !s.s.contains(k) {
73+
return -1 // TODO: push presence check to callers?
74+
}
75+
return s.s.get(k)
7276
}
7377

7478
// getEntry returns the i'th key and value stored in s,

src/cmd/compile/internal/ssa/deadstore.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,7 @@ func dse(f *Func) {
156156

157157
// A shadowRange encodes a set of byte offsets [lo():hi()] from
158158
// a given pointer that will be written to later in the block.
159-
// A zero shadowRange encodes an empty shadowed range (and so
160-
// does a -1 shadowRange, which is what sparsemap.get returns
161-
// on a failed lookup).
159+
// A zero shadowRange encodes an empty shadowed range.
162160
type shadowRange int32
163161

164162
func (sr shadowRange) lo() int64 {

src/cmd/compile/internal/ssa/sparsemap.go

Lines changed: 33 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,70 +7,60 @@ package ssa
77
// from https://research.swtch.com/sparse
88
// in turn, from Briggs and Torczon
99

10-
type sparseEntry struct {
11-
key ID
12-
val int32
10+
// sparseKey needs to be something we can index a slice with.
11+
type sparseKey interface{ ~int | ~int32 }
12+
13+
type sparseEntry[K sparseKey, V any] struct {
14+
key K
15+
val V
1316
}
1417

15-
type sparseMap struct {
16-
dense []sparseEntry
18+
type genericSparseMap[K sparseKey, V any] struct {
19+
dense []sparseEntry[K, V]
1720
sparse []int32
1821
}
1922

20-
// newSparseMap returns a sparseMap that can map
21-
// integers between 0 and n-1 to int32s.
22-
func newSparseMap(n int) *sparseMap {
23-
return &sparseMap{dense: nil, sparse: make([]int32, n)}
23+
// newGenericSparseMap returns a sparseMap that can map
24+
// integers between 0 and n-1 to a value type.
25+
func newGenericSparseMap[K sparseKey, V any](n int) *genericSparseMap[K, V] {
26+
return &genericSparseMap[K, V]{dense: nil, sparse: make([]int32, n)}
2427
}
2528

26-
func (s *sparseMap) cap() int {
29+
func (s *genericSparseMap[K, V]) cap() int {
2730
return len(s.sparse)
2831
}
2932

30-
func (s *sparseMap) size() int {
33+
func (s *genericSparseMap[K, V]) size() int {
3134
return len(s.dense)
3235
}
3336

34-
func (s *sparseMap) contains(k ID) bool {
37+
func (s *genericSparseMap[K, V]) contains(k K) bool {
3538
i := s.sparse[k]
3639
return i < int32(len(s.dense)) && s.dense[i].key == k
3740
}
3841

39-
// get returns the value for key k, or -1 if k does
40-
// not appear in the map.
41-
func (s *sparseMap) get(k ID) int32 {
42+
// get returns the value for key k, or the zero V
43+
// if k does not appear in the map.
44+
func (s *genericSparseMap[K, V]) get(k K) V {
4245
i := s.sparse[k]
4346
if i < int32(len(s.dense)) && s.dense[i].key == k {
4447
return s.dense[i].val
4548
}
46-
return -1
49+
var v V
50+
return v
4751
}
4852

49-
func (s *sparseMap) set(k ID, v int32) {
53+
func (s *genericSparseMap[K, V]) set(k K, v V) {
5054
i := s.sparse[k]
5155
if i < int32(len(s.dense)) && s.dense[i].key == k {
5256
s.dense[i].val = v
5357
return
5458
}
55-
s.dense = append(s.dense, sparseEntry{k, v})
56-
s.sparse[k] = int32(len(s.dense)) - 1
57-
}
58-
59-
// setBit sets the v'th bit of k's value, where 0 <= v < 32
60-
func (s *sparseMap) setBit(k ID, v uint) {
61-
if v >= 32 {
62-
panic("bit index too large.")
63-
}
64-
i := s.sparse[k]
65-
if i < int32(len(s.dense)) && s.dense[i].key == k {
66-
s.dense[i].val |= 1 << v
67-
return
68-
}
69-
s.dense = append(s.dense, sparseEntry{k, 1 << v})
59+
s.dense = append(s.dense, sparseEntry[K, V]{k, v})
7060
s.sparse[k] = int32(len(s.dense)) - 1
7161
}
7262

73-
func (s *sparseMap) remove(k ID) {
63+
func (s *genericSparseMap[K, V]) remove(k K) {
7464
i := s.sparse[k]
7565
if i < int32(len(s.dense)) && s.dense[i].key == k {
7666
y := s.dense[len(s.dense)-1]
@@ -80,10 +70,18 @@ func (s *sparseMap) remove(k ID) {
8070
}
8171
}
8272

83-
func (s *sparseMap) clear() {
73+
func (s *genericSparseMap[K, V]) clear() {
8474
s.dense = s.dense[:0]
8575
}
8676

87-
func (s *sparseMap) contents() []sparseEntry {
77+
func (s *genericSparseMap[K, V]) contents() []sparseEntry[K, V] {
8878
return s.dense
8979
}
80+
81+
type sparseMap = genericSparseMap[ID, int32]
82+
83+
// newSparseMap returns a sparseMap that can map
84+
// integers between 0 and n-1 to int32s.
85+
func newSparseMap(n int) *sparseMap {
86+
return newGenericSparseMap[ID, int32](n)
87+
}

0 commit comments

Comments
 (0)