1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
|
//===--- GenPack.h - Swift IR Generation For Variadic Generics --*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2022 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 file implements IR generation for type and value packs in Swift.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_IRGEN_GENPACK_H
#define SWIFT_IRGEN_GENPACK_H
#include "IRGen.h"
#include "swift/AST/Types.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
namespace llvm {
class Value;
} // end namespace llvm
namespace swift {
namespace irgen {
class Address;
class IRGenFunction;
class IRGenModule;
class DynamicMetadataRequest;
class MetadataResponse;
class StackAddress;
MetadataResponse
emitPackArchetypeMetadataRef(IRGenFunction &IGF,
CanPackArchetypeType type,
DynamicMetadataRequest request);
std::pair<StackAddress, llvm::Value *>
emitTypeMetadataPack(IRGenFunction &IGF, CanPackType packType,
DynamicMetadataRequest request);
MetadataResponse
emitTypeMetadataPackRef(IRGenFunction &IGF,
CanPackType packType,
DynamicMetadataRequest request);
/// Given a pointer to a potentially heap-allocated pack of metadata/wtables,
/// mask off the bit that indicates whether it is heap allocated.
llvm::Value *maskMetadataPackPointer(IRGenFunction &IGF, llvm::Value *);
void bindOpenedElementArchetypesAtIndex(IRGenFunction &IGF,
GenericEnvironment *env,
llvm::Value *index);
llvm::Value *
emitTypeMetadataPackElementRef(IRGenFunction &IGF, CanPackType packType,
ArrayRef<ProtocolConformanceRef> conformances,
llvm::Value *index,
DynamicMetadataRequest request,
llvm::SmallVectorImpl<llvm::Value *> &wtables);
void cleanupTypeMetadataPack(IRGenFunction &IGF, StackAddress pack,
llvm::Value *shape);
std::pair<StackAddress, llvm::Value *>
emitWitnessTablePack(IRGenFunction &IGF, CanPackType packType,
PackConformance *conformance);
llvm::Value *emitWitnessTablePackRef(IRGenFunction &IGF, CanPackType packType,
PackConformance *conformance);
void cleanupWitnessTablePack(IRGenFunction &IGF, StackAddress pack,
llvm::Value *shape);
/// An on-stack pack metadata/wtable allocation.
///
/// Includes the stack address, the element count, and the kind of requirement
/// (a GenericRequirement::Kind represented as a raw uint8_t).
using StackPackAlloc =
std::tuple<StackAddress, /*shape*/ llvm::Value *, /*kind*/ uint8_t>;
/// Emits cleanups for an array of on-stack pack metadata/wtable allocations in
/// reverse order.
void cleanupStackAllocPacks(IRGenFunction &IGF,
ArrayRef<StackPackAlloc> allocs);
/// Emit the dynamic index of a particular structural component
/// of the given pack type. If the component is a pack expansion, this
/// is the index of the first element of the pack (or where it would be
/// if it had any elements).
llvm::Value *emitIndexOfStructuralPackComponent(IRGenFunction &IGF,
CanPackType packType,
unsigned componentIndex);
/// Emit the address that stores the given pack element.
///
/// For indirect packs, note that this is the address of the pack
/// array element, not the address stored in the pack array element.
Address emitStorageAddressOfPackElement(IRGenFunction &IGF, Address pack,
llvm::Value *index, SILType elementType,
CanSILPackType packType);
Size getPackElementSize(IRGenModule &, CanSILPackType ty);
StackAddress allocatePack(IRGenFunction &IGF, CanSILPackType packType);
void deallocatePack(IRGenFunction &IGF, StackAddress addr, CanSILPackType packType);
std::optional<StackAddress>
emitDynamicTupleTypeLabels(IRGenFunction &IGF, CanTupleType tupleType,
CanPackType packType, llvm::Value *shapeExpression);
StackAddress
emitDynamicFunctionParameterFlags(IRGenFunction &IGF,
AnyFunctionType::CanParamArrayRef params,
CanPackType packType,
llvm::Value *shapeExpression);
std::pair<StackAddress, llvm::Value *>
emitInducedTupleTypeMetadataPack(
IRGenFunction &IGF, llvm::Value *tupleMetadata);
MetadataResponse
emitInducedTupleTypeMetadataPackRef(
IRGenFunction &IGF, CanPackType packType,
llvm::Value *tupleMetadata);
} // end namespace irgen
} // end namespace swift
#endif
|