Skip to content

Commit d2dc3de

Browse files
committed
SIL: add the WorklistWithPayload utility
It is like `Worklist` but can store an additional arbitrary payload per element.
1 parent 7d79179 commit d2dc3de

File tree

1 file changed

+47
-0
lines changed

1 file changed

+47
-0
lines changed

SwiftCompilerSources/Sources/SIL/DataStructures/Worklist.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,54 @@ public struct Worklist<Set: IntrusiveSet> : CustomStringConvertible, NoReflectio
7070
}
7171
}
7272

73+
/// Like `Worklist` but can store an additional arbitrary payload per element.
74+
public struct WorklistWithPayload<Set: IntrusiveSet, Payload> : CustomStringConvertible, NoReflectionChildren {
75+
public typealias Element = Set.Element
76+
private var worklist: Stack<(Element, Payload)>
77+
private var pushedElements: Set
78+
79+
public init(_ context: some Context) {
80+
self.worklist = Stack(context)
81+
self.pushedElements = Set(context)
82+
}
83+
84+
public mutating func pop() -> (Element, Payload)? { return worklist.pop() }
85+
86+
public mutating func pushIfNotVisited(_ element: Element, with payload: Payload) {
87+
if pushedElements.insert(element) {
88+
worklist.append((element, payload))
89+
}
90+
}
91+
92+
public mutating func pushIfNotVisited<S: Sequence>(contentsOf other: S, with payload: Payload)
93+
where S.Element == Element
94+
{
95+
for element in other {
96+
pushIfNotVisited(element, with: payload)
97+
}
98+
}
99+
100+
/// Returns true if \p element was pushed to the worklist, regardless if it's already popped or not.
101+
public func hasBeenPushed(_ element: Element) -> Bool { pushedElements.contains(element) }
102+
103+
public var isEmpty: Bool { worklist.isEmpty }
104+
105+
public var description: String {
106+
"""
107+
worklist: \(worklist)
108+
pushed: \(pushedElements)
109+
"""
110+
}
111+
112+
/// TODO: once we have move-only types, make this a real deinit.
113+
public mutating func deinitialize() {
114+
pushedElements.deinitialize()
115+
worklist.deinitialize()
116+
}
117+
}
118+
73119
public typealias BasicBlockWorklist = Worklist<BasicBlockSet>
120+
public typealias BasicBlockWorklistWithPayload<Payload> = WorklistWithPayload<BasicBlockSet, Payload>
74121
public typealias InstructionWorklist = Worklist<InstructionSet>
75122
public typealias SpecificInstructionWorklist<InstType: Instruction> = Worklist<SpecificInstructionSet<InstType>>
76123
public typealias ValueWorklist = Worklist<ValueSet>

0 commit comments

Comments
 (0)