Skip to content

4.2 SILCombiner::propagateConcreteTypeOfInitExistential fixes. #17554

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 4 commits into from
Jun 27, 2018
Merged

4.2 SILCombiner::propagateConcreteTypeOfInitExistential fixes. #17554

merged 4 commits into from
Jun 27, 2018

Conversation

atrick
Copy link
Contributor

@atrick atrick commented Jun 27, 2018

Merge SILCombine fixes onto 4.2.

Fixes <rdar://40555427> [SR-7773]:
SILCombiner::propagateConcreteTypeOfInitExistential fails to full propagate type
substitutions.

Fixes <rdar://problem/40923849>
SILCombiner::propagateConcreteTypeOfInitExistential crashes on protocol
compositions.

Some simple low-risk NFC changes are merged in order to localize the important higher-risk differences between 4.2 and master. Some of the new code required finessing into 4.2, mainly because the SIL-level SubstitionMaps weren't merged.

Raj Barik and others added 4 commits June 26, 2018 19:46
…ial.cpp/h in order for other passes such as ExistentialSpecializer to use it apart from SILCombiner
In an upcoming bug fix, I want to pass SILBuilderContext to a
utility. I could continue reusing SILBuilder, even though the utility
must set its own insertion point and debug location. However, this is
terrible practice that I don't want to perpetuate.

The lifetime of a SILBuilder should correspond to a single insertion
point and debug location. That's the only sane way to preserve debug
information in SIL passes.

There are various pieces of contextual state that we've been adding to
the SILBuilder. Those have made it impossible to use SILBuilder
correctly. I'm pulling the context out, so clients can begin using
better practices. In the future, we can make SILBuilderContext
polymorphic, so passes can extend it easily with arbitrary
callbacks. We can also make it self-contained so we don't need to pass
around pointers to an InsertedInst list anymore.

(cherry picked from commit df94dff)
Fixes <rdar://40555427> [SR-7773]:
SILCombiner::propagateConcreteTypeOfInitExistential fails to full propagate type
substitutions.

Fixes <rdar://problem/40923849>
SILCombiner::propagateConcreteTypeOfInitExistential crashes on protocol
compositions.

This rewrite fixes several fundamental bugs in the SILCombiner optimization that
propagates concrete types. In particular, the pass needs to handle:

- Arguments of callee Self type in non-self position.
- Indirect and direct return values of Self type.
- Types that indirectly depend on Self within callee function signature.
- Protocol composition existentials.
- All of the above need to work for protocol extensions as well as witness methods.
- For protocol extensions, conformance lookup should be based on the existential's conformance list.

Additionally, the optimization should not depend on a SILFunction's DeclContext,
which is not serialized. (In fact, we should prevent SIL passes from using
DeclContext). Furthermore, the code needs to be expressed in a way that one can
reason about correctness and invariants.

The root cause of these bugs is that SIL passes are written based on untested
assumptions of Swift type system. A SIL pass needs to handle all verifiable SIL
input because passes need to be composable. Bail-out logic can be added to
simplify the design; however, _the bail-out logic itself cannot make any
assumptions about the language or type system_ that aren't clearly and
explicitly enforced in the SIL verifier. This is a common mistake and major
source of bugs.

I created as many unit tests as I reasonably could to prevent this code from
regressing. Creating enough unit tests to cover all corner cases that were
broken in the original code would be intractable. But the code has been
simplified such that many corner cases disappear.

This opens up some oportunity for generalizing the optimization and eliminating
special cases. However, I want this PR to be limited to fixing correctness
issues only. In the long term, it would be preferable to replace this
optimization entirely with a much more powerful general type propagation pass.

(cherry picked from commit 9d4b4c7)
@atrick
Copy link
Contributor Author

atrick commented Jun 27, 2018

@swift-ci test.

@atrick
Copy link
Contributor Author

atrick commented Jun 27, 2018

@slavapestov The last commit has the 4.2 vs master merge:
c37ce27

Don't worry, there are no wayward calls to dump.

@atrick atrick merged commit 77b6e7c into swiftlang:swift-4.2-branch Jun 27, 2018
@atrick atrick deleted the 4.2-silcombine-existential-fix branch October 16, 2018 16:25
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.

1 participant