`SILBuilder::createAllocStack` expects a debug variable when the location is a `VarDecl`. Since we are in pullbacks, there's no debug variables so we pass an empty one.
General support for debug-info-in-pullbacks will be added as part of SR-13535.
Also add a negative test for SR-13866.
Resolves SR-13865.
AD-generated data structures (linear map structs and branching trace enums) do not need to be resilient data structures. These decls ade missing a `@frozen` attribute.
Resolves rdar://71319547.
This makes it easier to understand conceptually why a ValueOwnershipKind with
Any ownership is invalid and also allowed me to explicitly document the lattice
that relates ownership constraints/value ownership kinds.
I have a need to have SwitchEnum{,Addr}Inst have different base classes
(TermInst, OwnershipForwardingTermInst). To do this I need to add a template to
SwitchEnumInstBase so I can switch that BaseTy. Sadly since we are using
SwitchEnumInstBase as an ADT type as well as an actual base type for
Instructions, this is impossible to do without introducing a template in a ton
of places.
Rather than doing that, I changed the code that was using SwitchEnumInstBase as
an ADT to instead use a proper ADT SwitchEnumBranch. I am happy to change the
name as possible see fit (maybe SwitchEnumTerm?).
We'll need this to get the right 'selfDC' when name lookup
finds a 'self' declaration in a capture list, eg
class C {
func bar() {}
func foo() {
_ = { [self] in bar() }
}
}
Previously, `LinearMapInfo::shouldDifferentiateInstruction` had a special case
for `copy_value`, returning true for `copy_value` instructions with an active
operand.
This is unexpected and led to "leaked owned value" ownership verification
failures due to unnecessarily cloned `copy_value` instructions during
differential generation.
Now, the special case is removed, fixing the failures.
`shouldDifferentiateInstruction` returns true for `copy_value` instructions
whose operand and result are both active.
Resolves SR-13530.
Fixes foward-mode crashed related to:
- Missing tangent buffers for non-wrt `inout` parameters.
- Tangent buffers not being initialized due to the corresponding original
buffer intialization instructions being non-active.
- Non-varied indirect results not being initialized.
- `emitDestroyValue` crashes due to `TangentVector` value category mismatch.
Resolves TF-984 and SR-13447.
Co-authored-by: Dan Zheng <danielzheng@google.com>
Make the differentiation transform generate transparent, ossa
reabstraction thunks.
This enables these thunks to be inlined into other ossa functions (e.g.
generated VJP and pullback functions) during mandatory inlining.
Resolves TF-989.
Unblocks further autodiff-related optimizations: SR-13390.
Fix SIL pullback function type calculation: remap original `unowned` results to
the correct pullback parameter convention depending on the `TangentVector` type
lowering.
Make `PullbackCloner` visitors for the following instructions check and handle
tangent value categories: `struct`, `struct_extract`, `tuple`, `destructure_tuple`.
Add differentiation tests for `Optional` struct and class stored properties,
exercising the instruction visitors above.
Resolves SR-13430.
Adds forward mode support for `apply` instruction with `inout` arguments.
Example of supported code:
```
func add(_ x: inout Float, _ y: inout Float) -> Float {
var result = x
result += y
return result
}
print(differential(at: 1, 1, in: add)(1, 1)) // prints "2"
```
Previously, JVP/VJP generation used a "return undef" hack when
differential/pullback values did not match the expected return type.
This was relevant before differentiation supported "loadable types with
address-only tangent types", which was diagnosed.
Now that support for the above exists, "return undef" should be removed and
replaced with an assertion.
Add differentiation support for non-active `try_apply` SIL instructions.
Notable pullback generation changes:
* Original basic blocks are now visited in a different order:
* starting from the original basic block, all its predecessors
* are visited in a breadth-first search order. This ensures that
* all successors of any block are visited before the block itself.
Resolves TF-433.
Fix `Optional` differentiation crash for non-resilient `Wrapped` reference type.
Add `NonresilientTracked` type to `DifferentiationUnittest` for testing.
Resolves SR-13377.
Pullback generation now supports `switch_enum` and `switch_enum_addr`
instructions for `Optional`-typed operands.
Currently, the logic is special-cased to `Optional`, but may be generalized in
the future to support enums following general rules.
Since the two ExtInfos share a common ClangTypeInfo, and C++ doesn't let us
forward declare nested classes, we need to hoist out AnyFunctionType::ExtInfo
and SILFunctionType::ExtInfo to the top-level.
We also add some convenience APIs on (AST|SIL)ExtInfo for frequently used
withXYZ methods. Note that all non-default construction still goes through the
builder's build() method.
We do not add any checks for invariants here; those will be added later.
Fix pullback generation for `unchecked_ref_cast` and `upcast` instructions
for class types with an address tangent value category.
Upstream end-to-end class differentiation tests.
Start `linear_function` canonicalization skeleton copying from
`differentiable_function` canonicalization. For now, transpose function
operands are filled in with `undef`.
`JVPCloner.h` is now tiny: `JVPCloner` exposes only a `bool run()` entry point.
All of the implementation is moved to `JVPCloner::Implementation` in
`JVPCloner.cpp`. Methods can be defined directly in `JVPCloner.cpp` without
separate declarations.
`VJPCloner.h` is now tiny: `VJPCloner` exposes only a `bool run()` entry point.
All of the implementation is moved to `VJPCloner::Implementation` in
`VJPCloner.cpp`. Methods can be defined directly in `VJPCloner.cpp` without
separate declarations.
Clarify `llvm_unreachable` after exhaustive switch is needed to silence
MSVC C4715, so we don't accidentally remove it.
Standardize some assertion messages.
Reimplement `PullbackCloner` using the pointer-to-implementation pattern.
`PullbackCloner.h` is now tiny: `PullbackCloner` exposes only a `bool run()`
entry point.
All of the implementation is moved to `PullbackCloner::Implementation` in
`PullbackCloner.cpp`.
Benefits of this approach:
- A main benefit is that methods can be defined directly in `PullbackCloner.cpp`
without needing to separately declare them in `PullbackCloner.h`.
- There is now no code duplication between `PullbackCloner.h` and
`PullbackCloner.cpp`.
- Consequently, method documentation is easier to read because it appears
directly on method definitions, instead of on method declarations in a
separate file. This is important for documentation of `PullbackCloner`
instruction visitor methods, which explain pullback transformation rules.
- Incremental recompilation may be faster since `PullbackCloner.h` changes less
often.
Partially resolves SR-13182.
Add base type parameter to `TangentStoredPropertyRequest`.
Use `TypeBase::getTypeOfMember` instead of `VarDecl::getType` to correctly
compute the member type of original stored properties, using the base type.
Resolves SR-13134.
Reverse-mode differentiation now supports `apply` instructions with multiple
active "semantic results" (formal results or `inout` parameters).
The "cannot differentiate through multiple results" non-differentiability error
is lifted.
Resolves TF-983.
This call only succeeds if the accessor has already been synthesized, which
makes it fragile. Replace it with calls to getOpaqueAccessor(),
which lazily evaluate the right requests ahead of time.
Previously, PullbackEmitter assumed that original values' value category
matches their `TangentVector` types' value category. This was problematic
for loadable types with address-only `TangentVector` types.
Now, PullbackEmitter starts to support differentiation of loadable types with
address-only `TangentVector` types. This patch focuses on supporting and testing
class types, more support can be added incrementally.
Resolves TF-1149.
Use TangentStoredPropertyRequest in differentiation transform.
Improve non-differentiability diagnostics regarding invalid stored
property projection instructions:
`struct_extract`, `struct_element_addr`, `ref_element_addr`.
Diagnose the following cases:
- Original property's type does not conform to `Differentiable`.
- Base type's `TangentVector` is not a struct.
- Tangent property not found: base type's `TangentVector` does not have a
stored property with the same name as the original property.
- Tangent property's type is not equal to the original property's
`TangentVector` type.
- Tangent property is not a stored property.
Resolves TF-969 and TF-970.
- Show SIL type when printing `AdjointValue`.
- Add utilities to print `PullbackEmitter` adjoint value and buffer mappings.
- Print generated VJP before printing generated pullback.
- This is useful because pullback generation may crash after VJP
generation succeeds.