IRGen: Emit type references for remote reflection

- Implement emission of type references for nominal type field
  reflection, using a small custom encoder resulting in packed
  structs, not strings. This will let us embed 7-bit encoded
  32-bit relative offsets directly in the structure (not yet
  hooked in).
- Use the AST Mangler for encoding type references
  Archetypes and internal references were complicating this before, so we
  can take the opportunity to reuse this machinery and avoid unique code
  and new ABI.

Next up: Tests for reading the reflection sections and converting the
demangle tree into a tree of type references.

Todo: For concrete types, serialize the types for associated types of
their conformances to bootstrap the typeref substitution process.

rdar://problem/15617914
This commit is contained in:
David Farler
2016-01-27 15:41:04 -08:00
parent 1c29dc49ae
commit a6a5ece206
33 changed files with 724 additions and 498 deletions

View File

@@ -293,18 +293,9 @@ IRGenModule::IRGenModule(IRGenModuleDispatcher &dispatcher, SourceFile *SF,
TypeMetadataRecordPtrTy
= TypeMetadataRecordTy->getPointerTo(DefaultAS);
FieldDescriptorTy = createStructType(*this, "swift.field_descriptor", {
Int32Ty, // Number of fields that follow
Int32Ty, // Size of fields that follow
// Tail-allocated FieldRecordTy elements
});
FieldRecordTy = createStructType(*this, "swift.field_record", {
Int32Ty, // Flags
RelativeAddressTy, // Offset to metadata or mangled name for external type
RelativeAddressTy, // Offset to field name
});
FieldRecordPtrTy = FieldRecordTy->getPointerTo(DefaultAS);
FieldDescriptorTy
= llvm::StructType::create(LLVMContext, "swift.field_descriptor");
FieldDescriptorPtrTy = FieldDescriptorTy->getPointerTo(DefaultAS);
FixedBufferTy = nullptr;
for (unsigned i = 0; i != MaxNumValueWitnesses; ++i)
@@ -476,6 +467,34 @@ llvm::Constant *IRGenModule::get##ID##Fn() { \
}
#include "RuntimeFunctions.def"
std::pair<llvm::GlobalVariable *, llvm::Constant *>
IRGenModule::createStringConstant(StringRef Str,
bool willBeRelativelyAddressed, StringRef sectionName) {
// If not, create it. This implicitly adds a trailing null.
auto init = llvm::ConstantDataArray::getString(LLVMContext, Str);
auto global = new llvm::GlobalVariable(Module, init->getType(), true,
llvm::GlobalValue::PrivateLinkage,
init);
// FIXME: ld64 crashes resolving relative references to coalesceable symbols.
// rdar://problem/22674524
// If we intend to relatively address this string, don't mark it with
// unnamed_addr to prevent it from going into the cstrings section and getting
// coalesced.
if (!willBeRelativelyAddressed)
global->setUnnamedAddr(true);
if (!sectionName.empty())
global->setSection(sectionName);
// Drill down to make an i8*.
auto zero = llvm::ConstantInt::get(SizeTy, 0);
llvm::Constant *indices[] = { zero, zero };
auto address = llvm::ConstantExpr::getInBoundsGetElementPtr(
global->getValueType(), global, indices);
return { global, address };
}
llvm::Constant *IRGenModule::getEmptyTupleMetadata() {
if (EmptyTupleMetadata)
return EmptyTupleMetadata;
@@ -899,30 +918,3 @@ IRGenModule *IRGenModuleDispatcher::getGenModule(SILFunction *f) {
return getPrimaryIGM();
}
StringRef IRGenModule::getFieldMetadataSectionName() {
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
return "__DATA, __swift2_field_names, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
return ".swift2_field_names";
break;
default:
llvm_unreachable("Don't know how to emit field name table for "
"the selected object format.");
}
}
StringRef IRGenModule::getFieldNamesSectionName() {
switch (TargetInfo.OutputObjectFormat) {
case llvm::Triple::MachO:
return "__DATA, __swift2_field_metadata, regular, no_dead_strip";
break;
case llvm::Triple::ELF:
return ".swift2_field_metadata";
break;
default:
llvm_unreachable("Don't know how to emit field metadata table for "
"the selected object format.");
}
}