Unreachable blocks possess some challenges to autodiff since in reverse pass (pullback generation) we need to execute the function backwards, pushing the values from return BB back to entry block. As a result, unreachable blocks might become reachable from the return BB and this might cause all kind of issues.
Many tests that use `-parse-stdlib` only do so because they want access
to the Builtin module. Now that we have the flag and ability to import
it, use that instead.
Add a new mandatory BooleanLiteralFolding pass which constant folds conditional branches with boolean literals as operands.
```
%1 = integer_literal -1
%2 = apply %bool_init(%1) // Bool.init(_builtinBooleanLiteral:)
%3 = struct_extract %2, #Bool._value
cond_br %3, bb1, bb2
```
->
```
...
br bb1
```
This pass is intended to run before DefiniteInitialization, where mandatory inlining and constant folding didn't run, yet (which would perform this kind of optimization).
This optimization is required to let DefiniteInitialization handle boolean literals correctly.
For example in infinite loops:
```
init() {
while true { // DI need to know that there is no loop exit from this while-statement
if some_condition {
member_field = init_value
break
}
}
}
```
Adds derivatives to already existing initializers that allow converting between floating point type. For example converting a Float to a Double.
Co-authored-by: Jaap Wijnen <jaap@passivelogic.com>
For linear maps containing control-flow, closures (representing the pullbacks
of intermediate values) may be passed as arguments, however, they may be
hidden behind a branch-tracing enum (tracing execution flow of the original
function).
Such linear maps did not use to get inlining benefits as the compiler
could not see that the intermediate pullback closures were actually part
of the input.
This change modifies the inliner logic to correctly award inlining
benefits to linear maps containing control-flow, by checking if a
"callee" in the linear map actually traces back to an input closure that
was received as part of a branch-tracing enum input argument.
Fixes#68945
Add `Differentiable` requirements to pattern substitutions / pattern generic signature when calculating constrained function type. Also, add requirements for differentiable results as well.
Fixes#65487
The use of 'nocapture' for parameters and return values is incorrect for C++ types, as they can actually capture a pointer into its own value (e.g. std::string in libstdc++)
rdar://115062687
Optional's `init_enum_data_addr` and `inject_enum_addr` instructions are generated in presence of non-loadable Optional values. The compiler used to treat these instructions as inactive, and this resulted in silent run-time
issues described in #64223.
The patch marks `init_enum_data_addr` as "active" if its Optional operand is also active, and in PullbackCloner we differentiate through it and the related `inject_enum_addr`.
However, we only determine this relation in simple cases when both instructions are in the same block. There is no def-use relation between them (both take the same Optional operand), so if there is more than one set of instructions
operating on the same Optional, or there is some control flow, we currently bail out.
In PullbackCloner, we walk over instructions in reverse order and start from `inject_enum_addr` and its `Optional<Wrapped>.TangentVector` operand. Assuming that is is already initialized, we emit an `unchecked_take_enum_data_addr` and set it as the adjoint buffer of `init_enum_data_addr`. The Optional value is
invalidated, and we have to destroy the enum data address later when we reach `init_enum_data_addr`.
We need a lowered type for branch trace enum in order to compute linear map tuple type. However, the lowering of branch trace enum type depends on the types of its elements (the payloads are linear map tuples of predecessor BB).
As lowered types are cached, we cannot populate branch trace enum entries in the end as we did before: we already used wrong lowered types for linear map tuples.
Traverse basic blocks in reverse post-order traverse order building linear map tuples and branch tracing enums in one go, ensuring that we've done with predecessor BBs before processing the BB itself.
This PR refactors the ASTDumper to make it more structured, less mistake-prone, and more amenable to future changes. For example:
```cpp
// Before:
void visitUnresolvedDotExpr(UnresolvedDotExpr *E) {
printCommon(E, "unresolved_dot_expr")
<< " field '" << E->getName() << "'";
PrintWithColorRAII(OS, ExprModifierColor)
<< " function_ref=" << getFunctionRefKindStr(E->getFunctionRefKind());
if (E->getBase()) {
OS << '\n';
printRec(E->getBase());
}
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
// After:
void visitUnresolvedDotExpr(UnresolvedDotExpr *E, StringRef label) {
printCommon(E, "unresolved_dot_expr", label);
printFieldQuoted(E->getName(), "field");
printField(E->getFunctionRefKind(), "function_ref", ExprModifierColor);
if (E->getBase()) {
printRec(E->getBase());
}
printFoot();
}
```
* Values are printed through calls to base class methods, rather than direct access to the underlying `raw_ostream`.
* These methods tend to reduce the chances of bugs like missing/extra spaces or newlines, too much/too little indentation, etc.
* More values are quoted, and unprintable/non-ASCII characters in quoted values are escaped before printing.
* Infrastructure to label child nodes now exists.
* Some weird breaks from the normal "style", like `PatternBindingDecl`'s original and processed initializers, have been brought into line.
* Some types that previously used ad-hoc dumping functions, like conformances and substitution maps, are now structured similarly to the dumper classes.
* I've fixed the odd dumping bug along the way. For example, distributed actors were only marked `actor`, not `distributed actor`.
This PR doesn't change the overall style of AST dumps; they're still pseudo-S-expressions. But the logic that implements this style is now isolated into a relatively small base class, making it feasible to introduce e.g. JSON dumping in the future.
For some values we cannot compute types for differentiation (for example,
tangent vector type), so it is better to diagnose them earlier. Otherwise we hit
assertions when generating code for such invalid values.
The LIT test is a reduced reproducer from the issue #66996. Before the patch the
compiler crashed while trying to get a tangent vector type for the following
value (partial_apply):
%54 = function_ref @$s4null1o2ffSdAA1FV_tFSdyKXEfu0_ :
$@convention(thin) @substituted <τ_0_0> (@inout_aliasable Double)
-> (@out τ_0_0, @error any Error) for <Double>
%55 = partial_apply [callee_guaranteed] %54(%2) :
$@convention(thin) @substituted <τ_0_0> (@inout_aliasable Double)
-> (@out τ_0_0, @error any Error) for <Double>
Now we emit a diagnostic instead.
The patch resolves issues #66996 and #63331
When the differentiating a function containing loops, we allocate a linear map context object on the heap. This context object may store non-trivial objects, such as closures, that need to be released explicitly. Fix the autodiff linear map context allocation builtins to correctly release such objects and not just free the memory they occupy.
This commit changes fixit messages from a question/suggestion to an
imperative message for protocol conformances and switch-case. Addresses
https://github.com/apple/swift/issues/67510.
LoadableByAddress was accidentally changing ownership of
direct_unowned values to @in (owned). This generates unsupported SIL
for on-stack partial applies, which now breaks SIL verification.
This also resulted in extra copies of values inside of closure
contexts. Before calling the original function, the value would need to
be copied onto the stack and the context would be destroyed. Now, we
simply pass a pointer directly from the closure context. See
IRGen/indirect_argument.sil+huge_partial_application.
I'm pretty sure fixing this has no effect on the mangling of public symbols.
Introduce the notion of "semantic result parameter". Handle differentiation of inouts via semantic result parameter abstraction. Do not consider non-wrt semantic result parameters as semantic results
Fixes#67174
It is necessary for opaque values where for casts that will newly start
out as checked_cast_brs and be lowered to checked_cast_addr_brs, since
the latter has the source formal type, IRGen relies on being able to
access it, and there's no way in general to obtain the source formal
type from the source lowered type.
The patch resolves#67402.
When the original function has a tuple result type, we should append
thunkedLinearMap as the last element of the tuple to match the function
declaration. Before this patch, the compiler used to wrap the original result
tuple and thunkedLinearMap into another tuple, and caused the verifier error.
Before the patch:
return %{{.*}} : $((Float, Double), @callee_guaranteed (Float) -> X.TangentVector)
After the patch:
return %{{.*}} : $(Float, Double, @callee_guaranteed (Float) -> X.TangentVector)
The above referenced issue was causing a compiler crash when writing
differentiable protocols and corresponding implementers, without importing
the `_Differentiation` module.
Changes in this CR fix the issue by marking any `@differentiable`
attributes as invalid, if the `_Differentiation` module has not been
imported. This ignores the `@differentiable` attributes when the
protocol witnesses are being verified. Witness verification was previously
leading to an error (due to missing `@differentiable` attribute on the protocol
requirement implementer), and the corresponding diagnostic emission code was
then leading to a crash, because it was expecting the `_Differentiation`
module to be present.
As described in the issue #62922, the compiler should not allow to discard @noDerivative attribute and keep @differentiable. The patch adds a diagnostic for this case.
Resolves#62922.
Now that `InferredGenericSignatureRequest` creates
`StructuralRequirement`s from of the generic signature with valid source
locations, additional redundancy warnings are produced. Update tests
with the new warnings.
* move the apply of partial_apply transformation from simplify-apply to simplify-partial_apply
* delete dead partial_apply instructions
* devirtualize apply, try_apply and begin_apply