Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Linker/LinkModules.cpp
35233 views
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(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(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(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(ComdatName);
134
if (const auto *GA = dyn_cast_or_null<GlobalAlias>(GVal)) {
135
GVal = GA->getAliaseeObject();
136
if (!GVal)
137
// We cannot resolve the size of the aliasee yet.
138
return emitError("Linking COMDATs named '" + ComdatName +
139
"': COMDAT key involves incomputable alias size.");
140
}
141
142
GVar = dyn_cast_or_null<GlobalVariable>(GVal);
143
if (!GVar)
144
return emitError(
145
"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("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(DstM, ComdatName, DstGV) ||
190
getComdatLeader(*SrcM, ComdatName, SrcGV))
191
return true;
192
193
const DataLayout &DstDL = DstM.getDataLayout();
194
const DataLayout &SrcDL = SrcM->getDataLayout();
195
uint64_t DstSize = DstDL.getTypeAllocSize(DstGV->getValueType());
196
uint64_t SrcSize = SrcDL.getTypeAllocSize(SrcGV->getValueType());
197
if (Result == Comdat::SelectionKind::ExactMatch) {
198
if (SrcGV->getInitializer() != DstGV->getInitializer())
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 {
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(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, SSK, 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(Dest.getValueType());
296
uint64_t SrcSize = DL.getTypeAllocSize(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("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(&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>(DGV);
347
auto *SGVar = dyn_cast<GlobalVariable>(&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(DAlign.valueOrOne(), SAlign.valueOrOne());
360
361
SGVar->setAlignment(Align);
362
DGVar->setAlignment(Align);
363
}
364
}
365
366
GlobalValue::VisibilityTypes Visibility =
367
getMinVisibility(DGV->getVisibility(), GV.getVisibility());
368
DGV->setVisibility(Visibility);
369
GV.setVisibility(Visibility);
370
371
GlobalValue::UnnamedAddr UnnamedAddr = GlobalValue::getMinUnnamedAddr(
372
DGV->getUnnamedAddr(), 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(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
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(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(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
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(C))
434
return;
435
if (GV.use_empty()) {
436
GV.eraseFromParent();
437
return;
438
}
439
440
if (auto *F = dyn_cast<Function>(&GV)) {
441
F->deleteBody();
442
} else if (auto *Var = dyn_cast<GlobalVariable>(&GV)) {
443
Var->setInitializer(nullptr);
444
} else {
445
auto &Alias = cast<GlobalAlias>(GV);
446
Module &M = *Alias.getParent();
447
GlobalValue *Declaration;
448
if (auto *FTy = dyn_cast<FunctionType>(Alias.getValueType())) {
449
Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, "", &M);
450
} else {
451
Declaration =
452
new GlobalVariable(M, Alias.getValueType(), /*isConstant*/ false,
453
GlobalValue::ExternalLinkage,
454
/*Initializer*/ nullptr);
455
}
456
Declaration->takeName(&Alias);
457
Alias.replaceAllUsesWith(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(&C))
470
continue;
471
Comdat::SelectionKind SK;
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
483
Module::ComdatSymTabType &ComdatSymTab = DstM.getComdatSymbolTable();
484
Module::ComdatSymTabType::iterator DstCI = ComdatSymTab.find(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(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(DstM.aliases()))
496
dropReplacedComdat(GV, ReplacedDstComdats);
497
498
for (GlobalVariable &GV : llvm::make_early_inc_range(DstM.globals()))
499
dropReplacedComdat(GV, ReplacedDstComdats);
500
501
for (Function &GV : llvm::make_early_inc_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(GO);
509
for (const Comdat *C : NonPrevailingComdats) {
510
SmallVector<GlobalObject *> ToUpdate;
511
for (GlobalObject *GO : C->getUsers())
512
if (GO->hasPrivateLinkage() && !AliasedGlobals.contains(GO))
513
ToUpdate.push_back(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(&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
// 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(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
// 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>(GV)) {
561
auto *NewVar = new GlobalVariable(*Var->getParent(), Var->getValueType(),
562
Var->isConstant(), Var->getLinkage(),
563
Var->getInitializer());
564
NewVar->copyAttributesFrom(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(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)
594
Internalize.insert(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(std::move(SrcM), ValuesToLink.getArrayRef(),
602
IRMover::LazyCallback(
603
[this](GlobalValue &GV, IRMover::ValueAdder Add) {
604
addLazyFor(GV, Add);
605
}),
606
/* IsPerformingImport */ false)) {
607
handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) {
608
DstM.getContext().diagnose(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(std::move(Src), Flags, std::move(InternalizeCallback));
645
}
646
647
//===----------------------------------------------------------------------===//
648
// C API.
649
//===----------------------------------------------------------------------===//
650
651
LLVMBool LLVMLinkModules2(LLVMModuleRef Dest, LLVMModuleRef Src) {
652
Module *D = unwrap(Dest);
653
std::unique_ptr<Module> M(unwrap(Src));
654
return Linker::linkModules(*D, std::move(M));
655
}
656
657