IRGen/Runtime: Use only the 'layout' subset of the vwtable to perform value type layout.

Full type metadata isn't necessary to calculate the runtime layout of a dependent struct or enum; we only need the non-function data from the value witness table (size, alignment, extra inhabitant count, and POD/BT/etc. flags). This can be generated more efficiently than the type metadata for many types--if we know a specific instantiation is fixed-layout, we can regenerate the layout information, or if we know the type has the same layout as another well-known type, we can get the layout from a common value witness table. This breaks a deadlock in most (but not all) cases where a value type is recursive using classes or fixed-layout indirected structs like UnsafePointer. rdar://problem/19898165

This time, factor out the ObjC-dependent parts of the tests so they only run with ObjC interop.

Swift SVN r30266
This commit is contained in:
Joe Groff
2015-07-16 15:38:17 +00:00
parent a41d7b7292
commit ec61fa4c5a
21 changed files with 736 additions and 88 deletions

View File

@@ -24,6 +24,7 @@
#include "swift/Basic/SuccessorMap.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Hashing.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
@@ -105,6 +106,7 @@ namespace irgen {
class ClangTypeConverter;
class EnumImplStrategy;
class ExplosionSchema;
class FixedTypeInfo;
class FormalType;
class IRGenDebugInfo;
class LinkEntity;
@@ -547,9 +549,20 @@ private:
/// protocol record.
llvm::WeakVH ref;
};
llvm::DenseMap<ProtocolDecl*, ObjCProtocolPair> ObjCProtocols;
llvm::SmallVector<ProtocolDecl*, 4> LazyObjCProtocolDefinitions;
llvm::SmallVector<ProtocolDecl*, 4> LazyObjCProtocolDefinitions;
/// Uniquing key for a fixed type layout record.
struct FixedLayoutKey {
unsigned size;
unsigned numExtraInhabitants;
unsigned align: 16;
unsigned pod: 1;
unsigned bitwiseTakable: 1;
};
friend struct ::llvm::DenseMapInfo<swift::irgen::IRGenModule::FixedLayoutKey>;
llvm::DenseMap<FixedLayoutKey, llvm::Constant *> PrivateFixedLayouts;
/// A mapping from order numbers to the LLVM functions which we
/// created for the SIL functions with those orders.
@@ -630,7 +643,8 @@ public:
void emitSILFunction(SILFunction *f);
void emitSILWitnessTable(SILWitnessTable *wt);
void emitSILStaticInitializer();
llvm::Constant *emitFixedTypeLayout(CanType t, const FixedTypeInfo &ti);
void emitNestedTypeDecls(DeclRange members);
void emitClangDecl(clang::Decl *decl);
void finalizeClangCodeGen();
@@ -728,4 +742,33 @@ public:
} // end namespace irgen
} // end namespace swift
namespace llvm {
template<>
struct DenseMapInfo<swift::irgen::IRGenModule::FixedLayoutKey> {
using FixedLayoutKey = swift::irgen::IRGenModule::FixedLayoutKey;
static inline FixedLayoutKey getEmptyKey() {
return {0, 0xFFFFFFFFu, 0, 0, 0};
}
static inline FixedLayoutKey getTombstoneKey() {
return {0, 0xFFFFFFFEu, 0, 0, 0};
}
static unsigned getHashValue(const FixedLayoutKey &key) {
return hash_combine(key.size, key.numExtraInhabitants, key.align,
(bool)key.pod, (bool)key.bitwiseTakable);
}
static bool isEqual(const FixedLayoutKey &a, const FixedLayoutKey &b) {
return a.size == b.size
&& a.numExtraInhabitants == b.numExtraInhabitants
&& a.align == b.align
&& a.pod == b.pod
&& a.bitwiseTakable == b.bitwiseTakable;
}
};
}
#endif