Skip to content

SIL: add a StackList data structure with zero cost operations. #36819

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 11, 2021

Conversation

eeckstein
Copy link
Contributor

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.

@eeckstein eeckstein requested a review from atrick April 8, 2021 18:14
@eeckstein
Copy link
Contributor Author

@swift-ci test

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.
plus: I moved both data structures into a separate header file.
@eeckstein
Copy link
Contributor Author

@swift-ci smoke test

@eeckstein eeckstein merged commit 553d441 into swiftlang:main Apr 11, 2021
@eeckstein eeckstein deleted the stacklist branch April 11, 2021 15:41
@aschwaighofer
Copy link
Contributor

This appears to be implicated in the failure in https://ci.swift.org/job/oss-swift_tools-R_stdlib-RD_test-simulator/5997/.

@atrick
Copy link
Contributor

atrick commented May 4, 2021

@eeckstein do you have a plan for instruction worklists? There's a general purpose SILInstructionWorklist and a more efficient PtrWorklist currently that use the LLVM ADTs.

@atrick
Copy link
Contributor

atrick commented May 4, 2021

@eeckstein I'm sure this won't be as efficient as the highly optimized SmallVector, but I generally prefer pass-level allocation because I don't need to contort all my pass designs to reuse malloc'd memory and I can move implementation into the .cpp files.

@atrick
Copy link
Contributor

atrick commented May 4, 2021

@eeckstein @gottesmm my only real complaint is that discoverability of SIL-specific ADTs is hard. We may need a SIL/Utils header subdirectory

@eeckstein
Copy link
Contributor Author

@atrick SILInstructionWorklist is a more high-level data structure for SILCombine. But yes, I'd like to have the same as BasicBlockWorklist for SILNodes (SILValue and instructions) - by doing the same "set" trick as with BasicBlockSet. My motivation for this is mainly to make those data structures available in libswift, where we don't have the LLVM ADTs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants