Skip to content

CopyPropagation for SILValues with ownership. #18902

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 1 commit into from
Sep 4, 2018
Merged

CopyPropagation for SILValues with ownership. #18902

merged 1 commit into from
Sep 4, 2018

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Aug 22, 2018

This pass is part of a prototype that I implemented a year ago to experiment with opaque SIL values. The pass isn't particularly useful until after opaque values are enabled. However, we want to begin incrementally merging support for opaque values because there are interdepedencies with other work. Also, we want to be transparent about opaque values work, now that we're ramping it back up.


This is a simple "utility" pass that canonicalizes SSA SILValues with
respect to copies and destroys. It is a self-contained, provably
complete pass that eliminates spurious copy_value instructions from
scalar SSA SILValues. It fundamentally depends on ownership SIL, but
otherwise can be run efficiently after any other pass. It separates
the pure problem of handling scalar SSA values from the more important
and complex problems:

  • Promoting variables to SSA form (PredictableMemOps and Mem2Reg
    partially do this).

  • Optimizing copies within "SIL borrow" scopes (another mandatory pass
    will be introduced to do this).

  • Composing and decomposing aggregates (SROA handles some of this).

  • Coalescing phis (A BlockArgumentOptimizer will be introduced as part
    of AddressLowering).

  • Removing unnecessary retain/release when nothing within its scope
    may release the same object (ARC Code Motion does some of this).

Note that removing SSA copies was more obviously necessary before the
migration to +0 argument convention.

@atrick
Copy link
Contributor Author

atrick commented Aug 22, 2018

@swift-ci test.

@atrick
Copy link
Contributor Author

atrick commented Aug 22, 2018

@eeckstein @gottesmm @aschwaighofer high-level reviews are welcome, keeping in mind that this isn't enabled yet.

The next step is moving all the ownership utilities into a centralized API.

@atrick
Copy link
Contributor Author

atrick commented Aug 28, 2018

@swift-ci test.

@atrick
Copy link
Contributor Author

atrick commented Aug 28, 2018

@aschwaighofer @eeckstein anyone interested in reviewing this?

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 872e8e347f14f357f4dcee69514af17fcfd05bae

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 872e8e347f14f357f4dcee69514af17fcfd05bae

@atrick
Copy link
Contributor Author

atrick commented Aug 28, 2018

@aschwaighofer @eeckstein I'm rewriting all the comments now. So don't spend time on the current PR until I finish that.

@atrick
Copy link
Contributor Author

atrick commented Aug 31, 2018

@eeckstein @aschwaighofer @gottesmm
I rewrote the comments so that they are much more approachable. I strongly encourage you to give this pass a real code review, using an actual source editor with a couple windows open, paying attention to the comments. This is about the best I can do to design a pass that is both extremely efficient but still readable, with precisely-encapsulated state. It's a model for how I think SIL passes should be structured, for reasons I won't try to enumerate here, but I will answer any questions. I hope you actually enjoy reading the code this time.

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

much better now, thanks!

///
/// bb0(%arg : @owned $T, %addr : @trivial $*T):
/// (The original copy is deleted.)
/// debug_value %copy : $T
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The operand be %arg

/// %copy = copy_value %0 : $T
/// store %3 to [init] %1 : $*T
/// (The non-consuming use now uses the original value.)
/// debug_value %0 : $T
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/%0/%arg

the same on the next 2 lines

/// debug_value %copy : $T
/// (A new copy_value is inserted before the consuming store.)
/// %copy = copy_value %0 : $T
/// store %3 to [init] %1 : $*T
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/%3/%copy/


void markBlockLive(SILBasicBlock *bb, IsLive_t isLive) {
assert(isLive != Dead && "erasing live blocks isn't implemented.");
liveBlocks[bb] = isLive;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

implicitly converting an enum to a bool.
Better: liveBlocks[bb] = (isLive == LiveOut);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course. Done.

This is a simple "utility" pass that canonicalizes SSA SILValues with
respect to copies and destroys. It is a self-contained, provably
complete pass that eliminates spurious copy_value instructions from
scalar SSA SILValues. It fundamentally depends on ownership SIL, but
otherwise can be run efficiently after any other pass. It separates
the pure problem of handling scalar SSA values from the more important
and complex problems:

- Promoting variables to SSA form (PredictableMemOps and Mem2Reg
  partially do this).

- Optimizing copies within "SIL borrow" scopes (another mandatory pass
  will be introduced to do this).

- Composing and decomposing aggregates (SROA handles some of this).

- Coalescing phis (A BlockArgumentOptimizer will be introduced as part
  of AddressLowering).

- Removing unnecessary retain/release when nothing within its scope
  may release the same object (ARC Code Motion does some of this).

Note that removing SSA copies was more obviously necessary before the
migration to +0 argument convention.
@atrick
Copy link
Contributor Author

atrick commented Sep 4, 2018

@swift-ci smoke test.

@atrick atrick merged commit 423c062 into swiftlang:master Sep 4, 2018
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