Skip to content

Commit e23a6f1

Browse files
authored
Merge pull request #12500 from xedin/fn-metadata-changes
[IRGen] Improvements to function type metadata
2 parents ec343c6 + fbd502a commit e23a6f1

File tree

16 files changed

+617
-256
lines changed

16 files changed

+617
-256
lines changed

include/swift/ABI/MetadataValues.h

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -550,19 +550,21 @@ enum class FunctionMetadataConvention: uint8_t {
550550
template <typename int_type>
551551
class TargetFunctionTypeFlags {
552552
enum : int_type {
553-
NumArgumentsMask = 0x00FFFFFFU,
554-
ConventionMask = 0x0F000000U,
555-
ConventionShift = 24U,
556-
ThrowsMask = 0x10000000U,
553+
NumParametersMask = 0x00FFFFFFU,
554+
ConventionMask = 0x0F000000U,
555+
ConventionShift = 25U,
556+
ThrowsMask = 0x10000000U,
557+
ParamFlagsMask = 0x01000000U,
557558
};
558559
int_type Data;
559560

560561
constexpr TargetFunctionTypeFlags(int_type Data) : Data(Data) {}
561562
public:
562563
constexpr TargetFunctionTypeFlags() : Data(0) {}
563564

564-
constexpr TargetFunctionTypeFlags withNumArguments(unsigned numArguments) const {
565-
return TargetFunctionTypeFlags((Data & ~NumArgumentsMask) | numArguments);
565+
constexpr TargetFunctionTypeFlags
566+
withNumParameters(unsigned numParams) const {
567+
return TargetFunctionTypeFlags((Data & ~NumParametersMask) | numParams);
566568
}
567569

568570
constexpr TargetFunctionTypeFlags<int_type>
@@ -576,19 +578,25 @@ class TargetFunctionTypeFlags {
576578
return TargetFunctionTypeFlags<int_type>((Data & ~ThrowsMask) |
577579
(throws ? ThrowsMask : 0));
578580
}
579-
580-
unsigned getNumArguments() const {
581-
return Data & NumArgumentsMask;
581+
582+
constexpr TargetFunctionTypeFlags<int_type>
583+
withParameterFlags(bool hasFlags) const {
584+
return TargetFunctionTypeFlags<int_type>((Data & ~ParamFlagsMask) |
585+
(hasFlags ? ParamFlagsMask : 0));
582586
}
583-
587+
588+
unsigned getNumParameters() const { return Data & NumParametersMask; }
589+
584590
FunctionMetadataConvention getConvention() const {
585591
return FunctionMetadataConvention((Data&ConventionMask) >> ConventionShift);
586592
}
587593

588594
bool throws() const {
589595
return bool(Data & ThrowsMask);
590596
}
591-
597+
598+
bool hasParameterFlags() const { return bool(Data & ParamFlagsMask); }
599+
592600
int_type getIntValue() const {
593601
return Data;
594602
}
@@ -606,6 +614,56 @@ class TargetFunctionTypeFlags {
606614
};
607615
using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
608616

617+
template <typename int_type>
618+
class TargetParameterTypeFlags {
619+
enum : int_type {
620+
InOutMask = 1 << 0,
621+
SharedMask = 1 << 1,
622+
VariadicMask = 1 << 2,
623+
};
624+
int_type Data;
625+
626+
constexpr TargetParameterTypeFlags(int_type Data) : Data(Data) {}
627+
628+
public:
629+
constexpr TargetParameterTypeFlags() : Data(0) {}
630+
631+
constexpr TargetParameterTypeFlags<int_type> withInOut(bool isInOut) const {
632+
return TargetParameterTypeFlags<int_type>((Data & ~InOutMask) |
633+
(isInOut ? InOutMask : 0));
634+
}
635+
636+
constexpr TargetParameterTypeFlags<int_type> withShared(bool isShared) const {
637+
return TargetParameterTypeFlags<int_type>((Data & ~SharedMask) |
638+
(isShared ? SharedMask : 0));
639+
}
640+
641+
constexpr TargetParameterTypeFlags<int_type>
642+
withVariadic(bool isVariadic) const {
643+
return TargetParameterTypeFlags<int_type>((Data & ~VariadicMask) |
644+
(isVariadic ? VariadicMask : 0));
645+
}
646+
647+
bool isNone() const { return Data == 0; }
648+
bool isInOut() const { return Data & InOutMask; }
649+
bool isShared() const { return Data & SharedMask; }
650+
bool isVariadic() const { return Data & VariadicMask; }
651+
652+
int_type getIntValue() const { return Data; }
653+
654+
static TargetParameterTypeFlags<int_type> fromIntValue(int_type Data) {
655+
return TargetParameterTypeFlags(Data);
656+
}
657+
658+
bool operator==(TargetParameterTypeFlags<int_type> other) const {
659+
return Data == other.Data;
660+
}
661+
bool operator!=(TargetParameterTypeFlags<int_type> other) const {
662+
return Data != other.Data;
663+
}
664+
};
665+
using ParameterFlags = TargetParameterTypeFlags<uint32_t>;
666+
609667
/// Field types and flags as represented in a nominal type's field/case type
610668
/// vector.
611669
class FieldType {

include/swift/Reflection/TypeRef.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ class FunctionTypeRef final : public TypeRef {
344344
for (const auto &Param : Parameters) {
345345
ID.addString(Param.getLabel().str());
346346
ID.addPointer(Param.getType());
347-
ID.addInteger(static_cast<uint32_t>(Param.getFlags().toRaw()));
347+
ID.addInteger(static_cast<uint32_t>(Param.getFlags().getIntValue()));
348348
}
349349
ID.addPointer(Result);
350350
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));

include/swift/Remote/MetadataReader.h

Lines changed: 38 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#ifndef SWIFT_REMOTE_METADATAREADER_H
1818
#define SWIFT_REMOTE_METADATAREADER_H
1919

20-
#include "swift/AST/Types.h"
2120
#include "swift/Runtime/Metadata.h"
2221
#include "swift/Remote/MemoryReader.h"
2322
#include "swift/Demangling/Demangler.h"
@@ -33,9 +32,9 @@ namespace remote {
3332
template <typename BuiltType> class FunctionParam {
3433
StringRef Label;
3534
BuiltType Type;
36-
ParameterTypeFlags Flags;
35+
ParameterFlags Flags;
3736

38-
FunctionParam(StringRef label, BuiltType type, ParameterTypeFlags flags)
37+
FunctionParam(StringRef label, BuiltType type, ParameterFlags flags)
3938
: Label(label), Type(type), Flags(flags) {}
4039

4140
public:
@@ -45,14 +44,15 @@ template <typename BuiltType> class FunctionParam {
4544

4645
StringRef getLabel() const { return Label; }
4746
BuiltType getType() const { return Type; }
48-
ParameterTypeFlags getFlags() const { return Flags; }
47+
ParameterFlags getFlags() const { return Flags; }
4948

5049
void setLabel(StringRef label) { Label = label; }
5150
void setType(BuiltType type) { Type = type; }
5251

5352
void setVariadic() { Flags = Flags.withVariadic(true); }
5453
void setShared() { Flags = Flags.withShared(true); }
5554
void setInOut() { Flags = Flags.withInOut(true); }
55+
void setFlags(ParameterFlags flags) { Flags = flags; };
5656

5757
FunctionParam withLabel(StringRef label) const {
5858
return FunctionParam(label, Type, Flags);
@@ -62,7 +62,7 @@ template <typename BuiltType> class FunctionParam {
6262
return FunctionParam(Label, type, Flags);
6363
}
6464

65-
FunctionParam withFlags(ParameterTypeFlags flags) const {
65+
FunctionParam withFlags(ParameterFlags flags) const {
6666
return FunctionParam(Label, Type, flags);
6767
}
6868
};
@@ -798,40 +798,32 @@ class MetadataReader {
798798
}
799799
case MetadataKind::Function: {
800800
auto Function = cast<TargetFunctionTypeMetadata<Runtime>>(Meta);
801+
auto *const parameters = Function->getParameters();
801802

802803
std::vector<FunctionParam<BuiltType>> Parameters;
803-
StoredPointer ArgumentAddress = MetadataAddress +
804-
sizeof(TargetFunctionTypeMetadata<Runtime>);
805-
for (StoredPointer i = 0; i < Function->getNumArguments(); ++i,
806-
ArgumentAddress += sizeof(StoredPointer)) {
807-
StoredPointer FlaggedArgumentAddress;
808-
if (!Reader->readInteger(RemoteAddress(ArgumentAddress),
809-
&FlaggedArgumentAddress))
804+
for (unsigned i = 0, n = Function->getNumParameters(); i != n; ++i) {
805+
StoredPointer ParamMetadata;
806+
if (!Reader->readInteger(RemoteAddress(parameters + i), &ParamMetadata))
810807
return BuiltType();
811808

812-
FunctionParam<BuiltType> Param;
813-
814-
// TODO: Use target-agnostic FlaggedPointer to mask this!
815-
const auto InOutMask = (StoredPointer) 1;
816-
// FIXME: Add import parameter related flags from metadata
817-
if ((FlaggedArgumentAddress & InOutMask) != 0)
818-
Param.setInOut();
819-
820-
FlaggedArgumentAddress &= ~InOutMask;
821-
if (auto ParamTypeRef = readTypeFromMetadata(FlaggedArgumentAddress)) {
822-
Param.setType(ParamTypeRef);
823-
Parameters.push_back(std::move(Param));
824-
} else {
809+
auto ParamTypeRef = readTypeFromMetadata(ParamMetadata);
810+
if (!ParamTypeRef)
825811
return BuiltType();
826-
}
812+
813+
FunctionParam<BuiltType> Param;
814+
Param.setType(ParamTypeRef);
815+
Param.setFlags(Function->getParameterFlags(i));
816+
Parameters.push_back(std::move(Param));
827817
}
828818

829819
auto Result = readTypeFromMetadata(Function->ResultType);
830820
if (!Result)
831821
return BuiltType();
832822

833-
auto flags = FunctionTypeFlags().withConvention(Function->getConvention())
834-
.withThrows(Function->throws());
823+
auto flags = FunctionTypeFlags()
824+
.withConvention(Function->getConvention())
825+
.withThrows(Function->throws())
826+
.withParameterFlags(Function->hasParameterFlags());
835827
auto BuiltFunction =
836828
Builder.createFunctionType(Parameters, Result, flags);
837829
TypeCache[MetadataAddress] = BuiltFunction;
@@ -1195,8 +1187,24 @@ class MetadataReader {
11951187
return _readMetadata<TargetExistentialMetatypeMetadata>(address);
11961188
case MetadataKind::ForeignClass:
11971189
return _readMetadata<TargetForeignClassMetadata>(address);
1198-
case MetadataKind::Function:
1199-
return _readMetadata<TargetFunctionTypeMetadata>(address);
1190+
case MetadataKind::Function: {
1191+
StoredSize flagsValue;
1192+
auto flagsAddr =
1193+
address + TargetFunctionTypeMetadata<Runtime>::OffsetToFlags;
1194+
if (!Reader->readInteger(RemoteAddress(flagsAddr), &flagsValue))
1195+
return nullptr;
1196+
1197+
auto flags =
1198+
TargetFunctionTypeFlags<StoredSize>::fromIntValue(flagsValue);
1199+
1200+
auto totalSize = sizeof(TargetFunctionTypeMetadata<Runtime>) +
1201+
flags.getNumParameters() * sizeof(StoredPointer);
1202+
1203+
if (flags.hasParameterFlags())
1204+
totalSize += flags.getNumParameters() * sizeof(uint32_t);
1205+
1206+
return _readMetadata(address, totalSize);
1207+
}
12001208
case MetadataKind::HeapGenericLocalVariable:
12011209
return _readMetadata<TargetGenericBoxHeapMetadata>(address);
12021210
case MetadataKind::HeapLocalVariable:

include/swift/Runtime/Metadata.h

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,36 +1745,48 @@ using EnumMetadata = TargetEnumMetadata<InProcess>;
17451745
template <typename Runtime>
17461746
struct TargetFunctionTypeMetadata : public TargetMetadata<Runtime> {
17471747
using StoredSize = typename Runtime::StoredSize;
1748-
1749-
// TODO: Make this target agnostic
1750-
using Argument = FlaggedPointer<const TargetMetadata<Runtime> *, 0>;
1748+
using Parameter = const TargetMetadata<Runtime> *;
17511749

17521750
TargetFunctionTypeFlags<StoredSize> Flags;
17531751

17541752
/// The type metadata for the result type.
17551753
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> ResultType;
17561754

1757-
TargetPointer<Runtime, Argument> getArguments() {
1758-
return reinterpret_cast<TargetPointer<Runtime, Argument>>(this + 1);
1755+
Parameter *getParameters() { return reinterpret_cast<Parameter *>(this + 1); }
1756+
1757+
const Parameter *getParameters() const {
1758+
return reinterpret_cast<const Parameter *>(this + 1);
17591759
}
17601760

1761-
TargetPointer<Runtime, const Argument> getArguments() const {
1762-
return reinterpret_cast<TargetPointer<Runtime, const Argument>>(this + 1);
1761+
ParameterFlags getParameterFlags(unsigned index) const {
1762+
assert(index < getNumParameters());
1763+
auto flags = hasParameterFlags() ? getParameterFlags()[index] : 0;
1764+
return ParameterFlags::fromIntValue(flags);
17631765
}
1764-
1765-
StoredSize getNumArguments() const {
1766-
return Flags.getNumArguments();
1766+
1767+
StoredSize getNumParameters() const {
1768+
return Flags.getNumParameters();
17671769
}
17681770
FunctionMetadataConvention getConvention() const {
17691771
return Flags.getConvention();
17701772
}
17711773
bool throws() const { return Flags.throws(); }
1774+
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
17721775

17731776
static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);
17741777

17751778
static bool classof(const TargetMetadata<Runtime> *metadata) {
17761779
return metadata->getKind() == MetadataKind::Function;
17771780
}
1781+
1782+
uint32_t *getParameterFlags() {
1783+
return reinterpret_cast<uint32_t *>(getParameters() + getNumParameters());
1784+
}
1785+
1786+
const uint32_t *getParameterFlags() const {
1787+
return reinterpret_cast<const uint32_t *>(getParameters() +
1788+
getNumParameters());
1789+
}
17781790
};
17791791
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
17801792

@@ -2639,28 +2651,58 @@ swift_getGenericWitnessTable(GenericWitnessTable *genericTable,
26392651
/// \brief Fetch a uniqued metadata for a function type.
26402652
SWIFT_RUNTIME_EXPORT
26412653
const FunctionTypeMetadata *
2642-
swift_getFunctionTypeMetadata(const void *flagsArgsAndResult[]);
2654+
swift_getFunctionTypeMetadata(FunctionTypeFlags flags,
2655+
const Metadata *const *parameters,
2656+
const uint32_t *parameterFlags,
2657+
const Metadata *result);
26432658

26442659
SWIFT_RUNTIME_EXPORT
26452660
const FunctionTypeMetadata *
26462661
swift_getFunctionTypeMetadata1(FunctionTypeFlags flags,
2647-
const void *arg0,
2648-
const Metadata *resultMetadata);
2662+
const Metadata *arg0,
2663+
const Metadata *result);
2664+
2665+
SWIFT_RUNTIME_EXPORT
2666+
const FunctionTypeMetadata *
2667+
swift_getFunctionTypeMetadata1WithFlags(FunctionTypeFlags flags,
2668+
const Metadata *arg0,
2669+
ParameterFlags flags0,
2670+
const Metadata *result);
26492671

26502672
SWIFT_RUNTIME_EXPORT
26512673
const FunctionTypeMetadata *
26522674
swift_getFunctionTypeMetadata2(FunctionTypeFlags flags,
2653-
const void *arg0,
2654-
const void *arg1,
2655-
const Metadata *resultMetadata);
2675+
const Metadata *arg0,
2676+
const Metadata *arg1,
2677+
const Metadata *result);
26562678

26572679
SWIFT_RUNTIME_EXPORT
26582680
const FunctionTypeMetadata *
2659-
swift_getFunctionTypeMetadata3(FunctionTypeFlags flags,
2660-
const void *arg0,
2661-
const void *arg1,
2662-
const void *arg2,
2663-
const Metadata *resultMetadata);
2681+
swift_getFunctionTypeMetadata2WithFlags(FunctionTypeFlags flags,
2682+
const Metadata *arg0,
2683+
ParameterFlags flags0,
2684+
const Metadata *arg1,
2685+
ParameterFlags flags1,
2686+
const Metadata *result);
2687+
2688+
SWIFT_RUNTIME_EXPORT
2689+
const FunctionTypeMetadata *swift_getFunctionTypeMetadata3(
2690+
FunctionTypeFlags flags,
2691+
const Metadata *arg0,
2692+
const Metadata *arg1,
2693+
const Metadata *arg2,
2694+
const Metadata *result);
2695+
2696+
SWIFT_RUNTIME_EXPORT
2697+
const FunctionTypeMetadata *swift_getFunctionTypeMetadata3WithFlags(
2698+
FunctionTypeFlags flags,
2699+
const Metadata *arg0,
2700+
ParameterFlags flags0,
2701+
const Metadata *arg1,
2702+
ParameterFlags flags1,
2703+
const Metadata *arg2,
2704+
ParameterFlags flags2,
2705+
const Metadata *result);
26642706

26652707
/// \brief Fetch a uniqued metadata for a thin function type.
26662708
SWIFT_RUNTIME_EXPORT

0 commit comments

Comments
 (0)