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:
Erik Eckstein
2021-04-23 20:26:42 +02:00
parent d49108da07
commit 14422cdb50
8 changed files with 235 additions and 5 deletions

View File

@@ -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);