| 1 | //===- CloneModule.cpp - Clone an entire module ---------------------------===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| 9 | // This file implements the CloneModule interface which makes a copy of an |
| 10 | // entire module. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #include "llvm/IR/DerivedTypes.h" |
| 15 | #include "llvm/IR/Module.h" |
| 16 | #include "llvm/Transforms/Utils/Cloning.h" |
| 17 | #include "llvm/Transforms/Utils/ValueMapper.h" |
| 18 | using namespace llvm; |
| 19 | |
| 20 | namespace llvm { |
| 21 | class Constant; |
| 22 | } |
| 23 | |
| 24 | static void copyComdat(GlobalObject *Dst, const GlobalObject *Src) { |
| 25 | const Comdat *SC = Src->getComdat(); |
| 26 | if (!SC) |
| 27 | return; |
| 28 | Comdat *DC = Dst->getParent()->getOrInsertComdat(Name: SC->getName()); |
| 29 | DC->setSelectionKind(SC->getSelectionKind()); |
| 30 | Dst->setComdat(DC); |
| 31 | } |
| 32 | |
| 33 | /// This is not as easy as it might seem because we have to worry about making |
| 34 | /// copies of global variables and functions, and making their (initializers and |
| 35 | /// references, respectively) refer to the right globals. |
| 36 | /// |
| 37 | /// Cloning un-materialized modules is not currently supported, so any |
| 38 | /// modules initialized via lazy loading should be materialized before cloning |
| 39 | std::unique_ptr<Module> llvm::CloneModule(const Module &M) { |
| 40 | // Create the value map that maps things from the old module over to the new |
| 41 | // module. |
| 42 | ValueToValueMapTy VMap; |
| 43 | return CloneModule(M, VMap); |
| 44 | } |
| 45 | |
| 46 | std::unique_ptr<Module> llvm::CloneModule(const Module &M, |
| 47 | ValueToValueMapTy &VMap) { |
| 48 | return CloneModule(M, VMap, ShouldCloneDefinition: [](const GlobalValue *GV) { return true; }); |
| 49 | } |
| 50 | |
| 51 | std::unique_ptr<Module> llvm::CloneModule( |
| 52 | const Module &M, ValueToValueMapTy &VMap, |
| 53 | function_ref<bool(const GlobalValue *)> ShouldCloneDefinition) { |
| 54 | |
| 55 | assert(M.isMaterialized() && "Module must be materialized before cloning!" ); |
| 56 | |
| 57 | // First off, we need to create the new module. |
| 58 | std::unique_ptr<Module> New = |
| 59 | std::make_unique<Module>(args: M.getModuleIdentifier(), args&: M.getContext()); |
| 60 | New->setSourceFileName(M.getSourceFileName()); |
| 61 | New->setDataLayout(M.getDataLayout()); |
| 62 | New->setTargetTriple(M.getTargetTriple()); |
| 63 | New->setModuleInlineAsm(M.getModuleInlineAsm()); |
| 64 | |
| 65 | // Loop over all of the global variables, making corresponding globals in the |
| 66 | // new module. Here we add them to the VMap and to the new Module. We |
| 67 | // don't worry about attributes or initializers, they will come later. |
| 68 | // |
| 69 | for (const GlobalVariable &I : M.globals()) { |
| 70 | GlobalVariable *NewGV = new GlobalVariable( |
| 71 | *New, I.getValueType(), I.isConstant(), I.getLinkage(), |
| 72 | (Constant *)nullptr, I.getName(), (GlobalVariable *)nullptr, |
| 73 | I.getThreadLocalMode(), I.getType()->getAddressSpace()); |
| 74 | NewGV->copyAttributesFrom(Src: &I); |
| 75 | VMap[&I] = NewGV; |
| 76 | } |
| 77 | |
| 78 | // Loop over the functions in the module, making external functions as before |
| 79 | for (const Function &I : M) { |
| 80 | Function *NF = |
| 81 | Function::Create(Ty: cast<FunctionType>(Val: I.getValueType()), Linkage: I.getLinkage(), |
| 82 | AddrSpace: I.getAddressSpace(), N: I.getName(), M: New.get()); |
| 83 | NF->copyAttributesFrom(Src: &I); |
| 84 | VMap[&I] = NF; |
| 85 | } |
| 86 | |
| 87 | // Loop over the aliases in the module |
| 88 | for (const GlobalAlias &I : M.aliases()) { |
| 89 | if (!ShouldCloneDefinition(&I)) { |
| 90 | // An alias cannot act as an external reference, so we need to create |
| 91 | // either a function or a global variable depending on the value type. |
| 92 | // FIXME: Once pointee types are gone we can probably pick one or the |
| 93 | // other. |
| 94 | GlobalValue *GV; |
| 95 | if (I.getValueType()->isFunctionTy()) |
| 96 | GV = Function::Create(Ty: cast<FunctionType>(Val: I.getValueType()), |
| 97 | Linkage: GlobalValue::ExternalLinkage, AddrSpace: I.getAddressSpace(), |
| 98 | N: I.getName(), M: New.get()); |
| 99 | else |
| 100 | GV = new GlobalVariable(*New, I.getValueType(), false, |
| 101 | GlobalValue::ExternalLinkage, nullptr, |
| 102 | I.getName(), nullptr, I.getThreadLocalMode(), |
| 103 | I.getType()->getAddressSpace()); |
| 104 | VMap[&I] = GV; |
| 105 | // We do not copy attributes (mainly because copying between different |
| 106 | // kinds of globals is forbidden), but this is generally not required for |
| 107 | // correctness. |
| 108 | continue; |
| 109 | } |
| 110 | auto *GA = GlobalAlias::create(Ty: I.getValueType(), |
| 111 | AddressSpace: I.getType()->getPointerAddressSpace(), |
| 112 | Linkage: I.getLinkage(), Name: I.getName(), Parent: New.get()); |
| 113 | GA->copyAttributesFrom(Src: &I); |
| 114 | VMap[&I] = GA; |
| 115 | } |
| 116 | |
| 117 | for (const GlobalIFunc &I : M.ifuncs()) { |
| 118 | // Defer setting the resolver function until after functions are cloned. |
| 119 | auto *GI = |
| 120 | GlobalIFunc::create(Ty: I.getValueType(), AddressSpace: I.getAddressSpace(), |
| 121 | Linkage: I.getLinkage(), Name: I.getName(), Resolver: nullptr, Parent: New.get()); |
| 122 | GI->copyAttributesFrom(Src: &I); |
| 123 | VMap[&I] = GI; |
| 124 | } |
| 125 | |
| 126 | // Similarly, copy over function bodies now... |
| 127 | // |
| 128 | for (const Function &I : M) { |
| 129 | Function *F = cast<Function>(Val&: VMap[&I]); |
| 130 | |
| 131 | if (I.isDeclaration()) { |
| 132 | // Copy over metadata for declarations since we're not doing it below in |
| 133 | // CloneFunctionInto(). |
| 134 | SmallVector<std::pair<unsigned, MDNode *>, 1> MDs; |
| 135 | I.getAllMetadata(MDs); |
| 136 | for (auto MD : MDs) |
| 137 | F->addMetadata(KindID: MD.first, MD&: *MapMetadata(MD: MD.second, VM&: VMap)); |
| 138 | continue; |
| 139 | } |
| 140 | |
| 141 | if (!ShouldCloneDefinition(&I)) { |
| 142 | // Skip after setting the correct linkage for an external reference. |
| 143 | F->setLinkage(GlobalValue::ExternalLinkage); |
| 144 | // Personality function is not valid on a declaration. |
| 145 | F->setPersonalityFn(nullptr); |
| 146 | continue; |
| 147 | } |
| 148 | |
| 149 | Function::arg_iterator DestI = F->arg_begin(); |
| 150 | for (const Argument &J : I.args()) { |
| 151 | DestI->setName(J.getName()); |
| 152 | VMap[&J] = &*DestI++; |
| 153 | } |
| 154 | |
| 155 | SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. |
| 156 | CloneFunctionInto(NewFunc: F, OldFunc: &I, VMap, Changes: CloneFunctionChangeType::ClonedModule, |
| 157 | Returns); |
| 158 | |
| 159 | if (I.hasPersonalityFn()) |
| 160 | F->setPersonalityFn(MapValue(V: I.getPersonalityFn(), VM&: VMap)); |
| 161 | |
| 162 | copyComdat(Dst: F, Src: &I); |
| 163 | } |
| 164 | |
| 165 | // And aliases |
| 166 | for (const GlobalAlias &I : M.aliases()) { |
| 167 | // We already dealt with undefined aliases above. |
| 168 | if (!ShouldCloneDefinition(&I)) |
| 169 | continue; |
| 170 | GlobalAlias *GA = cast<GlobalAlias>(Val&: VMap[&I]); |
| 171 | if (const Constant *C = I.getAliasee()) |
| 172 | GA->setAliasee(MapValue(V: C, VM&: VMap)); |
| 173 | } |
| 174 | |
| 175 | for (const GlobalIFunc &I : M.ifuncs()) { |
| 176 | GlobalIFunc *GI = cast<GlobalIFunc>(Val&: VMap[&I]); |
| 177 | if (const Constant *Resolver = I.getResolver()) |
| 178 | GI->setResolver(MapValue(V: Resolver, VM&: VMap)); |
| 179 | } |
| 180 | |
| 181 | // And named metadata.... |
| 182 | for (const NamedMDNode &NMD : M.named_metadata()) { |
| 183 | NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(Name: NMD.getName()); |
| 184 | for (const MDNode *N : NMD.operands()) |
| 185 | NewNMD->addOperand(M: MapMetadata(MD: N, VM&: VMap)); |
| 186 | } |
| 187 | |
| 188 | // Now that all of the things that global variable initializer can refer to |
| 189 | // have been created, loop through and copy the global variable referrers |
| 190 | // over... We also set the attributes on the global now. |
| 191 | // |
| 192 | for (const GlobalVariable &G : M.globals()) { |
| 193 | GlobalVariable *GV = cast<GlobalVariable>(Val&: VMap[&G]); |
| 194 | |
| 195 | SmallVector<std::pair<unsigned, MDNode *>, 1> MDs; |
| 196 | G.getAllMetadata(MDs); |
| 197 | for (auto MD : MDs) |
| 198 | GV->addMetadata(KindID: MD.first, MD&: *MapMetadata(MD: MD.second, VM&: VMap)); |
| 199 | |
| 200 | if (G.isDeclaration()) |
| 201 | continue; |
| 202 | |
| 203 | if (!ShouldCloneDefinition(&G)) { |
| 204 | // Skip after setting the correct linkage for an external reference. |
| 205 | GV->setLinkage(GlobalValue::ExternalLinkage); |
| 206 | continue; |
| 207 | } |
| 208 | if (G.hasInitializer()) |
| 209 | GV->setInitializer(MapValue(V: G.getInitializer(), VM&: VMap)); |
| 210 | |
| 211 | copyComdat(Dst: GV, Src: &G); |
| 212 | } |
| 213 | |
| 214 | return New; |
| 215 | } |
| 216 | |
| 217 | extern "C" { |
| 218 | |
| 219 | LLVMModuleRef LLVMCloneModule(LLVMModuleRef M) { |
| 220 | return wrap(P: CloneModule(M: *unwrap(P: M)).release()); |
| 221 | } |
| 222 | |
| 223 | } |
| 224 | |