Skip to content

Commit cbee90c

Browse files
authored
Merge pull request swiftlang#12812 from xedin/bring-back-function-metadata-changes
[IRGen] Improve function type metadata representation
2 parents e0ff7fe + aba149a commit cbee90c

File tree

17 files changed

+630
-256
lines changed

17 files changed

+630
-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: 35 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
};
@@ -800,38 +800,25 @@ class MetadataReader {
800800
auto Function = cast<TargetFunctionTypeMetadata<Runtime>>(Meta);
801801

802802
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))
803+
for (unsigned i = 0, n = Function->getNumParameters(); i != n; ++i) {
804+
auto ParamTypeRef = readTypeFromMetadata(Function->getParameter(i));
805+
if (!ParamTypeRef)
810806
return BuiltType();
811807

812808
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 {
825-
return BuiltType();
826-
}
809+
Param.setType(ParamTypeRef);
810+
Param.setFlags(Function->getParameterFlags(i));
811+
Parameters.push_back(std::move(Param));
827812
}
828813

829814
auto Result = readTypeFromMetadata(Function->ResultType);
830815
if (!Result)
831816
return BuiltType();
832817

833-
auto flags = FunctionTypeFlags().withConvention(Function->getConvention())
834-
.withThrows(Function->throws());
818+
auto flags = FunctionTypeFlags()
819+
.withConvention(Function->getConvention())
820+
.withThrows(Function->throws())
821+
.withParameterFlags(Function->hasParameterFlags());
835822
auto BuiltFunction =
836823
Builder.createFunctionType(Parameters, Result, flags);
837824
TypeCache[MetadataAddress] = BuiltFunction;
@@ -1195,8 +1182,26 @@ class MetadataReader {
11951182
return _readMetadata<TargetExistentialMetatypeMetadata>(address);
11961183
case MetadataKind::ForeignClass:
11971184
return _readMetadata<TargetForeignClassMetadata>(address);
1198-
case MetadataKind::Function:
1199-
return _readMetadata<TargetFunctionTypeMetadata>(address);
1185+
case MetadataKind::Function: {
1186+
StoredSize flagsValue;
1187+
auto flagsAddr =
1188+
address + TargetFunctionTypeMetadata<Runtime>::OffsetToFlags;
1189+
if (!Reader->readInteger(RemoteAddress(flagsAddr), &flagsValue))
1190+
return nullptr;
1191+
1192+
auto flags =
1193+
TargetFunctionTypeFlags<StoredSize>::fromIntValue(flagsValue);
1194+
1195+
using Parameter =
1196+
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>;
1197+
auto totalSize = sizeof(TargetFunctionTypeMetadata<Runtime>) +
1198+
flags.getNumParameters() * sizeof(Parameter);
1199+
1200+
if (flags.hasParameterFlags())
1201+
totalSize += flags.getNumParameters() * sizeof(uint32_t);
1202+
1203+
return _readMetadata(address, totalSize);
1204+
}
12001205
case MetadataKind::HeapGenericLocalVariable:
12011206
return _readMetadata<TargetGenericBoxHeapMetadata>(address);
12021207
case MetadataKind::HeapLocalVariable:

include/swift/Runtime/Metadata.h

Lines changed: 68 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1745,36 +1745,53 @@ 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 = ConstTargetMetadataPointer<Runtime, swift::TargetMetadata>;
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+
Parameter getParameter(unsigned index) const {
1762+
assert(index < getNumParameters());
1763+
return getParameters()[index];
17631764
}
1764-
1765-
StoredSize getNumArguments() const {
1766-
return Flags.getNumArguments();
1765+
1766+
ParameterFlags getParameterFlags(unsigned index) const {
1767+
assert(index < getNumParameters());
1768+
auto flags = hasParameterFlags() ? getParameterFlags()[index] : 0;
1769+
return ParameterFlags::fromIntValue(flags);
1770+
}
1771+
1772+
StoredSize getNumParameters() const {
1773+
return Flags.getNumParameters();
17671774
}
17681775
FunctionMetadataConvention getConvention() const {
17691776
return Flags.getConvention();
17701777
}
17711778
bool throws() const { return Flags.throws(); }
1779+
bool hasParameterFlags() const { return Flags.hasParameterFlags(); }
17721780

17731781
static constexpr StoredSize OffsetToFlags = sizeof(TargetMetadata<Runtime>);
17741782

17751783
static bool classof(const TargetMetadata<Runtime> *metadata) {
17761784
return metadata->getKind() == MetadataKind::Function;
17771785
}
1786+
1787+
uint32_t *getParameterFlags() {
1788+
return reinterpret_cast<uint32_t *>(getParameters() + getNumParameters());
1789+
}
1790+
1791+
const uint32_t *getParameterFlags() const {
1792+
return reinterpret_cast<const uint32_t *>(getParameters() +
1793+
getNumParameters());
1794+
}
17781795
};
17791796
using FunctionTypeMetadata = TargetFunctionTypeMetadata<InProcess>;
17801797

@@ -2639,28 +2656,58 @@ swift_getGenericWitnessTable(GenericWitnessTable *genericTable,
26392656
/// \brief Fetch a uniqued metadata for a function type.
26402657
SWIFT_RUNTIME_EXPORT
26412658
const FunctionTypeMetadata *
2642-
swift_getFunctionTypeMetadata(const void *flagsArgsAndResult[]);
2659+
swift_getFunctionTypeMetadata(FunctionTypeFlags flags,
2660+
const Metadata *const *parameters,
2661+
const uint32_t *parameterFlags,
2662+
const Metadata *result);
26432663

26442664
SWIFT_RUNTIME_EXPORT
26452665
const FunctionTypeMetadata *
26462666
swift_getFunctionTypeMetadata1(FunctionTypeFlags flags,
2647-
const void *arg0,
2648-
const Metadata *resultMetadata);
2667+
const Metadata *arg0,
2668+
const Metadata *result);
2669+
2670+
SWIFT_RUNTIME_EXPORT
2671+
const FunctionTypeMetadata *
2672+
swift_getFunctionTypeMetadata1WithFlags(FunctionTypeFlags flags,
2673+
const Metadata *arg0,
2674+
ParameterFlags flags0,
2675+
const Metadata *result);
26492676

26502677
SWIFT_RUNTIME_EXPORT
26512678
const FunctionTypeMetadata *
26522679
swift_getFunctionTypeMetadata2(FunctionTypeFlags flags,
2653-
const void *arg0,
2654-
const void *arg1,
2655-
const Metadata *resultMetadata);
2680+
const Metadata *arg0,
2681+
const Metadata *arg1,
2682+
const Metadata *result);
26562683

26572684
SWIFT_RUNTIME_EXPORT
26582685
const FunctionTypeMetadata *
2659-
swift_getFunctionTypeMetadata3(FunctionTypeFlags flags,
2660-
const void *arg0,
2661-
const void *arg1,
2662-
const void *arg2,
2663-
const Metadata *resultMetadata);
2686+
swift_getFunctionTypeMetadata2WithFlags(FunctionTypeFlags flags,
2687+
const Metadata *arg0,
2688+
ParameterFlags flags0,
2689+
const Metadata *arg1,
2690+
ParameterFlags flags1,
2691+
const Metadata *result);
2692+
2693+
SWIFT_RUNTIME_EXPORT
2694+
const FunctionTypeMetadata *swift_getFunctionTypeMetadata3(
2695+
FunctionTypeFlags flags,
2696+
const Metadata *arg0,
2697+
const Metadata *arg1,
2698+
const Metadata *arg2,
2699+
const Metadata *result);
2700+
2701+
SWIFT_RUNTIME_EXPORT
2702+
const FunctionTypeMetadata *swift_getFunctionTypeMetadata3WithFlags(
2703+
FunctionTypeFlags flags,
2704+
const Metadata *arg0,
2705+
ParameterFlags flags0,
2706+
const Metadata *arg1,
2707+
ParameterFlags flags1,
2708+
const Metadata *arg2,
2709+
ParameterFlags flags2,
2710+
const Metadata *result);
26642711

26652712
/// \brief Fetch a uniqued metadata for a thin function type.
26662713
SWIFT_RUNTIME_EXPORT

0 commit comments

Comments
 (0)