-
Notifications
You must be signed in to change notification settings - Fork 10.5k
SILGen: simplify cleanups and avoid critical edges. #19886
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
Conversation
@swift-ci test. |
@swift-ci benchmark. |
@swift-ci test source compatibility. |
Build comment file:Performance: -O
Performance: -Osize
Performance: -Onone
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the regressions before you merge the PR. Noise: Sometimes the performance results (not code size!) contain false alarms. Unexpected regressions which are marked with '(?)' are probably noise. If you see regressions which you cannot explain you can try to run the benchmarks again. If regressions still show up, please consult with the performance team (@eeckstein). Hardware Overview
|
Build failed |
Build failed |
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.
Looks like you are dicing/splicing. I think I found some nice feedback. Want to give it to you before you slice and dice more.
lib/SILGen/Condition.cpp
Outdated
|
||
SGF.B.emitBlock(TrueBB); | ||
void Condition::enter(SILGenFunction &SGF, SILBasicBlock *destBB) { | ||
assert(destBB && "Cannot enter a finished branch."); |
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.
branch
=> block
?
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.
Done.
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.
One last one.
@gottesmm thanks for looking at this. I'd like to add feedback from review as separate commits so you don't need to re-review anything, but in this case, you hadn't finished the first round, and rebasing was part of the feedback. So the commits are all new, but nothing has changed functionally. Unfortunately, github isn't listing the commits in the right order anymore--trust that they are in the right order on the branch. Incidentally, I think it's better to clone-for-review for anything non-trivial. |
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.
I still think 66bc68151dcfcc9c45869f08fab4220054adf12e should be before the previous one. What you would do is do the same change but make it so that you can pass false in that place. Then all usages of Condition pass false and we can eliminate that unfortunate code... no? I think together the end state is fine though.
Also:
- I wanted to give a +1 on a particular comment. It reads awesome!
- Found a typo.
Beyond that LGTM.
@@ -32,10 +32,12 @@ namespace Lowering { | |||
|
|||
/// A condition is the result of evaluating a boolean expression as | |||
/// control flow. | |||
/// | |||
/// For each Condition instance, `enterTrue` must be called before `complete`. | |||
/// If `enterFalse` is skipped, then an empty fall-through block is created. |
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.
Nice comment!
lib/SILGen/Condition.h
Outdated
/// complete - Complete this conditional execution. This should be called | ||
/// only after all other calls on this Condition have been made. | ||
/// This leaves SGF's SILGenBuilder at the continution block. |
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.
continution
=> continuation
@swift-ci benchmark. |
Rerunning benchmarks to see if the few changes were spurious. Locally, I see only improvements. In particular, CI reported a 10% regression on IterateData, but I see a 10% improvement (although it seems very flaky). The only reason for regression would be incidental change to inlining because the cost model doesn't handle unconditional branches sensibly. For code size, there is a 0.1% decrease in the benchmark suite and 0.1% increase in the stdlib. |
@swift-ci benchmark. |
I see no measurable impact on compile time. |
Build comment file:Performance: -O
Performance: -Osize
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the regressions before you merge the PR. Noise: Sometimes the performance results (not code size!) contain false alarms. Unexpected regressions which are marked with '(?)' are probably noise. If you see regressions which you cannot explain you can try to run the benchmarks again. If regressions still show up, please consult with the performance team (@eeckstein). Hardware Overview
|
@swift-ci test. |
1 similar comment
@swift-ci test. |
Build failed |
This avoids critical edges, which will be split in the optimizer anyway.
Allow a new SILBuilder to be created for an insertion point, while providing all of its necessary context. Ultimately, the builder's constructor should take an insertion point, DebugLocation, and context. Then we won't need to pass SILLocation to all of its methods. This makes much more sense and is much safer than saving the insertion point via an RAII object or defining a separate SILBuilderWithScope. Those broken abstractions should go away.
This is the best way to inherit the provided SILGenBuilder's debug scope and context, but insert at a different SIL location.
This code was attempting to generate a critical edge on one side of a condition. Not only is that undesirable, but it breaks the abstraction and results an a lot of complexity. As usual, fixing critical edges simply means removing unnecessary complexity.
This is the one place in SILGen where we need to explicitly split the critical edge. createBasicBlockAndBranch is a simply utility for that.
Avoid emitting unnecessary basic block for cleanup chains. This is a general approach that handles all cases while simplifying SILGen emission and keeping the CFG in a valid state during SILGen.
@swift-ci test. |
@swift-ci test. |
Keep the CFG in a valid, critical-edge free state that the SIL passes can handle.
Replace the ad-hoc on-the-fly cleanup block optimization with a more general block merging.
This simplifies SILGen now and will in subsequent commits allow massive simplification of SIL APIs and SIL passes.
Note that there's no downside to avoiding critical edges since they will be split anyway any various points in the SIL pipeline. However, there are many passes and utilities that can be made much simpler and more compute time and memory efficient.