diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 17:02:24 +0000 | 
| commit | 91bc56ed825ba56b3cc264aa5c95ab84f86832ab (patch) | |
| tree | 4df130b28021d86e13bf4565ef58c1c5a5e093b4 /contrib/llvm/lib/Bitcode/Writer | |
| parent | 9efc7e72bb1daf5d6019871d9c93a1c488a11229 (diff) | |
| parent | 5ca98fd98791947eba83a1ed3f2c8191ef7afa6c (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/Bitcode/Writer')
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp | 3 | ||||
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 207 | ||||
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp | 16 | ||||
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 80 | ||||
| -rw-r--r-- | contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h | 9 | 
5 files changed, 191 insertions, 124 deletions
| diff --git a/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp index cd1ada22cfd6..3747122fc98f 100644 --- a/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp +++ b/contrib/llvm/lib/Bitcode/Writer/BitWriter.cpp @@ -10,6 +10,7 @@  #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; @@ -18,7 +19,7 @@ using namespace llvm;  int LLVMWriteBitcodeToFile(LLVMModuleRef M, const char *Path) {    std::string ErrorInfo; -  raw_fd_ostream OS(Path, ErrorInfo, sys::fs::F_Binary); +  raw_fd_ostream OS(Path, ErrorInfo, sys::fs::F_None);    if (!ErrorInfo.empty())      return -1; diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 4cfc6bde76ed..b2e49486d70f 100644 --- a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -169,12 +169,16 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      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: @@ -195,6 +199,10 @@ static uint64_t getAttrKindEncoding(Attribute::AttrKind Kind) {      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: @@ -266,7 +274,7 @@ static void WriteAttributeGroupTable(const ValueEnumerator &VE,          if (Attr.isEnumAttribute()) {            Record.push_back(0);            Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum())); -        } else if (Attr.isAlignAttribute()) { +        } else if (Attr.isIntAttribute()) {            Record.push_back(1);            Record.push_back(getAttrKindEncoding(Attr.getKindAsEnum()));            Record.push_back(Attr.getValueAsInt()); @@ -382,7 +390,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; @@ -473,29 +480,25 @@ static void WriteTypeTable(const ValueEnumerator &VE, BitstreamWriter &Stream) {    Stream.ExitBlock();  } -static unsigned getEncodedLinkage(const GlobalValue *GV) { -  switch (GV->getLinkage()) { +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;    }    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; @@ -503,8 +506,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; @@ -514,6 +526,35 @@ 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<uint8_t, 64> Vals; +  for (const Comdat *C : VE.getComdats()) { +    // COMDAT: [selection_kind, name] +    Vals.push_back(getEncodedComdatSelectionKind(*C)); +    Vals.push_back(C->getName().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, @@ -522,9 +563,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); @@ -535,36 +576,35 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,    std::map<std::string, unsigned> 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();        } @@ -600,27 +640,30 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,    // Emit the global variable information.    SmallVector<unsigned, 64> 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, externally_initialized] -    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] +    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;      } @@ -630,21 +673,23 @@ 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, prefix] -    Vals.push_back(VE.getTypeID(F->getType())); -    Vals.push_back(F->getCallingConv()); -    Vals.push_back(F->isDeclaration()); +    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->hasPrefixData() ? (VE.getValueID(F->getPrefixData()) + 1) +    Vals.push_back(F.hasGC() ? GCMap[F.getGC()] : 0); +    Vals.push_back(F.hasUnnamedAddr()); +    Vals.push_back(F.hasPrefixData() ? (VE.getValueID(F.getPrefixData()) + 1)                                        : 0); +    Vals.push_back(getEncodedDLLStorageClass(F)); +    Vals.push_back(F.hasComdat() ? VE.getComdatID(F.getComdat()) : 0);      unsigned AbbrevToUse = 0;      Stream.EmitRecord(bitc::MODULE_CODE_FUNCTION, Vals, AbbrevToUse); @@ -652,13 +697,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(); @@ -907,7 +954,7 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal,    SmallVector<uint64_t, 64> 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. @@ -1077,12 +1124,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: @@ -1243,13 +1292,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; @@ -1384,13 +1433,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<AllocaInst>(I).getAlignment())+1); +    const AllocaInst &AI = cast<AllocaInst>(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<LoadInst>(I).isAtomic()) { @@ -1429,9 +1485,12 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,      pushValue(I.getOperand(2), InstID, Vals, VE);         // newval.      Vals.push_back(cast<AtomicCmpXchgInst>(I).isVolatile());      Vals.push_back(GetEncodedOrdering( -                     cast<AtomicCmpXchgInst>(I).getOrdering())); +                     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; @@ -1457,7 +1516,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. @@ -1795,17 +1855,10 @@ static void WriteUseList(const Value *V, const ValueEnumerator &VE,      return;    // Make a copy of the in-memory use-list for sorting. -  unsigned UseListSize = std::distance(V->use_begin(), V->use_end()); -  SmallVector<const User*, 8> 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); -  } +  SmallVector<const User*, 8> UserList(V->user_begin(), V->user_end());    // Sort the copy based on the order read by the BitcodeReader. -  std::sort(UseList.begin(), UseList.end(), bitcodereader_order); +  std::sort(UserList.begin(), UserList.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). @@ -1903,6 +1956,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); diff --git a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp index e5e76e29bd2d..4167f6da509a 100644 --- a/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp +++ b/contrib/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp @@ -1,4 +1,4 @@ -//===--- Bitcode/Writer/BitcodeWriterPass.cpp - Bitcode Writer ------------===// +//===- BitcodeWriterPass.cpp - Bitcode writing pass -----------------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -11,10 +11,18 @@  //  //===----------------------------------------------------------------------===// +#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); +  return PreservedAnalyses::all(); +} +  namespace {    class WriteBitcodePass : public ModulePass {      raw_ostream &OS; // raw_ostream to print on @@ -23,9 +31,9 @@ namespace {      explicit WriteBitcodePass(raw_ostream &o)        : ModulePass(ID), OS(o) {} -    const char *getPassName() const { return "Bitcode Writer"; } +    const char *getPassName() const override { return "Bitcode Writer"; } -    bool runOnModule(Module &M) { +    bool runOnModule(Module &M) override {        WriteBitcodeToFile(&M, OS);        return false;      } @@ -34,8 +42,6 @@ namespace {  char WriteBitcodePass::ID = 0; -/// createBitcodeWriterPass - Create and return a pass that writes the module -/// to the specified ostream.  ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str) {    return new WriteBitcodePass(Str);  } diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index a1641043b22a..15f8034a3691 100644 --- a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -73,37 +73,34 @@ ValueEnumerator::ValueEnumerator(const Module *M) {    SmallVector<std::pair<unsigned, MDNode*>, 8> MDs;    // Enumerate types used by function bodies and argument lists. -  for (Module::const_iterator F = M->begin(), E = M->end(); F != E; ++F) { - -    for (Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); -         I != E; ++I) -      EnumerateType(I->getType()); - -    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 (MDNode *MD = dyn_cast<MDNode>(*OI)) +  for (const Function &F : *M) { +    for (const Argument &A : F.args()) +      EnumerateType(A.getType()); + +    for (const BasicBlock &BB : F) +      for (const Instruction &I : BB) { +        for (const Use &Op : I.operands()) { +          if (MDNode *MD = dyn_cast<MDNode>(&Op))              if (MD->isFunctionLocal() && MD->getFunction())                // These will get enumerated during function-incorporation.                continue; -          EnumerateOperandType(*OI); +          EnumerateOperandType(Op);          } -        EnumerateType(I->getType()); -        if (const CallInst *CI = dyn_cast<CallInst>(I)) +        EnumerateType(I.getType()); +        if (const CallInst *CI = dyn_cast<CallInst>(&I))            EnumerateAttributes(CI->getAttributes()); -        else if (const InvokeInst *II = dyn_cast<InvokeInst>(I)) +        else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I))            EnumerateAttributes(II->getAttributes());          // Enumerate metadata attached with this instruction.          MDs.clear(); -        I->getAllMetadataOtherThanDebugLoc(MDs); +        I.getAllMetadataOtherThanDebugLoc(MDs);          for (unsigned i = 0, e = MDs.size(); i != e; ++i)            EnumerateMetadata(MDs[i].second); -        if (!I->getDebugLoc().isUnknown()) { +        if (!I.getDebugLoc().isUnknown()) {            MDNode *Scope, *IA; -          I->getDebugLoc().getScopeAndInlinedAt(Scope, IA, I->getContext()); +          I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext());            if (Scope) EnumerateMetadata(Scope);            if (IA) EnumerateMetadata(IA);          } @@ -120,6 +117,12 @@ unsigned ValueEnumerator::getInstructionID(const Instruction *Inst) const {    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++;  } @@ -159,12 +162,11 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,      V->dump();      OS << " Uses(" << std::distance(V->use_begin(),V->use_end()) << "):"; -    for (Value::const_use_iterator UI = V->use_begin(), UE = V->use_end(); -         UI != UE; ++UI) { -      if (UI != V->use_begin()) +    for (const Use &U : V->uses()) { +      if (&U != &*V->use_begin())          OS << ","; -      if((*UI)->hasName()) -        OS << " " << (*UI)->getName(); +      if(U->hasName()) +        OS << " " << U->getName();        else          OS << " [null]"; @@ -173,29 +175,19 @@ void ValueEnumerator::print(raw_ostream &OS, const ValueMapType &Map,    }  } -// Optimize constant ordering. -namespace { -  struct CstSortPredicate { -    ValueEnumerator &VE; -    explicit CstSortPredicate(ValueEnumerator &ve) : VE(ve) {} -    bool operator()(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 VE.getTypeID(LHS.first->getType()) < -               VE.getTypeID(RHS.first->getType()); -      // Then by frequency. -      return LHS.second > RHS.second; -    } -  }; -} -  /// OptimizeConstants - Reorder constant pool for denser encoding.  void ValueEnumerator::OptimizeConstants(unsigned CstStart, unsigned CstEnd) {    if (CstStart == CstEnd || CstStart+1 == CstEnd) return; -  CstSortPredicate P(*this); -  std::stable_sort(Values.begin()+CstStart, Values.begin()+CstEnd, P); +  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 @@ -321,6 +313,10 @@ void ValueEnumerator::EnumerateValue(const Value *V) {      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()); diff --git a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h index d1ca15f45d02..1c9f38e07b44 100644 --- a/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/contrib/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -16,6 +16,7 @@  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/UniqueVector.h"  #include "llvm/IR/Attributes.h"  #include <vector> @@ -25,6 +26,7 @@ class Type;  class Value;  class Instruction;  class BasicBlock; +class Comdat;  class Function;  class Module;  class MDNode; @@ -48,6 +50,10 @@ private:    typedef DenseMap<const Value*, unsigned> ValueMapType;    ValueMapType ValueMap;    ValueList Values; + +  typedef UniqueVector<const Comdat *> ComdatSetType; +  ComdatSetType Comdats; +    ValueList MDValues;    SmallVector<const MDNode *, 8> FunctionLocalMDs;    ValueMapType MDValueMap; @@ -139,6 +145,9 @@ public:      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. | 
