LLVM: lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

29using namespace llvm;

30

31namespace {

32

33

34static bool allowPromotionAlias(const std::string &Name) {

35

36

37

38 for (const char &C : Name) {

39 if (isAlnum(C) || C == '_' || C == '.')

40 continue;

41 return false;

42 }

43 return true;

44}

45

46

47

52 if (!ExportGV.hasLocalLinkage())

53 continue;

54

55 auto Name = ExportGV.getName();

57 if (!PromoteExtra.count(&ExportGV)) {

59 if (!ImportGV)

60 continue;

64 continue;

65 }

66 }

67

68 std::string OldName = Name.str();

69 std::string NewName = (Name + ModuleId).str();

70

71 if (const auto *C = ExportGV.getComdat())

72 if (C->getName() == Name)

74

75 ExportGV.setName(NewName);

78

79 if (ImportGV) {

80 ImportGV->setName(NewName);

82 }

83

84 if (isa(&ExportGV) && allowPromotionAlias(OldName)) {

85

86

87 std::string Alias =

88 ".lto_set_conditional " + OldName + "," + NewName + "\n";

90 }

91 }

92

93 if (!RenamedComdats.empty())

95 if (auto *C = GO.getComdat()) {

96 auto Replacement = RenamedComdats.find(C);

97 if (Replacement != RenamedComdats.end())

98 GO.setComdat(Replacement->second);

99 }

100}

101

102

103

104

105

106

109 auto ExternalizeTypeId = [&](CallInst *CI, unsigned ArgNo) {

112

114 Metadata *&GlobalMD = LocalToGlobal[MD];

115 if (!GlobalMD) {

116 std::string NewName = (Twine(LocalToGlobal.size()) + ModuleId).str();

117 GlobalMD = MDString::get(M.getContext(), NewName);

118 }

119

122 }

123 };

124

127 for (const Use &U : TypeTestFunc->uses()) {

129 ExternalizeTypeId(CI, 1);

130 }

131 }

132

133 if (Function *PublicTypeTestFunc =

135 for (const Use &U : PublicTypeTestFunc->uses()) {

137 ExternalizeTypeId(CI, 1);

138 }

139 }

140

141 if (Function *TypeCheckedLoadFunc =

143 for (const Use &U : TypeCheckedLoadFunc->uses()) {

145 ExternalizeTypeId(CI, 2);

146 }

147 }

148

150 &M, Intrinsic::type_checked_load_relative)) {

151 for (const Use &U : TypeCheckedLoadRelativeFunc->uses()) {

153 ExternalizeTypeId(CI, 2);

154 }

155 }

156

157 for (GlobalObject &GO : M.global_objects()) {

159 GO.getMetadata(LLVMContext::MD_type, MDs);

160

161 GO.eraseMetadata(LLVMContext::MD_type);

162 for (auto *MD : MDs) {

163 auto I = LocalToGlobal.find(MD->getOperand(1));

164 if (I == LocalToGlobal.end()) {

165 GO.addMetadata(LLVMContext::MD_type, *MD);

166 continue;

167 }

168 GO.addMetadata(

169 LLVMContext::MD_type,

170 *MDNode::get(M.getContext(), {MD->getOperand(0), I->second}));

171 }

172 }

173}

174

175

176

177void simplifyExternals(Module &M) {

180

182 if (F.isDeclaration() && F.use_empty()) {

183 F.eraseFromParent();

184 continue;

185 }

186

187 if (F.isDeclaration() || F.getFunctionType() == EmptyFT ||

188

189 F.getName().starts_with("llvm."))

190 continue;

191

194 F.getAddressSpace(), "", &M);

196

197 NewF->setAttributes(AttributeList::get(M.getContext(),

198 AttributeList::FunctionIndex,

199 F.getAttributes().getFnAttrs()));

201 F.replaceAllUsesWith(NewF);

202 F.eraseFromParent();

203 }

204

206 if (I.use_empty())

207 I.eraseFromParent();

208 else

209 assert(I.getResolverFunction() && "ifunc misses its resolver function");

210 }

211

213 if (GV.isDeclaration() && GV.use_empty()) {

214 GV.eraseFromParent();

215 continue;

216 }

217 }

218}

219

220static void

221filterModule(Module *M,

223 std::vector<GlobalValue *> V;

224 for (GlobalValue &GV : M->global_values())

225 if (!ShouldKeepDefinition(&GV))

226 V.push_back(&GV);

227

230 GV->eraseFromParent();

231}

232

235 return Fn(F);

237 return;

238 for (Value *Op : C->operands())

240}

241

242

243

244static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM,

245 bool CompilerUsed) {

247

249

250 for (auto *V : Used) {

252 if (GV && !GV->isDeclaration())

254 }

255

256 if (CompilerUsed)

258 else

260}

261

262#ifndef NDEBUG

263static bool enableUnifiedLTO(Module &M) {

264 bool UnifiedLTO = false;

265 if (auto *MD =

267 UnifiedLTO = MD->getZExtValue();

268 return UnifiedLTO;

269}

270#endif

271

272bool mustEmitToMergedModule(const GlobalValue *GV) {

273

274

275 return GV->getName() == "__cfi_check";

276}

277

278

279

280

281void splitAndWriteThinLTOBitcode(

284 const bool ShouldPreserveUseListOrder) {

286 if (ModuleId.empty()) {

287 assert(!enableUnifiedLTO(M));

288

289

294 false);

295

296 if (ThinLinkOS)

297

298

299 WriteBitcodeToFile(M, *ThinLinkOS, ShouldPreserveUseListOrder, &Index,

300 false);

301

302 return;

303 }

304

305 promoteTypeIds(M, ModuleId);

306

307

308

309

310

311

312

313 auto HasTypeMetadata = [](const GlobalObject *GO) {

314 if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated))

317 if (AssocGO->hasMetadata(LLVMContext::MD_type))

318 return true;

319 return GO->hasMetadata(LLVMContext::MD_type);

320 };

321

322

323

324

325

326

327

328

329

330

331

332

333

335

336

339 if (!GV.isDeclaration() && HasTypeMetadata(&GV)) {

341 MergedMComdats.insert(C);

342 forEachVirtualFunction(GV.getInitializer(), [&](Function *F) {

343 auto *RT = dyn_cast(F->getReturnType());

344 if (!RT || RT->getBitWidth() > 64 || F->arg_empty() ||

345 !F->arg_begin()->use_empty())

346 return;

347 for (auto &Arg : drop_begin(F->args())) {

348 auto *ArgT = dyn_cast(Arg.getType());

349 if (!ArgT || ArgT->getBitWidth() > 64)

350 return;

351 }

352 if (F->isDeclaration() &&

354 .doesNotAccessMemory())

355 EligibleVirtualFns.insert(F);

356 });

357 }

358

360 std::unique_ptr MergedM(

363 if (MergedMComdats.count(C))

364 return true;

365 if (mustEmitToMergedModule(GV))

366 return true;

368 return EligibleVirtualFns.count(F);

369 if (auto *GVar =

371 return HasTypeMetadata(GVar);

372 return false;

373 }));

375 MergedM->setModuleInlineAsm("");

376

377

378

379 cloneUsedGlobalVariables(M, *MergedM, false);

380 cloneUsedGlobalVariables(M, *MergedM, true);

381

383 if (F.isDeclaration() && !mustEmitToMergedModule(&F)) {

384

385

386

388 F.setComdat(nullptr);

389 }

390

392 for (auto &F : M)

393 if ((F.hasLocalLinkage() || F.hasAddressTaken()) && HasTypeMetadata(&F))

395 for (auto &A : M.aliases())

397 if (HasTypeMetadata(F))

399

400

401

402 filterModule(&M, [&](const GlobalValue *GV) {

404 if (HasTypeMetadata(GVar))

405 return false;

407 if (MergedMComdats.count(C))

408 return false;

409 if (mustEmitToMergedModule(GV))

410 return false;

411 return true;

412 });

413

414 promoteInternals(*MergedM, M, ModuleId, CfiFunctions);

415 promoteInternals(M, *MergedM, ModuleId, CfiFunctions);

416

417 auto &Ctx = MergedM->getContext();

419 for (auto *V : CfiFunctions) {

422 F.getMetadata(LLVMContext::MD_type, Types);

423

429 else if (F.hasExternalWeakLinkage())

431 else

437 }

438

439 if(!CfiFunctionMDs.empty()) {

440 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("cfi.functions");

441 for (auto *MD : CfiFunctionMDs)

443 }

444

446 for (auto &A : M.aliases()) {

448 continue;

449

451 FunctionAliases[F].push_back(&A);

452 }

453

454 if (!FunctionAliases.empty()) {

455 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases");

456 for (auto &Alias : FunctionAliases) {

459 for (auto *A : Alias.second)

462 }

463 }

464

467 Function *F = M.getFunction(Name);

468 if (F || F->use_empty())

469 return;

470

473 });

474

475 if (!Symvers.empty()) {

476 NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers");

477 for (auto *MD : Symvers)

479 }

480

481 simplifyExternals(*MergedM);

482

483

486

487

488

492

494

496

497

498

500 W.writeModule(M, ShouldPreserveUseListOrder, &Index,

501 true, &ModHash);

502 W.writeModule(*MergedM, ShouldPreserveUseListOrder, &MergedMIndex);

503 W.writeSymtab();

504 W.writeStrtab();

505 OS << Buffer;

506

507

508

509

510 if (ThinLinkOS) {

511 Buffer.clear();

514 W2.writeThinLinkBitcode(M, Index, ModHash);

515 W2.writeModule(*MergedM, false,

516 &MergedMIndex);

517 W2.writeSymtab();

518 W2.writeStrtab();

519 *ThinLinkOS << Buffer;

520 }

521}

522

523

524bool enableSplitLTOUnit(Module &M) {

525 bool EnableSplitLTOUnit = false;

527 M.getModuleFlag("EnableSplitLTOUnit")))

528 EnableSplitLTOUnit = MD->getZExtValue();

529 return EnableSplitLTOUnit;

530}

531

532

533bool requiresSplit(Module &M) {

534 for (auto &GO : M.global_objects()) {

535 if (GO.hasMetadata(LLVMContext::MD_type))

536 return true;

537 if (mustEmitToMergedModule(&GO))

538 return true;

539 }

540 return false;

541}

542

546 const bool ShouldPreserveUseListOrder) {

547 std::unique_ptr NewIndex = nullptr;

548

549

550 if (requiresSplit(M)) {

551 if (enableSplitLTOUnit(M)) {

552 splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M,

553 ShouldPreserveUseListOrder);

554 return true;

555 }

556

558 if (!ModuleId.empty()) {

559 promoteTypeIds(M, ModuleId);

560

561

562

563

564

565

566

567

569 NewIndex = std::make_unique(

571 Index = NewIndex.get();

572 }

573 }

574

575

576

577

578

579

582 true, &ModHash);

583

584

585

586 if (ThinLinkOS && Index)

588 return false;

589}

590

591}

592

597

598 M.removeDebugIntrinsicDeclarations();

599

600 bool Changed = writeThinLTOBitcode(

601 OS, ThinLinkOS,

604 },

606 ShouldPreserveUseListOrder);

607

609}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This is the interface for LLVM's primary stateless and local alias analysis.

static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")

This file contains the declarations for the subclasses of Constant, which represent the different fla...

Provides passes for computing function attributes based on interprocedural analyses.

Module.h This file contains the declarations for the Module class.

This header defines various interfaces for pass management in LLVM.

This is the interface to build a ModuleSummaryIndex for a module.

FunctionAnalysisManager FAM

A manager for alias analyses.

PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)

Get the result of an analysis pass for a given IR unit.

Value * getArgOperand(unsigned i) const

void setArgOperand(unsigned i, Value *v)

This class represents a function call, abstracting a target machine's calling convention.

This is an important base class in LLVM.

LLVM_ABI void removeDeadConstantUsers() const

If there are any dead constant users dangling off of this constant, remove them.

iterator find(const_arg_type_t< KeyT > Val)

std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)

Implements a dense probed hash-table based set.

static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)

This static method is the primary way of constructing a FunctionType.

static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)

void setAttributes(AttributeList Attrs)

Set the attribute list for this Function.

void copyAttributesFrom(const Function *Src)

copyAttributesFrom - copy all additional attributes (those not needed to create a Function) from the ...

LLVM_ABI bool isDeclaration() const

Return true if the primary definition of this global value is outside of the current translation unit...

LLVM_ABI const Comdat * getComdat() const

LLVM_ABI const GlobalObject * getAliaseeObject() const

LLVM_ABI void eraseFromParent()

This method unlinks 'this' from the containing module and deletes it.

@ HiddenVisibility

The GV is hidden.

void setVisibility(VisibilityTypes V)

@ ExternalLinkage

Externally visible function.

@ AvailableExternallyLinkage

Available for inspection, not emission.

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)

static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)

This class implements a map that also provides access to all stored values in a deterministic order.

Analysis pass to provide the ModuleSummaryIndex object.

Class to hold module path string table and global value map, and encapsulate methods for operating on...

static LLVM_ABI void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)

Parse inline ASM and collect the symvers directives that are defined in the current module.

A Module instance is used to store all the information related to an LLVM module.

@ Error

Emits an error if two values disagree, otherwise the resulting value is that of the operands.

iterator_range< global_object_iterator > global_objects()

GlobalValue * getNamedValue(StringRef Name) const

Return the global value in the module with the specified name, of arbitrary type.

Comdat * getOrInsertComdat(StringRef Name)

Return the Comdat in the module with the specified name.

void appendModuleInlineAsm(StringRef Asm)

Append to the module-scope inline assembly blocks.

iterator_range< global_value_iterator > global_values()

LLVM_ABI void addOperand(MDNode *M)

A set of analyses that are preserved following a run of a transformation pass.

static PreservedAnalyses none()

Convenience factory function for the empty preserved set.

static PreservedAnalyses all()

Construct a special preserved set that preserves all passes.

Analysis providing profile information.

A vector that has set insertion semantics.

size_type count(const_arg_type key) const

Count the number of elements of a given key in the SetVector.

bool insert(const value_type &X)

Insert a new element into the SetVector.

void push_back(const T &Elt)

This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.

StringRef - Represent a constant reference to a string, i.e.

LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)

Definition ThinLTOBitcodeWriter.cpp:594

Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...

static LLVM_ABI Type * getVoidTy(LLVMContext &C)

static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)

A Use represents the edge between a Value definition and its users.

LLVM Value Representation.

LLVM_ABI void setName(const Twine &Name)

Change the name of the value.

iterator_range< use_iterator > uses()

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)

size_type count(const_arg_type_t< ValueT > V) const

Return 1 if the specified key is in the set, 0 otherwise.

An efficient, type-erasing, non-owning reference to a callable.

This class implements an extremely fast bulk output stream that can only output to a stream.

@ C

The default llvm calling convention, compatible with C.

LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)

Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.

LLVM_ABI bool isJumpTableCanonical(Function *F)

std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)

Extract a Value from Metadata, allowing null.

This is an optimization pass for GlobalISel generic memory operations.

LLVM_ABI MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)

Returns the memory access properties of this copy of the function.

LLVM_ABI void WriteBitcodeToFile(const Module &M, raw_ostream &Out, bool ShouldPreserveUseListOrder=false, const ModuleSummaryIndex *Index=nullptr, bool GenerateHash=false, ModuleHash *ModHash=nullptr)

Write the specified module to the specified raw output stream.

decltype(auto) dyn_cast(const From &Val)

dyn_cast - Return the argument parameter cast to the specified type.

std::array< uint32_t, 5 > ModuleHash

160 bits SHA1

LLVM_ABI void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out, const ModuleSummaryIndex &Index, const ModuleHash &ModHash)

Write the specified thin link bitcode file (i.e., the minimized bitcode file) to the given raw output...

void append_range(Container &C, Range &&R)

Wrapper function to append range R to container C.

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...

LLVM_ABI bool convertToDeclaration(GlobalValue &GV)

Converts value GV to declaration, or replaces with a declaration if it is an alias.

InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy

Provide the FunctionAnalysisManager to Module proxy.

LLVM_ABI ModuleSummaryIndex buildModuleSummaryIndex(const Module &M, std::function< BlockFrequencyInfo *(const Function &F)> GetBFICallback, ProfileSummaryInfo *PSI, std::function< const StackSafetyInfo *(const Function &F)> GetSSICallback=[](const Function &F) -> const StackSafetyInfo *{ return nullptr;})

Direct function to compute a ModuleSummaryIndex from a given module.

auto dyn_cast_or_null(const Y &Val)

LLVM_ABI std::string getUniqueModuleId(Module *M)

Produce a unique identifier for this module by taking the MD5 sum of the names of the module's strong...

bool isAlnum(char C)

Checks whether character C is either a decimal digit or an uppercase or lowercase letter as classifie...

bool isa(const From &Val)

isa - Return true if the parameter to the template is an instance of one of the template type argu...

LLVM_ABI bool StripDebugInfo(Module &M)

Strip debug info in the module if it exists.

LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)

Adds global values to the llvm.compiler.used list.

DWARFExpression::Operation Op

ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.

AnalysisManager< Function > FunctionAnalysisManager

Convenience typedef for the Function analysis manager.

LLVM_ABI std::unique_ptr< Module > CloneModule(const Module &M)

Return an exact copy of the specified module.

LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)

Adds global values to the llvm.used list.

CfiFunctionLinkage

The type of CFI jumptable needed for a function.

AnalysisManager< Module > ModuleAnalysisManager

Convenience typedef for the Module analysis manager.

LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)

Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...