I also added a SILVerifier check that once we are in canonical SIL all
concurrent functions that are partial applied are banned from having Box
arguments.
I have not added support yet for this for address only types, so we do not crash
on that yet.
The main change is to detect infinite recursive calls under invariant conditions. For example:
func f() {
if #available(macOS 10.4.4, *) {
f()
}
}
or invariant conditions due to forwarded arguments:
func f(_ x: Int) {
if x > 0 {
f(x)
}
}
Also, improve the warning message. Instead of giving a warning at the function location
warning: all paths through this function will call itself
give a warning at the call location:
warning: function call causes an infinite recursion
Especially in case of multiple recursive calls, it makes it easier to locate the problem.
https://bugs.swift.org/browse/SR-11842
rdar://57460599
to check for improperly nested '@_semantic' functions.
Add a missing @_semantics("array.init") in ArraySlice found by the
diagnostic.
Distinguish between array.init and array.init.empty.
Categorize the types of semantic functions by how they affect the
inliner and pass pipeline, and centralize this logic in
PerformanceInlinerUtils. The ultimate goal is to prevent inlining of
"Fundamental" @_semantics calls and @_effects calls until the late
pipeline where we can safely discard semantics. However, that requires
significant pipeline changes.
In the meantime, this change prevents the situation from getting worse
and makes the intention clear. However, it has no significant effect
on the pass pipeline and inliner.
I did this by adding a kind to Arguments and making it so we have a kind that
emits as a separate NOTE when we emit diagnostics, but is emitted as a normal
argument when emitting to the bitstream.
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.
os log APIs, based on the fact that there is already a Sema check for
enforcing the user model.
Suppress the errors generated by for the _globalStringTablePointerBuiltin
when the OSLogOptimization pass emits diagnostics. This elimiantes the
cryptic error that always accompanies the diagnostics emitted by the
OSLogOptimization pass.
These were duplicated in 11 different files, and as they've gotten more
complex a few inconsistencies have snuck in. Sharing them should make future
changes easier and less bug-prone.
JVP functions are forward-mode derivative functions. They take original
arguments and return original results and a differential function. Differential
functions take derivatives wrt arguments and return derivatives wrt results.
`JVPEmitter` is a cloner that emits JVP and differential functions at the same
time. In JVP functions, function applications are replaced with JVP function
applications. In differential functions, function applications are replaced
with differential function applications.
In JVP functions, each basic block takes a differential struct containing callee
differentials. These structs are consumed by differential functions.
`VJPEmitter` is a cloner that emits VJP functions. It implements reverse-mode
automatic differentiation, along with `PullbackEmitter`.
`VJPEmitter` clones an original function, replacing function applications with
VJP function applications. In VJP functions, each basic block takes a pullback
struct (containing callee pullbacks) and produces a predecessor enum: these data
structures are consumed by pullback functions.
Canonicalizes `differentiable_function` instructions by filling in missing
derivative function operands.
Derivative function emission rules, based on the original function value:
- `function_ref`: look up differentiability witness with the exact or a minimal
superset derivative configuration. Emit a `differentiability_witness_function`
for the derivative function.
- `witness_method`: emit a `witness_method` with the minimal superset derivative
configuration for the derivative function.
- `class_method`: emit a `class_method` with the minimal superset derivative
configuration for the derivative function.
If an *actual* emitted derivative function has a superset derivative
configuration versus the *desired* derivative configuration, create a "subset
parameters thunk" to thunk the actual derivative to the desired type.
For `differentiable_function` instructions formed from curry thunk applications:
clone the curry thunk (with type `(Self) -> (T, ...) -> U`) and create a new
version with type `(Self) -> @differentiable (T, ...) -> U`.
Progress towards TF-1211.
The differentiation transform does the following:
- Canonicalizes differentiability witnesses by filling in missing derivative
function entries.
- Canonicalizes `differentiable_function` instructions by filling in missing
derivative function operands.
- If necessary, performs automatic differentiation: generating derivative
functions for original functions.
- When encountering non-differentiability code, produces a diagnostic and
errors out.
Partially resolves TF-1211: add the main canonicalization loop.
To incrementally stage changes, derivative functions are currently created
with empty bodies that fatal error with a nice message.
Derivative emitters will be upstreamed separately.
and eliminate dead code. This is meant to be a replacement for the utility:
recursivelyDeleteTriviallyDeadInstructions. The new utility performs more aggresive
dead-code elimination for ownership SIL.
This patch also migrates most non-force-delete uses of
recursivelyDeleteTriviallyDeadInstructions to the new utility.
and migrates one force-delete use of recursivelyDeleteTriviallyDeadInstructions
(in IRGenPrepare) to use the new utility.
of OSLogMessage constant evaluable and remove @_transparent annotation
from the methods. Also, improve diagnostics in the OSLogOptimization
pass as now it rely on seeing the appendInterpolation/Literal calls.
mode and separate out the code for top-level evaluation from the normal
step-by-step evaluation. This ensures that step-by-step evaluation
does not accidentally rely on any logic meant for top-level evaluation.
This change should not affect the observable behavior of the evaluator.
This will ensure that if an expert user is using this feature and makes a
mistake as a result of tweaking their code, they get an error. This will ensure
they do not ship and look into why this is happening.
This is not intended to be used by anyone except for expert stdlib users.
evaluator to precisely evaluate Builtin.assert_configuration.
Unify UnknownReason::Trap and UnknownReason::AssertionFailure error
values in the constant evaluator, now that we have 'condfail_message'
SIL instruction, which provides an error message for the traps.
@_semantics("constant_evaluable") annotation to denote constant
evaluable functions.
Add a test suite that uses the sil-opt pass ConstantEvaluableSubsetChecker.cpp
to check the constant evaluability of function in the OSLog
overlay.
1. builtin "int_expect", which makes the evaluator work on more
integer operations such as left/right shift (with traps) and
integer conversions.
2. builtin "_assertConfiguration", which enables the evaluator
to work with debug stdlib.
3. builtin "ptrtoint", which enables the evaluator to track
StaticString
4. _assertionFailure API, which enables the evaluator to report
stdlib assertion failures encountered during constant evaluation.
Also, enable attaching auxiliary data with the enum "UnknownReason"
and use it to improve diagnostics for UnknownSymbolicValues,
which represent failures during constant evaluation.
"globalStringTablePointer": String -> Builtin.RawPointer` to a
string_literal instruction if the string that is passed is constructed
from a literal. Otherwise, emit diagnostics.
This removes a bit of global state from the TypeChecker class, and
allows C function pointers to be formed to closures that capture
local functions, but have no transitive captures.
The new analysis simply checks if the captured value has been defined
yet; instead of asserting if it hasn't, we can now emit a diagnostic
using the source location tracked in the capture list.
Fixes <https://bugs.swift.org/browse/SR-4812>, <rdar://problem/40600800>.
If the final expression in a function or closure which is missing a
return has the appropriate type, rather than producing the usual
diagnostic about a missing return, produce a diagnostic with a fixit to
insert a return before thatn final expression.
h/t Nate Cook
unknown symbolic values by renaming some diagnostics and
creating new unknown reasons for each type of failure that
can happen during constant evaluation.
This fixes a test involving transitive captures of local functions,
as well as an infinite recursion possible with the old code.
Fixes <rdar://problem/34496304>.
The new pass is based on existing asserts in DiagnoseStaticExclusivity.
They were compiled out in release builds and only checked for captures of
inout parameters. This patch converts the assertions into diagnostics and
adds checks for captures of non-escaping function values.
Unlike the Sema-based checks that this replaces, the new code handles
transitive captures from recursive local functions, which means certain
invalid code that used to compile will now be rejected with an error.
The new analysis also looks at the ultimate usages of a local function
instead of just assuming all local functions are escaping, which fixes
issues where the compiler would reject valid code.
Fixes a bunch of related issues, including:
- <rdar://problem/29403178>
- <https://bugs.swift.org/browse/SR-8546> / <rdar://problem/43355341>
- <https://bugs.swift.org/browse/SR-9043> / <rdar://problem/45511834>
When compiling SwiftOnoneSupport, issue errors for missing functions which are expected in the module.
This ensures ABI compatibility.
rdar://problem/48924409
When compiling the OnoneSupport library, the compiler checks for @_semantics("prespecialize.X") attributes to pre-specialize function X.
rdar://problem/48924409
yields in generalized accessors: _read and _modify, which are
yield-once corountines. This pass is based on the existing SIL verifier
checks but diagnoses only those errors that can be introduced by programmers
when using yields.
<rdar://43578476>
Implements a constant interpreter that can deal with basic integer operations.
Summary of the features that it includes:
* builtin integer values, and builtin integer insts
* struct and tuple values, and insts that construct and extract them (necessary to use stdlib integers)
* function referencing and application (necessary to call stdlib integer functions)
* error handling data structures and logic, for telling you why your value is not evaluatable
* metatype values (not necessary for integers, but it's only a few extra lines, so I thought it would be more trouble than it's worth to put them in a separate PR)
* conditional branches (ditto)