diff options
Diffstat (limited to 'contrib/llvm/lib/Bitcode')
-rw-r--r-- | contrib/llvm/lib/Bitcode/Reader/BitReader.cpp | 106 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 4725 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp | 361 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp | 49 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 2493 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp | 51 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 820 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h | 208 | ||||
-rw-r--r-- | contrib/llvm/lib/Bitcode/module.modulemap | 1 |
9 files changed, 8814 insertions, 0 deletions
diff --git a/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp new file mode 100644 index 0000000..289c76e --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Reader/BitReader.cpp @@ -0,0 +1,106 @@ +//===-- BitReader.cpp -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/BitReader.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include <cstring> +#include <string> + +using namespace llvm; + +/* Builds a module from the bitcode in the specified memory buffer, returning a + reference to the module via the OutModule parameter. Returns 0 on success. + Optionally returns a human-readable error message via OutMessage. */ +LLVMBool LLVMParseBitcode(LLVMMemoryBufferRef MemBuf, + LLVMModuleRef *OutModule, char **OutMessage) { + return LLVMParseBitcodeInContext(wrap(&getGlobalContext()), MemBuf, OutModule, + OutMessage); +} + +LLVMBool LLVMParseBitcodeInContext(LLVMContextRef ContextRef, + LLVMMemoryBufferRef MemBuf, + LLVMModuleRef *OutModule, + char **OutMessage) { + MemoryBufferRef Buf = unwrap(MemBuf)->getMemBufferRef(); + LLVMContext &Ctx = *unwrap(ContextRef); + + std::string Message; + raw_string_ostream Stream(Message); + DiagnosticPrinterRawOStream DP(Stream); + + ErrorOr<std::unique_ptr<Module>> ModuleOrErr = parseBitcodeFile( + Buf, Ctx, [&](const DiagnosticInfo &DI) { DI.print(DP); }); + if (ModuleOrErr.getError()) { + if (OutMessage) { + Stream.flush(); + *OutMessage = strdup(Message.c_str()); + } + *OutModule = wrap((Module*)nullptr); + return 1; + } + + *OutModule = wrap(ModuleOrErr.get().release()); + return 0; +} + +/* Reads a module from the specified path, returning via the OutModule parameter + a module provider which performs lazy deserialization. Returns 0 on success. + Optionally returns a human-readable error message via OutMessage. */ +LLVMBool LLVMGetBitcodeModuleInContext(LLVMContextRef ContextRef, + LLVMMemoryBufferRef MemBuf, + LLVMModuleRef *OutM, + char **OutMessage) { + std::string Message; + std::unique_ptr<MemoryBuffer> Owner(unwrap(MemBuf)); + + ErrorOr<std::unique_ptr<Module>> ModuleOrErr = + getLazyBitcodeModule(std::move(Owner), *unwrap(ContextRef)); + Owner.release(); + + if (std::error_code EC = ModuleOrErr.getError()) { + *OutM = wrap((Module *)nullptr); + if (OutMessage) + *OutMessage = strdup(EC.message().c_str()); + return 1; + } + + *OutM = wrap(ModuleOrErr.get().release()); + + return 0; + +} + +LLVMBool LLVMGetBitcodeModule(LLVMMemoryBufferRef MemBuf, LLVMModuleRef *OutM, + char **OutMessage) { + return LLVMGetBitcodeModuleInContext(LLVMGetGlobalContext(), MemBuf, OutM, + OutMessage); +} + +/* Deprecated: Use LLVMGetBitcodeModuleInContext instead. */ +LLVMBool LLVMGetBitcodeModuleProviderInContext(LLVMContextRef ContextRef, + LLVMMemoryBufferRef MemBuf, + LLVMModuleProviderRef *OutMP, + char **OutMessage) { + return LLVMGetBitcodeModuleInContext(ContextRef, MemBuf, + reinterpret_cast<LLVMModuleRef*>(OutMP), + OutMessage); +} + +/* Deprecated: Use LLVMGetBitcodeModule instead. */ +LLVMBool LLVMGetBitcodeModuleProvider(LLVMMemoryBufferRef MemBuf, + LLVMModuleProviderRef *OutMP, + char **OutMessage) { + return LLVMGetBitcodeModuleProviderInContext(LLVMGetGlobalContext(), MemBuf, + OutMP, OutMessage); +} diff --git a/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp new file mode 100644 index 0000000..0cadd6c --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -0,0 +1,4725 @@ +//===- BitcodeReader.cpp - Internal BitcodeReader implementation ----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/IR/AutoUpgrade.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/DiagnosticPrinter.h" +#include "llvm/IR/GVMaterializer.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/OperandTraits.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/ValueHandle.h" +#include "llvm/Support/DataStream.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include <deque> +using namespace llvm; + +namespace { +enum { + SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex +}; + +class BitcodeReaderValueList { + std::vector<WeakVH> ValuePtrs; + + /// As we resolve forward-referenced constants, we add information about them + /// to this vector. This allows us to resolve them in bulk instead of + /// resolving each reference at a time. See the code in + /// ResolveConstantForwardRefs for more information about this. + /// + /// The key of this vector is the placeholder constant, the value is the slot + /// number that holds the resolved value. + typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy; + ResolveConstantsTy ResolveConstants; + LLVMContext &Context; +public: + BitcodeReaderValueList(LLVMContext &C) : Context(C) {} + ~BitcodeReaderValueList() { + assert(ResolveConstants.empty() && "Constants not resolved?"); + } + + // vector compatibility methods + unsigned size() const { return ValuePtrs.size(); } + void resize(unsigned N) { ValuePtrs.resize(N); } + void push_back(Value *V) { ValuePtrs.emplace_back(V); } + + void clear() { + assert(ResolveConstants.empty() && "Constants not resolved?"); + ValuePtrs.clear(); + } + + Value *operator[](unsigned i) const { + assert(i < ValuePtrs.size()); + return ValuePtrs[i]; + } + + Value *back() const { return ValuePtrs.back(); } + void pop_back() { ValuePtrs.pop_back(); } + bool empty() const { return ValuePtrs.empty(); } + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + ValuePtrs.resize(N); + } + + Constant *getConstantFwdRef(unsigned Idx, Type *Ty); + Value *getValueFwdRef(unsigned Idx, Type *Ty); + + void assignValue(Value *V, unsigned Idx); + + /// Once all constants are read, this method bulk resolves any forward + /// references. + void resolveConstantForwardRefs(); +}; + +class BitcodeReaderMDValueList { + unsigned NumFwdRefs; + bool AnyFwdRefs; + unsigned MinFwdRef; + unsigned MaxFwdRef; + std::vector<TrackingMDRef> MDValuePtrs; + + LLVMContext &Context; +public: + BitcodeReaderMDValueList(LLVMContext &C) + : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {} + + // vector compatibility methods + unsigned size() const { return MDValuePtrs.size(); } + void resize(unsigned N) { MDValuePtrs.resize(N); } + void push_back(Metadata *MD) { MDValuePtrs.emplace_back(MD); } + void clear() { MDValuePtrs.clear(); } + Metadata *back() const { return MDValuePtrs.back(); } + void pop_back() { MDValuePtrs.pop_back(); } + bool empty() const { return MDValuePtrs.empty(); } + + Metadata *operator[](unsigned i) const { + assert(i < MDValuePtrs.size()); + return MDValuePtrs[i]; + } + + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + MDValuePtrs.resize(N); + } + + Metadata *getValueFwdRef(unsigned Idx); + void assignValue(Metadata *MD, unsigned Idx); + void tryToResolveCycles(); +}; + +class BitcodeReader : public GVMaterializer { + LLVMContext &Context; + DiagnosticHandlerFunction DiagnosticHandler; + Module *TheModule = nullptr; + std::unique_ptr<MemoryBuffer> Buffer; + std::unique_ptr<BitstreamReader> StreamFile; + BitstreamCursor Stream; + bool IsStreamed; + uint64_t NextUnreadBit = 0; + bool SeenValueSymbolTable = false; + + std::vector<Type*> TypeList; + BitcodeReaderValueList ValueList; + BitcodeReaderMDValueList MDValueList; + std::vector<Comdat *> ComdatList; + SmallVector<Instruction *, 64> InstructionList; + + std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits; + std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits; + std::vector<std::pair<Function*, unsigned> > FunctionPrefixes; + std::vector<std::pair<Function*, unsigned> > FunctionPrologues; + std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns; + + SmallVector<Instruction*, 64> InstsWithTBAATag; + + /// The set of attributes by index. Index zero in the file is for null, and + /// is thus not represented here. As such all indices are off by one. + std::vector<AttributeSet> MAttributes; + + /// \brief The set of attribute groups. + std::map<unsigned, AttributeSet> MAttributeGroups; + + /// While parsing a function body, this is a list of the basic blocks for the + /// function. + std::vector<BasicBlock*> FunctionBBs; + + // When reading the module header, this list is populated with functions that + // have bodies later in the file. + std::vector<Function*> FunctionsWithBodies; + + // When intrinsic functions are encountered which require upgrading they are + // stored here with their replacement function. + typedef std::vector<std::pair<Function*, Function*> > UpgradedIntrinsicMap; + UpgradedIntrinsicMap UpgradedIntrinsics; + + // Map the bitcode's custom MDKind ID to the Module's MDKind ID. + DenseMap<unsigned, unsigned> MDKindMap; + + // Several operations happen after the module header has been read, but + // before function bodies are processed. This keeps track of whether + // we've done this yet. + bool SeenFirstFunctionBody = false; + + /// When function bodies are initially scanned, this map contains info about + /// where to find deferred function body in the stream. + DenseMap<Function*, uint64_t> DeferredFunctionInfo; + + /// When Metadata block is initially scanned when parsing the module, we may + /// choose to defer parsing of the metadata. This vector contains info about + /// which Metadata blocks are deferred. + std::vector<uint64_t> DeferredMetadataInfo; + + /// These are basic blocks forward-referenced by block addresses. They are + /// inserted lazily into functions when they're loaded. The basic block ID is + /// its index into the vector. + DenseMap<Function *, std::vector<BasicBlock *>> BasicBlockFwdRefs; + std::deque<Function *> BasicBlockFwdRefQueue; + + /// Indicates that we are using a new encoding for instruction operands where + /// most operands in the current FUNCTION_BLOCK are encoded relative to the + /// instruction number, for a more compact encoding. Some instruction + /// operands are not relative to the instruction ID: basic block numbers, and + /// types. Once the old style function blocks have been phased out, we would + /// not need this flag. + bool UseRelativeIDs = false; + + /// True if all functions will be materialized, negating the need to process + /// (e.g.) blockaddress forward references. + bool WillMaterializeAllForwardRefs = false; + + /// Functions that have block addresses taken. This is usually empty. + SmallPtrSet<const Function *, 4> BlockAddressesTaken; + + /// True if any Metadata block has been materialized. + bool IsMetadataMaterialized = false; + + bool StripDebugInfo = false; + +public: + std::error_code error(BitcodeError E, const Twine &Message); + std::error_code error(BitcodeError E); + std::error_code error(const Twine &Message); + + BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler); + BitcodeReader(LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler); + ~BitcodeReader() override { freeState(); } + + std::error_code materializeForwardReferencedFunctions(); + + void freeState(); + + void releaseBuffer(); + + bool isDematerializable(const GlobalValue *GV) const override; + std::error_code materialize(GlobalValue *GV) override; + std::error_code materializeModule(Module *M) override; + std::vector<StructType *> getIdentifiedStructTypes() const override; + void dematerialize(GlobalValue *GV) override; + + /// \brief Main interface to parsing a bitcode buffer. + /// \returns true if an error occurred. + std::error_code parseBitcodeInto(std::unique_ptr<DataStreamer> Streamer, + Module *M, + bool ShouldLazyLoadMetadata = false); + + /// \brief Cheap mechanism to just extract module triple + /// \returns true if an error occurred. + ErrorOr<std::string> parseTriple(); + + static uint64_t decodeSignRotatedValue(uint64_t V); + + /// Materialize any deferred Metadata block. + std::error_code materializeMetadata() override; + + void setStripDebugInfo() override; + +private: + std::vector<StructType *> IdentifiedStructTypes; + StructType *createIdentifiedStructType(LLVMContext &Context, StringRef Name); + StructType *createIdentifiedStructType(LLVMContext &Context); + + Type *getTypeByID(unsigned ID); + Value *getFnValueByID(unsigned ID, Type *Ty) { + if (Ty && Ty->isMetadataTy()) + return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID)); + return ValueList.getValueFwdRef(ID, Ty); + } + Metadata *getFnMetadataByID(unsigned ID) { + return MDValueList.getValueFwdRef(ID); + } + BasicBlock *getBasicBlock(unsigned ID) const { + if (ID >= FunctionBBs.size()) return nullptr; // Invalid ID + return FunctionBBs[ID]; + } + AttributeSet getAttributes(unsigned i) const { + if (i-1 < MAttributes.size()) + return MAttributes[i-1]; + return AttributeSet(); + } + + /// Read a value/type pair out of the specified record from slot 'Slot'. + /// Increment Slot past the number of slots used in the record. Return true on + /// failure. + bool getValueTypePair(SmallVectorImpl<uint64_t> &Record, unsigned &Slot, + unsigned InstNum, Value *&ResVal) { + if (Slot == Record.size()) return true; + unsigned ValNo = (unsigned)Record[Slot++]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + if (ValNo < InstNum) { + // If this is not a forward reference, just return the value we already + // have. + ResVal = getFnValueByID(ValNo, nullptr); + return ResVal == nullptr; + } + if (Slot == Record.size()) + return true; + + unsigned TypeNo = (unsigned)Record[Slot++]; + ResVal = getFnValueByID(ValNo, getTypeByID(TypeNo)); + return ResVal == nullptr; + } + + /// Read a value out of the specified record from slot 'Slot'. Increment Slot + /// past the number of slots used by the value in the record. Return true if + /// there is an error. + bool popValue(SmallVectorImpl<uint64_t> &Record, unsigned &Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + if (getValue(Record, Slot, InstNum, Ty, ResVal)) + return true; + // All values currently take a single record slot. + ++Slot; + return false; + } + + /// Like popValue, but does not increment the Slot number. + bool getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot, + unsigned InstNum, Type *Ty, Value *&ResVal) { + ResVal = getValue(Record, Slot, InstNum, Ty); + return ResVal == nullptr; + } + + /// Version of getValue that returns ResVal directly, or 0 if there is an + /// error. + Value *getValue(SmallVectorImpl<uint64_t> &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + unsigned ValNo = (unsigned)Record[Slot]; + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + /// Like getValue, but decodes signed VBRs. + Value *getValueSigned(SmallVectorImpl<uint64_t> &Record, unsigned Slot, + unsigned InstNum, Type *Ty) { + if (Slot == Record.size()) return nullptr; + unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]); + // Adjust the ValNo, if it was encoded relative to the InstNum. + if (UseRelativeIDs) + ValNo = InstNum - ValNo; + return getFnValueByID(ValNo, Ty); + } + + /// Converts alignment exponent (i.e. power of two (or zero)) to the + /// corresponding alignment to use. If alignment is too large, returns + /// a corresponding error code. + std::error_code parseAlignmentValue(uint64_t Exponent, unsigned &Alignment); + std::error_code parseAttrKind(uint64_t Code, Attribute::AttrKind *Kind); + std::error_code parseModule(bool Resume, bool ShouldLazyLoadMetadata = false); + std::error_code parseAttributeBlock(); + std::error_code parseAttributeGroupBlock(); + std::error_code parseTypeTable(); + std::error_code parseTypeTableBody(); + + std::error_code parseValueSymbolTable(); + std::error_code parseConstants(); + std::error_code rememberAndSkipFunctionBody(); + /// Save the positions of the Metadata blocks and skip parsing the blocks. + std::error_code rememberAndSkipMetadata(); + std::error_code parseFunctionBody(Function *F); + std::error_code globalCleanup(); + std::error_code resolveGlobalAndAliasInits(); + std::error_code parseMetadata(); + std::error_code parseMetadataAttachment(Function &F); + ErrorOr<std::string> parseModuleTriple(); + std::error_code parseUseLists(); + std::error_code initStream(std::unique_ptr<DataStreamer> Streamer); + std::error_code initStreamFromBuffer(); + std::error_code initLazyStream(std::unique_ptr<DataStreamer> Streamer); + std::error_code findFunctionInStream( + Function *F, + DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator); +}; +} // namespace + +BitcodeDiagnosticInfo::BitcodeDiagnosticInfo(std::error_code EC, + DiagnosticSeverity Severity, + const Twine &Msg) + : DiagnosticInfo(DK_Bitcode, Severity), Msg(Msg), EC(EC) {} + +void BitcodeDiagnosticInfo::print(DiagnosticPrinter &DP) const { DP << Msg; } + +static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler, + std::error_code EC, const Twine &Message) { + BitcodeDiagnosticInfo DI(EC, DS_Error, Message); + DiagnosticHandler(DI); + return EC; +} + +static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler, + std::error_code EC) { + return error(DiagnosticHandler, EC, EC.message()); +} + +static std::error_code error(DiagnosticHandlerFunction DiagnosticHandler, + const Twine &Message) { + return error(DiagnosticHandler, + make_error_code(BitcodeError::CorruptedBitcode), Message); +} + +std::error_code BitcodeReader::error(BitcodeError E, const Twine &Message) { + return ::error(DiagnosticHandler, make_error_code(E), Message); +} + +std::error_code BitcodeReader::error(const Twine &Message) { + return ::error(DiagnosticHandler, + make_error_code(BitcodeError::CorruptedBitcode), Message); +} + +std::error_code BitcodeReader::error(BitcodeError E) { + return ::error(DiagnosticHandler, make_error_code(E)); +} + +static DiagnosticHandlerFunction getDiagHandler(DiagnosticHandlerFunction F, + LLVMContext &C) { + if (F) + return F; + return [&C](const DiagnosticInfo &DI) { C.diagnose(DI); }; +} + +BitcodeReader::BitcodeReader(MemoryBuffer *Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler) + : Context(Context), + DiagnosticHandler(getDiagHandler(DiagnosticHandler, Context)), + Buffer(Buffer), IsStreamed(false), ValueList(Context), + MDValueList(Context) {} + +BitcodeReader::BitcodeReader(LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler) + : Context(Context), + DiagnosticHandler(getDiagHandler(DiagnosticHandler, Context)), + Buffer(nullptr), IsStreamed(true), ValueList(Context), + MDValueList(Context) {} + +std::error_code BitcodeReader::materializeForwardReferencedFunctions() { + if (WillMaterializeAllForwardRefs) + return std::error_code(); + + // Prevent recursion. + WillMaterializeAllForwardRefs = true; + + while (!BasicBlockFwdRefQueue.empty()) { + Function *F = BasicBlockFwdRefQueue.front(); + BasicBlockFwdRefQueue.pop_front(); + assert(F && "Expected valid function"); + if (!BasicBlockFwdRefs.count(F)) + // Already materialized. + continue; + + // Check for a function that isn't materializable to prevent an infinite + // loop. When parsing a blockaddress stored in a global variable, there + // isn't a trivial way to check if a function will have a body without a + // linear search through FunctionsWithBodies, so just check it here. + if (!F->isMaterializable()) + return error("Never resolved function from blockaddress"); + + // Try to materialize F. + if (std::error_code EC = materialize(F)) + return EC; + } + assert(BasicBlockFwdRefs.empty() && "Function missing from queue"); + + // Reset state. + WillMaterializeAllForwardRefs = false; + return std::error_code(); +} + +void BitcodeReader::freeState() { + Buffer = nullptr; + std::vector<Type*>().swap(TypeList); + ValueList.clear(); + MDValueList.clear(); + std::vector<Comdat *>().swap(ComdatList); + + std::vector<AttributeSet>().swap(MAttributes); + std::vector<BasicBlock*>().swap(FunctionBBs); + std::vector<Function*>().swap(FunctionsWithBodies); + DeferredFunctionInfo.clear(); + DeferredMetadataInfo.clear(); + MDKindMap.clear(); + + assert(BasicBlockFwdRefs.empty() && "Unresolved blockaddress fwd references"); + BasicBlockFwdRefQueue.clear(); +} + +//===----------------------------------------------------------------------===// +// Helper functions to implement forward reference resolution, etc. +//===----------------------------------------------------------------------===// + +/// Convert a string from a record into an std::string, return true on failure. +template <typename StrTy> +static bool convertToString(ArrayRef<uint64_t> Record, unsigned Idx, + StrTy &Result) { + if (Idx > Record.size()) + return true; + + for (unsigned i = Idx, e = Record.size(); i != e; ++i) + Result += (char)Record[i]; + return false; +} + +static bool hasImplicitComdat(size_t Val) { + switch (Val) { + default: + return false; + case 1: // Old WeakAnyLinkage + case 4: // Old LinkOnceAnyLinkage + case 10: // Old WeakODRLinkage + case 11: // Old LinkOnceODRLinkage + return true; + } +} + +static GlobalValue::LinkageTypes getDecodedLinkage(unsigned Val) { + switch (Val) { + default: // Map unknown/new linkages to external + case 0: + return GlobalValue::ExternalLinkage; + case 2: + return GlobalValue::AppendingLinkage; + case 3: + return GlobalValue::InternalLinkage; + case 5: + return GlobalValue::ExternalLinkage; // Obsolete DLLImportLinkage + case 6: + return GlobalValue::ExternalLinkage; // Obsolete DLLExportLinkage + case 7: + return GlobalValue::ExternalWeakLinkage; + case 8: + return GlobalValue::CommonLinkage; + case 9: + return GlobalValue::PrivateLinkage; + case 12: + return GlobalValue::AvailableExternallyLinkage; + case 13: + return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateLinkage + case 14: + return GlobalValue::PrivateLinkage; // Obsolete LinkerPrivateWeakLinkage + case 15: + return GlobalValue::ExternalLinkage; // Obsolete LinkOnceODRAutoHideLinkage + case 1: // Old value with implicit comdat. + case 16: + return GlobalValue::WeakAnyLinkage; + case 10: // Old value with implicit comdat. + case 17: + return GlobalValue::WeakODRLinkage; + case 4: // Old value with implicit comdat. + case 18: + return GlobalValue::LinkOnceAnyLinkage; + case 11: // Old value with implicit comdat. + case 19: + return GlobalValue::LinkOnceODRLinkage; + } +} + +static GlobalValue::VisibilityTypes getDecodedVisibility(unsigned Val) { + switch (Val) { + default: // Map unknown visibilities to default. + case 0: return GlobalValue::DefaultVisibility; + case 1: return GlobalValue::HiddenVisibility; + case 2: return GlobalValue::ProtectedVisibility; + } +} + +static GlobalValue::DLLStorageClassTypes +getDecodedDLLStorageClass(unsigned Val) { + switch (Val) { + default: // Map unknown values to default. + case 0: return GlobalValue::DefaultStorageClass; + case 1: return GlobalValue::DLLImportStorageClass; + case 2: return GlobalValue::DLLExportStorageClass; + } +} + +static GlobalVariable::ThreadLocalMode getDecodedThreadLocalMode(unsigned Val) { + switch (Val) { + case 0: return GlobalVariable::NotThreadLocal; + default: // Map unknown non-zero value to general dynamic. + case 1: return GlobalVariable::GeneralDynamicTLSModel; + case 2: return GlobalVariable::LocalDynamicTLSModel; + case 3: return GlobalVariable::InitialExecTLSModel; + case 4: return GlobalVariable::LocalExecTLSModel; + } +} + +static int getDecodedCastOpcode(unsigned Val) { + switch (Val) { + default: return -1; + case bitc::CAST_TRUNC : return Instruction::Trunc; + case bitc::CAST_ZEXT : return Instruction::ZExt; + case bitc::CAST_SEXT : return Instruction::SExt; + case bitc::CAST_FPTOUI : return Instruction::FPToUI; + case bitc::CAST_FPTOSI : return Instruction::FPToSI; + case bitc::CAST_UITOFP : return Instruction::UIToFP; + case bitc::CAST_SITOFP : return Instruction::SIToFP; + case bitc::CAST_FPTRUNC : return Instruction::FPTrunc; + case bitc::CAST_FPEXT : return Instruction::FPExt; + case bitc::CAST_PTRTOINT: return Instruction::PtrToInt; + case bitc::CAST_INTTOPTR: return Instruction::IntToPtr; + case bitc::CAST_BITCAST : return Instruction::BitCast; + case bitc::CAST_ADDRSPACECAST: return Instruction::AddrSpaceCast; + } +} + +static int getDecodedBinaryOpcode(unsigned Val, Type *Ty) { + bool IsFP = Ty->isFPOrFPVectorTy(); + // BinOps are only valid for int/fp or vector of int/fp types + if (!IsFP && !Ty->isIntOrIntVectorTy()) + return -1; + + switch (Val) { + default: + return -1; + case bitc::BINOP_ADD: + return IsFP ? Instruction::FAdd : Instruction::Add; + case bitc::BINOP_SUB: + return IsFP ? Instruction::FSub : Instruction::Sub; + case bitc::BINOP_MUL: + return IsFP ? Instruction::FMul : Instruction::Mul; + case bitc::BINOP_UDIV: + return IsFP ? -1 : Instruction::UDiv; + case bitc::BINOP_SDIV: + return IsFP ? Instruction::FDiv : Instruction::SDiv; + case bitc::BINOP_UREM: + return IsFP ? -1 : Instruction::URem; + case bitc::BINOP_SREM: + return IsFP ? Instruction::FRem : Instruction::SRem; + case bitc::BINOP_SHL: + return IsFP ? -1 : Instruction::Shl; + case bitc::BINOP_LSHR: + return IsFP ? -1 : Instruction::LShr; + case bitc::BINOP_ASHR: + return IsFP ? -1 : Instruction::AShr; + case bitc::BINOP_AND: + return IsFP ? -1 : Instruction::And; + case bitc::BINOP_OR: + return IsFP ? -1 : Instruction::Or; + case bitc::BINOP_XOR: + return IsFP ? -1 : Instruction::Xor; + } +} + +static AtomicRMWInst::BinOp getDecodedRMWOperation(unsigned Val) { + switch (Val) { + default: return AtomicRMWInst::BAD_BINOP; + case bitc::RMW_XCHG: return AtomicRMWInst::Xchg; + case bitc::RMW_ADD: return AtomicRMWInst::Add; + case bitc::RMW_SUB: return AtomicRMWInst::Sub; + case bitc::RMW_AND: return AtomicRMWInst::And; + case bitc::RMW_NAND: return AtomicRMWInst::Nand; + case bitc::RMW_OR: return AtomicRMWInst::Or; + case bitc::RMW_XOR: return AtomicRMWInst::Xor; + case bitc::RMW_MAX: return AtomicRMWInst::Max; + case bitc::RMW_MIN: return AtomicRMWInst::Min; + case bitc::RMW_UMAX: return AtomicRMWInst::UMax; + case bitc::RMW_UMIN: return AtomicRMWInst::UMin; + } +} + +static AtomicOrdering getDecodedOrdering(unsigned Val) { + switch (Val) { + case bitc::ORDERING_NOTATOMIC: return NotAtomic; + case bitc::ORDERING_UNORDERED: return Unordered; + case bitc::ORDERING_MONOTONIC: return Monotonic; + case bitc::ORDERING_ACQUIRE: return Acquire; + case bitc::ORDERING_RELEASE: return Release; + case bitc::ORDERING_ACQREL: return AcquireRelease; + default: // Map unknown orderings to sequentially-consistent. + case bitc::ORDERING_SEQCST: return SequentiallyConsistent; + } +} + +static SynchronizationScope getDecodedSynchScope(unsigned Val) { + switch (Val) { + case bitc::SYNCHSCOPE_SINGLETHREAD: return SingleThread; + default: // Map unknown scopes to cross-thread. + case bitc::SYNCHSCOPE_CROSSTHREAD: return CrossThread; + } +} + +static Comdat::SelectionKind getDecodedComdatSelectionKind(unsigned Val) { + switch (Val) { + default: // Map unknown selection kinds to any. + case bitc::COMDAT_SELECTION_KIND_ANY: + return Comdat::Any; + case bitc::COMDAT_SELECTION_KIND_EXACT_MATCH: + return Comdat::ExactMatch; + case bitc::COMDAT_SELECTION_KIND_LARGEST: + return Comdat::Largest; + case bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES: + return Comdat::NoDuplicates; + case bitc::COMDAT_SELECTION_KIND_SAME_SIZE: + return Comdat::SameSize; + } +} + +static void upgradeDLLImportExportLinkage(llvm::GlobalValue *GV, unsigned Val) { + switch (Val) { + case 5: GV->setDLLStorageClass(GlobalValue::DLLImportStorageClass); break; + case 6: GV->setDLLStorageClass(GlobalValue::DLLExportStorageClass); break; + } +} + +namespace llvm { +namespace { +/// \brief A class for maintaining the slot number definition +/// as a placeholder for the actual definition for forward constants defs. +class ConstantPlaceHolder : public ConstantExpr { + void operator=(const ConstantPlaceHolder &) = delete; + +public: + // allocate space for exactly one operand + void *operator new(size_t s) { return User::operator new(s, 1); } + explicit ConstantPlaceHolder(Type *Ty, LLVMContext &Context) + : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) { + Op<0>() = UndefValue::get(Type::getInt32Ty(Context)); + } + + /// \brief Methods to support type inquiry through isa, cast, and dyn_cast. + static bool classof(const Value *V) { + return isa<ConstantExpr>(V) && + cast<ConstantExpr>(V)->getOpcode() == Instruction::UserOp1; + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +}; +} // namespace + +// FIXME: can we inherit this from ConstantExpr? +template <> +struct OperandTraits<ConstantPlaceHolder> : + public FixedNumOperandTraits<ConstantPlaceHolder, 1> { +}; +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value) +} // namespace llvm + +void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) { + if (Idx == size()) { + push_back(V); + return; + } + + if (Idx >= size()) + resize(Idx+1); + + WeakVH &OldV = ValuePtrs[Idx]; + if (!OldV) { + OldV = V; + return; + } + + // Handle constants and non-constants (e.g. instrs) differently for + // efficiency. + if (Constant *PHC = dyn_cast<Constant>(&*OldV)) { + ResolveConstants.push_back(std::make_pair(PHC, Idx)); + OldV = V; + } else { + // If there was a forward reference to this value, replace it. + Value *PrevVal = OldV; + OldV->replaceAllUsesWith(V); + delete PrevVal; + } +} + + +Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, + Type *Ty) { + if (Idx >= size()) + resize(Idx + 1); + + if (Value *V = ValuePtrs[Idx]) { + if (Ty != V->getType()) + report_fatal_error("Type mismatch in constant table!"); + return cast<Constant>(V); + } + + // Create and return a placeholder, which will later be RAUW'd. + Constant *C = new ConstantPlaceHolder(Ty, Context); + ValuePtrs[Idx] = C; + return C; +} + +Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) { + // Bail out for a clearly invalid value. This would make us call resize(0) + if (Idx == UINT_MAX) + return nullptr; + + if (Idx >= size()) + resize(Idx + 1); + + if (Value *V = ValuePtrs[Idx]) { + // If the types don't match, it's invalid. + if (Ty && Ty != V->getType()) + return nullptr; + return V; + } + + // No type specified, must be invalid reference. + if (!Ty) return nullptr; + + // Create and return a placeholder, which will later be RAUW'd. + Value *V = new Argument(Ty); + ValuePtrs[Idx] = V; + return V; +} + +/// Once all constants are read, this method bulk resolves any forward +/// references. The idea behind this is that we sometimes get constants (such +/// as large arrays) which reference *many* forward ref constants. Replacing +/// each of these causes a lot of thrashing when building/reuniquing the +/// constant. Instead of doing this, we look at all the uses and rewrite all +/// the place holders at once for any constant that uses a placeholder. +void BitcodeReaderValueList::resolveConstantForwardRefs() { + // Sort the values by-pointer so that they are efficient to look up with a + // binary search. + std::sort(ResolveConstants.begin(), ResolveConstants.end()); + + SmallVector<Constant*, 64> NewOps; + + while (!ResolveConstants.empty()) { + Value *RealVal = operator[](ResolveConstants.back().second); + Constant *Placeholder = ResolveConstants.back().first; + ResolveConstants.pop_back(); + + // Loop over all users of the placeholder, updating them to reference the + // new value. If they reference more than one placeholder, update them all + // at once. + while (!Placeholder->use_empty()) { + auto UI = Placeholder->user_begin(); + User *U = *UI; + + // If the using object isn't uniqued, just update the operands. This + // handles instructions and initializers for global variables. + if (!isa<Constant>(U) || isa<GlobalValue>(U)) { + UI.getUse().set(RealVal); + continue; + } + + // Otherwise, we have a constant that uses the placeholder. Replace that + // constant with a new constant that has *all* placeholder uses updated. + Constant *UserC = cast<Constant>(U); + for (User::op_iterator I = UserC->op_begin(), E = UserC->op_end(); + I != E; ++I) { + Value *NewOp; + if (!isa<ConstantPlaceHolder>(*I)) { + // Not a placeholder reference. + NewOp = *I; + } else if (*I == Placeholder) { + // Common case is that it just references this one placeholder. + NewOp = RealVal; + } else { + // Otherwise, look up the placeholder in ResolveConstants. + ResolveConstantsTy::iterator It = + std::lower_bound(ResolveConstants.begin(), ResolveConstants.end(), + std::pair<Constant*, unsigned>(cast<Constant>(*I), + 0)); + assert(It != ResolveConstants.end() && It->first == *I); + NewOp = operator[](It->second); + } + + NewOps.push_back(cast<Constant>(NewOp)); + } + + // Make the new constant. + Constant *NewC; + if (ConstantArray *UserCA = dyn_cast<ConstantArray>(UserC)) { + NewC = ConstantArray::get(UserCA->getType(), NewOps); + } else if (ConstantStruct *UserCS = dyn_cast<ConstantStruct>(UserC)) { + NewC = ConstantStruct::get(UserCS->getType(), NewOps); + } else if (isa<ConstantVector>(UserC)) { + NewC = ConstantVector::get(NewOps); + } else { + assert(isa<ConstantExpr>(UserC) && "Must be a ConstantExpr."); + NewC = cast<ConstantExpr>(UserC)->getWithOperands(NewOps); + } + + UserC->replaceAllUsesWith(NewC); + UserC->destroyConstant(); + NewOps.clear(); + } + + // Update all ValueHandles, they should be the only users at this point. + Placeholder->replaceAllUsesWith(RealVal); + delete Placeholder; + } +} + +void BitcodeReaderMDValueList::assignValue(Metadata *MD, unsigned Idx) { + if (Idx == size()) { + push_back(MD); + return; + } + + if (Idx >= size()) + resize(Idx+1); + + TrackingMDRef &OldMD = MDValuePtrs[Idx]; + if (!OldMD) { + OldMD.reset(MD); + return; + } + + // If there was a forward reference to this value, replace it. + TempMDTuple PrevMD(cast<MDTuple>(OldMD.get())); + PrevMD->replaceAllUsesWith(MD); + --NumFwdRefs; +} + +Metadata *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { + if (Idx >= size()) + resize(Idx + 1); + + if (Metadata *MD = MDValuePtrs[Idx]) + return MD; + + // Track forward refs to be resolved later. + if (AnyFwdRefs) { + MinFwdRef = std::min(MinFwdRef, Idx); + MaxFwdRef = std::max(MaxFwdRef, Idx); + } else { + AnyFwdRefs = true; + MinFwdRef = MaxFwdRef = Idx; + } + ++NumFwdRefs; + + // Create and return a placeholder, which will later be RAUW'd. + Metadata *MD = MDNode::getTemporary(Context, None).release(); + MDValuePtrs[Idx].reset(MD); + return MD; +} + +void BitcodeReaderMDValueList::tryToResolveCycles() { + if (!AnyFwdRefs) + // Nothing to do. + return; + + if (NumFwdRefs) + // Still forward references... can't resolve cycles. + return; + + // Resolve any cycles. + for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) { + auto &MD = MDValuePtrs[I]; + auto *N = dyn_cast_or_null<MDNode>(MD); + if (!N) + continue; + + assert(!N->isTemporary() && "Unexpected forward reference"); + N->resolveCycles(); + } + + // Make sure we return early again until there's another forward ref. + AnyFwdRefs = false; +} + +Type *BitcodeReader::getTypeByID(unsigned ID) { + // The type table size is always specified correctly. + if (ID >= TypeList.size()) + return nullptr; + + if (Type *Ty = TypeList[ID]) + return Ty; + + // If we have a forward reference, the only possible case is when it is to a + // named struct. Just create a placeholder for now. + return TypeList[ID] = createIdentifiedStructType(Context); +} + +StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context, + StringRef Name) { + auto *Ret = StructType::create(Context, Name); + IdentifiedStructTypes.push_back(Ret); + return Ret; +} + +StructType *BitcodeReader::createIdentifiedStructType(LLVMContext &Context) { + auto *Ret = StructType::create(Context); + IdentifiedStructTypes.push_back(Ret); + return Ret; +} + + +//===----------------------------------------------------------------------===// +// Functions for parsing blocks from the bitcode file +//===----------------------------------------------------------------------===// + + +/// \brief This fills an AttrBuilder object with the LLVM attributes that have +/// been decoded from the given integer. This function must stay in sync with +/// 'encodeLLVMAttributesForBitcode'. +static void decodeLLVMAttributesForBitcode(AttrBuilder &B, + uint64_t EncodedAttrs) { + // FIXME: Remove in 4.0. + + // The alignment is stored as a 16-bit raw value from bits 31--16. We shift + // the bits above 31 down by 11 bits. + unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; + assert((!Alignment || isPowerOf2_32(Alignment)) && + "Alignment must be a power of two."); + + if (Alignment) + B.addAlignmentAttr(Alignment); + B.addRawValue(((EncodedAttrs & (0xfffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff)); +} + +std::error_code BitcodeReader::parseAttributeBlock() { + if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID)) + return error("Invalid record"); + + if (!MAttributes.empty()) + return error("Invalid multiple blocks"); + + SmallVector<uint64_t, 64> Record; + + SmallVector<AttributeSet, 8> Attrs; + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: ignore. + break; + case bitc::PARAMATTR_CODE_ENTRY_OLD: { // ENTRY: [paramidx0, attr0, ...] + // FIXME: Remove in 4.0. + if (Record.size() & 1) + return error("Invalid record"); + + for (unsigned i = 0, e = Record.size(); i != e; i += 2) { + AttrBuilder B; + decodeLLVMAttributesForBitcode(B, Record[i+1]); + Attrs.push_back(AttributeSet::get(Context, Record[i], B)); + } + + MAttributes.push_back(AttributeSet::get(Context, Attrs)); + Attrs.clear(); + break; + } + case bitc::PARAMATTR_CODE_ENTRY: { // ENTRY: [attrgrp0, attrgrp1, ...] + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Attrs.push_back(MAttributeGroups[Record[i]]); + + MAttributes.push_back(AttributeSet::get(Context, Attrs)); + Attrs.clear(); + break; + } + } + } +} + +// Returns Attribute::None on unrecognized codes. +static Attribute::AttrKind getAttrFromCode(uint64_t Code) { + switch (Code) { + default: + return Attribute::None; + case bitc::ATTR_KIND_ALIGNMENT: + return Attribute::Alignment; + case bitc::ATTR_KIND_ALWAYS_INLINE: + return Attribute::AlwaysInline; + case bitc::ATTR_KIND_BUILTIN: + return Attribute::Builtin; + case bitc::ATTR_KIND_BY_VAL: + return Attribute::ByVal; + case bitc::ATTR_KIND_IN_ALLOCA: + return Attribute::InAlloca; + case bitc::ATTR_KIND_COLD: + return Attribute::Cold; + case bitc::ATTR_KIND_CONVERGENT: + return Attribute::Convergent; + case bitc::ATTR_KIND_INLINE_HINT: + return Attribute::InlineHint; + case bitc::ATTR_KIND_IN_REG: + return Attribute::InReg; + case bitc::ATTR_KIND_JUMP_TABLE: + return Attribute::JumpTable; + case bitc::ATTR_KIND_MIN_SIZE: + return Attribute::MinSize; + case bitc::ATTR_KIND_NAKED: + return Attribute::Naked; + case bitc::ATTR_KIND_NEST: + return Attribute::Nest; + case bitc::ATTR_KIND_NO_ALIAS: + return Attribute::NoAlias; + case bitc::ATTR_KIND_NO_BUILTIN: + return Attribute::NoBuiltin; + case bitc::ATTR_KIND_NO_CAPTURE: + return Attribute::NoCapture; + case bitc::ATTR_KIND_NO_DUPLICATE: + return Attribute::NoDuplicate; + case bitc::ATTR_KIND_NO_IMPLICIT_FLOAT: + return Attribute::NoImplicitFloat; + case bitc::ATTR_KIND_NO_INLINE: + return Attribute::NoInline; + case bitc::ATTR_KIND_NON_LAZY_BIND: + return Attribute::NonLazyBind; + case bitc::ATTR_KIND_NON_NULL: + return Attribute::NonNull; + case bitc::ATTR_KIND_DEREFERENCEABLE: + return Attribute::Dereferenceable; + case bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL: + return Attribute::DereferenceableOrNull; + case bitc::ATTR_KIND_NO_RED_ZONE: + return Attribute::NoRedZone; + case bitc::ATTR_KIND_NO_RETURN: + return Attribute::NoReturn; + case bitc::ATTR_KIND_NO_UNWIND: + return Attribute::NoUnwind; + case bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE: + return Attribute::OptimizeForSize; + case bitc::ATTR_KIND_OPTIMIZE_NONE: + return Attribute::OptimizeNone; + case bitc::ATTR_KIND_READ_NONE: + return Attribute::ReadNone; + case bitc::ATTR_KIND_READ_ONLY: + return Attribute::ReadOnly; + case bitc::ATTR_KIND_RETURNED: + return Attribute::Returned; + case bitc::ATTR_KIND_RETURNS_TWICE: + return Attribute::ReturnsTwice; + case bitc::ATTR_KIND_S_EXT: + return Attribute::SExt; + case bitc::ATTR_KIND_STACK_ALIGNMENT: + return Attribute::StackAlignment; + case bitc::ATTR_KIND_STACK_PROTECT: + return Attribute::StackProtect; + case bitc::ATTR_KIND_STACK_PROTECT_REQ: + return Attribute::StackProtectReq; + case bitc::ATTR_KIND_STACK_PROTECT_STRONG: + return Attribute::StackProtectStrong; + case bitc::ATTR_KIND_SAFESTACK: + return Attribute::SafeStack; + case bitc::ATTR_KIND_STRUCT_RET: + return Attribute::StructRet; + case bitc::ATTR_KIND_SANITIZE_ADDRESS: + return Attribute::SanitizeAddress; + case bitc::ATTR_KIND_SANITIZE_THREAD: + return Attribute::SanitizeThread; + case bitc::ATTR_KIND_SANITIZE_MEMORY: + return Attribute::SanitizeMemory; + case bitc::ATTR_KIND_UW_TABLE: + return Attribute::UWTable; + case bitc::ATTR_KIND_Z_EXT: + return Attribute::ZExt; + } +} + +std::error_code BitcodeReader::parseAlignmentValue(uint64_t Exponent, + unsigned &Alignment) { + // Note: Alignment in bitcode files is incremented by 1, so that zero + // can be used for default alignment. + if (Exponent > Value::MaxAlignmentExponent + 1) + return error("Invalid alignment value"); + Alignment = (1 << static_cast<unsigned>(Exponent)) >> 1; + return std::error_code(); +} + +std::error_code BitcodeReader::parseAttrKind(uint64_t Code, + Attribute::AttrKind *Kind) { + *Kind = getAttrFromCode(Code); + if (*Kind == Attribute::None) + return error(BitcodeError::CorruptedBitcode, + "Unknown attribute kind (" + Twine(Code) + ")"); + return std::error_code(); +} + +std::error_code BitcodeReader::parseAttributeGroupBlock() { + if (Stream.EnterSubBlock(bitc::PARAMATTR_GROUP_BLOCK_ID)) + return error("Invalid record"); + + if (!MAttributeGroups.empty()) + return error("Invalid multiple blocks"); + + SmallVector<uint64_t, 64> Record; + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: ignore. + break; + case bitc::PARAMATTR_GRP_CODE_ENTRY: { // ENTRY: [grpid, idx, a0, a1, ...] + if (Record.size() < 3) + return error("Invalid record"); + + uint64_t GrpID = Record[0]; + uint64_t Idx = Record[1]; // Index of the object this attribute refers to. + + AttrBuilder B; + for (unsigned i = 2, e = Record.size(); i != e; ++i) { + if (Record[i] == 0) { // Enum attribute + Attribute::AttrKind Kind; + if (std::error_code EC = parseAttrKind(Record[++i], &Kind)) + return EC; + + B.addAttribute(Kind); + } else if (Record[i] == 1) { // Integer attribute + Attribute::AttrKind Kind; + if (std::error_code EC = parseAttrKind(Record[++i], &Kind)) + return EC; + if (Kind == Attribute::Alignment) + B.addAlignmentAttr(Record[++i]); + else if (Kind == Attribute::StackAlignment) + B.addStackAlignmentAttr(Record[++i]); + else if (Kind == Attribute::Dereferenceable) + B.addDereferenceableAttr(Record[++i]); + else if (Kind == Attribute::DereferenceableOrNull) + B.addDereferenceableOrNullAttr(Record[++i]); + } else { // String attribute + assert((Record[i] == 3 || Record[i] == 4) && + "Invalid attribute group entry"); + bool HasValue = (Record[i++] == 4); + SmallString<64> KindStr; + SmallString<64> ValStr; + + while (Record[i] != 0 && i != e) + KindStr += Record[i++]; + assert(Record[i] == 0 && "Kind string not null terminated"); + + if (HasValue) { + // Has a value associated with it. + ++i; // Skip the '0' that terminates the "kind" string. + while (Record[i] != 0 && i != e) + ValStr += Record[i++]; + assert(Record[i] == 0 && "Value string not null terminated"); + } + + B.addAttribute(KindStr.str(), ValStr.str()); + } + } + + MAttributeGroups[GrpID] = AttributeSet::get(Context, Idx, B); + break; + } + } + } +} + +std::error_code BitcodeReader::parseTypeTable() { + if (Stream.EnterSubBlock(bitc::TYPE_BLOCK_ID_NEW)) + return error("Invalid record"); + + return parseTypeTableBody(); +} + +std::error_code BitcodeReader::parseTypeTableBody() { + if (!TypeList.empty()) + return error("Invalid multiple blocks"); + + SmallVector<uint64_t, 64> Record; + unsigned NumRecords = 0; + + SmallString<64> TypeName; + + // Read all the records for this type table. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + if (NumRecords != TypeList.size()) + return error("Malformed block"); + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + Type *ResultTy = nullptr; + switch (Stream.readRecord(Entry.ID, Record)) { + default: + return error("Invalid value"); + case bitc::TYPE_CODE_NUMENTRY: // TYPE_CODE_NUMENTRY: [numentries] + // TYPE_CODE_NUMENTRY contains a count of the number of types in the + // type list. This allows us to reserve space. + if (Record.size() < 1) + return error("Invalid record"); + TypeList.resize(Record[0]); + continue; + case bitc::TYPE_CODE_VOID: // VOID + ResultTy = Type::getVoidTy(Context); + break; + case bitc::TYPE_CODE_HALF: // HALF + ResultTy = Type::getHalfTy(Context); + break; + case bitc::TYPE_CODE_FLOAT: // FLOAT + ResultTy = Type::getFloatTy(Context); + break; + case bitc::TYPE_CODE_DOUBLE: // DOUBLE + ResultTy = Type::getDoubleTy(Context); + break; + case bitc::TYPE_CODE_X86_FP80: // X86_FP80 + ResultTy = Type::getX86_FP80Ty(Context); + break; + case bitc::TYPE_CODE_FP128: // FP128 + ResultTy = Type::getFP128Ty(Context); + break; + case bitc::TYPE_CODE_PPC_FP128: // PPC_FP128 + ResultTy = Type::getPPC_FP128Ty(Context); + break; + case bitc::TYPE_CODE_LABEL: // LABEL + ResultTy = Type::getLabelTy(Context); + break; + case bitc::TYPE_CODE_METADATA: // METADATA + ResultTy = Type::getMetadataTy(Context); + break; + case bitc::TYPE_CODE_X86_MMX: // X86_MMX + ResultTy = Type::getX86_MMXTy(Context); + break; + case bitc::TYPE_CODE_INTEGER: { // INTEGER: [width] + if (Record.size() < 1) + return error("Invalid record"); + + uint64_t NumBits = Record[0]; + if (NumBits < IntegerType::MIN_INT_BITS || + NumBits > IntegerType::MAX_INT_BITS) + return error("Bitwidth for integer type out of range"); + ResultTy = IntegerType::get(Context, NumBits); + break; + } + case bitc::TYPE_CODE_POINTER: { // POINTER: [pointee type] or + // [pointee type, address space] + if (Record.size() < 1) + return error("Invalid record"); + unsigned AddressSpace = 0; + if (Record.size() == 2) + AddressSpace = Record[1]; + ResultTy = getTypeByID(Record[0]); + if (!ResultTy || + !PointerType::isValidElementType(ResultTy)) + return error("Invalid type"); + ResultTy = PointerType::get(ResultTy, AddressSpace); + break; + } + case bitc::TYPE_CODE_FUNCTION_OLD: { + // FIXME: attrid is dead, remove it in LLVM 4.0 + // FUNCTION: [vararg, attrid, retty, paramty x N] + if (Record.size() < 3) + return error("Invalid record"); + SmallVector<Type*, 8> ArgTys; + for (unsigned i = 3, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + ArgTys.push_back(T); + else + break; + } + + ResultTy = getTypeByID(Record[2]); + if (!ResultTy || ArgTys.size() < Record.size()-3) + return error("Invalid type"); + + ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); + break; + } + case bitc::TYPE_CODE_FUNCTION: { + // FUNCTION: [vararg, retty, paramty x N] + if (Record.size() < 2) + return error("Invalid record"); + SmallVector<Type*, 8> ArgTys; + for (unsigned i = 2, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) { + if (!FunctionType::isValidArgumentType(T)) + return error("Invalid function argument type"); + ArgTys.push_back(T); + } + else + break; + } + + ResultTy = getTypeByID(Record[1]); + if (!ResultTy || ArgTys.size() < Record.size()-2) + return error("Invalid type"); + + ResultTy = FunctionType::get(ResultTy, ArgTys, Record[0]); + break; + } + case bitc::TYPE_CODE_STRUCT_ANON: { // STRUCT: [ispacked, eltty x N] + if (Record.size() < 1) + return error("Invalid record"); + SmallVector<Type*, 8> EltTys; + for (unsigned i = 1, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + EltTys.push_back(T); + else + break; + } + if (EltTys.size() != Record.size()-1) + return error("Invalid type"); + ResultTy = StructType::get(Context, EltTys, Record[0]); + break; + } + case bitc::TYPE_CODE_STRUCT_NAME: // STRUCT_NAME: [strchr x N] + if (convertToString(Record, 0, TypeName)) + return error("Invalid record"); + continue; + + case bitc::TYPE_CODE_STRUCT_NAMED: { // STRUCT: [ispacked, eltty x N] + if (Record.size() < 1) + return error("Invalid record"); + + if (NumRecords >= TypeList.size()) + return error("Invalid TYPE table"); + + // Check to see if this was forward referenced, if so fill in the temp. + StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); + if (Res) { + Res->setName(TypeName); + TypeList[NumRecords] = nullptr; + } else // Otherwise, create a new struct. + Res = createIdentifiedStructType(Context, TypeName); + TypeName.clear(); + + SmallVector<Type*, 8> EltTys; + for (unsigned i = 1, e = Record.size(); i != e; ++i) { + if (Type *T = getTypeByID(Record[i])) + EltTys.push_back(T); + else + break; + } + if (EltTys.size() != Record.size()-1) + return error("Invalid record"); + Res->setBody(EltTys, Record[0]); + ResultTy = Res; + break; + } + case bitc::TYPE_CODE_OPAQUE: { // OPAQUE: [] + if (Record.size() != 1) + return error("Invalid record"); + + if (NumRecords >= TypeList.size()) + return error("Invalid TYPE table"); + + // Check to see if this was forward referenced, if so fill in the temp. + StructType *Res = cast_or_null<StructType>(TypeList[NumRecords]); + if (Res) { + Res->setName(TypeName); + TypeList[NumRecords] = nullptr; + } else // Otherwise, create a new struct with no body. + Res = createIdentifiedStructType(Context, TypeName); + TypeName.clear(); + ResultTy = Res; + break; + } + case bitc::TYPE_CODE_ARRAY: // ARRAY: [numelts, eltty] + if (Record.size() < 2) + return error("Invalid record"); + ResultTy = getTypeByID(Record[1]); + if (!ResultTy || !ArrayType::isValidElementType(ResultTy)) + return error("Invalid type"); + ResultTy = ArrayType::get(ResultTy, Record[0]); + break; + case bitc::TYPE_CODE_VECTOR: // VECTOR: [numelts, eltty] + if (Record.size() < 2) + return error("Invalid record"); + if (Record[0] == 0) + return error("Invalid vector length"); + ResultTy = getTypeByID(Record[1]); + if (!ResultTy || !StructType::isValidElementType(ResultTy)) + return error("Invalid type"); + ResultTy = VectorType::get(ResultTy, Record[0]); + break; + } + + if (NumRecords >= TypeList.size()) + return error("Invalid TYPE table"); + if (TypeList[NumRecords]) + return error( + "Invalid TYPE table: Only named structs can be forward referenced"); + assert(ResultTy && "Didn't read a type?"); + TypeList[NumRecords++] = ResultTy; + } +} + +std::error_code BitcodeReader::parseValueSymbolTable() { + if (Stream.EnterSubBlock(bitc::VALUE_SYMTAB_BLOCK_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + + Triple TT(TheModule->getTargetTriple()); + + // Read all the records for this value table. + SmallString<128> ValueName; + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: unknown type. + break; + case bitc::VST_CODE_ENTRY: { // VST_ENTRY: [valueid, namechar x N] + if (convertToString(Record, 1, ValueName)) + return error("Invalid record"); + unsigned ValueID = Record[0]; + if (ValueID >= ValueList.size() || !ValueList[ValueID]) + return error("Invalid record"); + Value *V = ValueList[ValueID]; + + V->setName(StringRef(ValueName.data(), ValueName.size())); + if (auto *GO = dyn_cast<GlobalObject>(V)) { + if (GO->getComdat() == reinterpret_cast<Comdat *>(1)) { + if (TT.isOSBinFormatMachO()) + GO->setComdat(nullptr); + else + GO->setComdat(TheModule->getOrInsertComdat(V->getName())); + } + } + ValueName.clear(); + break; + } + case bitc::VST_CODE_BBENTRY: { + if (convertToString(Record, 1, ValueName)) + return error("Invalid record"); + BasicBlock *BB = getBasicBlock(Record[0]); + if (!BB) + return error("Invalid record"); + + BB->setName(StringRef(ValueName.data(), ValueName.size())); + ValueName.clear(); + break; + } + } + } +} + +static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >> 1; } + +std::error_code BitcodeReader::parseMetadata() { + IsMetadataMaterialized = true; + unsigned NextMDValueNo = MDValueList.size(); + + if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + + auto getMD = + [&](unsigned ID) -> Metadata *{ return MDValueList.getValueFwdRef(ID); }; + auto getMDOrNull = [&](unsigned ID) -> Metadata *{ + if (ID) + return getMD(ID - 1); + return nullptr; + }; + auto getMDString = [&](unsigned ID) -> MDString *{ + // This requires that the ID is not really a forward reference. In + // particular, the MDString must already have been resolved. + return cast_or_null<MDString>(getMDOrNull(ID)); + }; + +#define GET_OR_DISTINCT(CLASS, DISTINCT, ARGS) \ + (DISTINCT ? CLASS::getDistinct ARGS : CLASS::get ARGS) + + // Read all the records. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + MDValueList.tryToResolveCycles(); + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + unsigned Code = Stream.readRecord(Entry.ID, Record); + bool IsDistinct = false; + switch (Code) { + default: // Default behavior: ignore. + break; + case bitc::METADATA_NAME: { + // Read name of the named metadata. + SmallString<8> Name(Record.begin(), Record.end()); + Record.clear(); + Code = Stream.ReadCode(); + + unsigned NextBitCode = Stream.readRecord(Code, Record); + if (NextBitCode != bitc::METADATA_NAMED_NODE) + return error("METADATA_NAME not followed by METADATA_NAMED_NODE"); + + // Read named metadata elements. + unsigned Size = Record.size(); + NamedMDNode *NMD = TheModule->getOrInsertNamedMetadata(Name); + for (unsigned i = 0; i != Size; ++i) { + MDNode *MD = dyn_cast_or_null<MDNode>(MDValueList.getValueFwdRef(Record[i])); + if (!MD) + return error("Invalid record"); + NMD->addOperand(MD); + } + break; + } + case bitc::METADATA_OLD_FN_NODE: { + // FIXME: Remove in 4.0. + // This is a LocalAsMetadata record, the only type of function-local + // metadata. + if (Record.size() % 2 == 1) + return error("Invalid record"); + + // If this isn't a LocalAsMetadata record, we're dropping it. This used + // to be legal, but there's no upgrade path. + auto dropRecord = [&] { + MDValueList.assignValue(MDNode::get(Context, None), NextMDValueNo++); + }; + if (Record.size() != 2) { + dropRecord(); + break; + } + + Type *Ty = getTypeByID(Record[0]); + if (Ty->isMetadataTy() || Ty->isVoidTy()) { + dropRecord(); + break; + } + + MDValueList.assignValue( + LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)), + NextMDValueNo++); + break; + } + case bitc::METADATA_OLD_NODE: { + // FIXME: Remove in 4.0. + if (Record.size() % 2 == 1) + return error("Invalid record"); + + unsigned Size = Record.size(); + SmallVector<Metadata *, 8> Elts; + for (unsigned i = 0; i != Size; i += 2) { + Type *Ty = getTypeByID(Record[i]); + if (!Ty) + return error("Invalid record"); + if (Ty->isMetadataTy()) + Elts.push_back(MDValueList.getValueFwdRef(Record[i+1])); + else if (!Ty->isVoidTy()) { + auto *MD = + ValueAsMetadata::get(ValueList.getValueFwdRef(Record[i + 1], Ty)); + assert(isa<ConstantAsMetadata>(MD) && + "Expected non-function-local metadata"); + Elts.push_back(MD); + } else + Elts.push_back(nullptr); + } + MDValueList.assignValue(MDNode::get(Context, Elts), NextMDValueNo++); + break; + } + case bitc::METADATA_VALUE: { + if (Record.size() != 2) + return error("Invalid record"); + + Type *Ty = getTypeByID(Record[0]); + if (Ty->isMetadataTy() || Ty->isVoidTy()) + return error("Invalid record"); + + MDValueList.assignValue( + ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)), + NextMDValueNo++); + break; + } + case bitc::METADATA_DISTINCT_NODE: + IsDistinct = true; + // fallthrough... + case bitc::METADATA_NODE: { + SmallVector<Metadata *, 8> Elts; + Elts.reserve(Record.size()); + for (unsigned ID : Record) + Elts.push_back(ID ? MDValueList.getValueFwdRef(ID - 1) : nullptr); + MDValueList.assignValue(IsDistinct ? MDNode::getDistinct(Context, Elts) + : MDNode::get(Context, Elts), + NextMDValueNo++); + break; + } + case bitc::METADATA_LOCATION: { + if (Record.size() != 5) + return error("Invalid record"); + + unsigned Line = Record[1]; + unsigned Column = Record[2]; + MDNode *Scope = cast<MDNode>(MDValueList.getValueFwdRef(Record[3])); + Metadata *InlinedAt = + Record[4] ? MDValueList.getValueFwdRef(Record[4] - 1) : nullptr; + MDValueList.assignValue( + GET_OR_DISTINCT(DILocation, Record[0], + (Context, Line, Column, Scope, InlinedAt)), + NextMDValueNo++); + break; + } + case bitc::METADATA_GENERIC_DEBUG: { + if (Record.size() < 4) + return error("Invalid record"); + + unsigned Tag = Record[1]; + unsigned Version = Record[2]; + + if (Tag >= 1u << 16 || Version != 0) + return error("Invalid record"); + + auto *Header = getMDString(Record[3]); + SmallVector<Metadata *, 8> DwarfOps; + for (unsigned I = 4, E = Record.size(); I != E; ++I) + DwarfOps.push_back(Record[I] ? MDValueList.getValueFwdRef(Record[I] - 1) + : nullptr); + MDValueList.assignValue(GET_OR_DISTINCT(GenericDINode, Record[0], + (Context, Tag, Header, DwarfOps)), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBRANGE: { + if (Record.size() != 3) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DISubrange, Record[0], + (Context, Record[1], unrotateSign(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_ENUMERATOR: { + if (Record.size() != 3) + return error("Invalid record"); + + MDValueList.assignValue(GET_OR_DISTINCT(DIEnumerator, Record[0], + (Context, unrotateSign(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_BASIC_TYPE: { + if (Record.size() != 6) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIBasicType, Record[0], + (Context, Record[1], getMDString(Record[2]), + Record[3], Record[4], Record[5])), + NextMDValueNo++); + break; + } + case bitc::METADATA_DERIVED_TYPE: { + if (Record.size() != 12) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIDerivedType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPOSITE_TYPE: { + if (Record.size() != 16) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DICompositeType, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDOrNull(Record[5]), getMDOrNull(Record[6]), + Record[7], Record[8], Record[9], Record[10], + getMDOrNull(Record[11]), Record[12], + getMDOrNull(Record[13]), getMDOrNull(Record[14]), + getMDString(Record[15]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBROUTINE_TYPE: { + if (Record.size() != 3) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DISubroutineType, Record[0], + (Context, Record[1], getMDOrNull(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_FILE: { + if (Record.size() != 3) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIFile, Record[0], (Context, getMDString(Record[1]), + getMDString(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_COMPILE_UNIT: { + if (Record.size() < 14 || Record.size() > 15) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT( + DICompileUnit, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), Record[4], getMDString(Record[5]), + Record[6], getMDString(Record[7]), Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]), + getMDOrNull(Record[11]), getMDOrNull(Record[12]), + getMDOrNull(Record[13]), Record.size() == 14 ? 0 : Record[14])), + NextMDValueNo++); + break; + } + case bitc::METADATA_SUBPROGRAM: { + if (Record.size() != 19) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT( + DISubprogram, Record[0], + (Context, getMDOrNull(Record[1]), getMDString(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], Record[9], + getMDOrNull(Record[10]), Record[11], Record[12], Record[13], + Record[14], getMDOrNull(Record[15]), getMDOrNull(Record[16]), + getMDOrNull(Record[17]), getMDOrNull(Record[18]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK: { + if (Record.size() != 5) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DILexicalBlock, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3], Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_LEXICAL_BLOCK_FILE: { + if (Record.size() != 4) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DILexicalBlockFile, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), Record[3])), + NextMDValueNo++); + break; + } + case bitc::METADATA_NAMESPACE: { + if (Record.size() != 5) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DINamespace, Record[0], + (Context, getMDOrNull(Record[1]), + getMDOrNull(Record[2]), getMDString(Record[3]), + Record[4])), + NextMDValueNo++); + break; + } + case bitc::METADATA_TEMPLATE_TYPE: { + if (Record.size() != 3) + return error("Invalid record"); + + MDValueList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter, + Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_TEMPLATE_VALUE: { + if (Record.size() != 5) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DITemplateValueParameter, Record[0], + (Context, Record[1], getMDString(Record[2]), + getMDOrNull(Record[3]), getMDOrNull(Record[4]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_GLOBAL_VAR: { + if (Record.size() != 11) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIGlobalVariable, Record[0], + (Context, getMDOrNull(Record[1]), + getMDString(Record[2]), getMDString(Record[3]), + getMDOrNull(Record[4]), Record[5], + getMDOrNull(Record[6]), Record[7], Record[8], + getMDOrNull(Record[9]), getMDOrNull(Record[10]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_LOCAL_VAR: { + // 10th field is for the obseleted 'inlinedAt:' field. + if (Record.size() != 9 && Record.size() != 10) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DILocalVariable, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDString(Record[3]), getMDOrNull(Record[4]), + Record[5], getMDOrNull(Record[6]), Record[7], + Record[8])), + NextMDValueNo++); + break; + } + case bitc::METADATA_EXPRESSION: { + if (Record.size() < 1) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIExpression, Record[0], + (Context, makeArrayRef(Record).slice(1))), + NextMDValueNo++); + break; + } + case bitc::METADATA_OBJC_PROPERTY: { + if (Record.size() != 8) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIObjCProperty, Record[0], + (Context, getMDString(Record[1]), + getMDOrNull(Record[2]), Record[3], + getMDString(Record[4]), getMDString(Record[5]), + Record[6], getMDOrNull(Record[7]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_IMPORTED_ENTITY: { + if (Record.size() != 6) + return error("Invalid record"); + + MDValueList.assignValue( + GET_OR_DISTINCT(DIImportedEntity, Record[0], + (Context, Record[1], getMDOrNull(Record[2]), + getMDOrNull(Record[3]), Record[4], + getMDString(Record[5]))), + NextMDValueNo++); + break; + } + case bitc::METADATA_STRING: { + std::string String(Record.begin(), Record.end()); + llvm::UpgradeMDStringConstant(String); + Metadata *MD = MDString::get(Context, String); + MDValueList.assignValue(MD, NextMDValueNo++); + break; + } + case bitc::METADATA_KIND: { + if (Record.size() < 2) + return error("Invalid record"); + + unsigned Kind = Record[0]; + SmallString<8> Name(Record.begin()+1, Record.end()); + + unsigned NewKind = TheModule->getMDKindID(Name.str()); + if (!MDKindMap.insert(std::make_pair(Kind, NewKind)).second) + return error("Conflicting METADATA_KIND records"); + break; + } + } + } +#undef GET_OR_DISTINCT +} + +/// Decode a signed value stored with the sign bit in the LSB for dense VBR +/// encoding. +uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) { + if ((V & 1) == 0) + return V >> 1; + if (V != 1) + return -(V >> 1); + // There is no such thing as -0 with integers. "-0" really means MININT. + return 1ULL << 63; +} + +/// Resolve all of the initializers for global values and aliases that we can. +std::error_code BitcodeReader::resolveGlobalAndAliasInits() { + std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInitWorklist; + std::vector<std::pair<GlobalAlias*, unsigned> > AliasInitWorklist; + std::vector<std::pair<Function*, unsigned> > FunctionPrefixWorklist; + std::vector<std::pair<Function*, unsigned> > FunctionPrologueWorklist; + std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFnWorklist; + + GlobalInitWorklist.swap(GlobalInits); + AliasInitWorklist.swap(AliasInits); + FunctionPrefixWorklist.swap(FunctionPrefixes); + FunctionPrologueWorklist.swap(FunctionPrologues); + FunctionPersonalityFnWorklist.swap(FunctionPersonalityFns); + + while (!GlobalInitWorklist.empty()) { + unsigned ValID = GlobalInitWorklist.back().second; + if (ValID >= ValueList.size()) { + // Not ready to resolve this yet, it requires something later in the file. + GlobalInits.push_back(GlobalInitWorklist.back()); + } else { + if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) + GlobalInitWorklist.back().first->setInitializer(C); + else + return error("Expected a constant"); + } + GlobalInitWorklist.pop_back(); + } + + while (!AliasInitWorklist.empty()) { + unsigned ValID = AliasInitWorklist.back().second; + if (ValID >= ValueList.size()) { + AliasInits.push_back(AliasInitWorklist.back()); + } else { + Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID]); + if (!C) + return error("Expected a constant"); + GlobalAlias *Alias = AliasInitWorklist.back().first; + if (C->getType() != Alias->getType()) + return error("Alias and aliasee types don't match"); + Alias->setAliasee(C); + } + AliasInitWorklist.pop_back(); + } + + while (!FunctionPrefixWorklist.empty()) { + unsigned ValID = FunctionPrefixWorklist.back().second; + if (ValID >= ValueList.size()) { + FunctionPrefixes.push_back(FunctionPrefixWorklist.back()); + } else { + if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) + FunctionPrefixWorklist.back().first->setPrefixData(C); + else + return error("Expected a constant"); + } + FunctionPrefixWorklist.pop_back(); + } + + while (!FunctionPrologueWorklist.empty()) { + unsigned ValID = FunctionPrologueWorklist.back().second; + if (ValID >= ValueList.size()) { + FunctionPrologues.push_back(FunctionPrologueWorklist.back()); + } else { + if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) + FunctionPrologueWorklist.back().first->setPrologueData(C); + else + return error("Expected a constant"); + } + FunctionPrologueWorklist.pop_back(); + } + + while (!FunctionPersonalityFnWorklist.empty()) { + unsigned ValID = FunctionPersonalityFnWorklist.back().second; + if (ValID >= ValueList.size()) { + FunctionPersonalityFns.push_back(FunctionPersonalityFnWorklist.back()); + } else { + if (Constant *C = dyn_cast_or_null<Constant>(ValueList[ValID])) + FunctionPersonalityFnWorklist.back().first->setPersonalityFn(C); + else + return error("Expected a constant"); + } + FunctionPersonalityFnWorklist.pop_back(); + } + + return std::error_code(); +} + +static APInt readWideAPInt(ArrayRef<uint64_t> Vals, unsigned TypeBits) { + SmallVector<uint64_t, 8> Words(Vals.size()); + std::transform(Vals.begin(), Vals.end(), Words.begin(), + BitcodeReader::decodeSignRotatedValue); + + return APInt(TypeBits, Words); +} + +std::error_code BitcodeReader::parseConstants() { + if (Stream.EnterSubBlock(bitc::CONSTANTS_BLOCK_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + + // Read all the records for this value table. + Type *CurTy = Type::getInt32Ty(Context); + unsigned NextCstNo = ValueList.size(); + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + if (NextCstNo != ValueList.size()) + return error("Invalid ronstant reference"); + + // Once all the constants have been read, go through and resolve forward + // references. + ValueList.resolveConstantForwardRefs(); + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + Value *V = nullptr; + unsigned BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: unknown constant + case bitc::CST_CODE_UNDEF: // UNDEF + V = UndefValue::get(CurTy); + break; + case bitc::CST_CODE_SETTYPE: // SETTYPE: [typeid] + if (Record.empty()) + return error("Invalid record"); + if (Record[0] >= TypeList.size() || !TypeList[Record[0]]) + return error("Invalid record"); + CurTy = TypeList[Record[0]]; + continue; // Skip the ValueList manipulation. + case bitc::CST_CODE_NULL: // NULL + V = Constant::getNullValue(CurTy); + break; + case bitc::CST_CODE_INTEGER: // INTEGER: [intval] + if (!CurTy->isIntegerTy() || Record.empty()) + return error("Invalid record"); + V = ConstantInt::get(CurTy, decodeSignRotatedValue(Record[0])); + break; + case bitc::CST_CODE_WIDE_INTEGER: {// WIDE_INTEGER: [n x intval] + if (!CurTy->isIntegerTy() || Record.empty()) + return error("Invalid record"); + + APInt VInt = + readWideAPInt(Record, cast<IntegerType>(CurTy)->getBitWidth()); + V = ConstantInt::get(Context, VInt); + + break; + } + case bitc::CST_CODE_FLOAT: { // FLOAT: [fpval] + if (Record.empty()) + return error("Invalid record"); + if (CurTy->isHalfTy()) + V = ConstantFP::get(Context, APFloat(APFloat::IEEEhalf, + APInt(16, (uint16_t)Record[0]))); + else if (CurTy->isFloatTy()) + V = ConstantFP::get(Context, APFloat(APFloat::IEEEsingle, + APInt(32, (uint32_t)Record[0]))); + else if (CurTy->isDoubleTy()) + V = ConstantFP::get(Context, APFloat(APFloat::IEEEdouble, + APInt(64, Record[0]))); + else if (CurTy->isX86_FP80Ty()) { + // Bits are not stored the same way as a normal i80 APInt, compensate. + uint64_t Rearrange[2]; + Rearrange[0] = (Record[1] & 0xffffLL) | (Record[0] << 16); + Rearrange[1] = Record[0] >> 48; + V = ConstantFP::get(Context, APFloat(APFloat::x87DoubleExtended, + APInt(80, Rearrange))); + } else if (CurTy->isFP128Ty()) + V = ConstantFP::get(Context, APFloat(APFloat::IEEEquad, + APInt(128, Record))); + else if (CurTy->isPPC_FP128Ty()) + V = ConstantFP::get(Context, APFloat(APFloat::PPCDoubleDouble, + APInt(128, Record))); + else + V = UndefValue::get(CurTy); + break; + } + + case bitc::CST_CODE_AGGREGATE: {// AGGREGATE: [n x value number] + if (Record.empty()) + return error("Invalid record"); + + unsigned Size = Record.size(); + SmallVector<Constant*, 16> Elts; + + if (StructType *STy = dyn_cast<StructType>(CurTy)) { + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i], + STy->getElementType(i))); + V = ConstantStruct::get(STy, Elts); + } else if (ArrayType *ATy = dyn_cast<ArrayType>(CurTy)) { + Type *EltTy = ATy->getElementType(); + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); + V = ConstantArray::get(ATy, Elts); + } else if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) { + Type *EltTy = VTy->getElementType(); + for (unsigned i = 0; i != Size; ++i) + Elts.push_back(ValueList.getConstantFwdRef(Record[i], EltTy)); + V = ConstantVector::get(Elts); + } else { + V = UndefValue::get(CurTy); + } + break; + } + case bitc::CST_CODE_STRING: // STRING: [values] + case bitc::CST_CODE_CSTRING: { // CSTRING: [values] + if (Record.empty()) + return error("Invalid record"); + + SmallString<16> Elts(Record.begin(), Record.end()); + V = ConstantDataArray::getString(Context, Elts, + BitCode == bitc::CST_CODE_CSTRING); + break; + } + case bitc::CST_CODE_DATA: {// DATA: [n x value] + if (Record.empty()) + return error("Invalid record"); + + Type *EltTy = cast<SequentialType>(CurTy)->getElementType(); + unsigned Size = Record.size(); + + if (EltTy->isIntegerTy(8)) { + SmallVector<uint8_t, 16> Elts(Record.begin(), Record.end()); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else if (EltTy->isIntegerTy(16)) { + SmallVector<uint16_t, 16> Elts(Record.begin(), Record.end()); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else if (EltTy->isIntegerTy(32)) { + SmallVector<uint32_t, 16> Elts(Record.begin(), Record.end()); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else if (EltTy->isIntegerTy(64)) { + SmallVector<uint64_t, 16> Elts(Record.begin(), Record.end()); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else if (EltTy->isFloatTy()) { + SmallVector<float, 16> Elts(Size); + std::transform(Record.begin(), Record.end(), Elts.begin(), BitsToFloat); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else if (EltTy->isDoubleTy()) { + SmallVector<double, 16> Elts(Size); + std::transform(Record.begin(), Record.end(), Elts.begin(), + BitsToDouble); + if (isa<VectorType>(CurTy)) + V = ConstantDataVector::get(Context, Elts); + else + V = ConstantDataArray::get(Context, Elts); + } else { + return error("Invalid type for value"); + } + break; + } + + case bitc::CST_CODE_CE_BINOP: { // CE_BINOP: [opcode, opval, opval] + if (Record.size() < 3) + return error("Invalid record"); + int Opc = getDecodedBinaryOpcode(Record[0], CurTy); + if (Opc < 0) { + V = UndefValue::get(CurTy); // Unknown binop. + } else { + Constant *LHS = ValueList.getConstantFwdRef(Record[1], CurTy); + Constant *RHS = ValueList.getConstantFwdRef(Record[2], CurTy); + unsigned Flags = 0; + if (Record.size() >= 4) { + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul || + Opc == Instruction::Shl) { + if (Record[3] & (1 << bitc::OBO_NO_SIGNED_WRAP)) + Flags |= OverflowingBinaryOperator::NoSignedWrap; + if (Record[3] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) + Flags |= OverflowingBinaryOperator::NoUnsignedWrap; + } else if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv || + Opc == Instruction::LShr || + Opc == Instruction::AShr) { + if (Record[3] & (1 << bitc::PEO_EXACT)) + Flags |= SDivOperator::IsExact; + } + } + V = ConstantExpr::get(Opc, LHS, RHS, Flags); + } + break; + } + case bitc::CST_CODE_CE_CAST: { // CE_CAST: [opcode, opty, opval] + if (Record.size() < 3) + return error("Invalid record"); + int Opc = getDecodedCastOpcode(Record[0]); + if (Opc < 0) { + V = UndefValue::get(CurTy); // Unknown cast. + } else { + Type *OpTy = getTypeByID(Record[1]); + if (!OpTy) + return error("Invalid record"); + Constant *Op = ValueList.getConstantFwdRef(Record[2], OpTy); + V = UpgradeBitCastExpr(Opc, Op, CurTy); + if (!V) V = ConstantExpr::getCast(Opc, Op, CurTy); + } + break; + } + case bitc::CST_CODE_CE_INBOUNDS_GEP: + case bitc::CST_CODE_CE_GEP: { // CE_GEP: [n x operands] + unsigned OpNum = 0; + Type *PointeeType = nullptr; + if (Record.size() % 2) + PointeeType = getTypeByID(Record[OpNum++]); + SmallVector<Constant*, 16> Elts; + while (OpNum != Record.size()) { + Type *ElTy = getTypeByID(Record[OpNum++]); + if (!ElTy) + return error("Invalid record"); + Elts.push_back(ValueList.getConstantFwdRef(Record[OpNum++], ElTy)); + } + + if (PointeeType && + PointeeType != + cast<SequentialType>(Elts[0]->getType()->getScalarType()) + ->getElementType()) + return error("Explicit gep operator type does not match pointee type " + "of pointer operand"); + + ArrayRef<Constant *> Indices(Elts.begin() + 1, Elts.end()); + V = ConstantExpr::getGetElementPtr(PointeeType, Elts[0], Indices, + BitCode == + bitc::CST_CODE_CE_INBOUNDS_GEP); + break; + } + case bitc::CST_CODE_CE_SELECT: { // CE_SELECT: [opval#, opval#, opval#] + if (Record.size() < 3) + return error("Invalid record"); + + Type *SelectorTy = Type::getInt1Ty(Context); + + // If CurTy is a vector of length n, then Record[0] must be a <n x i1> + // vector. Otherwise, it must be a single bit. + if (VectorType *VTy = dyn_cast<VectorType>(CurTy)) + SelectorTy = VectorType::get(Type::getInt1Ty(Context), + VTy->getNumElements()); + + V = ConstantExpr::getSelect(ValueList.getConstantFwdRef(Record[0], + SelectorTy), + ValueList.getConstantFwdRef(Record[1],CurTy), + ValueList.getConstantFwdRef(Record[2],CurTy)); + break; + } + case bitc::CST_CODE_CE_EXTRACTELT + : { // CE_EXTRACTELT: [opty, opval, opty, opval] + if (Record.size() < 3) + return error("Invalid record"); + VectorType *OpTy = + dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); + if (!OpTy) + return error("Invalid record"); + Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); + Constant *Op1 = nullptr; + if (Record.size() == 4) { + Type *IdxTy = getTypeByID(Record[2]); + if (!IdxTy) + return error("Invalid record"); + Op1 = ValueList.getConstantFwdRef(Record[3], IdxTy); + } else // TODO: Remove with llvm 4.0 + Op1 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + if (!Op1) + return error("Invalid record"); + V = ConstantExpr::getExtractElement(Op0, Op1); + break; + } + case bitc::CST_CODE_CE_INSERTELT + : { // CE_INSERTELT: [opval, opval, opty, opval] + VectorType *OpTy = dyn_cast<VectorType>(CurTy); + if (Record.size() < 3 || !OpTy) + return error("Invalid record"); + Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); + Constant *Op1 = ValueList.getConstantFwdRef(Record[1], + OpTy->getElementType()); + Constant *Op2 = nullptr; + if (Record.size() == 4) { + Type *IdxTy = getTypeByID(Record[2]); + if (!IdxTy) + return error("Invalid record"); + Op2 = ValueList.getConstantFwdRef(Record[3], IdxTy); + } else // TODO: Remove with llvm 4.0 + Op2 = ValueList.getConstantFwdRef(Record[2], Type::getInt32Ty(Context)); + if (!Op2) + return error("Invalid record"); + V = ConstantExpr::getInsertElement(Op0, Op1, Op2); + break; + } + case bitc::CST_CODE_CE_SHUFFLEVEC: { // CE_SHUFFLEVEC: [opval, opval, opval] + VectorType *OpTy = dyn_cast<VectorType>(CurTy); + if (Record.size() < 3 || !OpTy) + return error("Invalid record"); + Constant *Op0 = ValueList.getConstantFwdRef(Record[0], OpTy); + Constant *Op1 = ValueList.getConstantFwdRef(Record[1], OpTy); + Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), + OpTy->getNumElements()); + Constant *Op2 = ValueList.getConstantFwdRef(Record[2], ShufTy); + V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); + break; + } + case bitc::CST_CODE_CE_SHUFVEC_EX: { // [opty, opval, opval, opval] + VectorType *RTy = dyn_cast<VectorType>(CurTy); + VectorType *OpTy = + dyn_cast_or_null<VectorType>(getTypeByID(Record[0])); + if (Record.size() < 4 || !RTy || !OpTy) + return error("Invalid record"); + Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); + Type *ShufTy = VectorType::get(Type::getInt32Ty(Context), + RTy->getNumElements()); + Constant *Op2 = ValueList.getConstantFwdRef(Record[3], ShufTy); + V = ConstantExpr::getShuffleVector(Op0, Op1, Op2); + break; + } + case bitc::CST_CODE_CE_CMP: { // CE_CMP: [opty, opval, opval, pred] + if (Record.size() < 4) + return error("Invalid record"); + Type *OpTy = getTypeByID(Record[0]); + if (!OpTy) + return error("Invalid record"); + Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], OpTy); + + if (OpTy->isFPOrFPVectorTy()) + V = ConstantExpr::getFCmp(Record[3], Op0, Op1); + else + V = ConstantExpr::getICmp(Record[3], Op0, Op1); + break; + } + // This maintains backward compatibility, pre-asm dialect keywords. + // FIXME: Remove with the 4.0 release. + case bitc::CST_CODE_INLINEASM_OLD: { + if (Record.size() < 2) + return error("Invalid record"); + std::string AsmStr, ConstrStr; + bool HasSideEffects = Record[0] & 1; + bool IsAlignStack = Record[0] >> 1; + unsigned AsmStrSize = Record[1]; + if (2+AsmStrSize >= Record.size()) + return error("Invalid record"); + unsigned ConstStrSize = Record[2+AsmStrSize]; + if (3+AsmStrSize+ConstStrSize > Record.size()) + return error("Invalid record"); + + for (unsigned i = 0; i != AsmStrSize; ++i) + AsmStr += (char)Record[2+i]; + for (unsigned i = 0; i != ConstStrSize; ++i) + ConstrStr += (char)Record[3+AsmStrSize+i]; + PointerType *PTy = cast<PointerType>(CurTy); + V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), + AsmStr, ConstrStr, HasSideEffects, IsAlignStack); + break; + } + // This version adds support for the asm dialect keywords (e.g., + // inteldialect). + case bitc::CST_CODE_INLINEASM: { + if (Record.size() < 2) + return error("Invalid record"); + std::string AsmStr, ConstrStr; + bool HasSideEffects = Record[0] & 1; + bool IsAlignStack = (Record[0] >> 1) & 1; + unsigned AsmDialect = Record[0] >> 2; + unsigned AsmStrSize = Record[1]; + if (2+AsmStrSize >= Record.size()) + return error("Invalid record"); + unsigned ConstStrSize = Record[2+AsmStrSize]; + if (3+AsmStrSize+ConstStrSize > Record.size()) + return error("Invalid record"); + + for (unsigned i = 0; i != AsmStrSize; ++i) + AsmStr += (char)Record[2+i]; + for (unsigned i = 0; i != ConstStrSize; ++i) + ConstrStr += (char)Record[3+AsmStrSize+i]; + PointerType *PTy = cast<PointerType>(CurTy); + V = InlineAsm::get(cast<FunctionType>(PTy->getElementType()), + AsmStr, ConstrStr, HasSideEffects, IsAlignStack, + InlineAsm::AsmDialect(AsmDialect)); + break; + } + case bitc::CST_CODE_BLOCKADDRESS:{ + if (Record.size() < 3) + return error("Invalid record"); + Type *FnTy = getTypeByID(Record[0]); + if (!FnTy) + return error("Invalid record"); + Function *Fn = + dyn_cast_or_null<Function>(ValueList.getConstantFwdRef(Record[1],FnTy)); + if (!Fn) + return error("Invalid record"); + + // Don't let Fn get dematerialized. + BlockAddressesTaken.insert(Fn); + + // If the function is already parsed we can insert the block address right + // away. + BasicBlock *BB; + unsigned BBID = Record[2]; + if (!BBID) + // Invalid reference to entry block. + return error("Invalid ID"); + if (!Fn->empty()) { + Function::iterator BBI = Fn->begin(), BBE = Fn->end(); + for (size_t I = 0, E = BBID; I != E; ++I) { + if (BBI == BBE) + return error("Invalid ID"); + ++BBI; + } + BB = BBI; + } else { + // Otherwise insert a placeholder and remember it so it can be inserted + // when the function is parsed. + auto &FwdBBs = BasicBlockFwdRefs[Fn]; + if (FwdBBs.empty()) + BasicBlockFwdRefQueue.push_back(Fn); + if (FwdBBs.size() < BBID + 1) + FwdBBs.resize(BBID + 1); + if (!FwdBBs[BBID]) + FwdBBs[BBID] = BasicBlock::Create(Context); + BB = FwdBBs[BBID]; + } + V = BlockAddress::get(Fn, BB); + break; + } + } + + ValueList.assignValue(V, NextCstNo); + ++NextCstNo; + } +} + +std::error_code BitcodeReader::parseUseLists() { + if (Stream.EnterSubBlock(bitc::USELIST_BLOCK_ID)) + return error("Invalid record"); + + // Read all the records. + SmallVector<uint64_t, 64> Record; + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a use list record. + Record.clear(); + bool IsBB = false; + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: unknown type. + break; + case bitc::USELIST_CODE_BB: + IsBB = true; + // fallthrough + case bitc::USELIST_CODE_DEFAULT: { + unsigned RecordLength = Record.size(); + if (RecordLength < 3) + // Records should have at least an ID and two indexes. + return error("Invalid record"); + unsigned ID = Record.back(); + Record.pop_back(); + + Value *V; + if (IsBB) { + assert(ID < FunctionBBs.size() && "Basic block not found"); + V = FunctionBBs[ID]; + } else + V = ValueList[ID]; + unsigned NumUses = 0; + SmallDenseMap<const Use *, unsigned, 16> Order; + for (const Use &U : V->uses()) { + if (++NumUses > Record.size()) + break; + Order[&U] = Record[NumUses - 1]; + } + if (Order.size() != Record.size() || NumUses > Record.size()) + // Mismatches can happen if the functions are being materialized lazily + // (out-of-order), or a value has been upgraded. + break; + + V->sortUseList([&](const Use &L, const Use &R) { + return Order.lookup(&L) < Order.lookup(&R); + }); + break; + } + } + } +} + +/// When we see the block for metadata, remember where it is and then skip it. +/// This lets us lazily deserialize the metadata. +std::error_code BitcodeReader::rememberAndSkipMetadata() { + // Save the current stream state. + uint64_t CurBit = Stream.GetCurrentBitNo(); + DeferredMetadataInfo.push_back(CurBit); + + // Skip over the block for now. + if (Stream.SkipBlock()) + return error("Invalid record"); + return std::error_code(); +} + +std::error_code BitcodeReader::materializeMetadata() { + for (uint64_t BitPos : DeferredMetadataInfo) { + // Move the bit stream to the saved position. + Stream.JumpToBit(BitPos); + if (std::error_code EC = parseMetadata()) + return EC; + } + DeferredMetadataInfo.clear(); + return std::error_code(); +} + +void BitcodeReader::setStripDebugInfo() { StripDebugInfo = true; } + +/// When we see the block for a function body, remember where it is and then +/// skip it. This lets us lazily deserialize the functions. +std::error_code BitcodeReader::rememberAndSkipFunctionBody() { + // Get the function we are talking about. + if (FunctionsWithBodies.empty()) + return error("Insufficient function protos"); + + Function *Fn = FunctionsWithBodies.back(); + FunctionsWithBodies.pop_back(); + + // Save the current stream state. + uint64_t CurBit = Stream.GetCurrentBitNo(); + DeferredFunctionInfo[Fn] = CurBit; + + // Skip over the function block for now. + if (Stream.SkipBlock()) + return error("Invalid record"); + return std::error_code(); +} + +std::error_code BitcodeReader::globalCleanup() { + // Patch the initializers for globals and aliases up. + resolveGlobalAndAliasInits(); + if (!GlobalInits.empty() || !AliasInits.empty()) + return error("Malformed global initializer set"); + + // Look for intrinsic functions which need to be upgraded at some point + for (Function &F : *TheModule) { + Function *NewFn; + if (UpgradeIntrinsicFunction(&F, NewFn)) + UpgradedIntrinsics.push_back(std::make_pair(&F, NewFn)); + } + + // Look for global variables which need to be renamed. + for (GlobalVariable &GV : TheModule->globals()) + UpgradeGlobalVariable(&GV); + + // Force deallocation of memory for these vectors to favor the client that + // want lazy deserialization. + std::vector<std::pair<GlobalVariable*, unsigned> >().swap(GlobalInits); + std::vector<std::pair<GlobalAlias*, unsigned> >().swap(AliasInits); + return std::error_code(); +} + +std::error_code BitcodeReader::parseModule(bool Resume, + bool ShouldLazyLoadMetadata) { + if (Resume) + Stream.JumpToBit(NextUnreadBit); + else if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + std::vector<std::string> SectionTable; + std::vector<std::string> GCTable; + + // Read all the records for this module. + while (1) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return globalCleanup(); + + case BitstreamEntry::SubBlock: + switch (Entry.ID) { + default: // Skip unknown content. + if (Stream.SkipBlock()) + return error("Invalid record"); + break; + case bitc::BLOCKINFO_BLOCK_ID: + if (Stream.ReadBlockInfoBlock()) + return error("Malformed block"); + break; + case bitc::PARAMATTR_BLOCK_ID: + if (std::error_code EC = parseAttributeBlock()) + return EC; + break; + case bitc::PARAMATTR_GROUP_BLOCK_ID: + if (std::error_code EC = parseAttributeGroupBlock()) + return EC; + break; + case bitc::TYPE_BLOCK_ID_NEW: + if (std::error_code EC = parseTypeTable()) + return EC; + break; + case bitc::VALUE_SYMTAB_BLOCK_ID: + if (std::error_code EC = parseValueSymbolTable()) + return EC; + SeenValueSymbolTable = true; + break; + case bitc::CONSTANTS_BLOCK_ID: + if (std::error_code EC = parseConstants()) + return EC; + if (std::error_code EC = resolveGlobalAndAliasInits()) + return EC; + break; + case bitc::METADATA_BLOCK_ID: + if (ShouldLazyLoadMetadata && !IsMetadataMaterialized) { + if (std::error_code EC = rememberAndSkipMetadata()) + return EC; + break; + } + assert(DeferredMetadataInfo.empty() && "Unexpected deferred metadata"); + if (std::error_code EC = parseMetadata()) + return EC; + break; + case bitc::FUNCTION_BLOCK_ID: + // If this is the first function body we've seen, reverse the + // FunctionsWithBodies list. + if (!SeenFirstFunctionBody) { + std::reverse(FunctionsWithBodies.begin(), FunctionsWithBodies.end()); + if (std::error_code EC = globalCleanup()) + return EC; + SeenFirstFunctionBody = true; + } + + if (std::error_code EC = rememberAndSkipFunctionBody()) + return EC; + // For streaming bitcode, suspend parsing when we reach the function + // bodies. Subsequent materialization calls will resume it when + // necessary. For streaming, the function bodies must be at the end of + // the bitcode. If the bitcode file is old, the symbol table will be + // at the end instead and will not have been seen yet. In this case, + // just finish the parse now. + if (IsStreamed && SeenValueSymbolTable) { + NextUnreadBit = Stream.GetCurrentBitNo(); + return std::error_code(); + } + break; + case bitc::USELIST_BLOCK_ID: + if (std::error_code EC = parseUseLists()) + return EC; + break; + } + continue; + + case BitstreamEntry::Record: + // The interesting case. + break; + } + + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_VERSION: { // VERSION: [version#] + if (Record.size() < 1) + return error("Invalid record"); + // Only version #0 and #1 are supported so far. + unsigned module_version = Record[0]; + switch (module_version) { + default: + return error("Invalid value"); + case 0: + UseRelativeIDs = false; + break; + case 1: + UseRelativeIDs = true; + break; + } + break; + } + case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + TheModule->setTargetTriple(S); + break; + } + case bitc::MODULE_CODE_DATALAYOUT: { // DATALAYOUT: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + TheModule->setDataLayout(S); + break; + } + case bitc::MODULE_CODE_ASM: { // ASM: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + TheModule->setModuleInlineAsm(S); + break; + } + case bitc::MODULE_CODE_DEPLIB: { // DEPLIB: [strchr x N] + // FIXME: Remove in 4.0. + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + // Ignore value. + break; + } + case bitc::MODULE_CODE_SECTIONNAME: { // SECTIONNAME: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + SectionTable.push_back(S); + break; + } + case bitc::MODULE_CODE_GCNAME: { // SECTIONNAME: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + GCTable.push_back(S); + break; + } + case bitc::MODULE_CODE_COMDAT: { // COMDAT: [selection_kind, name] + if (Record.size() < 2) + return error("Invalid record"); + Comdat::SelectionKind SK = getDecodedComdatSelectionKind(Record[0]); + unsigned ComdatNameSize = Record[1]; + std::string ComdatName; + ComdatName.reserve(ComdatNameSize); + for (unsigned i = 0; i != ComdatNameSize; ++i) + ComdatName += (char)Record[2 + i]; + Comdat *C = TheModule->getOrInsertComdat(ComdatName); + C->setSelectionKind(SK); + ComdatList.push_back(C); + break; + } + // GLOBALVAR: [pointer type, isconst, initid, + // linkage, alignment, section, visibility, threadlocal, + // unnamed_addr, externally_initialized, dllstorageclass, + // comdat] + case bitc::MODULE_CODE_GLOBALVAR: { + if (Record.size() < 6) + return error("Invalid record"); + Type *Ty = getTypeByID(Record[0]); + if (!Ty) + return error("Invalid record"); + bool isConstant = Record[1] & 1; + bool explicitType = Record[1] & 2; + unsigned AddressSpace; + if (explicitType) { + AddressSpace = Record[1] >> 2; + } else { + if (!Ty->isPointerTy()) + return error("Invalid type for value"); + AddressSpace = cast<PointerType>(Ty)->getAddressSpace(); + Ty = cast<PointerType>(Ty)->getElementType(); + } + + uint64_t RawLinkage = Record[3]; + GlobalValue::LinkageTypes Linkage = getDecodedLinkage(RawLinkage); + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[4], Alignment)) + return EC; + std::string Section; + if (Record[5]) { + if (Record[5]-1 >= SectionTable.size()) + return error("Invalid ID"); + Section = SectionTable[Record[5]-1]; + } + GlobalValue::VisibilityTypes Visibility = GlobalValue::DefaultVisibility; + // Local linkage must have default visibility. + if (Record.size() > 6 && !GlobalValue::isLocalLinkage(Linkage)) + // FIXME: Change to an error if non-default in 4.0. + Visibility = getDecodedVisibility(Record[6]); + + GlobalVariable::ThreadLocalMode TLM = GlobalVariable::NotThreadLocal; + if (Record.size() > 7) + TLM = getDecodedThreadLocalMode(Record[7]); + + bool UnnamedAddr = false; + if (Record.size() > 8) + UnnamedAddr = Record[8]; + + bool ExternallyInitialized = false; + if (Record.size() > 9) + ExternallyInitialized = Record[9]; + + GlobalVariable *NewGV = + new GlobalVariable(*TheModule, Ty, isConstant, Linkage, nullptr, "", nullptr, + TLM, AddressSpace, ExternallyInitialized); + NewGV->setAlignment(Alignment); + if (!Section.empty()) + NewGV->setSection(Section); + NewGV->setVisibility(Visibility); + NewGV->setUnnamedAddr(UnnamedAddr); + + if (Record.size() > 10) + NewGV->setDLLStorageClass(getDecodedDLLStorageClass(Record[10])); + else + upgradeDLLImportExportLinkage(NewGV, RawLinkage); + + ValueList.push_back(NewGV); + + // Remember which value to use for the global initializer. + if (unsigned InitID = Record[2]) + GlobalInits.push_back(std::make_pair(NewGV, InitID-1)); + + if (Record.size() > 11) { + if (unsigned ComdatID = Record[11]) { + if (ComdatID > ComdatList.size()) + return error("Invalid global variable comdat ID"); + NewGV->setComdat(ComdatList[ComdatID - 1]); + } + } else if (hasImplicitComdat(RawLinkage)) { + NewGV->setComdat(reinterpret_cast<Comdat *>(1)); + } + break; + } + // FUNCTION: [type, callingconv, isproto, linkage, paramattr, + // alignment, section, visibility, gc, unnamed_addr, + // prologuedata, dllstorageclass, comdat, prefixdata] + case bitc::MODULE_CODE_FUNCTION: { + if (Record.size() < 8) + return error("Invalid record"); + Type *Ty = getTypeByID(Record[0]); + if (!Ty) + return error("Invalid record"); + if (auto *PTy = dyn_cast<PointerType>(Ty)) + Ty = PTy->getElementType(); + auto *FTy = dyn_cast<FunctionType>(Ty); + if (!FTy) + return error("Invalid type for value"); + + Function *Func = Function::Create(FTy, GlobalValue::ExternalLinkage, + "", TheModule); + + Func->setCallingConv(static_cast<CallingConv::ID>(Record[1])); + bool isProto = Record[2]; + uint64_t RawLinkage = Record[3]; + Func->setLinkage(getDecodedLinkage(RawLinkage)); + Func->setAttributes(getAttributes(Record[4])); + + unsigned Alignment; + if (std::error_code EC = parseAlignmentValue(Record[5], Alignment)) + return EC; + Func->setAlignment(Alignment); + if (Record[6]) { + if (Record[6]-1 >= SectionTable.size()) + return error("Invalid ID"); + Func->setSection(SectionTable[Record[6]-1]); + } + // Local linkage must have default visibility. + if (!Func->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. + Func->setVisibility(getDecodedVisibility(Record[7])); + if (Record.size() > 8 && Record[8]) { + if (Record[8]-1 >= GCTable.size()) + return error("Invalid ID"); + Func->setGC(GCTable[Record[8]-1].c_str()); + } + bool UnnamedAddr = false; + if (Record.size() > 9) + UnnamedAddr = Record[9]; + Func->setUnnamedAddr(UnnamedAddr); + if (Record.size() > 10 && Record[10] != 0) + FunctionPrologues.push_back(std::make_pair(Func, Record[10]-1)); + + if (Record.size() > 11) + Func->setDLLStorageClass(getDecodedDLLStorageClass(Record[11])); + else + upgradeDLLImportExportLinkage(Func, RawLinkage); + + if (Record.size() > 12) { + if (unsigned ComdatID = Record[12]) { + if (ComdatID > ComdatList.size()) + return error("Invalid function comdat ID"); + Func->setComdat(ComdatList[ComdatID - 1]); + } + } else if (hasImplicitComdat(RawLinkage)) { + Func->setComdat(reinterpret_cast<Comdat *>(1)); + } + + if (Record.size() > 13 && Record[13] != 0) + FunctionPrefixes.push_back(std::make_pair(Func, Record[13]-1)); + + if (Record.size() > 14 && Record[14] != 0) + FunctionPersonalityFns.push_back(std::make_pair(Func, Record[14] - 1)); + + ValueList.push_back(Func); + + // If this is a function with a body, remember the prototype we are + // creating now, so that we can match up the body with them later. + if (!isProto) { + Func->setIsMaterializable(true); + FunctionsWithBodies.push_back(Func); + if (IsStreamed) + DeferredFunctionInfo[Func] = 0; + } + break; + } + // ALIAS: [alias type, aliasee val#, linkage] + // ALIAS: [alias type, aliasee val#, linkage, visibility, dllstorageclass] + case bitc::MODULE_CODE_ALIAS: { + if (Record.size() < 3) + return error("Invalid record"); + Type *Ty = getTypeByID(Record[0]); + if (!Ty) + return error("Invalid record"); + auto *PTy = dyn_cast<PointerType>(Ty); + if (!PTy) + return error("Invalid type for value"); + + auto *NewGA = + GlobalAlias::create(PTy, getDecodedLinkage(Record[2]), "", TheModule); + // Old bitcode files didn't have visibility field. + // Local linkage must have default visibility. + if (Record.size() > 3 && !NewGA->hasLocalLinkage()) + // FIXME: Change to an error if non-default in 4.0. + NewGA->setVisibility(getDecodedVisibility(Record[3])); + if (Record.size() > 4) + NewGA->setDLLStorageClass(getDecodedDLLStorageClass(Record[4])); + else + upgradeDLLImportExportLinkage(NewGA, Record[2]); + if (Record.size() > 5) + NewGA->setThreadLocalMode(getDecodedThreadLocalMode(Record[5])); + if (Record.size() > 6) + NewGA->setUnnamedAddr(Record[6]); + ValueList.push_back(NewGA); + AliasInits.push_back(std::make_pair(NewGA, Record[1])); + break; + } + /// MODULE_CODE_PURGEVALS: [numvals] + case bitc::MODULE_CODE_PURGEVALS: + // Trim down the value list to the specified size. + if (Record.size() < 1 || Record[0] > ValueList.size()) + return error("Invalid record"); + ValueList.shrinkTo(Record[0]); + break; + } + Record.clear(); + } +} + +std::error_code +BitcodeReader::parseBitcodeInto(std::unique_ptr<DataStreamer> Streamer, + Module *M, bool ShouldLazyLoadMetadata) { + TheModule = M; + + if (std::error_code EC = initStream(std::move(Streamer))) + return EC; + + // Sniff for the signature. + if (Stream.Read(8) != 'B' || + Stream.Read(8) != 'C' || + Stream.Read(4) != 0x0 || + Stream.Read(4) != 0xC || + Stream.Read(4) != 0xE || + Stream.Read(4) != 0xD) + return error("Invalid bitcode signature"); + + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (1) { + if (Stream.AtEndOfStream()) { + // We didn't really read a proper Module. + return error("Malformed IR file"); + } + + BitstreamEntry Entry = + Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); + + if (Entry.Kind != BitstreamEntry::SubBlock) + return error("Malformed block"); + + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return parseModule(false, ShouldLazyLoadMetadata); + + if (Stream.SkipBlock()) + return error("Invalid record"); + } +} + +ErrorOr<std::string> BitcodeReader::parseModuleTriple() { + if (Stream.EnterSubBlock(bitc::MODULE_BLOCK_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + + std::string Triple; + // Read all the records for this module. + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return Triple; + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + switch (Stream.readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::MODULE_CODE_TRIPLE: { // TRIPLE: [strchr x N] + std::string S; + if (convertToString(Record, 0, S)) + return error("Invalid record"); + Triple = S; + break; + } + } + Record.clear(); + } + llvm_unreachable("Exit infinite loop"); +} + +ErrorOr<std::string> BitcodeReader::parseTriple() { + if (std::error_code EC = initStream(nullptr)) + return EC; + + // Sniff for the signature. + if (Stream.Read(8) != 'B' || + Stream.Read(8) != 'C' || + Stream.Read(4) != 0x0 || + Stream.Read(4) != 0xC || + Stream.Read(4) != 0xE || + Stream.Read(4) != 0xD) + return error("Invalid bitcode signature"); + + // We expect a number of well-defined blocks, though we don't necessarily + // need to understand them all. + while (1) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + + case BitstreamEntry::SubBlock: + if (Entry.ID == bitc::MODULE_BLOCK_ID) + return parseModuleTriple(); + + // Ignore other sub-blocks. + if (Stream.SkipBlock()) + return error("Malformed block"); + continue; + + case BitstreamEntry::Record: + Stream.skipRecord(Entry.ID); + continue; + } + } +} + +/// Parse metadata attachments. +std::error_code BitcodeReader::parseMetadataAttachment(Function &F) { + if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID)) + return error("Invalid record"); + + SmallVector<uint64_t, 64> Record; + while (1) { + BitstreamEntry Entry = Stream.advanceSkippingSubblocks(); + + switch (Entry.Kind) { + case BitstreamEntry::SubBlock: // Handled for us already. + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + return std::error_code(); + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a metadata attachment record. + Record.clear(); + switch (Stream.readRecord(Entry.ID, Record)) { + default: // Default behavior: ignore. + break; + case bitc::METADATA_ATTACHMENT: { + unsigned RecordLength = Record.size(); + if (Record.empty()) + return error("Invalid record"); + if (RecordLength % 2 == 0) { + // A function attachment. + for (unsigned I = 0; I != RecordLength; I += 2) { + auto K = MDKindMap.find(Record[I]); + if (K == MDKindMap.end()) + return error("Invalid ID"); + Metadata *MD = MDValueList.getValueFwdRef(Record[I + 1]); + F.setMetadata(K->second, cast<MDNode>(MD)); + } + continue; + } + + // An instruction attachment. + Instruction *Inst = InstructionList[Record[0]]; + for (unsigned i = 1; i != RecordLength; i = i+2) { + unsigned Kind = Record[i]; + DenseMap<unsigned, unsigned>::iterator I = + MDKindMap.find(Kind); + if (I == MDKindMap.end()) + return error("Invalid ID"); + Metadata *Node = MDValueList.getValueFwdRef(Record[i + 1]); + if (isa<LocalAsMetadata>(Node)) + // Drop the attachment. This used to be legal, but there's no + // upgrade path. + break; + Inst->setMetadata(I->second, cast<MDNode>(Node)); + if (I->second == LLVMContext::MD_tbaa) + InstsWithTBAATag.push_back(Inst); + } + break; + } + } + } +} + +static std::error_code typeCheckLoadStoreInst(DiagnosticHandlerFunction DH, + Type *ValType, Type *PtrType) { + if (!isa<PointerType>(PtrType)) + return error(DH, "Load/Store operand is not a pointer type"); + Type *ElemType = cast<PointerType>(PtrType)->getElementType(); + + if (ValType && ValType != ElemType) + return error(DH, "Explicit load/store type does not match pointee type of " + "pointer operand"); + if (!PointerType::isLoadableOrStorableType(ElemType)) + return error(DH, "Cannot load/store from pointer"); + return std::error_code(); +} + +/// Lazily parse the specified function body block. +std::error_code BitcodeReader::parseFunctionBody(Function *F) { + if (Stream.EnterSubBlock(bitc::FUNCTION_BLOCK_ID)) + return error("Invalid record"); + + InstructionList.clear(); + unsigned ModuleValueListSize = ValueList.size(); + unsigned ModuleMDValueListSize = MDValueList.size(); + + // Add all the function arguments to the value table. + for(Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) + ValueList.push_back(I); + + unsigned NextValueNo = ValueList.size(); + BasicBlock *CurBB = nullptr; + unsigned CurBBNo = 0; + + DebugLoc LastLoc; + auto getLastInstruction = [&]() -> Instruction * { + if (CurBB && !CurBB->empty()) + return &CurBB->back(); + else if (CurBBNo && FunctionBBs[CurBBNo - 1] && + !FunctionBBs[CurBBNo - 1]->empty()) + return &FunctionBBs[CurBBNo - 1]->back(); + return nullptr; + }; + + // Read all the records. + SmallVector<uint64_t, 64> Record; + while (1) { + BitstreamEntry Entry = Stream.advance(); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return error("Malformed block"); + case BitstreamEntry::EndBlock: + goto OutOfRecordLoop; + + case BitstreamEntry::SubBlock: + switch (Entry.ID) { + default: // Skip unknown content. + if (Stream.SkipBlock()) + return error("Invalid record"); + break; + case bitc::CONSTANTS_BLOCK_ID: + if (std::error_code EC = parseConstants()) + return EC; + NextValueNo = ValueList.size(); + break; + case bitc::VALUE_SYMTAB_BLOCK_ID: + if (std::error_code EC = parseValueSymbolTable()) + return EC; + break; + case bitc::METADATA_ATTACHMENT_ID: + if (std::error_code EC = parseMetadataAttachment(*F)) + return EC; + break; + case bitc::METADATA_BLOCK_ID: + if (std::error_code EC = parseMetadata()) + return EC; + break; + case bitc::USELIST_BLOCK_ID: + if (std::error_code EC = parseUseLists()) + return EC; + break; + } + continue; + + case BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read a record. + Record.clear(); + Instruction *I = nullptr; + unsigned BitCode = Stream.readRecord(Entry.ID, Record); + switch (BitCode) { + default: // Default behavior: reject + return error("Invalid value"); + case bitc::FUNC_CODE_DECLAREBLOCKS: { // DECLAREBLOCKS: [nblocks] + if (Record.size() < 1 || Record[0] == 0) + return error("Invalid record"); + // Create all the basic blocks for the function. + FunctionBBs.resize(Record[0]); + + // See if anything took the address of blocks in this function. + auto BBFRI = BasicBlockFwdRefs.find(F); + if (BBFRI == BasicBlockFwdRefs.end()) { + for (unsigned i = 0, e = FunctionBBs.size(); i != e; ++i) + FunctionBBs[i] = BasicBlock::Create(Context, "", F); + } else { + auto &BBRefs = BBFRI->second; + // Check for invalid basic block references. + if (BBRefs.size() > FunctionBBs.size()) + return error("Invalid ID"); + assert(!BBRefs.empty() && "Unexpected empty array"); + assert(!BBRefs.front() && "Invalid reference to entry block"); + for (unsigned I = 0, E = FunctionBBs.size(), RE = BBRefs.size(); I != E; + ++I) + if (I < RE && BBRefs[I]) { + BBRefs[I]->insertInto(F); + FunctionBBs[I] = BBRefs[I]; + } else { + FunctionBBs[I] = BasicBlock::Create(Context, "", F); + } + + // Erase from the table. + BasicBlockFwdRefs.erase(BBFRI); + } + + CurBB = FunctionBBs[0]; + continue; + } + + case bitc::FUNC_CODE_DEBUG_LOC_AGAIN: // DEBUG_LOC_AGAIN + // This record indicates that the last instruction is at the same + // location as the previous instruction with a location. + I = getLastInstruction(); + + if (!I) + return error("Invalid record"); + I->setDebugLoc(LastLoc); + I = nullptr; + continue; + + case bitc::FUNC_CODE_DEBUG_LOC: { // DEBUG_LOC: [line, col, scope, ia] + I = getLastInstruction(); + if (!I || Record.size() < 4) + return error("Invalid record"); + + unsigned Line = Record[0], Col = Record[1]; + unsigned ScopeID = Record[2], IAID = Record[3]; + + MDNode *Scope = nullptr, *IA = nullptr; + if (ScopeID) Scope = cast<MDNode>(MDValueList.getValueFwdRef(ScopeID-1)); + if (IAID) IA = cast<MDNode>(MDValueList.getValueFwdRef(IAID-1)); + LastLoc = DebugLoc::get(Line, Col, Scope, IA); + I->setDebugLoc(LastLoc); + I = nullptr; + continue; + } + + case bitc::FUNC_CODE_INST_BINOP: { // BINOP: [opval, ty, opval, opcode] + unsigned OpNum = 0; + Value *LHS, *RHS; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || + OpNum+1 > Record.size()) + return error("Invalid record"); + + int Opc = getDecodedBinaryOpcode(Record[OpNum++], LHS->getType()); + if (Opc == -1) + return error("Invalid record"); + I = BinaryOperator::Create((Instruction::BinaryOps)Opc, LHS, RHS); + InstructionList.push_back(I); + if (OpNum < Record.size()) { + if (Opc == Instruction::Add || + Opc == Instruction::Sub || + Opc == Instruction::Mul || + Opc == Instruction::Shl) { + if (Record[OpNum] & (1 << bitc::OBO_NO_SIGNED_WRAP)) + cast<BinaryOperator>(I)->setHasNoSignedWrap(true); + if (Record[OpNum] & (1 << bitc::OBO_NO_UNSIGNED_WRAP)) + cast<BinaryOperator>(I)->setHasNoUnsignedWrap(true); + } else if (Opc == Instruction::SDiv || + Opc == Instruction::UDiv || + Opc == Instruction::LShr || + Opc == Instruction::AShr) { + if (Record[OpNum] & (1 << bitc::PEO_EXACT)) + cast<BinaryOperator>(I)->setIsExact(true); + } else if (isa<FPMathOperator>(I)) { + FastMathFlags FMF; + if (0 != (Record[OpNum] & FastMathFlags::UnsafeAlgebra)) + FMF.setUnsafeAlgebra(); + if (0 != (Record[OpNum] & FastMathFlags::NoNaNs)) + FMF.setNoNaNs(); + if (0 != (Record[OpNum] & FastMathFlags::NoInfs)) + FMF.setNoInfs(); + if (0 != (Record[OpNum] & FastMathFlags::NoSignedZeros)) + FMF.setNoSignedZeros(); + if (0 != (Record[OpNum] & FastMathFlags::AllowReciprocal)) + FMF.setAllowReciprocal(); + if (FMF.any()) + I->setFastMathFlags(FMF); + } + + } + break; + } + case bitc::FUNC_CODE_INST_CAST: { // CAST: [opval, opty, destty, castopc] + unsigned OpNum = 0; + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + OpNum+2 != Record.size()) + return error("Invalid record"); + + Type *ResTy = getTypeByID(Record[OpNum]); + int Opc = getDecodedCastOpcode(Record[OpNum + 1]); + if (Opc == -1 || !ResTy) + return error("Invalid record"); + Instruction *Temp = nullptr; + if ((I = UpgradeBitCastInst(Opc, Op, ResTy, Temp))) { + if (Temp) { + InstructionList.push_back(Temp); + CurBB->getInstList().push_back(Temp); + } + } else { + I = CastInst::Create((Instruction::CastOps)Opc, Op, ResTy); + } + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP_OLD: + case bitc::FUNC_CODE_INST_GEP: { // GEP: type, [n x operands] + unsigned OpNum = 0; + + Type *Ty; + bool InBounds; + + if (BitCode == bitc::FUNC_CODE_INST_GEP) { + InBounds = Record[OpNum++]; + Ty = getTypeByID(Record[OpNum++]); + } else { + InBounds = BitCode == bitc::FUNC_CODE_INST_INBOUNDS_GEP_OLD; + Ty = nullptr; + } + + Value *BasePtr; + if (getValueTypePair(Record, OpNum, NextValueNo, BasePtr)) + return error("Invalid record"); + + if (!Ty) + Ty = cast<SequentialType>(BasePtr->getType()->getScalarType()) + ->getElementType(); + else if (Ty != + cast<SequentialType>(BasePtr->getType()->getScalarType()) + ->getElementType()) + return error( + "Explicit gep type does not match pointee type of pointer operand"); + + SmallVector<Value*, 16> GEPIdx; + while (OpNum != Record.size()) { + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return error("Invalid record"); + GEPIdx.push_back(Op); + } + + I = GetElementPtrInst::Create(Ty, BasePtr, GEPIdx); + + InstructionList.push_back(I); + if (InBounds) + cast<GetElementPtrInst>(I)->setIsInBounds(true); + break; + } + + case bitc::FUNC_CODE_INST_EXTRACTVAL: { + // EXTRACTVAL: [opty, opval, n x indices] + unsigned OpNum = 0; + Value *Agg; + if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + return error("Invalid record"); + + unsigned RecSize = Record.size(); + if (OpNum == RecSize) + return error("EXTRACTVAL: Invalid instruction with 0 indices"); + + SmallVector<unsigned, 4> EXTRACTVALIdx; + Type *CurTy = Agg->getType(); + for (; OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); + uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return error("EXTRACTVAL: Invalid type"); + if ((unsigned)Index != Index) + return error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return error("EXTRACTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return error("EXTRACTVAL: Invalid array index"); + EXTRACTVALIdx.push_back((unsigned)Index); + + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; + } + + I = ExtractValueInst::Create(Agg, EXTRACTVALIdx); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_INSERTVAL: { + // INSERTVAL: [opty, opval, opty, opval, n x indices] + unsigned OpNum = 0; + Value *Agg; + if (getValueTypePair(Record, OpNum, NextValueNo, Agg)) + return error("Invalid record"); + Value *Val; + if (getValueTypePair(Record, OpNum, NextValueNo, Val)) + return error("Invalid record"); + + unsigned RecSize = Record.size(); + if (OpNum == RecSize) + return error("INSERTVAL: Invalid instruction with 0 indices"); + + SmallVector<unsigned, 4> INSERTVALIdx; + Type *CurTy = Agg->getType(); + for (; OpNum != RecSize; ++OpNum) { + bool IsArray = CurTy->isArrayTy(); + bool IsStruct = CurTy->isStructTy(); + uint64_t Index = Record[OpNum]; + + if (!IsStruct && !IsArray) + return error("INSERTVAL: Invalid type"); + if ((unsigned)Index != Index) + return error("Invalid value"); + if (IsStruct && Index >= CurTy->subtypes().size()) + return error("INSERTVAL: Invalid struct index"); + if (IsArray && Index >= CurTy->getArrayNumElements()) + return error("INSERTVAL: Invalid array index"); + + INSERTVALIdx.push_back((unsigned)Index); + if (IsStruct) + CurTy = CurTy->subtypes()[Index]; + else + CurTy = CurTy->subtypes()[0]; + } + + if (CurTy != Val->getType()) + return error("Inserted value type doesn't match aggregate type"); + + I = InsertValueInst::Create(Agg, Val, INSERTVALIdx); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_SELECT: { // SELECT: [opval, ty, opval, opval] + // obsolete form of select + // handles select i1 ... in old bitcode + unsigned OpNum = 0; + Value *TrueVal, *FalseVal, *Cond; + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || + popValue(Record, OpNum, NextValueNo, Type::getInt1Ty(Context), Cond)) + return error("Invalid record"); + + I = SelectInst::Create(Cond, TrueVal, FalseVal); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_VSELECT: {// VSELECT: [ty,opval,opval,predty,pred] + // new form of select + // handles select i1 or select [N x i1] + unsigned OpNum = 0; + Value *TrueVal, *FalseVal, *Cond; + if (getValueTypePair(Record, OpNum, NextValueNo, TrueVal) || + popValue(Record, OpNum, NextValueNo, TrueVal->getType(), FalseVal) || + getValueTypePair(Record, OpNum, NextValueNo, Cond)) + return error("Invalid record"); + + // select condition can be either i1 or [N x i1] + if (VectorType* vector_type = + dyn_cast<VectorType>(Cond->getType())) { + // expect <n x i1> + if (vector_type->getElementType() != Type::getInt1Ty(Context)) + return error("Invalid type for value"); + } else { + // expect i1 + if (Cond->getType() != Type::getInt1Ty(Context)) + return error("Invalid type for value"); + } + + I = SelectInst::Create(Cond, TrueVal, FalseVal); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_EXTRACTELT: { // EXTRACTELT: [opty, opval, opval] + unsigned OpNum = 0; + Value *Vec, *Idx; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec) || + getValueTypePair(Record, OpNum, NextValueNo, Idx)) + return error("Invalid record"); + if (!Vec->getType()->isVectorTy()) + return error("Invalid type for value"); + I = ExtractElementInst::Create(Vec, Idx); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_INSERTELT: { // INSERTELT: [ty, opval,opval,opval] + unsigned OpNum = 0; + Value *Vec, *Elt, *Idx; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec)) + return error("Invalid record"); + if (!Vec->getType()->isVectorTy()) + return error("Invalid type for value"); + if (popValue(Record, OpNum, NextValueNo, + cast<VectorType>(Vec->getType())->getElementType(), Elt) || + getValueTypePair(Record, OpNum, NextValueNo, Idx)) + return error("Invalid record"); + I = InsertElementInst::Create(Vec, Elt, Idx); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_SHUFFLEVEC: {// SHUFFLEVEC: [opval,ty,opval,opval] + unsigned OpNum = 0; + Value *Vec1, *Vec2, *Mask; + if (getValueTypePair(Record, OpNum, NextValueNo, Vec1) || + popValue(Record, OpNum, NextValueNo, Vec1->getType(), Vec2)) + return error("Invalid record"); + + if (getValueTypePair(Record, OpNum, NextValueNo, Mask)) + return error("Invalid record"); + if (!Vec1->getType()->isVectorTy() || !Vec2->getType()->isVectorTy()) + return error("Invalid type for value"); + I = new ShuffleVectorInst(Vec1, Vec2, Mask); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_CMP: // CMP: [opty, opval, opval, pred] + // Old form of ICmp/FCmp returning bool + // Existed to differentiate between icmp/fcmp and vicmp/vfcmp which were + // both legal on vectors but had different behaviour. + case bitc::FUNC_CODE_INST_CMP2: { // CMP2: [opty, opval, opval, pred] + // FCmp/ICmp returning bool or vector of bool + + unsigned OpNum = 0; + Value *LHS, *RHS; + if (getValueTypePair(Record, OpNum, NextValueNo, LHS) || + popValue(Record, OpNum, NextValueNo, LHS->getType(), RHS) || + OpNum+1 != Record.size()) + return error("Invalid record"); + + if (LHS->getType()->isFPOrFPVectorTy()) + I = new FCmpInst((FCmpInst::Predicate)Record[OpNum], LHS, RHS); + else + I = new ICmpInst((ICmpInst::Predicate)Record[OpNum], LHS, RHS); + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_RET: // RET: [opty,opval<optional>] + { + unsigned Size = Record.size(); + if (Size == 0) { + I = ReturnInst::Create(Context); + InstructionList.push_back(I); + break; + } + + unsigned OpNum = 0; + Value *Op = nullptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return error("Invalid record"); + if (OpNum != Record.size()) + return error("Invalid record"); + + I = ReturnInst::Create(Context, Op); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#] + if (Record.size() != 1 && Record.size() != 3) + return error("Invalid record"); + BasicBlock *TrueDest = getBasicBlock(Record[0]); + if (!TrueDest) + return error("Invalid record"); + + if (Record.size() == 1) { + I = BranchInst::Create(TrueDest); + InstructionList.push_back(I); + } + else { + BasicBlock *FalseDest = getBasicBlock(Record[1]); + Value *Cond = getValue(Record, 2, NextValueNo, + Type::getInt1Ty(Context)); + if (!FalseDest || !Cond) + return error("Invalid record"); + I = BranchInst::Create(TrueDest, FalseDest, Cond); + InstructionList.push_back(I); + } + break; + } + case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...] + // Check magic + if ((Record[0] >> 16) == SWITCH_INST_MAGIC) { + // "New" SwitchInst format with case ranges. The changes to write this + // format were reverted but we still recognize bitcode that uses it. + // Hopefully someday we will have support for case ranges and can use + // this format again. + + Type *OpTy = getTypeByID(Record[1]); + unsigned ValueBitWidth = cast<IntegerType>(OpTy)->getBitWidth(); + + Value *Cond = getValue(Record, 2, NextValueNo, OpTy); + BasicBlock *Default = getBasicBlock(Record[3]); + if (!OpTy || !Cond || !Default) + return error("Invalid record"); + + unsigned NumCases = Record[4]; + + SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); + InstructionList.push_back(SI); + + unsigned CurIdx = 5; + for (unsigned i = 0; i != NumCases; ++i) { + SmallVector<ConstantInt*, 1> CaseVals; + unsigned NumItems = Record[CurIdx++]; + for (unsigned ci = 0; ci != NumItems; ++ci) { + bool isSingleNumber = Record[CurIdx++]; + + APInt Low; + unsigned ActiveWords = 1; + if (ValueBitWidth > 64) + ActiveWords = Record[CurIdx++]; + Low = readWideAPInt(makeArrayRef(&Record[CurIdx], ActiveWords), + ValueBitWidth); + CurIdx += ActiveWords; + + if (!isSingleNumber) { + ActiveWords = 1; + if (ValueBitWidth > 64) + ActiveWords = Record[CurIdx++]; + APInt High = readWideAPInt( + makeArrayRef(&Record[CurIdx], ActiveWords), ValueBitWidth); + CurIdx += ActiveWords; + + // FIXME: It is not clear whether values in the range should be + // compared as signed or unsigned values. The partially + // implemented changes that used this format in the past used + // unsigned comparisons. + for ( ; Low.ule(High); ++Low) + CaseVals.push_back(ConstantInt::get(Context, Low)); + } else + CaseVals.push_back(ConstantInt::get(Context, Low)); + } + BasicBlock *DestBB = getBasicBlock(Record[CurIdx++]); + for (SmallVector<ConstantInt*, 1>::iterator cvi = CaseVals.begin(), + cve = CaseVals.end(); cvi != cve; ++cvi) + SI->addCase(*cvi, DestBB); + } + I = SI; + break; + } + + // Old SwitchInst format without case ranges. + + if (Record.size() < 3 || (Record.size() & 1) == 0) + return error("Invalid record"); + Type *OpTy = getTypeByID(Record[0]); + Value *Cond = getValue(Record, 1, NextValueNo, OpTy); + BasicBlock *Default = getBasicBlock(Record[2]); + if (!OpTy || !Cond || !Default) + return error("Invalid record"); + unsigned NumCases = (Record.size()-3)/2; + SwitchInst *SI = SwitchInst::Create(Cond, Default, NumCases); + InstructionList.push_back(SI); + for (unsigned i = 0, e = NumCases; i != e; ++i) { + ConstantInt *CaseVal = + dyn_cast_or_null<ConstantInt>(getFnValueByID(Record[3+i*2], OpTy)); + BasicBlock *DestBB = getBasicBlock(Record[1+3+i*2]); + if (!CaseVal || !DestBB) { + delete SI; + return error("Invalid record"); + } + SI->addCase(CaseVal, DestBB); + } + I = SI; + break; + } + case bitc::FUNC_CODE_INST_INDIRECTBR: { // INDIRECTBR: [opty, op0, op1, ...] + if (Record.size() < 2) + return error("Invalid record"); + Type *OpTy = getTypeByID(Record[0]); + Value *Address = getValue(Record, 1, NextValueNo, OpTy); + if (!OpTy || !Address) + return error("Invalid record"); + unsigned NumDests = Record.size()-2; + IndirectBrInst *IBI = IndirectBrInst::Create(Address, NumDests); + InstructionList.push_back(IBI); + for (unsigned i = 0, e = NumDests; i != e; ++i) { + if (BasicBlock *DestBB = getBasicBlock(Record[2+i])) { + IBI->addDestination(DestBB); + } else { + delete IBI; + return error("Invalid record"); + } + } + I = IBI; + break; + } + + case bitc::FUNC_CODE_INST_INVOKE: { + // INVOKE: [attrs, cc, normBB, unwindBB, fnty, op0,op1,op2, ...] + if (Record.size() < 4) + return error("Invalid record"); + unsigned OpNum = 0; + AttributeSet PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + BasicBlock *NormalBB = getBasicBlock(Record[OpNum++]); + BasicBlock *UnwindBB = getBasicBlock(Record[OpNum++]); + + FunctionType *FTy = nullptr; + if (CCInfo >> 13 & 1 && + !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])))) + return error("Explicit invoke type is not a function type"); + + Value *Callee; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + return error("Invalid record"); + + PointerType *CalleeTy = dyn_cast<PointerType>(Callee->getType()); + if (!CalleeTy) + return error("Callee is not a pointer"); + if (!FTy) { + FTy = dyn_cast<FunctionType>(CalleeTy->getElementType()); + if (!FTy) + return error("Callee is not of pointer to function type"); + } else if (CalleeTy->getElementType() != FTy) + return error("Explicit invoke type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return error("Insufficient operands to call"); + + SmallVector<Value*, 16> Ops; + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { + Ops.push_back(getValue(Record, OpNum, NextValueNo, + FTy->getParamType(i))); + if (!Ops.back()) + return error("Invalid record"); + } + + if (!FTy->isVarArg()) { + if (Record.size() != OpNum) + return error("Invalid record"); + } else { + // Read type/value pairs for varargs params. + while (OpNum != Record.size()) { + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return error("Invalid record"); + Ops.push_back(Op); + } + } + + I = InvokeInst::Create(Callee, NormalBB, UnwindBB, Ops); + InstructionList.push_back(I); + cast<InvokeInst>(I) + ->setCallingConv(static_cast<CallingConv::ID>(~(1U << 13) & CCInfo)); + cast<InvokeInst>(I)->setAttributes(PAL); + break; + } + case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval] + unsigned Idx = 0; + Value *Val = nullptr; + if (getValueTypePair(Record, Idx, NextValueNo, Val)) + return error("Invalid record"); + I = ResumeInst::Create(Val); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_UNREACHABLE: // UNREACHABLE + I = new UnreachableInst(Context); + InstructionList.push_back(I); + break; + case bitc::FUNC_CODE_INST_PHI: { // PHI: [ty, val0,bb0, ...] + if (Record.size() < 1 || ((Record.size()-1)&1)) + return error("Invalid record"); + Type *Ty = getTypeByID(Record[0]); + if (!Ty) + return error("Invalid record"); + + PHINode *PN = PHINode::Create(Ty, (Record.size()-1)/2); + InstructionList.push_back(PN); + + for (unsigned i = 0, e = Record.size()-1; i != e; i += 2) { + Value *V; + // With the new function encoding, it is possible that operands have + // negative IDs (for forward references). Use a signed VBR + // representation to keep the encoding small. + if (UseRelativeIDs) + V = getValueSigned(Record, 1+i, NextValueNo, Ty); + else + V = getValue(Record, 1+i, NextValueNo, Ty); + BasicBlock *BB = getBasicBlock(Record[2+i]); + if (!V || !BB) + return error("Invalid record"); + PN->addIncoming(V, BB); + } + I = PN; + break; + } + + case bitc::FUNC_CODE_INST_LANDINGPAD: + case bitc::FUNC_CODE_INST_LANDINGPAD_OLD: { + // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?] + unsigned Idx = 0; + if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD) { + if (Record.size() < 3) + return error("Invalid record"); + } else { + assert(BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD); + if (Record.size() < 4) + return error("Invalid record"); + } + Type *Ty = getTypeByID(Record[Idx++]); + if (!Ty) + return error("Invalid record"); + if (BitCode == bitc::FUNC_CODE_INST_LANDINGPAD_OLD) { + Value *PersFn = nullptr; + if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) + return error("Invalid record"); + + if (!F->hasPersonalityFn()) + F->setPersonalityFn(cast<Constant>(PersFn)); + else if (F->getPersonalityFn() != cast<Constant>(PersFn)) + return error("Personality function mismatch"); + } + + bool IsCleanup = !!Record[Idx++]; + unsigned NumClauses = Record[Idx++]; + LandingPadInst *LP = LandingPadInst::Create(Ty, NumClauses); + LP->setCleanup(IsCleanup); + for (unsigned J = 0; J != NumClauses; ++J) { + LandingPadInst::ClauseType CT = + LandingPadInst::ClauseType(Record[Idx++]); (void)CT; + Value *Val; + + if (getValueTypePair(Record, Idx, NextValueNo, Val)) { + delete LP; + return error("Invalid record"); + } + + assert((CT != LandingPadInst::Catch || + !isa<ArrayType>(Val->getType())) && + "Catch clause has a invalid type!"); + assert((CT != LandingPadInst::Filter || + isa<ArrayType>(Val->getType())) && + "Filter clause has invalid type!"); + LP->addClause(cast<Constant>(Val)); + } + + I = LP; + InstructionList.push_back(I); + break; + } + + case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] + if (Record.size() != 4) + return error("Invalid record"); + uint64_t AlignRecord = Record[3]; + const uint64_t InAllocaMask = uint64_t(1) << 5; + const uint64_t ExplicitTypeMask = uint64_t(1) << 6; + const uint64_t FlagMask = InAllocaMask | ExplicitTypeMask; + bool InAlloca = AlignRecord & InAllocaMask; + Type *Ty = getTypeByID(Record[0]); + if ((AlignRecord & ExplicitTypeMask) == 0) { + auto *PTy = dyn_cast_or_null<PointerType>(Ty); + if (!PTy) + return error("Old-style alloca with a non-pointer type"); + Ty = PTy->getElementType(); + } + Type *OpTy = getTypeByID(Record[1]); + Value *Size = getFnValueByID(Record[2], OpTy); + unsigned Align; + if (std::error_code EC = + parseAlignmentValue(AlignRecord & ~FlagMask, Align)) { + return EC; + } + if (!Ty || !Size) + return error("Invalid record"); + AllocaInst *AI = new AllocaInst(Ty, Size, Align); + AI->setUsedWithInAlloca(InAlloca); + I = AI; + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_LOAD: { // LOAD: [opty, op, align, vol] + unsigned OpNum = 0; + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + (OpNum + 2 != Record.size() && OpNum + 3 != Record.size())) + return error("Invalid record"); + + Type *Ty = nullptr; + if (OpNum + 3 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + if (std::error_code EC = + typeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType())) + return EC; + if (!Ty) + Ty = cast<PointerType>(Op->getType())->getElementType(); + + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Ty, Op, "", Record[OpNum + 1], Align); + + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_LOADATOMIC: { + // LOADATOMIC: [opty, op, align, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op) || + (OpNum + 4 != Record.size() && OpNum + 5 != Record.size())) + return error("Invalid record"); + + Type *Ty = nullptr; + if (OpNum + 5 == Record.size()) + Ty = getTypeByID(Record[OpNum++]); + if (std::error_code EC = + typeCheckLoadStoreInst(DiagnosticHandler, Ty, Op->getType())) + return EC; + if (!Ty) + Ty = cast<PointerType>(Op->getType())->getElementType(); + + AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); + if (Ordering == NotAtomic || Ordering == Release || + Ordering == AcquireRelease) + return error("Invalid record"); + if (Ordering != NotAtomic && Record[OpNum] == 0) + return error("Invalid record"); + SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); + + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new LoadInst(Op, "", Record[OpNum+1], Align, Ordering, SynchScope); + + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_STORE: + case bitc::FUNC_CODE_INST_STORE_OLD: { // STORE2:[ptrty, ptr, val, align, vol] + unsigned OpNum = 0; + Value *Val, *Ptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + (BitCode == bitc::FUNC_CODE_INST_STORE + ? getValueTypePair(Record, OpNum, NextValueNo, Val) + : popValue(Record, OpNum, NextValueNo, + cast<PointerType>(Ptr->getType())->getElementType(), + Val)) || + OpNum + 2 != Record.size()) + return error("Invalid record"); + + if (std::error_code EC = typeCheckLoadStoreInst( + DiagnosticHandler, Val->getType(), Ptr->getType())) + return EC; + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_STOREATOMIC: + case bitc::FUNC_CODE_INST_STOREATOMIC_OLD: { + // STOREATOMIC: [ptrty, ptr, val, align, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Val, *Ptr; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + (BitCode == bitc::FUNC_CODE_INST_STOREATOMIC + ? getValueTypePair(Record, OpNum, NextValueNo, Val) + : popValue(Record, OpNum, NextValueNo, + cast<PointerType>(Ptr->getType())->getElementType(), + Val)) || + OpNum + 4 != Record.size()) + return error("Invalid record"); + + if (std::error_code EC = typeCheckLoadStoreInst( + DiagnosticHandler, Val->getType(), Ptr->getType())) + return EC; + AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); + if (Ordering == NotAtomic || Ordering == Acquire || + Ordering == AcquireRelease) + return error("Invalid record"); + SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); + if (Ordering != NotAtomic && Record[OpNum] == 0) + return error("Invalid record"); + + unsigned Align; + if (std::error_code EC = parseAlignmentValue(Record[OpNum], Align)) + return EC; + I = new StoreInst(Val, Ptr, Record[OpNum+1], Align, Ordering, SynchScope); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CMPXCHG_OLD: + case bitc::FUNC_CODE_INST_CMPXCHG: { + // CMPXCHG:[ptrty, ptr, cmp, new, vol, successordering, synchscope, + // failureordering?, isweak?] + unsigned OpNum = 0; + Value *Ptr, *Cmp, *New; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + (BitCode == bitc::FUNC_CODE_INST_CMPXCHG + ? getValueTypePair(Record, OpNum, NextValueNo, Cmp) + : popValue(Record, OpNum, NextValueNo, + cast<PointerType>(Ptr->getType())->getElementType(), + Cmp)) || + popValue(Record, OpNum, NextValueNo, Cmp->getType(), New) || + Record.size() < OpNum + 3 || Record.size() > OpNum + 5) + return error("Invalid record"); + AtomicOrdering SuccessOrdering = getDecodedOrdering(Record[OpNum + 1]); + if (SuccessOrdering == NotAtomic || SuccessOrdering == Unordered) + return error("Invalid record"); + SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 2]); + + if (std::error_code EC = typeCheckLoadStoreInst( + DiagnosticHandler, Cmp->getType(), Ptr->getType())) + return EC; + AtomicOrdering FailureOrdering; + if (Record.size() < 7) + FailureOrdering = + AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrdering); + else + FailureOrdering = getDecodedOrdering(Record[OpNum + 3]); + + I = new AtomicCmpXchgInst(Ptr, Cmp, New, SuccessOrdering, FailureOrdering, + SynchScope); + cast<AtomicCmpXchgInst>(I)->setVolatile(Record[OpNum]); + + if (Record.size() < 8) { + // Before weak cmpxchgs existed, the instruction simply returned the + // value loaded from memory, so bitcode files from that era will be + // expecting the first component of a modern cmpxchg. + CurBB->getInstList().push_back(I); + I = ExtractValueInst::Create(I, 0); + } else { + cast<AtomicCmpXchgInst>(I)->setWeak(Record[OpNum+4]); + } + + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_ATOMICRMW: { + // ATOMICRMW:[ptrty, ptr, val, op, vol, ordering, synchscope] + unsigned OpNum = 0; + Value *Ptr, *Val; + if (getValueTypePair(Record, OpNum, NextValueNo, Ptr) || + popValue(Record, OpNum, NextValueNo, + cast<PointerType>(Ptr->getType())->getElementType(), Val) || + OpNum+4 != Record.size()) + return error("Invalid record"); + AtomicRMWInst::BinOp Operation = getDecodedRMWOperation(Record[OpNum]); + if (Operation < AtomicRMWInst::FIRST_BINOP || + Operation > AtomicRMWInst::LAST_BINOP) + return error("Invalid record"); + AtomicOrdering Ordering = getDecodedOrdering(Record[OpNum + 2]); + if (Ordering == NotAtomic || Ordering == Unordered) + return error("Invalid record"); + SynchronizationScope SynchScope = getDecodedSynchScope(Record[OpNum + 3]); + I = new AtomicRMWInst(Operation, Ptr, Val, Ordering, SynchScope); + cast<AtomicRMWInst>(I)->setVolatile(Record[OpNum+1]); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_FENCE: { // FENCE:[ordering, synchscope] + if (2 != Record.size()) + return error("Invalid record"); + AtomicOrdering Ordering = getDecodedOrdering(Record[0]); + if (Ordering == NotAtomic || Ordering == Unordered || + Ordering == Monotonic) + return error("Invalid record"); + SynchronizationScope SynchScope = getDecodedSynchScope(Record[1]); + I = new FenceInst(Context, Ordering, SynchScope); + InstructionList.push_back(I); + break; + } + case bitc::FUNC_CODE_INST_CALL: { + // CALL: [paramattrs, cc, fnty, fnid, arg0, arg1...] + if (Record.size() < 3) + return error("Invalid record"); + + unsigned OpNum = 0; + AttributeSet PAL = getAttributes(Record[OpNum++]); + unsigned CCInfo = Record[OpNum++]; + + FunctionType *FTy = nullptr; + if (CCInfo >> 15 & 1 && + !(FTy = dyn_cast<FunctionType>(getTypeByID(Record[OpNum++])))) + return error("Explicit call type is not a function type"); + + Value *Callee; + if (getValueTypePair(Record, OpNum, NextValueNo, Callee)) + return error("Invalid record"); + + PointerType *OpTy = dyn_cast<PointerType>(Callee->getType()); + if (!OpTy) + return error("Callee is not a pointer type"); + if (!FTy) { + FTy = dyn_cast<FunctionType>(OpTy->getElementType()); + if (!FTy) + return error("Callee is not of pointer to function type"); + } else if (OpTy->getElementType() != FTy) + return error("Explicit call type does not match pointee type of " + "callee operand"); + if (Record.size() < FTy->getNumParams() + OpNum) + return error("Insufficient operands to call"); + + SmallVector<Value*, 16> Args; + // Read the fixed params. + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i, ++OpNum) { + if (FTy->getParamType(i)->isLabelTy()) + Args.push_back(getBasicBlock(Record[OpNum])); + else + Args.push_back(getValue(Record, OpNum, NextValueNo, + FTy->getParamType(i))); + if (!Args.back()) + return error("Invalid record"); + } + + // Read type/value pairs for varargs params. + if (!FTy->isVarArg()) { + if (OpNum != Record.size()) + return error("Invalid record"); + } else { + while (OpNum != Record.size()) { + Value *Op; + if (getValueTypePair(Record, OpNum, NextValueNo, Op)) + return error("Invalid record"); + Args.push_back(Op); + } + } + + I = CallInst::Create(FTy, Callee, Args); + InstructionList.push_back(I); + cast<CallInst>(I)->setCallingConv( + static_cast<CallingConv::ID>((~(1U << 14) & CCInfo) >> 1)); + CallInst::TailCallKind TCK = CallInst::TCK_None; + if (CCInfo & 1) + TCK = CallInst::TCK_Tail; + if (CCInfo & (1 << 14)) + TCK = CallInst::TCK_MustTail; + cast<CallInst>(I)->setTailCallKind(TCK); + cast<CallInst>(I)->setAttributes(PAL); + break; + } + case bitc::FUNC_CODE_INST_VAARG: { // VAARG: [valistty, valist, instty] + if (Record.size() < 3) + return error("Invalid record"); + Type *OpTy = getTypeByID(Record[0]); + Value *Op = getValue(Record, 1, NextValueNo, OpTy); + Type *ResTy = getTypeByID(Record[2]); + if (!OpTy || !Op || !ResTy) + return error("Invalid record"); + I = new VAArgInst(Op, ResTy); + InstructionList.push_back(I); + break; + } + } + + // Add instruction to end of current BB. If there is no current BB, reject + // this file. + if (!CurBB) { + delete I; + return error("Invalid instruction with no BB"); + } + CurBB->getInstList().push_back(I); + + // If this was a terminator instruction, move to the next block. + if (isa<TerminatorInst>(I)) { + ++CurBBNo; + CurBB = CurBBNo < FunctionBBs.size() ? FunctionBBs[CurBBNo] : nullptr; + } + + // Non-void values get registered in the value table for future use. + if (I && !I->getType()->isVoidTy()) + ValueList.assignValue(I, NextValueNo++); + } + +OutOfRecordLoop: + + // Check the function list for unresolved values. + if (Argument *A = dyn_cast<Argument>(ValueList.back())) { + if (!A->getParent()) { + // We found at least one unresolved value. Nuke them all to avoid leaks. + for (unsigned i = ModuleValueListSize, e = ValueList.size(); i != e; ++i){ + if ((A = dyn_cast_or_null<Argument>(ValueList[i])) && !A->getParent()) { + A->replaceAllUsesWith(UndefValue::get(A->getType())); + delete A; + } + } + return error("Never resolved value found in function"); + } + } + + // FIXME: Check for unresolved forward-declared metadata references + // and clean up leaks. + + // Trim the value list down to the size it was before we parsed this function. + ValueList.shrinkTo(ModuleValueListSize); + MDValueList.shrinkTo(ModuleMDValueListSize); + std::vector<BasicBlock*>().swap(FunctionBBs); + return std::error_code(); +} + +/// Find the function body in the bitcode stream +std::error_code BitcodeReader::findFunctionInStream( + Function *F, + DenseMap<Function *, uint64_t>::iterator DeferredFunctionInfoIterator) { + while (DeferredFunctionInfoIterator->second == 0) { + if (Stream.AtEndOfStream()) + return error("Could not find function in stream"); + // ParseModule will parse the next body in the stream and set its + // position in the DeferredFunctionInfo map. + if (std::error_code EC = parseModule(true)) + return EC; + } + return std::error_code(); +} + +//===----------------------------------------------------------------------===// +// GVMaterializer implementation +//===----------------------------------------------------------------------===// + +void BitcodeReader::releaseBuffer() { Buffer.release(); } + +std::error_code BitcodeReader::materialize(GlobalValue *GV) { + if (std::error_code EC = materializeMetadata()) + return EC; + + Function *F = dyn_cast<Function>(GV); + // If it's not a function or is already material, ignore the request. + if (!F || !F->isMaterializable()) + return std::error_code(); + + DenseMap<Function*, uint64_t>::iterator DFII = DeferredFunctionInfo.find(F); + assert(DFII != DeferredFunctionInfo.end() && "Deferred function not found!"); + // If its position is recorded as 0, its body is somewhere in the stream + // but we haven't seen it yet. + if (DFII->second == 0 && IsStreamed) + if (std::error_code EC = findFunctionInStream(F, DFII)) + return EC; + + // Move the bit stream to the saved position of the deferred function body. + Stream.JumpToBit(DFII->second); + + if (std::error_code EC = parseFunctionBody(F)) + return EC; + F->setIsMaterializable(false); + + if (StripDebugInfo) + stripDebugInfo(*F); + + // Upgrade any old intrinsic calls in the function. + for (UpgradedIntrinsicMap::iterator I = UpgradedIntrinsics.begin(), + E = UpgradedIntrinsics.end(); I != E; ++I) { + if (I->first != I->second) { + for (auto UI = I->first->user_begin(), UE = I->first->user_end(); + UI != UE;) { + if (CallInst* CI = dyn_cast<CallInst>(*UI++)) + UpgradeIntrinsicCall(CI, I->second); + } + } + } + + // Bring in any functions that this function forward-referenced via + // blockaddresses. + return materializeForwardReferencedFunctions(); +} + +bool BitcodeReader::isDematerializable(const GlobalValue *GV) const { + const Function *F = dyn_cast<Function>(GV); + if (!F || F->isDeclaration()) + return false; + + // Dematerializing F would leave dangling references that wouldn't be + // reconnected on re-materialization. + if (BlockAddressesTaken.count(F)) + return false; + + return DeferredFunctionInfo.count(const_cast<Function*>(F)); +} + +void BitcodeReader::dematerialize(GlobalValue *GV) { + Function *F = dyn_cast<Function>(GV); + // If this function isn't dematerializable, this is a noop. + if (!F || !isDematerializable(F)) + return; + + assert(DeferredFunctionInfo.count(F) && "No info to read function later?"); + + // Just forget the function body, we can remat it later. + F->dropAllReferences(); + F->setIsMaterializable(true); +} + +std::error_code BitcodeReader::materializeModule(Module *M) { + assert(M == TheModule && + "Can only Materialize the Module this BitcodeReader is attached to."); + + if (std::error_code EC = materializeMetadata()) + return EC; + + // Promise to materialize all forward references. + WillMaterializeAllForwardRefs = true; + + // Iterate over the module, deserializing any functions that are still on + // disk. + for (Module::iterator F = TheModule->begin(), E = TheModule->end(); + F != E; ++F) { + if (std::error_code EC = materialize(F)) + return EC; + } + // At this point, if there are any function bodies, the current bit is + // pointing to the END_BLOCK record after them. Now make sure the rest + // of the bits in the module have been read. + if (NextUnreadBit) + parseModule(true); + + // Check that all block address forward references got resolved (as we + // promised above). + if (!BasicBlockFwdRefs.empty()) + return error("Never resolved function from blockaddress"); + + // Upgrade any intrinsic calls that slipped through (should not happen!) and + // delete the old functions to clean up. We can't do this unless the entire + // module is materialized because there could always be another function body + // with calls to the old function. + for (std::vector<std::pair<Function*, Function*> >::iterator I = + UpgradedIntrinsics.begin(), E = UpgradedIntrinsics.end(); I != E; ++I) { + if (I->first != I->second) { + for (auto UI = I->first->user_begin(), UE = I->first->user_end(); + UI != UE;) { + if (CallInst* CI = dyn_cast<CallInst>(*UI++)) + UpgradeIntrinsicCall(CI, I->second); + } + if (!I->first->use_empty()) + I->first->replaceAllUsesWith(I->second); + I->first->eraseFromParent(); + } + } + std::vector<std::pair<Function*, Function*> >().swap(UpgradedIntrinsics); + + for (unsigned I = 0, E = InstsWithTBAATag.size(); I < E; I++) + UpgradeInstWithTBAATag(InstsWithTBAATag[I]); + + UpgradeDebugInfo(*M); + return std::error_code(); +} + +std::vector<StructType *> BitcodeReader::getIdentifiedStructTypes() const { + return IdentifiedStructTypes; +} + +std::error_code +BitcodeReader::initStream(std::unique_ptr<DataStreamer> Streamer) { + if (Streamer) + return initLazyStream(std::move(Streamer)); + return initStreamFromBuffer(); +} + +std::error_code BitcodeReader::initStreamFromBuffer() { + const unsigned char *BufPtr = (const unsigned char*)Buffer->getBufferStart(); + const unsigned char *BufEnd = BufPtr+Buffer->getBufferSize(); + + if (Buffer->getBufferSize() & 3) + return error("Invalid bitcode signature"); + + // If we have a wrapper header, parse it and ignore the non-bc file contents. + // The magic number is 0x0B17C0DE stored in little endian. + if (isBitcodeWrapper(BufPtr, BufEnd)) + if (SkipBitcodeWrapperHeader(BufPtr, BufEnd, true)) + return error("Invalid bitcode wrapper header"); + + StreamFile.reset(new BitstreamReader(BufPtr, BufEnd)); + Stream.init(&*StreamFile); + + return std::error_code(); +} + +std::error_code +BitcodeReader::initLazyStream(std::unique_ptr<DataStreamer> Streamer) { + // Check and strip off the bitcode wrapper; BitstreamReader expects never to + // see it. + auto OwnedBytes = + llvm::make_unique<StreamingMemoryObject>(std::move(Streamer)); + StreamingMemoryObject &Bytes = *OwnedBytes; + StreamFile = llvm::make_unique<BitstreamReader>(std::move(OwnedBytes)); + Stream.init(&*StreamFile); + + unsigned char buf[16]; + if (Bytes.readBytes(buf, 16, 0) != 16) + return error("Invalid bitcode signature"); + + if (!isBitcode(buf, buf + 16)) + return error("Invalid bitcode signature"); + + if (isBitcodeWrapper(buf, buf + 4)) { + const unsigned char *bitcodeStart = buf; + const unsigned char *bitcodeEnd = buf + 16; + SkipBitcodeWrapperHeader(bitcodeStart, bitcodeEnd, false); + Bytes.dropLeadingBytes(bitcodeStart - buf); + Bytes.setKnownObjectSize(bitcodeEnd - bitcodeStart); + } + return std::error_code(); +} + +namespace { +class BitcodeErrorCategoryType : public std::error_category { + const char *name() const LLVM_NOEXCEPT override { + return "llvm.bitcode"; + } + std::string message(int IE) const override { + BitcodeError E = static_cast<BitcodeError>(IE); + switch (E) { + case BitcodeError::InvalidBitcodeSignature: + return "Invalid bitcode signature"; + case BitcodeError::CorruptedBitcode: + return "Corrupted bitcode"; + } + llvm_unreachable("Unknown error type!"); + } +}; +} // namespace + +static ManagedStatic<BitcodeErrorCategoryType> ErrorCategory; + +const std::error_category &llvm::BitcodeErrorCategory() { + return *ErrorCategory; +} + +//===----------------------------------------------------------------------===// +// External interface +//===----------------------------------------------------------------------===// + +static ErrorOr<std::unique_ptr<Module>> +getBitcodeModuleImpl(std::unique_ptr<DataStreamer> Streamer, StringRef Name, + BitcodeReader *R, LLVMContext &Context, + bool MaterializeAll, bool ShouldLazyLoadMetadata) { + std::unique_ptr<Module> M = make_unique<Module>(Name, Context); + M->setMaterializer(R); + + auto cleanupOnError = [&](std::error_code EC) { + R->releaseBuffer(); // Never take ownership on error. + return EC; + }; + + // Delay parsing Metadata if ShouldLazyLoadMetadata is true. + if (std::error_code EC = R->parseBitcodeInto(std::move(Streamer), M.get(), + ShouldLazyLoadMetadata)) + return cleanupOnError(EC); + + if (MaterializeAll) { + // Read in the entire module, and destroy the BitcodeReader. + if (std::error_code EC = M->materializeAllPermanently()) + return cleanupOnError(EC); + } else { + // Resolve forward references from blockaddresses. + if (std::error_code EC = R->materializeForwardReferencedFunctions()) + return cleanupOnError(EC); + } + return std::move(M); +} + +/// \brief Get a lazy one-at-time loading module from bitcode. +/// +/// This isn't always used in a lazy context. In particular, it's also used by +/// \a parseBitcodeFile(). If this is truly lazy, then we need to eagerly pull +/// in forward-referenced functions from block address references. +/// +/// \param[in] MaterializeAll Set to \c true if we should materialize +/// everything. +static ErrorOr<std::unique_ptr<Module>> +getLazyBitcodeModuleImpl(std::unique_ptr<MemoryBuffer> &&Buffer, + LLVMContext &Context, bool MaterializeAll, + DiagnosticHandlerFunction DiagnosticHandler, + bool ShouldLazyLoadMetadata = false) { + BitcodeReader *R = + new BitcodeReader(Buffer.get(), Context, DiagnosticHandler); + + ErrorOr<std::unique_ptr<Module>> Ret = + getBitcodeModuleImpl(nullptr, Buffer->getBufferIdentifier(), R, Context, + MaterializeAll, ShouldLazyLoadMetadata); + if (!Ret) + return Ret; + + Buffer.release(); // The BitcodeReader owns it now. + return Ret; +} + +ErrorOr<std::unique_ptr<Module>> llvm::getLazyBitcodeModule( + std::unique_ptr<MemoryBuffer> &&Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler, bool ShouldLazyLoadMetadata) { + return getLazyBitcodeModuleImpl(std::move(Buffer), Context, false, + DiagnosticHandler, ShouldLazyLoadMetadata); +} + +ErrorOr<std::unique_ptr<Module>> llvm::getStreamedBitcodeModule( + StringRef Name, std::unique_ptr<DataStreamer> Streamer, + LLVMContext &Context, DiagnosticHandlerFunction DiagnosticHandler) { + std::unique_ptr<Module> M = make_unique<Module>(Name, Context); + BitcodeReader *R = new BitcodeReader(Context, DiagnosticHandler); + + return getBitcodeModuleImpl(std::move(Streamer), Name, R, Context, false, + false); +} + +ErrorOr<std::unique_ptr<Module>> +llvm::parseBitcodeFile(MemoryBufferRef Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler) { + std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false); + return getLazyBitcodeModuleImpl(std::move(Buf), Context, true, + DiagnosticHandler); + // TODO: Restore the use-lists to the in-memory state when the bitcode was + // written. We must defer until the Module has been fully materialized. +} + +std::string +llvm::getBitcodeTargetTriple(MemoryBufferRef Buffer, LLVMContext &Context, + DiagnosticHandlerFunction DiagnosticHandler) { + std::unique_ptr<MemoryBuffer> Buf = MemoryBuffer::getMemBuffer(Buffer, false); + auto R = llvm::make_unique<BitcodeReader>(Buf.release(), Context, + DiagnosticHandler); + ErrorOr<std::string> Triple = R->parseTriple(); + if (Triple.getError()) + return ""; + return Triple.get(); +} diff --git a/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp b/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp new file mode 100644 index 0000000..a103fbd --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Reader/BitstreamReader.cpp @@ -0,0 +1,361 @@ +//===- BitstreamReader.cpp - BitstreamReader implementation ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitstreamReader.h" + +using namespace llvm; + +//===----------------------------------------------------------------------===// +// BitstreamCursor implementation +//===----------------------------------------------------------------------===// + +void BitstreamCursor::freeState() { + // Free all the Abbrevs. + CurAbbrevs.clear(); + + // Free all the Abbrevs in the block scope. + BlockScope.clear(); +} + +/// EnterSubBlock - Having read the ENTER_SUBBLOCK abbrevid, enter +/// the block, and return true if the block has an error. +bool BitstreamCursor::EnterSubBlock(unsigned BlockID, unsigned *NumWordsP) { + // Save the current block's state on BlockScope. + BlockScope.push_back(Block(CurCodeSize)); + BlockScope.back().PrevAbbrevs.swap(CurAbbrevs); + + // Add the abbrevs specific to this block to the CurAbbrevs list. + if (const BitstreamReader::BlockInfo *Info = + BitStream->getBlockInfo(BlockID)) { + CurAbbrevs.insert(CurAbbrevs.end(), Info->Abbrevs.begin(), + Info->Abbrevs.end()); + } + + // Get the codesize of this block. + CurCodeSize = ReadVBR(bitc::CodeLenWidth); + // We can't read more than MaxChunkSize at a time + if (CurCodeSize > MaxChunkSize) + return true; + + SkipToFourByteBoundary(); + unsigned NumWords = Read(bitc::BlockSizeWidth); + if (NumWordsP) *NumWordsP = NumWords; + + // Validate that this block is sane. + return CurCodeSize == 0 || AtEndOfStream(); +} + +static uint64_t readAbbreviatedField(BitstreamCursor &Cursor, + const BitCodeAbbrevOp &Op) { + assert(!Op.isLiteral() && "Not to be used with literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + llvm_unreachable("Should not reach here"); + case BitCodeAbbrevOp::Fixed: + assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); + return Cursor.Read((unsigned)Op.getEncodingData()); + case BitCodeAbbrevOp::VBR: + assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); + return Cursor.ReadVBR64((unsigned)Op.getEncodingData()); + case BitCodeAbbrevOp::Char6: + return BitCodeAbbrevOp::DecodeChar6(Cursor.Read(6)); + } + llvm_unreachable("invalid abbreviation encoding"); +} + +static void skipAbbreviatedField(BitstreamCursor &Cursor, + const BitCodeAbbrevOp &Op) { + assert(!Op.isLiteral() && "Not to be used with literals!"); + + // Decode the value as we are commanded. + switch (Op.getEncoding()) { + case BitCodeAbbrevOp::Array: + case BitCodeAbbrevOp::Blob: + llvm_unreachable("Should not reach here"); + case BitCodeAbbrevOp::Fixed: + assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); + Cursor.Read((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::VBR: + assert((unsigned)Op.getEncodingData() <= Cursor.MaxChunkSize); + Cursor.ReadVBR64((unsigned)Op.getEncodingData()); + break; + case BitCodeAbbrevOp::Char6: + Cursor.Read(6); + break; + } +} + + + +/// skipRecord - Read the current record and discard it. +void BitstreamCursor::skipRecord(unsigned AbbrevID) { + // Skip unabbreviated records by reading past their entries. + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + (void)Code; + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + (void)ReadVBR64(6); + return; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + for (unsigned i = 0, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) + continue; + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + skipAbbreviatedField(*this, Op); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + assert(i+2 == e && "array op not second to last?"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + + // Read all the elements. + for (; NumElts; --NumElts) + skipAbbreviatedField(*this, EltEnc); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t NewEnd = GetCurrentBitNo()+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Skip over the blob. + JumpToBit(NewEnd); + } +} + +unsigned BitstreamCursor::readRecord(unsigned AbbrevID, + SmallVectorImpl<uint64_t> &Vals, + StringRef *Blob) { + if (AbbrevID == bitc::UNABBREV_RECORD) { + unsigned Code = ReadVBR(6); + unsigned NumElts = ReadVBR(6); + for (unsigned i = 0; i != NumElts; ++i) + Vals.push_back(ReadVBR64(6)); + return Code; + } + + const BitCodeAbbrev *Abbv = getAbbrev(AbbrevID); + + // Read the record code first. + assert(Abbv->getNumOperandInfos() != 0 && "no record code in abbreviation?"); + const BitCodeAbbrevOp &CodeOp = Abbv->getOperandInfo(0); + unsigned Code; + if (CodeOp.isLiteral()) + Code = CodeOp.getLiteralValue(); + else { + if (CodeOp.getEncoding() == BitCodeAbbrevOp::Array || + CodeOp.getEncoding() == BitCodeAbbrevOp::Blob) + report_fatal_error("Abbreviation starts with an Array or a Blob"); + Code = readAbbreviatedField(*this, CodeOp); + } + + for (unsigned i = 1, e = Abbv->getNumOperandInfos(); i != e; ++i) { + const BitCodeAbbrevOp &Op = Abbv->getOperandInfo(i); + if (Op.isLiteral()) { + Vals.push_back(Op.getLiteralValue()); + continue; + } + + if (Op.getEncoding() != BitCodeAbbrevOp::Array && + Op.getEncoding() != BitCodeAbbrevOp::Blob) { + Vals.push_back(readAbbreviatedField(*this, Op)); + continue; + } + + if (Op.getEncoding() == BitCodeAbbrevOp::Array) { + // Array case. Read the number of elements as a vbr6. + unsigned NumElts = ReadVBR(6); + + // Get the element encoding. + if (i + 2 != e) + report_fatal_error("Array op not second to last"); + const BitCodeAbbrevOp &EltEnc = Abbv->getOperandInfo(++i); + if (!EltEnc.isEncoding()) + report_fatal_error( + "Array element type has to be an encoding of a type"); + if (EltEnc.getEncoding() == BitCodeAbbrevOp::Array || + EltEnc.getEncoding() == BitCodeAbbrevOp::Blob) + report_fatal_error("Array element type can't be an Array or a Blob"); + + // Read all the elements. + for (; NumElts; --NumElts) + Vals.push_back(readAbbreviatedField(*this, EltEnc)); + continue; + } + + assert(Op.getEncoding() == BitCodeAbbrevOp::Blob); + // Blob case. Read the number of bytes as a vbr6. + unsigned NumElts = ReadVBR(6); + SkipToFourByteBoundary(); // 32-bit alignment + + // Figure out where the end of this blob will be including tail padding. + size_t CurBitPos = GetCurrentBitNo(); + size_t NewEnd = CurBitPos+((NumElts+3)&~3)*8; + + // If this would read off the end of the bitcode file, just set the + // record to empty and return. + if (!canSkipToPos(NewEnd/8)) { + Vals.append(NumElts, 0); + NextChar = BitStream->getBitcodeBytes().getExtent(); + break; + } + + // Otherwise, inform the streamer that we need these bytes in memory. + const char *Ptr = (const char*) + BitStream->getBitcodeBytes().getPointer(CurBitPos/8, NumElts); + + // If we can return a reference to the data, do so to avoid copying it. + if (Blob) { + *Blob = StringRef(Ptr, NumElts); + } else { + // Otherwise, unpack into Vals with zero extension. + for (; NumElts; --NumElts) + Vals.push_back((unsigned char)*Ptr++); + } + // Skip over tail padding. + JumpToBit(NewEnd); + } + + return Code; +} + + +void BitstreamCursor::ReadAbbrevRecord() { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + unsigned NumOpInfo = ReadVBR(5); + for (unsigned i = 0; i != NumOpInfo; ++i) { + bool IsLiteral = Read(1); + if (IsLiteral) { + Abbv->Add(BitCodeAbbrevOp(ReadVBR64(8))); + continue; + } + + BitCodeAbbrevOp::Encoding E = (BitCodeAbbrevOp::Encoding)Read(3); + if (BitCodeAbbrevOp::hasEncodingData(E)) { + uint64_t Data = ReadVBR64(5); + + // As a special case, handle fixed(0) (i.e., a fixed field with zero bits) + // and vbr(0) as a literal zero. This is decoded the same way, and avoids + // a slow path in Read() to have to handle reading zero bits. + if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) && + Data == 0) { + Abbv->Add(BitCodeAbbrevOp(0)); + continue; + } + + if ((E == BitCodeAbbrevOp::Fixed || E == BitCodeAbbrevOp::VBR) && + Data > MaxChunkSize) + report_fatal_error( + "Fixed or VBR abbrev record with size > MaxChunkData"); + + Abbv->Add(BitCodeAbbrevOp(E, Data)); + } else + Abbv->Add(BitCodeAbbrevOp(E)); + } + + if (Abbv->getNumOperandInfos() == 0) + report_fatal_error("Abbrev record with no operands"); + CurAbbrevs.push_back(Abbv); +} + +bool BitstreamCursor::ReadBlockInfoBlock() { + // If this is the second stream to get to the block info block, skip it. + if (BitStream->hasBlockInfoRecords()) + return SkipBlock(); + + if (EnterSubBlock(bitc::BLOCKINFO_BLOCK_ID)) return true; + + SmallVector<uint64_t, 64> Record; + BitstreamReader::BlockInfo *CurBlockInfo = nullptr; + + // Read all the records for this module. + while (1) { + BitstreamEntry Entry = advanceSkippingSubblocks(AF_DontAutoprocessAbbrevs); + + switch (Entry.Kind) { + case llvm::BitstreamEntry::SubBlock: // Handled for us already. + case llvm::BitstreamEntry::Error: + return true; + case llvm::BitstreamEntry::EndBlock: + return false; + case llvm::BitstreamEntry::Record: + // The interesting case. + break; + } + + // Read abbrev records, associate them with CurBID. + if (Entry.ID == bitc::DEFINE_ABBREV) { + if (!CurBlockInfo) return true; + ReadAbbrevRecord(); + + // ReadAbbrevRecord installs the abbrev in CurAbbrevs. Move it to the + // appropriate BlockInfo. + CurBlockInfo->Abbrevs.push_back(std::move(CurAbbrevs.back())); + CurAbbrevs.pop_back(); + continue; + } + + // Read a record. + Record.clear(); + switch (readRecord(Entry.ID, Record)) { + default: break; // Default behavior, ignore unknown content. + case bitc::BLOCKINFO_CODE_SETBID: + if (Record.size() < 1) return true; + CurBlockInfo = &BitStream->getOrCreateBlockInfo((unsigned)Record[0]); + break; + case bitc::BLOCKINFO_CODE_BLOCKNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 0, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->Name = Name; + break; + } + case bitc::BLOCKINFO_CODE_SETRECORDNAME: { + if (!CurBlockInfo) return true; + if (BitStream->isIgnoringBlockInfoNames()) break; // Ignore name. + std::string Name; + for (unsigned i = 1, e = Record.size(); i != e; ++i) + Name += (char)Record[i]; + CurBlockInfo->RecordNames.push_back(std::make_pair((unsigned)Record[0], + Name)); + break; + } + } + } +} + diff --git a/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp new file mode 100644 index 0000000..7218ea0 --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp @@ -0,0 +1,49 @@ +//===-- BitWriter.cpp -----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/BitWriter.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/raw_ostream.h" +using namespace llvm; + + +/*===-- Operations on modules ---------------------------------------------===*/ + +int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) { + std::error_code EC; + raw_fd_ostream OS(Path, EC, sys::fs::F_None); + + if (EC) + return -1; + + WriteBitcodeToFile(unwrap(M), OS); + return 0; +} + +int LLVMWriteBitcodeToFD(LLVMModuleRef M, int FD, int ShouldClose, + int Unbuffered) { + raw_fd_ostream OS(FD, ShouldClose, Unbuffered); + + WriteBitcodeToFile(unwrap(M), OS); + return 0; +} + +int LLVMWriteBitcodeToFileHandle(LLVMModuleRef M, int FileHandle) { + return LLVMWriteBitcodeToFD(M, FileHandle, true, false); +} + +LLVMMemoryBufferRef LLVMWriteBitcodeToMemoryBuffer(LLVMModuleRef M) { + std::string Data; + raw_string_ostream OS(Data); + + WriteBitcodeToFile(unwrap(M), OS); + return wrap(MemoryBuffer::getMemBufferCopy(OS.str()).release()); +} diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp new file mode 100644 index 0000000..e79eeb0 --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -0,0 +1,2493 @@ +//===--- Bitcode/Writer/BitcodeWriter.cpp - Bitcode Writer ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Bitcode writer implementation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/ReaderWriter.h" +#include "ValueEnumerator.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Bitcode/BitstreamWriter.h" +#include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/InlineAsm.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Operator.h" +#include "llvm/IR/UseListOrder.h" +#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" +#include <cctype> +#include <map> +using namespace llvm; + +/// These are manifest constants used by the bitcode writer. They do not need to +/// be kept in sync with the reader, but need to be consistent within this file. +enum { + // VALUE_SYMTAB_BLOCK abbrev id's. + VST_ENTRY_8_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + VST_ENTRY_7_ABBREV, + VST_ENTRY_6_ABBREV, + VST_BBENTRY_6_ABBREV, + + // CONSTANTS_BLOCK abbrev id's. + CONSTANTS_SETTYPE_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + CONSTANTS_INTEGER_ABBREV, + CONSTANTS_CE_CAST_Abbrev, + CONSTANTS_NULL_Abbrev, + + // FUNCTION_BLOCK abbrev id's. + FUNCTION_INST_LOAD_ABBREV = bitc::FIRST_APPLICATION_ABBREV, + FUNCTION_INST_BINOP_ABBREV, + FUNCTION_INST_BINOP_FLAGS_ABBREV, + FUNCTION_INST_CAST_ABBREV, + FUNCTION_INST_RET_VOID_ABBREV, + FUNCTION_INST_RET_VAL_ABBREV, + FUNCTION_INST_UNREACHABLE_ABBREV, + FUNCTION_INST_GEP_ABBREV, +}; + +static unsigned GetEncodedCastOpcode(unsigned Opcode) { + switch (Opcode) { + default: llvm_unreachable("Unknown cast instruction!"); + case Instruction::Trunc : return bitc::CAST_TRUNC; + case Instruction::ZExt : return bitc::CAST_ZEXT; + case Instruction::SExt : return bitc::CAST_SEXT; + case Instruction::FPToUI : return bitc::CAST_FPTOUI; + case Instruction::FPToSI : return bitc::CAST_FPTOSI; + case Instruction::UIToFP : return bitc::CAST_UITOFP; + case Instruction::SIToFP : return bitc::CAST_SITOFP; + case Instruction::FPTrunc : return bitc::CAST_FPTRUNC; + case Instruction::FPExt : return bitc::CAST_FPEXT; + case Instruction::PtrToInt: return bitc::CAST_PTRTOINT; + case Instruction::IntToPtr: return bitc::CAST_INTTOPTR; + case Instruction::BitCast : return bitc::CAST_BITCAST; + case Instruction::AddrSpaceCast: return bitc::CAST_ADDRSPACECAST; + } +} + +static unsigned GetEncodedBinaryOpcode(unsigned Opcode) { + switch (Opcode) { + default: llvm_unreachable("Unknown binary instruction!"); + case Instruction::Add: + case Instruction::FAdd: return bitc::BINOP_ADD; + case Instruction::Sub: + case Instruction::FSub: return bitc::BINOP_SUB; + case Instruction::Mul: + case Instruction::FMul: return bitc::BINOP_MUL; + case Instruction::UDiv: return bitc::BINOP_UDIV; + case Instruction::FDiv: + case Instruction::SDiv: return bitc::BINOP_SDIV; + case Instruction::URem: return bitc::BINOP_UREM; + case Instruction::FRem: + case Instruction::SRem: return bitc::BINOP_SREM; + case Instruction::Shl: return bitc::BINOP_SHL; + case Instruction::LShr: return bitc::BINOP_LSHR; + case Instruction::AShr: return bitc::BINOP_ASHR; + case Instruction::And: return bitc::BINOP_AND; + case Instruction::Or: return bitc::BINOP_OR; + case Instruction::Xor: return bitc::BINOP_XOR; + } +} + +static unsigned GetEncodedRMWOperation(AtomicRMWInst::BinOp Op) { + switch (Op) { + default: llvm_unreachable("Unknown RMW operation!"); + case AtomicRMWInst::Xchg: return bitc::RMW_XCHG; + case AtomicRMWInst::Add: return bitc::RMW_ADD; + case AtomicRMWInst::Sub: return bitc::RMW_SUB; + case AtomicRMWInst::And: return bitc::RMW_AND; + case AtomicRMWInst::Nand: return bitc::RMW_NAND; + case AtomicRMWInst::Or: return bitc::RMW_OR; + case AtomicRMWInst::Xor: return bitc::RMW_XOR; + case AtomicRMWInst::Max: return bitc::RMW_MAX; + case AtomicRMWInst::Min: return bitc::RMW_MIN; + case AtomicRMWInst::UMax: return bitc::RMW_UMAX; + case AtomicRMWInst::UMin: return bitc::RMW_UMIN; + } +} + +static unsigned GetEncodedOrdering(AtomicOrdering Ordering) { + switch (Ordering) { + case NotAtomic: return bitc::ORDERING_NOTATOMIC; + case Unordered: return bitc::ORDERING_UNORDERED; + case Monotonic: return bitc::ORDERING_MONOTONIC; + case Acquire: return bitc::ORDERING_ACQUIRE; + case Release: return bitc::ORDERING_RELEASE; + case AcquireRelease: return bitc::ORDERING_ACQREL; + case SequentiallyConsistent: return bitc::ORDERING_SEQCST; + } + llvm_unreachable("Invalid ordering"); +} + +static unsigned GetEncodedSynchScope(SynchronizationScope SynchScope) { + switch (SynchScope) { + case SingleThread: return bitc::SYNCHSCOPE_SINGLETHREAD; + case CrossThread: return bitc::SYNCHSCOPE_CROSSTHREAD; + } + llvm_unreachable("Invalid synch scope"); +} + +static void WriteStringRecord(unsigned Code, StringRef Str, + unsigned AbbrevToUse, BitstreamWriter &Stream) { + SmallVector<unsigned, 64> Vals; + + // Code: [strchar x N] + for (unsigned i = 0, e = Str.size(); i != e; ++i) { + if (AbbrevToUse && !BitCodeAbbrevOp::isChar6(Str[i])) + AbbrevToUse = 0; + Vals.push_back(Str[i]); + } + + // Emit the finished record. + Stream.EmitRecord(Code, Vals, AbbrevToUse); +} + +static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) { + switch (Kind) { + case Attribute::Alignment: + return bitc::ATTR_KIND_ALIGNMENT; + case Attribute::AlwaysInline: + return bitc::ATTR_KIND_ALWAYS_INLINE; + case Attribute::Builtin: + return bitc::ATTR_KIND_BUILTIN; + case Attribute::ByVal: + return bitc::ATTR_KIND_BY_VAL; + case Attribute::Convergent: + return bitc::ATTR_KIND_CONVERGENT; + case Attribute::InAlloca: + return bitc::ATTR_KIND_IN_ALLOCA; + case Attribute::Cold: + return bitc::ATTR_KIND_COLD; + case Attribute::InlineHint: + return bitc::ATTR_KIND_INLINE_HINT; + case Attribute::InReg: + return bitc::ATTR_KIND_IN_REG; + case Attribute::JumpTable: + return bitc::ATTR_KIND_JUMP_TABLE; + case Attribute::MinSize: + return bitc::ATTR_KIND_MIN_SIZE; + case Attribute::Naked: + return bitc::ATTR_KIND_NAKED; + case Attribute::Nest: + return bitc::ATTR_KIND_NEST; + case Attribute::NoAlias: + return bitc::ATTR_KIND_NO_ALIAS; + case Attribute::NoBuiltin: + return bitc::ATTR_KIND_NO_BUILTIN; + case Attribute::NoCapture: + return bitc::ATTR_KIND_NO_CAPTURE; + case Attribute::NoDuplicate: + return bitc::ATTR_KIND_NO_DUPLICATE; + case Attribute::NoImplicitFloat: + return bitc::ATTR_KIND_NO_IMPLICIT_FLOAT; + case Attribute::NoInline: + return bitc::ATTR_KIND_NO_INLINE; + case Attribute::NonLazyBind: + return bitc::ATTR_KIND_NON_LAZY_BIND; + case Attribute::NonNull: + return bitc::ATTR_KIND_NON_NULL; + case Attribute::Dereferenceable: + return bitc::ATTR_KIND_DEREFERENCEABLE; + case Attribute::DereferenceableOrNull: + return bitc::ATTR_KIND_DEREFERENCEABLE_OR_NULL; + case Attribute::NoRedZone: + return bitc::ATTR_KIND_NO_RED_ZONE; + case Attribute::NoReturn: + return bitc::ATTR_KIND_NO_RETURN; + case Attribute::NoUnwind: + return bitc::ATTR_KIND_NO_UNWIND; + case Attribute::OptimizeForSize: + return bitc::ATTR_KIND_OPTIMIZE_FOR_SIZE; + case Attribute::OptimizeNone: + return bitc::ATTR_KIND_OPTIMIZE_NONE; + case Attribute::ReadNone: + return bitc::ATTR_KIND_READ_NONE; + case Attribute::ReadOnly: + return bitc::ATTR_KIND_READ_ONLY; + case Attribute::Returned: + return bitc::ATTR_KIND_RETURNED; + case Attribute::ReturnsTwice: + return bitc::ATTR_KIND_RETURNS_TWICE; + case Attribute::SExt: + return bitc::ATTR_KIND_S_EXT; + case Attribute::StackAlignment: + return bitc::ATTR_KIND_STACK_ALIGNMENT; + case Attribute::StackProtect: + return bitc::ATTR_KIND_STACK_PROTECT; + case Attribute::StackProtectReq: + return bitc::ATTR_KIND_STACK_PROTECT_REQ; + case Attribute::StackProtectStrong: + return bitc::ATTR_KIND_STACK_PROTECT_STRONG; + case Attribute::SafeStack: + return bitc::ATTR_KIND_SAFESTACK; + case Attribute::StructRet: + return bitc::ATTR_KIND_STRUCT_RET; + case Attribute::SanitizeAddress: + return bitc::ATTR_KIND_SANITIZE_ADDRESS; + case Attribute::SanitizeThread: + return bitc::ATTR_KIND_SANITIZE_THREAD; + case Attribute::SanitizeMemory: + return bitc::ATTR_KIND_SANITIZE_MEMORY; + case Attribute::UWTable: + return bitc::ATTR_KIND_UW_TABLE; + case Attribute::ZExt: + return bitc::ATTR_KIND_Z_EXT; + case Attribute::EndAttrKinds: + llvm_unreachable("Can not encode end-attribute kinds marker."); + case Attribute::None: + llvm_unreachable("Can not encode none-attribute."); + } + + llvm_unreachable("Trying to encode unknown attribute"); +} + +static void WriteAttributeGroupTable(const ValueEnumerator &VE, + BitstreamWriter &Stream) { + const std::vector<AttributeSet> &AttrGrps = VE.getAttributeGroups(); + if (AttrGrps.empty()) return; + + Stream.EnterSubblock(bitc::PARAMATTR_GROUP_BLOCK_ID, 3); + + SmallVector<uint64_t, 64> Record; + for (unsigned i = 0, e = AttrGrps.size(); i != e; ++i) { + AttributeSet AS = AttrGrps[i]; + for (unsigned i = 0, e = AS.getNumSlots(); i != e; ++i) { + AttributeSet A = AS.getSlotAttributes(i); + + Record.push_back(VE.getAttributeGroupID(A)); + Record.push_back(AS.getSlotIndex(i)); + + for (AttributeSet::iterator I = AS.begin(0), E = AS.end(0); + I != E; ++I) { + Attribute Attr = *I; + if (Attr.isEnumAttribute()) { + Record.push_back(0); + Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); + } else if (Attr.isIntAttribute()) { + Record.push_back(1); + Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); + Record.push_back(Attr.getValueAsInt()); + } else { + StringRef Kind = Attr.getKindAsString(); + StringRef Val = Attr.getValueAsString(); + + Record.push_back(Val.empty() ? 3 : 4); + Record.append(Kind.begin(), Kind.end()); + Record.push_back(0); + if (!Val.empty()) { + Record.append(Val.begin(), Val.end()); + Record.push_back(0); + } + } + } + + Stream.EmitRecord(bitc::PARAMATTR_GRP_CODE_ENTRY, Record); + Record.clear(); + } + } + + Stream.ExitBlock(); +} + +static void WriteAttributeTable(const ValueEnumerator &VE, + BitstreamWriter &Stream) { + const std::vector<AttributeSet> &Attrs = VE.getAttributes(); + if (Attrs.empty()) return; + + Stream.EnterSubblock(bitc::PARAMATTR_BLOCK_ID, 3); + + SmallVector<uint64_t, 64> Record; + for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { + const AttributeSet &A = Attrs[i]; + for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) + Record.push_back(VE.getAttributeGroupID(A.getSlotAttributes(i))); + + Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); + Record.clear(); + } + + Stream.ExitBlock(); +} + +/// WriteTypeTable - Write out the type table for a module. +static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { + const ValueEnumerator::TypeList &TypeList = VE.getTypes(); + + Stream.EnterSubblock(bitc::TYPE_BLOCK_ID_NEW, 4 /*count from # abbrevs */); + SmallVector<uint64_t, 64> TypeVals; + + uint64_t NumBits = VE.computeBitsRequiredForTypeIndicies(); + + // Abbrev for TYPE_CODE_POINTER. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_POINTER)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); + Abbv->Add(BitCodeAbbrevOp(0)); // Addrspace = 0 + unsigned PtrAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_FUNCTION. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_FUNCTION)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // isvararg + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); + + unsigned FunctionAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_ANON. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_ANON)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); + + unsigned StructAnonAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAME. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAME)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + unsigned StructNameAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_STRUCT_NAMED. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_STRUCT_NAMED)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // ispacked + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); + + unsigned StructNamedAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for TYPE_CODE_ARRAY. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::TYPE_CODE_ARRAY)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // size + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, NumBits)); + + unsigned ArrayAbbrev = Stream.EmitAbbrev(Abbv); + + // Emit an entry count so the reader can reserve space. + TypeVals.push_back(TypeList.size()); + Stream.EmitRecord(bitc::TYPE_CODE_NUMENTRY, TypeVals); + TypeVals.clear(); + + // Loop over all of the types, emitting each in turn. + for (unsigned i = 0, e = TypeList.size(); i != e; ++i) { + Type *T = TypeList[i]; + int AbbrevToUse = 0; + unsigned Code = 0; + + switch (T->getTypeID()) { + case Type::VoidTyID: Code = bitc::TYPE_CODE_VOID; break; + case Type::HalfTyID: Code = bitc::TYPE_CODE_HALF; break; + case Type::FloatTyID: Code = bitc::TYPE_CODE_FLOAT; break; + case Type::DoubleTyID: Code = bitc::TYPE_CODE_DOUBLE; break; + case Type::X86_FP80TyID: Code = bitc::TYPE_CODE_X86_FP80; break; + case Type::FP128TyID: Code = bitc::TYPE_CODE_FP128; break; + case Type::PPC_FP128TyID: Code = bitc::TYPE_CODE_PPC_FP128; break; + case Type::LabelTyID: Code = bitc::TYPE_CODE_LABEL; break; + case Type::MetadataTyID: Code = bitc::TYPE_CODE_METADATA; break; + case Type::X86_MMXTyID: Code = bitc::TYPE_CODE_X86_MMX; break; + case Type::IntegerTyID: + // INTEGER: [width] + Code = bitc::TYPE_CODE_INTEGER; + TypeVals.push_back(cast<IntegerType>(T)->getBitWidth()); + break; + case Type::PointerTyID: { + PointerType *PTy = cast<PointerType>(T); + // POINTER: [pointee type, address space] + Code = bitc::TYPE_CODE_POINTER; + TypeVals.push_back(VE.getTypeID(PTy->getElementType())); + unsigned AddressSpace = PTy->getAddressSpace(); + TypeVals.push_back(AddressSpace); + if (AddressSpace == 0) AbbrevToUse = PtrAbbrev; + break; + } + case Type::FunctionTyID: { + FunctionType *FT = cast<FunctionType>(T); + // FUNCTION: [isvararg, retty, paramty x N] + Code = bitc::TYPE_CODE_FUNCTION; + TypeVals.push_back(FT->isVarArg()); + TypeVals.push_back(VE.getTypeID(FT->getReturnType())); + for (unsigned i = 0, e = FT->getNumParams(); i != e; ++i) + TypeVals.push_back(VE.getTypeID(FT->getParamType(i))); + AbbrevToUse = FunctionAbbrev; + break; + } + case Type::StructTyID: { + StructType *ST = cast<StructType>(T); + // STRUCT: [ispacked, eltty x N] + TypeVals.push_back(ST->isPacked()); + // Output all of the element types. + for (StructType::element_iterator I = ST->element_begin(), + E = ST->element_end(); I != E; ++I) + TypeVals.push_back(VE.getTypeID(*I)); + + if (ST->isLiteral()) { + Code = bitc::TYPE_CODE_STRUCT_ANON; + AbbrevToUse = StructAnonAbbrev; + } else { + if (ST->isOpaque()) { + Code = bitc::TYPE_CODE_OPAQUE; + } else { + Code = bitc::TYPE_CODE_STRUCT_NAMED; + AbbrevToUse = StructNamedAbbrev; + } + + // Emit the name if it is present. + if (!ST->getName().empty()) + WriteStringRecord(bitc::TYPE_CODE_STRUCT_NAME, ST->getName(), + StructNameAbbrev, Stream); + } + break; + } + case Type::ArrayTyID: { + ArrayType *AT = cast<ArrayType>(T); + // ARRAY: [numelts, eltty] + Code = bitc::TYPE_CODE_ARRAY; + TypeVals.push_back(AT->getNumElements()); + TypeVals.push_back(VE.getTypeID(AT->getElementType())); + AbbrevToUse = ArrayAbbrev; + break; + } + case Type::VectorTyID: { + VectorType *VT = cast<VectorType>(T); + // VECTOR [numelts, eltty] + Code = bitc::TYPE_CODE_VECTOR; + TypeVals.push_back(VT->getNumElements()); + TypeVals.push_back(VE.getTypeID(VT->getElementType())); + break; + } + } + + // Emit the finished record. + Stream.EmitRecord(Code, TypeVals, AbbrevToUse); + TypeVals.clear(); + } + + Stream.ExitBlock(); +} + +static unsigned getEncodedLinkage(const GlobalValue &GV) { + switch (GV.getLinkage()) { + case GlobalValue::ExternalLinkage: + return 0; + case GlobalValue::WeakAnyLinkage: + return 16; + case GlobalValue::AppendingLinkage: + return 2; + case GlobalValue::InternalLinkage: + return 3; + case GlobalValue::LinkOnceAnyLinkage: + return 18; + case GlobalValue::ExternalWeakLinkage: + return 7; + case GlobalValue::CommonLinkage: + return 8; + case GlobalValue::PrivateLinkage: + return 9; + case GlobalValue::WeakODRLinkage: + return 17; + case GlobalValue::LinkOnceODRLinkage: + return 19; + case GlobalValue::AvailableExternallyLinkage: + return 12; + } + llvm_unreachable("Invalid linkage"); +} + +static unsigned getEncodedVisibility(const GlobalValue &GV) { + switch (GV.getVisibility()) { + case GlobalValue::DefaultVisibility: return 0; + case GlobalValue::HiddenVisibility: return 1; + case GlobalValue::ProtectedVisibility: return 2; + } + llvm_unreachable("Invalid visibility"); +} + +static unsigned getEncodedDLLStorageClass(const GlobalValue &GV) { + switch (GV.getDLLStorageClass()) { + case GlobalValue::DefaultStorageClass: return 0; + case GlobalValue::DLLImportStorageClass: return 1; + case GlobalValue::DLLExportStorageClass: return 2; + } + llvm_unreachable("Invalid DLL storage class"); +} + +static unsigned getEncodedThreadLocalMode(const GlobalValue &GV) { + switch (GV.getThreadLocalMode()) { + case GlobalVariable::NotThreadLocal: return 0; + case GlobalVariable::GeneralDynamicTLSModel: return 1; + case GlobalVariable::LocalDynamicTLSModel: return 2; + case GlobalVariable::InitialExecTLSModel: return 3; + case GlobalVariable::LocalExecTLSModel: return 4; + } + llvm_unreachable("Invalid TLS model"); +} + +static unsigned getEncodedComdatSelectionKind(const Comdat &C) { + switch (C.getSelectionKind()) { + case Comdat::Any: + return bitc::COMDAT_SELECTION_KIND_ANY; + case Comdat::ExactMatch: + return bitc::COMDAT_SELECTION_KIND_EXACT_MATCH; + case Comdat::Largest: + return bitc::COMDAT_SELECTION_KIND_LARGEST; + case Comdat::NoDuplicates: + return bitc::COMDAT_SELECTION_KIND_NO_DUPLICATES; + case Comdat::SameSize: + return bitc::COMDAT_SELECTION_KIND_SAME_SIZE; + } + llvm_unreachable("Invalid selection kind"); +} + +static void writeComdats(const ValueEnumerator &VE, BitstreamWriter &Stream) { + SmallVector<uint16_t, 64> Vals; + for (const Comdat *C : VE.getComdats()) { + // COMDAT: [selection_kind, name] + Vals.push_back(getEncodedComdatSelectionKind(*C)); + size_t Size = C->getName().size(); + assert(isUInt<16>(Size)); + Vals.push_back(Size); + for (char Chr : C->getName()) + Vals.push_back((unsigned char)Chr); + Stream.EmitRecord(bitc::MODULE_CODE_COMDAT, Vals, /*AbbrevToUse=*/0); + Vals.clear(); + } +} + +// Emit top-level description of module, including target triple, inline asm, +// descriptors for global variables, and function prototype info. +static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, + BitstreamWriter &Stream) { + // Emit various pieces of data attached to a module. + if (!M->getTargetTriple().empty()) + WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), + 0/*TODO*/, Stream); + const std::string &DL = M->getDataLayoutStr(); + if (!DL.empty()) + WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, DL, 0 /*TODO*/, Stream); + if (!M->getModuleInlineAsm().empty()) + WriteStringRecord(bitc::MODULE_CODE_ASM, M->getModuleInlineAsm(), + 0/*TODO*/, Stream); + + // Emit information about sections and GC, computing how many there are. Also + // compute the maximum alignment value. + std::map<std::string, unsigned> SectionMap; + std::map<std::string, unsigned> GCMap; + unsigned MaxAlignment = 0; + unsigned MaxGlobalType = 0; + for (const GlobalValue &GV : M->globals()) { + MaxAlignment = std::max(MaxAlignment, GV.getAlignment()); + MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getValueType())); + if (GV.hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionMap[GV.getSection()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(), + 0/*TODO*/, Stream); + Entry = SectionMap.size(); + } + } + } + for (const Function &F : *M) { + MaxAlignment = std::max(MaxAlignment, F.getAlignment()); + if (F.hasSection()) { + // Give section names unique ID's. + unsigned &Entry = SectionMap[F.getSection()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(), + 0/*TODO*/, Stream); + Entry = SectionMap.size(); + } + } + if (F.hasGC()) { + // Same for GC names. + unsigned &Entry = GCMap[F.getGC()]; + if (!Entry) { + WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(), + 0/*TODO*/, Stream); + Entry = GCMap.size(); + } + } + } + + // Emit abbrev for globals, now that we know # sections and max alignment. + unsigned SimpleGVarAbbrev = 0; + if (!M->global_empty()) { + // Add an abbrev for common globals with no visibility or thread localness. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::MODULE_CODE_GLOBALVAR)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(MaxGlobalType+1))); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // AddrSpace << 2 + //| explicitType << 1 + //| constant + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer. + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage. + if (MaxAlignment == 0) // Alignment. + Abbv->Add(BitCodeAbbrevOp(0)); + else { + unsigned MaxEncAlignment = Log2_32(MaxAlignment)+1; + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(MaxEncAlignment+1))); + } + if (SectionMap.empty()) // Section. + Abbv->Add(BitCodeAbbrevOp(0)); + else + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + Log2_32_Ceil(SectionMap.size()+1))); + // Don't bother emitting vis + thread local. + SimpleGVarAbbrev = Stream.EmitAbbrev(Abbv); + } + + // Emit the global variable information. + SmallVector<unsigned, 64> Vals; + for (const GlobalVariable &GV : M->globals()) { + unsigned AbbrevToUse = 0; + + // GLOBALVAR: [type, isconst, initid, + // linkage, alignment, section, visibility, threadlocal, + // unnamed_addr, externally_initialized, dllstorageclass, + // comdat] + Vals.push_back(VE.getTypeID(GV.getValueType())); + Vals.push_back(GV.getType()->getAddressSpace() << 2 | 2 | GV.isConstant()); + Vals.push_back(GV.isDeclaration() ? 0 : + (VE.getValueID(GV.getInitializer()) + 1)); + Vals.push_back(getEncodedLinkage(GV)); + Vals.push_back(Log2_32(GV.getAlignment())+1); + Vals.push_back(GV.hasSection() ? SectionMap[GV.getSection()] : 0); + if (GV.isThreadLocal() || + GV.getVisibility() != GlobalValue::DefaultVisibility || + GV.hasUnnamedAddr() || GV.isExternallyInitialized() || + GV.getDLLStorageClass() != GlobalValue::DefaultStorageClass || + GV.hasComdat()) { + Vals.push_back(getEncodedVisibility(GV)); + Vals.push_back(getEncodedThreadLocalMode(GV)); + Vals.push_back(GV.hasUnnamedAddr()); + Vals.push_back(GV.isExternallyInitialized()); + Vals.push_back(getEncodedDLLStorageClass(GV)); + Vals.push_back(GV.hasComdat() ? VE.getComdatID(GV.getComdat()) : 0); + } else { + AbbrevToUse = SimpleGVarAbbrev; + } + + Stream.EmitRecord(bitc::MODULE_CODE_GLOBALVAR, Vals, AbbrevToUse); + Vals.clear(); + } + + // Emit the function proto information. + for (const Function &F : *M) { + // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, + // section, visibility, gc, unnamed_addr, prologuedata, + // dllstorageclass, comdat, prefixdata, personalityfn] + Vals.push_back(VE.getTypeID(F.getFunctionType())); + Vals.push_back(F.getCallingConv()); + Vals.push_back(F.isDeclaration()); + Vals.push_back(getEncodedLinkage(F)); + Vals.push_back(VE.getAttributeID(F.getAttributes())); + Vals.push_back(Log2_32(F.getAlignment())+1); + Vals.push_back(F.hasSection() ? SectionMap[F.getSection()] : 0); + Vals.push_back(getEncodedVisibility(F)); + Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0); + Vals.push_back(F.hasUnnamedAddr()); + Vals.push_back(F.hasPrologueData() ? (VE.getValueID(F.getPrologueData()) + 1) + : 0); + Vals.push_back(getEncodedDLLStorageClass(F)); + Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0); + Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1) + : 0); + Vals.push_back( + F.hasPersonalityFn() ? (VE.getValueID(F.getPersonalityFn()) + 1) : 0); + + unsigned AbbrevToUse = 0; + Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); + Vals.clear(); + } + + // Emit the alias information. + for (const GlobalAlias &A : M->aliases()) { + // ALIAS: [alias type, aliasee val#, linkage, visibility] + Vals.push_back(VE.getTypeID(A.getType())); + Vals.push_back(VE.getValueID(A.getAliasee())); + Vals.push_back(getEncodedLinkage(A)); + Vals.push_back(getEncodedVisibility(A)); + Vals.push_back(getEncodedDLLStorageClass(A)); + Vals.push_back(getEncodedThreadLocalMode(A)); + Vals.push_back(A.hasUnnamedAddr()); + unsigned AbbrevToUse = 0; + Stream.EmitRecord(bitc::MODULE_CODE_ALIAS, Vals, AbbrevToUse); + Vals.clear(); + } +} + +static uint64_t GetOptimizationFlags(const Value *V) { + uint64_t Flags = 0; + + if (const auto *OBO = dyn_cast<OverflowingBinaryOperator>(V)) { + if (OBO->hasNoSignedWrap()) + Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP; + if (OBO->hasNoUnsignedWrap()) + Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP; + } else if (const auto *PEO = dyn_cast<PossiblyExactOperator>(V)) { + if (PEO->isExact()) + Flags |= 1 << bitc::PEO_EXACT; + } else if (const auto *FPMO = dyn_cast<FPMathOperator>(V)) { + if (FPMO->hasUnsafeAlgebra()) + Flags |= FastMathFlags::UnsafeAlgebra; + if (FPMO->hasNoNaNs()) + Flags |= FastMathFlags::NoNaNs; + if (FPMO->hasNoInfs()) + Flags |= FastMathFlags::NoInfs; + if (FPMO->hasNoSignedZeros()) + Flags |= FastMathFlags::NoSignedZeros; + if (FPMO->hasAllowReciprocal()) + Flags |= FastMathFlags::AllowReciprocal; + } + + return Flags; +} + +static void WriteValueAsMetadata(const ValueAsMetadata *MD, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record) { + // Mimic an MDNode with a value as one operand. + Value *V = MD->getValue(); + Record.push_back(VE.getTypeID(V->getType())); + Record.push_back(VE.getValueID(V)); + Stream.EmitRecord(bitc::METADATA_VALUE, Record, 0); + Record.clear(); +} + +static void WriteMDTuple(const MDTuple *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + Metadata *MD = N->getOperand(i); + assert(!(MD && isa<LocalAsMetadata>(MD)) && + "Unexpected function-local metadata"); + Record.push_back(VE.getMetadataOrNullID(MD)); + } + Stream.EmitRecord(N->isDistinct() ? bitc::METADATA_DISTINCT_NODE + : bitc::METADATA_NODE, + Record, Abbrev); + Record.clear(); +} + +static void WriteDILocation(const DILocation *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getLine()); + Record.push_back(N->getColumn()); + Record.push_back(VE.getMetadataID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getInlinedAt())); + + Stream.EmitRecord(bitc::METADATA_LOCATION, Record, Abbrev); + Record.clear(); +} + +static void WriteGenericDINode(const GenericDINode *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(0); // Per-tag version field; unused for now. + + for (auto &I : N->operands()) + Record.push_back(VE.getMetadataOrNullID(I)); + + Stream.EmitRecord(bitc::METADATA_GENERIC_DEBUG, Record, Abbrev); + Record.clear(); +} + +static uint64_t rotateSign(int64_t I) { + uint64_t U = I; + return I < 0 ? ~(U << 1) : U << 1; +} + +static void WriteDISubrange(const DISubrange *N, const ValueEnumerator &, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getCount()); + Record.push_back(rotateSign(N->getLowerBound())); + + Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev); + Record.clear(); +} + +static void WriteDIEnumerator(const DIEnumerator *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(rotateSign(N->getValue())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + + Stream.EmitRecord(bitc::METADATA_ENUMERATOR, Record, Abbrev); + Record.clear(); +} + +static void WriteDIBasicType(const DIBasicType *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(N->getSizeInBits()); + Record.push_back(N->getAlignInBits()); + Record.push_back(N->getEncoding()); + + Stream.EmitRecord(bitc::METADATA_BASIC_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteDIDerivedType(const DIDerivedType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); + Record.push_back(N->getSizeInBits()); + Record.push_back(N->getAlignInBits()); + Record.push_back(N->getOffsetInBits()); + Record.push_back(N->getFlags()); + Record.push_back(VE.getMetadataOrNullID(N->getExtraData())); + + Stream.EmitRecord(bitc::METADATA_DERIVED_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteDICompositeType(const DICompositeType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getBaseType())); + Record.push_back(N->getSizeInBits()); + Record.push_back(N->getAlignInBits()); + Record.push_back(N->getOffsetInBits()); + Record.push_back(N->getFlags()); + Record.push_back(VE.getMetadataOrNullID(N->getElements().get())); + Record.push_back(N->getRuntimeLang()); + Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); + Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); + + Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteDISubroutineType(const DISubroutineType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getFlags()); + Record.push_back(VE.getMetadataOrNullID(N->getTypeArray().get())); + + Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteDIFile(const DIFile *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getRawFilename())); + Record.push_back(VE.getMetadataOrNullID(N->getRawDirectory())); + + Stream.EmitRecord(bitc::METADATA_FILE, Record, Abbrev); + Record.clear(); +} + +static void WriteDICompileUnit(const DICompileUnit *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getSourceLanguage()); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(VE.getMetadataOrNullID(N->getRawProducer())); + Record.push_back(N->isOptimized()); + Record.push_back(VE.getMetadataOrNullID(N->getRawFlags())); + Record.push_back(N->getRuntimeVersion()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSplitDebugFilename())); + Record.push_back(N->getEmissionKind()); + Record.push_back(VE.getMetadataOrNullID(N->getEnumTypes().get())); + Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes().get())); + Record.push_back(VE.getMetadataOrNullID(N->getSubprograms().get())); + Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables().get())); + Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities().get())); + Record.push_back(N->getDWOId()); + + Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); + Record.clear(); +} + +static void WriteDISubprogram(const DISubprogram *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(N->isLocalToUnit()); + Record.push_back(N->isDefinition()); + Record.push_back(N->getScopeLine()); + Record.push_back(VE.getMetadataOrNullID(N->getContainingType())); + Record.push_back(N->getVirtuality()); + Record.push_back(N->getVirtualIndex()); + Record.push_back(N->getFlags()); + Record.push_back(N->isOptimized()); + Record.push_back(VE.getMetadataOrNullID(N->getRawFunction())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); + Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); + Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); + + Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); + Record.clear(); +} + +static void WriteDILexicalBlock(const DILexicalBlock *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(N->getColumn()); + + Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK, Record, Abbrev); + Record.clear(); +} + +static void WriteDILexicalBlockFile(const DILexicalBlockFile *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getDiscriminator()); + + Stream.EmitRecord(bitc::METADATA_LEXICAL_BLOCK_FILE, Record, Abbrev); + Record.clear(); +} + +static void WriteDINamespace(const DINamespace *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(N->getLine()); + + Stream.EmitRecord(bitc::METADATA_NAMESPACE, Record, Abbrev); + Record.clear(); +} + +static void WriteDITemplateTypeParameter(const DITemplateTypeParameter *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + + Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteDITemplateValueParameter(const DITemplateValueParameter *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(VE.getMetadataOrNullID(N->getValue())); + + Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev); + Record.clear(); +} + +static void WriteDIGlobalVariable(const DIGlobalVariable *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getRawLinkageName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(N->isLocalToUnit()); + Record.push_back(N->isDefinition()); + Record.push_back(VE.getMetadataOrNullID(N->getRawVariable())); + Record.push_back(VE.getMetadataOrNullID(N->getStaticDataMemberDeclaration())); + + Stream.EmitRecord(bitc::METADATA_GLOBAL_VAR, Record, Abbrev); + Record.clear(); +} + +static void WriteDILocalVariable(const DILocalVariable *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + Record.push_back(N->getArg()); + Record.push_back(N->getFlags()); + + Stream.EmitRecord(bitc::METADATA_LOCAL_VAR, Record, Abbrev); + Record.clear(); +} + +static void WriteDIExpression(const DIExpression *N, const ValueEnumerator &, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.reserve(N->getElements().size() + 1); + + Record.push_back(N->isDistinct()); + Record.append(N->elements_begin(), N->elements_end()); + + Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev); + Record.clear(); +} + +static void WriteDIObjCProperty(const DIObjCProperty *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + Record.push_back(VE.getMetadataOrNullID(N->getFile())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getRawSetterName())); + Record.push_back(VE.getMetadataOrNullID(N->getRawGetterName())); + Record.push_back(N->getAttributes()); + Record.push_back(VE.getMetadataOrNullID(N->getType())); + + Stream.EmitRecord(bitc::METADATA_OBJC_PROPERTY, Record, Abbrev); + Record.clear(); +} + +static void WriteDIImportedEntity(const DIImportedEntity *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl<uint64_t> &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getTag()); + Record.push_back(VE.getMetadataOrNullID(N->getScope())); + Record.push_back(VE.getMetadataOrNullID(N->getEntity())); + Record.push_back(N->getLine()); + Record.push_back(VE.getMetadataOrNullID(N->getRawName())); + + Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev); + Record.clear(); +} + +static void WriteModuleMetadata(const Module *M, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + const auto &MDs = VE.getMDs(); + if (MDs.empty() && M->named_metadata_empty()) + return; + + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + + unsigned MDSAbbrev = 0; + if (VE.hasMDString()) { + // Abbrev for METADATA_STRING. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_STRING)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); + MDSAbbrev = Stream.EmitAbbrev(Abbv); + } + + // Initialize MDNode abbreviations. +#define HANDLE_MDNODE_LEAF(CLASS) unsigned CLASS##Abbrev = 0; +#include "llvm/IR/Metadata.def" + + if (VE.hasDILocation()) { + // Abbrev for METADATA_LOCATION. + // + // Assume the column is usually under 128, and always output the inlined-at + // location (it's never more expensive than building an array size 1). + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_LOCATION)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + DILocationAbbrev = Stream.EmitAbbrev(Abbv); + } + + if (VE.hasGenericDINode()) { + // Abbrev for METADATA_GENERIC_DEBUG. + // + // Assume the column is usually under 128, and always output the inlined-at + // location (it's never more expensive than building an array size 1). + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_GENERIC_DEBUG)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + GenericDINodeAbbrev = Stream.EmitAbbrev(Abbv); + } + + unsigned NameAbbrev = 0; + if (!M->named_metadata_empty()) { + // Abbrev for METADATA_NAME. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::METADATA_NAME)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); + NameAbbrev = Stream.EmitAbbrev(Abbv); + } + + SmallVector<uint64_t, 64> Record; + for (const Metadata *MD : MDs) { + if (const MDNode *N = dyn_cast<MDNode>(MD)) { + assert(N->isResolved() && "Expected forward references to be resolved"); + + switch (N->getMetadataID()) { + default: + llvm_unreachable("Invalid MDNode subclass"); +#define HANDLE_MDNODE_LEAF(CLASS) \ + case Metadata::CLASS##Kind: \ + Write##CLASS(cast<CLASS>(N), VE, Stream, Record, CLASS##Abbrev); \ + continue; +#include "llvm/IR/Metadata.def" + } + } + if (const auto *MDC = dyn_cast<ConstantAsMetadata>(MD)) { + WriteValueAsMetadata(MDC, VE, Stream, Record); + continue; + } + const MDString *MDS = cast<MDString>(MD); + // Code: [strchar x N] + Record.append(MDS->bytes_begin(), MDS->bytes_end()); + + // Emit the finished record. + Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev); + Record.clear(); + } + + // Write named metadata. + for (const NamedMDNode &NMD : M->named_metadata()) { + // Write name. + StringRef Str = NMD.getName(); + Record.append(Str.bytes_begin(), Str.bytes_end()); + Stream.EmitRecord(bitc::METADATA_NAME, Record, NameAbbrev); + Record.clear(); + + // Write named metadata operands. + for (const MDNode *N : NMD.operands()) + Record.push_back(VE.getMetadataID(N)); + Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); + Record.clear(); + } + + Stream.ExitBlock(); +} + +static void WriteFunctionLocalMetadata(const Function &F, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + bool StartedMetadataBlock = false; + SmallVector<uint64_t, 64> Record; + const SmallVectorImpl<const LocalAsMetadata *> &MDs = + VE.getFunctionLocalMDs(); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + assert(MDs[i] && "Expected valid function-local metadata"); + if (!StartedMetadataBlock) { + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + StartedMetadataBlock = true; + } + WriteValueAsMetadata(MDs[i], VE, Stream, Record); + } + + if (StartedMetadataBlock) + Stream.ExitBlock(); +} + +static void WriteMetadataAttachment(const Function &F, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + Stream.EnterSubblock(bitc::METADATA_ATTACHMENT_ID, 3); + + SmallVector<uint64_t, 64> Record; + + // Write metadata attachments + // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] + SmallVector<std::pair<unsigned, MDNode *>, 4> MDs; + F.getAllMetadata(MDs); + if (!MDs.empty()) { + for (const auto &I : MDs) { + Record.push_back(I.first); + Record.push_back(VE.getMetadataID(I.second)); + } + Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); + Record.clear(); + } + + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); + I != E; ++I) { + MDs.clear(); + I->getAllMetadataOtherThanDebugLoc(MDs); + + // If no metadata, ignore instruction. + if (MDs.empty()) continue; + + Record.push_back(VE.getInstructionID(I)); + + for (unsigned i = 0, e = MDs.size(); i != e; ++i) { + Record.push_back(MDs[i].first); + Record.push_back(VE.getMetadataID(MDs[i].second)); + } + Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); + Record.clear(); + } + + Stream.ExitBlock(); +} + +static void WriteModuleMetadataStore(const Module *M, BitstreamWriter &Stream) { + SmallVector<uint64_t, 64> Record; + + // Write metadata kinds + // METADATA_KIND - [n x [id, name]] + SmallVector<StringRef, 8> Names; + M->getMDKindNames(Names); + + if (Names.empty()) return; + + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + + for (unsigned MDKindID = 0, e = Names.size(); MDKindID != e; ++MDKindID) { + Record.push_back(MDKindID); + StringRef KName = Names[MDKindID]; + Record.append(KName.begin(), KName.end()); + + Stream.EmitRecord(bitc::METADATA_KIND, Record, 0); + Record.clear(); + } + + Stream.ExitBlock(); +} + +static void emitSignedInt64(SmallVectorImpl<uint64_t> &Vals, uint64_t V) { + if ((int64_t)V >= 0) + Vals.push_back(V << 1); + else + Vals.push_back((-V << 1) | 1); +} + +static void WriteConstants(unsigned FirstVal, unsigned LastVal, + const ValueEnumerator &VE, + BitstreamWriter &Stream, bool isGlobal) { + if (FirstVal == LastVal) return; + + Stream.EnterSubblock(bitc::CONSTANTS_BLOCK_ID, 4); + + unsigned AggregateAbbrev = 0; + unsigned String8Abbrev = 0; + unsigned CString7Abbrev = 0; + unsigned CString6Abbrev = 0; + // If this is a constant pool for the module, emit module-specific abbrevs. + if (isGlobal) { + // Abbrev for CST_CODE_AGGREGATE. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_AGGREGATE)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, Log2_32_Ceil(LastVal+1))); + AggregateAbbrev = Stream.EmitAbbrev(Abbv); + + // Abbrev for CST_CODE_STRING. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_STRING)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); + String8Abbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for CST_CODE_CSTRING. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); + CString7Abbrev = Stream.EmitAbbrev(Abbv); + // Abbrev for CST_CODE_CSTRING. + Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CSTRING)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + CString6Abbrev = Stream.EmitAbbrev(Abbv); + } + + SmallVector<uint64_t, 64> Record; + + const ValueEnumerator::ValueList &Vals = VE.getValues(); + Type *LastTy = nullptr; + for (unsigned i = FirstVal; i != LastVal; ++i) { + const Value *V = Vals[i].first; + // If we need to switch types, do so now. + if (V->getType() != LastTy) { + LastTy = V->getType(); + Record.push_back(VE.getTypeID(LastTy)); + Stream.EmitRecord(bitc::CST_CODE_SETTYPE, Record, + CONSTANTS_SETTYPE_ABBREV); + Record.clear(); + } + + if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) { + Record.push_back(unsigned(IA->hasSideEffects()) | + unsigned(IA->isAlignStack()) << 1 | + unsigned(IA->getDialect()&1) << 2); + + // Add the asm string. + const std::string &AsmStr = IA->getAsmString(); + Record.push_back(AsmStr.size()); + Record.append(AsmStr.begin(), AsmStr.end()); + + // Add the constraint string. + const std::string &ConstraintStr = IA->getConstraintString(); + Record.push_back(ConstraintStr.size()); + Record.append(ConstraintStr.begin(), ConstraintStr.end()); + Stream.EmitRecord(bitc::CST_CODE_INLINEASM, Record); + Record.clear(); + continue; + } + const Constant *C = cast<Constant>(V); + unsigned Code = -1U; + unsigned AbbrevToUse = 0; + if (C->isNullValue()) { + Code = bitc::CST_CODE_NULL; + } else if (isa<UndefValue>(C)) { + Code = bitc::CST_CODE_UNDEF; + } else if (const ConstantInt *IV = dyn_cast<ConstantInt>(C)) { + if (IV->getBitWidth() <= 64) { + uint64_t V = IV->getSExtValue(); + emitSignedInt64(Record, V); + Code = bitc::CST_CODE_INTEGER; + AbbrevToUse = CONSTANTS_INTEGER_ABBREV; + } else { // Wide integers, > 64 bits in size. + // We have an arbitrary precision integer value to write whose + // bit width is > 64. However, in canonical unsigned integer + // format it is likely that the high bits are going to be zero. + // So, we only write the number of active words. + unsigned NWords = IV->getValue().getActiveWords(); + const uint64_t *RawWords = IV->getValue().getRawData(); + for (unsigned i = 0; i != NWords; ++i) { + emitSignedInt64(Record, RawWords[i]); + } + Code = bitc::CST_CODE_WIDE_INTEGER; + } + } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(C)) { + Code = bitc::CST_CODE_FLOAT; + Type *Ty = CFP->getType(); + if (Ty->isHalfTy() || Ty->isFloatTy() || Ty->isDoubleTy()) { + Record.push_back(CFP->getValueAPF().bitcastToAPInt().getZExtValue()); + } else if (Ty->isX86_FP80Ty()) { + // api needed to prevent premature destruction + // bits are not in the same order as a normal i80 APInt, compensate. + APInt api = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Record.push_back((p[1] << 48) | (p[0] >> 16)); + Record.push_back(p[0] & 0xffffLL); + } else if (Ty->isFP128Ty() || Ty->isPPC_FP128Ty()) { + APInt api = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = api.getRawData(); + Record.push_back(p[0]); + Record.push_back(p[1]); + } else { + assert (0 && "Unknown FP type!"); + } + } else if (isa<ConstantDataSequential>(C) && + cast<ConstantDataSequential>(C)->isString()) { + const ConstantDataSequential *Str = cast<ConstantDataSequential>(C); + // Emit constant strings specially. + unsigned NumElts = Str->getNumElements(); + // If this is a null-terminated string, use the denser CSTRING encoding. + if (Str->isCString()) { + Code = bitc::CST_CODE_CSTRING; + --NumElts; // Don't encode the null, which isn't allowed by char6. + } else { + Code = bitc::CST_CODE_STRING; + AbbrevToUse = String8Abbrev; + } + bool isCStr7 = Code == bitc::CST_CODE_CSTRING; + bool isCStrChar6 = Code == bitc::CST_CODE_CSTRING; + for (unsigned i = 0; i != NumElts; ++i) { + unsigned char V = Str->getElementAsInteger(i); + Record.push_back(V); + isCStr7 &= (V & 128) == 0; + if (isCStrChar6) + isCStrChar6 = BitCodeAbbrevOp::isChar6(V); + } + + if (isCStrChar6) + AbbrevToUse = CString6Abbrev; + else if (isCStr7) + AbbrevToUse = CString7Abbrev; + } else if (const ConstantDataSequential *CDS = + dyn_cast<ConstantDataSequential>(C)) { + Code = bitc::CST_CODE_DATA; + Type *EltTy = CDS->getType()->getElementType(); + if (isa<IntegerType>(EltTy)) { + for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) + Record.push_back(CDS->getElementAsInteger(i)); + } else if (EltTy->isFloatTy()) { + for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { + union { float F; uint32_t I; }; + F = CDS->getElementAsFloat(i); + Record.push_back(I); + } + } else { + assert(EltTy->isDoubleTy() && "Unknown ConstantData element type"); + for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) { + union { double F; uint64_t I; }; + F = CDS->getElementAsDouble(i); + Record.push_back(I); + } + } + } else if (isa<ConstantArray>(C) || isa<ConstantStruct>(C) || + isa<ConstantVector>(C)) { + Code = bitc::CST_CODE_AGGREGATE; + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) + Record.push_back(VE.getValueID(C->getOperand(i))); + AbbrevToUse = AggregateAbbrev; + } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) { + switch (CE->getOpcode()) { + default: + if (Instruction::isCast(CE->getOpcode())) { + Code = bitc::CST_CODE_CE_CAST; + Record.push_back(GetEncodedCastOpcode(CE->getOpcode())); + Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); + Record.push_back(VE.getValueID(C->getOperand(0))); + AbbrevToUse = CONSTANTS_CE_CAST_Abbrev; + } else { + assert(CE->getNumOperands() == 2 && "Unknown constant expr!"); + Code = bitc::CST_CODE_CE_BINOP; + Record.push_back(GetEncodedBinaryOpcode(CE->getOpcode())); + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getValueID(C->getOperand(1))); + uint64_t Flags = GetOptimizationFlags(CE); + if (Flags != 0) + Record.push_back(Flags); + } + break; + case Instruction::GetElementPtr: { + Code = bitc::CST_CODE_CE_GEP; + const auto *GO = cast<GEPOperator>(C); + if (GO->isInBounds()) + Code = bitc::CST_CODE_CE_INBOUNDS_GEP; + Record.push_back(VE.getTypeID(GO->getSourceElementType())); + for (unsigned i = 0, e = CE->getNumOperands(); i != e; ++i) { + Record.push_back(VE.getTypeID(C->getOperand(i)->getType())); + Record.push_back(VE.getValueID(C->getOperand(i))); + } + break; + } + case Instruction::Select: + Code = bitc::CST_CODE_CE_SELECT; + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getValueID(C->getOperand(1))); + Record.push_back(VE.getValueID(C->getOperand(2))); + break; + case Instruction::ExtractElement: + Code = bitc::CST_CODE_CE_EXTRACTELT; + Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getTypeID(C->getOperand(1)->getType())); + Record.push_back(VE.getValueID(C->getOperand(1))); + break; + case Instruction::InsertElement: + Code = bitc::CST_CODE_CE_INSERTELT; + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getValueID(C->getOperand(1))); + Record.push_back(VE.getTypeID(C->getOperand(2)->getType())); + Record.push_back(VE.getValueID(C->getOperand(2))); + break; + case Instruction::ShuffleVector: + // If the return type and argument types are the same, this is a + // standard shufflevector instruction. If the types are different, + // then the shuffle is widening or truncating the input vectors, and + // the argument type must also be encoded. + if (C->getType() == C->getOperand(0)->getType()) { + Code = bitc::CST_CODE_CE_SHUFFLEVEC; + } else { + Code = bitc::CST_CODE_CE_SHUFVEC_EX; + Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); + } + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getValueID(C->getOperand(1))); + Record.push_back(VE.getValueID(C->getOperand(2))); + break; + case Instruction::ICmp: + case Instruction::FCmp: + Code = bitc::CST_CODE_CE_CMP; + Record.push_back(VE.getTypeID(C->getOperand(0)->getType())); + Record.push_back(VE.getValueID(C->getOperand(0))); + Record.push_back(VE.getValueID(C->getOperand(1))); + Record.push_back(CE->getPredicate()); + break; + } + } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(C)) { + Code = bitc::CST_CODE_BLOCKADDRESS; + Record.push_back(VE.getTypeID(BA->getFunction()->getType())); + Record.push_back(VE.getValueID(BA->getFunction())); + Record.push_back(VE.getGlobalBasicBlockID(BA->getBasicBlock())); + } else { +#ifndef NDEBUG + C->dump(); +#endif + llvm_unreachable("Unknown constant!"); + } + Stream.EmitRecord(Code, Record, AbbrevToUse); + Record.clear(); + } + + Stream.ExitBlock(); +} + +static void WriteModuleConstants(const ValueEnumerator &VE, + BitstreamWriter &Stream) { + const ValueEnumerator::ValueList &Vals = VE.getValues(); + + // Find the first constant to emit, which is the first non-globalvalue value. + // We know globalvalues have been emitted by WriteModuleInfo. + for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + if (!isa<GlobalValue>(Vals[i].first)) { + WriteConstants(i, Vals.size(), VE, Stream, true); + return; + } + } +} + +/// PushValueAndType - The file has to encode both the value and type id for +/// many values, because we need to know what type to create for forward +/// references. However, most operands are not forward references, so this type +/// field is not needed. +/// +/// This function adds V's value ID to Vals. If the value ID is higher than the +/// instruction ID, then it is a forward reference, and it also includes the +/// type ID. The value ID that is written is encoded relative to the InstID. +static bool PushValueAndType(const Value *V, unsigned InstID, + SmallVectorImpl<unsigned> &Vals, + ValueEnumerator &VE) { + unsigned ValID = VE.getValueID(V); + // Make encoding relative to the InstID. + Vals.push_back(InstID - ValID); + if (ValID >= InstID) { + Vals.push_back(VE.getTypeID(V->getType())); + return true; + } + return false; +} + +/// pushValue - Like PushValueAndType, but where the type of the value is +/// omitted (perhaps it was already encoded in an earlier operand). +static void pushValue(const Value *V, unsigned InstID, + SmallVectorImpl<unsigned> &Vals, + ValueEnumerator &VE) { + unsigned ValID = VE.getValueID(V); + Vals.push_back(InstID - ValID); +} + +static void pushValueSigned(const Value *V, unsigned InstID, + SmallVectorImpl<uint64_t> &Vals, + ValueEnumerator &VE) { + unsigned ValID = VE.getValueID(V); + int64_t diff = ((int32_t)InstID - (int32_t)ValID); + emitSignedInt64(Vals, diff); +} + +/// WriteInstruction - Emit an instruction to the specified stream. +static void WriteInstruction(const Instruction &I, unsigned InstID, + ValueEnumerator &VE, BitstreamWriter &Stream, + SmallVectorImpl<unsigned> &Vals) { + unsigned Code = 0; + unsigned AbbrevToUse = 0; + VE.setInstructionID(&I); + switch (I.getOpcode()) { + default: + if (Instruction::isCast(I.getOpcode())) { + Code = bitc::FUNC_CODE_INST_CAST; + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) + AbbrevToUse = FUNCTION_INST_CAST_ABBREV; + Vals.push_back(VE.getTypeID(I.getType())); + Vals.push_back(GetEncodedCastOpcode(I.getOpcode())); + } else { + assert(isa<BinaryOperator>(I) && "Unknown instruction!"); + Code = bitc::FUNC_CODE_INST_BINOP; + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) + AbbrevToUse = FUNCTION_INST_BINOP_ABBREV; + pushValue(I.getOperand(1), InstID, Vals, VE); + Vals.push_back(GetEncodedBinaryOpcode(I.getOpcode())); + uint64_t Flags = GetOptimizationFlags(&I); + if (Flags != 0) { + if (AbbrevToUse == FUNCTION_INST_BINOP_ABBREV) + AbbrevToUse = FUNCTION_INST_BINOP_FLAGS_ABBREV; + Vals.push_back(Flags); + } + } + break; + + case Instruction::GetElementPtr: { + Code = bitc::FUNC_CODE_INST_GEP; + AbbrevToUse = FUNCTION_INST_GEP_ABBREV; + auto &GEPInst = cast<GetElementPtrInst>(I); + Vals.push_back(GEPInst.isInBounds()); + Vals.push_back(VE.getTypeID(GEPInst.getSourceElementType())); + for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i) + PushValueAndType(I.getOperand(i), InstID, Vals, VE); + break; + } + case Instruction::ExtractValue: { + Code = bitc::FUNC_CODE_INST_EXTRACTVAL; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + const ExtractValueInst *EVI = cast<ExtractValueInst>(&I); + Vals.append(EVI->idx_begin(), EVI->idx_end()); + break; + } + case Instruction::InsertValue: { + Code = bitc::FUNC_CODE_INST_INSERTVAL; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + PushValueAndType(I.getOperand(1), InstID, Vals, VE); + const InsertValueInst *IVI = cast<InsertValueInst>(&I); + Vals.append(IVI->idx_begin(), IVI->idx_end()); + break; + } + case Instruction::Select: + Code = bitc::FUNC_CODE_INST_VSELECT; + PushValueAndType(I.getOperand(1), InstID, Vals, VE); + pushValue(I.getOperand(2), InstID, Vals, VE); + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + break; + case Instruction::ExtractElement: + Code = bitc::FUNC_CODE_INST_EXTRACTELT; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + PushValueAndType(I.getOperand(1), InstID, Vals, VE); + break; + case Instruction::InsertElement: + Code = bitc::FUNC_CODE_INST_INSERTELT; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + pushValue(I.getOperand(1), InstID, Vals, VE); + PushValueAndType(I.getOperand(2), InstID, Vals, VE); + break; + case Instruction::ShuffleVector: + Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + pushValue(I.getOperand(1), InstID, Vals, VE); + pushValue(I.getOperand(2), InstID, Vals, VE); + break; + case Instruction::ICmp: + case Instruction::FCmp: + // compare returning Int1Ty or vector of Int1Ty + Code = bitc::FUNC_CODE_INST_CMP2; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + pushValue(I.getOperand(1), InstID, Vals, VE); + Vals.push_back(cast<CmpInst>(I).getPredicate()); + break; + + case Instruction::Ret: + { + Code = bitc::FUNC_CODE_INST_RET; + unsigned NumOperands = I.getNumOperands(); + if (NumOperands == 0) + AbbrevToUse = FUNCTION_INST_RET_VOID_ABBREV; + else if (NumOperands == 1) { + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) + AbbrevToUse = FUNCTION_INST_RET_VAL_ABBREV; + } else { + for (unsigned i = 0, e = NumOperands; i != e; ++i) + PushValueAndType(I.getOperand(i), InstID, Vals, VE); + } + } + break; + case Instruction::Br: + { + Code = bitc::FUNC_CODE_INST_BR; + const BranchInst &II = cast<BranchInst>(I); + Vals.push_back(VE.getValueID(II.getSuccessor(0))); + if (II.isConditional()) { + Vals.push_back(VE.getValueID(II.getSuccessor(1))); + pushValue(II.getCondition(), InstID, Vals, VE); + } + } + break; + case Instruction::Switch: + { + Code = bitc::FUNC_CODE_INST_SWITCH; + const SwitchInst &SI = cast<SwitchInst>(I); + Vals.push_back(VE.getTypeID(SI.getCondition()->getType())); + pushValue(SI.getCondition(), InstID, Vals, VE); + Vals.push_back(VE.getValueID(SI.getDefaultDest())); + for (SwitchInst::ConstCaseIt i = SI.case_begin(), e = SI.case_end(); + i != e; ++i) { + Vals.push_back(VE.getValueID(i.getCaseValue())); + Vals.push_back(VE.getValueID(i.getCaseSuccessor())); + } + } + break; + case Instruction::IndirectBr: + Code = bitc::FUNC_CODE_INST_INDIRECTBR; + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); + // Encode the address operand as relative, but not the basic blocks. + pushValue(I.getOperand(0), InstID, Vals, VE); + for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) + Vals.push_back(VE.getValueID(I.getOperand(i))); + break; + + case Instruction::Invoke: { + const InvokeInst *II = cast<InvokeInst>(&I); + const Value *Callee = II->getCalledValue(); + FunctionType *FTy = II->getFunctionType(); + Code = bitc::FUNC_CODE_INST_INVOKE; + + Vals.push_back(VE.getAttributeID(II->getAttributes())); + Vals.push_back(II->getCallingConv() | 1 << 13); + Vals.push_back(VE.getValueID(II->getNormalDest())); + Vals.push_back(VE.getValueID(II->getUnwindDest())); + Vals.push_back(VE.getTypeID(FTy)); + PushValueAndType(Callee, InstID, Vals, VE); + + // Emit value #'s for the fixed parameters. + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) + pushValue(I.getOperand(i), InstID, Vals, VE); // fixed param. + + // Emit type/value pairs for varargs params. + if (FTy->isVarArg()) { + for (unsigned i = FTy->getNumParams(), e = I.getNumOperands()-3; + i != e; ++i) + PushValueAndType(I.getOperand(i), InstID, Vals, VE); // vararg + } + break; + } + case Instruction::Resume: + Code = bitc::FUNC_CODE_INST_RESUME; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + break; + case Instruction::Unreachable: + Code = bitc::FUNC_CODE_INST_UNREACHABLE; + AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV; + break; + + case Instruction::PHI: { + const PHINode &PN = cast<PHINode>(I); + Code = bitc::FUNC_CODE_INST_PHI; + // With the newer instruction encoding, forward references could give + // negative valued IDs. This is most common for PHIs, so we use + // signed VBRs. + SmallVector<uint64_t, 128> Vals64; + Vals64.push_back(VE.getTypeID(PN.getType())); + for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { + pushValueSigned(PN.getIncomingValue(i), InstID, Vals64, VE); + Vals64.push_back(VE.getValueID(PN.getIncomingBlock(i))); + } + // Emit a Vals64 vector and exit. + Stream.EmitRecord(Code, Vals64, AbbrevToUse); + Vals64.clear(); + return; + } + + case Instruction::LandingPad: { + const LandingPadInst &LP = cast<LandingPadInst>(I); + Code = bitc::FUNC_CODE_INST_LANDINGPAD; + Vals.push_back(VE.getTypeID(LP.getType())); + Vals.push_back(LP.isCleanup()); + Vals.push_back(LP.getNumClauses()); + for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { + if (LP.isCatch(I)) + Vals.push_back(LandingPadInst::Catch); + else + Vals.push_back(LandingPadInst::Filter); + PushValueAndType(LP.getClause(I), InstID, Vals, VE); + } + break; + } + + case Instruction::Alloca: { + Code = bitc::FUNC_CODE_INST_ALLOCA; + const AllocaInst &AI = cast<AllocaInst>(I); + Vals.push_back(VE.getTypeID(AI.getAllocatedType())); + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); + Vals.push_back(VE.getValueID(I.getOperand(0))); // size. + unsigned AlignRecord = Log2_32(AI.getAlignment()) + 1; + assert(Log2_32(Value::MaximumAlignment) + 1 < 1 << 5 && + "not enough bits for maximum alignment"); + assert(AlignRecord < 1 << 5 && "alignment greater than 1 << 64"); + AlignRecord |= AI.isUsedWithInAlloca() << 5; + AlignRecord |= 1 << 6; + Vals.push_back(AlignRecord); + break; + } + + case Instruction::Load: + if (cast<LoadInst>(I).isAtomic()) { + Code = bitc::FUNC_CODE_INST_LOADATOMIC; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); + } else { + Code = bitc::FUNC_CODE_INST_LOAD; + if (!PushValueAndType(I.getOperand(0), InstID, Vals, VE)) // ptr + AbbrevToUse = FUNCTION_INST_LOAD_ABBREV; + } + Vals.push_back(VE.getTypeID(I.getType())); + Vals.push_back(Log2_32(cast<LoadInst>(I).getAlignment())+1); + Vals.push_back(cast<LoadInst>(I).isVolatile()); + if (cast<LoadInst>(I).isAtomic()) { + Vals.push_back(GetEncodedOrdering(cast<LoadInst>(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast<LoadInst>(I).getSynchScope())); + } + break; + case Instruction::Store: + if (cast<StoreInst>(I).isAtomic()) + Code = bitc::FUNC_CODE_INST_STOREATOMIC; + else + Code = bitc::FUNC_CODE_INST_STORE; + PushValueAndType(I.getOperand(1), InstID, Vals, VE); // ptrty + ptr + PushValueAndType(I.getOperand(0), InstID, Vals, VE); // valty + val + Vals.push_back(Log2_32(cast<StoreInst>(I).getAlignment())+1); + Vals.push_back(cast<StoreInst>(I).isVolatile()); + if (cast<StoreInst>(I).isAtomic()) { + Vals.push_back(GetEncodedOrdering(cast<StoreInst>(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast<StoreInst>(I).getSynchScope())); + } + break; + case Instruction::AtomicCmpXchg: + Code = bitc::FUNC_CODE_INST_CMPXCHG; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr + PushValueAndType(I.getOperand(1), InstID, Vals, VE); // cmp. + pushValue(I.getOperand(2), InstID, Vals, VE); // newval. + Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile()); + Vals.push_back(GetEncodedOrdering( + cast<AtomicCmpXchgInst>(I).getSuccessOrdering())); + Vals.push_back(GetEncodedSynchScope( + cast<AtomicCmpXchgInst>(I).getSynchScope())); + Vals.push_back(GetEncodedOrdering( + cast<AtomicCmpXchgInst>(I).getFailureOrdering())); + Vals.push_back(cast<AtomicCmpXchgInst>(I).isWeak()); + break; + case Instruction::AtomicRMW: + Code = bitc::FUNC_CODE_INST_ATOMICRMW; + PushValueAndType(I.getOperand(0), InstID, Vals, VE); // ptrty + ptr + pushValue(I.getOperand(1), InstID, Vals, VE); // val. + Vals.push_back(GetEncodedRMWOperation( + cast<AtomicRMWInst>(I).getOperation())); + Vals.push_back(cast<AtomicRMWInst>(I).isVolatile()); + Vals.push_back(GetEncodedOrdering(cast<AtomicRMWInst>(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope( + cast<AtomicRMWInst>(I).getSynchScope())); + break; + case Instruction::Fence: + Code = bitc::FUNC_CODE_INST_FENCE; + Vals.push_back(GetEncodedOrdering(cast<FenceInst>(I).getOrdering())); + Vals.push_back(GetEncodedSynchScope(cast<FenceInst>(I).getSynchScope())); + break; + case Instruction::Call: { + const CallInst &CI = cast<CallInst>(I); + FunctionType *FTy = CI.getFunctionType(); + + Code = bitc::FUNC_CODE_INST_CALL; + + Vals.push_back(VE.getAttributeID(CI.getAttributes())); + Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) | + unsigned(CI.isMustTailCall()) << 14 | 1 << 15); + Vals.push_back(VE.getTypeID(FTy)); + PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee + + // Emit value #'s for the fixed parameters. + for (unsigned i = 0, e = FTy->getNumParams(); i != e; ++i) { + // Check for labels (can happen with asm labels). + if (FTy->getParamType(i)->isLabelTy()) + Vals.push_back(VE.getValueID(CI.getArgOperand(i))); + else + pushValue(CI.getArgOperand(i), InstID, Vals, VE); // fixed param. + } + + // Emit type/value pairs for varargs params. + if (FTy->isVarArg()) { + for (unsigned i = FTy->getNumParams(), e = CI.getNumArgOperands(); + i != e; ++i) + PushValueAndType(CI.getArgOperand(i), InstID, Vals, VE); // varargs + } + break; + } + case Instruction::VAArg: + Code = bitc::FUNC_CODE_INST_VAARG; + Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); // valistty + pushValue(I.getOperand(0), InstID, Vals, VE); // valist. + Vals.push_back(VE.getTypeID(I.getType())); // restype. + break; + } + + Stream.EmitRecord(Code, Vals, AbbrevToUse); + Vals.clear(); +} + +// Emit names for globals/functions etc. +static void WriteValueSymbolTable(const ValueSymbolTable &VST, + const ValueEnumerator &VE, + BitstreamWriter &Stream) { + if (VST.empty()) return; + Stream.EnterSubblock(bitc::VALUE_SYMTAB_BLOCK_ID, 4); + + // FIXME: Set up the abbrev, we know how many values there are! + // FIXME: We know if the type names can use 7-bit ascii. + SmallVector<unsigned, 64> NameVals; + + for (ValueSymbolTable::const_iterator SI = VST.begin(), SE = VST.end(); + SI != SE; ++SI) { + + const ValueName &Name = *SI; + + // Figure out the encoding to use for the name. + bool is7Bit = true; + bool isChar6 = true; + for (const char *C = Name.getKeyData(), *E = C+Name.getKeyLength(); + C != E; ++C) { + if (isChar6) + isChar6 = BitCodeAbbrevOp::isChar6(*C); + if ((unsigned char)*C & 128) { + is7Bit = false; + break; // don't bother scanning the rest. + } + } + + unsigned AbbrevToUse = VST_ENTRY_8_ABBREV; + + // VST_ENTRY: [valueid, namechar x N] + // VST_BBENTRY: [bbid, namechar x N] + unsigned Code; + if (isa<BasicBlock>(SI->getValue())) { + Code = bitc::VST_CODE_BBENTRY; + if (isChar6) + AbbrevToUse = VST_BBENTRY_6_ABBREV; + } else { + Code = bitc::VST_CODE_ENTRY; + if (isChar6) + AbbrevToUse = VST_ENTRY_6_ABBREV; + else if (is7Bit) + AbbrevToUse = VST_ENTRY_7_ABBREV; + } + + NameVals.push_back(VE.getValueID(SI->getValue())); + for (const char *P = Name.getKeyData(), + *E = Name.getKeyData()+Name.getKeyLength(); P != E; ++P) + NameVals.push_back((unsigned char)*P); + + // Emit the finished record. + Stream.EmitRecord(Code, NameVals, AbbrevToUse); + NameVals.clear(); + } + Stream.ExitBlock(); +} + +static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order, + BitstreamWriter &Stream) { + assert(Order.Shuffle.size() >= 2 && "Shuffle too small"); + unsigned Code; + if (isa<BasicBlock>(Order.V)) + Code = bitc::USELIST_CODE_BB; + else + Code = bitc::USELIST_CODE_DEFAULT; + + SmallVector<uint64_t, 64> Record(Order.Shuffle.begin(), Order.Shuffle.end()); + Record.push_back(VE.getValueID(Order.V)); + Stream.EmitRecord(Code, Record); +} + +static void WriteUseListBlock(const Function *F, ValueEnumerator &VE, + BitstreamWriter &Stream) { + assert(VE.shouldPreserveUseListOrder() && + "Expected to be preserving use-list order"); + + auto hasMore = [&]() { + return !VE.UseListOrders.empty() && VE.UseListOrders.back().F == F; + }; + if (!hasMore()) + // Nothing to do. + return; + + Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3); + while (hasMore()) { + WriteUseList(VE, std::move(VE.UseListOrders.back()), Stream); + VE.UseListOrders.pop_back(); + } + Stream.ExitBlock(); +} + +/// WriteFunction - Emit a function body to the module stream. +static void WriteFunction(const Function &F, ValueEnumerator &VE, + BitstreamWriter &Stream) { + Stream.EnterSubblock(bitc::FUNCTION_BLOCK_ID, 4); + VE.incorporateFunction(F); + + SmallVector<unsigned, 64> Vals; + + // Emit the number of basic blocks, so the reader can create them ahead of + // time. + Vals.push_back(VE.getBasicBlocks().size()); + Stream.EmitRecord(bitc::FUNC_CODE_DECLAREBLOCKS, Vals); + Vals.clear(); + + // If there are function-local constants, emit them now. + unsigned CstStart, CstEnd; + VE.getFunctionConstantRange(CstStart, CstEnd); + WriteConstants(CstStart, CstEnd, VE, Stream, false); + + // If there is function-local metadata, emit it now. + WriteFunctionLocalMetadata(F, VE, Stream); + + // Keep a running idea of what the instruction ID is. + unsigned InstID = CstEnd; + + bool NeedsMetadataAttachment = F.hasMetadata(); + + DILocation *LastDL = nullptr; + + // Finally, emit all the instructions, in order. + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); + I != E; ++I) { + WriteInstruction(*I, InstID, VE, Stream, Vals); + + if (!I->getType()->isVoidTy()) + ++InstID; + + // If the instruction has metadata, write a metadata attachment later. + NeedsMetadataAttachment |= I->hasMetadataOtherThanDebugLoc(); + + // If the instruction has a debug location, emit it. + DILocation *DL = I->getDebugLoc(); + if (!DL) + continue; + + if (DL == LastDL) { + // Just repeat the same debug loc as last time. + Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC_AGAIN, Vals); + continue; + } + + Vals.push_back(DL->getLine()); + Vals.push_back(DL->getColumn()); + Vals.push_back(VE.getMetadataOrNullID(DL->getScope())); + Vals.push_back(VE.getMetadataOrNullID(DL->getInlinedAt())); + Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); + Vals.clear(); + + LastDL = DL; + } + + // Emit names for all the instructions etc. + WriteValueSymbolTable(F.getValueSymbolTable(), VE, Stream); + + if (NeedsMetadataAttachment) + WriteMetadataAttachment(F, VE, Stream); + if (VE.shouldPreserveUseListOrder()) + WriteUseListBlock(&F, VE, Stream); + VE.purgeFunction(); + Stream.ExitBlock(); +} + +// Emit blockinfo, which defines the standard abbreviations etc. +static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { + // We only want to emit block info records for blocks that have multiple + // instances: CONSTANTS_BLOCK, FUNCTION_BLOCK and VALUE_SYMTAB_BLOCK. + // Other blocks can define their abbrevs inline. + Stream.EnterBlockInfoBlock(2); + + { // 8-bit fixed-width VST_ENTRY/VST_BBENTRY strings. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 3)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 8)); + if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, + Abbv) != VST_ENTRY_8_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + { // 7-bit fixed width VST_ENTRY strings. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); + if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, + Abbv) != VST_ENTRY_7_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // 6-bit char6 VST_ENTRY strings. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_ENTRY)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, + Abbv) != VST_ENTRY_6_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // 6-bit char6 VST_BBENTRY strings. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::VST_CODE_BBENTRY)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Char6)); + if (Stream.EmitBlockInfoAbbrev(bitc::VALUE_SYMTAB_BLOCK_ID, + Abbv) != VST_BBENTRY_6_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + + + { // SETTYPE abbrev for CONSTANTS_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_SETTYPE)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, + VE.computeBitsRequiredForTypeIndicies())); + if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, + Abbv) != CONSTANTS_SETTYPE_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + { // INTEGER abbrev for CONSTANTS_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_INTEGER)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); + if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, + Abbv) != CONSTANTS_INTEGER_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + { // CE_CAST abbrev for CONSTANTS_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_CE_CAST)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // cast opc + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // typeid + VE.computeBitsRequiredForTypeIndicies())); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); // value id + + if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, + Abbv) != CONSTANTS_CE_CAST_Abbrev) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // NULL abbrev for CONSTANTS_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::CST_CODE_NULL)); + if (Stream.EmitBlockInfoAbbrev(bitc::CONSTANTS_BLOCK_ID, + Abbv) != CONSTANTS_NULL_Abbrev) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + // FIXME: This should only use space for first class types! + + { // INST_LOAD abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_LOAD)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Ptr + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + VE.computeBitsRequiredForTypeIndicies())); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // Align + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // volatile + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_LOAD_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // INST_BINOP abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_BINOP_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // INST_BINOP_FLAGS abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_BINOP)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // LHS + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // RHS + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 7)); // flags + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_BINOP_FLAGS_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // INST_CAST abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_CAST)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // OpVal + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + VE.computeBitsRequiredForTypeIndicies())); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // opc + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_CAST_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + { // INST_RET abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_RET_VOID_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // INST_RET abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_RET)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // ValID + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_RET_VAL_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { // INST_UNREACHABLE abbrev for FUNCTION_BLOCK. + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_UNREACHABLE)); + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, + Abbv) != FUNCTION_INST_UNREACHABLE_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + { + BitCodeAbbrev *Abbv = new BitCodeAbbrev(); + Abbv->Add(BitCodeAbbrevOp(bitc::FUNC_CODE_INST_GEP)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, // dest ty + Log2_32_Ceil(VE.getTypes().size() + 1))); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); + if (Stream.EmitBlockInfoAbbrev(bitc::FUNCTION_BLOCK_ID, Abbv) != + FUNCTION_INST_GEP_ABBREV) + llvm_unreachable("Unexpected abbrev ordering!"); + } + + Stream.ExitBlock(); +} + +/// WriteModule - Emit the specified module to the bitstream. +static void WriteModule(const Module *M, BitstreamWriter &Stream, + bool ShouldPreserveUseListOrder) { + Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); + + SmallVector<unsigned, 1> Vals; + unsigned CurVersion = 1; + Vals.push_back(CurVersion); + Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); + + // Analyze the module, enumerating globals, functions, etc. + ValueEnumerator VE(*M, ShouldPreserveUseListOrder); + + // Emit blockinfo, which defines the standard abbreviations etc. + WriteBlockInfo(VE, Stream); + + // Emit information about attribute groups. + WriteAttributeGroupTable(VE, Stream); + + // Emit information about parameter attributes. + WriteAttributeTable(VE, Stream); + + // Emit information describing all of the types in the module. + WriteTypeTable(VE, Stream); + + writeComdats(VE, Stream); + + // Emit top-level description of module, including target triple, inline asm, + // descriptors for global variables, and function prototype info. + WriteModuleInfo(M, VE, Stream); + + // Emit constants. + WriteModuleConstants(VE, Stream); + + // Emit metadata. + WriteModuleMetadata(M, VE, Stream); + + // Emit metadata. + WriteModuleMetadataStore(M, Stream); + + // Emit names for globals/functions etc. + WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); + + // Emit module-level use-lists. + if (VE.shouldPreserveUseListOrder()) + WriteUseListBlock(nullptr, VE, Stream); + + // Emit function bodies. + for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) + if (!F->isDeclaration()) + WriteFunction(*F, VE, Stream); + + Stream.ExitBlock(); +} + +/// EmitDarwinBCHeader - If generating a bc file on darwin, we have to emit a +/// header and trailer to make it compatible with the system archiver. To do +/// this we emit the following header, and then emit a trailer that pads the +/// file out to be a multiple of 16 bytes. +/// +/// struct bc_header { +/// uint32_t Magic; // 0x0B17C0DE +/// uint32_t Version; // Version, currently always 0. +/// uint32_t BitcodeOffset; // Offset to traditional bitcode file. +/// uint32_t BitcodeSize; // Size of traditional bitcode file. +/// uint32_t CPUType; // CPU specifier. +/// ... potentially more later ... +/// }; +enum { + DarwinBCSizeFieldOffset = 3*4, // Offset to bitcode_size. + DarwinBCHeaderSize = 5*4 +}; + +static void WriteInt32ToBuffer(uint32_t Value, SmallVectorImpl<char> &Buffer, + uint32_t &Position) { + support::endian::write32le(&Buffer[Position], Value); + Position += 4; +} + +static void EmitDarwinBCHeaderAndTrailer(SmallVectorImpl<char> &Buffer, + const Triple &TT) { + unsigned CPUType = ~0U; + + // Match x86_64-*, i[3-9]86-*, powerpc-*, powerpc64-*, arm-*, thumb-*, + // armv[0-9]-*, thumbv[0-9]-*, armv5te-*, or armv6t2-*. The CPUType is a magic + // number from /usr/include/mach/machine.h. It is ok to reproduce the + // specific constants here because they are implicitly part of the Darwin ABI. + enum { + DARWIN_CPU_ARCH_ABI64 = 0x01000000, + DARWIN_CPU_TYPE_X86 = 7, + DARWIN_CPU_TYPE_ARM = 12, + DARWIN_CPU_TYPE_POWERPC = 18 + }; + + Triple::ArchType Arch = TT.getArch(); + if (Arch == Triple::x86_64) + CPUType = DARWIN_CPU_TYPE_X86 | DARWIN_CPU_ARCH_ABI64; + else if (Arch == Triple::x86) + CPUType = DARWIN_CPU_TYPE_X86; + else if (Arch == Triple::ppc) + CPUType = DARWIN_CPU_TYPE_POWERPC; + else if (Arch == Triple::ppc64) + CPUType = DARWIN_CPU_TYPE_POWERPC | DARWIN_CPU_ARCH_ABI64; + else if (Arch == Triple::arm || Arch == Triple::thumb) + CPUType = DARWIN_CPU_TYPE_ARM; + + // Traditional Bitcode starts after header. + assert(Buffer.size() >= DarwinBCHeaderSize && + "Expected header size to be reserved"); + unsigned BCOffset = DarwinBCHeaderSize; + unsigned BCSize = Buffer.size()-DarwinBCHeaderSize; + + // Write the magic and version. + unsigned Position = 0; + WriteInt32ToBuffer(0x0B17C0DE , Buffer, Position); + WriteInt32ToBuffer(0 , Buffer, Position); // Version. + WriteInt32ToBuffer(BCOffset , Buffer, Position); + WriteInt32ToBuffer(BCSize , Buffer, Position); + WriteInt32ToBuffer(CPUType , Buffer, Position); + + // If the file is not a multiple of 16 bytes, insert dummy padding. + while (Buffer.size() & 15) + Buffer.push_back(0); +} + +/// WriteBitcodeToFile - Write the specified module to the specified output +/// stream. +void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out, + bool ShouldPreserveUseListOrder) { + SmallVector<char, 0> Buffer; + Buffer.reserve(256*1024); + + // If this is darwin or another generic macho target, reserve space for the + // header. + Triple TT(M->getTargetTriple()); + if (TT.isOSDarwin()) + Buffer.insert(Buffer.begin(), DarwinBCHeaderSize, 0); + + // Emit the module into the buffer. + { + BitstreamWriter Stream(Buffer); + + // Emit the file header. + Stream.Emit((unsigned)'B', 8); + Stream.Emit((unsigned)'C', 8); + Stream.Emit(0x0, 4); + Stream.Emit(0xC, 4); + Stream.Emit(0xE, 4); + Stream.Emit(0xD, 4); + + // Emit the module. + WriteModule(M, Stream, ShouldPreserveUseListOrder); + } + + if (TT.isOSDarwin()) + EmitDarwinBCHeaderAndTrailer(Buffer, TT); + + // Write the generated bitstream to "Out". + Out.write((char*)&Buffer.front(), Buffer.size()); +} diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp new file mode 100644 index 0000000..c890380 --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp @@ -0,0 +1,51 @@ +//===- BitcodeWriterPass.cpp - Bitcode writing pass -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// BitcodeWriterPass implementation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitcodeWriterPass.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassManager.h" +#include "llvm/Pass.h" +using namespace llvm; + +PreservedAnalyses BitcodeWriterPass::run(Module &M) { + WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder); + return PreservedAnalyses::all(); +} + +namespace { + class WriteBitcodePass : public ModulePass { + raw_ostream &OS; // raw_ostream to print on + bool ShouldPreserveUseListOrder; + + public: + static char ID; // Pass identification, replacement for typeid + explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder) + : ModulePass(ID), OS(o), + ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {} + + const char *getPassName() const override { return "Bitcode Writer"; } + + bool runOnModule(Module &M) override { + WriteBitcodeToFile(&M, OS, ShouldPreserveUseListOrder); + return false; + } + }; +} // namespace + +char WriteBitcodePass::ID = 0; + +ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str, + bool ShouldPreserveUseListOrder) { + return new WriteBitcodePass(Str, ShouldPreserveUseListOrder); +} diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp new file mode 100644 index 0000000..53c3a40 --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -0,0 +1,820 @@ +//===-- ValueEnumerator.cpp - Number values and types for bitcode writer --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the ValueEnumerator class. +// +//===----------------------------------------------------------------------===// + +#include "ValueEnumerator.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DebugInfoMetadata.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/UseListOrder.h" +#include "llvm/IR/ValueSymbolTable.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +using namespace llvm; + +namespace { +struct OrderMap { + DenseMap<const Value *, std::pair<unsigned, bool>> IDs; + unsigned LastGlobalConstantID; + unsigned LastGlobalValueID; + + OrderMap() : LastGlobalConstantID(0), LastGlobalValueID(0) {} + + bool isGlobalConstant(unsigned ID) const { + return ID <= LastGlobalConstantID; + } + bool isGlobalValue(unsigned ID) const { + return ID <= LastGlobalValueID && !isGlobalConstant(ID); + } + + unsigned size() const { return IDs.size(); } + std::pair<unsigned, bool> &operator[](const Value *V) { return IDs[V]; } + std::pair<unsigned, bool> lookup(const Value *V) const { + return IDs.lookup(V); + } + void index(const Value *V) { + // Explicitly sequence get-size and insert-value operations to avoid UB. + unsigned ID = IDs.size() + 1; + IDs[V].first = ID; + } +}; +} // namespace + +static void orderValue(const Value *V, OrderMap &OM) { + if (OM.lookup(V).first) + return; + + if (const Constant *C = dyn_cast<Constant>(V)) + if (C->getNumOperands() && !isa<GlobalValue>(C)) + for (const Value *Op : C->operands()) + if (!isa<BasicBlock>(Op) && !isa<GlobalValue>(Op)) + orderValue(Op, OM); + + // Note: we cannot cache this lookup above, since inserting into the map + // changes the map's size, and thus affects the other IDs. + OM.index(V); +} + +static OrderMap orderModule(const Module &M) { + // This needs to match the order used by ValueEnumerator::ValueEnumerator() + // and ValueEnumerator::incorporateFunction(). + OrderMap OM; + + // In the reader, initializers of GlobalValues are set *after* all the + // globals have been read. Rather than awkwardly modeling this behaviour + // directly in predictValueUseListOrderImpl(), just assign IDs to + // initializers of GlobalValues before GlobalValues themselves to model this + // implicitly. + for (const GlobalVariable &G : M.globals()) + if (G.hasInitializer()) + if (!isa<GlobalValue>(G.getInitializer())) + orderValue(G.getInitializer(), OM); + for (const GlobalAlias &A : M.aliases()) + if (!isa<GlobalValue>(A.getAliasee())) + orderValue(A.getAliasee(), OM); + for (const Function &F : M) { + if (F.hasPrefixData()) + if (!isa<GlobalValue>(F.getPrefixData())) + orderValue(F.getPrefixData(), OM); + if (F.hasPrologueData()) + if (!isa<GlobalValue>(F.getPrologueData())) + orderValue(F.getPrologueData(), OM); + if (F.hasPersonalityFn()) + if (!isa<GlobalValue>(F.getPersonalityFn())) + orderValue(F.getPersonalityFn(), OM); + } + OM.LastGlobalConstantID = OM.size(); + + // Initializers of GlobalValues are processed in + // BitcodeReader::ResolveGlobalAndAliasInits(). Match the order there rather + // than ValueEnumerator, and match the code in predictValueUseListOrderImpl() + // by giving IDs in reverse order. + // + // Since GlobalValues never reference each other directly (just through + // initializers), their relative IDs only matter for determining order of + // uses in their initializers. + for (const Function &F : M) + orderValue(&F, OM); + for (const GlobalAlias &A : M.aliases()) + orderValue(&A, OM); + for (const GlobalVariable &G : M.globals()) + orderValue(&G, OM); + OM.LastGlobalValueID = OM.size(); + + for (const Function &F : M) { + if (F.isDeclaration()) + continue; + // Here we need to match the union of ValueEnumerator::incorporateFunction() + // and WriteFunction(). Basic blocks are implicitly declared before + // anything else (by declaring their size). + for (const BasicBlock &BB : F) + orderValue(&BB, OM); + for (const Argument &A : F.args()) + orderValue(&A, OM); + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + for (const Value *Op : I.operands()) + if ((isa<Constant>(*Op) && !isa<GlobalValue>(*Op)) || + isa<InlineAsm>(*Op)) + orderValue(Op, OM); + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + orderValue(&I, OM); + } + return OM; +} + +static void predictValueUseListOrderImpl(const Value *V, const Function *F, + unsigned ID, const OrderMap &OM, + UseListOrderStack &Stack) { + // Predict use-list order for this one. + typedef std::pair<const Use *, unsigned> Entry; + SmallVector<Entry, 64> List; + for (const Use &U : V->uses()) + // Check if this user will be serialized. + if (OM.lookup(U.getUser()).first) + List.push_back(std::make_pair(&U, List.size())); + + if (List.size() < 2) + // We may have lost some users. + return; + + bool IsGlobalValue = OM.isGlobalValue(ID); + std::sort(List.begin(), List.end(), [&](const Entry &L, const Entry &R) { + const Use *LU = L.first; + const Use *RU = R.first; + if (LU == RU) + return false; + + auto LID = OM.lookup(LU->getUser()).first; + auto RID = OM.lookup(RU->getUser()).first; + + // Global values are processed in reverse order. + // + // Moreover, initializers of GlobalValues are set *after* all the globals + // have been read (despite having earlier IDs). Rather than awkwardly + // modeling this behaviour here, orderModule() has assigned IDs to + // initializers of GlobalValues before GlobalValues themselves. + if (OM.isGlobalValue(LID) && OM.isGlobalValue(RID)) + return LID < RID; + + // If ID is 4, then expect: 7 6 5 1 2 3. + if (LID < RID) { + if (RID <= ID) + if (!IsGlobalValue) // GlobalValue uses don't get reversed. + return true; + return false; + } + if (RID < LID) { + if (LID <= ID) + if (!IsGlobalValue) // GlobalValue uses don't get reversed. + return false; + return true; + } + + // LID and RID are equal, so we have different operands of the same user. + // Assume operands are added in order for all instructions. + if (LID <= ID) + if (!IsGlobalValue) // GlobalValue uses don't get reversed. + return LU->getOperandNo() < RU->getOperandNo(); + return LU->getOperandNo() > RU->getOperandNo(); + }); + + if (std::is_sorted( + List.begin(), List.end(), + [](const Entry &L, const Entry &R) { return L.second < R.second; })) + // Order is already correct. + return; + + // Store the shuffle. + Stack.emplace_back(V, F, List.size()); + assert(List.size() == Stack.back().Shuffle.size() && "Wrong size"); + for (size_t I = 0, E = List.size(); I != E; ++I) + Stack.back().Shuffle[I] = List[I].second; +} + +static void predictValueUseListOrder(const Value *V, const Function *F, + OrderMap &OM, UseListOrderStack &Stack) { + auto &IDPair = OM[V]; + assert(IDPair.first && "Unmapped value"); + if (IDPair.second) + // Already predicted. + return; + + // Do the actual prediction. + IDPair.second = true; + if (!V->use_empty() && std::next(V->use_begin()) != V->use_end()) + predictValueUseListOrderImpl(V, F, IDPair.first, OM, Stack); + + // Recursive descent into constants. + if (const Constant *C = dyn_cast<Constant>(V)) + if (C->getNumOperands()) // Visit GlobalValues. + for (const Value *Op : C->operands()) + if (isa<Constant>(Op)) // Visit GlobalValues. + predictValueUseListOrder(Op, F, OM, Stack); +} + +static UseListOrderStack predictUseListOrder(const Module &M) { + OrderMap OM = orderModule(M); + + // Use-list orders need to be serialized after all the users have been added + // to a value, or else the shuffles will be incomplete. Store them per + // function in a stack. + // + // Aside from function order, the order of values doesn't matter much here. + UseListOrderStack Stack; + + // We want to visit the functions backward now so we can list function-local + // constants in the last Function they're used in. Module-level constants + // have already been visited above. + for (auto I = M.rbegin(), E = M.rend(); I != E; ++I) { + const Function &F = *I; + if (F.isDeclaration()) + continue; + for (const BasicBlock &BB : F) + predictValueUseListOrder(&BB, &F, OM, Stack); + for (const Argument &A : F.args()) + predictValueUseListOrder(&A, &F, OM, Stack); + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + for (const Value *Op : I.operands()) + if (isa<Constant>(*Op) || isa<InlineAsm>(*Op)) // Visit GlobalValues. + predictValueUseListOrder(Op, &F, OM, Stack); + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) + predictValueUseListOrder(&I, &F, OM, Stack); + } + + // Visit globals last, since the module-level use-list block will be seen + // before the function bodies are processed. + for (const GlobalVariable &G : M.globals()) + predictValueUseListOrder(&G, nullptr, OM, Stack); + for (const Function &F : M) + predictValueUseListOrder(&F, nullptr, OM, Stack); + for (const GlobalAlias &A : M.aliases()) + predictValueUseListOrder(&A, nullptr, OM, Stack); + for (const GlobalVariable &G : M.globals()) + if (G.hasInitializer()) + predictValueUseListOrder(G.getInitializer(), nullptr, OM, Stack); + for (const GlobalAlias &A : M.aliases()) + predictValueUseListOrder(A.getAliasee(), nullptr, OM, Stack); + for (const Function &F : M) { + if (F.hasPrefixData()) + predictValueUseListOrder(F.getPrefixData(), nullptr, OM, Stack); + if (F.hasPrologueData()) + predictValueUseListOrder(F.getPrologueData(), nullptr, OM, Stack); + if (F.hasPersonalityFn()) + predictValueUseListOrder(F.getPersonalityFn(), nullptr, OM, Stack); + } + + return Stack; +} + +static bool isIntOrIntVectorValue(const std::pair<const Value*, unsigned> &V) { + return V.first->getType()->isIntOrIntVectorTy(); +} + +ValueEnumerator::ValueEnumerator(const Module &M, + bool ShouldPreserveUseListOrder) + : HasMDString(false), HasDILocation(false), HasGenericDINode(false), + ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) { + if (ShouldPreserveUseListOrder) + UseListOrders = predictUseListOrder(M); + + // Enumerate the global variables. + for (const GlobalVariable &GV : M.globals()) + EnumerateValue(&GV); + + // Enumerate the functions. + for (const Function & F : M) { + EnumerateValue(&F); + EnumerateAttributes(F.getAttributes()); + } + + // Enumerate the aliases. + for (const GlobalAlias &GA : M.aliases()) + EnumerateValue(&GA); + + // Remember what is the cutoff between globalvalue's and other constants. + unsigned FirstConstant = Values.size(); + + // Enumerate the global variable initializers. + for (const GlobalVariable &GV : M.globals()) + if (GV.hasInitializer()) + EnumerateValue(GV.getInitializer()); + + // Enumerate the aliasees. + for (const GlobalAlias &GA : M.aliases()) + EnumerateValue(GA.getAliasee()); + + // Enumerate the prefix data constants. + for (const Function &F : M) + if (F.hasPrefixData()) + EnumerateValue(F.getPrefixData()); + + // Enumerate the prologue data constants. + for (const Function &F : M) + if (F.hasPrologueData()) + EnumerateValue(F.getPrologueData()); + + // Enumerate the personality functions. + for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) + if (I->hasPersonalityFn()) + EnumerateValue(I->getPersonalityFn()); + + // Enumerate the metadata type. + // + // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode + // only encodes the metadata type when it's used as a value. + EnumerateType(Type::getMetadataTy(M.getContext())); + + // Insert constants and metadata that are named at module level into the slot + // pool so that the module symbol table can refer to them... + EnumerateValueSymbolTable(M.getValueSymbolTable()); + EnumerateNamedMetadata(M); + + SmallVector<std::pair<unsigned, MDNode *>, 8> MDs; + + // Enumerate types used by function bodies and argument lists. + for (const Function &F : M) { + for (const Argument &A : F.args()) + EnumerateType(A.getType()); + + // Enumerate metadata attached to this function. + F.getAllMetadata(MDs); + for (const auto &I : MDs) + EnumerateMetadata(I.second); + + for (const BasicBlock &BB : F) + for (const Instruction &I : BB) { + for (const Use &Op : I.operands()) { + auto *MD = dyn_cast<MetadataAsValue>(&Op); + if (!MD) { + EnumerateOperandType(Op); + continue; + } + + // Local metadata is enumerated during function-incorporation. + if (isa<LocalAsMetadata>(MD->getMetadata())) + continue; + + EnumerateMetadata(MD->getMetadata()); + } + EnumerateType(I.getType()); + if (const CallInst *CI = dyn_cast<CallInst>(&I)) + EnumerateAttributes(CI->getAttributes()); + else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) + EnumerateAttributes(II->getAttributes()); + + // Enumerate metadata attached with this instruction. + MDs.clear(); + I.getAllMetadataOtherThanDebugLoc(MDs); + for (unsigned i = 0, e = MDs.size(); i != e; ++i) + EnumerateMetadata(MDs[i].second); + + // Don't enumerate the location directly -- it has a special record + // type -- but enumerate its operands. + if (DILocation *L = I.getDebugLoc()) + EnumerateMDNodeOperands(L); + } + } + + // Optimize constant ordering. + OptimizeConstants(FirstConstant, Values.size()); +} + +unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const { + InstructionMapType::const_iterator I = InstructionMap.find(Inst); + assert(I != InstructionMap.end() && "Instruction is not mapped!"); + return I->second; +} + +unsigned ValueEnumerator::getComdatID(const Comdat *C) const { + unsigned ComdatID = Comdats.idFor(C); + assert(ComdatID && "Comdat not found!"); + return ComdatID; +} + +void ValueEnumerator::setInstructionID(const Instruction *I) { + InstructionMap[I] = InstructionCount++; +} + +unsigned ValueEnumerator::getValueID(const Value *V) const { + if (auto *MD = dyn_cast<MetadataAsValue>(V)) + return getMetadataID(MD->getMetadata()); + + ValueMapType::const_iterator I = ValueMap.find(V); + assert(I != ValueMap.end() && "Value not in slotcalculator!"); + return I->second-1; +} + +void ValueEnumerator::dump() const { + print(dbgs(), ValueMap, "Default"); + dbgs() << '\n'; + print(dbgs(), MDValueMap, "MetaData"); + dbgs() << '\n'; +} + +void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map, + const char *Name) const { + + OS << "Map Name: " << Name << "\n"; + OS << "Size: " << Map.size() << "\n"; + for (ValueMapType::const_iterator I = Map.begin(), + E = Map.end(); I != E; ++I) { + + const Value *V = I->first; + if (V->hasName()) + OS << "Value: " << V->getName(); + else + OS << "Value: [null]\n"; + V->dump(); + + OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):"; + for (const Use &U : V->uses()) { + if (&U != &*V->use_begin()) + OS << ","; + if(U->hasName()) + OS << " " << U->getName(); + else + OS << " [null]"; + + } + OS << "\n\n"; + } +} + +void ValueEnumerator::print(raw_ostream &OS, const MetadataMapType &Map, + const char *Name) const { + + OS << "Map Name: " << Name << "\n"; + OS << "Size: " << Map.size() << "\n"; + for (auto I = Map.begin(), E = Map.end(); I != E; ++I) { + const Metadata *MD = I->first; + OS << "Metadata: slot = " << I->second << "\n"; + MD->print(OS); + } +} + +/// OptimizeConstants - Reorder constant pool for denser encoding. +void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) { + if (CstStart == CstEnd || CstStart+1 == CstEnd) return; + + if (ShouldPreserveUseListOrder) + // Optimizing constants makes the use-list order difficult to predict. + // Disable it for now when trying to preserve the order. + return; + + std::stable_sort(Values.begin() + CstStart, Values.begin() + CstEnd, + [this](const std::pair<const Value *, unsigned> &LHS, + const std::pair<const Value *, unsigned> &RHS) { + // Sort by plane. + if (LHS.first->getType() != RHS.first->getType()) + return getTypeID(LHS.first->getType()) < getTypeID(RHS.first->getType()); + // Then by frequency. + return LHS.second > RHS.second; + }); + + // Ensure that integer and vector of integer constants are at the start of the + // constant pool. This is important so that GEP structure indices come before + // gep constant exprs. + std::partition(Values.begin()+CstStart, Values.begin()+CstEnd, + isIntOrIntVectorValue); + + // Rebuild the modified portion of ValueMap. + for (; CstStart != CstEnd; ++CstStart) + ValueMap[Values[CstStart].first] = CstStart+1; +} + + +/// EnumerateValueSymbolTable - Insert all of the values in the specified symbol +/// table into the values table. +void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { + for (ValueSymbolTable::const_iterator VI = VST.begin(), VE = VST.end(); + VI != VE; ++VI) + EnumerateValue(VI->getValue()); +} + +/// Insert all of the values referenced by named metadata in the specified +/// module. +void ValueEnumerator::EnumerateNamedMetadata(const Module &M) { + for (Module::const_named_metadata_iterator I = M.named_metadata_begin(), + E = M.named_metadata_end(); + I != E; ++I) + EnumerateNamedMDNode(I); +} + +void ValueEnumerator::EnumerateNamedMDNode(const NamedMDNode *MD) { + for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) + EnumerateMetadata(MD->getOperand(i)); +} + +/// EnumerateMDNodeOperands - Enumerate all non-function-local values +/// and types referenced by the given MDNode. +void ValueEnumerator::EnumerateMDNodeOperands(const MDNode *N) { + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + Metadata *MD = N->getOperand(i); + if (!MD) + continue; + assert(!isa<LocalAsMetadata>(MD) && "MDNodes cannot be function-local"); + EnumerateMetadata(MD); + } +} + +void ValueEnumerator::EnumerateMetadata(const Metadata *MD) { + assert( + (isa<MDNode>(MD) || isa<MDString>(MD) || isa<ConstantAsMetadata>(MD)) && + "Invalid metadata kind"); + + // Insert a dummy ID to block the co-recursive call to + // EnumerateMDNodeOperands() from re-visiting MD in a cyclic graph. + // + // Return early if there's already an ID. + if (!MDValueMap.insert(std::make_pair(MD, 0)).second) + return; + + // Visit operands first to minimize RAUW. + if (auto *N = dyn_cast<MDNode>(MD)) + EnumerateMDNodeOperands(N); + else if (auto *C = dyn_cast<ConstantAsMetadata>(MD)) + EnumerateValue(C->getValue()); + + HasMDString |= isa<MDString>(MD); + HasDILocation |= isa<DILocation>(MD); + HasGenericDINode |= isa<GenericDINode>(MD); + + // Replace the dummy ID inserted above with the correct one. MDValueMap may + // have changed by inserting operands, so we need a fresh lookup here. + MDs.push_back(MD); + MDValueMap[MD] = MDs.size(); +} + +/// EnumerateFunctionLocalMetadataa - Incorporate function-local metadata +/// information reachable from the metadata. +void ValueEnumerator::EnumerateFunctionLocalMetadata( + const LocalAsMetadata *Local) { + // Check to see if it's already in! + unsigned &MDValueID = MDValueMap[Local]; + if (MDValueID) + return; + + MDs.push_back(Local); + MDValueID = MDs.size(); + + EnumerateValue(Local->getValue()); + + // Also, collect all function-local metadata for easy access. + FunctionLocalMDs.push_back(Local); +} + +void ValueEnumerator::EnumerateValue(const Value *V) { + assert(!V->getType()->isVoidTy() && "Can't insert void values!"); + assert(!isa<MetadataAsValue>(V) && "EnumerateValue doesn't handle Metadata!"); + + // Check to see if it's already in! + unsigned &ValueID = ValueMap[V]; + if (ValueID) { + // Increment use count. + Values[ValueID-1].second++; + return; + } + + if (auto *GO = dyn_cast<GlobalObject>(V)) + if (const Comdat *C = GO->getComdat()) + Comdats.insert(C); + + // Enumerate the type of this value. + EnumerateType(V->getType()); + + if (const Constant *C = dyn_cast<Constant>(V)) { + if (isa<GlobalValue>(C)) { + // Initializers for globals are handled explicitly elsewhere. + } else if (C->getNumOperands()) { + // If a constant has operands, enumerate them. This makes sure that if a + // constant has uses (for example an array of const ints), that they are + // inserted also. + + // We prefer to enumerate them with values before we enumerate the user + // itself. This makes it more likely that we can avoid forward references + // in the reader. We know that there can be no cycles in the constants + // graph that don't go through a global variable. + for (User::const_op_iterator I = C->op_begin(), E = C->op_end(); + I != E; ++I) + if (!isa<BasicBlock>(*I)) // Don't enumerate BB operand to BlockAddress. + EnumerateValue(*I); + + // Finally, add the value. Doing this could make the ValueID reference be + // dangling, don't reuse it. + Values.push_back(std::make_pair(V, 1U)); + ValueMap[V] = Values.size(); + return; + } + } + + // Add the value. + Values.push_back(std::make_pair(V, 1U)); + ValueID = Values.size(); +} + + +void ValueEnumerator::EnumerateType(Type *Ty) { + unsigned *TypeID = &TypeMap[Ty]; + + // We've already seen this type. + if (*TypeID) + return; + + // If it is a non-anonymous struct, mark the type as being visited so that we + // don't recursively visit it. This is safe because we allow forward + // references of these in the bitcode reader. + if (StructType *STy = dyn_cast<StructType>(Ty)) + if (!STy->isLiteral()) + *TypeID = ~0U; + + // Enumerate all of the subtypes before we enumerate this type. This ensures + // that the type will be enumerated in an order that can be directly built. + for (Type *SubTy : Ty->subtypes()) + EnumerateType(SubTy); + + // Refresh the TypeID pointer in case the table rehashed. + TypeID = &TypeMap[Ty]; + + // Check to see if we got the pointer another way. This can happen when + // enumerating recursive types that hit the base case deeper than they start. + // + // If this is actually a struct that we are treating as forward ref'able, + // then emit the definition now that all of its contents are available. + if (*TypeID && *TypeID != ~0U) + return; + + // Add this type now that its contents are all happily enumerated. + Types.push_back(Ty); + + *TypeID = Types.size(); +} + +// Enumerate the types for the specified value. If the value is a constant, +// walk through it, enumerating the types of the constant. +void ValueEnumerator::EnumerateOperandType(const Value *V) { + EnumerateType(V->getType()); + + if (auto *MD = dyn_cast<MetadataAsValue>(V)) { + assert(!isa<LocalAsMetadata>(MD->getMetadata()) && + "Function-local metadata should be left for later"); + + EnumerateMetadata(MD->getMetadata()); + return; + } + + const Constant *C = dyn_cast<Constant>(V); + if (!C) + return; + + // If this constant is already enumerated, ignore it, we know its type must + // be enumerated. + if (ValueMap.count(C)) + return; + + // This constant may have operands, make sure to enumerate the types in + // them. + for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) { + const Value *Op = C->getOperand(i); + + // Don't enumerate basic blocks here, this happens as operands to + // blockaddress. + if (isa<BasicBlock>(Op)) + continue; + + EnumerateOperandType(Op); + } +} + +void ValueEnumerator::EnumerateAttributes(AttributeSet PAL) { + if (PAL.isEmpty()) return; // null is always 0. + + // Do a lookup. + unsigned &Entry = AttributeMap[PAL]; + if (Entry == 0) { + // Never saw this before, add it. + Attribute.push_back(PAL); + Entry = Attribute.size(); + } + + // Do lookups for all attribute groups. + for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) { + AttributeSet AS = PAL.getSlotAttributes(i); + unsigned &Entry = AttributeGroupMap[AS]; + if (Entry == 0) { + AttributeGroups.push_back(AS); + Entry = AttributeGroups.size(); + } + } +} + +void ValueEnumerator::incorporateFunction(const Function &F) { + InstructionCount = 0; + NumModuleValues = Values.size(); + NumModuleMDs = MDs.size(); + + // Adding function arguments to the value table. + for (Function::const_arg_iterator I = F.arg_begin(), E = F.arg_end(); + I != E; ++I) + EnumerateValue(I); + + FirstFuncConstantID = Values.size(); + + // Add all function-level constants to the value table. + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) + for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); + OI != E; ++OI) { + if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) || + isa<InlineAsm>(*OI)) + EnumerateValue(*OI); + } + BasicBlocks.push_back(BB); + ValueMap[BB] = BasicBlocks.size(); + } + + // Optimize the constant layout. + OptimizeConstants(FirstFuncConstantID, Values.size()); + + // Add the function's parameter attributes so they are available for use in + // the function's instruction. + EnumerateAttributes(F.getAttributes()); + + FirstInstID = Values.size(); + + SmallVector<LocalAsMetadata *, 8> FnLocalMDVector; + // Add all of the instructions. + for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) { + for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) { + for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); + OI != E; ++OI) { + if (auto *MD = dyn_cast<MetadataAsValue>(&*OI)) + if (auto *Local = dyn_cast<LocalAsMetadata>(MD->getMetadata())) + // Enumerate metadata after the instructions they might refer to. + FnLocalMDVector.push_back(Local); + } + + if (!I->getType()->isVoidTy()) + EnumerateValue(I); + } + } + + // Add all of the function-local metadata. + for (unsigned i = 0, e = FnLocalMDVector.size(); i != e; ++i) + EnumerateFunctionLocalMetadata(FnLocalMDVector[i]); +} + +void ValueEnumerator::purgeFunction() { + /// Remove purged values from the ValueMap. + for (unsigned i = NumModuleValues, e = Values.size(); i != e; ++i) + ValueMap.erase(Values[i].first); + for (unsigned i = NumModuleMDs, e = MDs.size(); i != e; ++i) + MDValueMap.erase(MDs[i]); + for (unsigned i = 0, e = BasicBlocks.size(); i != e; ++i) + ValueMap.erase(BasicBlocks[i]); + + Values.resize(NumModuleValues); + MDs.resize(NumModuleMDs); + BasicBlocks.clear(); + FunctionLocalMDs.clear(); +} + +static void IncorporateFunctionInfoGlobalBBIDs(const Function *F, + DenseMap<const BasicBlock*, unsigned> &IDMap) { + unsigned Counter = 0; + for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) + IDMap[BB] = ++Counter; +} + +/// getGlobalBasicBlockID - This returns the function-specific ID for the +/// specified basic block. This is relatively expensive information, so it +/// should only be used by rare constructs such as address-of-label. +unsigned ValueEnumerator::getGlobalBasicBlockID(const BasicBlock *BB) const { + unsigned &Idx = GlobalBasicBlockIDs[BB]; + if (Idx != 0) + return Idx-1; + + IncorporateFunctionInfoGlobalBBIDs(BB->getParent(), GlobalBasicBlockIDs); + return getGlobalBasicBlockID(BB); +} + +uint64_t ValueEnumerator::computeBitsRequiredForTypeIndicies() const { + return Log2_32_Ceil(getTypes().size() + 1); +} diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h new file mode 100644 index 0000000..b2daa48 --- /dev/null +++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -0,0 +1,208 @@ +//===-- Bitcode/Writer/ValueEnumerator.h - Number values --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class gives values and types Unique ID's. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H +#define LLVM_LIB_BITCODE_WRITER_VALUEENUMERATOR_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/UniqueVector.h" +#include "llvm/IR/Attributes.h" +#include "llvm/IR/UseListOrder.h" +#include <vector> + +namespace llvm { + +class Type; +class Value; +class Instruction; +class BasicBlock; +class Comdat; +class Function; +class Module; +class Metadata; +class LocalAsMetadata; +class MDNode; +class NamedMDNode; +class AttributeSet; +class ValueSymbolTable; +class MDSymbolTable; +class raw_ostream; + +class ValueEnumerator { +public: + typedef std::vector<Type*> TypeList; + + // For each value, we remember its Value* and occurrence frequency. + typedef std::vector<std::pair<const Value*, unsigned> > ValueList; + + UseListOrderStack UseListOrders; + +private: + typedef DenseMap<Type*, unsigned> TypeMapType; + TypeMapType TypeMap; + TypeList Types; + + typedef DenseMap<const Value*, unsigned> ValueMapType; + ValueMapType ValueMap; + ValueList Values; + + typedef UniqueVector<const Comdat *> ComdatSetType; + ComdatSetType Comdats; + + std::vector<const Metadata *> MDs; + SmallVector<const LocalAsMetadata *, 8> FunctionLocalMDs; + typedef DenseMap<const Metadata *, unsigned> MetadataMapType; + MetadataMapType MDValueMap; + bool HasMDString; + bool HasDILocation; + bool HasGenericDINode; + bool ShouldPreserveUseListOrder; + + typedef DenseMap<AttributeSet, unsigned> AttributeGroupMapType; + AttributeGroupMapType AttributeGroupMap; + std::vector<AttributeSet> AttributeGroups; + + typedef DenseMap<AttributeSet, unsigned> AttributeMapType; + AttributeMapType AttributeMap; + std::vector<AttributeSet> Attribute; + + /// GlobalBasicBlockIDs - This map memoizes the basic block ID's referenced by + /// the "getGlobalBasicBlockID" method. + mutable DenseMap<const BasicBlock*, unsigned> GlobalBasicBlockIDs; + + typedef DenseMap<const Instruction*, unsigned> InstructionMapType; + InstructionMapType InstructionMap; + unsigned InstructionCount; + + /// BasicBlocks - This contains all the basic blocks for the currently + /// incorporated function. Their reverse mapping is stored in ValueMap. + std::vector<const BasicBlock*> BasicBlocks; + + /// When a function is incorporated, this is the size of the Values list + /// before incorporation. + unsigned NumModuleValues; + + /// When a function is incorporated, this is the size of the MDValues list + /// before incorporation. + unsigned NumModuleMDs; + + unsigned FirstFuncConstantID; + unsigned FirstInstID; + + ValueEnumerator(const ValueEnumerator &) = delete; + void operator=(const ValueEnumerator &) = delete; +public: + ValueEnumerator(const Module &M, bool ShouldPreserveUseListOrder); + + void dump() const; + void print(raw_ostream &OS, const ValueMapType &Map, const char *Name) const; + void print(raw_ostream &OS, const MetadataMapType &Map, + const char *Name) const; + + unsigned getValueID(const Value *V) const; + unsigned getMetadataID(const Metadata *MD) const { + auto ID = getMetadataOrNullID(MD); + assert(ID != 0 && "Metadata not in slotcalculator!"); + return ID - 1; + } + unsigned getMetadataOrNullID(const Metadata *MD) const { + return MDValueMap.lookup(MD); + } + + bool hasMDString() const { return HasMDString; } + bool hasDILocation() const { return HasDILocation; } + bool hasGenericDINode() const { return HasGenericDINode; } + + bool shouldPreserveUseListOrder() const { return ShouldPreserveUseListOrder; } + + unsigned getTypeID(Type *T) const { + TypeMapType::const_iterator I = TypeMap.find(T); + assert(I != TypeMap.end() && "Type not in ValueEnumerator!"); + return I->second-1; + } + + unsigned getInstructionID(const Instruction *I) const; + void setInstructionID(const Instruction *I); + + unsigned getAttributeID(AttributeSet PAL) const { + if (PAL.isEmpty()) return 0; // Null maps to zero. + AttributeMapType::const_iterator I = AttributeMap.find(PAL); + assert(I != AttributeMap.end() && "Attribute not in ValueEnumerator!"); + return I->second; + } + + unsigned getAttributeGroupID(AttributeSet PAL) const { + if (PAL.isEmpty()) return 0; // Null maps to zero. + AttributeGroupMapType::const_iterator I = AttributeGroupMap.find(PAL); + assert(I != AttributeGroupMap.end() && "Attribute not in ValueEnumerator!"); + return I->second; + } + + /// getFunctionConstantRange - Return the range of values that corresponds to + /// function-local constants. + void getFunctionConstantRange(unsigned &Start, unsigned &End) const { + Start = FirstFuncConstantID; + End = FirstInstID; + } + + const ValueList &getValues() const { return Values; } + const std::vector<const Metadata *> &getMDs() const { return MDs; } + const SmallVectorImpl<const LocalAsMetadata *> &getFunctionLocalMDs() const { + return FunctionLocalMDs; + } + const TypeList &getTypes() const { return Types; } + const std::vector<const BasicBlock*> &getBasicBlocks() const { + return BasicBlocks; + } + const std::vector<AttributeSet> &getAttributes() const { + return Attribute; + } + const std::vector<AttributeSet> &getAttributeGroups() const { + return AttributeGroups; + } + + const ComdatSetType &getComdats() const { return Comdats; } + unsigned getComdatID(const Comdat *C) const; + + /// getGlobalBasicBlockID - This returns the function-specific ID for the + /// specified basic block. This is relatively expensive information, so it + /// should only be used by rare constructs such as address-of-label. + unsigned getGlobalBasicBlockID(const BasicBlock *BB) const; + + /// incorporateFunction/purgeFunction - If you'd like to deal with a function, + /// use these two methods to get its data into the ValueEnumerator! + /// + void incorporateFunction(const Function &F); + void purgeFunction(); + uint64_t computeBitsRequiredForTypeIndicies() const; + +private: + void OptimizeConstants(unsigned CstStart, unsigned CstEnd); + + void EnumerateMDNodeOperands(const MDNode *N); + void EnumerateMetadata(const Metadata *MD); + void EnumerateFunctionLocalMetadata(const LocalAsMetadata *Local); + void EnumerateNamedMDNode(const NamedMDNode *NMD); + void EnumerateValue(const Value *V); + void EnumerateType(Type *T); + void EnumerateOperandType(const Value *V); + void EnumerateAttributes(AttributeSet PAL); + + void EnumerateValueSymbolTable(const ValueSymbolTable &ST); + void EnumerateNamedMetadata(const Module &M); +}; + +} // namespace llvm + +#endif diff --git a/contrib/llvm/lib/Bitcode/module.modulemap b/contrib/llvm/lib/Bitcode/module.modulemap new file mode 100644 index 0000000..7df1a0a --- /dev/null +++ b/contrib/llvm/lib/Bitcode/module.modulemap @@ -0,0 +1 @@ +module Bitcode { requires cplusplus umbrella "." module * { export * } } |