Skip to content

Commit ac1fb9d

Browse files
Merge pull request swiftlang#222 from swiftwasm/master
[pull] swiftwasm from master
2 parents 1470899 + 5f0ccca commit ac1fb9d

File tree

76 files changed

+4654
-1543
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+4654
-1543
lines changed

Diff for: include/swift/AST/Attr.h

+3
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,9 @@ class TypeEraserAttr final : public DeclAttribute {
11171117
TypeEraserLoc(typeEraserLoc) {}
11181118

11191119
const TypeLoc &getTypeEraserLoc() const { return TypeEraserLoc; }
1120+
TypeLoc &getTypeEraserLoc() { return TypeEraserLoc; }
1121+
1122+
bool hasViableTypeEraserInit(ProtocolDecl *protocol) const;
11201123

11211124
static bool classof(const DeclAttribute *DA) {
11221125
return DA->getKind() == DAK_TypeEraser;

Diff for: include/swift/AST/AutoDiff.h

+18-5
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,13 @@ struct AutoDiffConfig {
114114
SWIFT_DEBUG_DUMP;
115115
};
116116

117+
/// A semantic function result type: either a formal function result type or
118+
/// an `inout` parameter type. Used in derivative function type calculation.
119+
struct AutoDiffSemanticFunctionResultType {
120+
Type type;
121+
bool isInout;
122+
};
123+
117124
/// Key for caching SIL derivative function types.
118125
struct SILAutoDiffDerivativeFunctionKey {
119126
SILFunctionType *originalType;
@@ -263,11 +270,17 @@ using SILDifferentiabilityWitnessKey = std::pair<StringRef, AutoDiffConfig>;
263270
/// Automatic differentiation utility namespace.
264271
namespace autodiff {
265272

266-
/// Appends the subset's parameter's types to `results`, in the order in
267-
/// which they appear in the function type.
268-
void getSubsetParameterTypes(IndexSubset *indices, AnyFunctionType *type,
269-
SmallVectorImpl<Type> &results,
270-
bool reverseCurryLevels = false);
273+
/// Given a function type, collects its semantic result types in type order
274+
/// into `result`: first, the formal result type (if non-`Void`), followed by
275+
/// `inout` parameter types.
276+
///
277+
/// The function type may have at most two parameter lists.
278+
///
279+
/// Remaps the original semantic result using `genericEnv`, if specified.
280+
void getFunctionSemanticResultTypes(
281+
AnyFunctionType *functionType,
282+
SmallVectorImpl<AutoDiffSemanticFunctionResultType> &result,
283+
GenericEnvironment *genericEnv = nullptr);
271284

272285
/// "Constrained" derivative generic signatures require all differentiability
273286
/// parameters to conform to the `Differentiable` protocol.

Diff for: include/swift/AST/DiagnosticsSema.def

+38-2
Original file line numberDiff line numberDiff line change
@@ -2898,8 +2898,6 @@ ERROR(implements_attr_protocol_not_conformed_to,none,
28982898
(DeclName, DeclName))
28992899

29002900
// @differentiable
2901-
ERROR(differentiable_attr_void_result,none,
2902-
"cannot differentiate void function %0", (DeclName))
29032901
ERROR(differentiable_attr_no_vjp_or_jvp_when_linear,none,
29042902
"cannot specify 'vjp:' or 'jvp:' for linear functions; use '@transpose' "
29052903
"attribute for transpose registration instead", ())
@@ -2996,6 +2994,11 @@ ERROR(autodiff_attr_original_decl_none_valid_found,none,
29962994
"could not find function %0 with expected type %1", (DeclNameRef, Type))
29972995
ERROR(autodiff_attr_original_decl_not_same_type_context,none,
29982996
"%0 is not defined in the current type context", (DeclNameRef))
2997+
ERROR(autodiff_attr_original_void_result,none,
2998+
"cannot differentiate void function %0", (DeclName))
2999+
ERROR(autodiff_attr_original_multiple_semantic_results,none,
3000+
"cannot differentiate functions with both an 'inout' parameter and a "
3001+
"result", ())
29993002

30003003
// differentiation `wrt` parameters clause
30013004
ERROR(diff_function_no_parameters,none,
@@ -4386,6 +4389,39 @@ ERROR(dynamic_replacement_replaced_constructor_is_convenience, none,
43864389
ERROR(dynamic_replacement_replaced_constructor_is_not_convenience, none,
43874390
"replaced constructor %0 is not marked as convenience", (DeclNameRef))
43884391

4392+
//------------------------------------------------------------------------------
4393+
// MARK: @_typeEraser()
4394+
//------------------------------------------------------------------------------
4395+
4396+
ERROR(non_nominal_type_eraser,none,
4397+
"type eraser must be a class, struct, or enum", ())
4398+
ERROR(type_eraser_does_not_conform,none,
4399+
"type eraser %0 must conform to protocol %1", (Type, Type))
4400+
ERROR(type_eraser_not_accessible,none,
4401+
"%select{private|fileprivate|internal|public|open}0 type eraser %1 "
4402+
"cannot have more restrictive access than protocol %2 "
4403+
"(which is %select{private|fileprivate|internal|public|open}3)",
4404+
(AccessLevel, Identifier, Type, AccessLevel))
4405+
ERROR(type_eraser_missing_init,none,
4406+
"type eraser %0 must have an initializer of the form "
4407+
"'init<T: %1>(erasing: T)'", (Type, StringRef))
4408+
ERROR(type_eraser_unviable_init,none,
4409+
"type eraser %0 has no viable initializer of the form "
4410+
"'init<T: %1>(erasing: T)'", (Type, StringRef))
4411+
4412+
NOTE(type_eraser_declared_here,none,
4413+
"type eraser declared here",())
4414+
NOTE(type_eraser_failable_init,none,
4415+
"'init(erasing:)' cannot be failable",())
4416+
NOTE(type_eraser_init_unsatisfied_requirements,none,
4417+
"'init(erasing:)' cannot have unsatisfied requirements "
4418+
"when %0 = 'some %1'", (Type, StringRef))
4419+
NOTE(type_eraser_init_not_accessible,none,
4420+
"%select{private|fileprivate|internal|public|open}0 'init(erasing:)' "
4421+
"cannot have more restrictive access than protocol %1 "
4422+
"(which is %select{private|fileprivate|internal|public|open}2)",
4423+
(AccessLevel, Type, AccessLevel))
4424+
43894425
//------------------------------------------------------------------------------
43904426
// MARK: @available
43914427
//------------------------------------------------------------------------------

Diff for: include/swift/AST/IRGenOptions.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ class IRGenOptions {
210210
/// Enable use of the swiftcall calling convention.
211211
unsigned UseSwiftCall : 1;
212212

213+
/// Enable the use of type layouts for value witness functions and use
214+
/// vw functions instead of outlined copy/destroy functions.
215+
unsigned UseTypeLayoutValueHandling : 1;
216+
213217
/// Instrument code to generate profiling information.
214218
unsigned GenerateProfile : 1;
215219

@@ -263,7 +267,7 @@ class IRGenOptions {
263267
LazyInitializeClassMetadata(false),
264268
LazyInitializeProtocolConformances(false), DisableLegacyTypeInfo(false),
265269
PrespecializeGenericMetadata(false), UseIncrementalLLVMCodeGen(true),
266-
UseSwiftCall(false), GenerateProfile(false),
270+
UseSwiftCall(false), UseTypeLayoutValueHandling(false), GenerateProfile(false),
267271
EnableDynamicReplacementChaining(false),
268272
DisableRoundTripDebugTypes(false), DisableDebuggerShadowCopies(false),
269273
CmdArgs(), SanitizeCoverage(llvm::SanitizerCoverageOptions()),

Diff for: include/swift/AST/KnownIdentifiers.def

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ IDENTIFIER(encode)
6464
IDENTIFIER(encodeIfPresent)
6565
IDENTIFIER(Encoder)
6666
IDENTIFIER(encoder)
67+
IDENTIFIER(erasing)
6768
IDENTIFIER(error)
6869
IDENTIFIER(errorDomain)
6970
IDENTIFIER(first)

Diff for: include/swift/AST/TypeCheckRequests.h

+19
Original file line numberDiff line numberDiff line change
@@ -2054,6 +2054,25 @@ class DifferentiableAttributeTypeCheckRequest
20542054
void cacheResult(IndexSubset *value) const;
20552055
};
20562056

2057+
/// Checks whether a type eraser has a viable initializer.
2058+
class TypeEraserHasViableInitRequest
2059+
: public SimpleRequest<TypeEraserHasViableInitRequest,
2060+
bool(TypeEraserAttr *, ProtocolDecl *),
2061+
CacheKind::Cached> {
2062+
public:
2063+
using SimpleRequest::SimpleRequest;
2064+
2065+
private:
2066+
friend SimpleRequest;
2067+
2068+
// Evaluation
2069+
llvm::Expected<bool> evaluate(Evaluator &evaluator, TypeEraserAttr *attr,
2070+
ProtocolDecl *protocol) const;
2071+
2072+
public:
2073+
bool isCached() const { return true; }
2074+
};
2075+
20572076
// Allow AnyValue to compare two Type values, even though Type doesn't
20582077
// support ==.
20592078
template<>

Diff for: include/swift/AST/TypeCheckerTypeIDZone.def

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ SWIFT_REQUEST(TypeChecker, DefaultTypeRequest,
4646
SWIFT_REQUEST(TypeChecker, DifferentiableAttributeTypeCheckRequest,
4747
IndexSubset *(DifferentiableAttr *),
4848
SeparatelyCached, NoLocationInfo)
49+
SWIFT_REQUEST(TypeChecker, TypeEraserHasViableInitRequest,
50+
bool(TypeEraserAttr *, ProtocolDecl *),
51+
Cached, NoLocationInfo)
4952
SWIFT_REQUEST(TypeChecker, DynamicallyReplacedDeclRequest,
5053
ValueDecl *(ValueDecl *),
5154
Cached, NoLocationInfo)

Diff for: include/swift/AST/Types.h

+92-4
Original file line numberDiff line numberDiff line change
@@ -3203,15 +3203,25 @@ class AnyFunctionType : public TypeBase {
32033203
return getExtInfo().getRepresentation();
32043204
}
32053205

3206+
/// Appends the parameters indicated by `parameterIndices` to `results`.
3207+
///
3208+
/// For curried function types: if `reverseCurryLevels` is true, append
3209+
/// the `self` parameter last instead of first.
3210+
///
3211+
/// TODO(TF-874): Simplify logic and remove the `reverseCurryLevels` flag.
3212+
void getSubsetParameters(IndexSubset *parameterIndices,
3213+
SmallVectorImpl<AnyFunctionType::Param> &results,
3214+
bool reverseCurryLevels = false);
3215+
32063216
/// Returns the derivative function type for the given parameter indices,
32073217
/// result index, derivative function kind, derivative function generic
32083218
/// signature (optional), and other auxiliary parameters.
32093219
///
32103220
/// Preconditions:
32113221
/// - Parameters corresponding to parameter indices must conform to
32123222
/// `Differentiable`.
3213-
/// - The result corresponding to the result index must conform to
3214-
/// `Differentiable`.
3223+
/// - There is one semantic function result type: either the formal original
3224+
/// result or an `inout` parameter. It must conform to `Differentiable`.
32153225
///
32163226
/// Typing rules, given:
32173227
/// - Original function type. Three cases:
@@ -3257,6 +3267,11 @@ class AnyFunctionType : public TypeBase {
32573267
/// original result | deriv. wrt result | deriv. wrt params
32583268
/// \endverbatim
32593269
///
3270+
/// The original type may have `inout` parameters. If so, the
3271+
/// differential/pullback typing rules are more nuanced: see documentation for
3272+
/// `getAutoDiffDerivativeFunctionLinearMapType` for details. Semantically,
3273+
/// `inout` parameters behave as both parameters and results.
3274+
///
32603275
/// By default, if the original type has a `self` parameter list and parameter
32613276
/// indices include `self`, the computed derivative function type will return
32623277
/// a linear map taking/returning self's tangent *last* instead of first, for
@@ -3267,12 +3282,54 @@ class AnyFunctionType : public TypeBase {
32673282
/// derivative function types, e.g. when type-checking `@differentiable` and
32683283
/// `@derivative` attributes.
32693284
AnyFunctionType *getAutoDiffDerivativeFunctionType(
3270-
IndexSubset *parameterIndices, unsigned resultIndex,
3271-
AutoDiffDerivativeFunctionKind kind,
3285+
IndexSubset *parameterIndices, AutoDiffDerivativeFunctionKind kind,
32723286
LookupConformanceFn lookupConformance,
32733287
GenericSignature derivativeGenericSignature = GenericSignature(),
32743288
bool makeSelfParamFirst = false);
32753289

3290+
/// Returns the corresponding linear map function type for the given parameter
3291+
/// indices, linear map function kind, and other auxiliary parameters.
3292+
///
3293+
/// Preconditions:
3294+
/// - Parameters corresponding to parameter indices must conform to
3295+
/// `Differentiable`.
3296+
/// - There is one semantic function result type: either the formal original
3297+
/// result or an `inout` parameter. It must conform to `Differentiable`.
3298+
///
3299+
/// Differential typing rules: takes "wrt" parameter derivatives and returns a
3300+
/// "wrt" result derivative.
3301+
///
3302+
/// - Case 1: original function has no `inout` parameters.
3303+
/// - Original: `(T0, T1, ...) -> R`
3304+
/// - Differential: `(T0.Tan, T1.Tan, ...) -> R.Tan`
3305+
/// - Case 2: original function has a non-wrt `inout` parameter.
3306+
/// - Original: `(T0, inout T1, ...) -> Void`
3307+
/// - Differential: `(T0.Tan, ...) -> T1.Tan`
3308+
/// - Case 3: original function has a wrt `inout` parameter.
3309+
/// - Original: `(T0, inout T1, ...) -> Void`
3310+
/// - Differential: `(T0.Tan, inout T1.Tan, ...) -> Void`
3311+
///
3312+
/// Pullback typing rules: takes a "wrt" result derivative and returns "wrt"
3313+
/// parameter derivatives.
3314+
///
3315+
/// - Case 1: original function has no `inout` parameters.
3316+
/// - Original: `(T0, T1, ...) -> R`
3317+
/// - Pullback: `R.Tan -> (T0.Tan, T1.Tan, ...)`
3318+
/// - Case 2: original function has a non-wrt `inout` parameter.
3319+
/// - Original: `(T0, inout T1, ...) -> Void`
3320+
/// - Pullback: `(T1.Tan) -> (T0.Tan, ...)`
3321+
/// - Case 3: original function has a wrt `inout` parameter.
3322+
/// - Original: `(T0, inout T1, ...) -> Void`
3323+
/// - Pullback: `(inout T1.Tan) -> (T0.Tan, ...)`
3324+
///
3325+
/// If `makeSelfParamFirst` is true, `self`'s tangent is reordered to appear
3326+
/// first. `makeSelfParamFirst` should be true when working with user-facing
3327+
/// derivative function types, e.g. when type-checking `@differentiable` and
3328+
/// `@derivative` attributes.
3329+
AnyFunctionType *getAutoDiffDerivativeFunctionLinearMapType(
3330+
IndexSubset *parameterIndices, AutoDiffLinearMapKind kind,
3331+
LookupConformanceFn lookupConformance, bool makeSelfParamFirst = false);
3332+
32763333
/// True if the parameter declaration it is attached to is guaranteed
32773334
/// to not persist the closure for longer than the duration of the call.
32783335
bool isNoEscape() const {
@@ -4404,6 +4461,28 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
44044461
return getParameters().back();
44054462
}
44064463

4464+
struct IndirectMutatingParameterFilter {
4465+
bool operator()(SILParameterInfo param) const {
4466+
return param.isIndirectMutating();
4467+
}
4468+
};
4469+
using IndirectMutatingParameterIter =
4470+
llvm::filter_iterator<const SILParameterInfo *,
4471+
IndirectMutatingParameterFilter>;
4472+
using IndirectMutatingParameterRange =
4473+
iterator_range<IndirectMutatingParameterIter>;
4474+
4475+
/// A range of SILParameterInfo for all indirect mutating parameters.
4476+
IndirectMutatingParameterRange getIndirectMutatingParameters() const {
4477+
return llvm::make_filter_range(getParameters(),
4478+
IndirectMutatingParameterFilter());
4479+
}
4480+
4481+
/// Returns the number of indirect mutating parameters.
4482+
unsigned getNumIndirectMutatingParameters() const {
4483+
return llvm::count_if(getParameters(), IndirectMutatingParameterFilter());
4484+
}
4485+
44074486
/// Get the generic signature used to apply the substitutions of a substituted function type
44084487
CanGenericSignature getSubstGenericSignature() const {
44094488
return GenericSigAndIsImplied.getPointer();
@@ -4486,18 +4565,27 @@ class SILFunctionType final : public TypeBase, public llvm::FoldingSetNode,
44864565
/// - Returns original results, followed by a differential function, which
44874566
/// takes "wrt" parameter derivatives and returns a "wrt" result derivative.
44884567
///
4568+
/// \verbatim
44894569
/// $(T0, ...) -> (R0, ..., (T0.Tan, T1.Tan, ...) -> R0.Tan)
44904570
/// ^~~~~~~ ^~~~~~~~~~~~~~~~~~~ ^~~~~~
44914571
/// original results | derivatives wrt params | derivative wrt result
4572+
/// \endverbatim
44924573
///
44934574
/// VJP derivative type:
44944575
/// - Takes original parameters.
44954576
/// - Returns original results, followed by a pullback function, which
44964577
/// takes a "wrt" result derivative and returns "wrt" parameter derivatives.
44974578
///
4579+
/// \verbatim
44984580
/// $(T0, ...) -> (R0, ..., (R0.Tan) -> (T0.Tan, T1.Tan, ...))
44994581
/// ^~~~~~~ ^~~~~~ ^~~~~~~~~~~~~~~~~~~
45004582
/// original results | derivative wrt result | derivatives wrt params
4583+
/// \endverbatim
4584+
///
4585+
/// The original type may have `inout` parameters. If so, the
4586+
/// differential/pullback typing rules are more nuanced: see documentation for
4587+
/// `getAutoDiffDerivativeFunctionLinearMapType` for details. Semantically,
4588+
/// `inout` parameters behave as both parameters and results.
45014589
///
45024590
/// A "constrained derivative generic signature" is computed from
45034591
/// `derivativeFunctionGenericSignature`, if specified. Otherwise, it is

Diff for: include/swift/Option/FrontendOptions.td

+3
Original file line numberDiff line numberDiff line change
@@ -674,4 +674,7 @@ def emit_ldadd_cfile_path
674674
def previous_module_installname_map_file
675675
: Separate<["-"], "previous-module-installname-map-file">, MetaVarName<"<path>">,
676676
HelpText<"Path to a Json file indicating module name to installname map for @_originallyDefinedIn">;
677+
678+
def enable_type_layouts : Flag<["-"], "enable-type-layout">,
679+
HelpText<"Enable type layout based lowering">;
677680
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

0 commit comments

Comments
 (0)