Skip to content

Commit dd12fec

Browse files
authored
Merge pull request #3509 from swiftwasm/main
[pull] swiftwasm from main
2 parents e9a268a + 4164b2e commit dd12fec

File tree

75 files changed

+943
-248
lines changed

Some content is hidden

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

75 files changed

+943
-248
lines changed

include/swift/AST/Types.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3005,12 +3005,11 @@ class AnyFunctionType : public TypeBase {
30053005

30063006
public:
30073007
/// Take an array of parameters and turn it into a tuple or paren type.
3008+
///
3009+
/// \param wantParamFlags Whether to preserve the parameter flags from the
3010+
/// given set of parameters.
30083011
static Type composeTuple(ASTContext &ctx, ArrayRef<Param> params,
3009-
bool canonicalVararg);
3010-
static Type composeTuple(ASTContext &ctx, CanParamArrayRef params,
3011-
bool canonicalVararg) {
3012-
return composeTuple(ctx, params.getOriginalArray(), canonicalVararg);
3013-
}
3012+
bool wantParamFlags = true);
30143013

30153014
/// Given two arrays of parameters determine if they are equal in their
30163015
/// canonicalized form. Internal labels and type sugar is *not* taken into

include/swift/SIL/AbstractionPattern.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -432,6 +432,7 @@ class AbstractionPattern {
432432
const clang::ObjCMethodDecl *ObjCMethod;
433433
const clang::CXXMethodDecl *CXXMethod;
434434
const AbstractionPattern *OrigTupleElements;
435+
const void *RawTypePtr;
435436
};
436437
CanGenericSignature GenericSig;
437438

@@ -1274,7 +1275,7 @@ class AbstractionPattern {
12741275
/// pattern?
12751276
bool matchesTuple(CanTupleType substType);
12761277

1277-
bool isTuple() {
1278+
bool isTuple() const {
12781279
switch (getKind()) {
12791280
case Kind::Invalid:
12801281
llvm_unreachable("querying invalid abstraction pattern!");
@@ -1386,8 +1387,32 @@ class AbstractionPattern {
13861387
Lowering::TypeConverter &TC
13871388
) const;
13881389

1390+
/// How values are passed or returned according to this abstraction pattern.
1391+
enum CallingConventionKind {
1392+
// Value is passed or returned directly as a unit.
1393+
Direct,
1394+
// Value is passed or returned indirectly through memory.
1395+
Indirect,
1396+
// Value is a tuple that is destructured, and each element is considered
1397+
// independently.
1398+
Destructured,
1399+
};
1400+
1401+
/// If this abstraction pattern appears in function return position, how is
1402+
/// the corresponding value returned?
1403+
CallingConventionKind getResultConvention(TypeConverter &TC) const;
1404+
1405+
/// If this abstraction pattern appears in function parameter position, how
1406+
/// is the corresponding value passed?
1407+
CallingConventionKind getParameterConvention(TypeConverter &TC) const;
1408+
13891409
void dump() const LLVM_ATTRIBUTE_USED;
13901410
void print(raw_ostream &OS) const;
1411+
1412+
bool operator==(const AbstractionPattern &other) const;
1413+
bool operator!=(const AbstractionPattern &other) const {
1414+
return !(*this == other);
1415+
}
13911416
};
13921417

13931418
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &out,

include/swift/SIL/TypeLowering.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -734,6 +734,9 @@ class TypeConverter {
734734
///
735735
/// Second element is a ResilienceExpansion.
736736
llvm::DenseMap<std::pair<SILType, unsigned>, unsigned> TypeFields;
737+
738+
llvm::DenseMap<AbstractClosureExpr *, Optional<AbstractionPattern>>
739+
ClosureAbstractionPatterns;
737740

738741
CanAnyFunctionType makeConstantInterfaceType(SILDeclRef constant);
739742

@@ -1106,6 +1109,22 @@ class TypeConverter {
11061109
SILType enumType,
11071110
EnumElementDecl *elt);
11081111

1112+
/// Get the preferred abstraction pattern, if any, by which to lower a
1113+
/// declaration.
1114+
///
1115+
/// This can be set using \c setAbstractionPattern , but only before
1116+
/// the abstraction pattern is queried using this function. Once the
1117+
/// abstraction pattern has been asked for, it may not be changed.
1118+
Optional<AbstractionPattern> getConstantAbstractionPattern(SILDeclRef constant);
1119+
1120+
/// Set the preferred abstraction pattern for a closure.
1121+
///
1122+
/// The abstraction pattern can only be set before any calls to
1123+
/// \c getConstantAbstractionPattern on the same closure. It may not be
1124+
/// changed once it has been read.
1125+
void setAbstractionPattern(AbstractClosureExpr *closure,
1126+
AbstractionPattern pattern);
1127+
11091128
private:
11101129
CanType computeLoweredRValueType(TypeExpansionContext context,
11111130
AbstractionPattern origType,

lib/APIDigester/ModuleAnalyzerNodes.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,8 +1519,7 @@ SwiftDeclCollector::constructTypeNode(Type T, TypeInitInfo Info) {
15191519
Root->addChild(constructTypeNode(Fun->getResult()));
15201520

15211521
auto Input = AnyFunctionType::composeTuple(Fun->getASTContext(),
1522-
Fun->getParams(),
1523-
/*canonicalVararg=*/false);
1522+
Fun->getParams());
15241523
Root->addChild(constructTypeNode(Input));
15251524
return Root;
15261525
}

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3457,12 +3457,12 @@ Type AnyFunctionType::Param::getParameterType(bool forCanonical,
34573457
}
34583458

34593459
Type AnyFunctionType::composeTuple(ASTContext &ctx, ArrayRef<Param> params,
3460-
bool canonicalVararg) {
3460+
bool wantParamFlags) {
34613461
SmallVector<TupleTypeElt, 4> elements;
34623462
for (const auto &param : params) {
3463-
Type eltType = param.getParameterType(canonicalVararg, &ctx);
3464-
elements.emplace_back(eltType, param.getLabel(),
3465-
param.getParameterFlags());
3463+
auto flags = wantParamFlags ? param.getParameterFlags()
3464+
: ParameterTypeFlags();
3465+
elements.emplace_back(param.getParameterType(), param.getLabel(), flags);
34663466
}
34673467
return TupleType::get(elements, ctx);
34683468
}

lib/AST/ASTVerifier.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,6 +1136,7 @@ class Verifier : public ASTWalker {
11361136
}
11371137

11381138
void verifyChecked(TupleExpr *E) {
1139+
PrettyStackTraceExpr debugStack(Ctx, "verifying TupleExpr", E);
11391140
const TupleType *exprTy = E->getType()->castTo<TupleType>();
11401141
for_each(exprTy->getElements().begin(), exprTy->getElements().end(),
11411142
E->getElements().begin(),
@@ -1148,8 +1149,14 @@ class Verifier : public ASTWalker {
11481149
Out << elt->getType() << "\n";
11491150
abort();
11501151
}
1152+
if (!field.getParameterFlags().isNone()) {
1153+
Out << "TupleExpr has non-empty parameter flags?\n";
1154+
Out << "sub expr: \n";
1155+
elt->dump(Out);
1156+
Out << "\n";
1157+
abort();
1158+
}
11511159
});
1152-
// FIXME: Check all the variadic elements.
11531160
verifyCheckedBase(E);
11541161
}
11551162

@@ -1970,10 +1977,15 @@ class Verifier : public ASTWalker {
19701977

19711978
void verifyChecked(ParenExpr *E) {
19721979
PrettyStackTraceExpr debugStack(Ctx, "verifying ParenExpr", E);
1973-
if (!isa<ParenType>(E->getType().getPointer())) {
1980+
auto ty = dyn_cast<ParenType>(E->getType().getPointer());
1981+
if (!ty) {
19741982
Out << "ParenExpr not of ParenType\n";
19751983
abort();
19761984
}
1985+
if (!ty->getParameterFlags().isNone()) {
1986+
Out << "ParenExpr has non-empty parameter flags?\n";
1987+
abort();
1988+
}
19771989
verifyCheckedBase(E);
19781990
}
19791991

lib/AST/RequirementMachine/Symbol.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,9 @@ int Symbol::compare(Symbol other, const ProtocolGraph &graph) const {
506506
auto protos = getProtocols();
507507
auto otherProtos = other.getProtocols();
508508

509+
if (getName() != other.getName())
510+
return getName().compare(other.getName());
511+
509512
// Symbols with more protocols are 'smaller' than those with fewer.
510513
if (protos.size() != otherProtos.size())
511514
return protos.size() > otherProtos.size() ? -1 : 1;
@@ -516,7 +519,6 @@ int Symbol::compare(Symbol other, const ProtocolGraph &graph) const {
516519
return result;
517520
}
518521

519-
result = getName().compare(other.getName());
520522
break;
521523
}
522524

lib/Option/features.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
},
99
{
1010
"name": "index-unit-output-path"
11+
},
12+
{
13+
"name": "library-level"
1114
}
1215
]
1316
}

lib/SIL/IR/AbstractionPattern.cpp

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,3 +1233,155 @@ AbstractionPattern AbstractionPattern::getAutoDiffDerivativeFunctionType(
12331233
llvm_unreachable("called on unsupported abstraction pattern kind");
12341234
}
12351235
}
1236+
1237+
AbstractionPattern::CallingConventionKind
1238+
AbstractionPattern::getResultConvention(TypeConverter &TC) const {
1239+
// Tuples should be destructured.
1240+
if (isTuple()) {
1241+
return Destructured;
1242+
}
1243+
switch (getKind()) {
1244+
case Kind::Opaque:
1245+
// Maximally abstracted values are always passed indirectly.
1246+
return Indirect;
1247+
1248+
case Kind::OpaqueFunction:
1249+
case Kind::OpaqueDerivativeFunction:
1250+
case Kind::PartialCurriedObjCMethodType:
1251+
case Kind::CurriedObjCMethodType:
1252+
case Kind::PartialCurriedCFunctionAsMethodType:
1253+
case Kind::CurriedCFunctionAsMethodType:
1254+
case Kind::CFunctionAsMethodType:
1255+
case Kind::ObjCMethodType:
1256+
case Kind::CXXMethodType:
1257+
case Kind::CurriedCXXMethodType:
1258+
case Kind::PartialCurriedCXXMethodType:
1259+
case Kind::CXXOperatorMethodType:
1260+
case Kind::CurriedCXXOperatorMethodType:
1261+
case Kind::PartialCurriedCXXOperatorMethodType:
1262+
// Function types are always passed directly
1263+
return Direct;
1264+
1265+
case Kind::ClangType:
1266+
case Kind::Type:
1267+
case Kind::Discard:
1268+
// Pass according to the formal type.
1269+
return SILType::isFormallyReturnedIndirectly(getType(),
1270+
TC,
1271+
getGenericSignatureOrNull())
1272+
? Indirect : Direct;
1273+
1274+
case Kind::Invalid:
1275+
case Kind::Tuple:
1276+
case Kind::ObjCCompletionHandlerArgumentsType:
1277+
llvm_unreachable("should not get here");
1278+
}
1279+
}
1280+
1281+
AbstractionPattern::CallingConventionKind
1282+
AbstractionPattern::getParameterConvention(TypeConverter &TC) const {
1283+
// Tuples should be destructured.
1284+
if (isTuple()) {
1285+
return Destructured;
1286+
}
1287+
switch (getKind()) {
1288+
case Kind::Opaque:
1289+
// Maximally abstracted values are always passed indirectly.
1290+
return Indirect;
1291+
1292+
case Kind::OpaqueFunction:
1293+
case Kind::OpaqueDerivativeFunction:
1294+
case Kind::PartialCurriedObjCMethodType:
1295+
case Kind::CurriedObjCMethodType:
1296+
case Kind::PartialCurriedCFunctionAsMethodType:
1297+
case Kind::CurriedCFunctionAsMethodType:
1298+
case Kind::CFunctionAsMethodType:
1299+
case Kind::ObjCMethodType:
1300+
case Kind::CXXMethodType:
1301+
case Kind::CurriedCXXMethodType:
1302+
case Kind::PartialCurriedCXXMethodType:
1303+
case Kind::CXXOperatorMethodType:
1304+
case Kind::CurriedCXXOperatorMethodType:
1305+
case Kind::PartialCurriedCXXOperatorMethodType:
1306+
// Function types are always passed directly
1307+
return Direct;
1308+
1309+
case Kind::ClangType:
1310+
case Kind::Type:
1311+
case Kind::Discard:
1312+
// Pass according to the formal type.
1313+
return SILType::isFormallyPassedIndirectly(getType(),
1314+
TC,
1315+
getGenericSignatureOrNull())
1316+
? Indirect : Direct;
1317+
1318+
case Kind::Invalid:
1319+
case Kind::Tuple:
1320+
case Kind::ObjCCompletionHandlerArgumentsType:
1321+
llvm_unreachable("should not get here");
1322+
}
1323+
}
1324+
1325+
bool
1326+
AbstractionPattern::operator==(const AbstractionPattern &other) const {
1327+
if (TheKind != other.TheKind)
1328+
return false;
1329+
1330+
switch (getKind()) {
1331+
case Kind::Opaque:
1332+
case Kind::Invalid:
1333+
case Kind::OpaqueFunction:
1334+
case Kind::OpaqueDerivativeFunction:
1335+
// No additional info to compare.
1336+
return true;
1337+
1338+
case Kind::Tuple:
1339+
if (getNumTupleElements() != other.getNumTupleElements()) {
1340+
return false;
1341+
}
1342+
for (unsigned i = 0; i < getNumTupleElements(); ++i) {
1343+
if (getTupleElementType(i) != other.getTupleElementType(i)) {
1344+
return false;
1345+
}
1346+
}
1347+
return true;
1348+
1349+
case Kind::Type:
1350+
case Kind::Discard:
1351+
return OrigType == other.OrigType
1352+
&& GenericSig == other.GenericSig;
1353+
1354+
case Kind::ClangType:
1355+
return OrigType == other.OrigType
1356+
&& GenericSig == other.GenericSig
1357+
&& ClangType == other.ClangType;
1358+
1359+
case Kind::ObjCCompletionHandlerArgumentsType:
1360+
case Kind::CFunctionAsMethodType:
1361+
case Kind::CurriedCFunctionAsMethodType:
1362+
case Kind::PartialCurriedCFunctionAsMethodType:
1363+
return OrigType == other.OrigType
1364+
&& GenericSig == other.GenericSig
1365+
&& ClangType == other.ClangType
1366+
&& OtherData == other.OtherData;
1367+
1368+
case Kind::ObjCMethodType:
1369+
case Kind::CurriedObjCMethodType:
1370+
case Kind::PartialCurriedObjCMethodType:
1371+
return OrigType == other.OrigType
1372+
&& GenericSig == other.GenericSig
1373+
&& ObjCMethod == other.ObjCMethod
1374+
&& OtherData == other.OtherData;
1375+
1376+
case Kind::CXXMethodType:
1377+
case Kind::CXXOperatorMethodType:
1378+
case Kind::CurriedCXXMethodType:
1379+
case Kind::CurriedCXXOperatorMethodType:
1380+
case Kind::PartialCurriedCXXMethodType:
1381+
case Kind::PartialCurriedCXXOperatorMethodType:
1382+
return OrigType == other.OrigType
1383+
&& GenericSig == other.GenericSig
1384+
&& CXXMethod == other.CXXMethod
1385+
&& OtherData == other.OtherData;
1386+
}
1387+
}

lib/SIL/IR/SILFunctionType.cpp

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2072,7 +2072,8 @@ static CanSILFunctionType getSILFunctionType(
20722072
// for thick or polymorphic functions. We don't need to worry about
20732073
// non-opaque patterns because the type-checker forbids non-thick
20742074
// function types from having generic parameters or results.
2075-
if (origType.isTypeParameter() &&
2075+
if (!constant &&
2076+
origType.isTypeParameter() &&
20762077
substFnInterfaceType->getExtInfo().getSILRepresentation()
20772078
!= SILFunctionType::Representation::Thick &&
20782079
isa<FunctionType>(substFnInterfaceType)) {
@@ -3183,9 +3184,18 @@ static CanSILFunctionType getUncachedSILFunctionTypeForConstant(
31833184
auto proto = constant.getDecl()->getDeclContext()->getSelfProtocolDecl();
31843185
witnessMethodConformance = ProtocolConformanceRef(proto);
31853186
}
3187+
3188+
// Does this constant have a preferred abstraction pattern set?
3189+
AbstractionPattern origType = [&]{
3190+
if (auto abstraction = TC.getConstantAbstractionPattern(constant)) {
3191+
return *abstraction;
3192+
} else {
3193+
return AbstractionPattern(origLoweredInterfaceType);
3194+
}
3195+
}();
31863196

31873197
return ::getNativeSILFunctionType(
3188-
TC, context, AbstractionPattern(origLoweredInterfaceType),
3198+
TC, context, origType,
31893199
origLoweredInterfaceType, extInfoBuilder, constant, constant, None,
31903200
witnessMethodConformance);
31913201
}

0 commit comments

Comments
 (0)