Skip to content

Commit d128d81

Browse files
authored
Merge pull request #60035 from eeckstein/silnode-set
SIL: add efficient Set data structures for SILValue and SILInstruction, similar to BasicBlockSet.
2 parents 6f22102 + 777b421 commit d128d81

25 files changed

+755
-251
lines changed

SwiftCompilerSources/Sources/Optimizer/DataStructures/BasicBlockSet.swift

Lines changed: 0 additions & 59 deletions
This file was deleted.

SwiftCompilerSources/Sources/Optimizer/DataStructures/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
swift_compiler_sources(Optimizer
1010
BasicBlockRange.swift
11-
BasicBlockSet.swift
1211
BasicBlockWorklist.swift
1312
InstructionRange.swift
13+
Set.swift
1414
Stack.swift)

SwiftCompilerSources/Sources/Optimizer/DataStructures/InstructionRange.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@ struct InstructionRange : CustomStringConvertible, CustomReflectable {
4646
/// The underlying block range.
4747
private(set) var blockRange: BasicBlockRange
4848

49-
private var insertedInsts: Set<Instruction>
49+
private var insertedInsts: InstructionSet
5050

5151
init(begin beginInst: Instruction, _ context: PassContext) {
5252
self.begin = beginInst
53-
self.insertedInsts = Set<Instruction>()
5453
self.blockRange = BasicBlockRange(begin: beginInst.block, context)
54+
self.insertedInsts = InstructionSet(context)
5555
}
5656

5757
/// Insert a potential end instruction.
@@ -143,6 +143,7 @@ struct InstructionRange : CustomStringConvertible, CustomReflectable {
143143

144144
/// TODO: once we have move-only types, make this a real deinit.
145145
mutating func deinitialize() {
146+
insertedInsts.deinitialize()
146147
blockRange.deinitialize()
147148
}
148149
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
//===--- Set.swift - sets for basic blocks, values and instructions -------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2022 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import SIL
14+
import OptimizerBridging
15+
16+
/// A set of basic blocks.
17+
///
18+
/// This is an extremely efficient implementation which does not need memory
19+
/// allocations or hash lookups.
20+
///
21+
/// This type should be a move-only type, but unfortunately we don't have move-only
22+
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
23+
/// destruct this data structure, e.g. in a `defer {}` block.
24+
struct BasicBlockSet : CustomStringConvertible, CustomReflectable {
25+
26+
private let context: PassContext
27+
private let bridged: BridgedBasicBlockSet
28+
29+
init(_ context: PassContext) {
30+
self.context = context
31+
self.bridged = PassContext_allocBasicBlockSet(context._bridged)
32+
}
33+
34+
func contains(_ block: BasicBlock) -> Bool {
35+
BasicBlockSet_contains(bridged, block.bridged) != 0
36+
}
37+
38+
mutating func insert(_ block: BasicBlock) {
39+
BasicBlockSet_insert(bridged, block.bridged)
40+
}
41+
42+
mutating func erase(_ block: BasicBlock) {
43+
BasicBlockSet_erase(bridged, block.bridged)
44+
}
45+
46+
var description: String {
47+
let function = BasicBlockSet_getFunction(bridged).function
48+
let blockNames = function.blocks.enumerated().filter { contains($0.1) }
49+
.map { "bb\($0.0)"}
50+
return "{" + blockNames.joined(separator: ", ") + "}"
51+
}
52+
53+
var customMirror: Mirror { Mirror(self, children: []) }
54+
55+
/// TODO: once we have move-only types, make this a real deinit.
56+
mutating func deinitialize() {
57+
PassContext_freeBasicBlockSet(context._bridged, bridged)
58+
}
59+
}
60+
61+
/// A set of values.
62+
///
63+
/// This is an extremely efficient implementation which does not need memory
64+
/// allocations or hash lookups.
65+
///
66+
/// This type should be a move-only type, but unfortunately we don't have move-only
67+
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
68+
/// destruct this data structure, e.g. in a `defer {}` block.
69+
struct ValueSet : CustomStringConvertible, CustomReflectable {
70+
71+
private let context: PassContext
72+
private let bridged: BridgedNodeSet
73+
74+
init(_ context: PassContext) {
75+
self.context = context
76+
self.bridged = PassContext_allocNodeSet(context._bridged)
77+
}
78+
79+
func contains(_ value: Value) -> Bool {
80+
NodeSet_containsValue(bridged, value.bridged) != 0
81+
}
82+
83+
mutating func insert(_ value: Value) {
84+
NodeSet_insertValue(bridged, value.bridged)
85+
}
86+
87+
mutating func erase(_ value: Value) {
88+
NodeSet_eraseValue(bridged, value.bridged)
89+
}
90+
91+
var description: String {
92+
let function = NodeSet_getFunction(bridged).function
93+
var d = "{\n"
94+
for block in function.blocks {
95+
for arg in block.arguments {
96+
if contains(arg) {
97+
d += arg.description
98+
}
99+
}
100+
for inst in block.instructions {
101+
for result in inst.results {
102+
if contains(result) {
103+
d += result.description
104+
}
105+
}
106+
}
107+
}
108+
d += "}\n"
109+
return d
110+
}
111+
112+
var customMirror: Mirror { Mirror(self, children: []) }
113+
114+
/// TODO: once we have move-only types, make this a real deinit.
115+
mutating func deinitialize() {
116+
PassContext_freeNodeSet(context._bridged, bridged)
117+
}
118+
}
119+
120+
/// A set of instructions.
121+
///
122+
/// This is an extremely efficient implementation which does not need memory
123+
/// allocations or hash lookups.
124+
///
125+
/// This type should be a move-only type, but unfortunately we don't have move-only
126+
/// types yet. Therefore it's needed to call `deinitialize()` explicitly to
127+
/// destruct this data structure, e.g. in a `defer {}` block.
128+
struct InstructionSet : CustomStringConvertible, CustomReflectable {
129+
130+
private let context: PassContext
131+
private let bridged: BridgedNodeSet
132+
133+
init(_ context: PassContext) {
134+
self.context = context
135+
self.bridged = PassContext_allocNodeSet(context._bridged)
136+
}
137+
138+
func contains(_ inst: Instruction) -> Bool {
139+
NodeSet_containsInstruction(bridged, inst.bridged) != 0
140+
}
141+
142+
mutating func insert(_ inst: Instruction) {
143+
NodeSet_insertInstruction(bridged, inst.bridged)
144+
}
145+
146+
mutating func erase(_ inst: Instruction) {
147+
NodeSet_eraseInstruction(bridged, inst.bridged)
148+
}
149+
150+
var description: String {
151+
let function = NodeSet_getFunction(bridged).function
152+
var d = "{\n"
153+
for block in function.blocks {
154+
for inst in block.instructions {
155+
if contains(inst) {
156+
d += inst.description
157+
}
158+
}
159+
}
160+
d += "}\n"
161+
return d
162+
}
163+
164+
var customMirror: Mirror { Mirror(self, children: []) }
165+
166+
/// TODO: once we have move-only types, make this a real deinit.
167+
mutating func deinitialize() {
168+
PassContext_freeNodeSet(context._bridged, bridged)
169+
}
170+
}

0 commit comments

Comments
 (0)