[llvm] r289461 - Refactor BitcodeReader: move Metadata and ValueId handling in their own class/file

Mehdi Amini via llvm-commits llvm-commits at lists.llvm.org
Mon Dec 12 15:46:17 PST 2016


Hi Paul,

Thanks for notifying me! (There was another commit at the same time that broke all the configs, so I missed the windows specific issue I introduced).

I was about to fix it but Nico Weber already did in the meantime.

Best,

— 
Mehdi

> On Dec 12, 2016, at 2:14 PM, Robinson, Paul <paul.robinson at sony.com> wrote:
> 
> Hi Mehdi, it looks like this made the Windows bots sad.
> Can you take a look?  Probably a missing 'using' or something.
> Thanks,
> --paulr
> 
> FAILED: C:\PROGRA~2\MICROS~3.0\VC\bin\amd64\cl.exe   /nologo /TP -DGTEST_HAS_RTTI=0 -DUNICODE -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS -D_HAS_EXCEPTIONS=0 -D_SCL_SECURE_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_UNICODE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Ilib\Bitcode\Reader -ID:\buildslave\clang-x64-ninja-win7\llvm\lib\Bitcode\Reader -Iinclude -ID:\buildslave\clang-x64-ninja-win7\llvm\include /DWIN32 /D_WINDOWS   /W4 -wd4141 -wd4146 -wd4180 -wd4244 -wd4258 -wd4267 -wd4291 -wd4345 -wd4351 -wd4355 -wd4456 -wd4457 -wd4458 -wd4459 -wd4503 -wd4624 -wd4722 -wd4800 -wd4100 -wd4127 -wd4512 -wd4505 -wd4610 -wd4510 -wd4702 -wd4245 -wd4706 -wd4310 -wd4701 -wd4703 -wd4389 -wd4611 -wd4805 -wd4204 -wd4577 -wd4091 -wd4592 -wd4319 -wd4324 -w14062 -we4238 /Zc:inline /Zc:strictStrings /Oi /Zc:rvalueCast /MD /O2 /Ob2   -UNDEBUG  /EHs-c- /GR- /showIncludes /Folib\Bitcode\Reader\CMakeFiles\LLVMBitReader.dir\MetadataLoader.cpp.obj /Fdlib\Bitcode\Reader\CMakeFiles\LLVMBitReader.dir\ /FS -c D:\buildslave\clang-x64-ninja-win7\llvm\lib\Bitcode\Reader\MetadataLoader.cpp
> D:\buildslave\clang-x64-ninja-win7\llvm\lib\Bitcode\Reader\MetadataLoader.cpp(1284): error C2668: 'llvm::make_unique': ambiguous call to overloaded function
> D:\buildslave\clang-x64-ninja-win7\llvm\include\llvm/ADT/STLExtras.h(680): note: could be 'std::unique_ptr<llvm::MetadataLoader::MetadataLoaderImpl,std::default_delete<_Ty>> llvm::make_unique<llvm::MetadataLoader::MetadataLoaderImpl,llvm::BitstreamCursor&,llvm::Module&,llvm::BitcodeReaderValueList&,std::function<llvm::Type *(unsigned int)>&>(llvm::BitstreamCursor &,llvm::Module &,llvm::BitcodeReaderValueList &,std::function<llvm::Type *(unsigned int)> &)'
>        with
>        [
>            _Ty=llvm::MetadataLoader::MetadataLoaderImpl
>        ]
> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\memory(1628): note: or       'std::unique_ptr<llvm::MetadataLoader::MetadataLoaderImpl,std::default_delete<_Ty>> std::make_unique<llvm::MetadataLoader::MetadataLoaderImpl,llvm::BitstreamCursor&,llvm::Module&,llvm::BitcodeReaderValueList&,std::function<llvm::Type *(unsigned int)>&>(llvm::BitstreamCursor &,llvm::Module &,llvm::BitcodeReaderValueList &,std::function<llvm::Type *(unsigned int)> &)' [found using argument-dependent lookup]
>        with
>        [
>            _Ty=llvm::MetadataLoader::MetadataLoaderImpl
>        ]
> D:\buildslave\clang-x64-ninja-win7\llvm\lib\Bitcode\Reader\MetadataLoader.cpp(1284): note: while trying to match the argument list '(llvm::BitstreamCursor, llvm::Module, llvm::BitcodeReaderValueList, std::function<llvm::Type *(unsigned int)>)'
> 
> 
>> -----Original Message-----
>> From: llvm-commits [mailto:llvm-commits-bounces at lists.llvm.org] On Behalf
>> Of Mehdi Amini via llvm-commits
>> Sent: Monday, December 12, 2016 11:34 AM
>> To: llvm-commits at lists.llvm.org
>> Subject: [llvm] r289461 - Refactor BitcodeReader: move Metadata and
>> ValueId handling in their own class/file
>> 
>> Author: mehdi_amini
>> Date: Mon Dec 12 13:34:26 2016
>> New Revision: 289461
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=289461&view=rev
>> Log:
>> Refactor BitcodeReader: move Metadata and ValueId handling in their own
>> class/file
>> 
>> Summary:
>> I'm planning on changing the way we load metadata to enable laziness.
>> I'm getting lost in this gigantic files, and gigantic class that is the
>> bitcode
>> reader. This is a first toward splitting it in a few coarse components
>> that
>> are more easily understandable.
>> 
>> Reviewers: pcc, tejohnson
>> 
>> Subscribers: mgorny, llvm-commits, dexonsmith
>> 
>> Differential Revision: https://reviews.llvm.org/D27646
>> 
>> Added:
>>    llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp
>>    llvm/trunk/lib/Bitcode/Reader/MetadataLoader.h
>>    llvm/trunk/lib/Bitcode/Reader/ValueList.cpp
>>    llvm/trunk/lib/Bitcode/Reader/ValueList.h
>> Modified:
>>    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>>    llvm/trunk/lib/Bitcode/Reader/CMakeLists.txt
>> 
>> Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=289461&r1=2894
>> 60&r2=289461&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
>> +++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Dec 12 13:34:26
>> 2016
>> @@ -8,6 +8,9 @@
>> //===--------------------------------------------------------------------
>> --===//
>> 
>> #include "llvm/Bitcode/BitcodeReader.h"
>> +#include "MetadataLoader.h"
>> +#include "ValueList.h"
>> +
>> #include "llvm/ADT/APFloat.h"
>> #include "llvm/ADT/APInt.h"
>> #include "llvm/ADT/ArrayRef.h"
>> @@ -94,140 +97,6 @@ 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 BitcodeReaderMetadataList {
>> -  unsigned NumFwdRefs;
>> -  bool AnyFwdRefs;
>> -  unsigned MinFwdRef;
>> -  unsigned MaxFwdRef;
>> -
>> -  /// Array of metadata references.
>> -  ///
>> -  /// Don't use std::vector here.  Some versions of libc++ copy (instead
>> of
>> -  /// move) on resize, and TrackingMDRef is very expensive to copy.
>> -  SmallVector<TrackingMDRef, 1> MetadataPtrs;
>> -
>> -  /// Structures for resolving old type refs.
>> -  struct {
>> -    SmallDenseMap<MDString *, TempMDTuple, 1> Unknown;
>> -    SmallDenseMap<MDString *, DICompositeType *, 1> Final;
>> -    SmallDenseMap<MDString *, DICompositeType *, 1> FwdDecls;
>> -    SmallVector<std::pair<TrackingMDRef, TempMDTuple>, 1> Arrays;
>> -  } OldTypeRefs;
>> -
>> -  LLVMContext &Context;
>> -
>> -public:
>> -  BitcodeReaderMetadataList(LLVMContext &C)
>> -      : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
>> -
>> -  // vector compatibility methods
>> -  unsigned size() const { return MetadataPtrs.size(); }
>> -  void resize(unsigned N) { MetadataPtrs.resize(N); }
>> -  void push_back(Metadata *MD) { MetadataPtrs.emplace_back(MD); }
>> -  void clear() { MetadataPtrs.clear(); }
>> -  Metadata *back() const { return MetadataPtrs.back(); }
>> -  void pop_back() { MetadataPtrs.pop_back(); }
>> -  bool empty() const { return MetadataPtrs.empty(); }
>> -
>> -  Metadata *operator[](unsigned i) const {
>> -    assert(i < MetadataPtrs.size());
>> -    return MetadataPtrs[i];
>> -  }
>> -
>> -  Metadata *lookup(unsigned I) const {
>> -    if (I < MetadataPtrs.size())
>> -      return MetadataPtrs[I];
>> -    return nullptr;
>> -  }
>> -
>> -  void shrinkTo(unsigned N) {
>> -    assert(N <= size() && "Invalid shrinkTo request!");
>> -    assert(!AnyFwdRefs && "Unexpected forward refs");
>> -    MetadataPtrs.resize(N);
>> -  }
>> -
>> -  /// Return the given metadata, creating a replaceable forward reference
>> if
>> -  /// necessary.
>> -  Metadata *getMetadataFwdRef(unsigned Idx);
>> -
>> -  /// Return the the given metadata only if it is fully resolved.
>> -  ///
>> -  /// Gives the same result as \a lookup(), unless \a
>> MDNode::isResolved()
>> -  /// would give \c false.
>> -  Metadata *getMetadataIfResolved(unsigned Idx);
>> -
>> -  MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
>> -  void assignValue(Metadata *MD, unsigned Idx);
>> -  void tryToResolveCycles();
>> -  bool hasFwdRefs() const { return AnyFwdRefs; }
>> -
>> -  /// Upgrade a type that had an MDString reference.
>> -  void addTypeRef(MDString &UUID, DICompositeType &CT);
>> -
>> -  /// Upgrade a type that had an MDString reference.
>> -  Metadata *upgradeTypeRef(Metadata *MaybeUUID);
>> -
>> -  /// Upgrade a type ref array that may have MDString references.
>> -  Metadata *upgradeTypeRefArray(Metadata *MaybeTuple);
>> -
>> -private:
>> -  Metadata *resolveTypeRefArray(Metadata *MaybeTuple);
>> -};
>> -
>> Error error(const Twine &Message) {
>>   return make_error<StringError>(
>>       Message, make_error_code(BitcodeError::CorruptedBitcode));
>> @@ -526,7 +395,7 @@ class BitcodeReader : public BitcodeRead
>> 
>>   std::vector<Type*> TypeList;
>>   BitcodeReaderValueList ValueList;
>> -  BitcodeReaderMetadataList MetadataList;
>> +  Optional<MetadataLoader> MDLoader;
>>   std::vector<Comdat *> ComdatList;
>>   SmallVector<Instruction *, 64> InstructionList;
>> 
>> @@ -536,8 +405,6 @@ class BitcodeReader : public BitcodeRead
>>   std::vector<std::pair<Function*, unsigned> > FunctionPrologues;
>>   std::vector<std::pair<Function*, unsigned> > FunctionPersonalityFns;
>> 
>> -  bool HasSeenOldLoopTags = false;
>> -
>>   /// 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;
>> @@ -560,9 +427,6 @@ class BitcodeReader : public BitcodeRead
>>   // Intrinsics which were remangled because of types rename
>>   UpdatedIntrinsicMap RemangledIntrinsics;
>> 
>> -  // 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.
>> @@ -597,10 +461,6 @@ class BitcodeReader : public BitcodeRead
>> 
>>   bool StripDebugInfo = false;
>> 
>> -  /// Functions that need to be matched with subprograms when upgrading
>> old
>> -  /// metadata.
>> -  SmallDenseMap<Function *, DISubprogram *, 16> FunctionsWithSPs;
>> -
>>   std::vector<std::string> BundleTags;
>> 
>> public:
>> @@ -638,7 +498,7 @@ private:
>>   }
>> 
>>   Metadata *getFnMetadataByID(unsigned ID) {
>> -    return MetadataList.getMetadataFwdRef(ID);
>> +    return MDLoader->getMetadataFwdRef(ID);
>>   }
>> 
>>   BasicBlock *getBasicBlock(unsigned ID) const {
>> @@ -742,14 +602,6 @@ private:
>>   Error parseFunctionBody(Function *F);
>>   Error globalCleanup();
>>   Error resolveGlobalAndIndirectSymbolInits();
>> -  Error parseMetadata(bool ModuleLevel = false);
>> -  Error parseMetadataStrings(ArrayRef<uint64_t> Record, StringRef Blob,
>> -                             unsigned &NextMetadataNo);
>> -  Error parseMetadataKinds();
>> -  Error parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
>> -  Error parseGlobalObjectAttachment(GlobalObject &GO,
>> -                                    ArrayRef<uint64_t> Record);
>> -  Error parseMetadataAttachment(Function &F);
>>   Error parseUseLists();
>>   Error findFunctionInStream(
>>       Function *F,
>> @@ -831,7 +683,7 @@ BitcodeReader::BitcodeReader(BitstreamCu
>>                              StringRef ProducerIdentification,
>>                              LLVMContext &Context)
>>     : BitcodeReaderBase(std::move(Stream)), Context(Context),
>> -      ValueList(Context), MetadataList(Context) {
>> +      ValueList(Context) {
>>   this->ProducerIdentification = ProducerIdentification;
>> }
>> 
>> @@ -1114,360 +966,6 @@ static void upgradeDLLImportExportLinkag
>>   }
>> }
>> 
>> -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);
>> -};
>> -
>> -} // end anonymous namespace
>> -
>> -// FIXME: can we inherit this from ConstantExpr?
>> -template <>
>> -struct OperandTraits<ConstantPlaceHolder> :
>> -  public FixedNumOperandTraits<ConstantPlaceHolder, 1> {
>> -};
>> -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
>> -
>> -} // end 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 == std::numeric_limits<unsigned>::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 BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
>> -  if (Idx == size()) {
>> -    push_back(MD);
>> -    return;
>> -  }
>> -
>> -  if (Idx >= size())
>> -    resize(Idx+1);
>> -
>> -  TrackingMDRef &OldMD = MetadataPtrs[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 *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
>> -  if (Idx >= size())
>> -    resize(Idx + 1);
>> -
>> -  if (Metadata *MD = MetadataPtrs[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();
>> -  MetadataPtrs[Idx].reset(MD);
>> -  return MD;
>> -}
>> -
>> -Metadata *BitcodeReaderMetadataList::getMetadataIfResolved(unsigned Idx)
>> {
>> -  Metadata *MD = lookup(Idx);
>> -  if (auto *N = dyn_cast_or_null<MDNode>(MD))
>> -    if (!N->isResolved())
>> -      return nullptr;
>> -  return MD;
>> -}
>> -
>> -MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
>> -  return dyn_cast_or_null<MDNode>(getMetadataFwdRef(Idx));
>> -}
>> -
>> -void BitcodeReaderMetadataList::tryToResolveCycles() {
>> -  if (NumFwdRefs)
>> -    // Still forward references... can't resolve cycles.
>> -    return;
>> -
>> -  bool DidReplaceTypeRefs = false;
>> -
>> -  // Give up on finding a full definition for any forward decls that
>> remain.
>> -  for (const auto &Ref : OldTypeRefs.FwdDecls)
>> -    OldTypeRefs.Final.insert(Ref);
>> -  OldTypeRefs.FwdDecls.clear();
>> -
>> -  // Upgrade from old type ref arrays.  In strange cases, this could add
>> to
>> -  // OldTypeRefs.Unknown.
>> -  for (const auto &Array : OldTypeRefs.Arrays) {
>> -    DidReplaceTypeRefs = true;
>> -    Array.second-
>>> replaceAllUsesWith(resolveTypeRefArray(Array.first.get()));
>> -  }
>> -  OldTypeRefs.Arrays.clear();
>> -
>> -  // Replace old string-based type refs with the resolved node, if
>> possible.
>> -  // If we haven't seen the node, leave it to the verifier to complain
>> about
>> -  // the invalid string reference.
>> -  for (const auto &Ref : OldTypeRefs.Unknown) {
>> -    DidReplaceTypeRefs = true;
>> -    if (DICompositeType *CT = OldTypeRefs.Final.lookup(Ref.first))
>> -      Ref.second->replaceAllUsesWith(CT);
>> -    else
>> -      Ref.second->replaceAllUsesWith(Ref.first);
>> -  }
>> -  OldTypeRefs.Unknown.clear();
>> -
>> -  // Make sure all the upgraded types are resolved.
>> -  if (DidReplaceTypeRefs) {
>> -    AnyFwdRefs = true;
>> -    MinFwdRef = 0;
>> -    MaxFwdRef = MetadataPtrs.size() - 1;
>> -  }
>> -
>> -  if (!AnyFwdRefs)
>> -    // Nothing to do.
>> -    return;
>> -
>> -  // Resolve any cycles.
>> -  for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
>> -    auto &MD = MetadataPtrs[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;
>> -}
>> -
>> -void BitcodeReaderMetadataList::addTypeRef(MDString &UUID,
>> -                                           DICompositeType &CT) {
>> -  assert(CT.getRawIdentifier() == &UUID && "Mismatched UUID");
>> -  if (CT.isForwardDecl())
>> -    OldTypeRefs.FwdDecls.insert(std::make_pair(&UUID, &CT));
>> -  else
>> -    OldTypeRefs.Final.insert(std::make_pair(&UUID, &CT));
>> -}
>> -
>> -Metadata *BitcodeReaderMetadataList::upgradeTypeRef(Metadata *MaybeUUID)
>> {
>> -  auto *UUID = dyn_cast_or_null<MDString>(MaybeUUID);
>> -  if (LLVM_LIKELY(!UUID))
>> -    return MaybeUUID;
>> -
>> -  if (auto *CT = OldTypeRefs.Final.lookup(UUID))
>> -    return CT;
>> -
>> -  auto &Ref = OldTypeRefs.Unknown[UUID];
>> -  if (!Ref)
>> -    Ref = MDNode::getTemporary(Context, None);
>> -  return Ref.get();
>> -}
>> -
>> -Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(Metadata
>> *MaybeTuple) {
>> -  auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
>> -  if (!Tuple || Tuple->isDistinct())
>> -    return MaybeTuple;
>> -
>> -  // Look through the array immediately if possible.
>> -  if (!Tuple->isTemporary())
>> -    return resolveTypeRefArray(Tuple);
>> -
>> -  // Create and return a placeholder to use for now.  Eventually
>> -  // resolveTypeRefArrays() will be resolve this forward reference.
>> -  OldTypeRefs.Arrays.emplace_back(
>> -      std::piecewise_construct, std::forward_as_tuple(Tuple),
>> -      std::forward_as_tuple(MDTuple::getTemporary(Context, None)));
>> -  return OldTypeRefs.Arrays.back().second.get();
>> -}
>> -
>> -Metadata *BitcodeReaderMetadataList::resolveTypeRefArray(Metadata
>> *MaybeTuple) {
>> -  auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
>> -  if (!Tuple || Tuple->isDistinct())
>> -    return MaybeTuple;
>> -
>> -  // Look through the DITypeRefArray, upgrading each DITypeRef.
>> -  SmallVector<Metadata *, 32> Ops;
>> -  Ops.reserve(Tuple->getNumOperands());
>> -  for (Metadata *MD : Tuple->operands())
>> -    Ops.push_back(upgradeTypeRef(MD));
>> -
>> -  return MDTuple::get(Context, Ops);
>> -}
>> 
>> Type *BitcodeReader::getTypeByID(unsigned ID) {
>>   // The type table size is always specified correctly.
>> @@ -2321,798 +1819,6 @@ Error BitcodeReader::parseValueSymbolTab
>>   }
>> }
>> 
>> -/// Parse a single METADATA_KIND record, inserting result in MDKindMap.
>> -Error BitcodeReader::parseMetadataKindRecord(
>> -    SmallVectorImpl<uint64_t> &Record) {
>> -  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");
>> -  return Error::success();
>> -}
>> -
>> -static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >>
>> 1; }
>> -
>> -Error BitcodeReader::parseMetadataStrings(ArrayRef<uint64_t> Record,
>> -                                          StringRef Blob,
>> -                                          unsigned &NextMetadataNo) {
>> -  // All the MDStrings in the block are emitted together in a single
>> -  // record.  The strings are concatenated and stored in a blob along
>> with
>> -  // their sizes.
>> -  if (Record.size() != 2)
>> -    return error("Invalid record: metadata strings layout");
>> -
>> -  unsigned NumStrings = Record[0];
>> -  unsigned StringsOffset = Record[1];
>> -  if (!NumStrings)
>> -    return error("Invalid record: metadata strings with no strings");
>> -  if (StringsOffset > Blob.size())
>> -    return error("Invalid record: metadata strings corrupt offset");
>> -
>> -  StringRef Lengths = Blob.slice(0, StringsOffset);
>> -  SimpleBitstreamCursor R(Lengths);
>> -
>> -  StringRef Strings = Blob.drop_front(StringsOffset);
>> -  do {
>> -    if (R.AtEndOfStream())
>> -      return error("Invalid record: metadata strings bad length");
>> -
>> -    unsigned Size = R.ReadVBR(6);
>> -    if (Strings.size() < Size)
>> -      return error("Invalid record: metadata strings truncated chars");
>> -
>> -    MetadataList.assignValue(MDString::get(Context, Strings.slice(0,
>> Size)),
>> -                             NextMetadataNo++);
>> -    Strings = Strings.drop_front(Size);
>> -  } while (--NumStrings);
>> -
>> -  return Error::success();
>> -}
>> -
>> -namespace {
>> -
>> -class PlaceholderQueue {
>> -  // Placeholders would thrash around when moved, so store in a
>> std::deque
>> -  // instead of some sort of vector.
>> -  std::deque<DistinctMDOperandPlaceholder> PHs;
>> -
>> -public:
>> -  DistinctMDOperandPlaceholder &getPlaceholderOp(unsigned ID);
>> -  void flush(BitcodeReaderMetadataList &MetadataList);
>> -};
>> -
>> -} // end anonymous namespace
>> -
>> -DistinctMDOperandPlaceholder &PlaceholderQueue::getPlaceholderOp(unsigned
>> ID) {
>> -  PHs.emplace_back(ID);
>> -  return PHs.back();
>> -}
>> -
>> -void PlaceholderQueue::flush(BitcodeReaderMetadataList &MetadataList) {
>> -  while (!PHs.empty()) {
>> -    PHs.front().replaceUseWith(
>> -        MetadataList.getMetadataFwdRef(PHs.front().getID()));
>> -    PHs.pop_front();
>> -  }
>> -}
>> -
>> -/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
>> -/// module level metadata.
>> -Error BitcodeReader::parseMetadata(bool ModuleLevel) {
>> -  assert((ModuleLevel || DeferredMetadataInfo.empty()) &&
>> -         "Must read all module-level metadata before function-level");
>> -
>> -  unsigned NextMetadataNo = MetadataList.size();
>> -
>> -  if (!ModuleLevel && MetadataList.hasFwdRefs())
>> -    return error("Invalid metadata: fwd refs into function blocks");
>> -
>> -  if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
>> -    return error("Invalid record");
>> -
>> -  std::vector<std::pair<DICompileUnit *, Metadata *>> CUSubprograms;
>> -  SmallVector<uint64_t, 64> Record;
>> -
>> -  PlaceholderQueue Placeholders;
>> -  bool IsDistinct;
>> -  auto getMD = [&](unsigned ID) -> Metadata * {
>> -    if (!IsDistinct)
>> -      return MetadataList.getMetadataFwdRef(ID);
>> -    if (auto *MD = MetadataList.getMetadataIfResolved(ID))
>> -      return MD;
>> -    return &Placeholders.getPlaceholderOp(ID);
>> -  };
>> -  auto getMDOrNull = [&](unsigned ID) -> Metadata * {
>> -    if (ID)
>> -      return getMD(ID - 1);
>> -    return nullptr;
>> -  };
>> -  auto getMDOrNullWithoutPlaceholders = [&](unsigned ID) -> Metadata * {
>> -    if (ID)
>> -      return MetadataList.getMetadataFwdRef(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));
>> -  };
>> -
>> -  // Support for old type refs.
>> -  auto getDITypeRefOrNull = [&](unsigned ID) {
>> -    return MetadataList.upgradeTypeRef(getMDOrNull(ID));
>> -  };
>> -
>> -#define GET_OR_DISTINCT(CLASS, ARGS)
>> \
>> -  (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
>> -
>> -  // Read all the records.
>> -  while (true) {
>> -    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
>> -
>> -    switch (Entry.Kind) {
>> -    case BitstreamEntry::SubBlock: // Handled for us already.
>> -    case BitstreamEntry::Error:
>> -      return error("Malformed block");
>> -    case BitstreamEntry::EndBlock:
>> -      // Upgrade old-style CU <-> SP pointers to point from SP to CU.
>> -      for (auto CU_SP : CUSubprograms)
>> -        if (auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
>> -          for (auto &Op : SPs->operands())
>> -            if (auto *SP = dyn_cast_or_null<MDNode>(Op))
>> -              SP->replaceOperandWith(7, CU_SP.first);
>> -
>> -      MetadataList.tryToResolveCycles();
>> -      Placeholders.flush(MetadataList);
>> -      return Error::success();
>> -    case BitstreamEntry::Record:
>> -      // The interesting case.
>> -      break;
>> -    }
>> -
>> -    // Read a record.
>> -    Record.clear();
>> -    StringRef Blob;
>> -    unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob);
>> -    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 = MetadataList.getMDNodeFwdRefOrNull(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 = [&] {
>> -        MetadataList.assignValue(MDNode::get(Context, None),
>> NextMetadataNo++);
>> -      };
>> -      if (Record.size() != 2) {
>> -        dropRecord();
>> -        break;
>> -      }
>> -
>> -      Type *Ty = getTypeByID(Record[0]);
>> -      if (Ty->isMetadataTy() || Ty->isVoidTy()) {
>> -        dropRecord();
>> -        break;
>> -      }
>> -
>> -      MetadataList.assignValue(
>> -          LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
>> -          NextMetadataNo++);
>> -      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(getMD(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);
>> -      }
>> -      MetadataList.assignValue(MDNode::get(Context, Elts),
>> NextMetadataNo++);
>> -      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");
>> -
>> -      MetadataList.assignValue(
>> -          ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_DISTINCT_NODE:
>> -      IsDistinct = true;
>> -      LLVM_FALLTHROUGH;
>> -    case bitc::METADATA_NODE: {
>> -      SmallVector<Metadata *, 8> Elts;
>> -      Elts.reserve(Record.size());
>> -      for (unsigned ID : Record)
>> -        Elts.push_back(getMDOrNull(ID));
>> -      MetadataList.assignValue(IsDistinct ? MDNode::getDistinct(Context,
>> Elts)
>> -                                          : MDNode::get(Context, Elts),
>> -                               NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_LOCATION: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      unsigned Line = Record[1];
>> -      unsigned Column = Record[2];
>> -      Metadata *Scope = getMD(Record[3]);
>> -      Metadata *InlinedAt = getMDOrNull(Record[4]);
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DILocation,
>> -                          (Context, Line, Column, Scope, InlinedAt)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_GENERIC_DEBUG: {
>> -      if (Record.size() < 4)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      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(getMDOrNull(Record[I]));
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(GenericDINode, (Context, Tag, Header,
>> DwarfOps)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_SUBRANGE: {
>> -      if (Record.size() != 3)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DISubrange,
>> -                          (Context, Record[1], unrotateSign(Record[2]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_ENUMERATOR: {
>> -      if (Record.size() != 3)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIEnumerator, (Context,
>> unrotateSign(Record[1]),
>> -                                         getMDString(Record[2]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_BASIC_TYPE: {
>> -      if (Record.size() != 6)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIBasicType,
>> -                          (Context, Record[1], getMDString(Record[2]),
>> -                           Record[3], Record[4], Record[5])),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_DERIVED_TYPE: {
>> -      if (Record.size() != 12)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIDerivedType,
>> -                          (Context, Record[1], getMDString(Record[2]),
>> -                           getMDOrNull(Record[3]), Record[4],
>> -                           getDITypeRefOrNull(Record[5]),
>> -                           getDITypeRefOrNull(Record[6]), Record[7],
>> Record[8],
>> -                           Record[9], Flags,
>> getDITypeRefOrNull(Record[11]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_COMPOSITE_TYPE: {
>> -      if (Record.size() != 16)
>> -        return error("Invalid record");
>> -
>> -      // If we have a UUID and this is not a forward declaration, lookup
>> the
>> -      // mapping.
>> -      IsDistinct = Record[0] & 0x1;
>> -      bool IsNotUsedInTypeRef = Record[0] >= 2;
>> -      unsigned Tag = Record[1];
>> -      MDString *Name = getMDString(Record[2]);
>> -      Metadata *File = getMDOrNull(Record[3]);
>> -      unsigned Line = Record[4];
>> -      Metadata *Scope = getDITypeRefOrNull(Record[5]);
>> -      Metadata *BaseType = getDITypeRefOrNull(Record[6]);
>> -      uint64_t SizeInBits = Record[7];
>> -      if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
>> -        return error("Alignment value is too large");
>> -      uint32_t AlignInBits = Record[8];
>> -      uint64_t OffsetInBits = Record[9];
>> -      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
>> -      Metadata *Elements = getMDOrNull(Record[11]);
>> -      unsigned RuntimeLang = Record[12];
>> -      Metadata *VTableHolder = getDITypeRefOrNull(Record[13]);
>> -      Metadata *TemplateParams = getMDOrNull(Record[14]);
>> -      auto *Identifier = getMDString(Record[15]);
>> -      DICompositeType *CT = nullptr;
>> -      if (Identifier)
>> -        CT = DICompositeType::buildODRType(
>> -            Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
>> -            SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
>> RuntimeLang,
>> -            VTableHolder, TemplateParams);
>> -
>> -      // Create a node if we didn't get a lazy ODR type.
>> -      if (!CT)
>> -        CT = GET_OR_DISTINCT(DICompositeType,
>> -                             (Context, Tag, Name, File, Line, Scope,
>> BaseType,
>> -                              SizeInBits, AlignInBits, OffsetInBits,
>> Flags,
>> -                              Elements, RuntimeLang, VTableHolder,
>> -                              TemplateParams, Identifier));
>> -      if (!IsNotUsedInTypeRef && Identifier)
>> -        MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
>> -
>> -      MetadataList.assignValue(CT, NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_SUBROUTINE_TYPE: {
>> -      if (Record.size() < 3 || Record.size() > 4)
>> -        return error("Invalid record");
>> -      bool IsOldTypeRefArray = Record[0] < 2;
>> -      unsigned CC = (Record.size() > 3) ? Record[3] : 0;
>> -
>> -      IsDistinct = Record[0] & 0x1;
>> -      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[1]);
>> -      Metadata *Types = getMDOrNull(Record[2]);
>> -      if (LLVM_UNLIKELY(IsOldTypeRefArray))
>> -        Types = MetadataList.upgradeTypeRefArray(Types);
>> -
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -
>> -    case bitc::METADATA_MODULE: {
>> -      if (Record.size() != 6)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIModule,
>> -                          (Context, getMDOrNull(Record[1]),
>> -                           getMDString(Record[2]),
>> getMDString(Record[3]),
>> -                           getMDString(Record[4]),
>> getMDString(Record[5]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -
>> -    case bitc::METADATA_FILE: {
>> -      if (Record.size() != 3)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIFile, (Context, getMDString(Record[1]),
>> -                                   getMDString(Record[2]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_COMPILE_UNIT: {
>> -      if (Record.size() < 14 || Record.size() > 17)
>> -        return error("Invalid record");
>> -
>> -      // Ignore Record[0], which indicates whether this compile unit is
>> -      // distinct.  It's always distinct.
>> -      IsDistinct = true;
>> -      auto *CU = DICompileUnit::getDistinct(
>> -          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[12]), getMDOrNull(Record[13]),
>> -          Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
>> -          Record.size() <= 14 ? 0 : Record[14],
>> -          Record.size() <= 16 ? true : Record[16]);
>> -
>> -      MetadataList.assignValue(CU, NextMetadataNo++);
>> -
>> -      // Move the Upgrade the list of subprograms.
>> -      if (Metadata *SPs = getMDOrNullWithoutPlaceholders(Record[11]))
>> -        CUSubprograms.push_back({CU, SPs});
>> -      break;
>> -    }
>> -    case bitc::METADATA_SUBPROGRAM: {
>> -      if (Record.size() < 18 || Record.size() > 20)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct =
>> -          (Record[0] & 1) || Record[8]; // All definitions should be
>> distinct.
>> -      // Version 1 has a Function as Record[15].
>> -      // Version 2 has removed Record[15].
>> -      // Version 3 has the Unit as Record[15].
>> -      // Version 4 added thisAdjustment.
>> -      bool HasUnit = Record[0] >= 2;
>> -      if (HasUnit && Record.size() < 19)
>> -        return error("Invalid record");
>> -      Metadata *CUorFn = getMDOrNull(Record[15]);
>> -      unsigned Offset = Record.size() >= 19 ? 1 : 0;
>> -      bool HasFn = Offset && !HasUnit;
>> -      bool HasThisAdj = Record.size() >= 20;
>> -      DISubprogram *SP = GET_OR_DISTINCT(
>> -          DISubprogram, (Context,
>> -                         getDITypeRefOrNull(Record[1]),  // scope
>> -                         getMDString(Record[2]),         // name
>> -                         getMDString(Record[3]),         // linkageName
>> -                         getMDOrNull(Record[4]),         // file
>> -                         Record[5],                      // line
>> -                         getMDOrNull(Record[6]),         // type
>> -                         Record[7],                      // isLocal
>> -                         Record[8],                      // isDefinition
>> -                         Record[9],                      // scopeLine
>> -                         getDITypeRefOrNull(Record[10]), //
>> containingType
>> -                         Record[11],                     // virtuality
>> -                         Record[12],                     // virtualIndex
>> -                         HasThisAdj ? Record[19] : 0,    //
>> thisAdjustment
>> -                         static_cast<DINode::DIFlags>(Record[13] // flags
>> -                                                      ),
>> -                         Record[14],                       // isOptimized
>> -                         HasUnit ? CUorFn : nullptr,       // unit
>> -                         getMDOrNull(Record[15 + Offset]), //
>> templateParams
>> -                         getMDOrNull(Record[16 + Offset]), // declaration
>> -                         getMDOrNull(Record[17 + Offset])  // variables
>> -                         ));
>> -      MetadataList.assignValue(SP, NextMetadataNo++);
>> -
>> -      // Upgrade sp->function mapping to function->sp mapping.
>> -      if (HasFn) {
>> -        if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
>> -          if (auto *F = dyn_cast<Function>(CMD->getValue())) {
>> -            if (F->isMaterializable())
>> -              // Defer until materialized; unmaterialized functions may
>> not have
>> -              // metadata.
>> -              FunctionsWithSPs[F] = SP;
>> -            else if (!F->empty())
>> -              F->setSubprogram(SP);
>> -          }
>> -      }
>> -      break;
>> -    }
>> -    case bitc::METADATA_LEXICAL_BLOCK: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DILexicalBlock,
>> -                          (Context, getMDOrNull(Record[1]),
>> -                           getMDOrNull(Record[2]), Record[3],
>> Record[4])),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_LEXICAL_BLOCK_FILE: {
>> -      if (Record.size() != 4)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DILexicalBlockFile,
>> -                          (Context, getMDOrNull(Record[1]),
>> -                           getMDOrNull(Record[2]), Record[3])),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_NAMESPACE: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0] & 1;
>> -      bool ExportSymbols = Record[0] & 2;
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DINamespace,
>> -                          (Context, getMDOrNull(Record[1]),
>> -                           getMDOrNull(Record[2]),
>> getMDString(Record[3]),
>> -                           Record[4], ExportSymbols)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_MACRO: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIMacro,
>> -                          (Context, Record[1], Record[2],
>> -                           getMDString(Record[3]),
>> getMDString(Record[4]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_MACRO_FILE: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIMacroFile,
>> -                          (Context, Record[1], Record[2],
>> -                           getMDOrNull(Record[3]),
>> getMDOrNull(Record[4]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_TEMPLATE_TYPE: {
>> -      if (Record.size() != 3)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
>> -                                               (Context,
>> getMDString(Record[1]),
>> -
>> getDITypeRefOrNull(Record[2]))),
>> -                               NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_TEMPLATE_VALUE: {
>> -      if (Record.size() != 5)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DITemplateValueParameter,
>> -                          (Context, Record[1], getMDString(Record[2]),
>> -                           getDITypeRefOrNull(Record[3]),
>> -                           getMDOrNull(Record[4]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_GLOBAL_VAR: {
>> -      if (Record.size() < 11 || Record.size() > 12)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -
>> -      // Upgrade old metadata, which stored a global variable reference
>> or a
>> -      // ConstantInt here.
>> -      Metadata *Expr = getMDOrNull(Record[9]);
>> -      uint32_t AlignInBits = 0;
>> -      if (Record.size() > 11) {
>> -        if (Record[11] > (uint64_t)std::numeric_limits<uint32_t>::max())
>> -          return error("Alignment value is too large");
>> -        AlignInBits = Record[11];
>> -      }
>> -      GlobalVariable *Attach = nullptr;
>> -      if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
>> -        if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
>> -          Attach = GV;
>> -          Expr = nullptr;
>> -        } else if (auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
>> -          Expr = DIExpression::get(Context,
>> -                                   {dwarf::DW_OP_constu, CI-
>>> getZExtValue(),
>> -                                    dwarf::DW_OP_stack_value});
>> -        } else {
>> -          Expr = nullptr;
>> -        }
>> -      }
>> -
>> -      DIGlobalVariable *DGV = GET_OR_DISTINCT(
>> -          DIGlobalVariable,
>> -          (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
>> -           getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
>> -           getDITypeRefOrNull(Record[6]), Record[7], Record[8], Expr,
>> -           getMDOrNull(Record[10]), AlignInBits));
>> -      MetadataList.assignValue(DGV, NextMetadataNo++);
>> -
>> -      if (Attach)
>> -        Attach->addDebugInfo(DGV);
>> -
>> -      break;
>> -    }
>> -    case bitc::METADATA_LOCAL_VAR: {
>> -      // 10th field is for the obseleted 'inlinedAt:' field.
>> -      if (Record.size() < 8 || Record.size() > 10)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0] & 1;
>> -      bool HasAlignment = Record[0] & 2;
>> -      // 2nd field used to be an artificial tag, either
>> DW_TAG_auto_variable or
>> -      // DW_TAG_arg_variable, if we have alignment flag encoded it means,
>> that
>> -      // this is newer version of record which doesn't have artifical
>> tag.
>> -      bool HasTag = !HasAlignment && Record.size() > 8;
>> -      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 +
>> HasTag]);
>> -      uint32_t AlignInBits = 0;
>> -      if (HasAlignment) {
>> -        if (Record[8 + HasTag] >
>> -            (uint64_t)std::numeric_limits<uint32_t>::max())
>> -          return error("Alignment value is too large");
>> -        AlignInBits = Record[8 + HasTag];
>> -      }
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DILocalVariable,
>> -                          (Context, getMDOrNull(Record[1 + HasTag]),
>> -                           getMDString(Record[2 + HasTag]),
>> -                           getMDOrNull(Record[3 + HasTag]), Record[4 +
>> HasTag],
>> -                           getDITypeRefOrNull(Record[5 + HasTag]),
>> -                           Record[6 + HasTag], Flags, AlignInBits)),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_EXPRESSION: {
>> -      if (Record.size() < 1)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0] & 1;
>> -      bool HasOpFragment = Record[0] & 2;
>> -      auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);
>> -      if (!HasOpFragment)
>> -        if (unsigned N = Elts.size())
>> -          if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
>> -            Elts[N-3] = dwarf::DW_OP_LLVM_fragment;
>> -
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIExpression,
>> -                          (Context, makeArrayRef(Record).slice(1))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_OBJC_PROPERTY: {
>> -      if (Record.size() != 8)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIObjCProperty,
>> -                          (Context, getMDString(Record[1]),
>> -                           getMDOrNull(Record[2]), Record[3],
>> -                           getMDString(Record[4]),
>> getMDString(Record[5]),
>> -                           Record[6], getDITypeRefOrNull(Record[7]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_IMPORTED_ENTITY: {
>> -      if (Record.size() != 6)
>> -        return error("Invalid record");
>> -
>> -      IsDistinct = Record[0];
>> -      MetadataList.assignValue(
>> -          GET_OR_DISTINCT(DIImportedEntity,
>> -                          (Context, Record[1], getMDOrNull(Record[2]),
>> -                           getDITypeRefOrNull(Record[3]), Record[4],
>> -                           getMDString(Record[5]))),
>> -          NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_STRING_OLD: {
>> -      std::string String(Record.begin(), Record.end());
>> -
>> -      // Test for upgrading !llvm.loop.
>> -      HasSeenOldLoopTags |= mayBeOldLoopAttachmentTag(String);
>> -
>> -      Metadata *MD = MDString::get(Context, String);
>> -      MetadataList.assignValue(MD, NextMetadataNo++);
>> -      break;
>> -    }
>> -    case bitc::METADATA_STRINGS:
>> -      if (Error Err = parseMetadataStrings(Record, Blob, NextMetadataNo))
>> -        return Err;
>> -      break;
>> -    case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
>> -      if (Record.size() % 2 == 0)
>> -        return error("Invalid record");
>> -      unsigned ValueID = Record[0];
>> -      if (ValueID >= ValueList.size())
>> -        return error("Invalid record");
>> -      if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
>> -        if (Error Err = parseGlobalObjectAttachment(
>> -                *GO, ArrayRef<uint64_t>(Record).slice(1)))
>> -          return Err;
>> -      break;
>> -    }
>> -    case bitc::METADATA_KIND: {
>> -      // Support older bitcode files that had METADATA_KIND records in a
>> -      // block with METADATA_BLOCK_ID.
>> -      if (Error Err = parseMetadataKindRecord(Record))
>> -        return Err;
>> -      break;
>> -    }
>> -    }
>> -  }
>> -
>> -#undef GET_OR_DISTINCT
>> -}
>> -
>> -/// Parse the metadata kinds out of the METADATA_KIND_BLOCK.
>> -Error BitcodeReader::parseMetadataKinds() {
>> -  if (Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID))
>> -    return error("Invalid record");
>> -
>> -  SmallVector<uint64_t, 64> Record;
>> -
>> -  // Read all the records.
>> -  while (true) {
>> -    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 Error::success();
>> -    case BitstreamEntry::Record:
>> -      // The interesting case.
>> -      break;
>> -    }
>> -
>> -    // Read a record.
>> -    Record.clear();
>> -    unsigned Code = Stream.readRecord(Entry.ID, Record);
>> -    switch (Code) {
>> -    default: // Default behavior: ignore.
>> -      break;
>> -    case bitc::METADATA_KIND: {
>> -      if (Error Err = parseMetadataKindRecord(Record))
>> -        return Err;
>> -      break;
>> -    }
>> -    }
>> -  }
>> -}
>> -
>> /// Decode a signed value stored with the sign bit in the LSB for dense
>> VBR
>> /// encoding.
>> uint64_t BitcodeReader::decodeSignRotatedValue(uint64_t V) {
>> @@ -3777,7 +2483,7 @@ Error BitcodeReader::materializeMetadata
>>   for (uint64_t BitPos : DeferredMetadataInfo) {
>>     // Move the bit stream to the saved position.
>>     Stream.JumpToBit(BitPos);
>> -    if (Error Err = parseMetadata(true))
>> +    if (Error Err = MDLoader->parseModuleMetadata())
>>       return Err;
>>   }
>>   DeferredMetadataInfo.clear();
>> @@ -3961,11 +2667,11 @@ Error BitcodeReader::parseModule(uint64_
>>           break;
>>         }
>>         assert(DeferredMetadataInfo.empty() && "Unexpected deferred
>> metadata");
>> -        if (Error Err = parseMetadata(true))
>> +        if (Error Err = MDLoader->parseModuleMetadata())
>>           return Err;
>>         break;
>>       case bitc::METADATA_KIND_BLOCK_ID:
>> -        if (Error Err = parseMetadataKinds())
>> +        if (Error Err = MDLoader->parseMetadataKinds())
>>           return Err;
>>         break;
>>       case bitc::FUNCTION_BLOCK_ID:
>> @@ -4367,92 +3073,11 @@ Error BitcodeReader::parseModule(uint64_
>> 
>> Error BitcodeReader::parseBitcodeInto(Module *M, bool
>> ShouldLazyLoadMetadata) {
>>   TheModule = M;
>> +  MDLoader = MetadataLoader(Stream, *M, ValueList,
>> +                            [&](unsigned ID) { return getTypeByID(ID);
>> });
>>   return parseModule(0, ShouldLazyLoadMetadata);
>> }
>> 
>> -Error BitcodeReader::parseGlobalObjectAttachment(GlobalObject &GO,
>> -                                                 ArrayRef<uint64_t>
>> Record) {
>> -  assert(Record.size() % 2 == 0);
>> -  for (unsigned I = 0, E = Record.size(); I != E; I += 2) {
>> -    auto K = MDKindMap.find(Record[I]);
>> -    if (K == MDKindMap.end())
>> -      return error("Invalid ID");
>> -    MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
>> -    if (!MD)
>> -      return error("Invalid metadata attachment");
>> -    GO.addMetadata(K->second, *MD);
>> -  }
>> -  return Error::success();
>> -}
>> -
>> -/// Parse metadata attachments.
>> -Error BitcodeReader::parseMetadataAttachment(Function &F) {
>> -  if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
>> -    return error("Invalid record");
>> -
>> -  SmallVector<uint64_t, 64> Record;
>> -
>> -  while (true) {
>> -    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 Error::success();
>> -    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.
>> -        if (Error Err = parseGlobalObjectAttachment(F, Record))
>> -          return Err;
>> -        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 = MetadataList.getMetadataFwdRef(Record[i + 1]);
>> -        if (isa<LocalAsMetadata>(Node))
>> -          // Drop the attachment.  This used to be legal, but there's no
>> -          // upgrade path.
>> -          break;
>> -        MDNode *MD = dyn_cast_or_null<MDNode>(Node);
>> -        if (!MD)
>> -          return error("Invalid metadata attachment");
>> -
>> -        if (HasSeenOldLoopTags && I->second == LLVMContext::MD_loop)
>> -          MD = upgradeInstructionLoopAttachment(*MD);
>> -
>> -        if (I->second == LLVMContext::MD_tbaa) {
>> -          assert(!MD->isTemporary() && "should load MDs before
>> attachments");
>> -          MD = UpgradeTBAANode(*MD);
>> -        }
>> -        Inst->setMetadata(I->second, MD);
>> -      }
>> -      break;
>> -    }
>> -    }
>> -  }
>> -}
>> 
>> Error BitcodeReader::typeCheckLoadStoreInst(Type *ValType, Type *PtrType)
>> {
>>   if (!isa<PointerType>(PtrType))
>> @@ -4473,12 +3098,12 @@ Error BitcodeReader::parseFunctionBody(F
>>     return error("Invalid record");
>> 
>>   // Unexpected unresolved metadata when parsing function.
>> -  if (MetadataList.hasFwdRefs())
>> +  if (MDLoader->hasFwdRefs())
>>     return error("Invalid function metadata: incoming forward
>> references");
>> 
>>   InstructionList.clear();
>>   unsigned ModuleValueListSize = ValueList.size();
>> -  unsigned ModuleMetadataListSize = MetadataList.size();
>> +  unsigned ModuleMDLoaderSize = MDLoader->size();
>> 
>>   // Add all the function arguments to the value table.
>>   for (Argument &I : F->args())
>> @@ -4528,11 +3153,13 @@ Error BitcodeReader::parseFunctionBody(F
>>           return Err;
>>         break;
>>       case bitc::METADATA_ATTACHMENT_ID:
>> -        if (Error Err = parseMetadataAttachment(*F))
>> +        if (Error Err = MDLoader->parseMetadataAttachment(*F,
>> InstructionList))
>>           return Err;
>>         break;
>>       case bitc::METADATA_BLOCK_ID:
>> -        if (Error Err = parseMetadata())
>> +        assert(DeferredMetadataInfo.empty() &&
>> +               "Must read all module-level metadata before function-
>> level");
>> +        if (Error Err = MDLoader->parseFunctionMetadata())
>>           return Err;
>>         break;
>>       case bitc::USELIST_BLOCK_ID:
>> @@ -4610,12 +3237,12 @@ Error BitcodeReader::parseFunctionBody(F
>> 
>>       MDNode *Scope = nullptr, *IA = nullptr;
>>       if (ScopeID) {
>> -        Scope = MetadataList.getMDNodeFwdRefOrNull(ScopeID - 1);
>> +        Scope = MDLoader->getMDNodeFwdRefOrNull(ScopeID - 1);
>>         if (!Scope)
>>           return error("Invalid record");
>>       }
>>       if (IAID) {
>> -        IA = MetadataList.getMDNodeFwdRefOrNull(IAID - 1);
>> +        IA = MDLoader->getMDNodeFwdRefOrNull(IAID - 1);
>>         if (!IA)
>>           return error("Invalid record");
>>       }
>> @@ -5740,12 +4367,12 @@ OutOfRecordLoop:
>>   }
>> 
>>   // Unexpected unresolved metadata about to be dropped.
>> -  if (MetadataList.hasFwdRefs())
>> +  if (MDLoader->hasFwdRefs())
>>     return error("Invalid function metadata: outgoing forward refs");
>> 
>>   // Trim the value list down to the size it was before we parsed this
>> function.
>>   ValueList.shrinkTo(ModuleValueListSize);
>> -  MetadataList.shrinkTo(ModuleMetadataListSize);
>> +  MDLoader->shrinkTo(ModuleMDLoaderSize);
>>   std::vector<BasicBlock*>().swap(FunctionBBs);
>>   return Error::success();
>> }
>> @@ -5819,7 +4446,7 @@ Error BitcodeReader::materialize(GlobalV
>>       CallSite(*UI++).setCalledFunction(I.second);
>> 
>>   // Finish fn->subprogram upgrade for materialized functions.
>> -  if (DISubprogram *SP = FunctionsWithSPs.lookup(F))
>> +  if (DISubprogram *SP = MDLoader->lookupSubprogramForFunction(F))
>>     F->setSubprogram(SP);
>> 
>>   // Bring in any functions that this function forward-referenced via
>> 
>> Modified: llvm/trunk/lib/Bitcode/Reader/CMakeLists.txt
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/CMakeLists.txt?rev=289461&r1=289460&
>> r2=289461&view=diff
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/CMakeLists.txt (original)
>> +++ llvm/trunk/lib/Bitcode/Reader/CMakeLists.txt Mon Dec 12 13:34:26 2016
>> @@ -2,6 +2,8 @@ add_llvm_library(LLVMBitReader
>>   BitReader.cpp
>>   BitcodeReader.cpp
>>   BitstreamReader.cpp
>> +  MetadataLoader.cpp
>> +  ValueList.cpp
>> 
>>   ADDITIONAL_HEADER_DIRS
>>   ${LLVM_MAIN_INCLUDE_DIR}/llvm/Bitcode
>> 
>> Added: llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp?rev=289461&view=a
>> uto
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp (added)
>> +++ llvm/trunk/lib/Bitcode/Reader/MetadataLoader.cpp Mon Dec 12 13:34:26
>> 2016
>> @@ -0,0 +1,1316 @@
>> +//===- MetadataLoader.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 "MetadataLoader.h"
>> +#include "ValueList.h"
>> +
>> +#include "llvm/ADT/APFloat.h"
>> +#include "llvm/ADT/APInt.h"
>> +#include "llvm/ADT/ArrayRef.h"
>> +#include "llvm/ADT/DenseMap.h"
>> +#include "llvm/ADT/None.h"
>> +#include "llvm/ADT/STLExtras.h"
>> +#include "llvm/ADT/SmallString.h"
>> +#include "llvm/ADT/SmallVector.h"
>> +#include "llvm/ADT/StringRef.h"
>> +#include "llvm/ADT/Triple.h"
>> +#include "llvm/ADT/Twine.h"
>> +#include "llvm/Bitcode/BitcodeReader.h"
>> +#include "llvm/Bitcode/BitstreamReader.h"
>> +#include "llvm/Bitcode/LLVMBitCodes.h"
>> +#include "llvm/IR/Argument.h"
>> +#include "llvm/IR/Attributes.h"
>> +#include "llvm/IR/AutoUpgrade.h"
>> +#include "llvm/IR/BasicBlock.h"
>> +#include "llvm/IR/CallSite.h"
>> +#include "llvm/IR/CallingConv.h"
>> +#include "llvm/IR/Comdat.h"
>> +#include "llvm/IR/Constant.h"
>> +#include "llvm/IR/Constants.h"
>> +#include "llvm/IR/DebugInfo.h"
>> +#include "llvm/IR/DebugInfoMetadata.h"
>> +#include "llvm/IR/DebugLoc.h"
>> +#include "llvm/IR/DerivedTypes.h"
>> +#include "llvm/IR/DiagnosticInfo.h"
>> +#include "llvm/IR/DiagnosticPrinter.h"
>> +#include "llvm/IR/Function.h"
>> +#include "llvm/IR/GVMaterializer.h"
>> +#include "llvm/IR/GlobalAlias.h"
>> +#include "llvm/IR/GlobalIFunc.h"
>> +#include "llvm/IR/GlobalIndirectSymbol.h"
>> +#include "llvm/IR/GlobalObject.h"
>> +#include "llvm/IR/GlobalValue.h"
>> +#include "llvm/IR/GlobalVariable.h"
>> +#include "llvm/IR/InlineAsm.h"
>> +#include "llvm/IR/InstrTypes.h"
>> +#include "llvm/IR/Instruction.h"
>> +#include "llvm/IR/Instructions.h"
>> +#include "llvm/IR/Intrinsics.h"
>> +#include "llvm/IR/LLVMContext.h"
>> +#include "llvm/IR/Module.h"
>> +#include "llvm/IR/ModuleSummaryIndex.h"
>> +#include "llvm/IR/OperandTraits.h"
>> +#include "llvm/IR/Operator.h"
>> +#include "llvm/IR/TrackingMDRef.h"
>> +#include "llvm/IR/Type.h"
>> +#include "llvm/IR/ValueHandle.h"
>> +#include "llvm/Support/AtomicOrdering.h"
>> +#include "llvm/Support/Casting.h"
>> +#include "llvm/Support/CommandLine.h"
>> +#include "llvm/Support/Compiler.h"
>> +#include "llvm/Support/Debug.h"
>> +#include "llvm/Support/Error.h"
>> +#include "llvm/Support/ErrorHandling.h"
>> +#include "llvm/Support/ManagedStatic.h"
>> +#include "llvm/Support/MemoryBuffer.h"
>> +#include "llvm/Support/raw_ostream.h"
>> +#include <algorithm>
>> +#include <cassert>
>> +#include <cstddef>
>> +#include <cstdint>
>> +#include <deque>
>> +#include <limits>
>> +#include <map>
>> +#include <memory>
>> +#include <string>
>> +#include <system_error>
>> +#include <tuple>
>> +#include <utility>
>> +#include <vector>
>> +
>> +using namespace llvm;
>> +
>> +namespace {
>> +
>> +static int64_t unrotateSign(uint64_t U) { return U & 1 ? ~(U >> 1) : U >>
>> 1; }
>> +
>> +class BitcodeReaderMetadataList {
>> +  unsigned NumFwdRefs;
>> +  bool AnyFwdRefs;
>> +  unsigned MinFwdRef;
>> +  unsigned MaxFwdRef;
>> +
>> +  /// Array of metadata references.
>> +  ///
>> +  /// Don't use std::vector here.  Some versions of libc++ copy (instead
>> of
>> +  /// move) on resize, and TrackingMDRef is very expensive to copy.
>> +  SmallVector<TrackingMDRef, 1> MetadataPtrs;
>> +
>> +  /// Structures for resolving old type refs.
>> +  struct {
>> +    SmallDenseMap<MDString *, TempMDTuple, 1> Unknown;
>> +    SmallDenseMap<MDString *, DICompositeType *, 1> Final;
>> +    SmallDenseMap<MDString *, DICompositeType *, 1> FwdDecls;
>> +    SmallVector<std::pair<TrackingMDRef, TempMDTuple>, 1> Arrays;
>> +  } OldTypeRefs;
>> +
>> +  LLVMContext &Context;
>> +
>> +public:
>> +  BitcodeReaderMetadataList(LLVMContext &C)
>> +      : NumFwdRefs(0), AnyFwdRefs(false), Context(C) {}
>> +
>> +  // vector compatibility methods
>> +  unsigned size() const { return MetadataPtrs.size(); }
>> +  void resize(unsigned N) { MetadataPtrs.resize(N); }
>> +  void push_back(Metadata *MD) { MetadataPtrs.emplace_back(MD); }
>> +  void clear() { MetadataPtrs.clear(); }
>> +  Metadata *back() const { return MetadataPtrs.back(); }
>> +  void pop_back() { MetadataPtrs.pop_back(); }
>> +  bool empty() const { return MetadataPtrs.empty(); }
>> +
>> +  Metadata *operator[](unsigned i) const {
>> +    assert(i < MetadataPtrs.size());
>> +    return MetadataPtrs[i];
>> +  }
>> +
>> +  Metadata *lookup(unsigned I) const {
>> +    if (I < MetadataPtrs.size())
>> +      return MetadataPtrs[I];
>> +    return nullptr;
>> +  }
>> +
>> +  void shrinkTo(unsigned N) {
>> +    assert(N <= size() && "Invalid shrinkTo request!");
>> +    assert(!AnyFwdRefs && "Unexpected forward refs");
>> +    MetadataPtrs.resize(N);
>> +  }
>> +
>> +  /// Return the given metadata, creating a replaceable forward reference
>> if
>> +  /// necessary.
>> +  Metadata *getMetadataFwdRef(unsigned Idx);
>> +
>> +  /// Return the the given metadata only if it is fully resolved.
>> +  ///
>> +  /// Gives the same result as \a lookup(), unless \a
>> MDNode::isResolved()
>> +  /// would give \c false.
>> +  Metadata *getMetadataIfResolved(unsigned Idx);
>> +
>> +  MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
>> +  void assignValue(Metadata *MD, unsigned Idx);
>> +  void tryToResolveCycles();
>> +  bool hasFwdRefs() const { return AnyFwdRefs; }
>> +
>> +  /// Upgrade a type that had an MDString reference.
>> +  void addTypeRef(MDString &UUID, DICompositeType &CT);
>> +
>> +  /// Upgrade a type that had an MDString reference.
>> +  Metadata *upgradeTypeRef(Metadata *MaybeUUID);
>> +
>> +  /// Upgrade a type ref array that may have MDString references.
>> +  Metadata *upgradeTypeRefArray(Metadata *MaybeTuple);
>> +
>> +private:
>> +  Metadata *resolveTypeRefArray(Metadata *MaybeTuple);
>> +};
>> +
>> +void BitcodeReaderMetadataList::assignValue(Metadata *MD, unsigned Idx) {
>> +  if (Idx == size()) {
>> +    push_back(MD);
>> +    return;
>> +  }
>> +
>> +  if (Idx >= size())
>> +    resize(Idx + 1);
>> +
>> +  TrackingMDRef &OldMD = MetadataPtrs[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 *BitcodeReaderMetadataList::getMetadataFwdRef(unsigned Idx) {
>> +  if (Idx >= size())
>> +    resize(Idx + 1);
>> +
>> +  if (Metadata *MD = MetadataPtrs[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();
>> +  MetadataPtrs[Idx].reset(MD);
>> +  return MD;
>> +}
>> +
>> +Metadata *BitcodeReaderMetadataList::getMetadataIfResolved(unsigned Idx)
>> {
>> +  Metadata *MD = lookup(Idx);
>> +  if (auto *N = dyn_cast_or_null<MDNode>(MD))
>> +    if (!N->isResolved())
>> +      return nullptr;
>> +  return MD;
>> +}
>> +
>> +MDNode *BitcodeReaderMetadataList::getMDNodeFwdRefOrNull(unsigned Idx) {
>> +  return dyn_cast_or_null<MDNode>(getMetadataFwdRef(Idx));
>> +}
>> +
>> +void BitcodeReaderMetadataList::tryToResolveCycles() {
>> +  if (NumFwdRefs)
>> +    // Still forward references... can't resolve cycles.
>> +    return;
>> +
>> +  bool DidReplaceTypeRefs = false;
>> +
>> +  // Give up on finding a full definition for any forward decls that
>> remain.
>> +  for (const auto &Ref : OldTypeRefs.FwdDecls)
>> +    OldTypeRefs.Final.insert(Ref);
>> +  OldTypeRefs.FwdDecls.clear();
>> +
>> +  // Upgrade from old type ref arrays.  In strange cases, this could add
>> to
>> +  // OldTypeRefs.Unknown.
>> +  for (const auto &Array : OldTypeRefs.Arrays) {
>> +    DidReplaceTypeRefs = true;
>> +    Array.second-
>>> replaceAllUsesWith(resolveTypeRefArray(Array.first.get()));
>> +  }
>> +  OldTypeRefs.Arrays.clear();
>> +
>> +  // Replace old string-based type refs with the resolved node, if
>> possible.
>> +  // If we haven't seen the node, leave it to the verifier to complain
>> about
>> +  // the invalid string reference.
>> +  for (const auto &Ref : OldTypeRefs.Unknown) {
>> +    DidReplaceTypeRefs = true;
>> +    if (DICompositeType *CT = OldTypeRefs.Final.lookup(Ref.first))
>> +      Ref.second->replaceAllUsesWith(CT);
>> +    else
>> +      Ref.second->replaceAllUsesWith(Ref.first);
>> +  }
>> +  OldTypeRefs.Unknown.clear();
>> +
>> +  // Make sure all the upgraded types are resolved.
>> +  if (DidReplaceTypeRefs) {
>> +    AnyFwdRefs = true;
>> +    MinFwdRef = 0;
>> +    MaxFwdRef = MetadataPtrs.size() - 1;
>> +  }
>> +
>> +  if (!AnyFwdRefs)
>> +    // Nothing to do.
>> +    return;
>> +
>> +  // Resolve any cycles.
>> +  for (unsigned I = MinFwdRef, E = MaxFwdRef + 1; I != E; ++I) {
>> +    auto &MD = MetadataPtrs[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;
>> +}
>> +
>> +void BitcodeReaderMetadataList::addTypeRef(MDString &UUID,
>> +                                           DICompositeType &CT) {
>> +  assert(CT.getRawIdentifier() == &UUID && "Mismatched UUID");
>> +  if (CT.isForwardDecl())
>> +    OldTypeRefs.FwdDecls.insert(std::make_pair(&UUID, &CT));
>> +  else
>> +    OldTypeRefs.Final.insert(std::make_pair(&UUID, &CT));
>> +}
>> +
>> +Metadata *BitcodeReaderMetadataList::upgradeTypeRef(Metadata *MaybeUUID)
>> {
>> +  auto *UUID = dyn_cast_or_null<MDString>(MaybeUUID);
>> +  if (LLVM_LIKELY(!UUID))
>> +    return MaybeUUID;
>> +
>> +  if (auto *CT = OldTypeRefs.Final.lookup(UUID))
>> +    return CT;
>> +
>> +  auto &Ref = OldTypeRefs.Unknown[UUID];
>> +  if (!Ref)
>> +    Ref = MDNode::getTemporary(Context, None);
>> +  return Ref.get();
>> +}
>> +
>> +Metadata *BitcodeReaderMetadataList::upgradeTypeRefArray(Metadata
>> *MaybeTuple) {
>> +  auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
>> +  if (!Tuple || Tuple->isDistinct())
>> +    return MaybeTuple;
>> +
>> +  // Look through the array immediately if possible.
>> +  if (!Tuple->isTemporary())
>> +    return resolveTypeRefArray(Tuple);
>> +
>> +  // Create and return a placeholder to use for now.  Eventually
>> +  // resolveTypeRefArrays() will be resolve this forward reference.
>> +  OldTypeRefs.Arrays.emplace_back(
>> +      std::piecewise_construct, std::forward_as_tuple(Tuple),
>> +      std::forward_as_tuple(MDTuple::getTemporary(Context, None)));
>> +  return OldTypeRefs.Arrays.back().second.get();
>> +}
>> +
>> +Metadata *BitcodeReaderMetadataList::resolveTypeRefArray(Metadata
>> *MaybeTuple) {
>> +  auto *Tuple = dyn_cast_or_null<MDTuple>(MaybeTuple);
>> +  if (!Tuple || Tuple->isDistinct())
>> +    return MaybeTuple;
>> +
>> +  // Look through the DITypeRefArray, upgrading each DITypeRef.
>> +  SmallVector<Metadata *, 32> Ops;
>> +  Ops.reserve(Tuple->getNumOperands());
>> +  for (Metadata *MD : Tuple->operands())
>> +    Ops.push_back(upgradeTypeRef(MD));
>> +
>> +  return MDTuple::get(Context, Ops);
>> +}
>> +
>> +namespace {
>> +
>> +class PlaceholderQueue {
>> +  // Placeholders would thrash around when moved, so store in a
>> std::deque
>> +  // instead of some sort of vector.
>> +  std::deque<DistinctMDOperandPlaceholder> PHs;
>> +
>> +public:
>> +  DistinctMDOperandPlaceholder &getPlaceholderOp(unsigned ID);
>> +  void flush(BitcodeReaderMetadataList &MetadataList);
>> +};
>> +
>> +} // end anonymous namespace
>> +
>> +DistinctMDOperandPlaceholder &PlaceholderQueue::getPlaceholderOp(unsigned
>> ID) {
>> +  PHs.emplace_back(ID);
>> +  return PHs.back();
>> +}
>> +
>> +void PlaceholderQueue::flush(BitcodeReaderMetadataList &MetadataList) {
>> +  while (!PHs.empty()) {
>> +    PHs.front().replaceUseWith(
>> +        MetadataList.getMetadataFwdRef(PHs.front().getID()));
>> +    PHs.pop_front();
>> +  }
>> +}
>> +
>> +} // anonynous namespace
>> +
>> +class MetadataLoader::MetadataLoaderImpl {
>> +  BitcodeReaderMetadataList MetadataList;
>> +  BitcodeReaderValueList &ValueList;
>> +  BitstreamCursor &Stream;
>> +  LLVMContext &Context;
>> +  Module &TheModule;
>> +  std::function<Type *(unsigned)> getTypeByID;
>> +
>> +  /// Functions that need to be matched with subprograms when upgrading
>> old
>> +  /// metadata.
>> +  SmallDenseMap<Function *, DISubprogram *, 16> FunctionsWithSPs;
>> +
>> +  // Map the bitcode's custom MDKind ID to the Module's MDKind ID.
>> +  DenseMap<unsigned, unsigned> MDKindMap;
>> +
>> +  bool HasSeenOldLoopTags = false;
>> +
>> +  Error parseMetadataStrings(ArrayRef<uint64_t> Record, StringRef Blob,
>> +                             unsigned &NextMetadataNo);
>> +  Error parseGlobalObjectAttachment(GlobalObject &GO,
>> +                                    ArrayRef<uint64_t> Record);
>> +  Error parseMetadataKindRecord(SmallVectorImpl<uint64_t> &Record);
>> +
>> +public:
>> +  MetadataLoaderImpl(BitstreamCursor &Stream, Module &TheModule,
>> +                     BitcodeReaderValueList &ValueList,
>> +                     std::function<Type *(unsigned)> getTypeByID)
>> +      : MetadataList(TheModule.getContext()), ValueList(ValueList),
>> +        Stream(Stream), Context(TheModule.getContext()),
>> TheModule(TheModule),
>> +        getTypeByID(getTypeByID) {}
>> +
>> +  Error parseMetadata(bool ModuleLevel);
>> +
>> +  bool hasFwdRefs() const { return MetadataList.hasFwdRefs(); }
>> +  Metadata *getMetadataFwdRef(unsigned Idx) {
>> +    return MetadataList.getMetadataFwdRef(Idx);
>> +  }
>> +
>> +  MDNode *getMDNodeFwdRefOrNull(unsigned Idx) {
>> +    return MetadataList.getMDNodeFwdRefOrNull(Idx);
>> +  }
>> +
>> +  DISubprogram *lookupSubprogramForFunction(Function *F) {
>> +    return FunctionsWithSPs.lookup(F);
>> +  }
>> +
>> +  bool hasSeenOldLoopTags() { return HasSeenOldLoopTags; }
>> +
>> +  Error parseMetadataAttachment(
>> +      Function &F, const SmallVectorImpl<Instruction *>
>> &InstructionList);
>> +
>> +  Error parseMetadataKinds();
>> +
>> +  unsigned size() const { return MetadataList.size(); }
>> +  void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
>> +};
>> +
>> +Error error(const Twine &Message) {
>> +  return make_error<StringError>(
>> +      Message, make_error_code(BitcodeError::CorruptedBitcode));
>> +}
>> +
>> +/// Parse a METADATA_BLOCK. If ModuleLevel is true then we are parsing
>> +/// module level metadata.
>> +Error MetadataLoader::MetadataLoaderImpl::parseMetadata(bool ModuleLevel)
>> {
>> +  if (!ModuleLevel && MetadataList.hasFwdRefs())
>> +    return error("Invalid metadata: fwd refs into function blocks");
>> +
>> +  if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID))
>> +    return error("Invalid record");
>> +
>> +  unsigned NextMetadataNo = MetadataList.size();
>> +  std::vector<std::pair<DICompileUnit *, Metadata *>> CUSubprograms;
>> +  SmallVector<uint64_t, 64> Record;
>> +
>> +  PlaceholderQueue Placeholders;
>> +  bool IsDistinct;
>> +  auto getMD = [&](unsigned ID) -> Metadata * {
>> +    if (!IsDistinct)
>> +      return MetadataList.getMetadataFwdRef(ID);
>> +    if (auto *MD = MetadataList.getMetadataIfResolved(ID))
>> +      return MD;
>> +    return &Placeholders.getPlaceholderOp(ID);
>> +  };
>> +  auto getMDOrNull = [&](unsigned ID) -> Metadata * {
>> +    if (ID)
>> +      return getMD(ID - 1);
>> +    return nullptr;
>> +  };
>> +  auto getMDOrNullWithoutPlaceholders = [&](unsigned ID) -> Metadata * {
>> +    if (ID)
>> +      return MetadataList.getMetadataFwdRef(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));
>> +  };
>> +
>> +  // Support for old type refs.
>> +  auto getDITypeRefOrNull = [&](unsigned ID) {
>> +    return MetadataList.upgradeTypeRef(getMDOrNull(ID));
>> +  };
>> +
>> +#define GET_OR_DISTINCT(CLASS, ARGS)
>> \
>> +  (IsDistinct ? CLASS::getDistinct ARGS : CLASS::get ARGS)
>> +
>> +  // Read all the records.
>> +  while (true) {
>> +    BitstreamEntry Entry = Stream.advanceSkippingSubblocks();
>> +
>> +    switch (Entry.Kind) {
>> +    case BitstreamEntry::SubBlock: // Handled for us already.
>> +    case BitstreamEntry::Error:
>> +      return error("Malformed block");
>> +    case BitstreamEntry::EndBlock:
>> +      // Upgrade old-style CU <-> SP pointers to point from SP to CU.
>> +      for (auto CU_SP : CUSubprograms)
>> +        if (auto *SPs = dyn_cast_or_null<MDTuple>(CU_SP.second))
>> +          for (auto &Op : SPs->operands())
>> +            if (auto *SP = dyn_cast_or_null<MDNode>(Op))
>> +              SP->replaceOperandWith(7, CU_SP.first);
>> +
>> +      MetadataList.tryToResolveCycles();
>> +      Placeholders.flush(MetadataList);
>> +      return Error::success();
>> +    case BitstreamEntry::Record:
>> +      // The interesting case.
>> +      break;
>> +    }
>> +
>> +    // Read a record.
>> +    Record.clear();
>> +    StringRef Blob;
>> +    unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob);
>> +    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 = MetadataList.getMDNodeFwdRefOrNull(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 = [&] {
>> +        MetadataList.assignValue(MDNode::get(Context, None),
>> NextMetadataNo++);
>> +      };
>> +      if (Record.size() != 2) {
>> +        dropRecord();
>> +        break;
>> +      }
>> +
>> +      Type *Ty = getTypeByID(Record[0]);
>> +      if (Ty->isMetadataTy() || Ty->isVoidTy()) {
>> +        dropRecord();
>> +        break;
>> +      }
>> +
>> +      MetadataList.assignValue(
>> +          LocalAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
>> +          NextMetadataNo++);
>> +      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(getMD(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);
>> +      }
>> +      MetadataList.assignValue(MDNode::get(Context, Elts),
>> NextMetadataNo++);
>> +      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");
>> +
>> +      MetadataList.assignValue(
>> +          ValueAsMetadata::get(ValueList.getValueFwdRef(Record[1], Ty)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_DISTINCT_NODE:
>> +      IsDistinct = true;
>> +      LLVM_FALLTHROUGH;
>> +    case bitc::METADATA_NODE: {
>> +      SmallVector<Metadata *, 8> Elts;
>> +      Elts.reserve(Record.size());
>> +      for (unsigned ID : Record)
>> +        Elts.push_back(getMDOrNull(ID));
>> +      MetadataList.assignValue(IsDistinct ? MDNode::getDistinct(Context,
>> Elts)
>> +                                          : MDNode::get(Context, Elts),
>> +                               NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_LOCATION: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      unsigned Line = Record[1];
>> +      unsigned Column = Record[2];
>> +      Metadata *Scope = getMD(Record[3]);
>> +      Metadata *InlinedAt = getMDOrNull(Record[4]);
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DILocation,
>> +                          (Context, Line, Column, Scope, InlinedAt)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_GENERIC_DEBUG: {
>> +      if (Record.size() < 4)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      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(getMDOrNull(Record[I]));
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(GenericDINode, (Context, Tag, Header,
>> DwarfOps)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_SUBRANGE: {
>> +      if (Record.size() != 3)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DISubrange,
>> +                          (Context, Record[1], unrotateSign(Record[2]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_ENUMERATOR: {
>> +      if (Record.size() != 3)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIEnumerator, (Context,
>> unrotateSign(Record[1]),
>> +                                         getMDString(Record[2]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_BASIC_TYPE: {
>> +      if (Record.size() != 6)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIBasicType,
>> +                          (Context, Record[1], getMDString(Record[2]),
>> +                           Record[3], Record[4], Record[5])),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_DERIVED_TYPE: {
>> +      if (Record.size() != 12)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIDerivedType,
>> +                          (Context, Record[1], getMDString(Record[2]),
>> +                           getMDOrNull(Record[3]), Record[4],
>> +                           getDITypeRefOrNull(Record[5]),
>> +                           getDITypeRefOrNull(Record[6]), Record[7],
>> Record[8],
>> +                           Record[9], Flags,
>> getDITypeRefOrNull(Record[11]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_COMPOSITE_TYPE: {
>> +      if (Record.size() != 16)
>> +        return error("Invalid record");
>> +
>> +      // If we have a UUID and this is not a forward declaration, lookup
>> the
>> +      // mapping.
>> +      IsDistinct = Record[0] & 0x1;
>> +      bool IsNotUsedInTypeRef = Record[0] >= 2;
>> +      unsigned Tag = Record[1];
>> +      MDString *Name = getMDString(Record[2]);
>> +      Metadata *File = getMDOrNull(Record[3]);
>> +      unsigned Line = Record[4];
>> +      Metadata *Scope = getDITypeRefOrNull(Record[5]);
>> +      Metadata *BaseType = getDITypeRefOrNull(Record[6]);
>> +      uint64_t SizeInBits = Record[7];
>> +      if (Record[8] > (uint64_t)std::numeric_limits<uint32_t>::max())
>> +        return error("Alignment value is too large");
>> +      uint32_t AlignInBits = Record[8];
>> +      uint64_t OffsetInBits = Record[9];
>> +      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[10]);
>> +      Metadata *Elements = getMDOrNull(Record[11]);
>> +      unsigned RuntimeLang = Record[12];
>> +      Metadata *VTableHolder = getDITypeRefOrNull(Record[13]);
>> +      Metadata *TemplateParams = getMDOrNull(Record[14]);
>> +      auto *Identifier = getMDString(Record[15]);
>> +      DICompositeType *CT = nullptr;
>> +      if (Identifier)
>> +        CT = DICompositeType::buildODRType(
>> +            Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
>> +            SizeInBits, AlignInBits, OffsetInBits, Flags, Elements,
>> RuntimeLang,
>> +            VTableHolder, TemplateParams);
>> +
>> +      // Create a node if we didn't get a lazy ODR type.
>> +      if (!CT)
>> +        CT = GET_OR_DISTINCT(DICompositeType,
>> +                             (Context, Tag, Name, File, Line, Scope,
>> BaseType,
>> +                              SizeInBits, AlignInBits, OffsetInBits,
>> Flags,
>> +                              Elements, RuntimeLang, VTableHolder,
>> +                              TemplateParams, Identifier));
>> +      if (!IsNotUsedInTypeRef && Identifier)
>> +        MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
>> +
>> +      MetadataList.assignValue(CT, NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_SUBROUTINE_TYPE: {
>> +      if (Record.size() < 3 || Record.size() > 4)
>> +        return error("Invalid record");
>> +      bool IsOldTypeRefArray = Record[0] < 2;
>> +      unsigned CC = (Record.size() > 3) ? Record[3] : 0;
>> +
>> +      IsDistinct = Record[0] & 0x1;
>> +      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[1]);
>> +      Metadata *Types = getMDOrNull(Record[2]);
>> +      if (LLVM_UNLIKELY(IsOldTypeRefArray))
>> +        Types = MetadataList.upgradeTypeRefArray(Types);
>> +
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DISubroutineType, (Context, Flags, CC, Types)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +
>> +    case bitc::METADATA_MODULE: {
>> +      if (Record.size() != 6)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIModule,
>> +                          (Context, getMDOrNull(Record[1]),
>> +                           getMDString(Record[2]),
>> getMDString(Record[3]),
>> +                           getMDString(Record[4]),
>> getMDString(Record[5]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +
>> +    case bitc::METADATA_FILE: {
>> +      if (Record.size() != 3)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIFile, (Context, getMDString(Record[1]),
>> +                                   getMDString(Record[2]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_COMPILE_UNIT: {
>> +      if (Record.size() < 14 || Record.size() > 17)
>> +        return error("Invalid record");
>> +
>> +      // Ignore Record[0], which indicates whether this compile unit is
>> +      // distinct.  It's always distinct.
>> +      IsDistinct = true;
>> +      auto *CU = DICompileUnit::getDistinct(
>> +          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[12]), getMDOrNull(Record[13]),
>> +          Record.size() <= 15 ? nullptr : getMDOrNull(Record[15]),
>> +          Record.size() <= 14 ? 0 : Record[14],
>> +          Record.size() <= 16 ? true : Record[16]);
>> +
>> +      MetadataList.assignValue(CU, NextMetadataNo++);
>> +
>> +      // Move the Upgrade the list of subprograms.
>> +      if (Metadata *SPs = getMDOrNullWithoutPlaceholders(Record[11]))
>> +        CUSubprograms.push_back({CU, SPs});
>> +      break;
>> +    }
>> +    case bitc::METADATA_SUBPROGRAM: {
>> +      if (Record.size() < 18 || Record.size() > 20)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct =
>> +          (Record[0] & 1) || Record[8]; // All definitions should be
>> distinct.
>> +      // Version 1 has a Function as Record[15].
>> +      // Version 2 has removed Record[15].
>> +      // Version 3 has the Unit as Record[15].
>> +      // Version 4 added thisAdjustment.
>> +      bool HasUnit = Record[0] >= 2;
>> +      if (HasUnit && Record.size() < 19)
>> +        return error("Invalid record");
>> +      Metadata *CUorFn = getMDOrNull(Record[15]);
>> +      unsigned Offset = Record.size() >= 19 ? 1 : 0;
>> +      bool HasFn = Offset && !HasUnit;
>> +      bool HasThisAdj = Record.size() >= 20;
>> +      DISubprogram *SP = GET_OR_DISTINCT(
>> +          DISubprogram, (Context,
>> +                         getDITypeRefOrNull(Record[1]),  // scope
>> +                         getMDString(Record[2]),         // name
>> +                         getMDString(Record[3]),         // linkageName
>> +                         getMDOrNull(Record[4]),         // file
>> +                         Record[5],                      // line
>> +                         getMDOrNull(Record[6]),         // type
>> +                         Record[7],                      // isLocal
>> +                         Record[8],                      // isDefinition
>> +                         Record[9],                      // scopeLine
>> +                         getDITypeRefOrNull(Record[10]), //
>> containingType
>> +                         Record[11],                     // virtuality
>> +                         Record[12],                     // virtualIndex
>> +                         HasThisAdj ? Record[19] : 0,    //
>> thisAdjustment
>> +                         static_cast<DINode::DIFlags>(Record[13] // flags
>> +                                                      ),
>> +                         Record[14],                       // isOptimized
>> +                         HasUnit ? CUorFn : nullptr,       // unit
>> +                         getMDOrNull(Record[15 + Offset]), //
>> templateParams
>> +                         getMDOrNull(Record[16 + Offset]), // declaration
>> +                         getMDOrNull(Record[17 + Offset])  // variables
>> +                         ));
>> +      MetadataList.assignValue(SP, NextMetadataNo++);
>> +
>> +      // Upgrade sp->function mapping to function->sp mapping.
>> +      if (HasFn) {
>> +        if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(CUorFn))
>> +          if (auto *F = dyn_cast<Function>(CMD->getValue())) {
>> +            if (F->isMaterializable())
>> +              // Defer until materialized; unmaterialized functions may
>> not have
>> +              // metadata.
>> +              FunctionsWithSPs[F] = SP;
>> +            else if (!F->empty())
>> +              F->setSubprogram(SP);
>> +          }
>> +      }
>> +      break;
>> +    }
>> +    case bitc::METADATA_LEXICAL_BLOCK: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DILexicalBlock,
>> +                          (Context, getMDOrNull(Record[1]),
>> +                           getMDOrNull(Record[2]), Record[3],
>> Record[4])),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_LEXICAL_BLOCK_FILE: {
>> +      if (Record.size() != 4)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DILexicalBlockFile,
>> +                          (Context, getMDOrNull(Record[1]),
>> +                           getMDOrNull(Record[2]), Record[3])),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_NAMESPACE: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0] & 1;
>> +      bool ExportSymbols = Record[0] & 2;
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DINamespace,
>> +                          (Context, getMDOrNull(Record[1]),
>> +                           getMDOrNull(Record[2]),
>> getMDString(Record[3]),
>> +                           Record[4], ExportSymbols)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_MACRO: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIMacro,
>> +                          (Context, Record[1], Record[2],
>> +                           getMDString(Record[3]),
>> getMDString(Record[4]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_MACRO_FILE: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIMacroFile,
>> +                          (Context, Record[1], Record[2],
>> +                           getMDOrNull(Record[3]),
>> getMDOrNull(Record[4]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_TEMPLATE_TYPE: {
>> +      if (Record.size() != 3)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
>> +                                               (Context,
>> getMDString(Record[1]),
>> +
>> getDITypeRefOrNull(Record[2]))),
>> +                               NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_TEMPLATE_VALUE: {
>> +      if (Record.size() != 5)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DITemplateValueParameter,
>> +                          (Context, Record[1], getMDString(Record[2]),
>> +                           getDITypeRefOrNull(Record[3]),
>> +                           getMDOrNull(Record[4]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_GLOBAL_VAR: {
>> +      if (Record.size() < 11 || Record.size() > 12)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +
>> +      // Upgrade old metadata, which stored a global variable reference
>> or a
>> +      // ConstantInt here.
>> +      Metadata *Expr = getMDOrNull(Record[9]);
>> +      uint32_t AlignInBits = 0;
>> +      if (Record.size() > 11) {
>> +        if (Record[11] > (uint64_t)std::numeric_limits<uint32_t>::max())
>> +          return error("Alignment value is too large");
>> +        AlignInBits = Record[11];
>> +      }
>> +      GlobalVariable *Attach = nullptr;
>> +      if (auto *CMD = dyn_cast_or_null<ConstantAsMetadata>(Expr)) {
>> +        if (auto *GV = dyn_cast<GlobalVariable>(CMD->getValue())) {
>> +          Attach = GV;
>> +          Expr = nullptr;
>> +        } else if (auto *CI = dyn_cast<ConstantInt>(CMD->getValue())) {
>> +          Expr = DIExpression::get(Context,
>> +                                   {dwarf::DW_OP_constu, CI-
>>> getZExtValue(),
>> +                                    dwarf::DW_OP_stack_value});
>> +        } else {
>> +          Expr = nullptr;
>> +        }
>> +      }
>> +
>> +      DIGlobalVariable *DGV = GET_OR_DISTINCT(
>> +          DIGlobalVariable,
>> +          (Context, getMDOrNull(Record[1]), getMDString(Record[2]),
>> +           getMDString(Record[3]), getMDOrNull(Record[4]), Record[5],
>> +           getDITypeRefOrNull(Record[6]), Record[7], Record[8], Expr,
>> +           getMDOrNull(Record[10]), AlignInBits));
>> +      MetadataList.assignValue(DGV, NextMetadataNo++);
>> +
>> +      if (Attach)
>> +        Attach->addDebugInfo(DGV);
>> +
>> +      break;
>> +    }
>> +    case bitc::METADATA_LOCAL_VAR: {
>> +      // 10th field is for the obseleted 'inlinedAt:' field.
>> +      if (Record.size() < 8 || Record.size() > 10)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0] & 1;
>> +      bool HasAlignment = Record[0] & 2;
>> +      // 2nd field used to be an artificial tag, either
>> DW_TAG_auto_variable or
>> +      // DW_TAG_arg_variable, if we have alignment flag encoded it means,
>> that
>> +      // this is newer version of record which doesn't have artifical
>> tag.
>> +      bool HasTag = !HasAlignment && Record.size() > 8;
>> +      DINode::DIFlags Flags = static_cast<DINode::DIFlags>(Record[7 +
>> HasTag]);
>> +      uint32_t AlignInBits = 0;
>> +      if (HasAlignment) {
>> +        if (Record[8 + HasTag] >
>> (uint64_t)std::numeric_limits<uint32_t>::max())
>> +          return error("Alignment value is too large");
>> +        AlignInBits = Record[8 + HasTag];
>> +      }
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DILocalVariable,
>> +                          (Context, getMDOrNull(Record[1 + HasTag]),
>> +                           getMDString(Record[2 + HasTag]),
>> +                           getMDOrNull(Record[3 + HasTag]), Record[4 +
>> HasTag],
>> +                           getDITypeRefOrNull(Record[5 + HasTag]),
>> +                           Record[6 + HasTag], Flags, AlignInBits)),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_EXPRESSION: {
>> +      if (Record.size() < 1)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0] & 1;
>> +      bool HasOpFragment = Record[0] & 2;
>> +      auto Elts = MutableArrayRef<uint64_t>(Record).slice(1);
>> +      if (!HasOpFragment)
>> +        if (unsigned N = Elts.size())
>> +          if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
>> +            Elts[N - 3] = dwarf::DW_OP_LLVM_fragment;
>> +
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIExpression,
>> +                          (Context, makeArrayRef(Record).slice(1))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_OBJC_PROPERTY: {
>> +      if (Record.size() != 8)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIObjCProperty,
>> +                          (Context, getMDString(Record[1]),
>> +                           getMDOrNull(Record[2]), Record[3],
>> +                           getMDString(Record[4]),
>> getMDString(Record[5]),
>> +                           Record[6], getDITypeRefOrNull(Record[7]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_IMPORTED_ENTITY: {
>> +      if (Record.size() != 6)
>> +        return error("Invalid record");
>> +
>> +      IsDistinct = Record[0];
>> +      MetadataList.assignValue(
>> +          GET_OR_DISTINCT(DIImportedEntity,
>> +                          (Context, Record[1], getMDOrNull(Record[2]),
>> +                           getDITypeRefOrNull(Record[3]), Record[4],
>> +                           getMDString(Record[5]))),
>> +          NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_STRING_OLD: {
>> +      std::string String(Record.begin(), Record.end());
>> +
>> +      // Test for upgrading !llvm.loop.
>> +      HasSeenOldLoopTags |= mayBeOldLoopAttachmentTag(String);
>> +
>> +      Metadata *MD = MDString::get(Context, String);
>> +      MetadataList.assignValue(MD, NextMetadataNo++);
>> +      break;
>> +    }
>> +    case bitc::METADATA_STRINGS:
>> +      if (Error Err = parseMetadataStrings(Record, Blob, NextMetadataNo))
>> +        return Err;
>> +      break;
>> +    case bitc::METADATA_GLOBAL_DECL_ATTACHMENT: {
>> +      if (Record.size() % 2 == 0)
>> +        return error("Invalid record");
>> +      unsigned ValueID = Record[0];
>> +      if (ValueID >= ValueList.size())
>> +        return error("Invalid record");
>> +      if (auto *GO = dyn_cast<GlobalObject>(ValueList[ValueID]))
>> +        if (Error Err = parseGlobalObjectAttachment(
>> +                *GO, ArrayRef<uint64_t>(Record).slice(1)))
>> +          return Err;
>> +      break;
>> +    }
>> +    case bitc::METADATA_KIND: {
>> +      // Support older bitcode files that had METADATA_KIND records in a
>> +      // block with METADATA_BLOCK_ID.
>> +      if (Error Err = parseMetadataKindRecord(Record))
>> +        return Err;
>> +      break;
>> +    }
>> +    }
>> +  }
>> +#undef GET_OR_DISTINCT
>> +}
>> +
>> +Error MetadataLoader::MetadataLoaderImpl::parseMetadataStrings(
>> +    ArrayRef<uint64_t> Record, StringRef Blob, unsigned &NextMetadataNo)
>> {
>> +  // All the MDStrings in the block are emitted together in a single
>> +  // record.  The strings are concatenated and stored in a blob along
>> with
>> +  // their sizes.
>> +  if (Record.size() != 2)
>> +    return error("Invalid record: metadata strings layout");
>> +
>> +  unsigned NumStrings = Record[0];
>> +  unsigned StringsOffset = Record[1];
>> +  if (!NumStrings)
>> +    return error("Invalid record: metadata strings with no strings");
>> +  if (StringsOffset > Blob.size())
>> +    return error("Invalid record: metadata strings corrupt offset");
>> +
>> +  StringRef Lengths = Blob.slice(0, StringsOffset);
>> +  SimpleBitstreamCursor R(Lengths);
>> +
>> +  StringRef Strings = Blob.drop_front(StringsOffset);
>> +  do {
>> +    if (R.AtEndOfStream())
>> +      return error("Invalid record: metadata strings bad length");
>> +
>> +    unsigned Size = R.ReadVBR(6);
>> +    if (Strings.size() < Size)
>> +      return error("Invalid record: metadata strings truncated chars");
>> +
>> +    MetadataList.assignValue(MDString::get(Context, Strings.slice(0,
>> Size)),
>> +                             NextMetadataNo++);
>> +    Strings = Strings.drop_front(Size);
>> +  } while (--NumStrings);
>> +
>> +  return Error::success();
>> +}
>> +
>> +Error MetadataLoader::MetadataLoaderImpl::parseGlobalObjectAttachment(
>> +    GlobalObject &GO, ArrayRef<uint64_t> Record) {
>> +  assert(Record.size() % 2 == 0);
>> +  for (unsigned I = 0, E = Record.size(); I != E; I += 2) {
>> +    auto K = MDKindMap.find(Record[I]);
>> +    if (K == MDKindMap.end())
>> +      return error("Invalid ID");
>> +    MDNode *MD = MetadataList.getMDNodeFwdRefOrNull(Record[I + 1]);
>> +    if (!MD)
>> +      return error("Invalid metadata attachment");
>> +    GO.addMetadata(K->second, *MD);
>> +  }
>> +  return Error::success();
>> +}
>> +
>> +/// Parse metadata attachments.
>> +Error MetadataLoader::MetadataLoaderImpl::parseMetadataAttachment(
>> +    Function &F, const SmallVectorImpl<Instruction *> &InstructionList) {
>> +  if (Stream.EnterSubBlock(bitc::METADATA_ATTACHMENT_ID))
>> +    return error("Invalid record");
>> +
>> +  SmallVector<uint64_t, 64> Record;
>> +
>> +  while (true) {
>> +    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 Error::success();
>> +    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.
>> +        if (Error Err = parseGlobalObjectAttachment(F, Record))
>> +          return Err;
>> +        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 = MetadataList.getMetadataFwdRef(Record[i + 1]);
>> +        if (isa<LocalAsMetadata>(Node))
>> +          // Drop the attachment.  This used to be legal, but there's no
>> +          // upgrade path.
>> +          break;
>> +        MDNode *MD = dyn_cast_or_null<MDNode>(Node);
>> +        if (!MD)
>> +          return error("Invalid metadata attachment");
>> +
>> +        if (HasSeenOldLoopTags && I->second == LLVMContext::MD_loop)
>> +          MD = upgradeInstructionLoopAttachment(*MD);
>> +
>> +        if (I->second == LLVMContext::MD_tbaa) {
>> +          assert(!MD->isTemporary() && "should load MDs before
>> attachments");
>> +          MD = UpgradeTBAANode(*MD);
>> +        }
>> +        Inst->setMetadata(I->second, MD);
>> +      }
>> +      break;
>> +    }
>> +    }
>> +  }
>> +}
>> +
>> +/// Parse a single METADATA_KIND record, inserting result in MDKindMap.
>> +Error MetadataLoader::MetadataLoaderImpl::parseMetadataKindRecord(
>> +    SmallVectorImpl<uint64_t> &Record) {
>> +  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");
>> +  return Error::success();
>> +}
>> +
>> +/// Parse the metadata kinds out of the METADATA_KIND_BLOCK.
>> +Error MetadataLoader::MetadataLoaderImpl::parseMetadataKinds() {
>> +  if (Stream.EnterSubBlock(bitc::METADATA_KIND_BLOCK_ID))
>> +    return error("Invalid record");
>> +
>> +  SmallVector<uint64_t, 64> Record;
>> +
>> +  // Read all the records.
>> +  while (true) {
>> +    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 Error::success();
>> +    case BitstreamEntry::Record:
>> +      // The interesting case.
>> +      break;
>> +    }
>> +
>> +    // Read a record.
>> +    Record.clear();
>> +    unsigned Code = Stream.readRecord(Entry.ID, Record);
>> +    switch (Code) {
>> +    default: // Default behavior: ignore.
>> +      break;
>> +    case bitc::METADATA_KIND: {
>> +      if (Error Err = parseMetadataKindRecord(Record))
>> +        return Err;
>> +      break;
>> +    }
>> +    }
>> +  }
>> +}
>> +
>> +MetadataLoader &MetadataLoader::operator=(MetadataLoader &&RHS) {
>> +  Pimpl = std::move(RHS.Pimpl);
>> +  return *this;
>> +}
>> +MetadataLoader::MetadataLoader(MetadataLoader &&RHS)
>> +    : Pimpl(std::move(RHS.Pimpl)) {}
>> +
>> +MetadataLoader::~MetadataLoader() = default;
>> +MetadataLoader::MetadataLoader(BitstreamCursor &Stream, Module
>> &TheModule,
>> +                               BitcodeReaderValueList &ValueList,
>> +                               std::function<Type *(unsigned)>
>> getTypeByID)
>> +    : Pimpl(make_unique<MetadataLoaderImpl>(Stream, TheModule, ValueList,
>> +                                            getTypeByID)) {}
>> +
>> +Error MetadataLoader::parseMetadata(bool ModuleLevel) {
>> +  return Pimpl->parseMetadata(ModuleLevel);
>> +}
>> +
>> +bool MetadataLoader::hasFwdRefs() const { return Pimpl->hasFwdRefs(); }
>> +
>> +/// Return the given metadata, creating a replaceable forward reference
>> if
>> +/// necessary.
>> +Metadata *MetadataLoader::getMetadataFwdRef(unsigned Idx) {
>> +  return Pimpl->getMetadataFwdRef(Idx);
>> +}
>> +
>> +MDNode *MetadataLoader::getMDNodeFwdRefOrNull(unsigned Idx) {
>> +  return Pimpl->getMDNodeFwdRefOrNull(Idx);
>> +}
>> +
>> +DISubprogram *MetadataLoader::lookupSubprogramForFunction(Function *F) {
>> +  return Pimpl->lookupSubprogramForFunction(F);
>> +}
>> +
>> +Error MetadataLoader::parseMetadataAttachment(
>> +    Function &F, const SmallVectorImpl<Instruction *> &InstructionList) {
>> +  return Pimpl->parseMetadataAttachment(F, InstructionList);
>> +}
>> +
>> +Error MetadataLoader::parseMetadataKinds() {
>> +  return Pimpl->parseMetadataKinds();
>> +}
>> +
>> +unsigned MetadataLoader::size() const { return Pimpl->size(); }
>> +void MetadataLoader::shrinkTo(unsigned N) { return Pimpl->shrinkTo(N); }
>> 
>> Added: llvm/trunk/lib/Bitcode/Reader/MetadataLoader.h
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/MetadataLoader.h?rev=289461&view=aut
>> o
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/MetadataLoader.h (added)
>> +++ llvm/trunk/lib/Bitcode/Reader/MetadataLoader.h Mon Dec 12 13:34:26
>> 2016
>> @@ -0,0 +1,79 @@
>> +//===-- Bitcode/Reader/MetadataLoader.h - Load Metadatas -------*- C++ -
>> *-====//
>> +//
>> +//                     The LLVM Compiler Infrastructure
>> +//
>> +// This file is distributed under the University of Illinois Open Source
>> +// License. See LICENSE.TXT for details.
>> +//
>> +//===--------------------------------------------------------------------
>> --===//
>> +//
>> +// This class handles loading Metadatas.
>> +//
>> +//===--------------------------------------------------------------------
>> --===//
>> +
>> +#ifndef LLVM_LIB_BITCODE_READER_METADATALOADER_H
>> +#define LLVM_LIB_BITCODE_READER_METADATALOADER_H
>> +
>> +#include "llvm/ADT/SmallVector.h"
>> +#include "llvm/Support/Error.h"
>> +
>> +#include <functional>
>> +#include <memory>
>> +
>> +namespace llvm {
>> +class BitcodeReaderValueList;
>> +class BitstreamCursor;
>> +class DISubprogram;
>> +class Error;
>> +class Function;
>> +class Instruction;
>> +class Metadata;
>> +class MDNode;
>> +class Module;
>> +class Type;
>> +
>> +/// Helper class that handles loading Metadatas and keeping them
>> available.
>> +class MetadataLoader {
>> +  class MetadataLoaderImpl;
>> +  std::unique_ptr<MetadataLoaderImpl> Pimpl;
>> +  Error parseMetadata(bool ModuleLevel);
>> +
>> +public:
>> +  ~MetadataLoader();
>> +  MetadataLoader(BitstreamCursor &Stream, Module &TheModule,
>> +                 BitcodeReaderValueList &ValueList,
>> +                 std::function<Type *(unsigned)> getTypeByID);
>> +  MetadataLoader &operator=(MetadataLoader &&);
>> +  MetadataLoader(MetadataLoader &&);
>> +
>> +  // Parse a module metadata block
>> +  Error parseModuleMetadata() { return parseMetadata(true); }
>> +
>> +  // Parse a function metadata block
>> +  Error parseFunctionMetadata() { return parseMetadata(false); }
>> +
>> +  // Return true there are remaining unresolved forward references.
>> +  bool hasFwdRefs() const;
>> +
>> +  /// Return the given metadata, creating a replaceable forward reference
>> if
>> +  /// necessary.
>> +  Metadata *getMetadataFwdRef(unsigned Idx);
>> +
>> +  MDNode *getMDNodeFwdRefOrNull(unsigned Idx);
>> +
>> +  /// Return the DISubprogra metadata for a Function if any, null
>> otherwise.
>> +  DISubprogram *lookupSubprogramForFunction(Function *F);
>> +
>> +  /// Parse a `METADATA_ATTACHMENT` block for a function.
>> +  Error parseMetadataAttachment(
>> +      Function &F, const SmallVectorImpl<Instruction *>
>> &InstructionList);
>> +
>> +  /// Parse a `METADATA_KIND` block for the current module.
>> +  Error parseMetadataKinds();
>> +
>> +  unsigned size() const;
>> +  void shrinkTo(unsigned N);
>> +};
>> +}
>> +
>> +#endif // LLVM_LIB_BITCODE_READER_METADATALOADER_H
>> 
>> Added: llvm/trunk/lib/Bitcode/Reader/ValueList.cpp
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/ValueList.cpp?rev=289461&view=auto
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/ValueList.cpp (added)
>> +++ llvm/trunk/lib/Bitcode/Reader/ValueList.cpp Mon Dec 12 13:34:26 2016
>> @@ -0,0 +1,199 @@
>> +//===----- ValueList.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 "ValueList.h"
>> +#include "llvm/IR/Constants.h"
>> +#include "llvm/IR/Instructions.h"
>> +
>> +using namespace llvm;
>> +
>> +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);
>> +};
>> +
>> +} // end anonymous namespace
>> +
>> +// FIXME: can we inherit this from ConstantExpr?
>> +template <>
>> +struct OperandTraits<ConstantPlaceHolder>
>> +    : public FixedNumOperandTraits<ConstantPlaceHolder, 1> {};
>> +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
>> +
>> +} // end 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 == std::numeric_limits<unsigned>::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;
>> +  }
>> +}
>> 
>> Added: llvm/trunk/lib/Bitcode/Reader/ValueList.h
>> URL: http://llvm.org/viewvc/llvm-
>> project/llvm/trunk/lib/Bitcode/Reader/ValueList.h?rev=289461&view=auto
>> ==========================================================================
>> ====
>> --- llvm/trunk/lib/Bitcode/Reader/ValueList.h (added)
>> +++ llvm/trunk/lib/Bitcode/Reader/ValueList.h Mon Dec 12 13:34:26 2016
>> @@ -0,0 +1,76 @@
>> +//===-- Bitcode/Reader/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.
>> +//
>> +//===--------------------------------------------------------------------
>> --===//
>> +
>> +#include "llvm/IR/LLVMContext.h"
>> +#include "llvm/IR/ValueHandle.h"
>> +
>> +#include <vector>
>> +
>> +namespace llvm {
>> +class Constant;
>> +
>> +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();
>> +};
>> +
>> +} // namespace llvm
>> 
>> 
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits



More information about the llvm-commits mailing list