1 //===- llvm-lto: a simple command-line program to link modules with LTO ---===// 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 program takes in a list of bitcode files, links them, performs link-time 10 // optimization, and outputs an object file. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm-c/lto.h" 15 #include "llvm/ADT/ArrayRef.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/SmallString.h" 18 #include "llvm/ADT/StringExtras.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/ADT/StringSet.h" 21 #include "llvm/ADT/Twine.h" 22 #include "llvm/Bitcode/BitcodeReader.h" 23 #include "llvm/Bitcode/BitcodeWriter.h" 24 #include "llvm/CodeGen/CommandFlags.h" 25 #include "llvm/IR/DiagnosticInfo.h" 26 #include "llvm/IR/DiagnosticPrinter.h" 27 #include "llvm/IR/LLVMContext.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/ModuleSummaryIndex.h" 30 #include "llvm/IR/Verifier.h" 31 #include "llvm/IRReader/IRReader.h" 32 #include "llvm/LTO/legacy/LTOCodeGenerator.h" 33 #include "llvm/LTO/legacy/LTOModule.h" 34 #include "llvm/LTO/legacy/ThinLTOCodeGenerator.h" 35 #include "llvm/Support/Allocator.h" 36 #include "llvm/Support/Casting.h" 37 #include "llvm/Support/CommandLine.h" 38 #include "llvm/Support/Error.h" 39 #include "llvm/Support/ErrorHandling.h" 40 #include "llvm/Support/ErrorOr.h" 41 #include "llvm/Support/FileSystem.h" 42 #include "llvm/Support/InitLLVM.h" 43 #include "llvm/Support/MemoryBuffer.h" 44 #include "llvm/Support/Path.h" 45 #include "llvm/Support/SourceMgr.h" 46 #include "llvm/Support/TargetSelect.h" 47 #include "llvm/Support/ToolOutputFile.h" 48 #include "llvm/Support/raw_ostream.h" 49 #include "llvm/Support/WithColor.h" 50 #include "llvm/Target/TargetOptions.h" 51 #include <algorithm> 52 #include <cassert> 53 #include <cstdint> 54 #include <cstdlib> 55 #include <map> 56 #include <memory> 57 #include <string> 58 #include <system_error> 59 #include <tuple> 60 #include <utility> 61 #include <vector> 62 63 using namespace llvm; 64 65 static codegen::RegisterCodeGenFlags CGF; 66 67 static cl::OptionCategory LTOCategory("LTO Options"); 68 69 static cl::opt<char> 70 OptLevel("O", 71 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " 72 "(default = '-O2')"), 73 cl::Prefix, cl::init('2'), cl::cat(LTOCategory)); 74 75 static cl::opt<bool> 76 IndexStats("thinlto-index-stats", 77 cl::desc("Print statistic for the index in every input files"), 78 cl::init(false), cl::cat(LTOCategory)); 79 80 static cl::opt<bool> DisableVerify( 81 "disable-verify", cl::init(false), 82 cl::desc("Do not run the verifier during the optimization pipeline"), 83 cl::cat(LTOCategory)); 84 85 static cl::opt<bool> EnableFreestanding( 86 "lto-freestanding", cl::init(false), 87 cl::desc("Enable Freestanding (disable builtins / TLI) during LTO"), 88 cl::cat(LTOCategory)); 89 90 static cl::opt<bool> UseDiagnosticHandler( 91 "use-diagnostic-handler", cl::init(false), 92 cl::desc("Use a diagnostic handler to test the handler interface"), 93 cl::cat(LTOCategory)); 94 95 static cl::opt<bool> 96 ThinLTO("thinlto", cl::init(false), 97 cl::desc("Only write combined global index for ThinLTO backends"), 98 cl::cat(LTOCategory)); 99 100 enum ThinLTOModes { 101 THINLINK, 102 THINDISTRIBUTE, 103 THINEMITIMPORTS, 104 THINPROMOTE, 105 THINIMPORT, 106 THININTERNALIZE, 107 THINOPT, 108 THINCODEGEN, 109 THINALL 110 }; 111 112 cl::opt<ThinLTOModes> ThinLTOMode( 113 "thinlto-action", cl::desc("Perform a single ThinLTO stage:"), 114 cl::values( 115 clEnumValN( 116 THINLINK, "thinlink", 117 "ThinLink: produces the index by linking only the summaries."), 118 clEnumValN(THINDISTRIBUTE, "distributedindexes", 119 "Produces individual indexes for distributed backends."), 120 clEnumValN(THINEMITIMPORTS, "emitimports", 121 "Emit imports files for distributed backends."), 122 clEnumValN(THINPROMOTE, "promote", 123 "Perform pre-import promotion (requires -thinlto-index)."), 124 clEnumValN(THINIMPORT, "import", 125 "Perform both promotion and " 126 "cross-module importing (requires " 127 "-thinlto-index)."), 128 clEnumValN(THININTERNALIZE, "internalize", 129 "Perform internalization driven by -exported-symbol " 130 "(requires -thinlto-index)."), 131 clEnumValN(THINOPT, "optimize", "Perform ThinLTO optimizations."), 132 clEnumValN(THINCODEGEN, "codegen", "CodeGen (expected to match llc)"), 133 clEnumValN(THINALL, "run", "Perform ThinLTO end-to-end")), 134 cl::cat(LTOCategory)); 135 136 static cl::opt<std::string> 137 ThinLTOIndex("thinlto-index", 138 cl::desc("Provide the index produced by a ThinLink, required " 139 "to perform the promotion and/or importing."), 140 cl::cat(LTOCategory)); 141 142 static cl::opt<std::string> ThinLTOPrefixReplace( 143 "thinlto-prefix-replace", 144 cl::desc("Control where files for distributed backends are " 145 "created. Expects 'oldprefix;newprefix' and if path " 146 "prefix of output file is oldprefix it will be " 147 "replaced with newprefix."), 148 cl::cat(LTOCategory)); 149 150 static cl::opt<std::string> ThinLTOModuleId( 151 "thinlto-module-id", 152 cl::desc("For the module ID for the file to process, useful to " 153 "match what is in the index."), 154 cl::cat(LTOCategory)); 155 156 static cl::opt<std::string> ThinLTOCacheDir("thinlto-cache-dir", 157 cl::desc("Enable ThinLTO caching."), 158 cl::cat(LTOCategory)); 159 160 static cl::opt<int> ThinLTOCachePruningInterval( 161 "thinlto-cache-pruning-interval", cl::init(1200), 162 cl::desc("Set ThinLTO cache pruning interval."), cl::cat(LTOCategory)); 163 164 static cl::opt<uint64_t> ThinLTOCacheMaxSizeBytes( 165 "thinlto-cache-max-size-bytes", 166 cl::desc("Set ThinLTO cache pruning directory maximum size in bytes."), 167 cl::cat(LTOCategory)); 168 169 static cl::opt<int> ThinLTOCacheMaxSizeFiles( 170 "thinlto-cache-max-size-files", cl::init(1000000), 171 cl::desc("Set ThinLTO cache pruning directory maximum number of files."), 172 cl::cat(LTOCategory)); 173 174 static cl::opt<unsigned> ThinLTOCacheEntryExpiration( 175 "thinlto-cache-entry-expiration", cl::init(604800) /* 1w */, 176 cl::desc("Set ThinLTO cache entry expiration time."), cl::cat(LTOCategory)); 177 178 static cl::opt<std::string> ThinLTOSaveTempsPrefix( 179 "thinlto-save-temps", 180 cl::desc("Save ThinLTO temp files using filenames created by adding " 181 "suffixes to the given file path prefix."), 182 cl::cat(LTOCategory)); 183 184 static cl::opt<std::string> ThinLTOGeneratedObjectsDir( 185 "thinlto-save-objects", 186 cl::desc("Save ThinLTO generated object files using filenames created in " 187 "the given directory."), 188 cl::cat(LTOCategory)); 189 190 static cl::opt<bool> SaveLinkedModuleFile( 191 "save-linked-module", cl::init(false), 192 cl::desc("Write linked LTO module to file before optimize"), 193 cl::cat(LTOCategory)); 194 195 static cl::opt<bool> 196 SaveModuleFile("save-merged-module", cl::init(false), 197 cl::desc("Write merged LTO module to file before CodeGen"), 198 cl::cat(LTOCategory)); 199 200 static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, 201 cl::desc("<input bitcode files>"), 202 cl::cat(LTOCategory)); 203 204 static cl::opt<std::string> OutputFilename("o", cl::init(""), 205 cl::desc("Override output filename"), 206 cl::value_desc("filename"), 207 cl::cat(LTOCategory)); 208 209 static cl::list<std::string> ExportedSymbols( 210 "exported-symbol", 211 cl::desc("List of symbols to export from the resulting object file"), 212 cl::cat(LTOCategory)); 213 214 static cl::list<std::string> 215 DSOSymbols("dso-symbol", 216 cl::desc("Symbol to put in the symtab in the resulting dso"), 217 cl::cat(LTOCategory)); 218 219 static cl::opt<bool> ListSymbolsOnly( 220 "list-symbols-only", cl::init(false), 221 cl::desc("Instead of running LTO, list the symbols in each IR file"), 222 cl::cat(LTOCategory)); 223 224 static cl::opt<bool> ListDependentLibrariesOnly( 225 "list-dependent-libraries-only", cl::init(false), 226 cl::desc( 227 "Instead of running LTO, list the dependent libraries in each IR file"), 228 cl::cat(LTOCategory)); 229 230 static cl::opt<bool> QueryHasCtorDtor( 231 "query-hasCtorDtor", cl::init(false), 232 cl::desc("Queries LTOModule::hasCtorDtor() on each IR file")); 233 234 static cl::opt<bool> 235 SetMergedModule("set-merged-module", cl::init(false), 236 cl::desc("Use the first input module as the merged module"), 237 cl::cat(LTOCategory)); 238 239 static cl::opt<unsigned> Parallelism("j", cl::Prefix, cl::init(1), 240 cl::desc("Number of backend threads"), 241 cl::cat(LTOCategory)); 242 243 static cl::opt<bool> RestoreGlobalsLinkage( 244 "restore-linkage", cl::init(false), 245 cl::desc("Restore original linkage of globals prior to CodeGen"), 246 cl::cat(LTOCategory)); 247 248 static cl::opt<bool> CheckHasObjC( 249 "check-for-objc", cl::init(false), 250 cl::desc("Only check if the module has objective-C defined in it"), 251 cl::cat(LTOCategory)); 252 253 static cl::opt<bool> PrintMachOCPUOnly( 254 "print-macho-cpu-only", cl::init(false), 255 cl::desc("Instead of running LTO, print the mach-o cpu in each IR file"), 256 cl::cat(LTOCategory)); 257 258 static cl::opt<bool> 259 DebugPassManager("debug-pass-manager", cl::init(false), cl::Hidden, 260 cl::desc("Print pass management debugging information"), 261 cl::cat(LTOCategory)); 262 263 static cl::opt<bool> 264 LTOSaveBeforeOpt("lto-save-before-opt", cl::init(false), 265 cl::desc("Save the IR before running optimizations")); 266 267 static cl::opt<bool> TryUseNewDbgInfoFormat( 268 "try-experimental-debuginfo-iterators", 269 cl::desc("Enable debuginfo iterator positions, if they're built in"), 270 cl::init(false), cl::Hidden); 271 272 extern cl::opt<bool> UseNewDbgInfoFormat; 273 extern cl::opt<cl::boolOrDefault> LoadBitcodeIntoNewDbgInfoFormat; 274 extern cl::opt<cl::boolOrDefault> PreserveInputDbgFormat; 275 276 namespace { 277 278 struct ModuleInfo { 279 BitVector CanBeHidden; 280 }; 281 282 } // end anonymous namespace 283 284 static void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity, 285 const char *Msg, void *) { 286 errs() << "llvm-lto: "; 287 switch (Severity) { 288 case LTO_DS_NOTE: 289 errs() << "note: "; 290 break; 291 case LTO_DS_REMARK: 292 errs() << "remark: "; 293 break; 294 case LTO_DS_ERROR: 295 errs() << "error: "; 296 break; 297 case LTO_DS_WARNING: 298 errs() << "warning: "; 299 break; 300 } 301 errs() << Msg << "\n"; 302 } 303 304 static std::string CurrentActivity; 305 306 namespace { 307 struct LLVMLTODiagnosticHandler : public DiagnosticHandler { 308 bool handleDiagnostics(const DiagnosticInfo &DI) override { 309 raw_ostream &OS = errs(); 310 OS << "llvm-lto: "; 311 switch (DI.getSeverity()) { 312 case DS_Error: 313 OS << "error"; 314 break; 315 case DS_Warning: 316 OS << "warning"; 317 break; 318 case DS_Remark: 319 OS << "remark"; 320 break; 321 case DS_Note: 322 OS << "note"; 323 break; 324 } 325 if (!CurrentActivity.empty()) 326 OS << ' ' << CurrentActivity; 327 OS << ": "; 328 329 DiagnosticPrinterRawOStream DP(OS); 330 DI.print(DP); 331 OS << '\n'; 332 333 if (DI.getSeverity() == DS_Error) 334 exit(1); 335 return true; 336 } 337 }; 338 } 339 340 static void error(const Twine &Msg) { 341 errs() << "llvm-lto: " << Msg << '\n'; 342 exit(1); 343 } 344 345 static void error(std::error_code EC, const Twine &Prefix) { 346 if (EC) 347 error(Prefix + ": " + EC.message()); 348 } 349 350 template <typename T> 351 static void error(const ErrorOr<T> &V, const Twine &Prefix) { 352 error(V.getError(), Prefix); 353 } 354 355 static void maybeVerifyModule(const Module &Mod) { 356 if (!DisableVerify && verifyModule(Mod, &errs())) 357 error("Broken Module"); 358 } 359 360 static std::unique_ptr<LTOModule> 361 getLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer, 362 const TargetOptions &Options) { 363 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 364 MemoryBuffer::getFile(Path); 365 error(BufferOrErr, "error loading file '" + Path + "'"); 366 Buffer = std::move(BufferOrErr.get()); 367 CurrentActivity = ("loading file '" + Path + "'").str(); 368 std::unique_ptr<LLVMContext> Context = std::make_unique<LLVMContext>(); 369 Context->setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(), 370 true); 371 ErrorOr<std::unique_ptr<LTOModule>> Ret = LTOModule::createInLocalContext( 372 std::move(Context), Buffer->getBufferStart(), Buffer->getBufferSize(), 373 Options, Path); 374 CurrentActivity = ""; 375 maybeVerifyModule((*Ret)->getModule()); 376 return std::move(*Ret); 377 } 378 379 /// Print some statistics on the index for each input files. 380 static void printIndexStats() { 381 for (auto &Filename : InputFilenames) { 382 ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': "); 383 std::unique_ptr<ModuleSummaryIndex> Index = 384 ExitOnErr(getModuleSummaryIndexForFile(Filename)); 385 // Skip files without a module summary. 386 if (!Index) 387 report_fatal_error(Twine(Filename) + " does not contain an index"); 388 389 unsigned Calls = 0, Refs = 0, Functions = 0, Alias = 0, Globals = 0; 390 for (auto &Summaries : *Index) { 391 for (auto &Summary : Summaries.second.SummaryList) { 392 Refs += Summary->refs().size(); 393 if (auto *FuncSummary = dyn_cast<FunctionSummary>(Summary.get())) { 394 Functions++; 395 Calls += FuncSummary->calls().size(); 396 } else if (isa<AliasSummary>(Summary.get())) 397 Alias++; 398 else 399 Globals++; 400 } 401 } 402 outs() << "Index " << Filename << " contains " 403 << (Alias + Globals + Functions) << " nodes (" << Functions 404 << " functions, " << Alias << " alias, " << Globals 405 << " globals) and " << (Calls + Refs) << " edges (" << Refs 406 << " refs and " << Calls << " calls)\n"; 407 } 408 } 409 410 /// Load each IR file and dump certain information based on active flags. 411 /// 412 /// The main point here is to provide lit-testable coverage for the LTOModule 413 /// functionality that's exposed by the C API. Moreover, this provides testing 414 /// coverage for modules that have been created in their own contexts. 415 static void testLTOModule(const TargetOptions &Options) { 416 for (auto &Filename : InputFilenames) { 417 std::unique_ptr<MemoryBuffer> Buffer; 418 std::unique_ptr<LTOModule> Module = 419 getLocalLTOModule(Filename, Buffer, Options); 420 421 if (ListSymbolsOnly) { 422 // List the symbols. 423 outs() << Filename << ":\n"; 424 for (int I = 0, E = Module->getSymbolCount(); I != E; ++I) 425 outs() << Module->getSymbolName(I) << "\n"; 426 } 427 if (QueryHasCtorDtor) 428 outs() << Filename 429 << ": hasCtorDtor = " << (Module->hasCtorDtor() ? "true" : "false") 430 << "\n"; 431 } 432 } 433 434 static std::unique_ptr<MemoryBuffer> loadFile(StringRef Filename) { 435 ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename.str() + 436 "': "); 437 return ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename))); 438 } 439 440 static void listDependentLibraries() { 441 for (auto &Filename : InputFilenames) { 442 auto Buffer = loadFile(Filename); 443 std::string E; 444 std::unique_ptr<lto::InputFile> Input(LTOModule::createInputFile( 445 Buffer->getBufferStart(), Buffer->getBufferSize(), Filename.c_str(), 446 E)); 447 if (!Input) 448 error(E); 449 450 // List the dependent libraries. 451 outs() << Filename << ":\n"; 452 for (size_t I = 0, C = LTOModule::getDependentLibraryCount(Input.get()); 453 I != C; ++I) { 454 size_t L = 0; 455 const char *S = LTOModule::getDependentLibrary(Input.get(), I, &L); 456 assert(S); 457 outs() << StringRef(S, L) << "\n"; 458 } 459 } 460 } 461 462 static void printMachOCPUOnly() { 463 LLVMContext Context; 464 Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(), 465 true); 466 TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple()); 467 for (auto &Filename : InputFilenames) { 468 ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr = 469 LTOModule::createFromFile(Context, Filename, Options); 470 if (!ModuleOrErr) 471 error(ModuleOrErr, "llvm-lto: "); 472 473 Expected<uint32_t> CPUType = (*ModuleOrErr)->getMachOCPUType(); 474 Expected<uint32_t> CPUSubType = (*ModuleOrErr)->getMachOCPUSubType(); 475 if (!CPUType) 476 error("Error while printing mach-o cputype: " + 477 toString(CPUType.takeError())); 478 if (!CPUSubType) 479 error("Error while printing mach-o cpusubtype: " + 480 toString(CPUSubType.takeError())); 481 outs() << llvm::format("%s:\ncputype: %u\ncpusubtype: %u\n", 482 Filename.c_str(), *CPUType, *CPUSubType); 483 } 484 } 485 486 /// Create a combined index file from the input IR files and write it. 487 /// 488 /// This is meant to enable testing of ThinLTO combined index generation, 489 /// currently available via the gold plugin via -thinlto. 490 static void createCombinedModuleSummaryIndex() { 491 ModuleSummaryIndex CombinedIndex(/*HaveGVs=*/false); 492 for (auto &Filename : InputFilenames) { 493 ExitOnError ExitOnErr("llvm-lto: error loading file '" + Filename + "': "); 494 std::unique_ptr<MemoryBuffer> MB = 495 ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(Filename))); 496 ExitOnErr(readModuleSummaryIndex(*MB, CombinedIndex)); 497 } 498 // In order to use this index for testing, specifically import testing, we 499 // need to update any indirect call edges created from SamplePGO, so that they 500 // point to the correct GUIDs. 501 updateIndirectCalls(CombinedIndex); 502 std::error_code EC; 503 assert(!OutputFilename.empty()); 504 raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC, 505 sys::fs::OpenFlags::OF_None); 506 error(EC, "error opening the file '" + OutputFilename + ".thinlto.bc'"); 507 writeIndexToFile(CombinedIndex, OS); 508 OS.close(); 509 } 510 511 /// Parse the thinlto_prefix_replace option into the \p OldPrefix and 512 /// \p NewPrefix strings, if it was specified. 513 static void getThinLTOOldAndNewPrefix(std::string &OldPrefix, 514 std::string &NewPrefix) { 515 assert(ThinLTOPrefixReplace.empty() || 516 ThinLTOPrefixReplace.find(';') != StringRef::npos); 517 StringRef PrefixReplace = ThinLTOPrefixReplace; 518 std::pair<StringRef, StringRef> Split = PrefixReplace.split(";"); 519 OldPrefix = Split.first.str(); 520 NewPrefix = Split.second.str(); 521 } 522 523 /// Given the original \p Path to an output file, replace any path 524 /// prefix matching \p OldPrefix with \p NewPrefix. Also, create the 525 /// resulting directory if it does not yet exist. 526 static std::string getThinLTOOutputFile(StringRef Path, StringRef OldPrefix, 527 StringRef NewPrefix) { 528 if (OldPrefix.empty() && NewPrefix.empty()) 529 return std::string(Path); 530 SmallString<128> NewPath(Path); 531 llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix); 532 StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str()); 533 if (!ParentPath.empty()) { 534 // Make sure the new directory exists, creating it if necessary. 535 if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath)) 536 error(EC, "error creating the directory '" + ParentPath + "'"); 537 } 538 return std::string(NewPath); 539 } 540 541 namespace thinlto { 542 543 std::vector<std::unique_ptr<MemoryBuffer>> 544 loadAllFilesForIndex(const ModuleSummaryIndex &Index) { 545 std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; 546 547 for (auto &ModPath : Index.modulePaths()) { 548 const auto &Filename = ModPath.first(); 549 std::string CurrentActivity = ("loading file '" + Filename + "'").str(); 550 auto InputOrErr = MemoryBuffer::getFile(Filename); 551 error(InputOrErr, "error " + CurrentActivity); 552 InputBuffers.push_back(std::move(*InputOrErr)); 553 } 554 return InputBuffers; 555 } 556 557 std::unique_ptr<ModuleSummaryIndex> loadCombinedIndex() { 558 if (ThinLTOIndex.empty()) 559 report_fatal_error("Missing -thinlto-index for ThinLTO promotion stage"); 560 ExitOnError ExitOnErr("llvm-lto: error loading file '" + ThinLTOIndex + 561 "': "); 562 return ExitOnErr(getModuleSummaryIndexForFile(ThinLTOIndex)); 563 } 564 565 static std::unique_ptr<lto::InputFile> loadInputFile(MemoryBufferRef Buffer) { 566 ExitOnError ExitOnErr("llvm-lto: error loading input '" + 567 Buffer.getBufferIdentifier().str() + "': "); 568 return ExitOnErr(lto::InputFile::create(Buffer)); 569 } 570 571 static std::unique_ptr<Module> loadModuleFromInput(lto::InputFile &File, 572 LLVMContext &CTX) { 573 auto &Mod = File.getSingleBitcodeModule(); 574 auto ModuleOrErr = Mod.parseModule(CTX); 575 if (!ModuleOrErr) { 576 handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { 577 SMDiagnostic Err = SMDiagnostic(Mod.getModuleIdentifier(), 578 SourceMgr::DK_Error, EIB.message()); 579 Err.print("llvm-lto", errs()); 580 }); 581 report_fatal_error("Can't load module, abort."); 582 } 583 maybeVerifyModule(**ModuleOrErr); 584 if (ThinLTOModuleId.getNumOccurrences()) { 585 if (InputFilenames.size() != 1) 586 report_fatal_error("Can't override the module id for multiple files"); 587 (*ModuleOrErr)->setModuleIdentifier(ThinLTOModuleId); 588 } 589 return std::move(*ModuleOrErr); 590 } 591 592 static void writeModuleToFile(Module &TheModule, StringRef Filename) { 593 std::error_code EC; 594 raw_fd_ostream OS(Filename, EC, sys::fs::OpenFlags::OF_None); 595 error(EC, "error opening the file '" + Filename + "'"); 596 maybeVerifyModule(TheModule); 597 WriteBitcodeToFile(TheModule, OS, /* ShouldPreserveUseListOrder */ true); 598 } 599 600 class ThinLTOProcessing { 601 public: 602 ThinLTOCodeGenerator ThinGenerator; 603 604 ThinLTOProcessing(const TargetOptions &Options) { 605 ThinGenerator.setCodePICModel(codegen::getExplicitRelocModel()); 606 ThinGenerator.setTargetOptions(Options); 607 ThinGenerator.setCacheDir(ThinLTOCacheDir); 608 ThinGenerator.setCachePruningInterval(ThinLTOCachePruningInterval); 609 ThinGenerator.setCacheEntryExpiration(ThinLTOCacheEntryExpiration); 610 ThinGenerator.setCacheMaxSizeFiles(ThinLTOCacheMaxSizeFiles); 611 ThinGenerator.setCacheMaxSizeBytes(ThinLTOCacheMaxSizeBytes); 612 ThinGenerator.setFreestanding(EnableFreestanding); 613 ThinGenerator.setDebugPassManager(DebugPassManager); 614 615 // Add all the exported symbols to the table of symbols to preserve. 616 for (unsigned i = 0; i < ExportedSymbols.size(); ++i) 617 ThinGenerator.preserveSymbol(ExportedSymbols[i]); 618 } 619 620 void run() { 621 switch (ThinLTOMode) { 622 case THINLINK: 623 return thinLink(); 624 case THINDISTRIBUTE: 625 return distributedIndexes(); 626 case THINEMITIMPORTS: 627 return emitImports(); 628 case THINPROMOTE: 629 return promote(); 630 case THINIMPORT: 631 return import(); 632 case THININTERNALIZE: 633 return internalize(); 634 case THINOPT: 635 return optimize(); 636 case THINCODEGEN: 637 return codegen(); 638 case THINALL: 639 return runAll(); 640 } 641 } 642 643 private: 644 /// Load the input files, create the combined index, and write it out. 645 void thinLink() { 646 // Perform "ThinLink": just produce the index 647 if (OutputFilename.empty()) 648 report_fatal_error( 649 "OutputFilename is necessary to store the combined index.\n"); 650 651 LLVMContext Ctx; 652 std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; 653 for (unsigned i = 0; i < InputFilenames.size(); ++i) { 654 auto &Filename = InputFilenames[i]; 655 std::string CurrentActivity = "loading file '" + Filename + "'"; 656 auto InputOrErr = MemoryBuffer::getFile(Filename); 657 error(InputOrErr, "error " + CurrentActivity); 658 InputBuffers.push_back(std::move(*InputOrErr)); 659 ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer()); 660 } 661 662 auto CombinedIndex = ThinGenerator.linkCombinedIndex(); 663 if (!CombinedIndex) 664 report_fatal_error("ThinLink didn't create an index"); 665 std::error_code EC; 666 raw_fd_ostream OS(OutputFilename, EC, sys::fs::OpenFlags::OF_None); 667 error(EC, "error opening the file '" + OutputFilename + "'"); 668 writeIndexToFile(*CombinedIndex, OS); 669 } 670 671 /// Load the combined index from disk, then compute and generate 672 /// individual index files suitable for ThinLTO distributed backend builds 673 /// on the files mentioned on the command line (these must match the index 674 /// content). 675 void distributedIndexes() { 676 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 677 report_fatal_error("Can't handle a single output filename and multiple " 678 "input files, do not provide an output filename and " 679 "the output files will be suffixed from the input " 680 "ones."); 681 682 std::string OldPrefix, NewPrefix; 683 getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix); 684 685 auto Index = loadCombinedIndex(); 686 for (auto &Filename : InputFilenames) { 687 LLVMContext Ctx; 688 auto Buffer = loadFile(Filename); 689 auto Input = loadInputFile(Buffer->getMemBufferRef()); 690 auto TheModule = loadModuleFromInput(*Input, Ctx); 691 692 // Build a map of module to the GUIDs and summary objects that should 693 // be written to its index. 694 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex; 695 GVSummaryPtrSet DecSummaries; 696 ThinGenerator.gatherImportedSummariesForModule( 697 *TheModule, *Index, ModuleToSummariesForIndex, DecSummaries, *Input); 698 699 std::string OutputName = OutputFilename; 700 if (OutputName.empty()) { 701 OutputName = Filename + ".thinlto.bc"; 702 } 703 OutputName = getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix); 704 std::error_code EC; 705 raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None); 706 error(EC, "error opening the file '" + OutputName + "'"); 707 writeIndexToFile(*Index, OS, &ModuleToSummariesForIndex, &DecSummaries); 708 } 709 } 710 711 /// Load the combined index from disk, compute the imports, and emit 712 /// the import file lists for each module to disk. 713 void emitImports() { 714 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 715 report_fatal_error("Can't handle a single output filename and multiple " 716 "input files, do not provide an output filename and " 717 "the output files will be suffixed from the input " 718 "ones."); 719 720 std::string OldPrefix, NewPrefix; 721 getThinLTOOldAndNewPrefix(OldPrefix, NewPrefix); 722 723 auto Index = loadCombinedIndex(); 724 for (auto &Filename : InputFilenames) { 725 LLVMContext Ctx; 726 auto Buffer = loadFile(Filename); 727 auto Input = loadInputFile(Buffer->getMemBufferRef()); 728 auto TheModule = loadModuleFromInput(*Input, Ctx); 729 std::string OutputName = OutputFilename; 730 if (OutputName.empty()) { 731 OutputName = Filename + ".imports"; 732 } 733 OutputName = 734 getThinLTOOutputFile(OutputName, OldPrefix, NewPrefix); 735 ThinGenerator.emitImports(*TheModule, OutputName, *Index, *Input); 736 } 737 } 738 739 /// Load the combined index from disk, then load every file referenced by 740 /// the index and add them to the generator, finally perform the promotion 741 /// on the files mentioned on the command line (these must match the index 742 /// content). 743 void promote() { 744 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 745 report_fatal_error("Can't handle a single output filename and multiple " 746 "input files, do not provide an output filename and " 747 "the output files will be suffixed from the input " 748 "ones."); 749 750 auto Index = loadCombinedIndex(); 751 for (auto &Filename : InputFilenames) { 752 LLVMContext Ctx; 753 auto Buffer = loadFile(Filename); 754 auto Input = loadInputFile(Buffer->getMemBufferRef()); 755 auto TheModule = loadModuleFromInput(*Input, Ctx); 756 757 ThinGenerator.promote(*TheModule, *Index, *Input); 758 759 std::string OutputName = OutputFilename; 760 if (OutputName.empty()) { 761 OutputName = Filename + ".thinlto.promoted.bc"; 762 } 763 writeModuleToFile(*TheModule, OutputName); 764 } 765 } 766 767 /// Load the combined index from disk, then load every file referenced by 768 /// the index and add them to the generator, then performs the promotion and 769 /// cross module importing on the files mentioned on the command line 770 /// (these must match the index content). 771 void import() { 772 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 773 report_fatal_error("Can't handle a single output filename and multiple " 774 "input files, do not provide an output filename and " 775 "the output files will be suffixed from the input " 776 "ones."); 777 778 auto Index = loadCombinedIndex(); 779 auto InputBuffers = loadAllFilesForIndex(*Index); 780 for (auto &MemBuffer : InputBuffers) 781 ThinGenerator.addModule(MemBuffer->getBufferIdentifier(), 782 MemBuffer->getBuffer()); 783 784 for (auto &Filename : InputFilenames) { 785 LLVMContext Ctx; 786 auto Buffer = loadFile(Filename); 787 auto Input = loadInputFile(Buffer->getMemBufferRef()); 788 auto TheModule = loadModuleFromInput(*Input, Ctx); 789 790 ThinGenerator.crossModuleImport(*TheModule, *Index, *Input); 791 792 std::string OutputName = OutputFilename; 793 if (OutputName.empty()) { 794 OutputName = Filename + ".thinlto.imported.bc"; 795 } 796 writeModuleToFile(*TheModule, OutputName); 797 } 798 } 799 800 void internalize() { 801 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 802 report_fatal_error("Can't handle a single output filename and multiple " 803 "input files, do not provide an output filename and " 804 "the output files will be suffixed from the input " 805 "ones."); 806 807 if (ExportedSymbols.empty()) 808 errs() << "Warning: -internalize will not perform without " 809 "-exported-symbol\n"; 810 811 auto Index = loadCombinedIndex(); 812 auto InputBuffers = loadAllFilesForIndex(*Index); 813 for (auto &MemBuffer : InputBuffers) 814 ThinGenerator.addModule(MemBuffer->getBufferIdentifier(), 815 MemBuffer->getBuffer()); 816 817 for (auto &Filename : InputFilenames) { 818 LLVMContext Ctx; 819 auto Buffer = loadFile(Filename); 820 auto Input = loadInputFile(Buffer->getMemBufferRef()); 821 auto TheModule = loadModuleFromInput(*Input, Ctx); 822 823 ThinGenerator.internalize(*TheModule, *Index, *Input); 824 825 std::string OutputName = OutputFilename; 826 if (OutputName.empty()) { 827 OutputName = Filename + ".thinlto.internalized.bc"; 828 } 829 writeModuleToFile(*TheModule, OutputName); 830 } 831 } 832 833 void optimize() { 834 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 835 report_fatal_error("Can't handle a single output filename and multiple " 836 "input files, do not provide an output filename and " 837 "the output files will be suffixed from the input " 838 "ones."); 839 if (!ThinLTOIndex.empty()) 840 errs() << "Warning: -thinlto-index ignored for optimize stage"; 841 842 for (auto &Filename : InputFilenames) { 843 LLVMContext Ctx; 844 auto Buffer = loadFile(Filename); 845 auto Input = loadInputFile(Buffer->getMemBufferRef()); 846 auto TheModule = loadModuleFromInput(*Input, Ctx); 847 848 ThinGenerator.optimize(*TheModule); 849 850 std::string OutputName = OutputFilename; 851 if (OutputName.empty()) { 852 OutputName = Filename + ".thinlto.imported.bc"; 853 } 854 writeModuleToFile(*TheModule, OutputName); 855 } 856 } 857 858 void codegen() { 859 if (InputFilenames.size() != 1 && !OutputFilename.empty()) 860 report_fatal_error("Can't handle a single output filename and multiple " 861 "input files, do not provide an output filename and " 862 "the output files will be suffixed from the input " 863 "ones."); 864 if (!ThinLTOIndex.empty()) 865 errs() << "Warning: -thinlto-index ignored for codegen stage"; 866 867 std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; 868 for (auto &Filename : InputFilenames) { 869 LLVMContext Ctx; 870 auto InputOrErr = MemoryBuffer::getFile(Filename); 871 error(InputOrErr, "error " + CurrentActivity); 872 InputBuffers.push_back(std::move(*InputOrErr)); 873 ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer()); 874 } 875 ThinGenerator.setCodeGenOnly(true); 876 ThinGenerator.run(); 877 for (auto BinName : 878 zip(ThinGenerator.getProducedBinaries(), InputFilenames)) { 879 std::string OutputName = OutputFilename; 880 if (OutputName.empty()) 881 OutputName = std::get<1>(BinName) + ".thinlto.o"; 882 else if (OutputName == "-") { 883 outs() << std::get<0>(BinName)->getBuffer(); 884 return; 885 } 886 887 std::error_code EC; 888 raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None); 889 error(EC, "error opening the file '" + OutputName + "'"); 890 OS << std::get<0>(BinName)->getBuffer(); 891 } 892 } 893 894 /// Full ThinLTO process 895 void runAll() { 896 if (!OutputFilename.empty()) 897 report_fatal_error("Do not provide an output filename for ThinLTO " 898 " processing, the output files will be suffixed from " 899 "the input ones."); 900 901 if (!ThinLTOIndex.empty()) 902 errs() << "Warning: -thinlto-index ignored for full ThinLTO process"; 903 904 LLVMContext Ctx; 905 std::vector<std::unique_ptr<MemoryBuffer>> InputBuffers; 906 for (unsigned i = 0; i < InputFilenames.size(); ++i) { 907 auto &Filename = InputFilenames[i]; 908 std::string CurrentActivity = "loading file '" + Filename + "'"; 909 auto InputOrErr = MemoryBuffer::getFile(Filename); 910 error(InputOrErr, "error " + CurrentActivity); 911 InputBuffers.push_back(std::move(*InputOrErr)); 912 ThinGenerator.addModule(Filename, InputBuffers.back()->getBuffer()); 913 } 914 915 if (!ThinLTOSaveTempsPrefix.empty()) 916 ThinGenerator.setSaveTempsDir(ThinLTOSaveTempsPrefix); 917 918 if (!ThinLTOGeneratedObjectsDir.empty()) { 919 ThinGenerator.setGeneratedObjectsDirectory(ThinLTOGeneratedObjectsDir); 920 ThinGenerator.run(); 921 return; 922 } 923 924 ThinGenerator.run(); 925 926 auto &Binaries = ThinGenerator.getProducedBinaries(); 927 if (Binaries.size() != InputFilenames.size()) 928 report_fatal_error("Number of output objects does not match the number " 929 "of inputs"); 930 931 for (unsigned BufID = 0; BufID < Binaries.size(); ++BufID) { 932 auto OutputName = InputFilenames[BufID] + ".thinlto.o"; 933 std::error_code EC; 934 raw_fd_ostream OS(OutputName, EC, sys::fs::OpenFlags::OF_None); 935 error(EC, "error opening the file '" + OutputName + "'"); 936 OS << Binaries[BufID]->getBuffer(); 937 } 938 } 939 940 /// Load the combined index from disk, then load every file referenced by 941 }; 942 943 } // end namespace thinlto 944 945 int main(int argc, char **argv) { 946 InitLLVM X(argc, argv); 947 cl::HideUnrelatedOptions({<OCategory, &getColorCategory()}); 948 cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); 949 // Load bitcode into the new debug info format by default. 950 if (LoadBitcodeIntoNewDbgInfoFormat == cl::boolOrDefault::BOU_UNSET) 951 LoadBitcodeIntoNewDbgInfoFormat = cl::boolOrDefault::BOU_TRUE; 952 953 // RemoveDIs debug-info transition: tests may request that we /try/ to use the 954 // new debug-info format. 955 if (TryUseNewDbgInfoFormat) { 956 // Turn the new debug-info format on. 957 UseNewDbgInfoFormat = true; 958 } 959 // Since llvm-lto collects multiple IR modules together, for simplicity's sake 960 // we disable the "PreserveInputDbgFormat" flag to enforce a single debug info 961 // format. 962 PreserveInputDbgFormat = cl::boolOrDefault::BOU_FALSE; 963 964 if (OptLevel < '0' || OptLevel > '3') 965 error("optimization level must be between 0 and 3"); 966 967 // Initialize the configured targets. 968 InitializeAllTargets(); 969 InitializeAllTargetMCs(); 970 InitializeAllAsmPrinters(); 971 InitializeAllAsmParsers(); 972 973 // set up the TargetOptions for the machine 974 TargetOptions Options = codegen::InitTargetOptionsFromCodeGenFlags(Triple()); 975 976 if (ListSymbolsOnly || QueryHasCtorDtor) { 977 testLTOModule(Options); 978 return 0; 979 } 980 981 if (ListDependentLibrariesOnly) { 982 listDependentLibraries(); 983 return 0; 984 } 985 986 if (IndexStats) { 987 printIndexStats(); 988 return 0; 989 } 990 991 if (CheckHasObjC) { 992 for (auto &Filename : InputFilenames) { 993 ExitOnError ExitOnErr(std::string(*argv) + ": error loading file '" + 994 Filename + "': "); 995 std::unique_ptr<MemoryBuffer> BufferOrErr = 996 ExitOnErr(errorOrToExpected(MemoryBuffer::getFile(Filename))); 997 auto Buffer = std::move(BufferOrErr.get()); 998 if (ExitOnErr(isBitcodeContainingObjCCategory(*Buffer))) 999 outs() << "Bitcode " << Filename << " contains ObjC\n"; 1000 else 1001 outs() << "Bitcode " << Filename << " does not contain ObjC\n"; 1002 } 1003 return 0; 1004 } 1005 1006 if (PrintMachOCPUOnly) { 1007 printMachOCPUOnly(); 1008 return 0; 1009 } 1010 1011 if (ThinLTOMode.getNumOccurrences()) { 1012 if (ThinLTOMode.getNumOccurrences() > 1) 1013 report_fatal_error("You can't specify more than one -thinlto-action"); 1014 thinlto::ThinLTOProcessing ThinLTOProcessor(Options); 1015 ThinLTOProcessor.run(); 1016 return 0; 1017 } 1018 1019 if (ThinLTO) { 1020 createCombinedModuleSummaryIndex(); 1021 return 0; 1022 } 1023 1024 unsigned BaseArg = 0; 1025 1026 LLVMContext Context; 1027 Context.setDiagnosticHandler(std::make_unique<LLVMLTODiagnosticHandler>(), 1028 true); 1029 1030 LTOCodeGenerator CodeGen(Context); 1031 CodeGen.setDisableVerify(DisableVerify); 1032 1033 if (UseDiagnosticHandler) 1034 CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); 1035 1036 CodeGen.setCodePICModel(codegen::getExplicitRelocModel()); 1037 CodeGen.setFreestanding(EnableFreestanding); 1038 CodeGen.setDebugPassManager(DebugPassManager); 1039 1040 CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); 1041 CodeGen.setTargetOptions(Options); 1042 CodeGen.setShouldRestoreGlobalsLinkage(RestoreGlobalsLinkage); 1043 1044 StringSet<MallocAllocator> DSOSymbolsSet; 1045 for (unsigned i = 0; i < DSOSymbols.size(); ++i) 1046 DSOSymbolsSet.insert(DSOSymbols[i]); 1047 1048 std::vector<std::string> KeptDSOSyms; 1049 1050 for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { 1051 CurrentActivity = "loading file '" + InputFilenames[i] + "'"; 1052 ErrorOr<std::unique_ptr<LTOModule>> ModuleOrErr = 1053 LTOModule::createFromFile(Context, InputFilenames[i], Options); 1054 std::unique_ptr<LTOModule> &Module = *ModuleOrErr; 1055 CurrentActivity = ""; 1056 1057 unsigned NumSyms = Module->getSymbolCount(); 1058 for (unsigned I = 0; I < NumSyms; ++I) { 1059 StringRef Name = Module->getSymbolName(I); 1060 if (!DSOSymbolsSet.count(Name)) 1061 continue; 1062 lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); 1063 unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; 1064 if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) 1065 KeptDSOSyms.push_back(std::string(Name)); 1066 } 1067 1068 // We use the first input module as the destination module when 1069 // SetMergedModule is true. 1070 if (SetMergedModule && i == BaseArg) { 1071 // Transfer ownership to the code generator. 1072 CodeGen.setModule(std::move(Module)); 1073 } else if (!CodeGen.addModule(Module.get())) { 1074 // Print a message here so that we know addModule() did not abort. 1075 error("error adding file '" + InputFilenames[i] + "'"); 1076 } 1077 } 1078 1079 // Add all the exported symbols to the table of symbols to preserve. 1080 for (unsigned i = 0; i < ExportedSymbols.size(); ++i) 1081 CodeGen.addMustPreserveSymbol(ExportedSymbols[i]); 1082 1083 // Add all the dso symbols to the table of symbols to expose. 1084 for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) 1085 CodeGen.addMustPreserveSymbol(KeptDSOSyms[i]); 1086 1087 // Set cpu and attrs strings for the default target/subtarget. 1088 CodeGen.setCpu(codegen::getMCPU()); 1089 1090 CodeGen.setOptLevel(OptLevel - '0'); 1091 CodeGen.setAttrs(codegen::getMAttrs()); 1092 1093 if (auto FT = codegen::getExplicitFileType()) 1094 CodeGen.setFileType(*FT); 1095 1096 if (!OutputFilename.empty()) { 1097 if (LTOSaveBeforeOpt) 1098 CodeGen.setSaveIRBeforeOptPath(OutputFilename + ".0.preopt.bc"); 1099 1100 if (SaveLinkedModuleFile) { 1101 std::string ModuleFilename = OutputFilename; 1102 ModuleFilename += ".linked.bc"; 1103 std::string ErrMsg; 1104 1105 if (!CodeGen.writeMergedModules(ModuleFilename)) 1106 error("writing linked module failed."); 1107 } 1108 1109 if (!CodeGen.optimize()) { 1110 // Diagnostic messages should have been printed by the handler. 1111 error("error optimizing the code"); 1112 } 1113 1114 if (SaveModuleFile) { 1115 std::string ModuleFilename = OutputFilename; 1116 ModuleFilename += ".merged.bc"; 1117 std::string ErrMsg; 1118 1119 if (!CodeGen.writeMergedModules(ModuleFilename)) 1120 error("writing merged module failed."); 1121 } 1122 1123 auto AddStream = 1124 [&](size_t Task, 1125 const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> { 1126 std::string PartFilename = OutputFilename; 1127 if (Parallelism != 1) 1128 PartFilename += "." + utostr(Task); 1129 1130 std::error_code EC; 1131 auto S = 1132 std::make_unique<raw_fd_ostream>(PartFilename, EC, sys::fs::OF_None); 1133 if (EC) 1134 error("error opening the file '" + PartFilename + "': " + EC.message()); 1135 return std::make_unique<CachedFileStream>(std::move(S)); 1136 }; 1137 1138 if (!CodeGen.compileOptimized(AddStream, Parallelism)) 1139 // Diagnostic messages should have been printed by the handler. 1140 error("error compiling the code"); 1141 1142 } else { 1143 if (Parallelism != 1) 1144 error("-j must be specified together with -o"); 1145 1146 if (SaveModuleFile) 1147 error(": -save-merged-module must be specified with -o"); 1148 1149 const char *OutputName = nullptr; 1150 if (!CodeGen.compile_to_file(&OutputName)) 1151 error("error compiling the code"); 1152 // Diagnostic messages should have been printed by the handler. 1153 1154 outs() << "Wrote native object file '" << OutputName << "'\n"; 1155 } 1156 1157 return 0; 1158 } 1159