Skip to content

Commit 9345e88

Browse files
authored
Merge pull request #36871 from apple/revert-36819-stacklist
2 parents 299df93 + ddfdf47 commit 9345e88

20 files changed

+137
-404
lines changed

include/swift/SIL/BasicBlockBits.h

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
//
1515
//===----------------------------------------------------------------------===//
1616

17-
#ifndef SWIFT_SIL_BASICBLOCKBITS_H
18-
#define SWIFT_SIL_BASICBLOCKBITS_H
17+
#ifndef SWIFT_SIL_SILBITFIELD_H
18+
#define SWIFT_SIL_SILBITFIELD_H
1919

2020
#include "swift/SIL/SILFunction.h"
2121
#include "llvm/ADT/SmallVector.h"
@@ -173,6 +173,101 @@ class BasicBlockSet {
173173
void erase(SILBasicBlock *block) { flag.reset(block); }
174174
};
175175

176+
/// An implementation of `llvm::SetVector<SILBasicBlock *,
177+
/// SmallVector<SILBasicBlock *, N>,
178+
/// BasicBlockSet>`.
179+
///
180+
/// Unfortunately it's not possible to use `llvm::SetVector` directly because
181+
/// the BasicBlockSet constructor needs a `SILFunction` argument.
182+
///
183+
/// Note: This class does not provide a `remove` method intentinally, because
184+
/// it would have a O(n) complexity.
185+
template <unsigned N> class BasicBlockSetVector {
186+
using Vector = llvm::SmallVector<SILBasicBlock *, N>;
187+
188+
Vector vector;
189+
BasicBlockSet set;
190+
191+
public:
192+
using iterator = typename Vector::const_iterator;
193+
194+
BasicBlockSetVector(SILFunction *function) : set(function) {}
195+
196+
iterator begin() const { return vector.begin(); }
197+
iterator end() const { return vector.end(); }
198+
199+
unsigned size() const { return vector.size(); }
200+
bool empty() const { return vector.empty(); }
201+
202+
bool contains(SILBasicBlock *block) const { return set.contains(block); }
203+
204+
/// Returns true if \p block was not contained in the set before inserting.
205+
bool insert(SILBasicBlock *block) {
206+
if (set.insert(block)) {
207+
vector.push_back(block);
208+
return true;
209+
}
210+
return false;
211+
}
212+
};
213+
214+
/// A utility for processing basic blocks in a worklist.
215+
///
216+
/// It is basically a combination of a block vector and a block set. It can be
217+
/// used for typical worklist-processing algorithms.
218+
template <unsigned N> class BasicBlockWorklist {
219+
llvm::SmallVector<SILBasicBlock *, N> worklist;
220+
BasicBlockSet visited;
221+
222+
public:
223+
/// Construct an empty worklist.
224+
BasicBlockWorklist(SILFunction *function) : visited(function) {}
225+
226+
/// Initialize the worklist with \p initialBlock.
227+
BasicBlockWorklist(SILBasicBlock *initialBlock)
228+
: visited(initialBlock->getParent()) {
229+
push(initialBlock);
230+
}
231+
232+
/// Pops the last added element from the worklist or returns null, if the
233+
/// worklist is empty.
234+
SILBasicBlock *pop() {
235+
if (worklist.empty())
236+
return nullptr;
237+
return worklist.pop_back_val();
238+
}
239+
240+
/// Pushes \p block onto the worklist if \p block has never been push before.
241+
bool pushIfNotVisited(SILBasicBlock *block) {
242+
if (visited.insert(block)) {
243+
worklist.push_back(block);
244+
return true;
245+
}
246+
return false;
247+
}
248+
249+
/// Like `pushIfNotVisited`, but requires that \p block has never been on the
250+
/// worklist before.
251+
void push(SILBasicBlock *block) {
252+
assert(!visited.contains(block));
253+
visited.insert(block);
254+
worklist.push_back(block);
255+
}
256+
257+
/// Like `pop`, but marks the returned block as "unvisited". This means, that
258+
/// the block can be pushed onto the worklist again.
259+
SILBasicBlock *popAndForget() {
260+
if (worklist.empty())
261+
return nullptr;
262+
SILBasicBlock *block = worklist.pop_back_val();
263+
visited.erase(block);
264+
return block;
265+
}
266+
267+
/// Returns true if \p block was visited, i.e. has been added to the worklist.
268+
bool isVisited(SILBasicBlock *block) const { return visited.contains(block); }
269+
};
270+
176271
} // namespace swift
177272

178273
#endif

include/swift/SIL/BasicBlockDatastructures.h

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

include/swift/SIL/SILModule.h

Lines changed: 0 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -49,52 +49,10 @@
4949
#include "llvm/Support/raw_ostream.h"
5050
#include <functional>
5151

52-
namespace swift {
53-
54-
/// A fixed size slab of memory, which can be allocated and freed by the
55-
/// SILModule at (basically) zero cost.
56-
class FixedSizeSlab : public llvm::ilist_node<FixedSizeSlab>,
57-
public SILAllocated<FixedSizeSlab> {
58-
public:
59-
/// The capacity of the payload.
60-
static constexpr size_t capacity = 64 * sizeof(uintptr_t);
61-
62-
private:
63-
friend class SILModule;
64-
65-
/// The magic number which is stored in overflowGuard.
66-
static constexpr uintptr_t magicNumber = (uintptr_t)0xdeadbeafdeadbeafull;
67-
68-
/// The payload.
69-
char data[capacity];
70-
71-
/// Used for a cheap buffer overflow check - in the spirit of libgmalloc.
72-
uintptr_t overflowGuard = magicNumber;
73-
74-
public:
75-
/// Returns the payload pointing to \p T.
76-
template<typename T> T *dataFor() { return (T *)(&data[0]); }
77-
78-
/// Returns the payload pointing to const \p T
79-
template<typename T> const T *dataFor() const { return (const T *)(&data[0]); }
80-
};
81-
82-
} // end swift namespace
83-
8452
namespace llvm {
8553
namespace yaml {
8654
class Output;
8755
} // end namespace yaml
88-
89-
template <>
90-
struct ilist_traits<::swift::FixedSizeSlab> :
91-
public ilist_node_traits<::swift::FixedSizeSlab> {
92-
public:
93-
static void deleteNode(::swift::FixedSizeSlab *V) {
94-
llvm_unreachable("cannot delete a slab");
95-
}
96-
};
97-
9856
} // end namespace llvm
9957

10058
namespace swift {
@@ -171,7 +129,6 @@ class SILModule {
171129
};
172130

173131
using ActionCallback = std::function<void()>;
174-
using SlabList = llvm::ilist<FixedSizeSlab>;
175132

176133
private:
177134
friend KeyPathPattern;
@@ -194,12 +151,6 @@ class SILModule {
194151
/// Allocator that manages the memory of all the pieces of the SILModule.
195152
mutable llvm::BumpPtrAllocator BPA;
196153

197-
/// The list of freed slabs, which can be reused.
198-
SlabList freeSlabs;
199-
200-
/// For consistency checking.
201-
size_t numAllocatedSlabs = 0;
202-
203154
/// The swift Module associated with this SILModule.
204155
ModuleDecl *TheSwiftModule;
205156

@@ -782,22 +733,6 @@ class SILModule {
782733
return static_cast<T *>(allocate(sizeof(T) * Count, alignof(T)));
783734
}
784735

785-
/// Allocates a slab of memory.
786-
///
787-
/// This has (almost) zero cost, because for the first time, the allocation is
788-
/// done with the BPA.
789-
/// Subsequent allocations are reusing the already freed slabs.
790-
FixedSizeSlab *allocSlab();
791-
792-
/// Frees a slab.
793-
///
794-
/// This has (almost) zero cost, because the slab is just put into the
795-
/// freeSlabs list.
796-
void freeSlab(FixedSizeSlab *slab);
797-
798-
/// Frees all slabs of a list.
799-
void freeAllSlabs(SlabList &slabs);
800-
801736
template <typename T>
802737
MutableArrayRef<T> allocateCopy(ArrayRef<T> Array) const {
803738
MutableArrayRef<T> result(allocate<T>(Array.size()), Array.size());

0 commit comments

Comments
 (0)