Hi everyone,
SIL opaque values (-enable-sil-opaque-values) is a compiler infrastructure project that defers the lowering of resilient and generic types to addresses, until the AddressLowering pass, so they are treated like loadable SSA values for better optimization. It's an idea proposed nearly 10 years ago (!) in Proposal: Opaque SIL values . I'll defer to the original proposal for an overview and additional motivation, as it is still true today.
The first stage of this project has been to make SILGen fully compatible with SIL opaque values and run AddressLowering soon after SILGen. This would allow us to have -enable-sil-opaque-values on by default and set us up to unlock the first of several benefits of this project: simplify SILGen.
Many people over the years have put in work to get that first stage done. Unfortunately, every time we have reached a milestone in terms of full functionality, such as building the standard library cleanly, we've regressed.
Progress is lost primarily from new contributions to SILGen or SIL that are not tested under SIL Opaque Values. So, I'd like to ask everyone to please test your changes under -enable-sil-opaque-values too:
- For a non-executable test doing
-emit-sil,-emit-iror later: Add aRUNline with-enable-sil-opaque-values. That covers both SILGen and AddressLowering compatibility.- If you have separate SILGen and SIL test files, you can test just SILGen under opaque values with
-emit-silgen-ossa -enable-sil-opaque-values, which goes a bit further than-emit-silgento reach verified SIL, but without running any diagnostic or mandatory passes.
- If you have separate SILGen and SIL test files, you can test just SILGen under opaque values with
- For a test using
%target-run-simple-swift, we have a build targetcheck-swift-optimize_none_with_opaque_valuesthat will compile and run your test under-enable-sil-opaque-values. - Tests that only go up to
-typecheckor an earlier stage of the compiler don't need additional testing.
In an effort to prevent further backsliding as work continues on opaque values, I plan to increase the amount of testing and usage of it:
- Specific sub-targets of the standard library will start building with the flag enabled. So far, we have
swift-backtraceusing it and I'm eyeing Volatile, RegexParser, RegexBuilder, and Distributed next. - I've started auditing and automatically updating tests to have an additional RUN line exercising opaque values.
- CI will start running the execution tests under opaque values. This will mean you won't need a second RUN line if your test is using
%target-run-simple-swift
Here are some guidelines while working on new code in SILGen:
- Rely on
SILFunctionConventionsto determine whether an argument or result of a function is transferred indirectly (i.e., as an address) or directly as an SSA value. - Avoid using
TypeLowering::isAddressOnly(), as it will give only the fixed, post-AddressLowering answer, which is wrong in SILGen under opaque values. I'm working to make that API unavailable within SILGen with this PR and introducingisLoadableOrOpaque. - Much of what is backing opaque values today in the compiler relies upon the
SILAddressConventionstype and theAddressLoweringpass, so they're worth a read.