mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
KeyPath's getter/setter/hash/equals functions have their own calling convention, which receives generic arguments and embedded indices from a given KeyPath argument buffer. The convention was previously implemented by: 1. Accepting an argument buffer as an UnsafeRawPointer and casting it to indices tuple pointer in SIL. 2. Bind generic arguments info from the given argument buffer while emitting prologue in IRGen by creating a new forwarding thunk. This 2-phase lowering approach was not ideal, as it blocked KeyPath projection optimization [^1], and also required having a target arch specific signature lowering logic in SIL-level [^2]. This patch centralizes the KeyPath accessor calling convention logic to IRGen, by introducing `@convention(keypath_accessor_XXX)` convention in SIL and lowering it in IRGen. This change unblocks the KeyPath projection optimization while capturing subscript indices, and also makes it easier to support WebAssembly target. [^1]: https://github.com/apple/swift/pull/28799 [^2]: https://forums.swift.org/t/wasm-support/16087/21
121 lines
4.5 KiB
C++
121 lines
4.5 KiB
C++
//===--- GenericRequirement.h - Generic requirements ------------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This class describes types for working with requirements of generic
|
|
// signatures and the layout of the generic arguments section of
|
|
// generic type metadata.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_IRGEN_GENERICREQUIREMENT_H
|
|
#define SWIFT_IRGEN_GENERICREQUIREMENT_H
|
|
|
|
#include "swift/AST/Type.h"
|
|
#include "swift/IRGen/GenericRequirement.h"
|
|
#include "llvm/ADT/DenseMapInfo.h"
|
|
#include "llvm/ADT/STLExtras.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
namespace llvm {
|
|
class Value;
|
|
}
|
|
|
|
namespace swift {
|
|
class CanGenericSignature;
|
|
enum class MetadataState : size_t;
|
|
class ModuleDecl;
|
|
class NominalTypeDecl;
|
|
class ProtocolDecl;
|
|
class SubstitutionMap;
|
|
|
|
namespace irgen {
|
|
class Address;
|
|
class IRGenFunction;
|
|
class IRGenModule;
|
|
class DynamicMetadataRequest;
|
|
|
|
using RequirementCallback =
|
|
llvm::function_ref<void(GenericRequirement requirement)>;
|
|
|
|
/// Enumerate the generic requirements imposed by a generic signature.
|
|
void enumerateGenericSignatureRequirements(CanGenericSignature signature,
|
|
const RequirementCallback &callback);
|
|
|
|
/// Given a substitution map and a generic requirement for the
|
|
/// substitution map's input generic signature, emit the required value.
|
|
llvm::Value *
|
|
emitGenericRequirementFromSubstitutions(IRGenFunction &IGF,
|
|
GenericRequirement requirement,
|
|
MetadataState metadataState,
|
|
SubstitutionMap subs,
|
|
bool onHeapPacks=false);
|
|
|
|
void emitInitOfGenericRequirementsBuffer(IRGenFunction &IGF,
|
|
ArrayRef<GenericRequirement> reqts,
|
|
Address buffer,
|
|
MetadataState metadataState,
|
|
SubstitutionMap subs,
|
|
bool onHeapPacks=false);
|
|
|
|
/// Given a required value, map the requirement into the given
|
|
/// context and bind the value.
|
|
void bindGenericRequirement(IRGenFunction &IGF,
|
|
GenericRequirement requirement,
|
|
llvm::Value *requiredValue,
|
|
MetadataState metadataState,
|
|
SubstitutionMap subs);
|
|
|
|
void bindFromGenericRequirementsBuffer(IRGenFunction &IGF,
|
|
ArrayRef<GenericRequirement> reqts,
|
|
Address buffer,
|
|
MetadataState metadataState,
|
|
SubstitutionMap subs);
|
|
|
|
void bindPolymorphicArgumentsFromComponentIndices(IRGenFunction &IGF,
|
|
GenericEnvironment *genericEnv,
|
|
ArrayRef<GenericRequirement> requirements,
|
|
llvm::Value *args,
|
|
llvm::Value *size,
|
|
bool hasSubscriptIndices);
|
|
|
|
|
|
/// A class describing the layout of the generic requirements of a
|
|
/// nominal type metadata.
|
|
///
|
|
/// The generic requirements are always laid out as a sequence of shape
|
|
/// parameters, followed by type metadata and witness tables.
|
|
class GenericTypeRequirements {
|
|
llvm::SmallVector<GenericRequirement, 4> Requirements;
|
|
|
|
public:
|
|
GenericTypeRequirements(IRGenModule &IGM, NominalTypeDecl *decl);
|
|
GenericTypeRequirements(IRGenModule &IGM, GenericSignature sig);
|
|
|
|
/// Return the layout chunks.
|
|
ArrayRef<GenericRequirement> getRequirements() const {
|
|
return Requirements;
|
|
}
|
|
|
|
bool empty() const { return Requirements.empty(); }
|
|
|
|
void emitInitOfBuffer(IRGenFunction &IGF, SubstitutionMap subs,
|
|
Address buffer);
|
|
|
|
void bindFromBuffer(IRGenFunction &IGF, Address buffer, MetadataState state,
|
|
SubstitutionMap subs);
|
|
};
|
|
|
|
} // end namespace irgen
|
|
} // end namespace swift
|
|
|
|
#endif
|