From 07d98b4afbdcbb4eed048400d9116de1ec83e866 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 26 Apr 2007 02:46:40 +0000 Subject: [PATCH] add bitcode alias support git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36461 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 74 ++++++++++++++++++++------ lib/Bitcode/Reader/BitcodeReader.h | 2 + lib/Bitcode/Writer/BitcodeWriter.cpp | 12 +++++ lib/Bitcode/Writer/ValueEnumerator.cpp | 10 ++++ 4 files changed, 81 insertions(+), 17 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 6f824c63b88..6f18f7e6cf6 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -398,6 +398,47 @@ static uint64_t DecodeSignRotatedValue(uint64_t V) { return 1ULL << 63; } +/// ResolveGlobalAndAliasInits - Resolve all of the initializers for global +/// values and aliases that we can. +bool BitcodeReader::ResolveGlobalAndAliasInits() { + std::vector > GlobalInitWorklist; + std::vector > AliasInitWorklist; + + GlobalInitWorklist.swap(GlobalInits); + AliasInitWorklist.swap(AliasInits); + + while (!GlobalInitWorklist.empty()) { + unsigned ValID = GlobalInits.back().second; + if (ValID >= ValueList.size()) { + // Not ready to resolve this yet, it requires something later in the file. + GlobalInitWorklist.push_back(GlobalInits.back()); + } else { + if (Constant *C = dyn_cast(ValueList[ValID])) + GlobalInitWorklist.back().first->setInitializer(C); + else + return Error("Global variable initializer is not a constant!"); + } + GlobalInitWorklist.pop_back(); + } + + while (!AliasInitWorklist.empty()) { + unsigned ValID = AliasInitWorklist.back().second; + if (ValID >= ValueList.size()) { + AliasInits.push_back(AliasInitWorklist.back()); + } else { + if (Constant *C = dyn_cast(ValueList[ValID])) + AliasInitWorklist.back().first->setAliasee( + // FIXME: + cast(C)); + else + return Error("Alias initializer is not a constant!"); + } + AliasInitWorklist.pop_back(); + } + return false; +} + + bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { if (Stream.EnterSubBlock()) return Error("Malformed block record"); @@ -410,20 +451,6 @@ bool BitcodeReader::ParseConstants(BitstreamReader &Stream) { while (1) { unsigned Code = Stream.ReadCode(); if (Code == bitc::END_BLOCK) { - // If there are global var inits to process, do so now. - if (!GlobalInits.empty()) { - while (!GlobalInits.empty()) { - unsigned ValID = GlobalInits.back().second; - if (ValID >= ValueList.size()) - return Error("Invalid value ID for global var init!"); - if (Constant *C = dyn_cast(ValueList[ValID])) - GlobalInits.back().first->setInitializer(C); - else - return Error("Global variable initializer is not a constant!"); - GlobalInits.pop_back(); - } - } - if (NextCstNo != ValueList.size()) return Error("Invalid constant reference!"); @@ -646,7 +673,8 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream, while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code == bitc::END_BLOCK) { - if (!GlobalInits.empty()) + ResolveGlobalAndAliasInits(); + if (!GlobalInits.empty() || !AliasInits.empty()) return Error("Malformed global initializer set"); if (Stream.ReadBlockEnd()) return Error("Error at end of module block"); @@ -672,7 +700,7 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream, return true; break; case bitc::CONSTANTS_BLOCK_ID: - if (ParseConstants(Stream)) + if (ParseConstants(Stream) || ResolveGlobalAndAliasInits()) return true; break; } @@ -795,9 +823,21 @@ bool BitcodeReader::ParseModule(BitstreamReader &Stream, Func->setVisibility(GetDecodedVisibility(Record[6])); ValueList.push_back(Func); - // TODO: remember initializer/global pair for later substitution. break; } + // ALIAS: [alias type, aliasee val#, linkage] + case bitc::MODULE_CODE_ALIAS: + if (Record.size() < 3) + return Error("Invalid MODULE_ALIAS record"); + const Type *Ty = getTypeByID(Record[0]); + if (!isa(Ty)) + return Error("Function not a pointer type!"); + + GlobalAlias *NewGA = new GlobalAlias(Ty, GetDecodedLinkage(Record[2]), + "", 0, TheModule); + ValueList.push_back(NewGA); + AliasInits.push_back(std::make_pair(NewGA, Record[1])); + break; } Record.clear(); } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 3935ebbfe09..79bf8ea62f4 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -57,6 +57,7 @@ class BitcodeReader : public ModuleProvider { std::vector TypeList; BitcodeReaderValueList ValueList; std::vector > GlobalInits; + std::vector > AliasInits; public: BitcodeReader() : ErrorString(0) {} virtual ~BitcodeReader() {} @@ -93,6 +94,7 @@ private: bool ParseTypeSymbolTable(BitstreamReader &Stream); bool ParseValueSymbolTable(BitstreamReader &Stream); bool ParseConstants(BitstreamReader &Stream); + bool ResolveGlobalAndAliasInits(); }; } // End llvm namespace diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index bfb1815f129..b4f3f69b554 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -309,6 +309,18 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); Vals.clear(); } + + + // Emit the alias information. + for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end(); + AI != E; ++AI) { + Vals.push_back(VE.getTypeID(AI->getType())); + Vals.push_back(VE.getValueID(AI->getAliasee())); + Vals.push_back(getEncodedLinkage(AI)); + unsigned AbbrevToUse = 0; + Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); + Vals.clear(); + } } diff --git a/lib/Bitcode/Writer/ValueEnumerator.cpp b/lib/Bitcode/Writer/ValueEnumerator.cpp index f4b7a760157..1172c4fa219 100644 --- a/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -28,12 +28,22 @@ ValueEnumerator::ValueEnumerator(const Module *M) { for (Module::const_iterator I = M->begin(), E = M->end(); I != E; ++I) EnumerateValue(I); + // Enumerate the aliases. + for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); + I != E; ++I) + EnumerateValue(I); + // Enumerate the global variable initializers. for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); I != E; ++I) if (I->hasInitializer()) EnumerateValue(I->getInitializer()); + // Enumerate the aliasees. + for (Module::const_alias_iterator I = M->alias_begin(), E = M->alias_end(); + I != E; ++I) + EnumerateValue(I->getAliasee()); + // FIXME: Implement the 'string constant' optimization. // Enumerate types used by the type symbol table.