1311116Sdim//===- ThinLTOBitcodeWriter.cpp - Bitcode writing pass for ThinLTO --------===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim 9321369Sdim#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 10321369Sdim#include "llvm/Analysis/BasicAliasAnalysis.h" 11311116Sdim#include "llvm/Analysis/ModuleSummaryAnalysis.h" 12321369Sdim#include "llvm/Analysis/ProfileSummaryInfo.h" 13311116Sdim#include "llvm/Analysis/TypeMetadataUtils.h" 14311116Sdim#include "llvm/Bitcode/BitcodeWriter.h" 15311116Sdim#include "llvm/IR/Constants.h" 16321369Sdim#include "llvm/IR/DebugInfo.h" 17311116Sdim#include "llvm/IR/Intrinsics.h" 18311116Sdim#include "llvm/IR/Module.h" 19311116Sdim#include "llvm/IR/PassManager.h" 20360784Sdim#include "llvm/InitializePasses.h" 21341825Sdim#include "llvm/Object/ModuleSymbolTable.h" 22311116Sdim#include "llvm/Pass.h" 23311116Sdim#include "llvm/Support/ScopedPrinter.h" 24321369Sdim#include "llvm/Support/raw_ostream.h" 25321369Sdim#include "llvm/Transforms/IPO.h" 26321369Sdim#include "llvm/Transforms/IPO/FunctionAttrs.h" 27341825Sdim#include "llvm/Transforms/IPO/FunctionImport.h" 28360784Sdim#include "llvm/Transforms/IPO/LowerTypeTests.h" 29311116Sdim#include "llvm/Transforms/Utils/Cloning.h" 30321369Sdim#include "llvm/Transforms/Utils/ModuleUtils.h" 31311116Sdimusing namespace llvm; 32311116Sdim 33311116Sdimnamespace { 34311116Sdim 35311116Sdim// Promote each local-linkage entity defined by ExportM and used by ImportM by 36311116Sdim// changing visibility and appending the given ModuleId. 37321369Sdimvoid promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId, 38321369Sdim SetVector<GlobalValue *> &PromoteExtra) { 39321369Sdim DenseMap<const Comdat *, Comdat *> RenamedComdats; 40321369Sdim for (auto &ExportGV : ExportM.global_values()) { 41311116Sdim if (!ExportGV.hasLocalLinkage()) 42321369Sdim continue; 43311116Sdim 44321369Sdim auto Name = ExportGV.getName(); 45327952Sdim GlobalValue *ImportGV = nullptr; 46327952Sdim if (!PromoteExtra.count(&ExportGV)) { 47327952Sdim ImportGV = ImportM.getNamedValue(Name); 48327952Sdim if (!ImportGV) 49327952Sdim continue; 50327952Sdim ImportGV->removeDeadConstantUsers(); 51327952Sdim if (ImportGV->use_empty()) { 52327952Sdim ImportGV->eraseFromParent(); 53327952Sdim continue; 54327952Sdim } 55327952Sdim } 56311116Sdim 57321369Sdim std::string NewName = (Name + ModuleId).str(); 58311116Sdim 59321369Sdim if (const auto *C = ExportGV.getComdat()) 60321369Sdim if (C->getName() == Name) 61321369Sdim RenamedComdats.try_emplace(C, ExportM.getOrInsertComdat(NewName)); 62321369Sdim 63311116Sdim ExportGV.setName(NewName); 64311116Sdim ExportGV.setLinkage(GlobalValue::ExternalLinkage); 65311116Sdim ExportGV.setVisibility(GlobalValue::HiddenVisibility); 66311116Sdim 67321369Sdim if (ImportGV) { 68321369Sdim ImportGV->setName(NewName); 69321369Sdim ImportGV->setVisibility(GlobalValue::HiddenVisibility); 70321369Sdim } 71321369Sdim } 72311116Sdim 73321369Sdim if (!RenamedComdats.empty()) 74321369Sdim for (auto &GO : ExportM.global_objects()) 75321369Sdim if (auto *C = GO.getComdat()) { 76321369Sdim auto Replacement = RenamedComdats.find(C); 77321369Sdim if (Replacement != RenamedComdats.end()) 78321369Sdim GO.setComdat(Replacement->second); 79321369Sdim } 80311116Sdim} 81311116Sdim 82311116Sdim// Promote all internal (i.e. distinct) type ids used by the module by replacing 83311116Sdim// them with external type ids formed using the module id. 84311116Sdim// 85311116Sdim// Note that this needs to be done before we clone the module because each clone 86311116Sdim// will receive its own set of distinct metadata nodes. 87311116Sdimvoid promoteTypeIds(Module &M, StringRef ModuleId) { 88311116Sdim DenseMap<Metadata *, Metadata *> LocalToGlobal; 89311116Sdim auto ExternalizeTypeId = [&](CallInst *CI, unsigned ArgNo) { 90311116Sdim Metadata *MD = 91311116Sdim cast<MetadataAsValue>(CI->getArgOperand(ArgNo))->getMetadata(); 92311116Sdim 93311116Sdim if (isa<MDNode>(MD) && cast<MDNode>(MD)->isDistinct()) { 94311116Sdim Metadata *&GlobalMD = LocalToGlobal[MD]; 95311116Sdim if (!GlobalMD) { 96327952Sdim std::string NewName = (Twine(LocalToGlobal.size()) + ModuleId).str(); 97311116Sdim GlobalMD = MDString::get(M.getContext(), NewName); 98311116Sdim } 99311116Sdim 100311116Sdim CI->setArgOperand(ArgNo, 101311116Sdim MetadataAsValue::get(M.getContext(), GlobalMD)); 102311116Sdim } 103311116Sdim }; 104311116Sdim 105311116Sdim if (Function *TypeTestFunc = 106311116Sdim M.getFunction(Intrinsic::getName(Intrinsic::type_test))) { 107311116Sdim for (const Use &U : TypeTestFunc->uses()) { 108311116Sdim auto CI = cast<CallInst>(U.getUser()); 109311116Sdim ExternalizeTypeId(CI, 1); 110311116Sdim } 111311116Sdim } 112311116Sdim 113311116Sdim if (Function *TypeCheckedLoadFunc = 114311116Sdim M.getFunction(Intrinsic::getName(Intrinsic::type_checked_load))) { 115311116Sdim for (const Use &U : TypeCheckedLoadFunc->uses()) { 116311116Sdim auto CI = cast<CallInst>(U.getUser()); 117311116Sdim ExternalizeTypeId(CI, 2); 118311116Sdim } 119311116Sdim } 120311116Sdim 121311116Sdim for (GlobalObject &GO : M.global_objects()) { 122311116Sdim SmallVector<MDNode *, 1> MDs; 123311116Sdim GO.getMetadata(LLVMContext::MD_type, MDs); 124311116Sdim 125311116Sdim GO.eraseMetadata(LLVMContext::MD_type); 126311116Sdim for (auto MD : MDs) { 127311116Sdim auto I = LocalToGlobal.find(MD->getOperand(1)); 128311116Sdim if (I == LocalToGlobal.end()) { 129311116Sdim GO.addMetadata(LLVMContext::MD_type, *MD); 130311116Sdim continue; 131311116Sdim } 132311116Sdim GO.addMetadata( 133311116Sdim LLVMContext::MD_type, 134341825Sdim *MDNode::get(M.getContext(), {MD->getOperand(0), I->second})); 135311116Sdim } 136311116Sdim } 137311116Sdim} 138311116Sdim 139311116Sdim// Drop unused globals, and drop type information from function declarations. 140311116Sdim// FIXME: If we made functions typeless then there would be no need to do this. 141311116Sdimvoid simplifyExternals(Module &M) { 142311116Sdim FunctionType *EmptyFT = 143311116Sdim FunctionType::get(Type::getVoidTy(M.getContext()), false); 144311116Sdim 145311116Sdim for (auto I = M.begin(), E = M.end(); I != E;) { 146311116Sdim Function &F = *I++; 147311116Sdim if (F.isDeclaration() && F.use_empty()) { 148311116Sdim F.eraseFromParent(); 149311116Sdim continue; 150311116Sdim } 151311116Sdim 152327952Sdim if (!F.isDeclaration() || F.getFunctionType() == EmptyFT || 153327952Sdim // Changing the type of an intrinsic may invalidate the IR. 154327952Sdim F.getName().startswith("llvm.")) 155311116Sdim continue; 156311116Sdim 157311116Sdim Function *NewF = 158344779Sdim Function::Create(EmptyFT, GlobalValue::ExternalLinkage, 159344779Sdim F.getAddressSpace(), "", &M); 160311116Sdim NewF->setVisibility(F.getVisibility()); 161311116Sdim NewF->takeName(&F); 162311116Sdim F.replaceAllUsesWith(ConstantExpr::getBitCast(NewF, F.getType())); 163311116Sdim F.eraseFromParent(); 164311116Sdim } 165311116Sdim 166311116Sdim for (auto I = M.global_begin(), E = M.global_end(); I != E;) { 167311116Sdim GlobalVariable &GV = *I++; 168311116Sdim if (GV.isDeclaration() && GV.use_empty()) { 169311116Sdim GV.eraseFromParent(); 170311116Sdim continue; 171311116Sdim } 172311116Sdim } 173311116Sdim} 174311116Sdim 175341825Sdimstatic void 176341825SdimfilterModule(Module *M, 177341825Sdim function_ref<bool(const GlobalValue *)> ShouldKeepDefinition) { 178341825Sdim std::vector<GlobalValue *> V; 179341825Sdim for (GlobalValue &GV : M->global_values()) 180341825Sdim if (!ShouldKeepDefinition(&GV)) 181341825Sdim V.push_back(&GV); 182311116Sdim 183341825Sdim for (GlobalValue *GV : V) 184341825Sdim if (!convertToDeclaration(*GV)) 185341825Sdim GV->eraseFromParent(); 186311116Sdim} 187311116Sdim 188321369Sdimvoid forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) { 189321369Sdim if (auto *F = dyn_cast<Function>(C)) 190321369Sdim return Fn(F); 191321369Sdim if (isa<GlobalValue>(C)) 192321369Sdim return; 193321369Sdim for (Value *Op : C->operands()) 194321369Sdim forEachVirtualFunction(cast<Constant>(Op), Fn); 195321369Sdim} 196321369Sdim 197311116Sdim// If it's possible to split M into regular and thin LTO parts, do so and write 198311116Sdim// a multi-module bitcode file with the two parts to OS. Otherwise, write only a 199311116Sdim// regular LTO bitcode file to OS. 200321369Sdimvoid splitAndWriteThinLTOBitcode( 201321369Sdim raw_ostream &OS, raw_ostream *ThinLinkOS, 202321369Sdim function_ref<AAResults &(Function &)> AARGetter, Module &M) { 203321369Sdim std::string ModuleId = getUniqueModuleId(&M); 204311116Sdim if (ModuleId.empty()) { 205341825Sdim // We couldn't generate a module ID for this module, write it out as a 206341825Sdim // regular LTO module with an index for summary-based dead stripping. 207341825Sdim ProfileSummaryInfo PSI(M); 208341825Sdim M.addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); 209341825Sdim ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI); 210341825Sdim WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index); 211341825Sdim 212321369Sdim if (ThinLinkOS) 213321369Sdim // We don't have a ThinLTO part, but still write the module to the 214321369Sdim // ThinLinkOS if requested so that the expected output file is produced. 215341825Sdim WriteBitcodeToFile(M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false, 216341825Sdim &Index); 217341825Sdim 218311116Sdim return; 219311116Sdim } 220311116Sdim 221311116Sdim promoteTypeIds(M, ModuleId); 222311116Sdim 223360784Sdim // Returns whether a global or its associated global has attached type 224360784Sdim // metadata. The former may participate in CFI or whole-program 225360784Sdim // devirtualization, so they need to appear in the merged module instead of 226360784Sdim // the thin LTO module. Similarly, globals that are associated with globals 227360784Sdim // with type metadata need to appear in the merged module because they will 228360784Sdim // reference the global's section directly. 229341825Sdim auto HasTypeMetadata = [](const GlobalObject *GO) { 230360784Sdim if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated)) 231360784Sdim if (auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0))) 232360784Sdim if (auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue())) 233360784Sdim if (AssocGO->hasMetadata(LLVMContext::MD_type)) 234360784Sdim return true; 235341825Sdim return GO->hasMetadata(LLVMContext::MD_type); 236311116Sdim }; 237311116Sdim 238321369Sdim // Collect the set of virtual functions that are eligible for virtual constant 239321369Sdim // propagation. Each eligible function must not access memory, must return 240321369Sdim // an integer of width <=64 bits, must take at least one argument, must not 241321369Sdim // use its first argument (assumed to be "this") and all arguments other than 242321369Sdim // the first one must be of <=64 bit integer type. 243321369Sdim // 244321369Sdim // Note that we test whether this copy of the function is readnone, rather 245321369Sdim // than testing function attributes, which must hold for any copy of the 246321369Sdim // function, even a less optimized version substituted at link time. This is 247321369Sdim // sound because the virtual constant propagation optimizations effectively 248321369Sdim // inline all implementations of the virtual function into each call site, 249321369Sdim // rather than using function attributes to perform local optimization. 250344779Sdim DenseSet<const Function *> EligibleVirtualFns; 251321369Sdim // If any member of a comdat lives in MergedM, put all members of that 252321369Sdim // comdat in MergedM to keep the comdat together. 253321369Sdim DenseSet<const Comdat *> MergedMComdats; 254321369Sdim for (GlobalVariable &GV : M.globals()) 255321369Sdim if (HasTypeMetadata(&GV)) { 256321369Sdim if (const auto *C = GV.getComdat()) 257321369Sdim MergedMComdats.insert(C); 258321369Sdim forEachVirtualFunction(GV.getInitializer(), [&](Function *F) { 259321369Sdim auto *RT = dyn_cast<IntegerType>(F->getReturnType()); 260321369Sdim if (!RT || RT->getBitWidth() > 64 || F->arg_empty() || 261321369Sdim !F->arg_begin()->use_empty()) 262321369Sdim return; 263321369Sdim for (auto &Arg : make_range(std::next(F->arg_begin()), F->arg_end())) { 264321369Sdim auto *ArgT = dyn_cast<IntegerType>(Arg.getType()); 265321369Sdim if (!ArgT || ArgT->getBitWidth() > 64) 266321369Sdim return; 267321369Sdim } 268321369Sdim if (!F->isDeclaration() && 269321369Sdim computeFunctionBodyMemoryAccess(*F, AARGetter(*F)) == MAK_ReadNone) 270321369Sdim EligibleVirtualFns.insert(F); 271321369Sdim }); 272321369Sdim } 273321369Sdim 274311116Sdim ValueToValueMapTy VMap; 275321369Sdim std::unique_ptr<Module> MergedM( 276341825Sdim CloneModule(M, VMap, [&](const GlobalValue *GV) -> bool { 277321369Sdim if (const auto *C = GV->getComdat()) 278321369Sdim if (MergedMComdats.count(C)) 279321369Sdim return true; 280321369Sdim if (auto *F = dyn_cast<Function>(GV)) 281321369Sdim return EligibleVirtualFns.count(F); 282321369Sdim if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getBaseObject())) 283321369Sdim return HasTypeMetadata(GVar); 284321369Sdim return false; 285321369Sdim })); 286321369Sdim StripDebugInfo(*MergedM); 287341825Sdim MergedM->setModuleInlineAsm(""); 288311116Sdim 289321369Sdim for (Function &F : *MergedM) 290321369Sdim if (!F.isDeclaration()) { 291321369Sdim // Reset the linkage of all functions eligible for virtual constant 292321369Sdim // propagation. The canonical definitions live in the thin LTO module so 293321369Sdim // that they can be imported. 294321369Sdim F.setLinkage(GlobalValue::AvailableExternallyLinkage); 295321369Sdim F.setComdat(nullptr); 296321369Sdim } 297311116Sdim 298321369Sdim SetVector<GlobalValue *> CfiFunctions; 299321369Sdim for (auto &F : M) 300321369Sdim if ((!F.hasLocalLinkage() || F.hasAddressTaken()) && HasTypeMetadata(&F)) 301321369Sdim CfiFunctions.insert(&F); 302311116Sdim 303321369Sdim // Remove all globals with type metadata, globals with comdats that live in 304321369Sdim // MergedM, and aliases pointing to such globals from the thin LTO module. 305321369Sdim filterModule(&M, [&](const GlobalValue *GV) { 306321369Sdim if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getBaseObject())) 307321369Sdim if (HasTypeMetadata(GVar)) 308321369Sdim return false; 309321369Sdim if (const auto *C = GV->getComdat()) 310321369Sdim if (MergedMComdats.count(C)) 311321369Sdim return false; 312321369Sdim return true; 313321369Sdim }); 314321369Sdim 315321369Sdim promoteInternals(*MergedM, M, ModuleId, CfiFunctions); 316321369Sdim promoteInternals(M, *MergedM, ModuleId, CfiFunctions); 317321369Sdim 318341825Sdim auto &Ctx = MergedM->getContext(); 319321369Sdim SmallVector<MDNode *, 8> CfiFunctionMDs; 320321369Sdim for (auto V : CfiFunctions) { 321321369Sdim Function &F = *cast<Function>(V); 322321369Sdim SmallVector<MDNode *, 2> Types; 323321369Sdim F.getMetadata(LLVMContext::MD_type, Types); 324321369Sdim 325321369Sdim SmallVector<Metadata *, 4> Elts; 326321369Sdim Elts.push_back(MDString::get(Ctx, F.getName())); 327321369Sdim CfiFunctionLinkage Linkage; 328360784Sdim if (lowertypetests::isJumpTableCanonical(&F)) 329321369Sdim Linkage = CFL_Definition; 330360784Sdim else if (F.hasExternalWeakLinkage()) 331321369Sdim Linkage = CFL_WeakDeclaration; 332321369Sdim else 333321369Sdim Linkage = CFL_Declaration; 334321369Sdim Elts.push_back(ConstantAsMetadata::get( 335321369Sdim llvm::ConstantInt::get(Type::getInt8Ty(Ctx), Linkage))); 336321369Sdim for (auto Type : Types) 337321369Sdim Elts.push_back(Type); 338321369Sdim CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts)); 339321369Sdim } 340321369Sdim 341321369Sdim if(!CfiFunctionMDs.empty()) { 342321369Sdim NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("cfi.functions"); 343321369Sdim for (auto MD : CfiFunctionMDs) 344321369Sdim NMD->addOperand(MD); 345321369Sdim } 346321369Sdim 347341825Sdim SmallVector<MDNode *, 8> FunctionAliases; 348341825Sdim for (auto &A : M.aliases()) { 349341825Sdim if (!isa<Function>(A.getAliasee())) 350341825Sdim continue; 351341825Sdim 352341825Sdim auto *F = cast<Function>(A.getAliasee()); 353341825Sdim 354341825Sdim Metadata *Elts[] = { 355341825Sdim MDString::get(Ctx, A.getName()), 356341825Sdim MDString::get(Ctx, F->getName()), 357341825Sdim ConstantAsMetadata::get( 358341825Sdim ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())), 359341825Sdim ConstantAsMetadata::get( 360341825Sdim ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())), 361341825Sdim }; 362341825Sdim 363341825Sdim FunctionAliases.push_back(MDTuple::get(Ctx, Elts)); 364341825Sdim } 365341825Sdim 366341825Sdim if (!FunctionAliases.empty()) { 367341825Sdim NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases"); 368341825Sdim for (auto MD : FunctionAliases) 369341825Sdim NMD->addOperand(MD); 370341825Sdim } 371341825Sdim 372341825Sdim SmallVector<MDNode *, 8> Symvers; 373341825Sdim ModuleSymbolTable::CollectAsmSymvers(M, [&](StringRef Name, StringRef Alias) { 374341825Sdim Function *F = M.getFunction(Name); 375341825Sdim if (!F || F->use_empty()) 376341825Sdim return; 377341825Sdim 378341825Sdim Symvers.push_back(MDTuple::get( 379341825Sdim Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)})); 380341825Sdim }); 381341825Sdim 382341825Sdim if (!Symvers.empty()) { 383341825Sdim NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers"); 384341825Sdim for (auto MD : Symvers) 385341825Sdim NMD->addOperand(MD); 386341825Sdim } 387341825Sdim 388311116Sdim simplifyExternals(*MergedM); 389311116Sdim 390321369Sdim // FIXME: Try to re-use BSI and PFI from the original module here. 391321369Sdim ProfileSummaryInfo PSI(M); 392321369Sdim ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI); 393321369Sdim 394321369Sdim // Mark the merged module as requiring full LTO. We still want an index for 395321369Sdim // it though, so that it can participate in summary-based dead stripping. 396321369Sdim MergedM->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); 397321369Sdim ModuleSummaryIndex MergedMIndex = 398321369Sdim buildModuleSummaryIndex(*MergedM, nullptr, &PSI); 399321369Sdim 400311116Sdim SmallVector<char, 0> Buffer; 401321369Sdim 402311116Sdim BitcodeWriter W(Buffer); 403321369Sdim // Save the module hash produced for the full bitcode, which will 404321369Sdim // be used in the backends, and use that in the minimized bitcode 405321369Sdim // produced for the full link. 406321369Sdim ModuleHash ModHash = {{0}}; 407341825Sdim W.writeModule(M, /*ShouldPreserveUseListOrder=*/false, &Index, 408321369Sdim /*GenerateHash=*/true, &ModHash); 409341825Sdim W.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, &MergedMIndex); 410321369Sdim W.writeSymtab(); 411321369Sdim W.writeStrtab(); 412321369Sdim OS << Buffer; 413311116Sdim 414327952Sdim // If a minimized bitcode module was requested for the thin link, only 415327952Sdim // the information that is needed by thin link will be written in the 416327952Sdim // given OS (the merged module will be written as usual). 417321369Sdim if (ThinLinkOS) { 418321369Sdim Buffer.clear(); 419321369Sdim BitcodeWriter W2(Buffer); 420321369Sdim StripDebugInfo(M); 421341825Sdim W2.writeThinLinkBitcode(M, Index, ModHash); 422341825Sdim W2.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, 423321369Sdim &MergedMIndex); 424321369Sdim W2.writeSymtab(); 425321369Sdim W2.writeStrtab(); 426321369Sdim *ThinLinkOS << Buffer; 427321369Sdim } 428311116Sdim} 429311116Sdim 430353358Sdim// Check if the LTO Unit splitting has been enabled. 431353358Sdimbool enableSplitLTOUnit(Module &M) { 432344779Sdim bool EnableSplitLTOUnit = false; 433344779Sdim if (auto *MD = mdconst::extract_or_null<ConstantInt>( 434344779Sdim M.getModuleFlag("EnableSplitLTOUnit"))) 435344779Sdim EnableSplitLTOUnit = MD->getZExtValue(); 436353358Sdim return EnableSplitLTOUnit; 437353358Sdim} 438344779Sdim 439353358Sdim// Returns whether this module needs to be split because it uses type metadata. 440353358Sdimbool hasTypeMetadata(Module &M) { 441311116Sdim for (auto &GO : M.global_objects()) { 442341825Sdim if (GO.hasMetadata(LLVMContext::MD_type)) 443311116Sdim return true; 444311116Sdim } 445311116Sdim return false; 446311116Sdim} 447311116Sdim 448321369Sdimvoid writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS, 449321369Sdim function_ref<AAResults &(Function &)> AARGetter, 450321369Sdim Module &M, const ModuleSummaryIndex *Index) { 451353358Sdim std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr; 452353358Sdim // See if this module has any type metadata. If so, we try to split it 453353358Sdim // or at least promote type ids to enable WPD. 454353358Sdim if (hasTypeMetadata(M)) { 455353358Sdim if (enableSplitLTOUnit(M)) 456353358Sdim return splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M); 457353358Sdim // Promote type ids as needed for index-based WPD. 458353358Sdim std::string ModuleId = getUniqueModuleId(&M); 459353358Sdim if (!ModuleId.empty()) { 460353358Sdim promoteTypeIds(M, ModuleId); 461353358Sdim // Need to rebuild the index so that it contains type metadata 462353358Sdim // for the newly promoted type ids. 463353358Sdim // FIXME: Probably should not bother building the index at all 464353358Sdim // in the caller of writeThinLTOBitcode (which does so via the 465353358Sdim // ModuleSummaryIndexAnalysis pass), since we have to rebuild it 466353358Sdim // anyway whenever there is type metadata (here or in 467353358Sdim // splitAndWriteThinLTOBitcode). Just always build it once via the 468353358Sdim // buildModuleSummaryIndex when Module(s) are ready. 469353358Sdim ProfileSummaryInfo PSI(M); 470360784Sdim NewIndex = std::make_unique<ModuleSummaryIndex>( 471353358Sdim buildModuleSummaryIndex(M, nullptr, &PSI)); 472353358Sdim Index = NewIndex.get(); 473353358Sdim } 474353358Sdim } 475311116Sdim 476353358Sdim // Write it out as an unsplit ThinLTO module. 477321369Sdim 478321369Sdim // Save the module hash produced for the full bitcode, which will 479321369Sdim // be used in the backends, and use that in the minimized bitcode 480321369Sdim // produced for the full link. 481321369Sdim ModuleHash ModHash = {{0}}; 482341825Sdim WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, Index, 483321369Sdim /*GenerateHash=*/true, &ModHash); 484327952Sdim // If a minimized bitcode module was requested for the thin link, only 485327952Sdim // the information that is needed by thin link will be written in the 486327952Sdim // given OS. 487327952Sdim if (ThinLinkOS && Index) 488341825Sdim WriteThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash); 489311116Sdim} 490311116Sdim 491311116Sdimclass WriteThinLTOBitcode : public ModulePass { 492311116Sdim raw_ostream &OS; // raw_ostream to print on 493321369Sdim // The output stream on which to emit a minimized module for use 494321369Sdim // just in the thin link, if requested. 495321369Sdim raw_ostream *ThinLinkOS; 496311116Sdim 497311116Sdimpublic: 498311116Sdim static char ID; // Pass identification, replacement for typeid 499321369Sdim WriteThinLTOBitcode() : ModulePass(ID), OS(dbgs()), ThinLinkOS(nullptr) { 500311116Sdim initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry()); 501311116Sdim } 502311116Sdim 503321369Sdim explicit WriteThinLTOBitcode(raw_ostream &o, raw_ostream *ThinLinkOS) 504321369Sdim : ModulePass(ID), OS(o), ThinLinkOS(ThinLinkOS) { 505311116Sdim initializeWriteThinLTOBitcodePass(*PassRegistry::getPassRegistry()); 506311116Sdim } 507311116Sdim 508311116Sdim StringRef getPassName() const override { return "ThinLTO Bitcode Writer"; } 509311116Sdim 510311116Sdim bool runOnModule(Module &M) override { 511311116Sdim const ModuleSummaryIndex *Index = 512311116Sdim &(getAnalysis<ModuleSummaryIndexWrapperPass>().getIndex()); 513321369Sdim writeThinLTOBitcode(OS, ThinLinkOS, LegacyAARGetter(*this), M, Index); 514311116Sdim return true; 515311116Sdim } 516311116Sdim void getAnalysisUsage(AnalysisUsage &AU) const override { 517311116Sdim AU.setPreservesAll(); 518321369Sdim AU.addRequired<AssumptionCacheTracker>(); 519311116Sdim AU.addRequired<ModuleSummaryIndexWrapperPass>(); 520321369Sdim AU.addRequired<TargetLibraryInfoWrapperPass>(); 521311116Sdim } 522311116Sdim}; 523311116Sdim} // anonymous namespace 524311116Sdim 525311116Sdimchar WriteThinLTOBitcode::ID = 0; 526311116SdimINITIALIZE_PASS_BEGIN(WriteThinLTOBitcode, "write-thinlto-bitcode", 527311116Sdim "Write ThinLTO Bitcode", false, true) 528321369SdimINITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) 529311116SdimINITIALIZE_PASS_DEPENDENCY(ModuleSummaryIndexWrapperPass) 530321369SdimINITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 531311116SdimINITIALIZE_PASS_END(WriteThinLTOBitcode, "write-thinlto-bitcode", 532311116Sdim "Write ThinLTO Bitcode", false, true) 533311116Sdim 534321369SdimModulePass *llvm::createWriteThinLTOBitcodePass(raw_ostream &Str, 535321369Sdim raw_ostream *ThinLinkOS) { 536321369Sdim return new WriteThinLTOBitcode(Str, ThinLinkOS); 537311116Sdim} 538321369Sdim 539321369SdimPreservedAnalyses 540321369Sdimllvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) { 541321369Sdim FunctionAnalysisManager &FAM = 542321369Sdim AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 543321369Sdim writeThinLTOBitcode(OS, ThinLinkOS, 544321369Sdim [&FAM](Function &F) -> AAResults & { 545321369Sdim return FAM.getResult<AAManager>(F); 546321369Sdim }, 547321369Sdim M, &AM.getResult<ModuleSummaryIndexAnalysis>(M)); 548321369Sdim return PreservedAnalyses::all(); 549321369Sdim} 550