Skip to content

Commit ab4e416

Browse files
authored
Merge pull request swiftlang#83586 from Xazax-hun/reverse-interop-better-simd
[cxx-interop] Support SIMD types in reverse interop
2 parents bf16a42 + 9807881 commit ab4e416

File tree

7 files changed

+273
-76
lines changed

7 files changed

+273
-76
lines changed

lib/IRGen/IRABIDetailsProvider.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "clang/CodeGen/ModuleBuilder.h"
3939
#include "clang/CodeGen/SwiftCallingConv.h"
4040
#include "llvm/IR/DerivedTypes.h"
41+
#include <optional>
4142

4243
using namespace swift;
4344
using namespace irgen;
@@ -59,14 +60,25 @@ getPrimitiveTypeFromLLVMType(ASTContext &ctx, const llvm::Type *type) {
5960
default:
6061
return std::nullopt;
6162
}
62-
} else if (type->isFloatTy()) {
63+
}
64+
if (type->isFloatTy()) {
6365
return ctx.getFloatType();
64-
} else if (type->isDoubleTy()) {
66+
}
67+
if (type->isDoubleTy()) {
6568
return ctx.getDoubleType();
66-
} else if (type->isPointerTy()) {
69+
}
70+
if (type->isPointerTy()) {
6771
return ctx.getOpaquePointerType();
6872
}
69-
// FIXME: Handle vector type.
73+
if (const auto *vecTy = dyn_cast<llvm::VectorType>(type)) {
74+
auto elemTy = getPrimitiveTypeFromLLVMType(ctx, vecTy->getElementType());
75+
if (!elemTy)
76+
return std::nullopt;
77+
auto elemCount = vecTy->getElementCount();
78+
if (!elemCount.isFixed())
79+
return std::nullopt;
80+
return BuiltinVectorType::get(ctx, *elemTy, elemCount.getFixedValue());
81+
}
7082
return std::nullopt;
7183
}
7284

lib/PrintAsClang/PrimitiveTypeMapping.cpp

Lines changed: 58 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313
#include "PrimitiveTypeMapping.h"
1414
#include "swift/AST/ASTContext.h"
1515
#include "swift/AST/Decl.h"
16+
#include "swift/AST/Identifier.h"
1617
#include "swift/AST/Module.h"
1718
#include "swift/Basic/Assertions.h"
1819
#include "swift/ClangImporter/ClangImporter.h"
20+
#include <optional>
1921

2022
using namespace swift;
2123

2224
/// Find the implementation of the named type in the named module if loaded.
23-
static TypeDecl *findTypeInModuleByName(ASTContext &ctx,
24-
Identifier moduleName,
25+
static TypeDecl *findTypeInModuleByName(ASTContext &ctx, Identifier moduleName,
2526
Identifier typeName) {
2627
auto module = ctx.getLoadedModule(moduleName);
2728
if (!module)
@@ -69,18 +70,15 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
6970

7071
// Map stdlib types.
7172
#define MAP(SWIFT_NAME, CLANG_REPR, NEEDS_NULLABILITY) \
72-
addMappedType(ctx.StdlibModuleName, \
73-
ctx.getIdentifier(#SWIFT_NAME), \
73+
addMappedType(ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME), \
7474
{CLANG_REPR, std::optional<StringRef>(CLANG_REPR), \
7575
std::optional<StringRef>(CLANG_REPR), NEEDS_NULLABILITY})
7676
#define MAP_C(SWIFT_NAME, OBJC_REPR, C_REPR, NEEDS_NULLABILITY) \
77-
addMappedType(ctx.StdlibModuleName, \
78-
ctx.getIdentifier(#SWIFT_NAME), \
77+
addMappedType(ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME), \
7978
{OBJC_REPR, std::optional<StringRef>(C_REPR), \
8079
std::optional<StringRef>(C_REPR), NEEDS_NULLABILITY})
8180
#define MAP_CXX(SWIFT_NAME, OBJC_REPR, C_REPR, CXX_REPR, NEEDS_NULLABILITY) \
82-
addMappedType(ctx.StdlibModuleName, \
83-
ctx.getIdentifier(#SWIFT_NAME), \
81+
addMappedType(ctx.StdlibModuleName, ctx.getIdentifier(#SWIFT_NAME), \
8482
{OBJC_REPR, std::optional<StringRef>(C_REPR), \
8583
std::optional<StringRef>(CXX_REPR), NEEDS_NULLABILITY})
8684

@@ -140,10 +138,10 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
140138
{"BOOL", std::nullopt, std::nullopt, false});
141139
addMappedType(ctx.Id_ObjectiveC, ctx.getIdentifier("Selector"),
142140
{"SEL", std::nullopt, std::nullopt, true});
143-
addMappedType(ctx.Id_ObjectiveC,
144-
ctx.getIdentifier(swift::getSwiftName(
145-
KnownFoundationEntity::NSZone)),
146-
{"struct _NSZone *", std::nullopt, std::nullopt, true});
141+
addMappedType(
142+
ctx.Id_ObjectiveC,
143+
ctx.getIdentifier(swift::getSwiftName(KnownFoundationEntity::NSZone)),
144+
{"struct _NSZone *", std::nullopt, std::nullopt, true});
147145

148146
addMappedType(ctx.Id_Darwin, ctx.getIdentifier("DarwinBoolean"),
149147
{"Boolean", std::nullopt, std::nullopt, false});
@@ -157,17 +155,33 @@ void PrimitiveTypeMapping::initialize(ASTContext &ctx) {
157155
// Use typedefs we set up for SIMD vector types.
158156
#define MAP_SIMD_TYPE(BASENAME, _, __) \
159157
StringRef simd2##BASENAME = "swift_" #BASENAME "2"; \
160-
addMappedType(ctx.Id_simd, ctx.getIdentifier(#BASENAME "2"), \
161-
{simd2##BASENAME, simd2##BASENAME, simd2##BASENAME, false}, \
162-
/*applyToUnderlying*/false); \
158+
addMappedType( \
159+
ctx.Id_simd, ctx.getIdentifier(#BASENAME "2"), \
160+
{simd2##BASENAME, simd2##BASENAME, simd2##BASENAME, false, true}, \
161+
/*applyToUnderlying*/ false); \
162+
addMappedType( \
163+
ctx.Id_simd, ctx.getIdentifier("simd_" #BASENAME "2"), \
164+
{simd2##BASENAME, simd2##BASENAME, simd2##BASENAME, false, true}, \
165+
/*applyToUnderlying*/ false); \
163166
StringRef simd3##BASENAME = "swift_" #BASENAME "3"; \
164-
addMappedType(ctx.Id_simd, ctx.getIdentifier(#BASENAME "3"), \
165-
{simd3##BASENAME, simd3##BASENAME, simd3##BASENAME, false}, \
166-
/*applyToUnderlying*/false); \
167+
addMappedType( \
168+
ctx.Id_simd, ctx.getIdentifier(#BASENAME "3"), \
169+
{simd3##BASENAME, simd3##BASENAME, simd3##BASENAME, false, true}, \
170+
/*applyToUnderlying*/ false); \
171+
addMappedType( \
172+
ctx.Id_simd, ctx.getIdentifier("simd_" #BASENAME "3"), \
173+
{simd3##BASENAME, simd3##BASENAME, simd3##BASENAME, false, true}, \
174+
/*applyToUnderlying*/ false); \
167175
StringRef simd4##BASENAME = "swift_" #BASENAME "4"; \
168-
addMappedType(ctx.Id_simd, ctx.getIdentifier(#BASENAME "4"), \
169-
{simd4##BASENAME, simd4##BASENAME, simd4##BASENAME, false}, \
170-
/*applyToUnderlying*/false);
176+
addMappedType( \
177+
ctx.Id_simd, ctx.getIdentifier(#BASENAME "4"), \
178+
{simd4##BASENAME, simd4##BASENAME, simd4##BASENAME, false, true}, \
179+
/*applyToUnderlying*/ false); \
180+
addMappedType( \
181+
ctx.Id_simd, ctx.getIdentifier("simd_" #BASENAME "4"), \
182+
{simd4##BASENAME, simd4##BASENAME, simd4##BASENAME, false, true}, \
183+
/*applyToUnderlying*/ false);
184+
171185
#include "swift/ClangImporter/SIMDMappedTypes.def"
172186
static_assert(SWIFT_MAX_IMPORTED_SIMD_ELEMENTS == 4,
173187
"must add or remove special name mappings if max number of "
@@ -192,15 +206,17 @@ PrimitiveTypeMapping::getMappedTypeInfoOrNull(const TypeDecl *typeDecl) {
192206
std::optional<PrimitiveTypeMapping::ClangTypeInfo>
193207
PrimitiveTypeMapping::getKnownObjCTypeInfo(const TypeDecl *typeDecl) {
194208
if (auto *typeInfo = getMappedTypeInfoOrNull(typeDecl))
195-
return ClangTypeInfo{typeInfo->objcName, typeInfo->canBeNullable};
209+
return ClangTypeInfo{typeInfo->objcName, typeInfo->canBeNullable,
210+
typeInfo->simd};
196211
return std::nullopt;
197212
}
198213

199214
std::optional<PrimitiveTypeMapping::ClangTypeInfo>
200215
PrimitiveTypeMapping::getKnownCTypeInfo(const TypeDecl *typeDecl) {
201216
if (auto *typeInfo = getMappedTypeInfoOrNull(typeDecl)) {
202217
if (typeInfo->cName)
203-
return ClangTypeInfo{*typeInfo->cName, typeInfo->canBeNullable};
218+
return ClangTypeInfo{*typeInfo->cName, typeInfo->canBeNullable,
219+
typeInfo->simd};
204220
}
205221
return std::nullopt;
206222
}
@@ -209,7 +225,25 @@ std::optional<PrimitiveTypeMapping::ClangTypeInfo>
209225
PrimitiveTypeMapping::getKnownCxxTypeInfo(const TypeDecl *typeDecl) {
210226
if (auto *typeInfo = getMappedTypeInfoOrNull(typeDecl)) {
211227
if (typeInfo->cxxName)
212-
return ClangTypeInfo{*typeInfo->cxxName, typeInfo->canBeNullable};
228+
return ClangTypeInfo{*typeInfo->cxxName, typeInfo->canBeNullable,
229+
typeInfo->simd};
213230
}
214231
return std::nullopt;
215232
}
233+
234+
std::optional<PrimitiveTypeMapping::ClangTypeInfo>
235+
PrimitiveTypeMapping::getKnownSIMDTypeInfo(Type t, ASTContext &ctx) {
236+
auto vecTy = t->getAs<BuiltinVectorType>();
237+
if (!vecTy)
238+
return std::nullopt;
239+
240+
auto elemTy = vecTy->getElementType();
241+
auto numElems = vecTy->getNumElements();
242+
243+
std::string elemTyName = elemTy.getString();
244+
// While the element type starts with an upper case, vector types start with
245+
// lower case.
246+
elemTyName[0] = std::tolower(elemTyName[0]);
247+
Identifier swiftName = ctx.getIdentifier("swift_" + elemTyName + std::to_string(numElems));
248+
return ClangTypeInfo{swiftName.str(), false, true};
249+
}

lib/PrintAsClang/PrimitiveTypeMapping.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,21 @@ namespace swift {
2121

2222
class ASTContext;
2323
class TypeDecl;
24+
class Type;
2425

2526
/// Provides a mapping from Swift's primitive types to C / Objective-C / C++
2627
/// primitive types.
2728
///
2829
/// Certain types have mappings that differ in different language modes.
29-
/// For example, Swift's `Int` maps to `NSInteger` for Objective-C declarations,
30-
/// but to something like `intptr_t` or `swift::Int` for C and C++ declarations.
30+
/// For example, Swift's `Int` maps to `NSInteger` for Objective-C
31+
/// declarations, but to something like `intptr_t` or `swift::Int` for C and
32+
/// C++ declarations.
3133
class PrimitiveTypeMapping {
3234
public:
3335
struct ClangTypeInfo {
3436
StringRef name;
3537
bool canBeNullable;
38+
bool simd;
3639
};
3740

3841
/// Returns the Objective-C type name and nullability for the given Swift
@@ -47,6 +50,8 @@ class PrimitiveTypeMapping {
4750
/// primitive type declaration, or \c None if no such type name exists.
4851
std::optional<ClangTypeInfo> getKnownCxxTypeInfo(const TypeDecl *typeDecl);
4952

53+
std::optional<ClangTypeInfo> getKnownSIMDTypeInfo(Type t, ASTContext &ctx);
54+
5055
private:
5156
void initialize(ASTContext &ctx);
5257

@@ -58,6 +63,7 @@ class PrimitiveTypeMapping {
5863
// The C++ name of the Swift type.
5964
std::optional<StringRef> cxxName;
6065
bool canBeNullable;
66+
bool simd = false;
6167
};
6268

6369
FullClangTypeInfo *getMappedTypeInfoOrNull(const TypeDecl *typeDecl);

0 commit comments

Comments
 (0)