1 //===-LTO.cpp - LLVM Link Time Optimizer ----------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements functions and classes used to support LTO. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/LTO/LTO.h" 15 #include "llvm/Analysis/TargetLibraryInfo.h" 16 #include "llvm/Analysis/TargetTransformInfo.h" 17 #include "llvm/Bitcode/BitcodeReader.h" 18 #include "llvm/Bitcode/BitcodeWriter.h" 19 #include "llvm/CodeGen/Analysis.h" 20 #include "llvm/IR/AutoUpgrade.h" 21 #include "llvm/IR/DiagnosticPrinter.h" 22 #include "llvm/IR/LegacyPassManager.h" 23 #include "llvm/LTO/LTOBackend.h" 24 #include "llvm/Linker/IRMover.h" 25 #include "llvm/Object/ModuleSummaryIndexObjectFile.h" 26 #include "llvm/Support/ManagedStatic.h" 27 #include "llvm/Support/MemoryBuffer.h" 28 #include "llvm/Support/Path.h" 29 #include "llvm/Support/SHA1.h" 30 #include "llvm/Support/SourceMgr.h" 31 #include "llvm/Support/TargetRegistry.h" 32 #include "llvm/Support/ThreadPool.h" 33 #include "llvm/Support/Threading.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include "llvm/Target/TargetMachine.h" 36 #include "llvm/Target/TargetOptions.h" 37 #include "llvm/Transforms/IPO.h" 38 #include "llvm/Transforms/IPO/PassManagerBuilder.h" 39 #include "llvm/Transforms/Utils/SplitModule.h" 40 41 #include <set> 42 43 using namespace llvm; 44 using namespace lto; 45 using namespace object; 46 47 #define DEBUG_TYPE "lto" 48 49 // Returns a unique hash for the Module considering the current list of 50 // export/import and other global analysis results. 51 // The hash is produced in \p Key. 52 static void computeCacheKey( 53 SmallString<40> &Key, const Config &Conf, const ModuleSummaryIndex &Index, 54 StringRef ModuleID, const FunctionImporter::ImportMapTy &ImportList, 55 const FunctionImporter::ExportSetTy &ExportList, 56 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 57 const GVSummaryMapTy &DefinedGlobals) { 58 // Compute the unique hash for this entry. 59 // This is based on the current compiler version, the module itself, the 60 // export list, the hash for every single module in the import list, the 61 // list of ResolvedODR for the module, and the list of preserved symbols. 62 SHA1 Hasher; 63 64 // Start with the compiler revision 65 Hasher.update(LLVM_VERSION_STRING); 66 #ifdef HAVE_LLVM_REVISION 67 Hasher.update(LLVM_REVISION); 68 #endif 69 70 // Include the parts of the LTO configuration that affect code generation. 71 auto AddString = [&](StringRef Str) { 72 Hasher.update(Str); 73 Hasher.update(ArrayRef<uint8_t>{0}); 74 }; 75 auto AddUnsigned = [&](unsigned I) { 76 uint8_t Data[4]; 77 Data[0] = I; 78 Data[1] = I >> 8; 79 Data[2] = I >> 16; 80 Data[3] = I >> 24; 81 Hasher.update(ArrayRef<uint8_t>{Data, 4}); 82 }; 83 AddString(Conf.CPU); 84 // FIXME: Hash more of Options. For now all clients initialize Options from 85 // command-line flags (which is unsupported in production), but may set 86 // RelaxELFRelocations. The clang driver can also pass FunctionSections, 87 // DataSections and DebuggerTuning via command line flags. 88 AddUnsigned(Conf.Options.RelaxELFRelocations); 89 AddUnsigned(Conf.Options.FunctionSections); 90 AddUnsigned(Conf.Options.DataSections); 91 AddUnsigned((unsigned)Conf.Options.DebuggerTuning); 92 for (auto &A : Conf.MAttrs) 93 AddString(A); 94 AddUnsigned(Conf.RelocModel); 95 AddUnsigned(Conf.CodeModel); 96 AddUnsigned(Conf.CGOptLevel); 97 AddUnsigned(Conf.OptLevel); 98 AddString(Conf.OptPipeline); 99 AddString(Conf.AAPipeline); 100 AddString(Conf.OverrideTriple); 101 AddString(Conf.DefaultTriple); 102 103 // Include the hash for the current module 104 auto ModHash = Index.getModuleHash(ModuleID); 105 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash))); 106 for (auto F : ExportList) 107 // The export list can impact the internalization, be conservative here 108 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&F, sizeof(F))); 109 110 // Include the hash for every module we import functions from 111 for (auto &Entry : ImportList) { 112 auto ModHash = Index.getModuleHash(Entry.first()); 113 Hasher.update(ArrayRef<uint8_t>((uint8_t *)&ModHash[0], sizeof(ModHash))); 114 } 115 116 // Include the hash for the resolved ODR. 117 for (auto &Entry : ResolvedODR) { 118 Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.first, 119 sizeof(GlobalValue::GUID))); 120 Hasher.update(ArrayRef<uint8_t>((const uint8_t *)&Entry.second, 121 sizeof(GlobalValue::LinkageTypes))); 122 } 123 124 // Include the hash for the linkage type to reflect internalization and weak 125 // resolution. 126 for (auto &GS : DefinedGlobals) { 127 GlobalValue::LinkageTypes Linkage = GS.second->linkage(); 128 Hasher.update( 129 ArrayRef<uint8_t>((const uint8_t *)&Linkage, sizeof(Linkage))); 130 } 131 132 Key = toHex(Hasher.result()); 133 } 134 135 static void thinLTOResolveWeakForLinkerGUID( 136 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 137 DenseSet<GlobalValueSummary *> &GlobalInvolvedWithAlias, 138 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 139 isPrevailing, 140 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 141 recordNewLinkage) { 142 for (auto &S : GVSummaryList) { 143 GlobalValue::LinkageTypes OriginalLinkage = S->linkage(); 144 if (!GlobalValue::isWeakForLinker(OriginalLinkage)) 145 continue; 146 // We need to emit only one of these. The prevailing module will keep it, 147 // but turned into a weak, while the others will drop it when possible. 148 // This is both a compile-time optimization and a correctness 149 // transformation. This is necessary for correctness when we have exported 150 // a reference - we need to convert the linkonce to weak to 151 // ensure a copy is kept to satisfy the exported reference. 152 // FIXME: We may want to split the compile time and correctness 153 // aspects into separate routines. 154 if (isPrevailing(GUID, S.get())) { 155 if (GlobalValue::isLinkOnceLinkage(OriginalLinkage)) 156 S->setLinkage(GlobalValue::getWeakLinkage( 157 GlobalValue::isLinkOnceODRLinkage(OriginalLinkage))); 158 } 159 // Alias and aliasee can't be turned into available_externally. 160 else if (!isa<AliasSummary>(S.get()) && 161 !GlobalInvolvedWithAlias.count(S.get()) && 162 (GlobalValue::isLinkOnceODRLinkage(OriginalLinkage) || 163 GlobalValue::isWeakODRLinkage(OriginalLinkage))) 164 S->setLinkage(GlobalValue::AvailableExternallyLinkage); 165 if (S->linkage() != OriginalLinkage) 166 recordNewLinkage(S->modulePath(), GUID, S->linkage()); 167 } 168 } 169 170 // Resolve Weak and LinkOnce values in the \p Index. 171 // 172 // We'd like to drop these functions if they are no longer referenced in the 173 // current module. However there is a chance that another module is still 174 // referencing them because of the import. We make sure we always emit at least 175 // one copy. 176 void llvm::thinLTOResolveWeakForLinkerInIndex( 177 ModuleSummaryIndex &Index, 178 function_ref<bool(GlobalValue::GUID, const GlobalValueSummary *)> 179 isPrevailing, 180 function_ref<void(StringRef, GlobalValue::GUID, GlobalValue::LinkageTypes)> 181 recordNewLinkage) { 182 // We won't optimize the globals that are referenced by an alias for now 183 // Ideally we should turn the alias into a global and duplicate the definition 184 // when needed. 185 DenseSet<GlobalValueSummary *> GlobalInvolvedWithAlias; 186 for (auto &I : Index) 187 for (auto &S : I.second) 188 if (auto AS = dyn_cast<AliasSummary>(S.get())) 189 GlobalInvolvedWithAlias.insert(&AS->getAliasee()); 190 191 for (auto &I : Index) 192 thinLTOResolveWeakForLinkerGUID(I.second, I.first, GlobalInvolvedWithAlias, 193 isPrevailing, recordNewLinkage); 194 } 195 196 static void thinLTOInternalizeAndPromoteGUID( 197 GlobalValueSummaryList &GVSummaryList, GlobalValue::GUID GUID, 198 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 199 for (auto &S : GVSummaryList) { 200 if (isExported(S->modulePath(), GUID)) { 201 if (GlobalValue::isLocalLinkage(S->linkage())) 202 S->setLinkage(GlobalValue::ExternalLinkage); 203 } else if (!GlobalValue::isLocalLinkage(S->linkage())) 204 S->setLinkage(GlobalValue::InternalLinkage); 205 } 206 } 207 208 // Update the linkages in the given \p Index to mark exported values 209 // as external and non-exported values as internal. 210 void llvm::thinLTOInternalizeAndPromoteInIndex( 211 ModuleSummaryIndex &Index, 212 function_ref<bool(StringRef, GlobalValue::GUID)> isExported) { 213 for (auto &I : Index) 214 thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); 215 } 216 217 Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { 218 std::unique_ptr<InputFile> File(new InputFile); 219 220 Expected<std::unique_ptr<object::IRObjectFile>> IRObj = 221 IRObjectFile::create(Object, File->Ctx); 222 if (!IRObj) 223 return IRObj.takeError(); 224 File->Obj = std::move(*IRObj); 225 226 for (const auto &C : File->Obj->getModule().getComdatSymbolTable()) { 227 auto P = 228 File->ComdatMap.insert(std::make_pair(&C.second, File->Comdats.size())); 229 assert(P.second); 230 (void)P; 231 File->Comdats.push_back(C.first()); 232 } 233 234 return std::move(File); 235 } 236 237 Expected<int> InputFile::Symbol::getComdatIndex() const { 238 if (!GV) 239 return -1; 240 const GlobalObject *GO; 241 if (auto *GA = dyn_cast<GlobalAlias>(GV)) { 242 GO = GA->getBaseObject(); 243 if (!GO) 244 return make_error<StringError>("Unable to determine comdat of alias!", 245 inconvertibleErrorCode()); 246 } else { 247 GO = cast<GlobalObject>(GV); 248 } 249 if (const Comdat *C = GO->getComdat()) { 250 auto I = File->ComdatMap.find(C); 251 assert(I != File->ComdatMap.end()); 252 return I->second; 253 } 254 return -1; 255 } 256 257 LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, 258 Config &Conf) 259 : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), 260 Ctx(Conf) {} 261 262 LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) { 263 if (!Backend) 264 this->Backend = 265 createInProcessThinBackend(llvm::heavyweight_hardware_concurrency()); 266 } 267 268 LTO::LTO(Config Conf, ThinBackend Backend, 269 unsigned ParallelCodeGenParallelismLevel) 270 : Conf(std::move(Conf)), 271 RegularLTO(ParallelCodeGenParallelismLevel, this->Conf), 272 ThinLTO(std::move(Backend)) {} 273 274 // Add the given symbol to the GlobalResolutions map, and resolve its partition. 275 void LTO::addSymbolToGlobalRes(IRObjectFile *Obj, 276 SmallPtrSet<GlobalValue *, 8> &Used, 277 const InputFile::Symbol &Sym, 278 SymbolResolution Res, unsigned Partition) { 279 GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 280 281 auto &GlobalRes = GlobalResolutions[Sym.getName()]; 282 if (GV) { 283 GlobalRes.UnnamedAddr &= GV->hasGlobalUnnamedAddr(); 284 if (Res.Prevailing) 285 GlobalRes.IRName = GV->getName(); 286 } 287 if (Res.VisibleToRegularObj || (GV && Used.count(GV)) || 288 (GlobalRes.Partition != GlobalResolution::Unknown && 289 GlobalRes.Partition != Partition)) 290 GlobalRes.Partition = GlobalResolution::External; 291 else 292 GlobalRes.Partition = Partition; 293 } 294 295 static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, 296 ArrayRef<SymbolResolution> Res) { 297 StringRef Path = Input->getMemoryBufferRef().getBufferIdentifier(); 298 OS << Path << '\n'; 299 auto ResI = Res.begin(); 300 for (const InputFile::Symbol &Sym : Input->symbols()) { 301 assert(ResI != Res.end()); 302 SymbolResolution Res = *ResI++; 303 304 OS << "-r=" << Path << ',' << Sym.getName() << ','; 305 if (Res.Prevailing) 306 OS << 'p'; 307 if (Res.FinalDefinitionInLinkageUnit) 308 OS << 'l'; 309 if (Res.VisibleToRegularObj) 310 OS << 'x'; 311 OS << '\n'; 312 } 313 assert(ResI == Res.end()); 314 } 315 316 Error LTO::add(std::unique_ptr<InputFile> Input, 317 ArrayRef<SymbolResolution> Res) { 318 assert(!CalledGetMaxTasks); 319 320 if (Conf.ResolutionFile) 321 writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); 322 323 // FIXME: move to backend 324 Module &M = Input->Obj->getModule(); 325 if (!Conf.OverrideTriple.empty()) 326 M.setTargetTriple(Conf.OverrideTriple); 327 else if (M.getTargetTriple().empty()) 328 M.setTargetTriple(Conf.DefaultTriple); 329 330 MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); 331 Expected<bool> HasThinLTOSummary = hasGlobalValueSummary(MBRef); 332 if (!HasThinLTOSummary) 333 return HasThinLTOSummary.takeError(); 334 335 if (*HasThinLTOSummary) 336 return addThinLTO(std::move(Input), Res); 337 else 338 return addRegularLTO(std::move(Input), Res); 339 } 340 341 // Add a regular LTO object to the link. 342 Error LTO::addRegularLTO(std::unique_ptr<InputFile> Input, 343 ArrayRef<SymbolResolution> Res) { 344 if (!RegularLTO.CombinedModule) { 345 RegularLTO.CombinedModule = 346 llvm::make_unique<Module>("ld-temp.o", RegularLTO.Ctx); 347 RegularLTO.Mover = llvm::make_unique<IRMover>(*RegularLTO.CombinedModule); 348 } 349 Expected<std::unique_ptr<object::IRObjectFile>> ObjOrErr = 350 IRObjectFile::create(Input->Obj->getMemoryBufferRef(), RegularLTO.Ctx); 351 if (!ObjOrErr) 352 return ObjOrErr.takeError(); 353 std::unique_ptr<object::IRObjectFile> Obj = std::move(*ObjOrErr); 354 355 Module &M = Obj->getModule(); 356 if (Error Err = M.materializeMetadata()) 357 return Err; 358 UpgradeDebugInfo(M); 359 360 SmallPtrSet<GlobalValue *, 8> Used; 361 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 362 363 std::vector<GlobalValue *> Keep; 364 365 for (GlobalVariable &GV : M.globals()) 366 if (GV.hasAppendingLinkage()) 367 Keep.push_back(&GV); 368 369 auto ResI = Res.begin(); 370 for (const InputFile::Symbol &Sym : 371 make_range(InputFile::symbol_iterator(Obj->symbol_begin(), nullptr), 372 InputFile::symbol_iterator(Obj->symbol_end(), nullptr))) { 373 assert(ResI != Res.end()); 374 SymbolResolution Res = *ResI++; 375 addSymbolToGlobalRes(Obj.get(), Used, Sym, Res, 0); 376 377 GlobalValue *GV = Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 378 if (Sym.getFlags() & object::BasicSymbolRef::SF_Undefined) 379 continue; 380 if (Res.Prevailing && GV) { 381 Keep.push_back(GV); 382 switch (GV->getLinkage()) { 383 default: 384 break; 385 case GlobalValue::LinkOnceAnyLinkage: 386 GV->setLinkage(GlobalValue::WeakAnyLinkage); 387 break; 388 case GlobalValue::LinkOnceODRLinkage: 389 GV->setLinkage(GlobalValue::WeakODRLinkage); 390 break; 391 } 392 } 393 // Common resolution: collect the maximum size/alignment over all commons. 394 // We also record if we see an instance of a common as prevailing, so that 395 // if none is prevailing we can ignore it later. 396 if (Sym.getFlags() & object::BasicSymbolRef::SF_Common) { 397 // FIXME: We should figure out what to do about commons defined by asm. 398 // For now they aren't reported correctly by ModuleSymbolTable. 399 assert(GV); 400 auto &CommonRes = RegularLTO.Commons[GV->getName()]; 401 CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize()); 402 CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment()); 403 CommonRes.Prevailing |= Res.Prevailing; 404 } 405 406 // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit. 407 } 408 assert(ResI == Res.end()); 409 410 return RegularLTO.Mover->move(Obj->takeModule(), Keep, 411 [](GlobalValue &, IRMover::ValueAdder) {}, 412 /* LinkModuleInlineAsm */ true); 413 } 414 415 // Add a ThinLTO object to the link. 416 Error LTO::addThinLTO(std::unique_ptr<InputFile> Input, 417 ArrayRef<SymbolResolution> Res) { 418 Module &M = Input->Obj->getModule(); 419 SmallPtrSet<GlobalValue *, 8> Used; 420 collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); 421 422 MemoryBufferRef MBRef = Input->Obj->getMemoryBufferRef(); 423 Expected<std::unique_ptr<object::ModuleSummaryIndexObjectFile>> 424 SummaryObjOrErr = object::ModuleSummaryIndexObjectFile::create(MBRef); 425 if (!SummaryObjOrErr) 426 return SummaryObjOrErr.takeError(); 427 ThinLTO.CombinedIndex.mergeFrom((*SummaryObjOrErr)->takeIndex(), 428 ThinLTO.ModuleMap.size()); 429 430 auto ResI = Res.begin(); 431 for (const InputFile::Symbol &Sym : Input->symbols()) { 432 assert(ResI != Res.end()); 433 SymbolResolution Res = *ResI++; 434 addSymbolToGlobalRes(Input->Obj.get(), Used, Sym, Res, 435 ThinLTO.ModuleMap.size() + 1); 436 437 GlobalValue *GV = Input->Obj->getSymbolGV(Sym.I->getRawDataRefImpl()); 438 if (Res.Prevailing && GV) 439 ThinLTO.PrevailingModuleForGUID[GV->getGUID()] = 440 MBRef.getBufferIdentifier(); 441 } 442 assert(ResI == Res.end()); 443 444 ThinLTO.ModuleMap[MBRef.getBufferIdentifier()] = MBRef; 445 return Error::success(); 446 } 447 448 unsigned LTO::getMaxTasks() const { 449 CalledGetMaxTasks = true; 450 return RegularLTO.ParallelCodeGenParallelismLevel + ThinLTO.ModuleMap.size(); 451 } 452 453 Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { 454 // Save the status of having a regularLTO combined module, as 455 // this is needed for generating the ThinLTO Task ID, and 456 // the CombinedModule will be moved at the end of runRegularLTO. 457 bool HasRegularLTO = RegularLTO.CombinedModule != nullptr; 458 // Invoke regular LTO if there was a regular LTO module to start with. 459 if (HasRegularLTO) 460 if (auto E = runRegularLTO(AddStream)) 461 return E; 462 return runThinLTO(AddStream, Cache, HasRegularLTO); 463 } 464 465 Error LTO::runRegularLTO(AddStreamFn AddStream) { 466 // Make sure commons have the right size/alignment: we kept the largest from 467 // all the prevailing when adding the inputs, and we apply it here. 468 const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout(); 469 for (auto &I : RegularLTO.Commons) { 470 if (!I.second.Prevailing) 471 // Don't do anything if no instance of this common was prevailing. 472 continue; 473 GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first); 474 if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) { 475 // Don't create a new global if the type is already correct, just make 476 // sure the alignment is correct. 477 OldGV->setAlignment(I.second.Align); 478 continue; 479 } 480 ArrayType *Ty = 481 ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size); 482 auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false, 483 GlobalValue::CommonLinkage, 484 ConstantAggregateZero::get(Ty), ""); 485 GV->setAlignment(I.second.Align); 486 if (OldGV) { 487 OldGV->replaceAllUsesWith(ConstantExpr::getBitCast(GV, OldGV->getType())); 488 GV->takeName(OldGV); 489 OldGV->eraseFromParent(); 490 } else { 491 GV->setName(I.first); 492 } 493 } 494 495 if (Conf.PreOptModuleHook && 496 !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule)) 497 return Error::success(); 498 499 if (!Conf.CodeGenOnly) { 500 for (const auto &R : GlobalResolutions) { 501 if (R.second.IRName.empty()) 502 continue; 503 if (R.second.Partition != 0 && 504 R.second.Partition != GlobalResolution::External) 505 continue; 506 507 GlobalValue *GV = 508 RegularLTO.CombinedModule->getNamedValue(R.second.IRName); 509 // Ignore symbols defined in other partitions. 510 if (!GV || GV->hasLocalLinkage()) 511 continue; 512 GV->setUnnamedAddr(R.second.UnnamedAddr ? GlobalValue::UnnamedAddr::Global 513 : GlobalValue::UnnamedAddr::None); 514 if (R.second.Partition == 0) 515 GV->setLinkage(GlobalValue::InternalLinkage); 516 } 517 518 if (Conf.PostInternalizeModuleHook && 519 !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) 520 return Error::success(); 521 } 522 return backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, 523 std::move(RegularLTO.CombinedModule)); 524 } 525 526 /// This class defines the interface to the ThinLTO backend. 527 class lto::ThinBackendProc { 528 protected: 529 Config &Conf; 530 ModuleSummaryIndex &CombinedIndex; 531 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries; 532 533 public: 534 ThinBackendProc(Config &Conf, ModuleSummaryIndex &CombinedIndex, 535 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries) 536 : Conf(Conf), CombinedIndex(CombinedIndex), 537 ModuleToDefinedGVSummaries(ModuleToDefinedGVSummaries) {} 538 539 virtual ~ThinBackendProc() {} 540 virtual Error start( 541 unsigned Task, MemoryBufferRef MBRef, 542 const FunctionImporter::ImportMapTy &ImportList, 543 const FunctionImporter::ExportSetTy &ExportList, 544 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 545 MapVector<StringRef, MemoryBufferRef> &ModuleMap) = 0; 546 virtual Error wait() = 0; 547 }; 548 549 namespace { 550 class InProcessThinBackend : public ThinBackendProc { 551 ThreadPool BackendThreadPool; 552 AddStreamFn AddStream; 553 NativeObjectCache Cache; 554 555 Optional<Error> Err; 556 std::mutex ErrMu; 557 558 public: 559 InProcessThinBackend( 560 Config &Conf, ModuleSummaryIndex &CombinedIndex, 561 unsigned ThinLTOParallelismLevel, 562 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 563 AddStreamFn AddStream, NativeObjectCache Cache) 564 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), 565 BackendThreadPool(ThinLTOParallelismLevel), 566 AddStream(std::move(AddStream)), Cache(std::move(Cache)) {} 567 568 Error runThinLTOBackendThread( 569 AddStreamFn AddStream, NativeObjectCache Cache, unsigned Task, 570 MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex, 571 const FunctionImporter::ImportMapTy &ImportList, 572 const FunctionImporter::ExportSetTy &ExportList, 573 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 574 const GVSummaryMapTy &DefinedGlobals, 575 MapVector<StringRef, MemoryBufferRef> &ModuleMap) { 576 auto RunThinBackend = [&](AddStreamFn AddStream) { 577 LTOLLVMContext BackendContext(Conf); 578 Expected<std::unique_ptr<Module>> MOrErr = 579 parseBitcodeFile(MBRef, BackendContext); 580 if (!MOrErr) 581 return MOrErr.takeError(); 582 583 return thinBackend(Conf, Task, AddStream, **MOrErr, CombinedIndex, 584 ImportList, DefinedGlobals, ModuleMap); 585 }; 586 587 auto ModuleID = MBRef.getBufferIdentifier(); 588 589 if (!Cache || !CombinedIndex.modulePaths().count(ModuleID) || 590 all_of(CombinedIndex.getModuleHash(ModuleID), 591 [](uint32_t V) { return V == 0; })) 592 // Cache disabled or no entry for this module in the combined index or 593 // no module hash. 594 return RunThinBackend(AddStream); 595 596 SmallString<40> Key; 597 // The module may be cached, this helps handling it. 598 computeCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList, ExportList, 599 ResolvedODR, DefinedGlobals); 600 if (AddStreamFn CacheAddStream = Cache(Task, Key)) 601 return RunThinBackend(CacheAddStream); 602 603 return Error::success(); 604 } 605 606 Error start( 607 unsigned Task, MemoryBufferRef MBRef, 608 const FunctionImporter::ImportMapTy &ImportList, 609 const FunctionImporter::ExportSetTy &ExportList, 610 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 611 MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { 612 StringRef ModulePath = MBRef.getBufferIdentifier(); 613 assert(ModuleToDefinedGVSummaries.count(ModulePath)); 614 const GVSummaryMapTy &DefinedGlobals = 615 ModuleToDefinedGVSummaries.find(ModulePath)->second; 616 BackendThreadPool.async( 617 [=](MemoryBufferRef MBRef, ModuleSummaryIndex &CombinedIndex, 618 const FunctionImporter::ImportMapTy &ImportList, 619 const FunctionImporter::ExportSetTy &ExportList, 620 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> 621 &ResolvedODR, 622 const GVSummaryMapTy &DefinedGlobals, 623 MapVector<StringRef, MemoryBufferRef> &ModuleMap) { 624 Error E = runThinLTOBackendThread( 625 AddStream, Cache, Task, MBRef, CombinedIndex, ImportList, 626 ExportList, ResolvedODR, DefinedGlobals, ModuleMap); 627 if (E) { 628 std::unique_lock<std::mutex> L(ErrMu); 629 if (Err) 630 Err = joinErrors(std::move(*Err), std::move(E)); 631 else 632 Err = std::move(E); 633 } 634 }, 635 MBRef, std::ref(CombinedIndex), std::ref(ImportList), 636 std::ref(ExportList), std::ref(ResolvedODR), std::ref(DefinedGlobals), 637 std::ref(ModuleMap)); 638 return Error::success(); 639 } 640 641 Error wait() override { 642 BackendThreadPool.wait(); 643 if (Err) 644 return std::move(*Err); 645 else 646 return Error::success(); 647 } 648 }; 649 } // end anonymous namespace 650 651 ThinBackend lto::createInProcessThinBackend(unsigned ParallelismLevel) { 652 return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, 653 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 654 AddStreamFn AddStream, NativeObjectCache Cache) { 655 return llvm::make_unique<InProcessThinBackend>( 656 Conf, CombinedIndex, ParallelismLevel, ModuleToDefinedGVSummaries, 657 AddStream, Cache); 658 }; 659 } 660 661 // Given the original \p Path to an output file, replace any path 662 // prefix matching \p OldPrefix with \p NewPrefix. Also, create the 663 // resulting directory if it does not yet exist. 664 std::string lto::getThinLTOOutputFile(const std::string &Path, 665 const std::string &OldPrefix, 666 const std::string &NewPrefix) { 667 if (OldPrefix.empty() && NewPrefix.empty()) 668 return Path; 669 SmallString<128> NewPath(Path); 670 llvm::sys::path::replace_path_prefix(NewPath, OldPrefix, NewPrefix); 671 StringRef ParentPath = llvm::sys::path::parent_path(NewPath.str()); 672 if (!ParentPath.empty()) { 673 // Make sure the new directory exists, creating it if necessary. 674 if (std::error_code EC = llvm::sys::fs::create_directories(ParentPath)) 675 llvm::errs() << "warning: could not create directory '" << ParentPath 676 << "': " << EC.message() << '\n'; 677 } 678 return NewPath.str(); 679 } 680 681 namespace { 682 class WriteIndexesThinBackend : public ThinBackendProc { 683 std::string OldPrefix, NewPrefix; 684 bool ShouldEmitImportsFiles; 685 686 std::string LinkedObjectsFileName; 687 std::unique_ptr<llvm::raw_fd_ostream> LinkedObjectsFile; 688 689 public: 690 WriteIndexesThinBackend( 691 Config &Conf, ModuleSummaryIndex &CombinedIndex, 692 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 693 std::string OldPrefix, std::string NewPrefix, bool ShouldEmitImportsFiles, 694 std::string LinkedObjectsFileName) 695 : ThinBackendProc(Conf, CombinedIndex, ModuleToDefinedGVSummaries), 696 OldPrefix(OldPrefix), NewPrefix(NewPrefix), 697 ShouldEmitImportsFiles(ShouldEmitImportsFiles), 698 LinkedObjectsFileName(LinkedObjectsFileName) {} 699 700 Error start( 701 unsigned Task, MemoryBufferRef MBRef, 702 const FunctionImporter::ImportMapTy &ImportList, 703 const FunctionImporter::ExportSetTy &ExportList, 704 const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, 705 MapVector<StringRef, MemoryBufferRef> &ModuleMap) override { 706 StringRef ModulePath = MBRef.getBufferIdentifier(); 707 std::string NewModulePath = 708 getThinLTOOutputFile(ModulePath, OldPrefix, NewPrefix); 709 710 std::error_code EC; 711 if (!LinkedObjectsFileName.empty()) { 712 if (!LinkedObjectsFile) { 713 LinkedObjectsFile = llvm::make_unique<raw_fd_ostream>( 714 LinkedObjectsFileName, EC, sys::fs::OpenFlags::F_None); 715 if (EC) 716 return errorCodeToError(EC); 717 } 718 *LinkedObjectsFile << NewModulePath << '\n'; 719 } 720 721 std::map<std::string, GVSummaryMapTy> ModuleToSummariesForIndex; 722 gatherImportedSummariesForModule(ModulePath, ModuleToDefinedGVSummaries, 723 ImportList, ModuleToSummariesForIndex); 724 725 raw_fd_ostream OS(NewModulePath + ".thinlto.bc", EC, 726 sys::fs::OpenFlags::F_None); 727 if (EC) 728 return errorCodeToError(EC); 729 WriteIndexToFile(CombinedIndex, OS, &ModuleToSummariesForIndex); 730 731 if (ShouldEmitImportsFiles) 732 return errorCodeToError( 733 EmitImportsFiles(ModulePath, NewModulePath + ".imports", ImportList)); 734 return Error::success(); 735 } 736 737 Error wait() override { return Error::success(); } 738 }; 739 } // end anonymous namespace 740 741 ThinBackend lto::createWriteIndexesThinBackend(std::string OldPrefix, 742 std::string NewPrefix, 743 bool ShouldEmitImportsFiles, 744 std::string LinkedObjectsFile) { 745 return [=](Config &Conf, ModuleSummaryIndex &CombinedIndex, 746 const StringMap<GVSummaryMapTy> &ModuleToDefinedGVSummaries, 747 AddStreamFn AddStream, NativeObjectCache Cache) { 748 return llvm::make_unique<WriteIndexesThinBackend>( 749 Conf, CombinedIndex, ModuleToDefinedGVSummaries, OldPrefix, NewPrefix, 750 ShouldEmitImportsFiles, LinkedObjectsFile); 751 }; 752 } 753 754 Error LTO::runThinLTO(AddStreamFn AddStream, NativeObjectCache Cache, 755 bool HasRegularLTO) { 756 if (ThinLTO.ModuleMap.empty()) 757 return Error::success(); 758 759 if (Conf.CombinedIndexHook && !Conf.CombinedIndexHook(ThinLTO.CombinedIndex)) 760 return Error::success(); 761 762 // Collect for each module the list of function it defines (GUID -> 763 // Summary). 764 StringMap<std::map<GlobalValue::GUID, GlobalValueSummary *>> 765 ModuleToDefinedGVSummaries(ThinLTO.ModuleMap.size()); 766 ThinLTO.CombinedIndex.collectDefinedGVSummariesPerModule( 767 ModuleToDefinedGVSummaries); 768 // Create entries for any modules that didn't have any GV summaries 769 // (either they didn't have any GVs to start with, or we suppressed 770 // generation of the summaries because they e.g. had inline assembly 771 // uses that couldn't be promoted/renamed on export). This is so 772 // InProcessThinBackend::start can still launch a backend thread, which 773 // is passed the map of summaries for the module, without any special 774 // handling for this case. 775 for (auto &Mod : ThinLTO.ModuleMap) 776 if (!ModuleToDefinedGVSummaries.count(Mod.first)) 777 ModuleToDefinedGVSummaries.try_emplace(Mod.first); 778 779 StringMap<FunctionImporter::ImportMapTy> ImportLists( 780 ThinLTO.ModuleMap.size()); 781 StringMap<FunctionImporter::ExportSetTy> ExportLists( 782 ThinLTO.ModuleMap.size()); 783 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR; 784 785 if (Conf.OptLevel > 0) { 786 ComputeCrossModuleImport(ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, 787 ImportLists, ExportLists); 788 789 std::set<GlobalValue::GUID> ExportedGUIDs; 790 for (auto &Res : GlobalResolutions) { 791 if (!Res.second.IRName.empty() && 792 Res.second.Partition == GlobalResolution::External) 793 ExportedGUIDs.insert(GlobalValue::getGUID(Res.second.IRName)); 794 } 795 796 auto isPrevailing = [&](GlobalValue::GUID GUID, 797 const GlobalValueSummary *S) { 798 return ThinLTO.PrevailingModuleForGUID[GUID] == S->modulePath(); 799 }; 800 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) { 801 const auto &ExportList = ExportLists.find(ModuleIdentifier); 802 return (ExportList != ExportLists.end() && 803 ExportList->second.count(GUID)) || 804 ExportedGUIDs.count(GUID); 805 }; 806 thinLTOInternalizeAndPromoteInIndex(ThinLTO.CombinedIndex, isExported); 807 808 auto recordNewLinkage = [&](StringRef ModuleIdentifier, 809 GlobalValue::GUID GUID, 810 GlobalValue::LinkageTypes NewLinkage) { 811 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage; 812 }; 813 814 thinLTOResolveWeakForLinkerInIndex(ThinLTO.CombinedIndex, isPrevailing, 815 recordNewLinkage); 816 } 817 818 std::unique_ptr<ThinBackendProc> BackendProc = 819 ThinLTO.Backend(Conf, ThinLTO.CombinedIndex, ModuleToDefinedGVSummaries, 820 AddStream, Cache); 821 822 // Partition numbers for ThinLTO jobs start at 1 (see comments for 823 // GlobalResolution in LTO.h). Task numbers, however, start at 824 // ParallelCodeGenParallelismLevel if an LTO module is present, as tasks 0 825 // through ParallelCodeGenParallelismLevel-1 are reserved for parallel code 826 // generation partitions. 827 unsigned Task = 828 HasRegularLTO ? RegularLTO.ParallelCodeGenParallelismLevel : 0; 829 unsigned Partition = 1; 830 831 for (auto &Mod : ThinLTO.ModuleMap) { 832 if (Error E = BackendProc->start(Task, Mod.second, ImportLists[Mod.first], 833 ExportLists[Mod.first], 834 ResolvedODR[Mod.first], ThinLTO.ModuleMap)) 835 return E; 836 837 ++Task; 838 ++Partition; 839 } 840 841 return BackendProc->wait(); 842 } 843