X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FBitcode%2FWriter%2FBitcodeWriter.cpp;h=f0453fff122f8af691cde63b40cb4563475f00bb;hb=ed356a925a35dcfd58fad093254b401bc7eb6ec5;hp=1b73f23e8f601f3b7cd8cde8e9c20e007d644aaf;hpb=48fbcfe6b959df628a6455e00ac8d94fa6ade87a;p=oota-llvm.git diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 1b73f23e8f6..f0453fff122 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -17,11 +17,13 @@ #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" @@ -32,12 +34,6 @@ #include using namespace llvm; -static cl::opt -EnablePreserveUseListOrdering("enable-bc-uselist-preserve", - cl::desc("Turn on experimental support for " - "use-list order preservation."), - cl::init(false), cl::Hidden); - /// 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 { @@ -60,10 +56,7 @@ enum { FUNCTION_INST_CAST_ABBREV, FUNCTION_INST_RET_VOID_ABBREV, FUNCTION_INST_RET_VAL_ABBREV, - FUNCTION_INST_UNREACHABLE_ABBREV, - - // SwitchInst Magic - SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex + FUNCTION_INST_UNREACHABLE_ABBREV }; static unsigned GetEncodedCastOpcode(unsigned Opcode) { @@ -81,6 +74,7 @@ static unsigned GetEncodedCastOpcode(unsigned Opcode) { 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; } } @@ -161,6 +155,99 @@ static void WriteStringRecord(unsigned Code, StringRef Str, 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::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::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::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 &AttrGrps = VE.getAttributeGroups(); @@ -182,10 +269,10 @@ static void WriteAttributeGroupTable(const ValueEnumerator &VE, Attribute Attr = *I; if (Attr.isEnumAttribute()) { Record.push_back(0); - Record.push_back(Attr.getKindAsEnum()); - } else if (Attr.isAlignAttribute()) { + Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); + } else if (Attr.isIntAttribute()) { Record.push_back(1); - Record.push_back(Attr.getKindAsEnum()); + Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); Record.push_back(Attr.getValueAsInt()); } else { StringRef Kind = Attr.getKindAsString(); @@ -299,7 +386,6 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { unsigned Code = 0; switch (T->getTypeID()) { - default: llvm_unreachable("Unknown type!"); 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; @@ -390,30 +476,36 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) { Stream.ExitBlock(); } -static unsigned getEncodedLinkage(const GlobalValue *GV) { - switch (GV->getLinkage()) { - case GlobalValue::ExternalLinkage: return 0; - case GlobalValue::WeakAnyLinkage: return 1; - case GlobalValue::AppendingLinkage: return 2; - case GlobalValue::InternalLinkage: return 3; - case GlobalValue::LinkOnceAnyLinkage: return 4; - case GlobalValue::DLLImportLinkage: return 5; - case GlobalValue::DLLExportLinkage: return 6; - case GlobalValue::ExternalWeakLinkage: return 7; - case GlobalValue::CommonLinkage: return 8; - case GlobalValue::PrivateLinkage: return 9; - case GlobalValue::WeakODRLinkage: return 10; - case GlobalValue::LinkOnceODRLinkage: return 11; - case GlobalValue::AvailableExternallyLinkage: return 12; - case GlobalValue::LinkerPrivateLinkage: return 13; - case GlobalValue::LinkerPrivateWeakLinkage: return 14; - case GlobalValue::LinkOnceODRAutoHideLinkage: return 15; +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()) { +static unsigned getEncodedVisibility(const GlobalValue &GV) { + switch (GV.getVisibility()) { case GlobalValue::DefaultVisibility: return 0; case GlobalValue::HiddenVisibility: return 1; case GlobalValue::ProtectedVisibility: return 2; @@ -421,8 +513,17 @@ static unsigned getEncodedVisibility(const GlobalValue *GV) { llvm_unreachable("Invalid visibility"); } -static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) { - switch (GV->getThreadLocalMode()) { +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; @@ -432,6 +533,37 @@ static unsigned getEncodedThreadLocalMode(const GlobalVariable *GV) { 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 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, @@ -440,9 +572,9 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, if (!M->getTargetTriple().empty()) WriteStringRecord(bitc::MODULE_CODE_TRIPLE, M->getTargetTriple(), 0/*TODO*/, Stream); - if (!M->getDataLayout().empty()) - WriteStringRecord(bitc::MODULE_CODE_DATALAYOUT, M->getDataLayout(), - 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); @@ -453,36 +585,35 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, std::map GCMap; unsigned MaxAlignment = 0; unsigned MaxGlobalType = 0; - for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end(); - GV != E; ++GV) { - MaxAlignment = std::max(MaxAlignment, GV->getAlignment()); - MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV->getType())); - if (GV->hasSection()) { + for (const GlobalValue &GV : M->globals()) { + MaxAlignment = std::max(MaxAlignment, GV.getAlignment()); + MaxGlobalType = std::max(MaxGlobalType, VE.getTypeID(GV.getType())); + if (GV.hasSection()) { // Give section names unique ID's. - unsigned &Entry = SectionMap[GV->getSection()]; + unsigned &Entry = SectionMap[GV.getSection()]; if (!Entry) { - WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV->getSection(), + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, GV.getSection(), 0/*TODO*/, Stream); Entry = SectionMap.size(); } } } - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { - MaxAlignment = std::max(MaxAlignment, F->getAlignment()); - if (F->hasSection()) { + 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()]; + unsigned &Entry = SectionMap[F.getSection()]; if (!Entry) { - WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F->getSection(), + WriteStringRecord(bitc::MODULE_CODE_SECTIONNAME, F.getSection(), 0/*TODO*/, Stream); Entry = SectionMap.size(); } } - if (F->hasGC()) { + if (F.hasGC()) { // Same for GC names. - unsigned &Entry = GCMap[F->getGC()]; + unsigned &Entry = GCMap[F.getGC()]; if (!Entry) { - WriteStringRecord(bitc::MODULE_CODE_GCNAME, F->getGC(), + WriteStringRecord(bitc::MODULE_CODE_GCNAME, F.getGC(), 0/*TODO*/, Stream); Entry = GCMap.size(); } @@ -499,7 +630,7 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, Log2_32_Ceil(MaxGlobalType+1))); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 1)); // Constant. Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Initializer. - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 4)); // Linkage. + Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Fixed, 5)); // Linkage. if (MaxAlignment == 0) // Alignment. Abbv->Add(BitCodeAbbrevOp(0)); else { @@ -518,27 +649,31 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, // Emit the global variable information. SmallVector Vals; - for (Module::const_global_iterator GV = M->global_begin(),E = M->global_end(); - GV != E; ++GV) { + for (const GlobalVariable &GV : M->globals()) { unsigned AbbrevToUse = 0; // GLOBALVAR: [type, isconst, initid, // linkage, alignment, section, visibility, threadlocal, - // unnamed_addr] - Vals.push_back(VE.getTypeID(GV->getType())); - Vals.push_back(GV->isConstant()); - Vals.push_back(GV->isDeclaration() ? 0 : - (VE.getValueID(GV->getInitializer()) + 1)); + // unnamed_addr, externally_initialized, dllstorageclass, + // comdat] + Vals.push_back(VE.getTypeID(GV.getType())); + Vals.push_back(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()) { + 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(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; } @@ -548,19 +683,26 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, } // Emit the function proto information. - for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { + for (const Function &F : *M) { // FUNCTION: [type, callingconv, isproto, linkage, paramattrs, alignment, - // section, visibility, gc, unnamed_addr] - Vals.push_back(VE.getTypeID(F->getType())); - Vals.push_back(F->getCallingConv()); - Vals.push_back(F->isDeclaration()); + // section, visibility, gc, unnamed_addr, prologuedata, + // dllstorageclass, comdat, prefixdata] + Vals.push_back(VE.getTypeID(F.getType())); + 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(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.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); unsigned AbbrevToUse = 0; Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -568,13 +710,15 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, } // Emit the alias information. - for (Module::const_alias_iterator AI = M->alias_begin(), E = M->alias_end(); - AI != E; ++AI) { + for (const GlobalAlias &A : M->aliases()) { // ALIAS: [alias type, aliasee val#, linkage, visibility] - Vals.push_back(VE.getTypeID(AI->getType())); - Vals.push_back(VE.getValueID(AI->getAliasee())); - Vals.push_back(getEncodedLinkage(AI)); - Vals.push_back(getEncodedVisibility(AI)); + 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(); @@ -584,18 +728,15 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE, static uint64_t GetOptimizationFlags(const Value *V) { uint64_t Flags = 0; - if (const OverflowingBinaryOperator *OBO = - dyn_cast(V)) { + if (const auto *OBO = dyn_cast(V)) { if (OBO->hasNoSignedWrap()) Flags |= 1 << bitc::OBO_NO_SIGNED_WRAP; if (OBO->hasNoUnsignedWrap()) Flags |= 1 << bitc::OBO_NO_UNSIGNED_WRAP; - } else if (const PossiblyExactOperator *PEO = - dyn_cast(V)) { + } else if (const auto *PEO = dyn_cast(V)) { if (PEO->isExact()) Flags |= 1 << bitc::PEO_EXACT; - } else if (const FPMathOperator *FPMO = - dyn_cast(V)) { + } else if (const auto *FPMO = dyn_cast(V)) { if (FPMO->hasUnsafeAlgebra()) Flags |= FastMathFlags::UnsafeAlgebra; if (FPMO->hasNoNaNs()) @@ -611,89 +752,393 @@ static uint64_t GetOptimizationFlags(const Value *V) { return Flags; } -static void WriteMDNode(const MDNode *N, - const ValueEnumerator &VE, - BitstreamWriter &Stream, - SmallVector &Record) { +static void WriteValueAsMetadata(const ValueAsMetadata *MD, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 &Record, unsigned Abbrev) { for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { - if (N->getOperand(i)) { - Record.push_back(VE.getTypeID(N->getOperand(i)->getType())); - Record.push_back(VE.getValueID(N->getOperand(i))); - } else { - Record.push_back(VE.getTypeID(Type::getVoidTy(N->getContext()))); - Record.push_back(0); - } + Metadata *MD = N->getOperand(i); + assert(!(MD && isa(MD)) && + "Unexpected function-local metadata"); + Record.push_back(VE.getMetadataOrNullID(MD)); } - unsigned MDCode = N->isFunctionLocal() ? bitc::METADATA_FN_NODE : - bitc::METADATA_NODE; - Stream.EmitRecord(MDCode, Record, 0); + Stream.EmitRecord(N->isDistinct() ? bitc::METADATA_DISTINCT_NODE + : bitc::METADATA_NODE, + Record, Abbrev); + Record.clear(); +} + +static void WriteMDLocation(const MDLocation *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 WriteGenericDebugNode(const GenericDebugNode *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 WriteMDSubrange(const MDSubrange *N, const ValueEnumerator &, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getCount()); + Record.push_back(rotateSign(N->getLo())); + + Stream.EmitRecord(bitc::METADATA_SUBRANGE, Record, Abbrev); + Record.clear(); +} + +static void WriteMDEnumerator(const MDEnumerator *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 WriteMDBasicType(const MDBasicType *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 WriteMDDerivedType(const MDDerivedType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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.getMetadataID(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 WriteMDCompositeType(const MDCompositeType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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())); + Record.push_back(N->getRuntimeLang()); + Record.push_back(VE.getMetadataOrNullID(N->getVTableHolder())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier())); + + Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteMDSubroutineType(const MDSubroutineType *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getFlags()); + Record.push_back(VE.getMetadataOrNullID(N->getTypeArray())); + + Stream.EmitRecord(bitc::METADATA_SUBROUTINE_TYPE, Record, Abbrev); + Record.clear(); +} + +static void WriteMDFile(const MDFile *N, const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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 WriteMDCompileUnit(const MDCompileUnit *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &Record, + unsigned Abbrev) { + Record.push_back(N->isDistinct()); + Record.push_back(N->getSourceLanguage()); + Record.push_back(VE.getMetadataID(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())); + Record.push_back(VE.getMetadataOrNullID(N->getRetainedTypes())); + Record.push_back(VE.getMetadataOrNullID(N->getSubprograms())); + Record.push_back(VE.getMetadataOrNullID(N->getGlobalVariables())); + Record.push_back(VE.getMetadataOrNullID(N->getImportedEntities())); + + Stream.EmitRecord(bitc::METADATA_COMPILE_UNIT, Record, Abbrev); Record.clear(); } +static void WriteMDSubprogram(const MDSubprogram *N, + const ValueEnumerator &VE, + BitstreamWriter &Stream, + SmallVectorImpl &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->getFunction())); + Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams())); + Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); + Record.push_back(VE.getMetadataOrNullID(N->getVariables())); + + Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); + Record.clear(); +} + +static void WriteMDLexicalBlock(const MDLexicalBlock *, const ValueEnumerator &, + BitstreamWriter &, SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDLexicalBlockFile(const MDLexicalBlockFile *, + const ValueEnumerator &, BitstreamWriter &, + SmallVectorImpl &, unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDNamespace(const MDNamespace *, const ValueEnumerator &, + BitstreamWriter &, SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDTemplateTypeParameter(const MDTemplateTypeParameter *, + const ValueEnumerator &, + BitstreamWriter &, + SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDTemplateValueParameter(const MDTemplateValueParameter *, + const ValueEnumerator &, + BitstreamWriter &, + SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDGlobalVariable(const MDGlobalVariable *, + const ValueEnumerator &, BitstreamWriter &, + SmallVectorImpl &, unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDLocalVariable(const MDLocalVariable *, + const ValueEnumerator &, BitstreamWriter &, + SmallVectorImpl &, unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDExpression(const MDExpression *, const ValueEnumerator &, + BitstreamWriter &, SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDObjCProperty(const MDObjCProperty *, const ValueEnumerator &, + BitstreamWriter &, SmallVectorImpl &, + unsigned) { + llvm_unreachable("write not implemented"); +} +static void WriteMDImportedEntity(const MDImportedEntity *, + const ValueEnumerator &, BitstreamWriter &, + SmallVectorImpl &, unsigned) { + llvm_unreachable("write not implemented"); +} + static void WriteModuleMetadata(const Module *M, const ValueEnumerator &VE, BitstreamWriter &Stream) { - const ValueEnumerator::ValueList &Vals = VE.getMDValues(); - bool StartedMetadataBlock = false; + const auto &MDs = VE.getMDs(); + if (MDs.empty() && M->named_metadata_empty()) + return; + + Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); + unsigned MDSAbbrev = 0; - SmallVector Record; - for (unsigned i = 0, e = Vals.size(); i != e; ++i) { + 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); + } - if (const MDNode *N = dyn_cast(Vals[i].first)) { - if (!N->isFunctionLocal() || !N->getFunction()) { - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - StartedMetadataBlock = true; - } - WriteMDNode(N, VE, Stream, Record); - } - } else if (const MDString *MDS = dyn_cast(Vals[i].first)) { - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - - // 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); - StartedMetadataBlock = true; - } + // Initialize MDNode abbreviations. +#define HANDLE_MDNODE_LEAF(CLASS) unsigned CLASS##Abbrev = 0; +#include "llvm/IR/Metadata.def" - // Code: [strchar x N] - Record.append(MDS->begin(), MDS->end()); + if (VE.hasMDLocation()) { + // 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)); + MDLocationAbbrev = Stream.EmitAbbrev(Abbv); + } - // Emit the finished record. - Stream.EmitRecord(bitc::METADATA_STRING, Record, MDSAbbrev); - Record.clear(); - } + if (VE.hasGenericDebugNode()) { + // 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)); + GenericDebugNodeAbbrev = Stream.EmitAbbrev(Abbv); } - // Write named metadata. - for (Module::const_named_metadata_iterator I = M->named_metadata_begin(), - E = M->named_metadata_end(); I != E; ++I) { - const NamedMDNode *NMD = I; - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - StartedMetadataBlock = true; + 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 Record; + for (const Metadata *MD : MDs) { + if (const MDNode *N = dyn_cast(MD)) { + switch (N->getMetadataID()) { + default: + llvm_unreachable("Invalid MDNode subclass"); +#define HANDLE_MDNODE_LEAF(CLASS) \ + case Metadata::CLASS##Kind: \ + Write##CLASS(cast(N), VE, Stream, Record, CLASS##Abbrev); \ + continue; +#include "llvm/IR/Metadata.def" + } + } + if (const auto *MDC = dyn_cast(MD)) { + WriteValueAsMetadata(MDC, VE, Stream, Record); + continue; } + const MDString *MDS = cast(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(); - for (unsigned i = 0, e = Str.size(); i != e; ++i) - Record.push_back(Str[i]); - Stream.EmitRecord(bitc::METADATA_NAME, Record, 0/*TODO*/); + 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 (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) - Record.push_back(VE.getValueID(NMD->getOperand(i))); + for (const MDNode *N : NMD.operands()) + Record.push_back(VE.getMetadataID(N)); Stream.EmitRecord(bitc::METADATA_NAMED_NODE, Record, 0); Record.clear(); } - if (StartedMetadataBlock) - Stream.ExitBlock(); + Stream.ExitBlock(); } static void WriteFunctionLocalMetadata(const Function &F, @@ -701,16 +1146,16 @@ static void WriteFunctionLocalMetadata(const Function &F, BitstreamWriter &Stream) { bool StartedMetadataBlock = false; SmallVector Record; - const SmallVector &Vals = VE.getFunctionLocalMDValues(); - for (unsigned i = 0, e = Vals.size(); i != e; ++i) - if (const MDNode *N = Vals[i]) - if (N->isFunctionLocal() && N->getFunction() == &F) { - if (!StartedMetadataBlock) { - Stream.EnterSubblock(bitc::METADATA_BLOCK_ID, 3); - StartedMetadataBlock = true; - } - WriteMDNode(N, VE, Stream, Record); - } + const SmallVectorImpl &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(); @@ -725,7 +1170,7 @@ static void WriteMetadataAttachment(const Function &F, // Write metadata attachments // METADATA_ATTACHMENT - [m x [value, [n x [id, mdnode]]] - SmallVector, 4> MDs; + SmallVector, 4> MDs; for (Function::const_iterator BB = F.begin(), E = F.end(); BB != E; ++BB) for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); @@ -740,7 +1185,7 @@ static void WriteMetadataAttachment(const Function &F, for (unsigned i = 0, e = MDs.size(); i != e; ++i) { Record.push_back(MDs[i].first); - Record.push_back(VE.getValueID(MDs[i].second)); + Record.push_back(VE.getMetadataID(MDs[i].second)); } Stream.EmitRecord(bitc::METADATA_ATTACHMENT, Record, 0); Record.clear(); @@ -780,34 +1225,6 @@ static void emitSignedInt64(SmallVectorImpl &Vals, uint64_t V) { Vals.push_back((-V << 1) | 1); } -static void EmitAPInt(SmallVectorImpl &Vals, - unsigned &Code, unsigned &AbbrevToUse, const APInt &Val, - bool EmitSizeForWideNumbers = false - ) { - if (Val.getBitWidth() <= 64) { - uint64_t V = Val.getSExtValue(); - emitSignedInt64(Vals, 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 = Val.getActiveWords(); - - if (EmitSizeForWideNumbers) - Vals.push_back(NWords); - - const uint64_t *RawWords = Val.getRawData(); - for (unsigned i = 0; i != NWords; ++i) { - emitSignedInt64(Vals, RawWords[i]); - } - Code = bitc::CST_CODE_WIDE_INTEGER; - } -} - static void WriteConstants(unsigned FirstVal, unsigned LastVal, const ValueEnumerator &VE, BitstreamWriter &Stream, bool isGlobal) { @@ -851,7 +1268,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, SmallVector Record; const ValueEnumerator::ValueList &Vals = VE.getValues(); - Type *LastTy = 0; + 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. @@ -891,7 +1308,23 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, } else if (isa(C)) { Code = bitc::CST_CODE_UNDEF; } else if (const ConstantInt *IV = dyn_cast(C)) { - EmitAPInt(Record, Code, AbbrevToUse, IV->getValue()); + 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(C)) { Code = bitc::CST_CODE_FLOAT; Type *Ty = CFP->getType(); @@ -1005,12 +1438,14 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, 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: @@ -1078,7 +1513,7 @@ static void WriteModuleConstants(const ValueEnumerator &VE, /// 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, - SmallVector &Vals, + SmallVectorImpl &Vals, ValueEnumerator &VE) { unsigned ValID = VE.getValueID(V); // Make encoding relative to the InstID. @@ -1093,21 +1528,14 @@ static bool PushValueAndType(const Value *V, unsigned InstID, /// 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, - SmallVector &Vals, + SmallVectorImpl &Vals, ValueEnumerator &VE) { unsigned ValID = VE.getValueID(V); Vals.push_back(InstID - ValID); } -static void pushValue64(const Value *V, unsigned InstID, - SmallVector &Vals, - ValueEnumerator &VE) { - uint64_t ValID = VE.getValueID(V); - Vals.push_back(InstID - ValID); -} - static void pushValueSigned(const Value *V, unsigned InstID, - SmallVector &Vals, + SmallVectorImpl &Vals, ValueEnumerator &VE) { unsigned ValID = VE.getValueID(V); int64_t diff = ((int32_t)InstID - (int32_t)ValID); @@ -1117,7 +1545,7 @@ static void pushValueSigned(const Value *V, unsigned InstID, /// WriteInstruction - Emit an instruction to the specified stream. static void WriteInstruction(const Instruction &I, unsigned InstID, ValueEnumerator &VE, BitstreamWriter &Stream, - SmallVector &Vals) { + SmallVectorImpl &Vals) { unsigned Code = 0; unsigned AbbrevToUse = 0; VE.setInstructionID(&I); @@ -1178,13 +1606,13 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, case Instruction::ExtractElement: Code = bitc::FUNC_CODE_INST_EXTRACTELT; PushValueAndType(I.getOperand(0), InstID, Vals, VE); - pushValue(I.getOperand(1), 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); - pushValue(I.getOperand(2), InstID, Vals, VE); + PushValueAndType(I.getOperand(2), InstID, Vals, VE); break; case Instruction::ShuffleVector: Code = bitc::FUNC_CODE_INST_SHUFFLEVEC; @@ -1229,63 +1657,16 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; case Instruction::Switch: { - // Redefine Vals, since here we need to use 64 bit values - // explicitly to store large APInt numbers. - SmallVector Vals64; - Code = bitc::FUNC_CODE_INST_SWITCH; const SwitchInst &SI = cast(I); - - uint32_t SwitchRecordHeader = SI.hash() | (SWITCH_INST_MAGIC << 16); - Vals64.push_back(SwitchRecordHeader); - - Vals64.push_back(VE.getTypeID(SI.getCondition()->getType())); - pushValue64(SI.getCondition(), InstID, Vals64, VE); - Vals64.push_back(VE.getValueID(SI.getDefaultDest())); - Vals64.push_back(SI.getNumCases()); + 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) { - const IntegersSubset& CaseRanges = i.getCaseValueEx(); - unsigned Code, Abbrev; // will unused. - - if (CaseRanges.isSingleNumber()) { - Vals64.push_back(1/*NumItems = 1*/); - Vals64.push_back(true/*IsSingleNumber = true*/); - EmitAPInt(Vals64, Code, Abbrev, CaseRanges.getSingleNumber(0), true); - } else { - - Vals64.push_back(CaseRanges.getNumItems()); - - if (CaseRanges.isSingleNumbersOnly()) { - for (unsigned ri = 0, rn = CaseRanges.getNumItems(); - ri != rn; ++ri) { - - Vals64.push_back(true/*IsSingleNumber = true*/); - - EmitAPInt(Vals64, Code, Abbrev, - CaseRanges.getSingleNumber(ri), true); - } - } else - for (unsigned ri = 0, rn = CaseRanges.getNumItems(); - ri != rn; ++ri) { - IntegersSubset::Range r = CaseRanges.getItem(ri); - bool IsSingleNumber = CaseRanges.isSingleNumber(ri); - - Vals64.push_back(IsSingleNumber); - - EmitAPInt(Vals64, Code, Abbrev, r.getLow(), true); - if (!IsSingleNumber) - EmitAPInt(Vals64, Code, Abbrev, r.getHigh(), true); - } - } - Vals64.push_back(VE.getValueID(i.getCaseSuccessor())); + Vals.push_back(VE.getValueID(i.getCaseValue())); + Vals.push_back(VE.getValueID(i.getCaseSuccessor())); } - - Stream.EmitRecord(Code, Vals64, AbbrevToUse); - - // Also do expected action - clear external Vals collection: - Vals.clear(); - return; } break; case Instruction::IndirectBr: @@ -1366,13 +1747,20 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; } - case Instruction::Alloca: + case Instruction::Alloca: { Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); Vals.push_back(VE.getTypeID(I.getOperand(0)->getType())); Vals.push_back(VE.getValueID(I.getOperand(0))); // size. - Vals.push_back(Log2_32(cast(I).getAlignment())+1); + const AllocaInst &AI = cast(I); + 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; + Vals.push_back(AlignRecord); break; + } case Instruction::Load: if (cast(I).isAtomic()) { @@ -1411,9 +1799,12 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, pushValue(I.getOperand(2), InstID, Vals, VE); // newval. Vals.push_back(cast(I).isVolatile()); Vals.push_back(GetEncodedOrdering( - cast(I).getOrdering())); + cast(I).getSuccessOrdering())); Vals.push_back(GetEncodedSynchScope( cast(I).getSynchScope())); + Vals.push_back(GetEncodedOrdering( + cast(I).getFailureOrdering())); + Vals.push_back(cast(I).isWeak()); break; case Instruction::AtomicRMW: Code = bitc::FUNC_CODE_INST_ATOMICRMW; @@ -1439,7 +1830,8 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, Code = bitc::FUNC_CODE_INST_CALL; Vals.push_back(VE.getAttributeID(CI.getAttributes())); - Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall())); + Vals.push_back((CI.getCallingConv() << 1) | unsigned(CI.isTailCall()) | + unsigned(CI.isMustTailCall()) << 14); PushValueAndType(CI.getCalledValue(), InstID, Vals, VE); // Callee // Emit value #'s for the fixed parameters. @@ -1529,6 +1921,39 @@ static void WriteValueSymbolTable(const ValueSymbolTable &VST, Stream.ExitBlock(); } +static void WriteUseList(ValueEnumerator &VE, UseListOrder &&Order, + BitstreamWriter &Stream) { + assert(Order.Shuffle.size() >= 2 && "Shuffle too small"); + unsigned Code; + if (isa(Order.V)) + Code = bitc::USELIST_CODE_BB; + else + Code = bitc::USELIST_CODE_DEFAULT; + + SmallVector Record; + for (unsigned I : Order.Shuffle) + Record.push_back(I); + Record.push_back(VE.getValueID(Order.V)); + Stream.EmitRecord(Code, Record); +} + +static void WriteUseListBlock(const Function *F, ValueEnumerator &VE, + BitstreamWriter &Stream) { + 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) { @@ -1580,11 +2005,12 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, } else { MDNode *Scope, *IA; DL.getScopeAndInlinedAt(Scope, IA, I->getContext()); + assert(Scope && "Expected valid scope"); Vals.push_back(DL.getLine()); Vals.push_back(DL.getCol()); - Vals.push_back(Scope ? VE.getValueID(Scope)+1 : 0); - Vals.push_back(IA ? VE.getValueID(IA)+1 : 0); + Vals.push_back(VE.getMetadataOrNullID(Scope)); + Vals.push_back(VE.getMetadataOrNullID(IA)); Stream.EmitRecord(bitc::FUNC_CODE_DEBUG_LOC, Vals); Vals.clear(); @@ -1597,6 +2023,8 @@ static void WriteFunction(const Function &F, ValueEnumerator &VE, if (NeedsMetadataAttachment) WriteMetadataAttachment(F, VE, Stream); + if (shouldPreserveBitcodeUseListOrder()) + WriteUseListBlock(&F, VE, Stream); VE.purgeFunction(); Stream.ExitBlock(); } @@ -1762,103 +2190,6 @@ static void WriteBlockInfo(const ValueEnumerator &VE, BitstreamWriter &Stream) { Stream.ExitBlock(); } -// Sort the Users based on the order in which the reader parses the bitcode -// file. -static bool bitcodereader_order(const User *lhs, const User *rhs) { - // TODO: Implement. - return true; -} - -static void WriteUseList(const Value *V, const ValueEnumerator &VE, - BitstreamWriter &Stream) { - - // One or zero uses can't get out of order. - if (V->use_empty() || V->hasNUses(1)) - return; - - // Make a copy of the in-memory use-list for sorting. - unsigned UseListSize = std::distance(V->use_begin(), V->use_end()); - SmallVector UseList; - UseList.reserve(UseListSize); - for (Value::const_use_iterator I = V->use_begin(), E = V->use_end(); - I != E; ++I) { - const User *U = *I; - UseList.push_back(U); - } - - // Sort the copy based on the order read by the BitcodeReader. - std::sort(UseList.begin(), UseList.end(), bitcodereader_order); - - // TODO: Generate a diff between the BitcodeWriter in-memory use-list and the - // sorted list (i.e., the expected BitcodeReader in-memory use-list). - - // TODO: Emit the USELIST_CODE_ENTRYs. -} - -static void WriteFunctionUseList(const Function *F, ValueEnumerator &VE, - BitstreamWriter &Stream) { - VE.incorporateFunction(*F); - - for (Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end(); - AI != AE; ++AI) - WriteUseList(AI, VE, Stream); - for (Function::const_iterator BB = F->begin(), FE = F->end(); BB != FE; - ++BB) { - WriteUseList(BB, VE, Stream); - for (BasicBlock::const_iterator II = BB->begin(), IE = BB->end(); II != IE; - ++II) { - WriteUseList(II, VE, Stream); - for (User::const_op_iterator OI = II->op_begin(), E = II->op_end(); - OI != E; ++OI) { - if ((isa(*OI) && !isa(*OI)) || - isa(*OI)) - WriteUseList(*OI, VE, Stream); - } - } - } - VE.purgeFunction(); -} - -// Emit use-lists. -static void WriteModuleUseLists(const Module *M, ValueEnumerator &VE, - BitstreamWriter &Stream) { - Stream.EnterSubblock(bitc::USELIST_BLOCK_ID, 3); - - // XXX: this modifies the module, but in a way that should never change the - // behavior of any pass or codegen in LLVM. The problem is that GVs may - // contain entries in the use_list that do not exist in the Module and are - // not stored in the .bc file. - for (Module::const_global_iterator I = M->global_begin(), E = M->global_end(); - I != E; ++I) - I->removeDeadConstantUsers(); - - // Write the global variables. - for (Module::const_global_iterator GI = M->global_begin(), - GE = M->global_end(); GI != GE; ++GI) { - WriteUseList(GI, VE, Stream); - - // Write the global variable initializers. - if (GI->hasInitializer()) - WriteUseList(GI->getInitializer(), VE, Stream); - } - - // Write the functions. - for (Module::const_iterator FI = M->begin(), FE = M->end(); FI != FE; ++FI) { - WriteUseList(FI, VE, Stream); - if (!FI->isDeclaration()) - WriteFunctionUseList(FI, VE, Stream); - } - - // Write the aliases. - for (Module::const_alias_iterator AI = M->alias_begin(), AE = M->alias_end(); - AI != AE; ++AI) { - WriteUseList(AI, VE, Stream); - WriteUseList(AI->getAliasee(), VE, Stream); - } - - Stream.ExitBlock(); -} - /// WriteModule - Emit the specified module to the bitstream. static void WriteModule(const Module *M, BitstreamWriter &Stream) { Stream.EnterSubblock(bitc::MODULE_BLOCK_ID, 3); @@ -1869,7 +2200,7 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { Stream.EmitRecord(bitc::MODULE_CODE_VERSION, Vals); // Analyze the module, enumerating globals, functions, etc. - ValueEnumerator VE(M); + ValueEnumerator VE(*M); // Emit blockinfo, which defines the standard abbreviations etc. WriteBlockInfo(VE, Stream); @@ -1883,6 +2214,8 @@ static void WriteModule(const Module *M, BitstreamWriter &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); @@ -1899,9 +2232,9 @@ static void WriteModule(const Module *M, BitstreamWriter &Stream) { // Emit names for globals/functions etc. WriteValueSymbolTable(M->getValueSymbolTable(), VE, Stream); - // Emit use-lists. - if (EnablePreserveUseListOrdering) - WriteModuleUseLists(M, VE, Stream); + // Emit module-level use-lists. + if (shouldPreserveBitcodeUseListOrder()) + WriteUseListBlock(nullptr, VE, Stream); // Emit function bodies. for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F)