summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Bitcode/Reader/MetadataLoader.cpp')
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp49
1 files changed, 39 insertions, 10 deletions
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index 1e28411d01e..eb24ac6def1 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -86,6 +86,12 @@
using namespace llvm;
+/// Flag whether we need to import full type definitions for ThinLTO.
+/// Currently needed for Darwin and LLDB.
+static cl::opt<bool> ImportFullTypeDefinitions(
+ "import-full-type-definitions", cl::init(false), cl::Hidden,
+ cl::desc("Import full type definitions for ThinLTO."));
+
namespace {
static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; }
@@ -399,7 +405,7 @@ public:
Stream(Stream), Context(TheModule.getContext()), TheModule(TheModule),
getTypeByID(getTypeByID) {}
- Error parseMetadata(bool ModuleLevel);
+ Error parseMetadata(bool ModuleLevel, bool IsImporting);
bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
Metadata *getMetadataFwdRef(unsigned Idx) {
@@ -435,7 +441,8 @@ Error error(const Twine &Message) {
/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
/// module level metadata.
-Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
+Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel,
+ bool IsImporting) {
if (!ModuleLevel && MetadataList.hasFwdRefs())
return error("Invalid metadata: fwd refs into function blocks");
@@ -709,18 +716,38 @@ Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel) {
Metadata *File = getMDOrNull(Record[3]);
unsigned Line = Record[4];
Metadata *Scope = getDITypeRefOrNull(Record[5]);
- Metadata *BaseType = getDITypeRefOrNull(Record[6]);
+ Metadata *BaseType = nullptr;
uint64_t SizeInBits = Record[7];
if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
return error("Alignment value is too large");
uint32_t AlignInBits = Record[8];
- uint64_t OffsetInBits = Record[9];
+ uint64_t OffsetInBits = 0;
DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
- Metadata *Elements = getMDOrNull(Record[11]);
+ Metadata *Elements = nullptr;
unsigned RuntimeLang = Record[12];
- Metadata *VTableHolder = getDITypeRefOrNull(Record[13]);
- Metadata *TemplateParams = getMDOrNull(Record[14]);
+ Metadata *VTableHolder = nullptr;
+ Metadata *TemplateParams = nullptr;
auto *Identifier = getMDString(Record[15]);
+ // If this module is being parsed so that it can be ThinLTO imported
+ // into another module, composite types only need to be imported
+ // as type declarations (unless full type definitions requested).
+ // Create type declarations up front to save memory. Also, buildODRType
+ // handles the case where this is type ODRed with a definition needed
+ // by the importing module, in which case the existing definition is
+ // used.
+ if (IsImporting && !ImportFullTypeDefinitions &&
+ (Tag == dwarf::DW_TAG_enumeration_type ||
+ Tag == dwarf::DW_TAG_class_type ||
+ Tag == dwarf::DW_TAG_structure_type ||
+ Tag == dwarf::DW_TAG_union_type)) {
+ Flags = Flags | DINode::FlagFwdDecl;
+ } else {
+ BaseType = getDITypeRefOrNull(Record[6]);
+ OffsetInBits = Record[9];
+ Elements = getMDOrNull(Record[11]);
+ VTableHolder = getDITypeRefOrNull(Record[13]);
+ TemplateParams = getMDOrNull(Record[14]);
+ }
DICompositeType *CT = nullptr;
if (Identifier)
CT = DICompositeType::buildODRType(
@@ -1281,17 +1308,19 @@ MetadataLoader &MetadataLoader::operator=(MetadataLoader &&RHS) {
return *this;
}
MetadataLoader::MetadataLoader(MetadataLoader &&RHS)
- : Pimpl(std::move(RHS.Pimpl)) {}
+ : Pimpl(std::move(RHS.Pimpl)), IsImporting(RHS.IsImporting) {}
MetadataLoader::~MetadataLoader() = default;
MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
BitcodeReaderValueList &ValueList,
+ bool IsImporting,
std::function<Type *(unsigned)> getTypeByID)
: Pimpl(llvm::make_unique<MetadataLoaderImpl>(Stream, TheModule, ValueList,
- getTypeByID)) {}
+ getTypeByID)),
+ IsImporting(IsImporting) {}
Error MetadataLoader::parseMetadata(bool ModuleLevel) {
- return Pimpl->parseMetadata(ModuleLevel);
+ return Pimpl->parseMetadata(ModuleLevel, IsImporting);
}
bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
OpenPOWER on IntegriCloud