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 | New->IsNewDbgInfoFormat = M.IsNewDbgInfoFormat; |
65 | |
66 | // Loop over all of the global variables, making corresponding globals in the |
67 | // new module. Here we add them to the VMap and to the new Module. We |
68 | // don't worry about attributes or initializers, they will come later. |
69 | // |
70 | for (const GlobalVariable &I : M.globals()) { |
71 | GlobalVariable *NewGV = new GlobalVariable( |
72 | *New, I.getValueType(), I.isConstant(), I.getLinkage(), |
73 | (Constant *)nullptr, I.getName(), (GlobalVariable *)nullptr, |
74 | I.getThreadLocalMode(), I.getType()->getAddressSpace()); |
75 | NewGV->copyAttributesFrom(Src: &I); |
76 | VMap[&I] = NewGV; |
77 | } |
78 | |
79 | // Loop over the functions in the module, making external functions as before |
80 | for (const Function &I : M) { |
81 | Function *NF = |
82 | Function::Create(Ty: cast<FunctionType>(Val: I.getValueType()), Linkage: I.getLinkage(), |
83 | AddrSpace: I.getAddressSpace(), N: I.getName(), M: New.get()); |
84 | NF->copyAttributesFrom(Src: &I); |
85 | VMap[&I] = NF; |
86 | } |
87 | |
88 | // Loop over the aliases in the module |
89 | for (const GlobalAlias &I : M.aliases()) { |
90 | if (!ShouldCloneDefinition(&I)) { |
91 | // An alias cannot act as an external reference, so we need to create |
92 | // either a function or a global variable depending on the value type. |
93 | // FIXME: Once pointee types are gone we can probably pick one or the |
94 | // other. |
95 | GlobalValue *GV; |
96 | if (I.getValueType()->isFunctionTy()) |
97 | GV = Function::Create(Ty: cast<FunctionType>(Val: I.getValueType()), |
98 | Linkage: GlobalValue::ExternalLinkage, AddrSpace: I.getAddressSpace(), |
99 | N: I.getName(), M: New.get()); |
100 | else |
101 | GV = new GlobalVariable(*New, I.getValueType(), false, |
102 | GlobalValue::ExternalLinkage, nullptr, |
103 | I.getName(), nullptr, I.getThreadLocalMode(), |
104 | I.getType()->getAddressSpace()); |
105 | VMap[&I] = GV; |
106 | // We do not copy attributes (mainly because copying between different |
107 | // kinds of globals is forbidden), but this is generally not required for |
108 | // correctness. |
109 | continue; |
110 | } |
111 | auto *GA = GlobalAlias::create(Ty: I.getValueType(), |
112 | AddressSpace: I.getType()->getPointerAddressSpace(), |
113 | Linkage: I.getLinkage(), Name: I.getName(), Parent: New.get()); |
114 | GA->copyAttributesFrom(Src: &I); |
115 | VMap[&I] = GA; |
116 | } |
117 | |
118 | for (const GlobalIFunc &I : M.ifuncs()) { |
119 | // Defer setting the resolver function until after functions are cloned. |
120 | auto *GI = |
121 | GlobalIFunc::create(Ty: I.getValueType(), AddressSpace: I.getAddressSpace(), |
122 | Linkage: I.getLinkage(), Name: I.getName(), Resolver: nullptr, Parent: New.get()); |
123 | GI->copyAttributesFrom(Src: &I); |
124 | VMap[&I] = GI; |
125 | } |
126 | |
127 | // Now that all of the things that global variable initializer can refer to |
128 | // have been created, loop through and copy the global variable referrers |
129 | // over... We also set the attributes on the global now. |
130 | // |
131 | for (const GlobalVariable &G : M.globals()) { |
132 | GlobalVariable *GV = cast<GlobalVariable>(Val&: VMap[&G]); |
133 | |
134 | SmallVector<std::pair<unsigned, MDNode *>, 1> MDs; |
135 | G.getAllMetadata(MDs); |
136 | for (auto MD : MDs) |
137 | GV->addMetadata(KindID: MD.first, MD&: *MapMetadata(MD: MD.second, VM&: VMap)); |
138 | |
139 | if (G.isDeclaration()) |
140 | continue; |
141 | |
142 | if (!ShouldCloneDefinition(&G)) { |
143 | // Skip after setting the correct linkage for an external reference. |
144 | GV->setLinkage(GlobalValue::ExternalLinkage); |
145 | continue; |
146 | } |
147 | if (G.hasInitializer()) |
148 | GV->setInitializer(MapValue(V: G.getInitializer(), VM&: VMap)); |
149 | |
150 | copyComdat(Dst: GV, Src: &G); |
151 | } |
152 | |
153 | // Similarly, copy over function bodies now... |
154 | // |
155 | for (const Function &I : M) { |
156 | Function *F = cast<Function>(Val&: VMap[&I]); |
157 | |
158 | if (I.isDeclaration()) { |
159 | // Copy over metadata for declarations since we're not doing it below in |
160 | // CloneFunctionInto(). |
161 | SmallVector<std::pair<unsigned, MDNode *>, 1> MDs; |
162 | I.getAllMetadata(MDs); |
163 | for (auto MD : MDs) |
164 | F->addMetadata(KindID: MD.first, MD&: *MapMetadata(MD: MD.second, VM&: VMap)); |
165 | continue; |
166 | } |
167 | |
168 | if (!ShouldCloneDefinition(&I)) { |
169 | // Skip after setting the correct linkage for an external reference. |
170 | F->setLinkage(GlobalValue::ExternalLinkage); |
171 | // Personality function is not valid on a declaration. |
172 | F->setPersonalityFn(nullptr); |
173 | continue; |
174 | } |
175 | |
176 | Function::arg_iterator DestI = F->arg_begin(); |
177 | for (const Argument &J : I.args()) { |
178 | DestI->setName(J.getName()); |
179 | VMap[&J] = &*DestI++; |
180 | } |
181 | |
182 | SmallVector<ReturnInst *, 8> Returns; // Ignore returns cloned. |
183 | CloneFunctionInto(NewFunc: F, OldFunc: &I, VMap, Changes: CloneFunctionChangeType::ClonedModule, |
184 | Returns); |
185 | |
186 | if (I.hasPersonalityFn()) |
187 | F->setPersonalityFn(MapValue(V: I.getPersonalityFn(), VM&: VMap)); |
188 | |
189 | copyComdat(Dst: F, Src: &I); |
190 | } |
191 | |
192 | // And aliases |
193 | for (const GlobalAlias &I : M.aliases()) { |
194 | // We already dealt with undefined aliases above. |
195 | if (!ShouldCloneDefinition(&I)) |
196 | continue; |
197 | GlobalAlias *GA = cast<GlobalAlias>(Val&: VMap[&I]); |
198 | if (const Constant *C = I.getAliasee()) |
199 | GA->setAliasee(MapValue(V: C, VM&: VMap)); |
200 | } |
201 | |
202 | for (const GlobalIFunc &I : M.ifuncs()) { |
203 | GlobalIFunc *GI = cast<GlobalIFunc>(Val&: VMap[&I]); |
204 | if (const Constant *Resolver = I.getResolver()) |
205 | GI->setResolver(MapValue(V: Resolver, VM&: VMap)); |
206 | } |
207 | |
208 | // And named metadata.... |
209 | for (const NamedMDNode &NMD : M.named_metadata()) { |
210 | NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(Name: NMD.getName()); |
211 | for (const MDNode *N : NMD.operands()) |
212 | NewNMD->addOperand(M: MapMetadata(MD: N, VM&: VMap)); |
213 | } |
214 | |
215 | return New; |
216 | } |
217 | |
218 | extern "C" { |
219 | |
220 | LLVMModuleRef LLVMCloneModule(LLVMModuleRef M) { |
221 | return wrap(P: CloneModule(M: *unwrap(P: M)).release()); |
222 | } |
223 | |
224 | } |
225 | |