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 (C)

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.