1 | //===- lib/Linker/LinkModules.cpp - Module Linker Implementation ----------===// |
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 LLVM module linker. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "LinkDiagnosticInfo.h" |
14 | #include "llvm-c/Linker.h" |
15 | #include "llvm/ADT/SetVector.h" |
16 | #include "llvm/IR/Comdat.h" |
17 | #include "llvm/IR/GlobalValue.h" |
18 | #include "llvm/IR/LLVMContext.h" |
19 | #include "llvm/IR/Module.h" |
20 | #include "llvm/Linker/Linker.h" |
21 | #include "llvm/Support/Error.h" |
22 | using namespace llvm; |
23 | |
24 | namespace { |
25 | |
26 | enum class LinkFrom { Dst, Src, Both }; |
27 | |
28 | /// This is an implementation class for the LinkModules function, which is the |
29 | /// entrypoint for this file. |
30 | class ModuleLinker { |
31 | IRMover &Mover; |
32 | std::unique_ptr<Module> SrcM; |
33 | |
34 | SetVector<GlobalValue *> ValuesToLink; |
35 | |
36 | /// For symbol clashes, prefer those from Src. |
37 | unsigned Flags; |
38 | |
39 | /// List of global value names that should be internalized. |
40 | StringSet<> Internalize; |
41 | |
42 | /// Function that will perform the actual internalization. The reason for a |
43 | /// callback is that the linker cannot call internalizeModule without |
44 | /// creating a circular dependency between IPO and the linker. |
45 | std::function<void(Module &, const StringSet<> &)> InternalizeCallback; |
46 | |
47 | /// Used as the callback for lazy linking. |
48 | /// The mover has just hit GV and we have to decide if it, and other members |
49 | /// of the same comdat, should be linked. Every member to be linked is passed |
50 | /// to Add. |
51 | void addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add); |
52 | |
53 | bool shouldOverrideFromSrc() { return Flags & Linker::OverrideFromSrc; } |
54 | bool shouldLinkOnlyNeeded() { return Flags & Linker::LinkOnlyNeeded; } |
55 | |
56 | bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest, |
57 | const GlobalValue &Src); |
58 | |
59 | /// Should we have mover and linker error diag info? |
60 | bool emitError(const Twine &Message) { |
61 | SrcM->getContext().diagnose(DI: LinkDiagnosticInfo(DS_Error, Message)); |
62 | return true; |
63 | } |
64 | |
65 | bool getComdatLeader(Module &M, StringRef ComdatName, |
66 | const GlobalVariable *&GVar); |
67 | bool computeResultingSelectionKind(StringRef ComdatName, |
68 | Comdat::SelectionKind Src, |
69 | Comdat::SelectionKind Dst, |
70 | Comdat::SelectionKind &Result, |
71 | LinkFrom &From); |
72 | DenseMap<const Comdat *, std::pair<Comdat::SelectionKind, LinkFrom>> |
73 | ComdatsChosen; |
74 | bool getComdatResult(const Comdat *SrcC, Comdat::SelectionKind &SK, |
75 | LinkFrom &From); |
76 | // Keep track of the lazy linked global members of each comdat in source. |
77 | DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers; |
78 | |
79 | /// Given a global in the source module, return the global in the |
80 | /// destination module that is being linked to, if any. |
81 | GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) { |
82 | Module &DstM = Mover.getModule(); |
83 | // If the source has no name it can't link. If it has local linkage, |
84 | // there is no name match-up going on. |
85 | if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(Linkage: SrcGV->getLinkage())) |
86 | return nullptr; |
87 | |
88 | // Otherwise see if we have a match in the destination module's symtab. |
89 | GlobalValue *DGV = DstM.getNamedValue(Name: SrcGV->getName()); |
90 | if (!DGV) |
91 | return nullptr; |
92 | |
93 | // If we found a global with the same name in the dest module, but it has |
94 | // internal linkage, we are really not doing any linkage here. |
95 | if (DGV->hasLocalLinkage()) |
96 | return nullptr; |
97 | |
98 | // Otherwise, we do in fact link to the destination global. |
99 | return DGV; |
100 | } |
101 | |
102 | /// Drop GV if it is a member of a comdat that we are dropping. |
103 | /// This can happen with COFF's largest selection kind. |
104 | void dropReplacedComdat(GlobalValue &GV, |
105 | const DenseSet<const Comdat *> &ReplacedDstComdats); |
106 | |
107 | bool linkIfNeeded(GlobalValue &GV, SmallVectorImpl<GlobalValue *> &GVToClone); |
108 | |
109 | public: |
110 | ModuleLinker(IRMover &Mover, std::unique_ptr<Module> SrcM, unsigned Flags, |
111 | std::function<void(Module &, const StringSet<> &)> |
112 | InternalizeCallback = {}) |
113 | : Mover(Mover), SrcM(std::move(SrcM)), Flags(Flags), |
114 | InternalizeCallback(std::move(InternalizeCallback)) {} |
115 | |
116 | bool run(); |
117 | }; |
118 | } // namespace |
119 | |
120 | static GlobalValue::VisibilityTypes |
121 | getMinVisibility(GlobalValue::VisibilityTypes A, |
122 | GlobalValue::VisibilityTypes B) { |
123 | if (A == GlobalValue::HiddenVisibility || B == GlobalValue::HiddenVisibility) |
124 | return GlobalValue::HiddenVisibility; |
125 | if (A == GlobalValue::ProtectedVisibility || |
126 | B == GlobalValue::ProtectedVisibility) |
127 | return GlobalValue::ProtectedVisibility; |
128 | return GlobalValue::DefaultVisibility; |
129 | } |
130 | |
131 | bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName, |
132 | const GlobalVariable *&GVar) { |
133 | const GlobalValue *GVal = M.getNamedValue(Name: ComdatName); |
134 | if (const auto *GA = dyn_cast_or_null<GlobalAlias>(Val: GVal)) { |
135 | GVal = GA->getAliaseeObject(); |
136 | if (!GVal) |
137 | // We cannot resolve the size of the aliasee yet. |
138 | return emitError(Message: "Linking COMDATs named '" + ComdatName + |
139 | "': COMDAT key involves incomputable alias size." ); |
140 | } |
141 | |
142 | GVar = dyn_cast_or_null<GlobalVariable>(Val: GVal); |
143 | if (!GVar) |
144 | return emitError( |
145 | Message: "Linking COMDATs named '" + ComdatName + |
146 | "': GlobalVariable required for data dependent selection!" ); |
147 | |
148 | return false; |
149 | } |
150 | |
151 | bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName, |
152 | Comdat::SelectionKind Src, |
153 | Comdat::SelectionKind Dst, |
154 | Comdat::SelectionKind &Result, |
155 | LinkFrom &From) { |
156 | Module &DstM = Mover.getModule(); |
157 | // The ability to mix Comdat::SelectionKind::Any with |
158 | // Comdat::SelectionKind::Largest is a behavior that comes from COFF. |
159 | bool DstAnyOrLargest = Dst == Comdat::SelectionKind::Any || |
160 | Dst == Comdat::SelectionKind::Largest; |
161 | bool SrcAnyOrLargest = Src == Comdat::SelectionKind::Any || |
162 | Src == Comdat::SelectionKind::Largest; |
163 | if (DstAnyOrLargest && SrcAnyOrLargest) { |
164 | if (Dst == Comdat::SelectionKind::Largest || |
165 | Src == Comdat::SelectionKind::Largest) |
166 | Result = Comdat::SelectionKind::Largest; |
167 | else |
168 | Result = Comdat::SelectionKind::Any; |
169 | } else if (Src == Dst) { |
170 | Result = Dst; |
171 | } else { |
172 | return emitError(Message: "Linking COMDATs named '" + ComdatName + |
173 | "': invalid selection kinds!" ); |
174 | } |
175 | |
176 | switch (Result) { |
177 | case Comdat::SelectionKind::Any: |
178 | // Go with Dst. |
179 | From = LinkFrom::Dst; |
180 | break; |
181 | case Comdat::SelectionKind::NoDeduplicate: |
182 | From = LinkFrom::Both; |
183 | break; |
184 | case Comdat::SelectionKind::ExactMatch: |
185 | case Comdat::SelectionKind::Largest: |
186 | case Comdat::SelectionKind::SameSize: { |
187 | const GlobalVariable *DstGV; |
188 | const GlobalVariable *SrcGV; |
189 | if (getComdatLeader(M&: DstM, ComdatName, GVar&: DstGV) || |
190 | getComdatLeader(M&: *SrcM, ComdatName, GVar&: SrcGV)) |
191 | return true; |
192 | |
193 | const DataLayout &DstDL = DstM.getDataLayout(); |
194 | const DataLayout &SrcDL = SrcM->getDataLayout(); |
195 | uint64_t DstSize = DstDL.getTypeAllocSize(Ty: DstGV->getValueType()); |
196 | uint64_t SrcSize = SrcDL.getTypeAllocSize(Ty: SrcGV->getValueType()); |
197 | if (Result == Comdat::SelectionKind::ExactMatch) { |
198 | if (SrcGV->getInitializer() != DstGV->getInitializer()) |
199 | return emitError(Message: "Linking COMDATs named '" + ComdatName + |
200 | "': ExactMatch violated!" ); |
201 | From = LinkFrom::Dst; |
202 | } else if (Result == Comdat::SelectionKind::Largest) { |
203 | From = SrcSize > DstSize ? LinkFrom::Src : LinkFrom::Dst; |
204 | } else if (Result == Comdat::SelectionKind::SameSize) { |
205 | if (SrcSize != DstSize) |
206 | return emitError(Message: "Linking COMDATs named '" + ComdatName + |
207 | "': SameSize violated!" ); |
208 | From = LinkFrom::Dst; |
209 | } else { |
210 | llvm_unreachable("unknown selection kind" ); |
211 | } |
212 | break; |
213 | } |
214 | } |
215 | |
216 | return false; |
217 | } |
218 | |
219 | bool ModuleLinker::getComdatResult(const Comdat *SrcC, |
220 | Comdat::SelectionKind &Result, |
221 | LinkFrom &From) { |
222 | Module &DstM = Mover.getModule(); |
223 | Comdat::SelectionKind SSK = SrcC->getSelectionKind(); |
224 | StringRef ComdatName = SrcC->getName(); |
225 | Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); |
226 | Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(Key: ComdatName); |
227 | |
228 | if (DstCI == ComdatSymTab.end()) { |
229 | // Use the comdat if it is only available in one of the modules. |
230 | From = LinkFrom::Src; |
231 | Result = SSK; |
232 | return false; |
233 | } |
234 | |
235 | const Comdat *DstC = &DstCI->second; |
236 | Comdat::SelectionKind DSK = DstC->getSelectionKind(); |
237 | return computeResultingSelectionKind(ComdatName, Src: SSK, Dst: DSK, Result, From); |
238 | } |
239 | |
240 | bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc, |
241 | const GlobalValue &Dest, |
242 | const GlobalValue &Src) { |
243 | |
244 | // Should we unconditionally use the Src? |
245 | if (shouldOverrideFromSrc()) { |
246 | LinkFromSrc = true; |
247 | return false; |
248 | } |
249 | |
250 | // We always have to add Src if it has appending linkage. |
251 | if (Src.hasAppendingLinkage() || Dest.hasAppendingLinkage()) { |
252 | LinkFromSrc = true; |
253 | return false; |
254 | } |
255 | |
256 | bool SrcIsDeclaration = Src.isDeclarationForLinker(); |
257 | bool DestIsDeclaration = Dest.isDeclarationForLinker(); |
258 | |
259 | if (SrcIsDeclaration) { |
260 | // If Src is external or if both Src & Dest are external.. Just link the |
261 | // external globals, we aren't adding anything. |
262 | if (Src.hasDLLImportStorageClass()) { |
263 | // If one of GVs is marked as DLLImport, result should be dllimport'ed. |
264 | LinkFromSrc = DestIsDeclaration; |
265 | return false; |
266 | } |
267 | // If the Dest is weak, use the source linkage. |
268 | if (Dest.hasExternalWeakLinkage()) { |
269 | LinkFromSrc = true; |
270 | return false; |
271 | } |
272 | // Link an available_externally over a declaration. |
273 | LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration(); |
274 | return false; |
275 | } |
276 | |
277 | if (DestIsDeclaration) { |
278 | // If Dest is external but Src is not: |
279 | LinkFromSrc = true; |
280 | return false; |
281 | } |
282 | |
283 | if (Src.hasCommonLinkage()) { |
284 | if (Dest.hasLinkOnceLinkage() || Dest.hasWeakLinkage()) { |
285 | LinkFromSrc = true; |
286 | return false; |
287 | } |
288 | |
289 | if (!Dest.hasCommonLinkage()) { |
290 | LinkFromSrc = false; |
291 | return false; |
292 | } |
293 | |
294 | const DataLayout &DL = Dest.getDataLayout(); |
295 | uint64_t DestSize = DL.getTypeAllocSize(Ty: Dest.getValueType()); |
296 | uint64_t SrcSize = DL.getTypeAllocSize(Ty: Src.getValueType()); |
297 | LinkFromSrc = SrcSize > DestSize; |
298 | return false; |
299 | } |
300 | |
301 | if (Src.isWeakForLinker()) { |
302 | assert(!Dest.hasExternalWeakLinkage()); |
303 | assert(!Dest.hasAvailableExternallyLinkage()); |
304 | |
305 | if (Dest.hasLinkOnceLinkage() && Src.hasWeakLinkage()) { |
306 | LinkFromSrc = true; |
307 | return false; |
308 | } |
309 | |
310 | LinkFromSrc = false; |
311 | return false; |
312 | } |
313 | |
314 | if (Dest.isWeakForLinker()) { |
315 | assert(Src.hasExternalLinkage()); |
316 | LinkFromSrc = true; |
317 | return false; |
318 | } |
319 | |
320 | assert(!Src.hasExternalWeakLinkage()); |
321 | assert(!Dest.hasExternalWeakLinkage()); |
322 | assert(Dest.hasExternalLinkage() && Src.hasExternalLinkage() && |
323 | "Unexpected linkage type!" ); |
324 | return emitError(Message: "Linking globals named '" + Src.getName() + |
325 | "': symbol multiply defined!" ); |
326 | } |
327 | |
328 | bool ModuleLinker::linkIfNeeded(GlobalValue &GV, |
329 | SmallVectorImpl<GlobalValue *> &GVToClone) { |
330 | GlobalValue *DGV = getLinkedToGlobal(SrcGV: &GV); |
331 | |
332 | if (shouldLinkOnlyNeeded()) { |
333 | // Always import variables with appending linkage. |
334 | if (!GV.hasAppendingLinkage()) { |
335 | // Don't import globals unless they are referenced by the destination |
336 | // module. |
337 | if (!DGV) |
338 | return false; |
339 | // Don't import globals that are already defined in the destination module |
340 | if (!DGV->isDeclaration()) |
341 | return false; |
342 | } |
343 | } |
344 | |
345 | if (DGV && !GV.hasLocalLinkage() && !GV.hasAppendingLinkage()) { |
346 | auto *DGVar = dyn_cast<GlobalVariable>(Val: DGV); |
347 | auto *SGVar = dyn_cast<GlobalVariable>(Val: &GV); |
348 | if (DGVar && SGVar) { |
349 | if (DGVar->isDeclaration() && SGVar->isDeclaration() && |
350 | (!DGVar->isConstant() || !SGVar->isConstant())) { |
351 | DGVar->setConstant(false); |
352 | SGVar->setConstant(false); |
353 | } |
354 | if (DGVar->hasCommonLinkage() && SGVar->hasCommonLinkage()) { |
355 | MaybeAlign DAlign = DGVar->getAlign(); |
356 | MaybeAlign SAlign = SGVar->getAlign(); |
357 | MaybeAlign Align = std::nullopt; |
358 | if (DAlign || SAlign) |
359 | Align = std::max(a: DAlign.valueOrOne(), b: SAlign.valueOrOne()); |
360 | |
361 | SGVar->setAlignment(Align); |
362 | DGVar->setAlignment(Align); |
363 | } |
364 | } |
365 | |
366 | GlobalValue::VisibilityTypes Visibility = |
367 | getMinVisibility(A: DGV->getVisibility(), B: GV.getVisibility()); |
368 | DGV->setVisibility(Visibility); |
369 | GV.setVisibility(Visibility); |
370 | |
371 | GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr( |
372 | A: DGV->getUnnamedAddr(), B: GV.getUnnamedAddr()); |
373 | DGV->setUnnamedAddr(UnnamedAddr); |
374 | GV.setUnnamedAddr(UnnamedAddr); |
375 | } |
376 | |
377 | if (!DGV && !shouldOverrideFromSrc() && |
378 | (GV.hasLocalLinkage() || GV.hasLinkOnceLinkage() || |
379 | GV.hasAvailableExternallyLinkage())) |
380 | return false; |
381 | |
382 | if (GV.isDeclaration()) |
383 | return false; |
384 | |
385 | LinkFrom ComdatFrom = LinkFrom::Dst; |
386 | if (const Comdat *SC = GV.getComdat()) { |
387 | std::tie(args: std::ignore, args&: ComdatFrom) = ComdatsChosen[SC]; |
388 | if (ComdatFrom == LinkFrom::Dst) |
389 | return false; |
390 | } |
391 | |
392 | bool LinkFromSrc = true; |
393 | if (DGV && shouldLinkFromSource(LinkFromSrc, Dest: *DGV, Src: GV)) |
394 | return true; |
395 | if (DGV && ComdatFrom == LinkFrom::Both) |
396 | GVToClone.push_back(Elt: LinkFromSrc ? DGV : &GV); |
397 | if (LinkFromSrc) |
398 | ValuesToLink.insert(X: &GV); |
399 | return false; |
400 | } |
401 | |
402 | void ModuleLinker::addLazyFor(GlobalValue &GV, const IRMover::ValueAdder &Add) { |
403 | // Add these to the internalize list |
404 | if (!GV.hasLinkOnceLinkage() && !GV.hasAvailableExternallyLinkage() && |
405 | !shouldLinkOnlyNeeded()) |
406 | return; |
407 | |
408 | if (InternalizeCallback) |
409 | Internalize.insert(key: GV.getName()); |
410 | Add(GV); |
411 | |
412 | const Comdat *SC = GV.getComdat(); |
413 | if (!SC) |
414 | return; |
415 | for (GlobalValue *GV2 : LazyComdatMembers[SC]) { |
416 | GlobalValue *DGV = getLinkedToGlobal(SrcGV: GV2); |
417 | bool LinkFromSrc = true; |
418 | if (DGV && shouldLinkFromSource(LinkFromSrc, Dest: *DGV, Src: *GV2)) |
419 | return; |
420 | if (!LinkFromSrc) |
421 | continue; |
422 | if (InternalizeCallback) |
423 | Internalize.insert(key: GV2->getName()); |
424 | Add(*GV2); |
425 | } |
426 | } |
427 | |
428 | void ModuleLinker::dropReplacedComdat( |
429 | GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) { |
430 | Comdat *C = GV.getComdat(); |
431 | if (!C) |
432 | return; |
433 | if (!ReplacedDstComdats.count(V: C)) |
434 | return; |
435 | if (GV.use_empty()) { |
436 | GV.eraseFromParent(); |
437 | return; |
438 | } |
439 | |
440 | if (auto *F = dyn_cast<Function>(Val: &GV)) { |
441 | F->deleteBody(); |
442 | } else if (auto *Var = dyn_cast<GlobalVariable>(Val: &GV)) { |
443 | Var->setInitializer(nullptr); |
444 | } else { |
445 | auto &Alias = cast<GlobalAlias>(Val&: GV); |
446 | Module &M = *Alias.getParent(); |
447 | GlobalValue *Declaration; |
448 | if (auto *FTy = dyn_cast<FunctionType>(Val: Alias.getValueType())) { |
449 | Declaration = Function::Create(Ty: FTy, Linkage: GlobalValue::ExternalLinkage, N: "" , M: &M); |
450 | } else { |
451 | Declaration = |
452 | new GlobalVariable(M, Alias.getValueType(), /*isConstant*/ false, |
453 | GlobalValue::ExternalLinkage, |
454 | /*Initializer*/ nullptr); |
455 | } |
456 | Declaration->takeName(V: &Alias); |
457 | Alias.replaceAllUsesWith(V: Declaration); |
458 | Alias.eraseFromParent(); |
459 | } |
460 | } |
461 | |
462 | bool ModuleLinker::run() { |
463 | Module &DstM = Mover.getModule(); |
464 | DenseSet<const Comdat *> ReplacedDstComdats; |
465 | DenseSet<const Comdat *> NonPrevailingComdats; |
466 | |
467 | for (const auto &SMEC : SrcM->getComdatSymbolTable()) { |
468 | const Comdat &C = SMEC.getValue(); |
469 | if (ComdatsChosen.count(Val: &C)) |
470 | continue; |
471 | Comdat::SelectionKind SK; |
472 | LinkFrom From; |
473 | if (getComdatResult(SrcC: &C, Result&: SK, From)) |
474 | return true; |
475 | ComdatsChosen[&C] = std::make_pair(x&: SK, y&: From); |
476 | |
477 | if (From == LinkFrom::Dst) |
478 | NonPrevailingComdats.insert(V: &C); |
479 | |
480 | if (From != LinkFrom::Src) |
481 | continue; |
482 | |
483 | Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable(); |
484 | Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(Key: C.getName()); |
485 | if (DstCI == ComdatSymTab.end()) |
486 | continue; |
487 | |
488 | // The source comdat is replacing the dest one. |
489 | const Comdat *DstC = &DstCI->second; |
490 | ReplacedDstComdats.insert(V: DstC); |
491 | } |
492 | |
493 | // Alias have to go first, since we are not able to find their comdats |
494 | // otherwise. |
495 | for (GlobalAlias &GV : llvm::make_early_inc_range(Range: DstM.aliases())) |
496 | dropReplacedComdat(GV, ReplacedDstComdats); |
497 | |
498 | for (GlobalVariable &GV : llvm::make_early_inc_range(Range: DstM.globals())) |
499 | dropReplacedComdat(GV, ReplacedDstComdats); |
500 | |
501 | for (Function &GV : llvm::make_early_inc_range(Range&: DstM)) |
502 | dropReplacedComdat(GV, ReplacedDstComdats); |
503 | |
504 | if (!NonPrevailingComdats.empty()) { |
505 | DenseSet<GlobalObject *> AliasedGlobals; |
506 | for (auto &GA : SrcM->aliases()) |
507 | if (GlobalObject *GO = GA.getAliaseeObject(); GO && GO->getComdat()) |
508 | AliasedGlobals.insert(V: GO); |
509 | for (const Comdat *C : NonPrevailingComdats) { |
510 | SmallVector<GlobalObject *> ToUpdate; |
511 | for (GlobalObject *GO : C->getUsers()) |
512 | if (GO->hasPrivateLinkage() && !AliasedGlobals.contains(V: GO)) |
513 | ToUpdate.push_back(Elt: GO); |
514 | for (GlobalObject *GO : ToUpdate) { |
515 | GO->setLinkage(GlobalValue::AvailableExternallyLinkage); |
516 | GO->setComdat(nullptr); |
517 | } |
518 | } |
519 | } |
520 | |
521 | for (GlobalVariable &GV : SrcM->globals()) |
522 | if (GV.hasLinkOnceLinkage()) |
523 | if (const Comdat *SC = GV.getComdat()) |
524 | LazyComdatMembers[SC].push_back(x: &GV); |
525 | |
526 | for (Function &SF : *SrcM) |
527 | if (SF.hasLinkOnceLinkage()) |
528 | if (const Comdat *SC = SF.getComdat()) |
529 | LazyComdatMembers[SC].push_back(x: &SF); |
530 | |
531 | for (GlobalAlias &GA : SrcM->aliases()) |
532 | if (GA.hasLinkOnceLinkage()) |
533 | if (const Comdat *SC = GA.getComdat()) |
534 | LazyComdatMembers[SC].push_back(x: &GA); |
535 | |
536 | // Insert all of the globals in src into the DstM module... without linking |
537 | // initializers (which could refer to functions not yet mapped over). |
538 | SmallVector<GlobalValue *, 0> GVToClone; |
539 | for (GlobalVariable &GV : SrcM->globals()) |
540 | if (linkIfNeeded(GV, GVToClone)) |
541 | return true; |
542 | |
543 | for (Function &SF : *SrcM) |
544 | if (linkIfNeeded(GV&: SF, GVToClone)) |
545 | return true; |
546 | |
547 | for (GlobalAlias &GA : SrcM->aliases()) |
548 | if (linkIfNeeded(GV&: GA, GVToClone)) |
549 | return true; |
550 | |
551 | for (GlobalIFunc &GI : SrcM->ifuncs()) |
552 | if (linkIfNeeded(GV&: GI, GVToClone)) |
553 | return true; |
554 | |
555 | // For a variable in a comdat nodeduplicate, its initializer should be |
556 | // preserved (its content may be implicitly used by other members) even if |
557 | // symbol resolution does not pick it. Clone it into an unnamed private |
558 | // variable. |
559 | for (GlobalValue *GV : GVToClone) { |
560 | if (auto *Var = dyn_cast<GlobalVariable>(Val: GV)) { |
561 | auto *NewVar = new GlobalVariable(*Var->getParent(), Var->getValueType(), |
562 | Var->isConstant(), Var->getLinkage(), |
563 | Var->getInitializer()); |
564 | NewVar->copyAttributesFrom(Src: Var); |
565 | NewVar->setVisibility(GlobalValue::DefaultVisibility); |
566 | NewVar->setLinkage(GlobalValue::PrivateLinkage); |
567 | NewVar->setDSOLocal(true); |
568 | NewVar->setComdat(Var->getComdat()); |
569 | if (Var->getParent() != &Mover.getModule()) |
570 | ValuesToLink.insert(X: NewVar); |
571 | } else { |
572 | emitError(Message: "linking '" + GV->getName() + |
573 | "': non-variables in comdat nodeduplicate are not handled" ); |
574 | } |
575 | } |
576 | |
577 | for (unsigned I = 0; I < ValuesToLink.size(); ++I) { |
578 | GlobalValue *GV = ValuesToLink[I]; |
579 | const Comdat *SC = GV->getComdat(); |
580 | if (!SC) |
581 | continue; |
582 | for (GlobalValue *GV2 : LazyComdatMembers[SC]) { |
583 | GlobalValue *DGV = getLinkedToGlobal(SrcGV: GV2); |
584 | bool LinkFromSrc = true; |
585 | if (DGV && shouldLinkFromSource(LinkFromSrc, Dest: *DGV, Src: *GV2)) |
586 | return true; |
587 | if (LinkFromSrc) |
588 | ValuesToLink.insert(X: GV2); |
589 | } |
590 | } |
591 | |
592 | if (InternalizeCallback) { |
593 | for (GlobalValue *GV : ValuesToLink) |
594 | Internalize.insert(key: GV->getName()); |
595 | } |
596 | |
597 | // FIXME: Propagate Errors through to the caller instead of emitting |
598 | // diagnostics. |
599 | bool HasErrors = false; |
600 | if (Error E = |
601 | Mover.move(Src: std::move(SrcM), ValuesToLink: ValuesToLink.getArrayRef(), |
602 | AddLazyFor: IRMover::LazyCallback( |
603 | [this](GlobalValue &GV, IRMover::ValueAdder Add) { |
604 | addLazyFor(GV, Add); |
605 | }), |
606 | /* IsPerformingImport */ false)) { |
607 | handleAllErrors(E: std::move(E), Handlers: [&](ErrorInfoBase &EIB) { |
608 | DstM.getContext().diagnose(DI: LinkDiagnosticInfo(DS_Error, EIB.message())); |
609 | HasErrors = true; |
610 | }); |
611 | } |
612 | if (HasErrors) |
613 | return true; |
614 | |
615 | if (InternalizeCallback) |
616 | InternalizeCallback(DstM, Internalize); |
617 | |
618 | return false; |
619 | } |
620 | |
621 | Linker::Linker(Module &M) : Mover(M) {} |
622 | |
623 | bool Linker::linkInModule( |
624 | std::unique_ptr<Module> Src, unsigned Flags, |
625 | std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { |
626 | ModuleLinker ModLinker(Mover, std::move(Src), Flags, |
627 | std::move(InternalizeCallback)); |
628 | return ModLinker.run(); |
629 | } |
630 | |
631 | //===----------------------------------------------------------------------===// |
632 | // LinkModules entrypoint. |
633 | //===----------------------------------------------------------------------===// |
634 | |
635 | /// This function links two modules together, with the resulting Dest module |
636 | /// modified to be the composite of the two input modules. If an error occurs, |
637 | /// true is returned and ErrorMsg (if not null) is set to indicate the problem. |
638 | /// Upon failure, the Dest module could be in a modified state, and shouldn't be |
639 | /// relied on to be consistent. |
640 | bool Linker::linkModules( |
641 | Module &Dest, std::unique_ptr<Module> Src, unsigned Flags, |
642 | std::function<void(Module &, const StringSet<> &)> InternalizeCallback) { |
643 | Linker L(Dest); |
644 | return L.linkInModule(Src: std::move(Src), Flags, InternalizeCallback: std::move(InternalizeCallback)); |
645 | } |
646 | |
647 | //===----------------------------------------------------------------------===// |
648 | // C API. |
649 | //===----------------------------------------------------------------------===// |
650 | |
651 | LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) { |
652 | Module *D = unwrap(P: Dest); |
653 | std::unique_ptr<Module> M(unwrap(P: Src)); |
654 | return Linker::linkModules(Dest&: *D, Src: std::move(M)); |
655 | } |
656 | |