... with a fix for a non-assert build crash: I used the wrong ilist type for SlabList. This does not explain the crash, though. What I think happened here is that llvm miscompiled and put the llvm_unreachable from the Slab's deleteNode function unconditionally into the SILModule destructor.
Now by using simple_ilist, there is no need for a deleteNode at all.
A StackList is the best choice for things like worklists, etc., if no random access is needed.
Regardless of how large a Stack gets, there is no memory allocation needed (except maybe for the first few uses in the compiler run).
All operations have (almost) zero cost.
The needed memory is managed by the SILModule. Initially, the memory slabs are allocated with the module's bump pointer allocator. In contrast to bump pointer allocated memory, those slabs can be freed again (at zero cost) and then recycled.
StackList is meant to be a replacement for llvm::SmallVector, which needs to malloc after the small size is exceeded.
This is more a usability than a compile time improvement.
Usually we think hard about how to correctly use an llvm::SmallVector to avoid memory allocations: we chose the small size wisely and in many cases we keep a shared instance of a SmallVector to reuse its allocated capacity.
All this is not necessary by using a StackList: no need to select a small size and to share it across usages.