Progress on Opaque SIL Values

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-ir or later: Add a RUN line 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-silgen to reach verified SIL, but without running any diagnostic or mandatory passes.
  • For a test using %target-run-simple-swift, we have a build target check-swift-optimize_none_with_opaque_values that will compile and run your test under -enable-sil-opaque-values.
  • Tests that only go up to -typecheck or 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-backtrace using 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 SILFunctionConventions to 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 introducing isLoadableOrOpaque.
  • Much of what is backing opaque values today in the compiler relies upon the SILAddressConventions type and the AddressLowering pass, so they're worth a read.
11 Likes