ClangImporter: Import (some) vector types.

When -enable-simd-import is active, if we encounter a vector type, try to load the SIMD Swift module, and if successful, map float, double, and int vectors to SIMD.{Float,Double,Int}N types if they exist.

Swift SVN r27367
This commit is contained in:
Joe Groff
2015-04-16 19:04:09 +00:00
parent 780a3c9eae
commit 31388b0899
11 changed files with 129 additions and 17 deletions

View File

@@ -54,6 +54,7 @@ IDENTIFIER(RawValue)
IDENTIFIER(self)
IDENTIFIER(Self)
IDENTIFIER(setObject)
IDENTIFIER(SIMD)
IDENTIFIER(Some)
IDENTIFIER(subscript)
IDENTIFIER(toRaw)

View File

@@ -83,6 +83,9 @@ namespace swift {
/// \brief Enable support for native C function pointer types.
bool EnableCFunctionPointers = false;
/// \brief Enable support for SIMD type imports.
bool EnableSIMDImport = false;
/// \brief Enable features useful for running in the debugger.
bool DebuggerSupport = false;

View File

@@ -197,6 +197,10 @@ def enable_c_function_pointers : Flag<["-"],
"enable-c-function-pointers">,
HelpText<"Enable native C function pointer types">;
def enable_simd_import : Flag<["-"],
"enable-simd-import">,
HelpText<"Enable importing C vector types as SIMD types">;
def enable_character_literals : Flag<["-"], "enable-character-literals">,
HelpText<"Enable legacy character literals">;

View File

@@ -420,13 +420,45 @@ namespace {
}
ImportResult VisitVectorType(const clang::VectorType *type) {
// FIXME: We could map these.
// We can map this into a type from the SIMD module, if it exists.
if (!Impl.SwiftContext.LangOpts.EnableSIMDImport)
return Type();
auto *SIMD = Impl.tryLoadSIMDModule();
if (!SIMD)
return Type();
// Map the element type and count to a Swift name, such as
// float x 3 => Float3.
SmallString<16> name;
{
llvm::raw_svector_ostream names(name);
if (auto builtinTy
= dyn_cast<clang::BuiltinType>(type->getElementType())){
switch (builtinTy->getKind()) {
case clang::BuiltinType::Float:
names << "Float";
break;
case clang::BuiltinType::Double:
names << "Double";
break;
case clang::BuiltinType::Int:
names << "Int";
break;
default:
// TODO:
return Type();
}
} else {
return Type();
}
ImportResult VisitExtVectorType(const clang::ExtVectorType *type) {
// FIXME: We could map these.
return Type();
names << type->getNumElements();
names.flush();
}
return Impl.getNamedSwiftType(SIMD, name);
}
ImportResult VisitFunctionProtoType(const clang::FunctionProtoType *type) {
@@ -1651,19 +1683,30 @@ Module *ClangImporter::Implementation::getNamedModule(StringRef name) {
return SwiftContext.getLoadedModule(SwiftContext.getIdentifier(name));
}
Module *ClangImporter::Implementation::tryLoadFoundationModule() {
if (!checkedFoundationModule.hasValue()) {
Identifier name = SwiftContext.getIdentifier(FOUNDATION_MODULE_NAME);
static Module *tryLoadModule(ASTContext &C,
Identifier name,
bool importForwardDeclarations,
Optional<Module *> &cache) {
if (!cache.hasValue()) {
// If we're synthesizing forward declarations, we don't want to pull in
// Foundation too eagerly.
if (ImportForwardDeclarations)
checkedFoundationModule = SwiftContext.getLoadedModule(name);
// the module too eagerly.
if (importForwardDeclarations)
cache = C.getLoadedModule(name);
else
checkedFoundationModule = SwiftContext.getModule({ {name, SourceLoc()} });
cache = C.getModule({ {name, SourceLoc()} });
}
return checkedFoundationModule.getValue();
return cache.getValue();
}
Module *ClangImporter::Implementation::tryLoadFoundationModule() {
return tryLoadModule(SwiftContext, SwiftContext.Id_Foundation,
ImportForwardDeclarations, checkedFoundationModule);
}
Module *ClangImporter::Implementation::tryLoadSIMDModule() {
return tryLoadModule(SwiftContext, SwiftContext.Id_SIMD,
ImportForwardDeclarations, checkedSIMDModule);
}
Type ClangImporter::Implementation::getNamedSwiftType(Module *module,

View File

@@ -531,7 +531,7 @@ public:
clang::Selector setObjectForKeyedSubscript;
private:
Optional<Module *> checkedFoundationModule;
Optional<Module *> checkedFoundationModule, checkedSIMDModule;
/// External Decls that we have imported but not passed to the ASTContext yet.
SmallVector<Decl *, 4> RegisteredExternalDecls;
@@ -840,6 +840,12 @@ public:
/// into the ASTContext.
Module *tryLoadFoundationModule();
/// \brief Returns the "SIMD" module, if it can be loaded.
///
/// After this has been called, the SIMD module will or won't be loaded
/// into the ASTContext.
Module *tryLoadSIMDModule();
/// \brief Retrieves the Swift wrapper for the given Clang module, creating
/// it if necessary.
ClangModuleUnit *getWrapperForModule(ClangImporter &importer,

View File

@@ -618,6 +618,9 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
Opts.EnableCFunctionPointers |=
Args.hasArg(OPT_enable_c_function_pointers);
Opts.EnableSIMDImport |=
Args.hasArg(OPT_enable_simd_import);
Opts.EnableCharacterLiterals |= Args.hasArg(OPT_enable_character_literals);
if (auto A = Args.getLastArg(OPT_enable_access_control,

View File

@@ -0,0 +1,17 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -verify -enable-simd-import %s
import c_simd
import SIMD
let f4: Float4 = makes_float4()
let i3: Int3 = makes_int3()
let d2: Double2 = makes_double2()
takes_float4(f4)
takes_int3(i3)
takes_double2(d2)
// byte17 isn't available since there isn't a type in the SIMD module to map it to.
let mb17 = makes_byte17 // expected-error{{unresolved identifier 'makes_byte17'}}
let t17 = takes_byte17 // expected-error{{unresolved identifier 'takes_byte17'}}

View File

@@ -0,0 +1,13 @@
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -parse -verify -enable-simd-import %s
import c_simd
// Ensure that the SIMD types from the imported module get mapped into the
// SIMD Swift module, even if we in the importing module don't import SIMD.
takes_float4(makes_float4())
takes_int3(makes_int3())
takes_double2(makes_double2())
// Float4 should not have been transitively imported.
let x: Float4 = makes_float4() // expected-error{{undeclared type 'Float4'}}

View File

@@ -0,0 +1,3 @@
@_alignment(16) public struct Float4 { var x, y, z, w: Float }
@_alignment(16) public struct Double2 { var x, y: Double }
@_alignment(16) public struct Int3 { var x, y, z: Int32 }

View File

@@ -97,3 +97,8 @@ module exceptions {
header "exceptions.h"
export *
}
module c_simd {
header "simd.h"
export *
}

View File

@@ -0,0 +1,14 @@
typedef int int3 __attribute__((__ext_vector_type__(3)));
typedef float float4 __attribute__((__ext_vector_type__(4)));
typedef double double2 __attribute__((__ext_vector_type__(2)));
typedef unsigned char byte17 __attribute__((__ext_vector_type__(17)));
int3 makes_int3(void);
float4 makes_float4(void);
double2 makes_double2(void);
byte17 makes_byte17(void);
void takes_int3(int3 x);
void takes_float4(float4 x);
void takes_double2(double2 x);
void takes_byte17(byte17 x);