mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
libswift: Add the StackList data structure
StackList is a very efficient data structure for worklist type things. This is a port of the C++ utility with the same name. Compared to Array, it does not require any memory allocations.
This commit is contained in:
@@ -1079,6 +1079,26 @@ void SILPassManager::viewCallGraph() {
|
||||
// LibswiftPassInvocation
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static_assert(BridgedSlabCapacity == FixedSizeSlab::capacity,
|
||||
"wrong bridged slab capacity");
|
||||
|
||||
FixedSizeSlab *LibswiftPassInvocation::allocSlab(FixedSizeSlab *afterSlab) {
|
||||
FixedSizeSlab *slab = passManager->getModule()->allocSlab();
|
||||
if (afterSlab) {
|
||||
allocatedSlabs.insert(std::next(afterSlab->getIterator()), *slab);
|
||||
} else {
|
||||
allocatedSlabs.push_back(*slab);
|
||||
}
|
||||
return slab;
|
||||
}
|
||||
|
||||
FixedSizeSlab *LibswiftPassInvocation::freeSlab(FixedSizeSlab *slab) {
|
||||
FixedSizeSlab *prev = std::prev(&*slab->getIterator());
|
||||
allocatedSlabs.remove(*slab);
|
||||
passManager->getModule()->freeSlab(slab);
|
||||
return prev;
|
||||
}
|
||||
|
||||
void LibswiftPassInvocation::eraseInstruction(SILInstruction *inst) {
|
||||
if (silCombiner) {
|
||||
// TODO
|
||||
@@ -1088,6 +1108,7 @@ void LibswiftPassInvocation::eraseInstruction(SILInstruction *inst) {
|
||||
}
|
||||
|
||||
void LibswiftPassInvocation::finishedPassRun() {
|
||||
assert(allocatedSlabs.empty() && "StackList is leaking slabs");
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@@ -1099,6 +1120,38 @@ inline LibswiftPassInvocation *castToPassInvocation(BridgedPassContext ctxt) {
|
||||
static_cast<const LibswiftPassInvocation *>(ctxt.opaqueCtxt));
|
||||
}
|
||||
|
||||
inline FixedSizeSlab *castToSlab(BridgedSlab slab) {
|
||||
if (slab.data)
|
||||
return static_cast<FixedSizeSlab *>((FixedSizeSlabPayload *)slab.data);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline BridgedSlab toBridgedSlab(FixedSizeSlab *slab) {
|
||||
if (slab) {
|
||||
FixedSizeSlabPayload *payload = slab;
|
||||
assert((void *)payload == slab->dataFor<void>());
|
||||
return {payload};
|
||||
}
|
||||
return {nullptr};
|
||||
}
|
||||
|
||||
|
||||
BridgedSlab PassContext_getNextSlab(BridgedSlab slab) {
|
||||
return toBridgedSlab(&*std::next(castToSlab(slab)->getIterator()));
|
||||
}
|
||||
|
||||
BridgedSlab PassContext_allocSlab(BridgedPassContext passContext,
|
||||
BridgedSlab afterSlab) {
|
||||
auto *inv = castToPassInvocation(passContext);
|
||||
return toBridgedSlab(inv->allocSlab(castToSlab(afterSlab)));
|
||||
}
|
||||
|
||||
BridgedSlab PassContext_freeSlab(BridgedPassContext passContext,
|
||||
BridgedSlab slab) {
|
||||
auto *inv = castToPassInvocation(passContext);
|
||||
return toBridgedSlab(inv->freeSlab(castToSlab(slab)));
|
||||
}
|
||||
|
||||
void PassContext_notifyChanges(BridgedPassContext passContext,
|
||||
enum ChangeNotificationKind changeKind) {
|
||||
LibswiftPassInvocation *inv = castToPassInvocation(passContext);
|
||||
|
||||
Reference in New Issue
Block a user