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 | |