llvm.org GIT mirror llvm / 1f03619
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266510 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 4 years ago
4 changed file(s) with 517 addition(s) and 195 deletion(s). Raw diff Collapse all Expand all
9696 static inline RemapFlags operator|(RemapFlags LHS, RemapFlags RHS) {
9797 return RemapFlags(unsigned(LHS) | unsigned(RHS));
9898 }
99
100 class ValueMapperImpl;
101
102 /// Context for (re-)mapping values (and metadata).
103 ///
104 /// A shared context used for mapping and remapping of Value and Metadata
105 /// instances using \a ValueToValueMapTy, \a RemapFlags, \a
106 /// ValueMapTypeRemapper, and \a ValueMaterializer.
107 ///
108 /// There are a number of top-level entry points:
109 /// - \a mapValue() (and \a mapConstant());
110 /// - \a mapMetadata() (and \a mapMDNode());
111 /// - \a remapInstruction(); and
112 /// - \a remapFunction().
113 ///
114 /// The \a ValueMaterializer can be used as a callback, but cannot invoke any
115 /// of these top-level functions recursively. Instead, callbacks should use
116 /// one of the following to schedule work lazily in the \a ValueMapper
117 /// instance:
118 /// - \a scheduleMapGlobalInitializer()
119 /// - \a scheduleMapAppendingVariable()
120 /// - \a scheduleMapGlobalAliasee()
121 /// - \a scheduleRemapFunction()
122 ///
123 /// Sometimes a callback needs a diferent mapping context. Such a context can
124 /// be registered using \a registerAlternateMappingContext(), which takes an
125 /// alternate \a ValueToValueMapTy and \a ValueMaterializer and returns a ID to
126 /// pass into the schedule*() functions.
127 ///
128 /// TODO: lib/Linker really doesn't need the \a ValueHandle in the \a
129 /// ValueToValueMapTy. We should template \a ValueMapper (and its
130 /// implementation classes), and explicitly instantiate on two concrete
131 /// instances of \a ValueMap (one as \a ValueToValueMap, and one with raw \a
132 /// Value pointers). It may be viable to do away with \a TrackingMDRef in the
133 /// \a Metadata side map for the lib/Linker case as well, in which case we'll
134 /// need a new template parameter on \a ValueMap.
135 ///
136 /// TODO: Update callers of \a RemapInstruction() and \a MapValue() (etc.) to
137 /// use \a ValueMapper directly.
138 class ValueMapper {
139 void *pImpl;
140
141 ValueMapper(ValueMapper &&) = delete;
142 ValueMapper(const ValueMapper &) = delete;
143 ValueMapper &operator=(ValueMapper &&) = delete;
144 ValueMapper &operator=(const ValueMapper &) = delete;
145
146 public:
147 ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags = RF_None,
148 ValueMapTypeRemapper *TypeMapper = nullptr,
149 ValueMaterializer *Materializer = nullptr);
150 ~ValueMapper();
151
152 /// Register an alternate mapping context.
153 ///
154 /// Returns a MappingContextID that can be used with the various schedule*()
155 /// API to switch in a different value map on-the-fly.
156 unsigned
157 registerAlternateMappingContext(ValueToValueMapTy &VM,
158 ValueMaterializer *Materializer = nullptr);
159
160 /// Add to the current \a RemapFlags.
161 ///
162 /// \note Like the top-level mapping functions, \a addFlags() must be called
163 /// at the top level, not during a callback in a \a ValueMaterializer.
164 void addFlags(RemapFlags Flags);
165
166 Metadata *mapMetadata(const Metadata &MD);
167 MDNode *mapMDNode(const MDNode &N);
168
169 Value *mapValue(const Value &V);
170 Constant *mapConstant(const Constant &C);
171
172 void remapInstruction(Instruction &I);
173 void remapFunction(Function &F);
174
175 void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
176 unsigned MappingContextID = 0);
177 void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
178 bool IsOldCtorDtor,
179 ArrayRef NewMembers,
180 unsigned MappingContextID = 0);
181 void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
182 unsigned MappingContextID = 0);
183 void scheduleRemapFunction(Function &F, unsigned MappingContextID = 0);
184 };
99185
100186 /// Look up or compute a value in the value map.
101187 ///
114200 /// 6. Else if \c V is a \a MetadataAsValue, rewrap the return of \a
115201 /// MapMetadata().
116202 /// 7. Else, compute the equivalent constant, and return it.
117 Value *MapValue(const Value *V, ValueToValueMapTy &VM,
118 RemapFlags Flags = RF_None,
119 ValueMapTypeRemapper *TypeMapper = nullptr,
120 ValueMaterializer *Materializer = nullptr);
203 inline Value *MapValue(const Value *V, ValueToValueMapTy &VM,
204 RemapFlags Flags = RF_None,
205 ValueMapTypeRemapper *TypeMapper = nullptr,
206 ValueMaterializer *Materializer = nullptr) {
207 return ValueMapper(VM, Flags, TypeMapper, Materializer).mapValue(*V);
208 }
121209
122210 /// Lookup or compute a mapping for a piece of metadata.
123211 ///
134222 ///
135223 /// \note \a LocalAsMetadata is completely unsupported by \a MapMetadata.
136224 /// Instead, use \a MapValue() with its wrapping \a MetadataAsValue instance.
137 Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
138 RemapFlags Flags = RF_None,
139 ValueMapTypeRemapper *TypeMapper = nullptr,
140 ValueMaterializer *Materializer = nullptr);
225 inline Metadata *MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
226 RemapFlags Flags = RF_None,
227 ValueMapTypeRemapper *TypeMapper = nullptr,
228 ValueMaterializer *Materializer = nullptr) {
229 return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMetadata(*MD);
230 }
141231
142232 /// Version of MapMetadata with type safety for MDNode.
143 MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
144 RemapFlags Flags = RF_None,
145 ValueMapTypeRemapper *TypeMapper = nullptr,
146 ValueMaterializer *Materializer = nullptr);
233 inline MDNode *MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
234 RemapFlags Flags = RF_None,
235 ValueMapTypeRemapper *TypeMapper = nullptr,
236 ValueMaterializer *Materializer = nullptr) {
237 return ValueMapper(VM, Flags, TypeMapper, Materializer).mapMDNode(*MD);
238 }
147239
148240 /// Convert the instruction operands from referencing the current values into
149241 /// those specified by VM.
153245 ///
154246 /// Note that \a MapValue() only returns \c nullptr for SSA values missing from
155247 /// \c VM.
156 void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
157 RemapFlags Flags = RF_None,
158 ValueMapTypeRemapper *TypeMapper = nullptr,
159 ValueMaterializer *Materializer = nullptr);
248 inline void RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
249 RemapFlags Flags = RF_None,
250 ValueMapTypeRemapper *TypeMapper = nullptr,
251 ValueMaterializer *Materializer = nullptr) {
252 ValueMapper(VM, Flags, TypeMapper, Materializer).remapInstruction(*I);
253 }
160254
161255 /// Remap the operands, metadata, arguments, and instructions of a function.
162256 ///
164258 /// function; calls \a MapMetadata() on each attached MDNode; remaps the
165259 /// argument types using the provided \c TypeMapper; and calls \a
166260 /// RemapInstruction() on every instruction.
167 void RemapFunction(Function &F, ValueToValueMapTy &VM,
168 RemapFlags Flags = RF_None,
169 ValueMapTypeRemapper *TypeMapper = nullptr,
170 ValueMaterializer *Materializer = nullptr);
261 inline void RemapFunction(Function &F, ValueToValueMapTy &VM,
262 RemapFlags Flags = RF_None,
263 ValueMapTypeRemapper *TypeMapper = nullptr,
264 ValueMaterializer *Materializer = nullptr) {
265 ValueMapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
266 }
171267
172268 /// Version of MapValue with type safety for Constant.
173269 inline Constant *MapValue(const Constant *V, ValueToValueMapTy &VM,
174270 RemapFlags Flags = RF_None,
175271 ValueMapTypeRemapper *TypeMapper = nullptr,
176272 ValueMaterializer *Materializer = nullptr) {
177 // This can be null for RF_NullMapMissingGlobalValues.
178 return cast_or_null(
179 MapValue((const Value *)V, VM, Flags, TypeMapper, Materializer));
273 return ValueMapper(VM, Flags, TypeMapper, Materializer).mapConstant(*V);
180274 }
181275
182276 } // End llvm namespace
396396
397397 bool HasError = false;
398398
399 /// Flags to pass to value mapper invocations.
400 RemapFlags ValueMapperFlags = RF_MoveDistinctMDs | RF_IgnoreMissingLocals;
399 /// Entry point for mapping values and alternate context for mapping aliases.
400 ValueMapper Mapper;
401 unsigned AliasMCID;
401402
402403 /// Handles cloning of a global values from the source module into
403404 /// the destination module, including setting the attributes and visibility.
469470 std::unique_ptr SrcM, ArrayRef ValuesToLink,
470471 std::function AddLazyFor)
471472 : DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(AddLazyFor), TypeMap(Set),
472 GValMaterializer(*this), LValMaterializer(*this) {
473 GValMaterializer(*this), LValMaterializer(*this),
474 Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
475 &GValMaterializer),
476 AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
477 &LValMaterializer)) {
473478 for (GlobalValue *GV : ValuesToLink)
474479 maybeAdd(GV);
475480 }
711716 Type *EltTy = cast(TypeMap.get(SrcGV->getValueType()))
712717 ->getElementType();
713718
719 // FIXME: This upgrade is done during linking to support the C API. Once the
720 // old form is deprecated, we should move this upgrade to
721 // llvm::UpgradeGlobalVariable() and simplify the logic here and in
722 // Mapper::mapAppendingVariable() in ValueMapper.cpp.
714723 StringRef Name = SrcGV->getName();
715724 bool IsNewStructor = false;
716725 bool IsOldStructor = false;
728737 EltTy = StructType::get(SrcGV->getContext(), Tys, false);
729738 }
730739
740 uint64_t DstNumElements = 0;
731741 if (DstGV) {
732742 ArrayType *DstTy = cast(DstGV->getValueType());
743 DstNumElements = DstTy->getNumElements();
733744
734745 if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
735746 emitError(
772783 return nullptr;
773784 }
774785 }
775
776 SmallVector DstElements;
777 if (DstGV)
778 getArrayElements(DstGV->getInitializer(), DstElements);
779786
780787 SmallVector SrcElements;
781788 getArrayElements(SrcGV->getInitializer(), SrcElements);
792799 return !shouldLink(DGV, *Key);
793800 }),
794801 SrcElements.end());
795 uint64_t NewSize = DstElements.size() + SrcElements.size();
802 uint64_t NewSize = DstNumElements + SrcElements.size();
796803 ArrayType *NewType = ArrayType::get(EltTy, NewSize);
797804
798805 // Create the new global variable.
809816 // Stop recursion.
810817 ValueMap[SrcGV] = Ret;
811818
812 for (auto *V : SrcElements) {
813 Constant *NewV;
814 if (IsOldStructor) {
815 auto *S = cast(V);
816 auto *E1 = MapValue(S->getOperand(0), ValueMap, ValueMapperFlags,
817 &TypeMap, &GValMaterializer);
818 auto *E2 = MapValue(S->getOperand(1), ValueMap, ValueMapperFlags,
819 &TypeMap, &GValMaterializer);
820 Value *Null = Constant::getNullValue(VoidPtrTy);
821 NewV =
822 ConstantStruct::get(cast(EltTy), E1, E2, Null, nullptr);
823 } else {
824 NewV =
825 MapValue(V, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
826 }
827 DstElements.push_back(NewV);
828 }
829
830 NG->setInitializer(ConstantArray::get(NewType, DstElements));
819 Mapper.scheduleMapAppendingVariable(*NG,
820 DstGV ? DstGV->getInitializer() : nullptr,
821 IsOldStructor, SrcElements);
831822
832823 // Replace any uses of the two global variables with uses of the new
833824 // global.
934925 /// referenced are in Dest.
935926 void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
936927 // Figure out what the initializer looks like in the dest module.
937 Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, ValueMapperFlags,
938 &TypeMap, &GValMaterializer));
928 Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer());
939929 }
940930
941931 /// Copy the source function over into the dest function and fix up references
967957 Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList());
968958
969959 // Everything has been moved over. Remap it.
970 RemapFunction(Dst, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
960 Mapper.scheduleRemapFunction(Dst);
971961 return false;
972962 }
973963
974964 void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
975 Constant *Aliasee = Src.getAliasee();
976 Constant *Val = MapValue(Aliasee, AliasValueMap, ValueMapperFlags, &TypeMap,
977 &LValMaterializer);
978 Dst.setAliasee(Val);
965 Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID);
979966 }
980967
981968 bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
999986 NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
1000987 // Add Src elements into Dest node.
1001988 for (const MDNode *Op : NMD.operands())
1002 DestNMD->addOperand(MapMetadata(
1003 Op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues,
1004 &TypeMap, &GValMaterializer));
989 DestNMD->addOperand(Mapper.mapMDNode(*Op));
1005990 }
1006991 }
1007992
12411226 continue;
12421227
12431228 assert(!GV->isDeclaration());
1244 MapValue(GV, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
1229 Mapper.mapValue(*GV);
12451230 if (HasError)
12461231 return true;
12471232 }
12491234 // Note that we are done linking global value bodies. This prevents
12501235 // metadata linking from creating new references.
12511236 DoneLinkingBodies = true;
1237 Mapper.addFlags(RF_NullMapMissingGlobalValues);
12521238
12531239 // Remap all of the named MDNodes in Src into the DstM module. We do this
12541240 // after linking GlobalValues so that MDNodes that reference GlobalValues
1515 #include "llvm/IR/CallSite.h"
1616 #include "llvm/IR/Constants.h"
1717 #include "llvm/IR/Function.h"
18 #include "llvm/IR/GlobalAlias.h"
19 #include "llvm/IR/GlobalVariable.h"
1820 #include "llvm/IR/InlineAsm.h"
1921 #include "llvm/IR/Instructions.h"
2022 #include "llvm/IR/Metadata.h"
2830 }
2931
3032 namespace {
31
32 /// A GlobalValue whose initializer needs to be materialized.
33 struct DelayedGlobalValueInit {
34 GlobalValue *Old;
35 GlobalValue *New;
36 DelayedGlobalValueInit(const GlobalValue *Old, GlobalValue *New)
37 : Old(const_cast(Old)), New(New) {}
38 };
3933
4034 /// A basic block used in a BlockAddress whose function body is not yet
4135 /// materialized.
5751 TempBB(BasicBlock::Create(Old.getContext())) {}
5852 };
5953
54 struct WorklistEntry {
55 enum EntryKind {
56 MapGlobalInit,
57 MapAppendingVar,
58 MapGlobalAliasee,
59 RemapFunction
60 };
61 struct GVInitTy {
62 GlobalVariable *GV;
63 Constant *Init;
64 };
65 struct AppendingGVTy {
66 GlobalVariable *GV;
67 Constant *InitPrefix;
68 };
69 struct GlobalAliaseeTy {
70 GlobalAlias *GA;
71 Constant *Aliasee;
72 };
73
74 unsigned Kind : 2;
75 unsigned MCID : 29;
76 unsigned AppendingGVIsOldCtorDtor : 1;
77 unsigned AppendingGVNumNewMembers;
78 union {
79 GVInitTy GVInit;
80 AppendingGVTy AppendingGV;
81 GlobalAliaseeTy GlobalAliasee;
82 Function *RemapF;
83 } Data;
84 };
85
86 struct MappingContext {
87 ValueToValueMapTy *VM;
88 ValueMaterializer *Materializer = nullptr;
89
90 /// Construct a MappingContext with a value map and materializer.
91 explicit MappingContext(ValueToValueMapTy &VM,
92 ValueMaterializer *Materializer = nullptr)
93 : VM(&VM), Materializer(Materializer) {}
94 };
95
6096 class MDNodeMapper;
6197 class Mapper {
6298 friend class MDNodeMapper;
6399
64 ValueToValueMapTy *VM;
65100 RemapFlags Flags;
66101 ValueMapTypeRemapper *TypeMapper;
67 ValueMaterializer *Materializer;
68
69 SmallVector DelayedInits;
102 unsigned CurrentMCID = 0;
103 SmallVector MCs;
104 SmallVector Worklist;
70105 SmallVector DelayedBBs;
106 SmallVector AppendingInits;
71107
72108 public:
73109 Mapper(ValueToValueMapTy &VM, RemapFlags Flags,
74110 ValueMapTypeRemapper *TypeMapper, ValueMaterializer *Materializer)
75 : VM(&VM), Flags(Flags), TypeMapper(TypeMapper),
76 Materializer(Materializer) {}
77
78 ~Mapper();
111 : Flags(Flags), TypeMapper(TypeMapper),
112 MCs(1, MappingContext(VM, Materializer)) {}
113
114 /// ValueMapper should explicitly call \a flush() before destruction.
115 ~Mapper() { assert(!hasWorkToDo() && "Expected to be flushed"); }
116
117 bool hasWorkToDo() const { return !Worklist.empty(); }
118
119 unsigned
120 registerAlternateMappingContext(ValueToValueMapTy &VM,
121 ValueMaterializer *Materializer = nullptr) {
122 MCs.push_back(MappingContext(VM, Materializer));
123 return MCs.size() - 1;
124 }
125
126 void addFlags(RemapFlags Flags);
79127
80128 Value *mapValue(const Value *V);
81129 void remapInstruction(Instruction *I);
82130 void remapFunction(Function &F);
131
132 Constant *mapConstant(const Constant *C) {
133 return cast_or_null(mapValue(C));
134 }
83135
84136 /// Map metadata.
85137 ///
101153 // through metadata operands, always return nullptr on unmapped locals.
102154 Metadata *mapLocalAsMetadata(const LocalAsMetadata &LAM);
103155
156 void scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
157 unsigned MCID);
158 void scheduleMapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
159 bool IsOldCtorDtor,
160 ArrayRef NewMembers,
161 unsigned MCID);
162 void scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
163 unsigned MCID);
164 void scheduleRemapFunction(Function &F, unsigned MCID);
165
166 void flush();
167
104168 private:
105 ValueToValueMapTy &getVM() { return *VM; }
169 void mapGlobalInitializer(GlobalVariable &GV, Constant &Init);
170 void mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
171 bool IsOldCtorDtor,
172 ArrayRef NewMembers);
173 void mapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee);
174 void remapFunction(Function &F, ValueToValueMapTy &VM);
175
176 ValueToValueMapTy &getVM() { return *MCs[CurrentMCID].VM; }
177 ValueMaterializer *getMaterializer() { return MCs[CurrentMCID].Materializer; }
106178
107179 Value *mapBlockAddress(const BlockAddress &BA);
108180
263335
264336 } // end namespace
265337
266 Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
267 ValueMapTypeRemapper *TypeMapper,
268 ValueMaterializer *Materializer) {
269 return Mapper(VM, Flags, TypeMapper, Materializer).mapValue(V);
270 }
271
272338 Value *Mapper::mapValue(const Value *V) {
273339 ValueToValueMapTy::iterator I = getVM().find(V);
274340
277343 return I->second;
278344
279345 // If we have a materializer and it can materialize a value, use that.
280 if (Materializer) {
346 if (auto *Materializer = getMaterializer()) {
281347 if (Value *NewV =
282348 Materializer->materializeDeclFor(const_cast(V))) {
283349 getVM()[V] = NewV;
284350 if (auto *NewGV = dyn_cast(NewV))
285 DelayedInits.push_back(
286 DelayedGlobalValueInit(cast(V), NewGV));
351 Materializer->materializeInitFor(
352 NewGV, cast(const_cast(V)));
287353 return NewV;
288354 }
289355 }
683749 return None;
684750 }
685751
686 Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
687 RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
688 ValueMaterializer *Materializer) {
689 return Mapper(VM, Flags, TypeMapper, Materializer).mapMetadata(MD);
690 }
691
692752 Metadata *Mapper::mapLocalAsMetadata(const LocalAsMetadata &LAM) {
693753 // Lookup the mapping for the value itself, and return the appropriate
694754 // metadata.
715775 return MDNodeMapper(*this).map(*cast(MD));
716776 }
717777
718 Mapper::~Mapper() {
719 // Materialize global initializers.
720 while (!DelayedInits.empty()) {
721 auto Init = DelayedInits.pop_back_val();
722 Materializer->materializeInitFor(Init.New, Init.Old);
723 }
724
725 // Process block addresses delayed until global inits.
778 void Mapper::flush() {
779 // Flush out the worklist of global values.
780 while (!Worklist.empty()) {
781 WorklistEntry E = Worklist.pop_back_val();
782 CurrentMCID = E.MCID;
783 switch (E.Kind) {
784 case WorklistEntry::MapGlobalInit:
785 E.Data.GVInit.GV->setInitializer(mapConstant(E.Data.GVInit.Init));
786 break;
787 case WorklistEntry::MapAppendingVar: {
788 unsigned PrefixSize = AppendingInits.size() - E.AppendingGVNumNewMembers;
789 mapAppendingVariable(*E.Data.AppendingGV.GV,
790 E.Data.AppendingGV.InitPrefix,
791 E.AppendingGVIsOldCtorDtor,
792 makeArrayRef(AppendingInits).slice(PrefixSize));
793 AppendingInits.resize(PrefixSize);
794 break;
795 }
796 case WorklistEntry::MapGlobalAliasee:
797 E.Data.GlobalAliasee.GA->setAliasee(
798 mapConstant(E.Data.GlobalAliasee.Aliasee));
799 break;
800 case WorklistEntry::RemapFunction:
801 remapFunction(*E.Data.RemapF);
802 break;
803 }
804 }
805 CurrentMCID = 0;
806
807 // Finish logic for block addresses now that all global values have been
808 // handled.
726809 while (!DelayedBBs.empty()) {
727810 DelayedBasicBlock DBB = DelayedBBs.pop_back_val();
728811 BasicBlock *BB = cast_or_null(mapValue(DBB.OldBB));
729812 DBB.TempBB->replaceAllUsesWith(BB ? BB : DBB.OldBB);
730813 }
731
732 // We don't expect these to grow after clearing.
733 assert(DelayedInits.empty());
734 assert(DelayedBBs.empty());
735 }
736
737 MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
738 RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
739 ValueMaterializer *Materializer) {
740 return cast_or_null(MapMetadata(static_cast(MD), VM,
741 Flags, TypeMapper, Materializer));
742 }
743
744 void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VM,
745 RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
746 ValueMaterializer *Materializer) {
747 Mapper(VM, Flags, TypeMapper, Materializer).remapInstruction(I);
748814 }
749815
750816 void Mapper::remapInstruction(Instruction *I) {
781847 if (New != Old)
782848 I->setMetadata(MI.first, New);
783849 }
784
850
785851 if (!TypeMapper)
786852 return;
787853
807873 I->mutateType(TypeMapper->remapType(I->getType()));
808874 }
809875
810 void llvm::RemapFunction(Function &F, ValueToValueMapTy &VM, RemapFlags Flags,
811 ValueMapTypeRemapper *TypeMapper,
812 ValueMaterializer *Materializer) {
813 Mapper(VM, Flags, TypeMapper, Materializer).remapFunction(F);
814 }
815
816876 void Mapper::remapFunction(Function &F) {
817877 // Remap the operands.
818878 for (Use &Op : F.operands())
835895 for (Instruction &I : BB)
836896 remapInstruction(&I);
837897 }
898
899 void Mapper::mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix,
900 bool IsOldCtorDtor,
901 ArrayRef NewMembers) {
902 SmallVector Elements;
903 if (InitPrefix) {
904 unsigned NumElements =
905 cast(InitPrefix->getType())->getNumElements();
906 for (unsigned I = 0; I != NumElements; ++I)
907 Elements.push_back(InitPrefix->getAggregateElement(I));
908 }
909
910 PointerType *VoidPtrTy;
911 Type *EltTy;
912 if (IsOldCtorDtor) {
913 // FIXME: This upgrade is done during linking to support the C API. See
914 // also IRLinker::linkAppendingVarProto() in IRMover.cpp.
915 VoidPtrTy = Type::getInt8Ty(GV.getContext())->getPointerTo();
916 auto &ST = *cast(NewMembers.front()->getType());
917 Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy};
918 EltTy = StructType::get(GV.getContext(), Tys, false);
919 }
920
921 for (auto *V : NewMembers) {
922 Constant *NewV;
923 if (IsOldCtorDtor) {
924 auto *S = cast(V);
925 auto *E1 = mapValue(S->getOperand(0));
926 auto *E2 = mapValue(S->getOperand(1));
927 Value *Null = Constant::getNullValue(VoidPtrTy);
928 NewV =
929 ConstantStruct::get(cast(EltTy), E1, E2, Null, nullptr);
930 } else {
931 NewV = cast_or_null(mapValue(V));
932 }
933 Elements.push_back(NewV);
934 }
935
936 GV.setInitializer(ConstantArray::get(
937 cast(GV.getType()->getElementType()), Elements));
938 }
939
940 void Mapper::scheduleMapGlobalInitializer(GlobalVariable &GV, Constant &Init,
941 unsigned MCID) {
942 assert(MCID < MCs.size() && "Invalid mapping context");
943
944 WorklistEntry WE;
945 WE.Kind = WorklistEntry::MapGlobalInit;
946 WE.MCID = MCID;
947 WE.Data.GVInit.GV = &GV;
948 WE.Data.GVInit.Init = &Init;
949 Worklist.push_back(WE);
950 }
951
952 void Mapper::scheduleMapAppendingVariable(GlobalVariable &GV,
953 Constant *InitPrefix,
954 bool IsOldCtorDtor,
955 ArrayRef NewMembers,
956 unsigned MCID) {
957 assert(MCID < MCs.size() && "Invalid mapping context");
958
959 WorklistEntry WE;
960 WE.Kind = WorklistEntry::MapAppendingVar;
961 WE.MCID = MCID;
962 WE.Data.AppendingGV.GV = &GV;
963 WE.Data.AppendingGV.InitPrefix = InitPrefix;
964 WE.AppendingGVIsOldCtorDtor = IsOldCtorDtor;
965 WE.AppendingGVNumNewMembers = NewMembers.size();
966 Worklist.push_back(WE);
967 AppendingInits.append(NewMembers.begin(), NewMembers.end());
968 }
969
970 void Mapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
971 unsigned MCID) {
972 assert(MCID < MCs.size() && "Invalid mapping context");
973
974 WorklistEntry WE;
975 WE.Kind = WorklistEntry::MapGlobalAliasee;
976 WE.MCID = MCID;
977 WE.Data.GlobalAliasee.GA = &GA;
978 WE.Data.GlobalAliasee.Aliasee = &Aliasee;
979 Worklist.push_back(WE);
980 }
981
982 void Mapper::scheduleRemapFunction(Function &F, unsigned MCID) {
983 assert(MCID < MCs.size() && "Invalid mapping context");
984
985 WorklistEntry WE;
986 WE.Kind = WorklistEntry::RemapFunction;
987 WE.MCID = MCID;
988 WE.Data.RemapF = &F;
989 Worklist.push_back(WE);
990 }
991
992 void Mapper::addFlags(RemapFlags Flags) {
993 assert(!hasWorkToDo() && "Expected to have flushed the worklist");
994 this->Flags = this->Flags | Flags;
995 }
996
997 static Mapper *getAsMapper(void *pImpl) {
998 return reinterpret_cast(pImpl);
999 }
1000
1001 namespace {
1002
1003 class FlushingMapper {
1004 Mapper &M;
1005
1006 public:
1007 explicit FlushingMapper(void *pImpl) : M(*getAsMapper(pImpl)) {
1008 assert(!M.hasWorkToDo() && "Expected to be flushed");
1009 }
1010 ~FlushingMapper() { M.flush(); }
1011 Mapper *operator->() const { return &M; }
1012 };
1013
1014 } // end namespace
1015
1016 ValueMapper::ValueMapper(ValueToValueMapTy &VM, RemapFlags Flags,
1017 ValueMapTypeRemapper *TypeMapper,
1018 ValueMaterializer *Materializer)
1019 : pImpl(new Mapper(VM, Flags, TypeMapper, Materializer)) {}
1020
1021 ValueMapper::~ValueMapper() { delete getAsMapper(pImpl); }
1022
1023 unsigned
1024 ValueMapper::registerAlternateMappingContext(ValueToValueMapTy &VM,
1025 ValueMaterializer *Materializer) {
1026 return getAsMapper(pImpl)->registerAlternateMappingContext(VM, Materializer);
1027 }
1028
1029 void ValueMapper::addFlags(RemapFlags Flags) {
1030 FlushingMapper(pImpl)->addFlags(Flags);
1031 }
1032
1033 Value *ValueMapper::mapValue(const Value &V) {
1034 return FlushingMapper(pImpl)->mapValue(&V);
1035 }
1036
1037 Constant *ValueMapper::mapConstant(const Constant &C) {
1038 return cast_or_null(mapValue(C));
1039 }
1040
1041 Metadata *ValueMapper::mapMetadata(const Metadata &MD) {
1042 return FlushingMapper(pImpl)->mapMetadata(&MD);
1043 }
1044
1045 MDNode *ValueMapper::mapMDNode(const MDNode &N) {
1046 return cast_or_null(mapMetadata(N));
1047 }
1048
1049 void ValueMapper::remapInstruction(Instruction &I) {
1050 FlushingMapper(pImpl)->remapInstruction(&I);
1051 }
1052
1053 void ValueMapper::remapFunction(Function &F) {
1054 FlushingMapper(pImpl)->remapFunction(F);
1055 }
1056
1057 void ValueMapper::scheduleMapGlobalInitializer(GlobalVariable &GV,
1058 Constant &Init,
1059 unsigned MCID) {
1060 getAsMapper(pImpl)->scheduleMapGlobalInitializer(GV, Init, MCID);
1061 }
1062
1063 void ValueMapper::scheduleMapAppendingVariable(GlobalVariable &GV,
1064 Constant *InitPrefix,
1065 bool IsOldCtorDtor,
1066 ArrayRef NewMembers,
1067 unsigned MCID) {
1068 getAsMapper(pImpl)->scheduleMapAppendingVariable(
1069 GV, InitPrefix, IsOldCtorDtor, NewMembers, MCID);
1070 }
1071
1072 void ValueMapper::scheduleMapGlobalAliasee(GlobalAlias &GA, Constant &Aliasee,
1073 unsigned MCID) {
1074 getAsMapper(pImpl)->scheduleMapGlobalAliasee(GA, Aliasee, MCID);
1075 }
1076
1077 void ValueMapper::scheduleRemapFunction(Function &F, unsigned MCID) {
1078 getAsMapper(pImpl)->scheduleRemapFunction(F, MCID);
1079 }
1818
1919 namespace {
2020
21 TEST(ValueMapperTest, MapMetadata) {
21 TEST(ValueMapperTest, mapMDNode) {
2222 LLVMContext Context;
2323 auto *U = MDTuple::get(Context, None);
2424
2525 // The node should be unchanged.
2626 ValueToValueMapTy VM;
27 EXPECT_EQ(U, MapMetadata(U, VM, RF_None));
28 }
29
30 TEST(ValueMapperTest, MapMetadataCycle) {
27 EXPECT_EQ(U, ValueMapper(VM).mapMDNode(*U));
28 }
29
30 TEST(ValueMapperTest, mapMDNodeCycle) {
3131 LLVMContext Context;
3232 MDNode *U0;
3333 MDNode *U1;
5151 // Cycles shouldn't be duplicated.
5252 {
5353 ValueToValueMapTy VM;
54 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
55 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
54 EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
55 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
5656 }
5757
5858 // Check the other order.
5959 {
6060 ValueToValueMapTy VM;
61 EXPECT_EQ(U1, MapMetadata(U1, VM, RF_None));
62 EXPECT_EQ(U0, MapMetadata(U0, VM, RF_None));
63 }
64 }
65
66 TEST(ValueMapperTest, MapMetadataDuplicatedCycle) {
61 EXPECT_EQ(U1, ValueMapper(VM).mapMDNode(*U1));
62 EXPECT_EQ(U0, ValueMapper(VM).mapMDNode(*U0));
63 }
64 }
65
66 TEST(ValueMapperTest, mapMDNodeDuplicatedCycle) {
6767 LLVMContext Context;
6868 auto *PtrTy = Type::getInt8Ty(Context)->getPointerTo();
6969 std::unique_ptr G0 = llvm::make_unique(
9393 // have new nodes that reference G1 (instead of G0).
9494 ValueToValueMapTy VM;
9595 VM[G0.get()] = G1.get();
96 MDNode *MappedN0 = MapMetadata(N0, VM);
97 MDNode *MappedN1 = MapMetadata(N1, VM);
96 MDNode *MappedN0 = ValueMapper(VM).mapMDNode(*N0);
97 MDNode *MappedN1 = ValueMapper(VM).mapMDNode(*N1);
9898 EXPECT_NE(N0, MappedN0);
9999 EXPECT_NE(N1, MappedN1);
100100 EXPECT_EQ(ConstantAsMetadata::get(G1.get()), MappedN1->getOperand(1));
104104 EXPECT_TRUE(MappedN1->isResolved());
105105 }
106106
107 TEST(ValueMapperTest, MapMetadataUnresolved) {
107 TEST(ValueMapperTest, mapMDNodeUnresolved) {
108108 LLVMContext Context;
109109 TempMDTuple T = MDTuple::getTemporary(Context, None);
110110
111111 ValueToValueMapTy VM;
112 EXPECT_EQ(T.get(), MapMetadata(T.get(), VM, RF_NoModuleLevelChanges));
113 }
114
115 TEST(ValueMapperTest, MapMetadataDistinct) {
112 EXPECT_EQ(T.get(), ValueMapper(VM, RF_NoModuleLevelChanges).mapMDNode(*T));
113 }
114
115 TEST(ValueMapperTest, mapMDNodeDistinct) {
116116 LLVMContext Context;
117117 auto *D = MDTuple::getDistinct(Context, None);
118118
119119 {
120120 // The node should be cloned.
121121 ValueToValueMapTy VM;
122 EXPECT_NE(D, MapMetadata(D, VM, RF_None));
122 EXPECT_NE(D, ValueMapper(VM).mapMDNode(*D));
123123 }
124124 {
125125 // The node should be moved.
126126 ValueToValueMapTy VM;
127 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
128 }
129 }
130
131 TEST(ValueMapperTest, MapMetadataDistinctOperands) {
127 EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
128 }
129 }
130
131 TEST(ValueMapperTest, mapMDNodeDistinctOperands) {
132132 LLVMContext Context;
133133 Metadata *Old = MDTuple::getDistinct(Context, None);
134134 auto *D = MDTuple::getDistinct(Context, Old);
139139 VM.MD()[Old].reset(New);
140140
141141 // Make sure operands are updated.
142 EXPECT_EQ(D, MapMetadata(D, VM, RF_MoveDistinctMDs));
142 EXPECT_EQ(D, ValueMapper(VM, RF_MoveDistinctMDs).mapMDNode(*D));
143143 EXPECT_EQ(New, D->getOperand(0));
144144 }
145145
146 TEST(ValueMapperTest, MapMetadataSeeded) {
146 TEST(ValueMapperTest, mapMDNodeSeeded) {
147147 LLVMContext Context;
148148 auto *D = MDTuple::getDistinct(Context, None);
149149
153153
154154 VM.MD().insert(std::make_pair(D, TrackingMDRef(D)));
155155 EXPECT_EQ(D, *VM.getMappedMD(D));
156 EXPECT_EQ(D, MapMetadata(D, VM, RF_None));
157 }
158
159 TEST(ValueMapperTest, MapMetadataSeededWithNull) {
156 EXPECT_EQ(D, ValueMapper(VM).mapMDNode(*D));
157 }
158
159 TEST(ValueMapperTest, mapMDNodeSeededWithNull) {
160160 LLVMContext Context;
161161 auto *D = MDTuple::getDistinct(Context, None);
162162
166166
167167 VM.MD().insert(std::make_pair(D, TrackingMDRef()));
168168 EXPECT_EQ(nullptr, *VM.getMappedMD(D));
169 EXPECT_EQ(nullptr, MapMetadata(D, VM, RF_None));
170 }
171
172 TEST(ValueMapperTest, MapMetadataNullMapGlobalWithIgnoreMissingLocals) {
169 EXPECT_EQ(nullptr, ValueMapper(VM).mapMDNode(*D));
170 }
171
172 TEST(ValueMapperTest, mapMetadataNullMapGlobalWithIgnoreMissingLocals) {
173173 LLVMContext C;
174174 FunctionType *FTy =
175175 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
178178
179179 ValueToValueMapTy VM;
180180 RemapFlags Flags = RF_IgnoreMissingLocals | RF_NullMapMissingGlobalValues;
181 EXPECT_EQ(nullptr, MapValue(F.get(), VM, Flags));
182 }
183
184 TEST(ValueMapperTest, MapMetadataMDString) {
181 EXPECT_EQ(nullptr, ValueMapper(VM, Flags).mapValue(*F));
182 }
183
184 TEST(ValueMapperTest, mapMetadataMDString) {
185185 LLVMContext C;
186186 auto *S1 = MDString::get(C, "S1");
187187 ValueToValueMapTy VM;
188188
189189 // Make sure S1 maps to itself, but isn't memoized.
190 EXPECT_EQ(S1, MapMetadata(S1, VM));
190 EXPECT_EQ(S1, ValueMapper(VM).mapMetadata(*S1));
191191 EXPECT_EQ(None, VM.getMappedMD(S1));
192192
193193 // We still expect VM.MD() to be respected.
194194 auto *S2 = MDString::get(C, "S2");
195195 VM.MD()[S1].reset(S2);
196 EXPECT_EQ(S2, MapMetadata(S1, VM));
197 }
198
199 TEST(ValueMapperTest, MapMetadataGetMappedMD) {
196 EXPECT_EQ(S2, ValueMapper(VM).mapMetadata(*S1));
197 }
198
199 TEST(ValueMapperTest, mapMetadataGetMappedMD) {
200200 LLVMContext C;
201201 auto *N0 = MDTuple::get(C, None);
202202 auto *N1 = MDTuple::get(C, N0);
204204 // Make sure hasMD and getMappedMD work correctly.
205205 ValueToValueMapTy VM;
206206 EXPECT_FALSE(VM.hasMD());
207 EXPECT_EQ(N0, MapMetadata(N0, VM));
208 EXPECT_EQ(N1, MapMetadata(N1, VM));
207 EXPECT_EQ(N0, ValueMapper(VM).mapMetadata(*N0));
208 EXPECT_EQ(N1, ValueMapper(VM).mapMetadata(*N1));
209209 EXPECT_TRUE(VM.hasMD());
210210 ASSERT_NE(None, VM.getMappedMD(N0));
211211 ASSERT_NE(None, VM.getMappedMD(N1));
213213 EXPECT_EQ(N1, *VM.getMappedMD(N1));
214214 }
215215
216 TEST(ValueMapperTest, MapMetadataNoModuleLevelChanges) {
216 TEST(ValueMapperTest, mapMetadataNoModuleLevelChanges) {
217217 LLVMContext C;
218218 auto *N0 = MDTuple::get(C, None);
219219 auto *N1 = MDTuple::get(C, N0);
221221 // Nothing should be memoized when RF_NoModuleLevelChanges.
222222 ValueToValueMapTy VM;
223223 EXPECT_FALSE(VM.hasMD());
224 EXPECT_EQ(N0, MapMetadata(N0, VM, RF_NoModuleLevelChanges));
225 EXPECT_EQ(N1, MapMetadata(N1, VM, RF_NoModuleLevelChanges));
224 EXPECT_EQ(N0, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N0));
225 EXPECT_EQ(N1, ValueMapper(VM, RF_NoModuleLevelChanges).mapMetadata(*N1));
226226 EXPECT_FALSE(VM.hasMD());
227227 EXPECT_EQ(None, VM.getMappedMD(N0));
228228 EXPECT_EQ(None, VM.getMappedMD(N1));
229229 }
230230
231 TEST(ValueMapperTest, MapMetadataConstantAsMetadata) {
231 TEST(ValueMapperTest, mapMetadataConstantAsMetadata) {
232232 LLVMContext C;
233233 FunctionType *FTy =
234234 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
238238 auto *CAM = ConstantAsMetadata::get(F.get());
239239 {
240240 ValueToValueMapTy VM;
241 EXPECT_EQ(CAM, MapMetadata(CAM, VM));
241 EXPECT_EQ(CAM, ValueMapper(VM).mapMetadata(*CAM));
242242 EXPECT_TRUE(VM.MD().count(CAM));
243243 VM.MD().erase(CAM);
244 EXPECT_EQ(CAM, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
244 EXPECT_EQ(CAM, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
245245 EXPECT_TRUE(VM.MD().count(CAM));
246246
247247 auto *N = MDTuple::get(C, None);
248248 VM.MD()[CAM].reset(N);
249 EXPECT_EQ(N, MapMetadata(CAM, VM));
250 EXPECT_EQ(N, MapMetadata(CAM, VM, RF_IgnoreMissingLocals));
249 EXPECT_EQ(N, ValueMapper(VM).mapMetadata(*CAM));
250 EXPECT_EQ(N, ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*CAM));
251251 }
252252
253253 std::unique_ptr F2(
254254 Function::Create(FTy, GlobalValue::ExternalLinkage, "F2"));
255255 ValueToValueMapTy VM;
256256 VM[F.get()] = F2.get();
257 auto *F2MD = MapMetadata(CAM, VM);
257 auto *F2MD = ValueMapper(VM).mapMetadata(*CAM);
258258 EXPECT_TRUE(VM.MD().count(CAM));
259259 EXPECT_TRUE(F2MD);
260260 EXPECT_EQ(F2.get(), cast(F2MD)->getValue());
262262
263263 #ifdef GTEST_HAS_DEATH_TEST
264264 #ifndef NDEBUG
265 TEST(ValueMapperTest, MapMetadataLocalAsMetadata) {
265 TEST(ValueMapperTest, mapMetadataLocalAsMetadata) {
266266 LLVMContext C;
267267 FunctionType *FTy =
268268 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
270270 Function::Create(FTy, GlobalValue::ExternalLinkage, "F"));
271271 Argument &A = *F->arg_begin();
272272
273 // MapMetadata doesn't support LocalAsMetadata. The only valid container for
273 // mapMetadata doesn't support LocalAsMetadata. The only valid container for
274274 // LocalAsMetadata is a MetadataAsValue instance, so use it directly.
275275 auto *LAM = LocalAsMetadata::get(&A);
276276 ValueToValueMapTy VM;
277 EXPECT_DEATH(MapMetadata(LAM, VM), "Unexpected local metadata");
278 EXPECT_DEATH(MapMetadata(LAM, VM, RF_IgnoreMissingLocals),
277 EXPECT_DEATH(ValueMapper(VM).mapMetadata(*LAM), "Unexpected local metadata");
278 EXPECT_DEATH(ValueMapper(VM, RF_IgnoreMissingLocals).mapMetadata(*LAM),
279279 "Unexpected local metadata");
280280 }
281281 #endif
282282 #endif
283283
284 TEST(ValueMapperTest, MapValueLocalAsMetadata) {
284 TEST(ValueMapperTest, mapValueLocalAsMetadata) {
285285 LLVMContext C;
286286 FunctionType *FTy =
287287 FunctionType::get(Type::getVoidTy(C), Type::getInt8Ty(C), false);
304304 auto *N0 = MDTuple::get(C, None);
305305 auto *N0AV = MetadataAsValue::get(C, N0);
306306 ValueToValueMapTy VM;
307 EXPECT_EQ(N0AV, MapValue(MAV, VM));
308 EXPECT_EQ(nullptr, MapValue(MAV, VM, RF_IgnoreMissingLocals));
307 EXPECT_EQ(N0AV, ValueMapper(VM).mapValue(*MAV));
308 EXPECT_EQ(nullptr, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
309309 EXPECT_FALSE(VM.count(MAV));
310310 EXPECT_FALSE(VM.count(&A));
311311 EXPECT_EQ(None, VM.getMappedMD(LAM));
312312
313313 VM[MAV] = MAV;
314 EXPECT_EQ(MAV, MapValue(MAV, VM));
315 EXPECT_EQ(MAV, MapValue(MAV, VM, RF_IgnoreMissingLocals));
314 EXPECT_EQ(MAV, ValueMapper(VM).mapValue(*MAV));
315 EXPECT_EQ(MAV, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
316316 EXPECT_TRUE(VM.count(MAV));
317317 EXPECT_FALSE(VM.count(&A));
318318
319319 VM[MAV] = &A;
320 EXPECT_EQ(&A, MapValue(MAV, VM));
321 EXPECT_EQ(&A, MapValue(MAV, VM, RF_IgnoreMissingLocals));
320 EXPECT_EQ(&A, ValueMapper(VM).mapValue(*MAV));
321 EXPECT_EQ(&A, ValueMapper(VM, RF_IgnoreMissingLocals).mapValue(*MAV));
322322 EXPECT_TRUE(VM.count(MAV));
323323 EXPECT_FALSE(VM.count(&A));
324324 }
325325
326 TEST(ValueMapperTest, MapValueLocalAsMetadataToConstant) {
326 TEST(ValueMapperTest, mapValueLocalAsMetadataToConstant) {
327327 LLVMContext Context;
328328 auto *Int8 = Type::getInt8Ty(Context);
329329 FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context), Int8, false);
341341 auto *MDC = MetadataAsValue::get(Context, ValueAsMetadata::get(&C));
342342 EXPECT_TRUE(isa(MDA->getMetadata()));
343343 EXPECT_TRUE(isa(MDC->getMetadata()));
344 EXPECT_EQ(&C, MapValue(&A, VM));
345 EXPECT_EQ(MDC, MapValue(MDA, VM));
344 EXPECT_EQ(&C, ValueMapper(VM).mapValue(A));
345 EXPECT_EQ(MDC, ValueMapper(VM).mapValue(*MDA));
346346 }
347347
348348 } // end namespace