LLVM: lib/Linker/LinkModules.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
22using namespace llvm;
23
24namespace {
25
26enum class LinkFrom { Dst, Src, Both };
27
28
29
30class ModuleLinker {
31 IRMover &Mover;
32 std::unique_ptr SrcM;
33
34 SetVector<GlobalValue *> ValuesToLink;
35
36
37 unsigned Flags;
38
39
40 StringSet<> Internalize;
41
42
43
44
45 std::function<void(Module &, const StringSet<> &)> InternalizeCallback;
46
47
48
49
50
52
55
56 bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,
57 const GlobalValue &Src);
58
59
60 bool emitError(const Twine &Message) {
61 SrcM->getContext().diagnose(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,
71 LinkFrom &From);
72 DenseMap<const Comdat *, std::pair<Comdat::SelectionKind, LinkFrom>>
73 ComdatsChosen;
75 LinkFrom &From);
76
77 DenseMap<const Comdat *, std::vector<GlobalValue *>> LazyComdatMembers;
78
79
80
81 GlobalValue *getLinkedToGlobal(const GlobalValue *SrcGV) {
82 Module &DstM = Mover.getModule();
83
84
86 return nullptr;
87
88
90 if (!DGV)
91 return nullptr;
92
93
94
96 return nullptr;
97
98
99 return DGV;
100 }
101
102
103
104 void dropReplacedComdat(GlobalValue &GV,
105 const DenseSet<const Comdat *> &ReplacedDstComdats);
106
107 bool linkIfNeeded(GlobalValue &GV, SmallVectorImpl<GlobalValue *> &GVToClone);
108
109public:
110 ModuleLinker(IRMover &Mover, std::unique_ptr 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}
119
130
131bool ModuleLinker::getComdatLeader(Module &M, StringRef ComdatName,
133 const GlobalValue *GVal = M.getNamedValue(ComdatName);
136 if (!GVal)
137
138 return emitError("Linking COMDATs named '" + ComdatName +
139 "': COMDAT key involves incomputable alias size.");
140 }
141
143 if (!GVar)
144 return emitError(
145 "Linking COMDATs named '" + ComdatName +
146 "': GlobalVariable required for data dependent selection!");
147
148 return false;
149}
150
151bool ModuleLinker::computeResultingSelectionKind(StringRef ComdatName,
155 LinkFrom &From) {
157
158
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) {
171 } else {
172 return emitError("Linking COMDATs named '" + ComdatName +
173 "': invalid selection kinds!");
174 }
175
176 switch (Result) {
177 case Comdat::SelectionKind::Any:
178
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(DstM, ComdatName, DstGV) ||
190 getComdatLeader(*SrcM, ComdatName, SrcGV))
191 return true;
192
194 const DataLayout &SrcDL = SrcM->getDataLayout();
197 if (Result == Comdat::SelectionKind::ExactMatch) {
199 return emitError("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("Linking COMDATs named '" + ComdatName +
207 "': SameSize violated!");
208 From = LinkFrom::Dst;
209 } else {
211 }
212 break;
213 }
214 }
215
216 return false;
217}
218
219bool ModuleLinker::getComdatResult(const Comdat *SrcC,
221 LinkFrom &From) {
224 StringRef ComdatName = SrcC->getName();
227
228 if (DstCI == ComdatSymTab.end()) {
229
230 From = LinkFrom::Src;
232 return false;
233 }
234
235 const Comdat *DstC = &DstCI->second;
237 return computeResultingSelectionKind(ComdatName, SSK, DSK, Result, From);
238}
239
240bool ModuleLinker::shouldLinkFromSource(bool &LinkFromSrc,
241 const GlobalValue &Dest,
242 const GlobalValue &Src) {
243
244
245 if (shouldOverrideFromSrc()) {
246 LinkFromSrc = true;
247 return false;
248 }
249
250
252 LinkFromSrc = true;
253 return false;
254 }
255
256 bool SrcIsDeclaration = Src.isDeclarationForLinker();
258
259 if (SrcIsDeclaration) {
260
261
262 if (Src.hasDLLImportStorageClass()) {
263
264 LinkFromSrc = DestIsDeclaration;
265 return false;
266 }
267
269 LinkFromSrc = true;
270 return false;
271 }
272
273 LinkFromSrc = !Src.isDeclaration() && Dest.isDeclaration();
274 return false;
275 }
276
277 if (DestIsDeclaration) {
278
279 LinkFromSrc = true;
280 return false;
281 }
282
283 if (Src.hasCommonLinkage()) {
285 LinkFromSrc = true;
286 return false;
287 }
288
290 LinkFromSrc = false;
291 return false;
292 }
293
295 uint64_t DestSize = DL.getTypeAllocSize(Dest.getValueType());
296 uint64_t SrcSize = DL.getTypeAllocSize(Src.getValueType());
297 LinkFromSrc = SrcSize > DestSize;
298 return false;
299 }
300
301 if (Src.isWeakForLinker()) {
304
306 LinkFromSrc = true;
307 return false;
308 }
309
310 LinkFromSrc = false;
311 return false;
312 }
313
315 assert(Src.hasExternalLinkage());
316 LinkFromSrc = true;
317 return false;
318 }
319
320 assert(!Src.hasExternalWeakLinkage());
323 "Unexpected linkage type!");
324 return emitError("Linking globals named '" + Src.getName() +
325 "': symbol multiply defined!");
326}
327
328bool ModuleLinker::linkIfNeeded(GlobalValue &GV,
329 SmallVectorImpl<GlobalValue *> &GVToClone) {
330 GlobalValue *DGV = getLinkedToGlobal(&GV);
331
332 if (shouldLinkOnlyNeeded()) {
333
335
336
337 if (!DGV)
338 return false;
339
341 return false;
342 }
343 }
344
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)
360
361 SGVar->setAlignment(Align);
362 DGVar->setAlignment(Align);
363 }
364 }
365
370
375 }
376
377 if (!DGV && !shouldOverrideFromSrc() &&
380 return false;
381
383 return false;
384
385 LinkFrom ComdatFrom = LinkFrom::Dst;
386 if (const Comdat *SC = GV.getComdat()) {
387 std::tie(std::ignore, ComdatFrom) = ComdatsChosen[SC];
388 if (ComdatFrom == LinkFrom::Dst)
389 return false;
390 }
391
392 bool LinkFromSrc = true;
393 if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, GV))
394 return true;
395 if (DGV && ComdatFrom == LinkFrom::Both)
396 GVToClone.push_back(LinkFromSrc ? DGV : &GV);
397 if (LinkFromSrc)
398 ValuesToLink.insert(&GV);
399 return false;
400}
401
403
405 !shouldLinkOnlyNeeded())
406 return;
407
408 if (InternalizeCallback)
411
412 const Comdat *SC = GV.getComdat();
413 if (!SC)
414 return;
415 for (GlobalValue *GV2 : LazyComdatMembers[SC]) {
416 GlobalValue *DGV = getLinkedToGlobal(GV2);
417 bool LinkFromSrc = true;
418 if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))
419 return;
420 if (!LinkFromSrc)
421 continue;
422 if (InternalizeCallback)
423 Internalize.insert(GV2->getName());
424 Add(*GV2);
425 }
426}
427
428void ModuleLinker::dropReplacedComdat(
429 GlobalValue &GV, const DenseSet<const Comdat *> &ReplacedDstComdats) {
431 if ()
432 return;
433 if (!ReplacedDstComdats.count(C))
434 return;
437 return;
438 }
439
441 F->deleteBody();
443 Var->setInitializer(nullptr);
444 } else {
446 Module &M = *Alias.getParent();
447 GlobalValue *Declaration;
450 } else {
451 Declaration =
452 new GlobalVariable(M, Alias.getValueType(), false,
454 nullptr);
455 }
456 Declaration->takeName(&Alias);
457 Alias.replaceAllUsesWith(Declaration);
458 Alias.eraseFromParent();
459 }
460}
461
462bool ModuleLinker::run() {
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(&C))
470 continue;
472 LinkFrom From;
473 if (getComdatResult(&C, SK, From))
474 return true;
475 ComdatsChosen[&C] = std::make_pair(SK, From);
476
477 if (From == LinkFrom::Dst)
478 NonPrevailingComdats.insert(&C);
479
480 if (From != LinkFrom::Src)
481 continue;
482
485 if (DstCI == ComdatSymTab.end())
486 continue;
487
488
489 const Comdat *DstC = &DstCI->second;
490 ReplacedDstComdats.insert(DstC);
491 }
492
493
494
496 dropReplacedComdat(GV, ReplacedDstComdats);
497
499 dropReplacedComdat(GV, ReplacedDstComdats);
500
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(GO);
509 for (const Comdat *C : NonPrevailingComdats) {
511 for (GlobalObject *GO : C->getUsers())
512 if (GO->hasPrivateLinkage() && !AliasedGlobals.contains(GO))
514 for (GlobalObject *GO : ToUpdate) {
516 GO->setComdat(nullptr);
517 }
518 }
519 }
520
521 for (GlobalVariable &GV : SrcM->globals())
523 if (const Comdat *SC = GV.getComdat())
524 LazyComdatMembers[SC].push_back(&GV);
525
526 for (Function &SF : *SrcM)
527 if (SF.hasLinkOnceLinkage())
528 if (const Comdat *SC = SF.getComdat())
529 LazyComdatMembers[SC].push_back(&SF);
530
531 for (GlobalAlias &GA : SrcM->aliases())
532 if (GA.hasLinkOnceLinkage())
533 if (const Comdat *SC = GA.getComdat())
534 LazyComdatMembers[SC].push_back(&GA);
535
536
537
539 for (GlobalVariable &GV : SrcM->globals())
540 if (linkIfNeeded(GV, GVToClone))
541 return true;
542
543 for (Function &SF : *SrcM)
544 if (linkIfNeeded(SF, GVToClone))
545 return true;
546
547 for (GlobalAlias &GA : SrcM->aliases())
548 if (linkIfNeeded(GA, GVToClone))
549 return true;
550
551 for (GlobalIFunc &GI : SrcM->ifuncs())
552 if (linkIfNeeded(GI, GVToClone))
553 return true;
554
555
556
557
558
559 for (GlobalValue *GV : GVToClone) {
561 auto *NewVar = new GlobalVariable(*Var->getParent(), Var->getValueType(),
562 Var->isConstant(), Var->getLinkage(),
563 Var->getInitializer());
564 NewVar->copyAttributesFrom(Var);
567 NewVar->setDSOLocal(true);
568 NewVar->setComdat(Var->getComdat());
569 if (Var->getParent() != &Mover.getModule())
570 ValuesToLink.insert(NewVar);
571 } else {
572 emitError("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(GV2);
584 bool LinkFromSrc = true;
585 if (DGV && shouldLinkFromSource(LinkFromSrc, *DGV, *GV2))
586 return true;
587 if (LinkFromSrc)
588 ValuesToLink.insert(GV2);
589 }
590 }
591
592 if (InternalizeCallback) {
593 for (GlobalValue *GV : ValuesToLink)
595 }
596
597
598
599 bool HasErrors = false;
601 Mover.move(std::move(SrcM), ValuesToLink.getArrayRef(),
604 addLazyFor(GV, Add);
605 }),
606 false)) {
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
622
624 std::unique_ptr 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
633
634
635
636
637
638
639
641 Module &Dest, std::unique_ptr Src, unsigned Flags,
642 std::function<void(Module &, const StringSet<> &)> InternalizeCallback) {
644 return L.linkInModule(std::move(Src), Flags, std::move(InternalizeCallback));
645}
646
647
648
649
650
653 std::unique_ptr M(unwrap(Src));
655}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Module.h This file contains the declarations for the Module class.
static GlobalValue::VisibilityTypes getMinVisibility(GlobalValue::VisibilityTypes A, GlobalValue::VisibilityTypes B)
Definition LinkModules.cpp:121
Machine Check Debug Module
This file implements a set that has insertion order iteration characteristics.
LLVM_ABI StringRef getName() const
SelectionKind getSelectionKind() const
LLVM_ABI TypeSize getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
virtual std::string message() const
Return the error message as a string.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
bool hasLinkOnceLinkage() const
bool hasExternalLinkage() const
VisibilityTypes getVisibility() const
static bool isLocalLinkage(LinkageTypes Linkage)
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
LinkageTypes getLinkage() const
void setUnnamedAddr(UnnamedAddr Val)
bool hasLocalLinkage() const
LLVM_ABI const Comdat * getComdat() const
bool hasExternalWeakLinkage() const
bool isDeclarationForLinker() const
static UnnamedAddr getMinUnnamedAddr(UnnamedAddr A, UnnamedAddr B)
LLVM_ABI const GlobalObject * getAliaseeObject() const
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing module and deletes it.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
@ DefaultVisibility
The GV is visible.
@ HiddenVisibility
The GV is hidden.
@ ProtectedVisibility
The GV is protected.
void setVisibility(VisibilityTypes V)
LLVM_ABI const DataLayout & getDataLayout() const
Get the data layout of the module this global belongs to.
bool hasWeakLinkage() const
bool hasCommonLinkage() const
UnnamedAddr getUnnamedAddr() const
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
bool hasAppendingLinkage() const
bool hasAvailableExternallyLinkage() const
@ PrivateLinkage
Like Internal, but omit from symbol table.
@ ExternalLinkage
Externally visible function.
@ AvailableExternallyLinkage
Available for inspection, not emission.
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI Error move(std::unique_ptr< Module > Src, ArrayRef< GlobalValue * > ValuesToLink, LazyCallback AddLazyFor, bool IsPerformingImport)
Move in the provide values in ValuesToLink from Src.
std::function< void(GlobalValue &)> ValueAdder
llvm::unique_function< void(GlobalValue &GV, ValueAdder Add)> LazyCallback
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
@ OverrideFromSrc
Have symbols from Src shadow those in the Dest.
LLVM_ABI bool linkInModule(std::unique_ptr< Module > Src, unsigned Flags=Flags::None, std::function< void(Module &, const StringSet<> &)> InternalizeCallback={})
Link Src into the composite.
Definition LinkModules.cpp:623
static LLVM_ABI bool linkModules(Module &Dest, std::unique_ptr< Module > Src, unsigned Flags=Flags::None, std::function< void(Module &, const StringSet<> &)> InternalizeCallback={})
This function links two modules together, with the resulting Dest module modified to be the composite...
Definition LinkModules.cpp:640
LLVM_ABI Linker(Module &M)
Definition LinkModules.cpp:621
A Module instance is used to store all the information related to an LLVM module.
LLVMContext & getContext() const
Get the global data context.
const ComdatSymTabType & getComdatSymbolTable() const
Get the Module's symbol table for COMDATs (constant).
iterator_range< alias_iterator > aliases()
iterator_range< global_iterator > globals()
GlobalValue * getNamedValue(StringRef Name) const
Return the global value in the module with the specified name, of arbitrary type.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
size_type size() const
Determine the number of elements in the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
void push_back(const T &Elt)
iterator find(StringRef Key)
StringMapIterBase< Comdat, false > iterator
StringRef - Represent a constant reference to a string, i.e.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
LLVM_C_ABI LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src)
Definition LinkModules.cpp:651
struct LLVMOpaqueModule * LLVMModuleRef
The top-level container for all other LLVM Intermediate Representation (IR) objects.
This file contains the declaration of the Comdat class, which represents a single COMDAT in LLVM.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto dyn_cast_or_null(const Y &Val)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
Attribute unwrap(LLVMAttributeRef Attr)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
Align valueOrOne() const
For convenience, returns a valid alignment or 1 if undefined.