[llvm] r266510 - Reapply "ValueMapper: Eliminate cross-file co-recursion, NFC"

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 15 19:29:56 PDT 2016


Author: dexonsmith
Date: Fri Apr 15 21:29:55 2016
New Revision: 266510

URL: http://llvm.org/viewvc/llvm-project?rev=266510&view=rev
Log:
Reapply "ValueMapper: Eliminate cross-file co-recursion, NFC"

This reverts commit r266507, reapplying r266503 (and r266505
"ValueMapper: Use API from r266503 in unit tests, NFC") completely
unchanged.

I reverted because of a bot failure here:
  http://lab.llvm.org:8011/builders/lld-x86_64-freebsd/builds/16810/

However, looking more closely, the failure was from a host-compiler
crash (clang 3.7.1) when building:
  lib/CodeGen/AsmPrinter/CMakeFiles/LLVMAsmPrinter.dir/DwarfAccelTable.cpp.o

I didn't modify that file, or anything it includes, with that commit.

The next build (which hadn't picked up my revert) got past it:
  http://lab.llvm.org:8011/builders/lld-x86_64-freebsd/builds/16811/

I think this was just unfortunate timing.  I suppose the bot must be
flakey.

Modified:
    llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h
    llvm/trunk/lib/Linker/IRMover.cpp
    llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
    llvm/trunk/unittests/Transforms/Utils/ValueMapperTest.cpp

Modified: llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h?rev=266510&r1=266509&r2=266510&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/ValueMapper.h Fri Apr 15 21:29:55 2016
@@ -98,6 +98,92 @@ static inline RemapFlags operator|(Remap
   return RemapFlags(unsigned(LHS) | unsigned(RHS));
 }
 
+class ValueMapperImpl;
+
+/// Context for (re-)mapping values (and metadata).
+///
+/// A shared context used for mapping and remapping of Value and Metadata
+/// instances using \a ValueToValueMapTy, \a RemapFlags, \a
+/// ValueMapTypeRemapper, and \a ValueMaterializer.
+///
+/// There are a number of top-level entry points:
+/// - \a mapValue() (and \a mapConstant());
+/// - \a mapMetadata() (and \a mapMDNode());
+/// - \a remapInstruction(); and
+/// - \a remapFunction().
+///
+/// The \a ValueMaterializer can be used as a callback, but cannot invoke any
+/// of these top-level functions recursively.  Instead, callbacks should use
+/// one of the following to schedule work lazily in the \a ValueMapper
+/// instance:
+/// - \a scheduleMapGlobalInitializer()
+/// - \a scheduleMapAppendingVariable()
+/// - \a scheduleMapGlobalAliasee()
+/// - \a scheduleRemapFunction()
+///
+/// Sometimes a callback needs a diferent mapping context.  Such a context can
+/// be registered using \a registerAlternateMappingContext(), which takes an
+/// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
+/// pass into the schedule*() functions.
+///
+/// TODO: lib/Linker really doesn't need the \a ValueHandle in the \a
+/// ValueToValueMapTy.  We should template \a ValueMapper (and its
+/// implementation classes), and explicitly instantiate on two concrete
+/// instances of \a ValueMap (one as \a ValueToValueMap, and one with raw \a
+/// Value pointers).  It may be viable to do away with \a TrackingMDRef in the
+/// \a Metadata side map for the lib/Linker case as well, in which case we'll
+/// need a new template parameter on \a ValueMap.
+///
+/// TODO: Update callers of \a RemapInstruction() and \a MapValue() (etc.) to
+/// use \a ValueMapper directly.
+class ValueMapper {
+  void *pImpl;
+
+  ValueMapper(ValueMapper &&) = delete;
+  ValueMapper(const ValueMapper &) = delete;
+  ValueMapper &operator=(ValueMapper &&) = delete;
+  ValueMapper &operator=(const ValueMapper &) = delete;
+
+public:
+  ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
+              ValueMapTypeRemapper *TypeMapper = nullptr,
+              ValueMaterializer *Materializer = nullptr);
+  ~ValueMapper();
+
+  /// Register an alternate mapping context.
+  ///
+  /// Returns a MappingContextID that can be used with the various schedule*()
+  /// API to switch in a different value map on-the-fly.
+  unsigned
+  registerAlternateMappingContext(ValueToValueMapTy &VM,
+                                  ValueMaterializer *Materializer = nullptr);
+
+  /// Add to the current \a RemapFlags.
+  ///
+  /// \note Like the top-level mapping functions, \a addFlags() must be called
+  /// at the top level, not during a callback in a \a ValueMaterializer.
+  void addFlags(RemapFlags Flags);
+
+  Metadata *mapMetadata(const Metadata &MD);
+  MDNode *mapMDNode(const MDNode &N);
+
+  Value *mapValue(const Value &V);
+  Constant *mapConstant(const Constant &C);
+
+  void remapInstruction(Instruction &I);
+  void remapFunction(Function &F);
+
+  void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
+                                    unsigned MappingContextID = 0);
+  void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
+                                    bool IsOldCtorDtor,
+                                    ArrayRef<Constant *> NewMembers,
+                                    unsigned MappingContextID = 0);
+  void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
+                                unsigned MappingContextID = 0);
+  void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
+};
+
 /// Look up or compute a value in the value map.
 ///
 /// Return a mapped value for a function-local value (Argument, Instruction,
@@ -115,10 +201,12 @@ static inline RemapFlags operator|(Remap
 ///  6. Else if \c V is a \a MetadataAsValue, rewrap the return of \a
 ///     MapMetadata().
 ///  7. Else, compute the equivalent constant, and return it.
-Value *MapValue(const Value *V, ValueToValueMapTy &VM,
-                RemapFlags Flags = RF_None,
-                ValueMapTypeRemapper *TypeMapper = nullptr,
-                ValueMaterializer *Materializer = nullptr);
+inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
+                       RemapFlags Flags = RF_None,
+                       ValueMapTypeRemapper *TypeMapper = nullptr,
+                       ValueMaterializer *Materializer = nullptr) {
+  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapValue(*V);
+}
 
 /// Lookup or compute a mapping for a piece of metadata.
 ///
@@ -135,16 +223,20 @@ Value *MapValue(const Value *V, ValueToV
 ///
 /// \note \a LocalAsMetadata is completely unsupported by \a MapMetadata.
 /// Instead, use \a MapValue() with its wrapping \a MetadataAsValue instance.
-Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
-                      RemapFlags Flags = RF_None,
-                      ValueMapTypeRemapper *TypeMapper = nullptr,
-                      ValueMaterializer *Materializer = nullptr);
+inline Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
+                             RemapFlags Flags = RF_None,
+                             ValueMapTypeRemapper *TypeMapper = nullptr,
+                             ValueMaterializer *Materializer = nullptr) {
+  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMetadata(*MD);
+}
 
 /// Version of MapMetadata with type safety for MDNode.
-MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
-                    RemapFlags Flags = RF_None,
-                    ValueMapTypeRemapper *TypeMapper = nullptr,
-                    ValueMaterializer *Materializer = nullptr);
+inline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
+                           RemapFlags Flags = RF_None,
+                           ValueMapTypeRemapper *TypeMapper = nullptr,
+                           ValueMaterializer *Materializer = nullptr) {
+  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMDNode(*MD);
+}
 
 /// Convert the instruction operands from referencing the current values into
 /// those specified by VM.
@@ -154,10 +246,12 @@ MDNode *MapMetadata(const MDNode *MD, Va
 ///
 /// Note that \a MapValue() only returns \c nullptr for SSA values missing from
 /// \c VM.
-void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
-                      RemapFlags Flags = RF_None,
-                      ValueMapTypeRemapper *TypeMapper = nullptr,
-                      ValueMaterializer *Materializer = nullptr);
+inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
+                             RemapFlags Flags = RF_None,
+                             ValueMapTypeRemapper *TypeMapper = nullptr,
+                             ValueMaterializer *Materializer = nullptr) {
+  ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I);
+}
 
 /// Remap the operands, metadata, arguments, and instructions of a function.
 ///
@@ -165,19 +259,19 @@ void RemapInstruction(Instruction *I, Va
 /// function; calls \a MapMetadata() on each attached MDNode; remaps the
 /// argument types using the provided \c TypeMapper; and calls \a
 /// RemapInstruction() on every instruction.
-void RemapFunction(Function &F, ValueToValueMapTy &VM,
-                   RemapFlags Flags = RF_None,
-                   ValueMapTypeRemapper *TypeMapper = nullptr,
-                   ValueMaterializer *Materializer = nullptr);
+inline void RemapFunction(Function &F, ValueToValueMapTy &VM,
+                          RemapFlags Flags = RF_None,
+                          ValueMapTypeRemapper *TypeMapper = nullptr,
+                          ValueMaterializer *Materializer = nullptr) {
+  ValueMapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
+}
 
 /// Version of MapValue with type safety for Constant.
 inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
                           RemapFlags Flags = RF_None,
                           ValueMapTypeRemapper *TypeMapper = nullptr,
                           ValueMaterializer *Materializer = nullptr) {
-  // This can be null for RF_NullMapMissingGlobalValues.
-  return cast_or_null<Constant>(
-      MapValue((const Value *)V, VM, Flags, TypeMapper, Materializer));
+  return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
 }
 
 } // End llvm namespace

Modified: llvm/trunk/lib/Linker/IRMover.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Linker/IRMover.cpp?rev=266510&r1=266509&r2=266510&view=diff
==============================================================================
--- llvm/trunk/lib/Linker/IRMover.cpp (original)
+++ llvm/trunk/lib/Linker/IRMover.cpp Fri Apr 15 21:29:55 2016
@@ -397,8 +397,9 @@ class IRLinker {
 
   bool HasError = false;
 
-  /// Flags to pass to value mapper invocations.
-  RemapFlags ValueMapperFlags = RF_MoveDistinctMDs | RF_IgnoreMissingLocals;
+  /// Entry point for mapping values and alternate context for mapping aliases.
+  ValueMapper Mapper;
+  unsigned AliasMCID;
 
   /// Handles cloning of a global values from the source module into
   /// the destination module, including setting the attributes and visibility.
@@ -470,7 +471,11 @@ public:
            std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink,
            std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor)
       : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(AddLazyFor), TypeMap(Set),
-        GValMaterializer(*this), LValMaterializer(*this) {
+        GValMaterializer(*this), LValMaterializer(*this),
+        Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
+               &GValMaterializer),
+        AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
+                                                         &LValMaterializer)) {
     for (GlobalValue *GV : ValuesToLink)
       maybeAdd(GV);
   }
@@ -712,6 +717,10 @@ Constant *IRLinker::linkAppendingVarProt
   Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
                     ->getElementType();
 
+  // FIXME: This upgrade is done during linking to support the C API.  Once the
+  // old form is deprecated, we should move this upgrade to
+  // llvm::UpgradeGlobalVariable() and simplify the logic here and in
+  // Mapper::mapAppendingVariable() in ValueMapper.cpp.
   StringRef Name = SrcGV->getName();
   bool IsNewStructor = false;
   bool IsOldStructor = false;
@@ -729,8 +738,10 @@ Constant *IRLinker::linkAppendingVarProt
     EltTy = StructType::get(SrcGV->getContext(), Tys, false);
   }
 
+  uint64_t DstNumElements = 0;
   if (DstGV) {
     ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
+    DstNumElements = DstTy->getNumElements();
 
     if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
       emitError(
@@ -774,10 +785,6 @@ Constant *IRLinker::linkAppendingVarProt
     }
   }
 
-  SmallVector<Constant *, 16> DstElements;
-  if (DstGV)
-    getArrayElements(DstGV->getInitializer(), DstElements);
-
   SmallVector<Constant *, 16> SrcElements;
   getArrayElements(SrcGV->getInitializer(), SrcElements);
 
@@ -793,7 +800,7 @@ Constant *IRLinker::linkAppendingVarProt
                          return !shouldLink(DGV, *Key);
                        }),
         SrcElements.end());
-  uint64_t NewSize = DstElements.size() + SrcElements.size();
+  uint64_t NewSize = DstNumElements + SrcElements.size();
   ArrayType *NewType = ArrayType::get(EltTy, NewSize);
 
   // Create the new global variable.
@@ -810,25 +817,9 @@ Constant *IRLinker::linkAppendingVarProt
   // Stop recursion.
   ValueMap[SrcGV] = Ret;
 
-  for (auto *V : SrcElements) {
-    Constant *NewV;
-    if (IsOldStructor) {
-      auto *S = cast<ConstantStruct>(V);
-      auto *E1 = MapValue(S->getOperand(0), ValueMap, ValueMapperFlags,
-                          &TypeMap, &GValMaterializer);
-      auto *E2 = MapValue(S->getOperand(1), ValueMap, ValueMapperFlags,
-                          &TypeMap, &GValMaterializer);
-      Value *Null = Constant::getNullValue(VoidPtrTy);
-      NewV =
-          ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr);
-    } else {
-      NewV =
-          MapValue(V, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
-    }
-    DstElements.push_back(NewV);
-  }
-
-  NG->setInitializer(ConstantArray::get(NewType, DstElements));
+  Mapper.scheduleMapAppendingVariable(*NG,
+                                      DstGV ? DstGV->getInitializer() : nullptr,
+                                      IsOldStructor, SrcElements);
 
   // Replace any uses of the two global variables with uses of the new
   // global.
@@ -935,8 +926,7 @@ Constant *IRLinker::linkGlobalValueProto
 /// referenced are in Dest.
 void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
   // Figure out what the initializer looks like in the dest module.
-  Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, ValueMapperFlags,
-                              &TypeMap, &GValMaterializer));
+  Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer());
 }
 
 /// Copy the source function over into the dest function and fix up references
@@ -968,15 +958,12 @@ bool IRLinker::linkFunctionBody(Function
   Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList());
 
   // Everything has been moved over.  Remap it.
-  RemapFunction(Dst, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
+  Mapper.scheduleRemapFunction(Dst);
   return false;
 }
 
 void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
-  Constant *Aliasee = Src.getAliasee();
-  Constant *Val = MapValue(Aliasee, AliasValueMap, ValueMapperFlags, &TypeMap,
-                           &LValMaterializer);
-  Dst.setAliasee(Val);
+  Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID);
 }
 
 bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
@@ -1000,9 +987,7 @@ void IRLinker::linkNamedMDNodes() {
     NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
     // Add Src elements into Dest node.
     for (const MDNode *Op : NMD.operands())
-      DestNMD->addOperand(MapMetadata(
-          Op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues,
-          &TypeMap, &GValMaterializer));
+      DestNMD->addOperand(Mapper.mapMDNode(*Op));
   }
 }
 
@@ -1242,7 +1227,7 @@ bool IRLinker::run() {
       continue;
 
     assert(!GV->isDeclaration());
-    MapValue(GV, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
+    Mapper.mapValue(*GV);
     if (HasError)
       return true;
   }
@@ -1250,6 +1235,7 @@ bool IRLinker::run() {
   // Note that we are done linking global value bodies. This prevents
   // metadata linking from creating new references.
   DoneLinkingBodies = true;
+  Mapper.addFlags(RF_NullMapMissingGlobalValues);
 
   // Remap all of the named MDNodes in Src into the DstM module. We do this
   // after linking GlobalValues so that MDNodes that reference GlobalValues

Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=266510&r1=266509&r2=266510&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Fri Apr 15 21:29:55 2016
@@ -16,6 +16,8 @@
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalAlias.h"
+#include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/Instructions.h"
 #include "llvm/IR/Metadata.h"
@@ -30,14 +32,6 @@ void ValueMaterializer::materializeInitF
 
 namespace {
 
-/// A GlobalValue whose initializer needs to be materialized.
-struct DelayedGlobalValueInit {
-  GlobalValue *Old;
-  GlobalValue *New;
-  DelayedGlobalValueInit(const GlobalValue *Old, GlobalValue *New)
-      : Old(const_cast<GlobalValue *>(Old)), New(New) {}
-};
-
 /// A basic block used in a BlockAddress whose function body is not yet
 /// materialized.
 struct DelayedBasicBlock {
@@ -58,30 +52,88 @@ struct DelayedBasicBlock {
         TempBB(BasicBlock::Create(Old.getContext())) {}
 };
 
+struct WorklistEntry {
+  enum EntryKind {
+    MapGlobalInit,
+    MapAppendingVar,
+    MapGlobalAliasee,
+    RemapFunction
+  };
+  struct GVInitTy {
+    GlobalVariable *GV;
+    Constant *Init;
+  };
+  struct AppendingGVTy {
+    GlobalVariable *GV;
+    Constant *InitPrefix;
+  };
+  struct GlobalAliaseeTy {
+    GlobalAlias *GA;
+    Constant *Aliasee;
+  };
+
+  unsigned Kind : 2;
+  unsigned MCID : 29;
+  unsigned AppendingGVIsOldCtorDtor : 1;
+  unsigned AppendingGVNumNewMembers;
+  union {
+    GVInitTy GVInit;
+    AppendingGVTy AppendingGV;
+    GlobalAliaseeTy GlobalAliasee;
+    Function *RemapF;
+  } Data;
+};
+
+struct MappingContext {
+  ValueToValueMapTy *VM;
+  ValueMaterializer *Materializer = nullptr;
+
+  /// Construct a MappingContext with a value map and materializer.
+  explicit MappingContext(ValueToValueMapTy &VM,
+                          ValueMaterializer *Materializer = nullptr)
+      : VM(&VM), Materializer(Materializer) {}
+};
+
 class MDNodeMapper;
 class Mapper {
   friend class MDNodeMapper;
 
-  ValueToValueMapTy *VM;
   RemapFlags Flags;
   ValueMapTypeRemapper *TypeMapper;
-  ValueMaterializer *Materializer;
-
-  SmallVector<DelayedGlobalValueInit, 8> DelayedInits;
+  unsigned CurrentMCID = 0;
+  SmallVector<MappingContext, 2> MCs;
+  SmallVector<WorklistEntry, 4> Worklist;
   SmallVector<DelayedBasicBlock, 1> DelayedBBs;
+  SmallVector<Constant *, 16> AppendingInits;
 
 public:
   Mapper(ValueToValueMapTy &VM, RemapFlags Flags,
          ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer)
-      : VM(&VM), Flags(Flags), TypeMapper(TypeMapper),
-        Materializer(Materializer) {}
+      : Flags(Flags), TypeMapper(TypeMapper),
+        MCs(1, MappingContext(VM, Materializer)) {}
+
+  /// ValueMapper should explicitly call \a flush() before destruction.
+  ~Mapper() { assert(!hasWorkToDo() && "Expected to be flushed"); }
+
+  bool hasWorkToDo() const { return !Worklist.empty(); }
+
+  unsigned
+  registerAlternateMappingContext(ValueToValueMapTy &VM,
+                                  ValueMaterializer *Materializer = nullptr) {
+    MCs.push_back(MappingContext(VM, Materializer));
+    return MCs.size() - 1;
+  }
 
-  ~Mapper();
+  void addFlags(RemapFlags Flags);
 
   Value *mapValue(const Value *V);
   void remapInstruction(Instruction *I);
   void remapFunction(Function &F);
 
+  Constant *mapConstant(const Constant *C) {
+    return cast_or_null<Constant>(mapValue(C));
+  }
+
   /// Map metadata.
   ///
   /// Find the mapping for MD.  Guarantees that the return will be resolved
@@ -102,8 +154,28 @@ public:
   // through metadata operands, always return nullptr on unmapped locals.
   Metadata *mapLocalAsMetadata(const LocalAsMetadata &LAM);
 
+  void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
+                                    unsigned MCID);
+  void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
+                                    bool IsOldCtorDtor,
+                                    ArrayRef<Constant *> NewMembers,
+                                    unsigned MCID);
+  void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
+                                unsigned MCID);
+  void scheduleRemapFunction(Function &F, unsigned MCID);
+
+  void flush();
+
 private:
-  ValueToValueMapTy &getVM() { return *VM; }
+  void mapGlobalInitializer(GlobalVariable &GV, Constant &Init);
+  void mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
+                            bool IsOldCtorDtor,
+                            ArrayRef<Constant *> NewMembers);
+  void mapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee);
+  void remapFunction(Function &F, ValueToValueMapTy &VM);
+
+  ValueToValueMapTy &getVM() { return *MCs[CurrentMCID].VM; }
+  ValueMaterializer *getMaterializer() { return MCs[CurrentMCID].Materializer; }
 
   Value *mapBlockAddress(const BlockAddress &BA);
 
@@ -264,12 +336,6 @@ private:
 
 } // end namespace
 
-Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
-                      ValueMapTypeRemapper *TypeMapper,
-                      ValueMaterializer *Materializer) {
-  return Mapper(VM, Flags, TypeMapper, Materializer).mapValue(V);
-}
-
 Value *Mapper::mapValue(const Value *V) {
   ValueToValueMapTy::iterator I = getVM().find(V);
 
@@ -278,13 +344,13 @@ Value *Mapper::mapValue(const Value *V)
     return I->second;
 
   // If we have a materializer and it can materialize a value, use that.
-  if (Materializer) {
+  if (auto *Materializer = getMaterializer()) {
     if (Value *NewV =
             Materializer->materializeDeclFor(const_cast<Value *>(V))) {
       getVM()[V] = NewV;
       if (auto *NewGV = dyn_cast<GlobalValue>(NewV))
-        DelayedInits.push_back(
-            DelayedGlobalValueInit(cast<GlobalValue>(V), NewGV));
+        Materializer->materializeInitFor(
+            NewGV, cast<GlobalValue>(const_cast<Value *>(V)));
       return NewV;
     }
   }
@@ -684,12 +750,6 @@ Optional<Metadata *> Mapper::mapSimpleMe
   return None;
 }
 
-Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
-                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
-                            ValueMaterializer *Materializer) {
-  return Mapper(VM, Flags, TypeMapper, Materializer).mapMetadata(MD);
-}
-
 Metadata *Mapper::mapLocalAsMetadata(const LocalAsMetadata &LAM) {
   // Lookup the mapping for the value itself, and return the appropriate
   // metadata.
@@ -716,36 +776,42 @@ Metadata *Mapper::mapMetadata(const Meta
   return MDNodeMapper(*this).map(*cast<MDNode>(MD));
 }
 
-Mapper::~Mapper() {
-  // Materialize global initializers.
-  while (!DelayedInits.empty()) {
-    auto Init = DelayedInits.pop_back_val();
-    Materializer->materializeInitFor(Init.New, Init.Old);
+void Mapper::flush() {
+  // Flush out the worklist of global values.
+  while (!Worklist.empty()) {
+    WorklistEntry E = Worklist.pop_back_val();
+    CurrentMCID = E.MCID;
+    switch (E.Kind) {
+    case WorklistEntry::MapGlobalInit:
+      E.Data.GVInit.GV->setInitializer(mapConstant(E.Data.GVInit.Init));
+      break;
+    case WorklistEntry::MapAppendingVar: {
+      unsigned PrefixSize = AppendingInits.size() - E.AppendingGVNumNewMembers;
+      mapAppendingVariable(*E.Data.AppendingGV.GV,
+                           E.Data.AppendingGV.InitPrefix,
+                           E.AppendingGVIsOldCtorDtor,
+                           makeArrayRef(AppendingInits).slice(PrefixSize));
+      AppendingInits.resize(PrefixSize);
+      break;
+    }
+    case WorklistEntry::MapGlobalAliasee:
+      E.Data.GlobalAliasee.GA->setAliasee(
+          mapConstant(E.Data.GlobalAliasee.Aliasee));
+      break;
+    case WorklistEntry::RemapFunction:
+      remapFunction(*E.Data.RemapF);
+      break;
+    }
   }
+  CurrentMCID = 0;
 
-  // Process block addresses delayed until global inits.
+  // Finish logic for block addresses now that all global values have been
+  // handled.
   while (!DelayedBBs.empty()) {
     DelayedBasicBlock DBB = DelayedBBs.pop_back_val();
     BasicBlock *BB = cast_or_null<BasicBlock>(mapValue(DBB.OldBB));
     DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
   }
-
-  // We don't expect these to grow after clearing.
-  assert(DelayedInits.empty());
-  assert(DelayedBBs.empty());
-}
-
-MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
-                          RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
-                          ValueMaterializer *Materializer) {
-  return cast_or_null<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM,
-                                          Flags, TypeMapper, Materializer));
-}
-
-void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
-                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
-                            ValueMaterializer *Materializer) {
-  Mapper(VM, Flags, TypeMapper, Materializer).remapInstruction(I);
 }
 
 void Mapper::remapInstruction(Instruction *I) {
@@ -782,7 +848,7 @@ void Mapper::remapInstruction(Instructio
     if (New != Old)
       I->setMetadata(MI.first, New);
   }
-  
+
   if (!TypeMapper)
     return;
 
@@ -808,12 +874,6 @@ void Mapper::remapInstruction(Instructio
   I->mutateType(TypeMapper->remapType(I->getType()));
 }
 
-void llvm::RemapFunction(Function &F, ValueToValueMapTy &VM, RemapFlags Flags,
-                         ValueMapTypeRemapper *TypeMapper,
-                         ValueMaterializer *Materializer) {
-  Mapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
-}
-
 void Mapper::remapFunction(Function &F) {
   // Remap the operands.
   for (Use &Op : F.operands())
@@ -836,3 +896,185 @@ void Mapper::remapFunction(Function &F)
     for (Instruction &I : BB)
       remapInstruction(&I);
 }
+
+void Mapper::mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
+                                  bool IsOldCtorDtor,
+                                  ArrayRef<Constant *> NewMembers) {
+  SmallVector<Constant *, 16> Elements;
+  if (InitPrefix) {
+    unsigned NumElements =
+        cast<ArrayType>(InitPrefix->getType())->getNumElements();
+    for (unsigned I = 0; I != NumElements; ++I)
+      Elements.push_back(InitPrefix->getAggregateElement(I));
+  }
+
+  PointerType *VoidPtrTy;
+  Type *EltTy;
+  if (IsOldCtorDtor) {
+    // FIXME: This upgrade is done during linking to support the C API.  See
+    // also IRLinker::linkAppendingVarProto() in IRMover.cpp.
+    VoidPtrTy = Type::getInt8Ty(GV.getContext())->getPointerTo();
+    auto &ST = *cast<StructType>(NewMembers.front()->getType());
+    Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
+    EltTy = StructType::get(GV.getContext(), Tys, false);
+  }
+
+  for (auto *V : NewMembers) {
+    Constant *NewV;
+    if (IsOldCtorDtor) {
+      auto *S = cast<ConstantStruct>(V);
+      auto *E1 = mapValue(S->getOperand(0));
+      auto *E2 = mapValue(S->getOperand(1));
+      Value *Null = Constant::getNullValue(VoidPtrTy);
+      NewV =
+          ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr);
+    } else {
+      NewV = cast_or_null<Constant>(mapValue(V));
+    }
+    Elements.push_back(NewV);
+  }
+
+  GV.setInitializer(ConstantArray::get(
+      cast<ArrayType>(GV.getType()->getElementType()), Elements));
+}
+
+void Mapper::scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
+                                          unsigned MCID) {
+  assert(MCID < MCs.size() && "Invalid mapping context");
+
+  WorklistEntry WE;
+  WE.Kind = WorklistEntry::MapGlobalInit;
+  WE.MCID = MCID;
+  WE.Data.GVInit.GV = &GV;
+  WE.Data.GVInit.Init = &Init;
+  Worklist.push_back(WE);
+}
+
+void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
+                                          Constant *InitPrefix,
+                                          bool IsOldCtorDtor,
+                                          ArrayRef<Constant *> NewMembers,
+                                          unsigned MCID) {
+  assert(MCID < MCs.size() && "Invalid mapping context");
+
+  WorklistEntry WE;
+  WE.Kind = WorklistEntry::MapAppendingVar;
+  WE.MCID = MCID;
+  WE.Data.AppendingGV.GV = &GV;
+  WE.Data.AppendingGV.InitPrefix = InitPrefix;
+  WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
+  WE.AppendingGVNumNewMembers = NewMembers.size();
+  Worklist.push_back(WE);
+  AppendingInits.append(NewMembers.begin(), NewMembers.end());
+}
+
+void Mapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
+                                      unsigned MCID) {
+  assert(MCID < MCs.size() && "Invalid mapping context");
+
+  WorklistEntry WE;
+  WE.Kind = WorklistEntry::MapGlobalAliasee;
+  WE.MCID = MCID;
+  WE.Data.GlobalAliasee.GA = &GA;
+  WE.Data.GlobalAliasee.Aliasee = &Aliasee;
+  Worklist.push_back(WE);
+}
+
+void Mapper::scheduleRemapFunction(Function &F, unsigned MCID) {
+  assert(MCID < MCs.size() && "Invalid mapping context");
+
+  WorklistEntry WE;
+  WE.Kind = WorklistEntry::RemapFunction;
+  WE.MCID = MCID;
+  WE.Data.RemapF = &F;
+  Worklist.push_back(WE);
+}
+
+void Mapper::addFlags(RemapFlags Flags) {
+  assert(!hasWorkToDo() && "Expected to have flushed the worklist");
+  this->Flags = this->Flags | Flags;
+}
+
+static Mapper *getAsMapper(void *pImpl) {
+  return reinterpret_cast<Mapper *>(pImpl);
+}
+
+namespace {
+
+class FlushingMapper {
+  Mapper &M;
+
+public:
+  explicit FlushingMapper(void *pImpl) : M(*getAsMapper(pImpl)) {
+    assert(!M.hasWorkToDo() && "Expected to be flushed");
+  }
+  ~FlushingMapper() { M.flush(); }
+  Mapper *operator->() const { return &M; }
+};
+
+} // end namespace
+
+ValueMapper::ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags,
+                         ValueMapTypeRemapper *TypeMapper,
+                         ValueMaterializer *Materializer)
+    : pImpl(new Mapper(VM, Flags, TypeMapper, Materializer)) {}
+
+ValueMapper::~ValueMapper() { delete getAsMapper(pImpl); }
+
+unsigned
+ValueMapper::registerAlternateMappingContext(ValueToValueMapTy &VM,
+                                             ValueMaterializer *Materializer) {
+  return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);
+}
+
+void ValueMapper::addFlags(RemapFlags Flags) {
+  FlushingMapper(pImpl)->addFlags(Flags);
+}
+
+Value *ValueMapper::mapValue(const Value &V) {
+  return FlushingMapper(pImpl)->mapValue(&V);
+}
+
+Constant *ValueMapper::mapConstant(const Constant &C) {
+  return cast_or_null<Constant>(mapValue(C));
+}
+
+Metadata *ValueMapper::mapMetadata(const Metadata &MD) {
+  return FlushingMapper(pImpl)->mapMetadata(&MD);
+}
+
+MDNode *ValueMapper::mapMDNode(const MDNode &N) {
+  return cast_or_null<MDNode>(mapMetadata(N));
+}
+
+void ValueMapper::remapInstruction(Instruction &I) {
+  FlushingMapper(pImpl)->remapInstruction(&I);
+}
+
+void ValueMapper::remapFunction(Function &F) {
+  FlushingMapper(pImpl)->remapFunction(F);
+}
+
+void ValueMapper::scheduleMapGlobalInitializer(GlobalVariable &GV,
+                                               Constant &Init,
+                                               unsigned MCID) {
+  getAsMapper(pImpl)->scheduleMapGlobalInitializer(GV, Init, MCID);
+}
+
+void ValueMapper::scheduleMapAppendingVariable(GlobalVariable &GV,
+                                               Constant *InitPrefix,
+                                               bool IsOldCtorDtor,
+                                               ArrayRef<Constant *> NewMembers,
+                                               unsigned MCID) {
+  getAsMapper(pImpl)->scheduleMapAppendingVariable(
+      GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
+}
+
+void ValueMapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
+                                           unsigned MCID) {
+  getAsMapper(pImpl)->scheduleMapGlobalAliasee(GA, Aliasee, MCID);
+}
+
+void ValueMapper::scheduleRemapFunction(Function &F, unsigned MCID) {
+  getAsMapper(pImpl)->scheduleRemapFunction(F, MCID);
+}

Modified: llvm/trunk/unittests/Transforms/Utils/ValueMapperTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/Transforms/Utils/ValueMapperTest.cpp?rev=266510&r1=266509&r2=266510&view=diff
==============================================================================
--- llvm/trunk/unittests/Transforms/Utils/ValueMapperTest.cpp (original)
+++ llvm/trunk/unittests/Transforms/Utils/ValueMapperTest.cpp Fri Apr 15 21:29:55 2016
@@ -19,16 +19,16 @@ using namespace llvm;
 
 namespace {
 
-TEST(ValueMapperTest, MapMetadata) {
+TEST(ValueMapperTest, mapMDNode) {
   LLVMContext Context;
   auto *U = MDTuple::get(Context, None);
 
   // The node should be unchanged.
   ValueToValueMapTy VM;
-  EXPECT_EQ(U, MapMetadata(U, VM, RF_None));
+  EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U));
 }
 
-TEST(ValueMapperTest, MapMetadataCycle) {
+TEST(ValueMapperTest, mapMDNodeCycle) {
   LLVMContext Context;
   MDNode *U0;
   MDNode *U1;
@@ -52,19 +52,19 @@ TEST(ValueMapperTest, MapMetadataCycle)
   // Cycles shouldn't be duplicated.
   {
     ValueToValueMapTy VM;
-    EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
-    EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
+    EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
+    EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
   }
 
   // Check the other order.
   {
     ValueToValueMapTy VM;
-    EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
-    EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
+    EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
+    EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
   }
 }
 
-TEST(ValueMapperTest, MapMetadataDuplicatedCycle) {
+TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) {
   LLVMContext Context;
   auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo();
   std::unique_ptr<GlobalVariable> G0 = llvm::make_unique<GlobalVariable>(
@@ -94,8 +94,8 @@ TEST(ValueMapperTest, MapMetadataDuplica
   // have new nodes that reference G1 (instead of G0).
   ValueToValueMapTy VM;
   VM[G0.get()] = G1.get();
-  MDNode *MappedN0 = MapMetadata(N0, VM);
-  MDNode *MappedN1 = MapMetadata(N1, VM);
+  MDNode *MappedN0 = ValueMapper(VM).mapMDNode(*N0);
+  MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1);
   EXPECT_NE(N0, MappedN0);
   EXPECT_NE(N1, MappedN1);
   EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1));
@@ -105,31 +105,31 @@ TEST(ValueMapperTest, MapMetadataDuplica
   EXPECT_TRUE(MappedN1->isResolved());
 }
 
-TEST(ValueMapperTest, MapMetadataUnresolved) {
+TEST(ValueMapperTest, mapMDNodeUnresolved) {
   LLVMContext Context;
   TempMDTuple T = MDTuple::getTemporary(Context, None);
 
   ValueToValueMapTy VM;
-  EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
+  EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T));
 }
 
-TEST(ValueMapperTest, MapMetadataDistinct) {
+TEST(ValueMapperTest, mapMDNodeDistinct) {
   LLVMContext Context;
   auto *D = MDTuple::getDistinct(Context, None);
 
   {
     // The node should be cloned.
     ValueToValueMapTy VM;
-    EXPECT_NE(D, MapMetadata(D, VM, RF_None));
+    EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D));
   }
   {
     // The node should be moved.
     ValueToValueMapTy VM;
-    EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
+    EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
   }
 }
 
-TEST(ValueMapperTest, MapMetadataDistinctOperands) {
+TEST(ValueMapperTest, mapMDNodeDistinctOperands) {
   LLVMContext Context;
   Metadata *Old = MDTuple::getDistinct(Context, None);
   auto *D = MDTuple::getDistinct(Context, Old);
@@ -140,11 +140,11 @@ TEST(ValueMapperTest, MapMetadataDistinc
   VM.MD()[Old].reset(New);
 
   // Make sure operands are updated.
-  EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
+  EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
   EXPECT_EQ(New, D->getOperand(0));
 }
 
-TEST(ValueMapperTest, MapMetadataSeeded) {
+TEST(ValueMapperTest, mapMDNodeSeeded) {
   LLVMContext Context;
   auto *D = MDTuple::getDistinct(Context, None);
 
@@ -154,10 +154,10 @@ TEST(ValueMapperTest, MapMetadataSeeded)
 
   VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
   EXPECT_EQ(D, *VM.getMappedMD(D));
-  EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
+  EXPECT_EQ(D, ValueMapper(VM).mapMDNode(*D));
 }
 
-TEST(ValueMapperTest, MapMetadataSeededWithNull) {
+TEST(ValueMapperTest, mapMDNodeSeededWithNull) {
   LLVMContext Context;
   auto *D = MDTuple::getDistinct(Context, None);
 
@@ -167,10 +167,10 @@ TEST(ValueMapperTest, MapMetadataSeededW
 
   VM.MD().insert(std::make_pair(D, TrackingMDRef()));
   EXPECT_EQ(nullptr, *VM.getMappedMD(D));
-  EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
+  EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D));
 }
 
-TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) {
+TEST(ValueMapperTest, mapMetadataNullMapGlobalWithIgnoreMissingLocals) {
   LLVMContext C;
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
@@ -179,25 +179,25 @@ TEST(ValueMapperTest, MapMetadataNullMap
 
   ValueToValueMapTy VM;
   RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
-  EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags));
+  EXPECT_EQ(nullptr, ValueMapper(VM, Flags).mapValue(*F));
 }
 
-TEST(ValueMapperTest, MapMetadataMDString) {
+TEST(ValueMapperTest, mapMetadataMDString) {
   LLVMContext C;
   auto *S1 = MDString::get(C, "S1");
   ValueToValueMapTy VM;
 
   // Make sure S1 maps to itself, but isn't memoized.
-  EXPECT_EQ(S1, MapMetadata(S1, VM));
+  EXPECT_EQ(S1, ValueMapper(VM).mapMetadata(*S1));
   EXPECT_EQ(None, VM.getMappedMD(S1));
 
   // We still expect VM.MD() to be respected.
   auto *S2 = MDString::get(C, "S2");
   VM.MD()[S1].reset(S2);
-  EXPECT_EQ(S2, MapMetadata(S1, VM));
+  EXPECT_EQ(S2, ValueMapper(VM).mapMetadata(*S1));
 }
 
-TEST(ValueMapperTest, MapMetadataGetMappedMD) {
+TEST(ValueMapperTest, mapMetadataGetMappedMD) {
   LLVMContext C;
   auto *N0 = MDTuple::get(C, None);
   auto *N1 = MDTuple::get(C, N0);
@@ -205,8 +205,8 @@ TEST(ValueMapperTest, MapMetadataGetMapp
   // Make sure hasMD and getMappedMD work correctly.
   ValueToValueMapTy VM;
   EXPECT_FALSE(VM.hasMD());
-  EXPECT_EQ(N0, MapMetadata(N0, VM));
-  EXPECT_EQ(N1, MapMetadata(N1, VM));
+  EXPECT_EQ(N0, ValueMapper(VM).mapMetadata(*N0));
+  EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1));
   EXPECT_TRUE(VM.hasMD());
   ASSERT_NE(None, VM.getMappedMD(N0));
   ASSERT_NE(None, VM.getMappedMD(N1));
@@ -214,7 +214,7 @@ TEST(ValueMapperTest, MapMetadataGetMapp
   EXPECT_EQ(N1, *VM.getMappedMD(N1));
 }
 
-TEST(ValueMapperTest, MapMetadataNoModuleLevelChanges) {
+TEST(ValueMapperTest, mapMetadataNoModuleLevelChanges) {
   LLVMContext C;
   auto *N0 = MDTuple::get(C, None);
   auto *N1 = MDTuple::get(C, N0);
@@ -222,14 +222,14 @@ TEST(ValueMapperTest, MapMetadataNoModul
   // Nothing should be memoized when RF_NoModuleLevelChanges.
   ValueToValueMapTy VM;
   EXPECT_FALSE(VM.hasMD());
-  EXPECT_EQ(N0, MapMetadata(N0, VM, RF_NoModuleLevelChanges));
-  EXPECT_EQ(N1, MapMetadata(N1, VM, RF_NoModuleLevelChanges));
+  EXPECT_EQ(N0, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0));
+  EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1));
   EXPECT_FALSE(VM.hasMD());
   EXPECT_EQ(None, VM.getMappedMD(N0));
   EXPECT_EQ(None, VM.getMappedMD(N1));
 }
 
-TEST(ValueMapperTest, MapMetadataConstantAsMetadata) {
+TEST(ValueMapperTest, mapMetadataConstantAsMetadata) {
   LLVMContext C;
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
@@ -239,23 +239,23 @@ TEST(ValueMapperTest, MapMetadataConstan
   auto *CAM = ConstantAsMetadata::get(F.get());
   {
     ValueToValueMapTy VM;
-    EXPECT_EQ(CAM, MapMetadata(CAM, VM));
+    EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM));
     EXPECT_TRUE(VM.MD().count(CAM));
     VM.MD().erase(CAM);
-    EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
+    EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
     EXPECT_TRUE(VM.MD().count(CAM));
 
     auto *N = MDTuple::get(C, None);
     VM.MD()[CAM].reset(N);
-    EXPECT_EQ(N, MapMetadata(CAM, VM));
-    EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
+    EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM));
+    EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
   }
 
   std::unique_ptr<Function> F2(
       Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
   ValueToValueMapTy VM;
   VM[F.get()] = F2.get();
-  auto *F2MD = MapMetadata(CAM, VM);
+  auto *F2MD = ValueMapper(VM).mapMetadata(*CAM);
   EXPECT_TRUE(VM.MD().count(CAM));
   EXPECT_TRUE(F2MD);
   EXPECT_EQ(F2.get(), cast<ConstantAsMetadata>(F2MD)->getValue());
@@ -263,7 +263,7 @@ TEST(ValueMapperTest, MapMetadataConstan
 
 #ifdef GTEST_HAS_DEATH_TEST
 #ifndef NDEBUG
-TEST(ValueMapperTest, MapMetadataLocalAsMetadata) {
+TEST(ValueMapperTest, mapMetadataLocalAsMetadata) {
   LLVMContext C;
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
@@ -271,18 +271,18 @@ TEST(ValueMapperTest, MapMetadataLocalAs
       Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
   Argument &A = *F->arg_begin();
 
-  // MapMetadata doesn't support LocalAsMetadata.  The only valid container for
+  // mapMetadata doesn't support LocalAsMetadata.  The only valid container for
   // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
   auto *LAM = LocalAsMetadata::get(&A);
   ValueToValueMapTy VM;
-  EXPECT_DEATH(MapMetadata(LAM, VM), "Unexpected local metadata");
-  EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals),
+  EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata");
+  EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM),
                "Unexpected local metadata");
 }
 #endif
 #endif
 
-TEST(ValueMapperTest, MapValueLocalAsMetadata) {
+TEST(ValueMapperTest, mapValueLocalAsMetadata) {
   LLVMContext C;
   FunctionType *FTy =
       FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
@@ -305,26 +305,26 @@ TEST(ValueMapperTest, MapValueLocalAsMet
   auto *N0 = MDTuple::get(C, None);
   auto *N0AV = MetadataAsValue::get(C, N0);
   ValueToValueMapTy VM;
-  EXPECT_EQ(N0AV, MapValue(MAV, VM));
-  EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals));
+  EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
+  EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
   EXPECT_FALSE(VM.count(MAV));
   EXPECT_FALSE(VM.count(&A));
   EXPECT_EQ(None, VM.getMappedMD(LAM));
 
   VM[MAV] = MAV;
-  EXPECT_EQ(MAV, MapValue(MAV, VM));
-  EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals));
+  EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
+  EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
   EXPECT_TRUE(VM.count(MAV));
   EXPECT_FALSE(VM.count(&A));
 
   VM[MAV] = &A;
-  EXPECT_EQ(&A, MapValue(MAV, VM));
-  EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals));
+  EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
+  EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
   EXPECT_TRUE(VM.count(MAV));
   EXPECT_FALSE(VM.count(&A));
 }
 
-TEST(ValueMapperTest, MapValueLocalAsMetadataToConstant) {
+TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) {
   LLVMContext Context;
   auto *Int8 = Type::getInt8Ty(Context);
   FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
@@ -342,8 +342,8 @@ TEST(ValueMapperTest, MapValueLocalAsMet
   auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
   EXPECT_TRUE(isa<LocalAsMetadata>(MDA->getMetadata()));
   EXPECT_TRUE(isa<ConstantAsMetadata>(MDC->getMetadata()));
-  EXPECT_EQ(&C, MapValue(&A, VM));
-  EXPECT_EQ(MDC, MapValue(MDA, VM));
+  EXPECT_EQ(&C, ValueMapper(VM).mapValue(A));
+  EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA));
 }
 
 } // end namespace




More information about the llvm-commits mailing list