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

Swift SVN r30243
This commit is contained in:
Joe Groff
2015-07-16 01:28:42 +00:00
parent 8f78e7ab16
commit 2641d566ac
20 changed files with 670 additions and 88 deletions

View File

@@ -397,8 +397,8 @@ namespace {
SILType T) const override {
// Get the field offset vector.
llvm::Value *fieldVector = emitAddressOfFieldOffsetVector(IGF,
T.getStructOrBoundGenericStruct(),
metadata).getAddress();
T.getStructOrBoundGenericStruct(),
metadata).getAddress();
// Collect the stored properties of the type.
llvm::SmallVector<VarDecl*, 4> storedProperties;
@@ -406,17 +406,17 @@ namespace {
->getStoredProperties()) {
storedProperties.push_back(prop);
}
// Fill out an array with the field type metadata records.
// Fill out an array with the field type layout records.
Address fields = IGF.createAlloca(
llvm::ArrayType::get(IGF.IGM.TypeMetadataPtrTy,
llvm::ArrayType::get(IGF.IGM.Int8PtrPtrTy,
storedProperties.size()),
IGF.IGM.getPointerAlignment(), "structFields");
fields = IGF.Builder.CreateBitCast(fields,
IGF.IGM.TypeMetadataPtrTy->getPointerTo());
fields = IGF.Builder.CreateStructGEP(fields, 0, Size(0));
unsigned index = 0;
for (auto prop : storedProperties) {
auto propTy = T.getFieldType(prop, *IGF.IGM.SILMod);
llvm::Value *metadata = IGF.emitTypeMetadataRefForLayout(propTy);
llvm::Value *metadata = IGF.emitTypeLayoutRef(propTy);
Address field = IGF.Builder.CreateConstArrayGEP(fields, index,
IGF.IGM.getPointerSize());
IGF.Builder.CreateStore(metadata, field);