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