Index: include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h =================================================================== --- include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h +++ include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h @@ -46,7 +46,7 @@ class LambdaMaterializer final : public ValueMaterializer { public: LambdaMaterializer(MaterializerFtor M) : M(std::move(M)) {} - Value *materializeDeclFor(Value *V) final { return M(V); } + Value *materialize(Value *V) final { return M(V); } private: MaterializerFtor M; Index: include/llvm/Transforms/Utils/ValueMapper.h =================================================================== --- include/llvm/Transforms/Utils/ValueMapper.h +++ include/llvm/Transforms/Utils/ValueMapper.h @@ -47,15 +47,9 @@ ValueMaterializer &operator=(const ValueMaterializer &) = default; public: - /// The client should implement this method if they want to generate a mapped - /// Value on demand. For example, if linking lazily. - virtual Value *materializeDeclFor(Value *V) = 0; - - /// If the data being mapped is recursive, the above function can map just - /// the declaration and this is called to compute the initializer. It is - /// called after the mapping is recorded, so it doesn't need to worry about - /// recursion. - virtual void materializeInitFor(GlobalValue *New, GlobalValue *Old); + /// This method can be implemented to generate a mapped Value on demand. For + /// example, if linking lazily. Returns null if the value is not materialized. + virtual Value *materialize(Value *V) = 0; }; /// These are flags that the value mapping APIs allow. Index: lib/Linker/IRMover.cpp =================================================================== --- lib/Linker/IRMover.cpp +++ lib/Linker/IRMover.cpp @@ -349,8 +349,7 @@ public: GlobalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} - Value *materializeDeclFor(Value *V) override; - void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; + Value *materialize(Value *V) override; }; class LocalValueMaterializer final : public ValueMaterializer { @@ -358,8 +357,7 @@ public: LocalValueMaterializer(IRLinker &TheIRLinker) : TheIRLinker(TheIRLinker) {} - Value *materializeDeclFor(Value *V) override; - void materializeInitFor(GlobalValue *New, GlobalValue *Old) override; + Value *materialize(Value *V) override; }; /// Type of the Metadata map in \a ValueToValueMapTy. @@ -490,8 +488,7 @@ ~IRLinker() { SharedMDs = std::move(*ValueMap.getMDMap()); } bool run(); - Value *materializeDeclFor(Value *V, bool ForAlias); - void materializeInitFor(GlobalValue *New, GlobalValue *Old, bool ForAlias); + Value *materialize(Value *V, bool ForAlias); }; } @@ -516,45 +513,38 @@ } } -Value *GlobalValueMaterializer::materializeDeclFor(Value *V) { - return TheIRLinker.materializeDeclFor(V, false); +Value *GlobalValueMaterializer::materialize(Value *SGV) { + return TheIRLinker.materialize(SGV, false); } -void GlobalValueMaterializer::materializeInitFor(GlobalValue *New, - GlobalValue *Old) { - TheIRLinker.materializeInitFor(New, Old, false); +Value *LocalValueMaterializer::materialize(Value *SGV) { + return TheIRLinker.materialize(SGV, true); } -Value *LocalValueMaterializer::materializeDeclFor(Value *V) { - return TheIRLinker.materializeDeclFor(V, true); -} - -void LocalValueMaterializer::materializeInitFor(GlobalValue *New, - GlobalValue *Old) { - TheIRLinker.materializeInitFor(New, Old, true); -} - -Value *IRLinker::materializeDeclFor(Value *V, bool ForAlias) { +Value *IRLinker::materialize(Value *V, bool ForAlias) { auto *SGV = dyn_cast(V); if (!SGV) return nullptr; - return linkGlobalValueProto(SGV, ForAlias); -} + Constant *NewProto = linkGlobalValueProto(SGV, ForAlias); + if (!NewProto) + return NewProto; + + GlobalValue *New = dyn_cast(NewProto); + if (!New) + return NewProto; -void IRLinker::materializeInitFor(GlobalValue *New, GlobalValue *Old, - bool ForAlias) { // If we already created the body, just return. if (auto *F = dyn_cast(New)) { if (!F->isDeclaration()) - return; + return New; } else if (auto *V = dyn_cast(New)) { if (V->hasInitializer() || V->hasAppendingLinkage()) - return; + return New; } else { auto *A = cast(New); if (A->getAliasee()) - return; + return New; } // When linking a global for an alias, it will always be linked. However we @@ -565,11 +555,13 @@ // different, it means that the value already had a definition in the // destination module (linkonce for instance), but we need a new definition // for the alias ("New" will be different. - if (ForAlias && ValueMap.lookup(Old) == New) - return; + if (ForAlias && ValueMap.lookup(SGV) == New) + return New; + + if (ForAlias || shouldLink(New, *SGV)) + linkGlobalValueBody(*New, *SGV); - if (ForAlias || shouldLink(New, *Old)) - linkGlobalValueBody(*New, *Old); + return New; } /// Loop through the global variables in the src module and merge them into the Index: lib/Transforms/Utils/ValueMapper.cpp =================================================================== --- lib/Transforms/Utils/ValueMapper.cpp +++ lib/Transforms/Utils/ValueMapper.cpp @@ -29,8 +29,6 @@ // Out of line method to get vtable etc for class. void ValueMapTypeRemapper::anchor() {} void ValueMaterializer::anchor() {} -void ValueMaterializer::materializeInitFor(GlobalValue *New, GlobalValue *Old) { -} namespace { @@ -363,12 +361,8 @@ // If we have a materializer and it can materialize a value, use that. if (auto *Materializer = getMaterializer()) { - if (Value *NewV = - Materializer->materializeDeclFor(const_cast(V))) { + if (Value *NewV = Materializer->materialize(const_cast(V))) { getVM()[V] = NewV; - if (auto *NewGV = dyn_cast(NewV)) - Materializer->materializeInitFor( - NewGV, cast(const_cast(V))); return NewV; } }