Skip to content

[os_log][SIL Optimization] Make new os log APIs @_transparent and change OSLogOptimization pass so that inlining is not performed. #24971

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

Conversation

ravikandhadai
Copy link
Contributor

@atrick @eeckstein, I have made a change to the OSLogOptimization pass to address an issue raised by @gottesmm. Basically, I have removed inlining from the pass, which caused problems as the pass was in the mandatory pipeline but wasn't using Mandatory inlining (which happens earlier). The reason for that was that the pass used @_semantics attribute to identify log calls, extract the custom string interpolation argument of the call, and identify the instructions that must be constant evaluated. The call and the @_semantics attribute will be lost by mandatory inlining.

This commit changes how the instructions to constant evaluate are identified. The new approach uses the "initializer" calls of the custom string interpolation type: 'OSLogMessage' to drive the constant evaluation and folding. The initializer calls need not be inlined and are constant evaluable. The main benefit of the current approach is that, it will kick in at every place where the type 'OSLogMessage' is instantiated using a string interpolation, regardless of whether or not it is passed to a os_log call. E.g. the optimization will also apply to cases like the following.

    let x: OSLogMessage = "Hello \(1)"
    let y = x.formatString // This will be constant folded. 

A note: the diagnostics in this pass will be subsumed and enhanced by a new pass that will enforce the library implementation model (by checking if the implementation is constant evaluable etc.) and also the user model for the log calls (by checking if the log calls are passed a string interpolation). The diagnostics in this pass will eventually become redundant and should just be asserts/noops.

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 7c71b2c2d5cd871e21344f14d4b9ab1cff354bdb

Copy link
Contributor

@gottesmm gottesmm left a comment

Choose a reason for hiding this comment

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

So to be clear: you marked the initializer with a semantic call so you could just constant fold it instead of inlining it?

SILInstruction *currInst = &(*currI);

// Break if currInst is a release_value of 'oslogMessage'.
if (auto *releaseValueInst = dyn_cast<ReleaseValueInst>(currInst)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. For this to work when ownership is enabled, you need to at least handle destroy_value and probably need to look through copy_value.
  2. Is this a struct or a class? If it is a class, you probably also need strong_release.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So to be clear: you marked the initializer with a semantic call so you could just constant fold it instead of inlining it?

Yes, that's right. One thing I would add is that the initializer was always constant evaluated but was mandatorily inlined earlier and then evaluated. Now it is marked with @_semantics and not mandatorily inlined (it can still be constant evaluated), and more importantly it is used to identify the range of instructions to evaluate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  • For this to work when ownership is enabled, you need to at least handle destroy_value and probably need to look through copy_value.
  • Is this a struct or a class? If it is a class, you probably also need strong_release.

This is a struct. I see. Thanks for the update, I will watch out for that. Actually, this condition is more of a safe guard and in reality the evaluation should break even before this instruction as there will instructions that it cannot constant evaluate (due to the implementation of os_log) and will bail out earlier.

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test linux platform

@gottesmm
Copy link
Contributor

Can you add the destroy-value and copy value plz

@ravikandhadai
Copy link
Contributor Author

Can you add the destroy-value and copy value plz

Okay. Will copy_value happen just before destroy_value? In that case, it and also destroy_value can be used as a break condition

@ravikandhadai
Copy link
Contributor Author

ravikandhadai commented May 24, 2019

I pushed a commit that makes the OSLogOptimization pass work on ownership SIL. The following are the two main changes:

  • Fold results of instructions like destructure_tuple that could return multiple results and some of which are foldable.
  • Include destroy_value and copy_value in end of lifetime checks that is used to stop evaluation.

There is still a problem in this pass that causes ownership verification to fail. (Basically, the string initialization instructions that are created to fold string literals are not released.) Excepting this, the pass works on ownership SIL (i.e., when ownership stripping happens after serialization). I will a create follow up PR to address this problem, and also create PRs for changes to the constant evaluator to handle ownership SIL instructions.

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 7c71b2c2d5cd871e21344f14d4b9ab1cff354bdb

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 7c71b2c2d5cd871e21344f14d4b9ab1cff354bdb

@gottesmm
Copy link
Contributor

@ravikandhadai was the lack of releasing of the initialization instructions a /real/ bug?

@gottesmm
Copy link
Contributor

Also, you may want to look at destructure_struct as well.

@ravikandhadai ravikandhadai force-pushed the oslog-optimization-transparent branch from 44a397d to 4d4609a Compare June 12, 2019 00:25
@ravikandhadai
Copy link
Contributor Author

@ravikandhadai was the lack of releasing of the initialization instructions a /real/ bug?

Yes, it was a leak, but only discovered by the ownership verifier. Basically, when an instruction like %str = struct_extract S.str is folded and replaced by a string constant, the optimizer should also add a release/destroy _value instruction. I have updated the code so that cases like these are handled. Now the optimization pass also works with ownership SIL (but for rdar://51512044).

The main changes for this is in the function destroyFoldedValueAtEndOfUse which is called by substituteConstants.

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 44a397dac189ef63d1da9109eea7ea549a7bd58b

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4d4609a

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test macOS Platform

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4d4609a

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please smoke test macOS Platform

1 similar comment
@ravikandhadai
Copy link
Contributor Author

@swift-ci Please smoke test macOS Platform

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please test macOS Platform

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4d4609a

@ravikandhadai
Copy link
Contributor Author

@swift-ci Please clean test macOS Platform

@ravikandhadai ravikandhadai merged commit 6d3e3f0 into swiftlang:master Jun 13, 2019
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