-
Notifications
You must be signed in to change notification settings - Fork 10.6k
Stack allocate generic and resilient values #6389
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
Stack allocate generic and resilient values #6389
Conversation
|
@swift-ci Please test |
|
Awesome! |
|
Would it be better to extend SIL type lowering to distinguish fixed size address only types (weak references, existentials) from the generic/resilient case, eliminating the weird dependency on IRGen in the new SIL pass? |
gottesmm
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A question + a rename request.
include/swift/SIL/SILFunction.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you change this to getEntryBlock()?
tools/sil-opt/SILOpt.cpp
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question. I am worried about being able to mix IRGen and Performance passes. What is to stop me from doing so and if I do so what will happen? Should we have an additional SIL stage or something like that? (Just thinking out loud).
One could even argue that perhaps we need a separate entry point (like autolink is to the driver that only can optimize lowered SIL) or something like that.
Like I said I am just thinking out loud (unsure).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At this point nothing bad will happen and you are free to do so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok. So what will happen now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah ok. The pass was hidden by github's interface. You are just using the size information, nothing else. My worries are gone!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both passes will run in the order you specified.
|
Also, why couldn't we make these passes in a separate library. Then you don't need to do the dynamic stuff. libswiftSILIRGenPasses... |
|
(Even though I have a couple of high level thoughts... +1! Overall!) |
|
Build failed |
|
Build failed |
|
@slavapestov I don't see a good reason to replicate the recursive type lowering at the SIL level? |
|
@slavapestov Once we implement a SIL lowering pass that keeps large structs in memory (instead of aggressively exploding it) this pass will also very likely want to query IRGen for lowering properties such as size and will run in this IRGen pipeline. So will Andy's work (although it is not dependent on having an IRGenModule AFAIK). @gottesmm The pass manager has a dependency on the createPASSName() function. Moving the pass into a separate library does not fix that. |
|
@swift-ci Please test |
1 similar comment
|
@swift-ci Please test |
|
Build failed |
|
@swift-ci Please test |
1 similar comment
|
@swift-ci Please test |
|
Well, SIL already does a recursive walk over value types when lowering, it just computes less stuff than IRGen. But as long as you run the IRGen passes after serialization, it should be ok. One day we might want to come up with some abstractions to factor out duplication between SIL and IRGen type lowering. Sema has to do a recursive walk over value types too, to diagnose infinite types. @jckarter Any thoughts? |
|
SIL type lowering could definitely track some more interesting properties such as "empty", "uninhabited", and "fixed-size" that can be figured out irrespective of the concrete IR layout. I think it still makes sense to have a transitional stage between SIL and IRGen where we do SIL transformations based on properties that normally aren't determined till IRGen. |
…he heap Allocate buffers for local generic/resilient values on the stack. alloc_stack instructions in the entry block are translated using a dynamic alloca instruction with variables size. All other alloc_stack instructions in addition use llvm's stacksave/restore instrinsics to reset the stack (they could be executed multiple times and with varying sizes).
ea84151 to
9a3781c
Compare
|
@swift-ci Please smoke test |
This pipeline is run as part of IRGen and has access to the IRGenModule. Passes that run as part of this pipeline can query for the IRGenModule. We will use it for the AllocStackHoisting pass. It wants to know if a type is of non-fixed size. To break the cyclic dependency between IRGen -> SILOptimizer -> IRGen that would arise from the SILPassManager having to know about the createIRGENPASS() function IRGen passes instead of exposing this function dynamically have to add themselves to the pass manager.
Hoist alloc_stack instructions of 'generic' or resilient type to the entry block. At the same time also perform a very simple stack coloring analysis. This does not use a true liveness-analysis yet but rather employs some simple conservative checks to see whether the live ranges of two alloc_stacks might interfere. AllocStackHoisting is an IRGen SIL pass. This allows for using IRGen's type lowering information. Furthermore, hoisting and merging the alloc_stack instructions this late does not interfere with SIL optimizations because the resulting SIL never gets serialized.
9a3781c to
a87f343
Compare
|
@swift-ci Please smoke test os x |
|
@swift-ci Please smoke test |
|
@swift-ci Please benchmark |
|
@swift-ci Please benchmark |
Build comment file:Optimized (O) Regression (0)Improvement (13)
No Changes (138)
Regression (5)
Improvement (32)
No Changes (114)
|
Build comment file:Optimized (O) Regression (0)Improvement (13)
No Changes (138)
Regression (5)
Improvement (32)
No Changes (114)
|
IRGen: Allocate generic/resilient values on the stack instead of on the heap
Allocate buffers for local generic/resilient values on the stack. alloc_stack
instructions in the entry block are translated using a dynamic alloca
instruction with variables size. All other alloc_stack instructions in addition
use llvm's stacksave/restore instrinsics to reset the stack (they could be
executed multiple times and with varying sizes).
Add support of a IRGen lowering SIL pipeline
This pipeline is run as part of IRGen and has access to the IRGenModule.
Passes that run as part of this pipeline can query for the IRGenModule.
We will use it for the AllocStackHoisting pass. It wants to know when a type is of
non-fixed size.
To break the cyclic dependency between IRGen -> SILOptimizer -> IRGen that would
arise from the SILPassManager having to know about the createIRGENPASS()
function IRGen passes instead of exposing this function dynamically have to add
themselves to the pass manager.
Add an alloc_stack hoisting pass
Hoist alloc_stack instructions of 'generic' or resilient type to the entry
block. Ad the same time also perform a very simple stack coloring analysis.
This does not use a true liveness-analysis yet but rather employs some simple
conservative checks to see whether the live ranges of two alloc_stacks might
interfere.
AllocStackHoisting is an IRGen SIL pass. This allows for using IRGen's type
lowering information.