10b57cec5SDimitry Andric //===- ThinLTOBitcodeWriter.cpp - Bitcode writing pass for ThinLTO --------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" 100b57cec5SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h" 110b57cec5SDimitry Andric #include "llvm/Analysis/ModuleSummaryAnalysis.h" 120b57cec5SDimitry Andric #include "llvm/Analysis/ProfileSummaryInfo.h" 130b57cec5SDimitry Andric #include "llvm/Analysis/TypeMetadataUtils.h" 140b57cec5SDimitry Andric #include "llvm/Bitcode/BitcodeWriter.h" 150b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 160b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 17e8d8bef9SDimitry Andric #include "llvm/IR/Instructions.h" 180b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 190b57cec5SDimitry Andric #include "llvm/IR/Module.h" 200b57cec5SDimitry Andric #include "llvm/IR/PassManager.h" 210b57cec5SDimitry Andric #include "llvm/Object/ModuleSymbolTable.h" 220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 230b57cec5SDimitry Andric #include "llvm/Transforms/IPO.h" 240b57cec5SDimitry Andric #include "llvm/Transforms/IPO/FunctionAttrs.h" 250b57cec5SDimitry Andric #include "llvm/Transforms/IPO/FunctionImport.h" 268bcb0991SDimitry Andric #include "llvm/Transforms/IPO/LowerTypeTests.h" 270b57cec5SDimitry Andric #include "llvm/Transforms/Utils/Cloning.h" 280b57cec5SDimitry Andric #include "llvm/Transforms/Utils/ModuleUtils.h" 290b57cec5SDimitry Andric using namespace llvm; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric namespace { 320b57cec5SDimitry Andric 3369ade1e0SDimitry Andric // Determine if a promotion alias should be created for a symbol name. 3469ade1e0SDimitry Andric static bool allowPromotionAlias(const std::string &Name) { 3569ade1e0SDimitry Andric // Promotion aliases are used only in inline assembly. It's safe to 3669ade1e0SDimitry Andric // simply skip unusual names. Subset of MCAsmInfo::isAcceptableChar() 3769ade1e0SDimitry Andric // and MCAsmInfoXCOFF::isAcceptableChar(). 3869ade1e0SDimitry Andric for (const char &C : Name) { 3969ade1e0SDimitry Andric if (isAlnum(C) || C == '_' || C == '.') 4069ade1e0SDimitry Andric continue; 4169ade1e0SDimitry Andric return false; 4269ade1e0SDimitry Andric } 4369ade1e0SDimitry Andric return true; 4469ade1e0SDimitry Andric } 4569ade1e0SDimitry Andric 460b57cec5SDimitry Andric // Promote each local-linkage entity defined by ExportM and used by ImportM by 470b57cec5SDimitry Andric // changing visibility and appending the given ModuleId. 480b57cec5SDimitry Andric void promoteInternals(Module &ExportM, Module &ImportM, StringRef ModuleId, 490b57cec5SDimitry Andric SetVector<GlobalValue *> &PromoteExtra) { 500b57cec5SDimitry Andric DenseMap<const Comdat *, Comdat *> RenamedComdats; 510b57cec5SDimitry Andric for (auto &ExportGV : ExportM.global_values()) { 520b57cec5SDimitry Andric if (!ExportGV.hasLocalLinkage()) 530b57cec5SDimitry Andric continue; 540b57cec5SDimitry Andric 550b57cec5SDimitry Andric auto Name = ExportGV.getName(); 560b57cec5SDimitry Andric GlobalValue *ImportGV = nullptr; 570b57cec5SDimitry Andric if (!PromoteExtra.count(&ExportGV)) { 580b57cec5SDimitry Andric ImportGV = ImportM.getNamedValue(Name); 590b57cec5SDimitry Andric if (!ImportGV) 600b57cec5SDimitry Andric continue; 610b57cec5SDimitry Andric ImportGV->removeDeadConstantUsers(); 620b57cec5SDimitry Andric if (ImportGV->use_empty()) { 630b57cec5SDimitry Andric ImportGV->eraseFromParent(); 640b57cec5SDimitry Andric continue; 650b57cec5SDimitry Andric } 660b57cec5SDimitry Andric } 670b57cec5SDimitry Andric 6869ade1e0SDimitry Andric std::string OldName = Name.str(); 690b57cec5SDimitry Andric std::string NewName = (Name + ModuleId).str(); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric if (const auto *C = ExportGV.getComdat()) 720b57cec5SDimitry Andric if (C->getName() == Name) 730b57cec5SDimitry Andric RenamedComdats.try_emplace(C, ExportM.getOrInsertComdat(NewName)); 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric ExportGV.setName(NewName); 760b57cec5SDimitry Andric ExportGV.setLinkage(GlobalValue::ExternalLinkage); 770b57cec5SDimitry Andric ExportGV.setVisibility(GlobalValue::HiddenVisibility); 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric if (ImportGV) { 800b57cec5SDimitry Andric ImportGV->setName(NewName); 810b57cec5SDimitry Andric ImportGV->setVisibility(GlobalValue::HiddenVisibility); 820b57cec5SDimitry Andric } 8369ade1e0SDimitry Andric 8469ade1e0SDimitry Andric if (isa<Function>(&ExportGV) && allowPromotionAlias(OldName)) { 8569ade1e0SDimitry Andric // Create a local alias with the original name to avoid breaking 8669ade1e0SDimitry Andric // references from inline assembly. 870eae32dcSDimitry Andric std::string Alias = 880eae32dcSDimitry Andric ".lto_set_conditional " + OldName + "," + NewName + "\n"; 8969ade1e0SDimitry Andric ExportM.appendModuleInlineAsm(Alias); 9069ade1e0SDimitry Andric } 910b57cec5SDimitry Andric } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric if (!RenamedComdats.empty()) 940b57cec5SDimitry Andric for (auto &GO : ExportM.global_objects()) 950b57cec5SDimitry Andric if (auto *C = GO.getComdat()) { 960b57cec5SDimitry Andric auto Replacement = RenamedComdats.find(C); 970b57cec5SDimitry Andric if (Replacement != RenamedComdats.end()) 980b57cec5SDimitry Andric GO.setComdat(Replacement->second); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric // Promote all internal (i.e. distinct) type ids used by the module by replacing 1030b57cec5SDimitry Andric // them with external type ids formed using the module id. 1040b57cec5SDimitry Andric // 1050b57cec5SDimitry Andric // Note that this needs to be done before we clone the module because each clone 1060b57cec5SDimitry Andric // will receive its own set of distinct metadata nodes. 1070b57cec5SDimitry Andric void promoteTypeIds(Module &M, StringRef ModuleId) { 1080b57cec5SDimitry Andric DenseMap<Metadata *, Metadata *> LocalToGlobal; 1090b57cec5SDimitry Andric auto ExternalizeTypeId = [&](CallInst *CI, unsigned ArgNo) { 1100b57cec5SDimitry Andric Metadata *MD = 1110b57cec5SDimitry Andric cast<MetadataAsValue>(CI->getArgOperand(ArgNo))->getMetadata(); 1120b57cec5SDimitry Andric 1130b57cec5SDimitry Andric if (isa<MDNode>(MD) && cast<MDNode>(MD)->isDistinct()) { 1140b57cec5SDimitry Andric Metadata *&GlobalMD = LocalToGlobal[MD]; 1150b57cec5SDimitry Andric if (!GlobalMD) { 1160b57cec5SDimitry Andric std::string NewName = (Twine(LocalToGlobal.size()) + ModuleId).str(); 1170b57cec5SDimitry Andric GlobalMD = MDString::get(M.getContext(), NewName); 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric CI->setArgOperand(ArgNo, 1210b57cec5SDimitry Andric MetadataAsValue::get(M.getContext(), GlobalMD)); 1220b57cec5SDimitry Andric } 1230b57cec5SDimitry Andric }; 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric if (Function *TypeTestFunc = 1260b57cec5SDimitry Andric M.getFunction(Intrinsic::getName(Intrinsic::type_test))) { 1270b57cec5SDimitry Andric for (const Use &U : TypeTestFunc->uses()) { 1280b57cec5SDimitry Andric auto CI = cast<CallInst>(U.getUser()); 1290b57cec5SDimitry Andric ExternalizeTypeId(CI, 1); 1300b57cec5SDimitry Andric } 1310b57cec5SDimitry Andric } 1320b57cec5SDimitry Andric 133972a253aSDimitry Andric if (Function *PublicTypeTestFunc = 134972a253aSDimitry Andric M.getFunction(Intrinsic::getName(Intrinsic::public_type_test))) { 135972a253aSDimitry Andric for (const Use &U : PublicTypeTestFunc->uses()) { 136972a253aSDimitry Andric auto CI = cast<CallInst>(U.getUser()); 137972a253aSDimitry Andric ExternalizeTypeId(CI, 1); 138972a253aSDimitry Andric } 139972a253aSDimitry Andric } 140972a253aSDimitry Andric 1410b57cec5SDimitry Andric if (Function *TypeCheckedLoadFunc = 1420b57cec5SDimitry Andric M.getFunction(Intrinsic::getName(Intrinsic::type_checked_load))) { 1430b57cec5SDimitry Andric for (const Use &U : TypeCheckedLoadFunc->uses()) { 1440b57cec5SDimitry Andric auto CI = cast<CallInst>(U.getUser()); 1450b57cec5SDimitry Andric ExternalizeTypeId(CI, 2); 1460b57cec5SDimitry Andric } 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric 149*fe013be4SDimitry Andric if (Function *TypeCheckedLoadRelativeFunc = M.getFunction( 150*fe013be4SDimitry Andric Intrinsic::getName(Intrinsic::type_checked_load_relative))) { 151*fe013be4SDimitry Andric for (const Use &U : TypeCheckedLoadRelativeFunc->uses()) { 152*fe013be4SDimitry Andric auto CI = cast<CallInst>(U.getUser()); 153*fe013be4SDimitry Andric ExternalizeTypeId(CI, 2); 154*fe013be4SDimitry Andric } 155*fe013be4SDimitry Andric } 156*fe013be4SDimitry Andric 1570b57cec5SDimitry Andric for (GlobalObject &GO : M.global_objects()) { 1580b57cec5SDimitry Andric SmallVector<MDNode *, 1> MDs; 1590b57cec5SDimitry Andric GO.getMetadata(LLVMContext::MD_type, MDs); 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric GO.eraseMetadata(LLVMContext::MD_type); 162bdd1243dSDimitry Andric for (auto *MD : MDs) { 1630b57cec5SDimitry Andric auto I = LocalToGlobal.find(MD->getOperand(1)); 1640b57cec5SDimitry Andric if (I == LocalToGlobal.end()) { 1650b57cec5SDimitry Andric GO.addMetadata(LLVMContext::MD_type, *MD); 1660b57cec5SDimitry Andric continue; 1670b57cec5SDimitry Andric } 1680b57cec5SDimitry Andric GO.addMetadata( 1690b57cec5SDimitry Andric LLVMContext::MD_type, 1700b57cec5SDimitry Andric *MDNode::get(M.getContext(), {MD->getOperand(0), I->second})); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric } 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric // Drop unused globals, and drop type information from function declarations. 1760b57cec5SDimitry Andric // FIXME: If we made functions typeless then there would be no need to do this. 1770b57cec5SDimitry Andric void simplifyExternals(Module &M) { 1780b57cec5SDimitry Andric FunctionType *EmptyFT = 1790b57cec5SDimitry Andric FunctionType::get(Type::getVoidTy(M.getContext()), false); 1800b57cec5SDimitry Andric 181349cc55cSDimitry Andric for (Function &F : llvm::make_early_inc_range(M)) { 1820b57cec5SDimitry Andric if (F.isDeclaration() && F.use_empty()) { 1830b57cec5SDimitry Andric F.eraseFromParent(); 1840b57cec5SDimitry Andric continue; 1850b57cec5SDimitry Andric } 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric if (!F.isDeclaration() || F.getFunctionType() == EmptyFT || 1880b57cec5SDimitry Andric // Changing the type of an intrinsic may invalidate the IR. 1890b57cec5SDimitry Andric F.getName().startswith("llvm.")) 1900b57cec5SDimitry Andric continue; 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric Function *NewF = 1930b57cec5SDimitry Andric Function::Create(EmptyFT, GlobalValue::ExternalLinkage, 1940b57cec5SDimitry Andric F.getAddressSpace(), "", &M); 195fe6060f1SDimitry Andric NewF->copyAttributesFrom(&F); 196fe6060f1SDimitry Andric // Only copy function attribtues. 197349cc55cSDimitry Andric NewF->setAttributes(AttributeList::get(M.getContext(), 198349cc55cSDimitry Andric AttributeList::FunctionIndex, 199349cc55cSDimitry Andric F.getAttributes().getFnAttrs())); 2000b57cec5SDimitry Andric NewF->takeName(&F); 2010b57cec5SDimitry Andric F.replaceAllUsesWith(ConstantExpr::getBitCast(NewF, F.getType())); 2020b57cec5SDimitry Andric F.eraseFromParent(); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 205*fe013be4SDimitry Andric for (GlobalIFunc &I : llvm::make_early_inc_range(M.ifuncs())) { 206*fe013be4SDimitry Andric if (I.use_empty()) 207*fe013be4SDimitry Andric I.eraseFromParent(); 208*fe013be4SDimitry Andric else 209*fe013be4SDimitry Andric assert(I.getResolverFunction() && "ifunc misses its resolver function"); 210*fe013be4SDimitry Andric } 211*fe013be4SDimitry Andric 212349cc55cSDimitry Andric for (GlobalVariable &GV : llvm::make_early_inc_range(M.globals())) { 2130b57cec5SDimitry Andric if (GV.isDeclaration() && GV.use_empty()) { 2140b57cec5SDimitry Andric GV.eraseFromParent(); 2150b57cec5SDimitry Andric continue; 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric } 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric static void 2210b57cec5SDimitry Andric filterModule(Module *M, 2220b57cec5SDimitry Andric function_ref<bool(const GlobalValue *)> ShouldKeepDefinition) { 2230b57cec5SDimitry Andric std::vector<GlobalValue *> V; 2240b57cec5SDimitry Andric for (GlobalValue &GV : M->global_values()) 2250b57cec5SDimitry Andric if (!ShouldKeepDefinition(&GV)) 2260b57cec5SDimitry Andric V.push_back(&GV); 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric for (GlobalValue *GV : V) 2290b57cec5SDimitry Andric if (!convertToDeclaration(*GV)) 2300b57cec5SDimitry Andric GV->eraseFromParent(); 2310b57cec5SDimitry Andric } 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric void forEachVirtualFunction(Constant *C, function_ref<void(Function *)> Fn) { 2340b57cec5SDimitry Andric if (auto *F = dyn_cast<Function>(C)) 2350b57cec5SDimitry Andric return Fn(F); 2360b57cec5SDimitry Andric if (isa<GlobalValue>(C)) 2370b57cec5SDimitry Andric return; 2380b57cec5SDimitry Andric for (Value *Op : C->operands()) 2390b57cec5SDimitry Andric forEachVirtualFunction(cast<Constant>(Op), Fn); 2400b57cec5SDimitry Andric } 2410b57cec5SDimitry Andric 242fe6060f1SDimitry Andric // Clone any @llvm[.compiler].used over to the new module and append 243fe6060f1SDimitry Andric // values whose defs were cloned into that module. 244fe6060f1SDimitry Andric static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM, 245fe6060f1SDimitry Andric bool CompilerUsed) { 246fe6060f1SDimitry Andric SmallVector<GlobalValue *, 4> Used, NewUsed; 247fe6060f1SDimitry Andric // First collect those in the llvm[.compiler].used set. 248fe6060f1SDimitry Andric collectUsedGlobalVariables(SrcM, Used, CompilerUsed); 249fe6060f1SDimitry Andric // Next build a set of the equivalent values defined in DestM. 250fe6060f1SDimitry Andric for (auto *V : Used) { 251fe6060f1SDimitry Andric auto *GV = DestM.getNamedValue(V->getName()); 252fe6060f1SDimitry Andric if (GV && !GV->isDeclaration()) 253fe6060f1SDimitry Andric NewUsed.push_back(GV); 254fe6060f1SDimitry Andric } 255fe6060f1SDimitry Andric // Finally, add them to a llvm[.compiler].used variable in DestM. 256fe6060f1SDimitry Andric if (CompilerUsed) 257fe6060f1SDimitry Andric appendToCompilerUsed(DestM, NewUsed); 258fe6060f1SDimitry Andric else 259fe6060f1SDimitry Andric appendToUsed(DestM, NewUsed); 260fe6060f1SDimitry Andric } 261fe6060f1SDimitry Andric 262*fe013be4SDimitry Andric #ifndef NDEBUG 263*fe013be4SDimitry Andric static bool enableUnifiedLTO(Module &M) { 264*fe013be4SDimitry Andric bool UnifiedLTO = false; 265*fe013be4SDimitry Andric if (auto *MD = 266*fe013be4SDimitry Andric mdconst::extract_or_null<ConstantInt>(M.getModuleFlag("UnifiedLTO"))) 267*fe013be4SDimitry Andric UnifiedLTO = MD->getZExtValue(); 268*fe013be4SDimitry Andric return UnifiedLTO; 269*fe013be4SDimitry Andric } 270*fe013be4SDimitry Andric #endif 271*fe013be4SDimitry Andric 2720b57cec5SDimitry Andric // If it's possible to split M into regular and thin LTO parts, do so and write 2730b57cec5SDimitry Andric // a multi-module bitcode file with the two parts to OS. Otherwise, write only a 2740b57cec5SDimitry Andric // regular LTO bitcode file to OS. 2750b57cec5SDimitry Andric void splitAndWriteThinLTOBitcode( 2760b57cec5SDimitry Andric raw_ostream &OS, raw_ostream *ThinLinkOS, 2770b57cec5SDimitry Andric function_ref<AAResults &(Function &)> AARGetter, Module &M) { 2780b57cec5SDimitry Andric std::string ModuleId = getUniqueModuleId(&M); 2790b57cec5SDimitry Andric if (ModuleId.empty()) { 280*fe013be4SDimitry Andric assert(!enableUnifiedLTO(M)); 2810b57cec5SDimitry Andric // We couldn't generate a module ID for this module, write it out as a 2820b57cec5SDimitry Andric // regular LTO module with an index for summary-based dead stripping. 2830b57cec5SDimitry Andric ProfileSummaryInfo PSI(M); 2840b57cec5SDimitry Andric M.addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); 2850b57cec5SDimitry Andric ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI); 286*fe013be4SDimitry Andric WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, &Index, 287*fe013be4SDimitry Andric /*UnifiedLTO=*/false); 2880b57cec5SDimitry Andric 2890b57cec5SDimitry Andric if (ThinLinkOS) 2900b57cec5SDimitry Andric // We don't have a ThinLTO part, but still write the module to the 2910b57cec5SDimitry Andric // ThinLinkOS if requested so that the expected output file is produced. 2920b57cec5SDimitry Andric WriteBitcodeToFile(M, *ThinLinkOS, /*ShouldPreserveUseListOrder=*/false, 293*fe013be4SDimitry Andric &Index, /*UnifiedLTO=*/false); 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric return; 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric promoteTypeIds(M, ModuleId); 2990b57cec5SDimitry Andric 3008bcb0991SDimitry Andric // Returns whether a global or its associated global has attached type 3018bcb0991SDimitry Andric // metadata. The former may participate in CFI or whole-program 3028bcb0991SDimitry Andric // devirtualization, so they need to appear in the merged module instead of 3038bcb0991SDimitry Andric // the thin LTO module. Similarly, globals that are associated with globals 3048bcb0991SDimitry Andric // with type metadata need to appear in the merged module because they will 3058bcb0991SDimitry Andric // reference the global's section directly. 3060b57cec5SDimitry Andric auto HasTypeMetadata = [](const GlobalObject *GO) { 3078bcb0991SDimitry Andric if (MDNode *MD = GO->getMetadata(LLVMContext::MD_associated)) 3088bcb0991SDimitry Andric if (auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0))) 3098bcb0991SDimitry Andric if (auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue())) 3108bcb0991SDimitry Andric if (AssocGO->hasMetadata(LLVMContext::MD_type)) 3118bcb0991SDimitry Andric return true; 3120b57cec5SDimitry Andric return GO->hasMetadata(LLVMContext::MD_type); 3130b57cec5SDimitry Andric }; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric // Collect the set of virtual functions that are eligible for virtual constant 3160b57cec5SDimitry Andric // propagation. Each eligible function must not access memory, must return 3170b57cec5SDimitry Andric // an integer of width <=64 bits, must take at least one argument, must not 3180b57cec5SDimitry Andric // use its first argument (assumed to be "this") and all arguments other than 3190b57cec5SDimitry Andric // the first one must be of <=64 bit integer type. 3200b57cec5SDimitry Andric // 3210b57cec5SDimitry Andric // Note that we test whether this copy of the function is readnone, rather 3220b57cec5SDimitry Andric // than testing function attributes, which must hold for any copy of the 3230b57cec5SDimitry Andric // function, even a less optimized version substituted at link time. This is 3240b57cec5SDimitry Andric // sound because the virtual constant propagation optimizations effectively 3250b57cec5SDimitry Andric // inline all implementations of the virtual function into each call site, 3260b57cec5SDimitry Andric // rather than using function attributes to perform local optimization. 3270b57cec5SDimitry Andric DenseSet<const Function *> EligibleVirtualFns; 3280b57cec5SDimitry Andric // If any member of a comdat lives in MergedM, put all members of that 3290b57cec5SDimitry Andric // comdat in MergedM to keep the comdat together. 3300b57cec5SDimitry Andric DenseSet<const Comdat *> MergedMComdats; 3310b57cec5SDimitry Andric for (GlobalVariable &GV : M.globals()) 3320b57cec5SDimitry Andric if (HasTypeMetadata(&GV)) { 3330b57cec5SDimitry Andric if (const auto *C = GV.getComdat()) 3340b57cec5SDimitry Andric MergedMComdats.insert(C); 3350b57cec5SDimitry Andric forEachVirtualFunction(GV.getInitializer(), [&](Function *F) { 3360b57cec5SDimitry Andric auto *RT = dyn_cast<IntegerType>(F->getReturnType()); 3370b57cec5SDimitry Andric if (!RT || RT->getBitWidth() > 64 || F->arg_empty() || 3380b57cec5SDimitry Andric !F->arg_begin()->use_empty()) 3390b57cec5SDimitry Andric return; 340e8d8bef9SDimitry Andric for (auto &Arg : drop_begin(F->args())) { 3410b57cec5SDimitry Andric auto *ArgT = dyn_cast<IntegerType>(Arg.getType()); 3420b57cec5SDimitry Andric if (!ArgT || ArgT->getBitWidth() > 64) 3430b57cec5SDimitry Andric return; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric if (!F->isDeclaration() && 346bdd1243dSDimitry Andric computeFunctionBodyMemoryAccess(*F, AARGetter(*F)) 347bdd1243dSDimitry Andric .doesNotAccessMemory()) 3480b57cec5SDimitry Andric EligibleVirtualFns.insert(F); 3490b57cec5SDimitry Andric }); 3500b57cec5SDimitry Andric } 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric ValueToValueMapTy VMap; 3530b57cec5SDimitry Andric std::unique_ptr<Module> MergedM( 3540b57cec5SDimitry Andric CloneModule(M, VMap, [&](const GlobalValue *GV) -> bool { 3550b57cec5SDimitry Andric if (const auto *C = GV->getComdat()) 3560b57cec5SDimitry Andric if (MergedMComdats.count(C)) 3570b57cec5SDimitry Andric return true; 3580b57cec5SDimitry Andric if (auto *F = dyn_cast<Function>(GV)) 3590b57cec5SDimitry Andric return EligibleVirtualFns.count(F); 360349cc55cSDimitry Andric if (auto *GVar = 361349cc55cSDimitry Andric dyn_cast_or_null<GlobalVariable>(GV->getAliaseeObject())) 3620b57cec5SDimitry Andric return HasTypeMetadata(GVar); 3630b57cec5SDimitry Andric return false; 3640b57cec5SDimitry Andric })); 3650b57cec5SDimitry Andric StripDebugInfo(*MergedM); 3660b57cec5SDimitry Andric MergedM->setModuleInlineAsm(""); 3670b57cec5SDimitry Andric 368fe6060f1SDimitry Andric // Clone any llvm.*used globals to ensure the included values are 369fe6060f1SDimitry Andric // not deleted. 370fe6060f1SDimitry Andric cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ false); 371fe6060f1SDimitry Andric cloneUsedGlobalVariables(M, *MergedM, /*CompilerUsed*/ true); 372fe6060f1SDimitry Andric 3730b57cec5SDimitry Andric for (Function &F : *MergedM) 3740b57cec5SDimitry Andric if (!F.isDeclaration()) { 3750b57cec5SDimitry Andric // Reset the linkage of all functions eligible for virtual constant 3760b57cec5SDimitry Andric // propagation. The canonical definitions live in the thin LTO module so 3770b57cec5SDimitry Andric // that they can be imported. 3780b57cec5SDimitry Andric F.setLinkage(GlobalValue::AvailableExternallyLinkage); 3790b57cec5SDimitry Andric F.setComdat(nullptr); 3800b57cec5SDimitry Andric } 3810b57cec5SDimitry Andric 3820b57cec5SDimitry Andric SetVector<GlobalValue *> CfiFunctions; 3830b57cec5SDimitry Andric for (auto &F : M) 3840b57cec5SDimitry Andric if ((!F.hasLocalLinkage() || F.hasAddressTaken()) && HasTypeMetadata(&F)) 3850b57cec5SDimitry Andric CfiFunctions.insert(&F); 3860b57cec5SDimitry Andric 3870b57cec5SDimitry Andric // Remove all globals with type metadata, globals with comdats that live in 3880b57cec5SDimitry Andric // MergedM, and aliases pointing to such globals from the thin LTO module. 3890b57cec5SDimitry Andric filterModule(&M, [&](const GlobalValue *GV) { 390349cc55cSDimitry Andric if (auto *GVar = dyn_cast_or_null<GlobalVariable>(GV->getAliaseeObject())) 3910b57cec5SDimitry Andric if (HasTypeMetadata(GVar)) 3920b57cec5SDimitry Andric return false; 3930b57cec5SDimitry Andric if (const auto *C = GV->getComdat()) 3940b57cec5SDimitry Andric if (MergedMComdats.count(C)) 3950b57cec5SDimitry Andric return false; 3960b57cec5SDimitry Andric return true; 3970b57cec5SDimitry Andric }); 3980b57cec5SDimitry Andric 3990b57cec5SDimitry Andric promoteInternals(*MergedM, M, ModuleId, CfiFunctions); 4000b57cec5SDimitry Andric promoteInternals(M, *MergedM, ModuleId, CfiFunctions); 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric auto &Ctx = MergedM->getContext(); 4030b57cec5SDimitry Andric SmallVector<MDNode *, 8> CfiFunctionMDs; 404bdd1243dSDimitry Andric for (auto *V : CfiFunctions) { 4050b57cec5SDimitry Andric Function &F = *cast<Function>(V); 4060b57cec5SDimitry Andric SmallVector<MDNode *, 2> Types; 4070b57cec5SDimitry Andric F.getMetadata(LLVMContext::MD_type, Types); 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric SmallVector<Metadata *, 4> Elts; 4100b57cec5SDimitry Andric Elts.push_back(MDString::get(Ctx, F.getName())); 4110b57cec5SDimitry Andric CfiFunctionLinkage Linkage; 4128bcb0991SDimitry Andric if (lowertypetests::isJumpTableCanonical(&F)) 4130b57cec5SDimitry Andric Linkage = CFL_Definition; 4148bcb0991SDimitry Andric else if (F.hasExternalWeakLinkage()) 4150b57cec5SDimitry Andric Linkage = CFL_WeakDeclaration; 4160b57cec5SDimitry Andric else 4170b57cec5SDimitry Andric Linkage = CFL_Declaration; 4180b57cec5SDimitry Andric Elts.push_back(ConstantAsMetadata::get( 4190b57cec5SDimitry Andric llvm::ConstantInt::get(Type::getInt8Ty(Ctx), Linkage))); 420e8d8bef9SDimitry Andric append_range(Elts, Types); 4210b57cec5SDimitry Andric CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts)); 4220b57cec5SDimitry Andric } 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric if(!CfiFunctionMDs.empty()) { 4250b57cec5SDimitry Andric NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("cfi.functions"); 426bdd1243dSDimitry Andric for (auto *MD : CfiFunctionMDs) 4270b57cec5SDimitry Andric NMD->addOperand(MD); 4280b57cec5SDimitry Andric } 4290b57cec5SDimitry Andric 4300b57cec5SDimitry Andric SmallVector<MDNode *, 8> FunctionAliases; 4310b57cec5SDimitry Andric for (auto &A : M.aliases()) { 4320b57cec5SDimitry Andric if (!isa<Function>(A.getAliasee())) 4330b57cec5SDimitry Andric continue; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric auto *F = cast<Function>(A.getAliasee()); 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric Metadata *Elts[] = { 4380b57cec5SDimitry Andric MDString::get(Ctx, A.getName()), 4390b57cec5SDimitry Andric MDString::get(Ctx, F->getName()), 4400b57cec5SDimitry Andric ConstantAsMetadata::get( 4410b57cec5SDimitry Andric ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())), 4420b57cec5SDimitry Andric ConstantAsMetadata::get( 4430b57cec5SDimitry Andric ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())), 4440b57cec5SDimitry Andric }; 4450b57cec5SDimitry Andric 4460b57cec5SDimitry Andric FunctionAliases.push_back(MDTuple::get(Ctx, Elts)); 4470b57cec5SDimitry Andric } 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric if (!FunctionAliases.empty()) { 4500b57cec5SDimitry Andric NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases"); 451bdd1243dSDimitry Andric for (auto *MD : FunctionAliases) 4520b57cec5SDimitry Andric NMD->addOperand(MD); 4530b57cec5SDimitry Andric } 4540b57cec5SDimitry Andric 4550b57cec5SDimitry Andric SmallVector<MDNode *, 8> Symvers; 4560b57cec5SDimitry Andric ModuleSymbolTable::CollectAsmSymvers(M, [&](StringRef Name, StringRef Alias) { 4570b57cec5SDimitry Andric Function *F = M.getFunction(Name); 4580b57cec5SDimitry Andric if (!F || F->use_empty()) 4590b57cec5SDimitry Andric return; 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric Symvers.push_back(MDTuple::get( 4620b57cec5SDimitry Andric Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)})); 4630b57cec5SDimitry Andric }); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric if (!Symvers.empty()) { 4660b57cec5SDimitry Andric NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("symvers"); 467bdd1243dSDimitry Andric for (auto *MD : Symvers) 4680b57cec5SDimitry Andric NMD->addOperand(MD); 4690b57cec5SDimitry Andric } 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric simplifyExternals(*MergedM); 4720b57cec5SDimitry Andric 4730b57cec5SDimitry Andric // FIXME: Try to re-use BSI and PFI from the original module here. 4740b57cec5SDimitry Andric ProfileSummaryInfo PSI(M); 4750b57cec5SDimitry Andric ModuleSummaryIndex Index = buildModuleSummaryIndex(M, nullptr, &PSI); 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric // Mark the merged module as requiring full LTO. We still want an index for 4780b57cec5SDimitry Andric // it though, so that it can participate in summary-based dead stripping. 4790b57cec5SDimitry Andric MergedM->addModuleFlag(Module::Error, "ThinLTO", uint32_t(0)); 4800b57cec5SDimitry Andric ModuleSummaryIndex MergedMIndex = 4810b57cec5SDimitry Andric buildModuleSummaryIndex(*MergedM, nullptr, &PSI); 4820b57cec5SDimitry Andric 4830b57cec5SDimitry Andric SmallVector<char, 0> Buffer; 4840b57cec5SDimitry Andric 4850b57cec5SDimitry Andric BitcodeWriter W(Buffer); 4860b57cec5SDimitry Andric // Save the module hash produced for the full bitcode, which will 4870b57cec5SDimitry Andric // be used in the backends, and use that in the minimized bitcode 4880b57cec5SDimitry Andric // produced for the full link. 4890b57cec5SDimitry Andric ModuleHash ModHash = {{0}}; 4900b57cec5SDimitry Andric W.writeModule(M, /*ShouldPreserveUseListOrder=*/false, &Index, 4910b57cec5SDimitry Andric /*GenerateHash=*/true, &ModHash); 4920b57cec5SDimitry Andric W.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, &MergedMIndex); 4930b57cec5SDimitry Andric W.writeSymtab(); 4940b57cec5SDimitry Andric W.writeStrtab(); 4950b57cec5SDimitry Andric OS << Buffer; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric // If a minimized bitcode module was requested for the thin link, only 4980b57cec5SDimitry Andric // the information that is needed by thin link will be written in the 4990b57cec5SDimitry Andric // given OS (the merged module will be written as usual). 5000b57cec5SDimitry Andric if (ThinLinkOS) { 5010b57cec5SDimitry Andric Buffer.clear(); 5020b57cec5SDimitry Andric BitcodeWriter W2(Buffer); 5030b57cec5SDimitry Andric StripDebugInfo(M); 5040b57cec5SDimitry Andric W2.writeThinLinkBitcode(M, Index, ModHash); 5050b57cec5SDimitry Andric W2.writeModule(*MergedM, /*ShouldPreserveUseListOrder=*/false, 5060b57cec5SDimitry Andric &MergedMIndex); 5070b57cec5SDimitry Andric W2.writeSymtab(); 5080b57cec5SDimitry Andric W2.writeStrtab(); 5090b57cec5SDimitry Andric *ThinLinkOS << Buffer; 5100b57cec5SDimitry Andric } 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric // Check if the LTO Unit splitting has been enabled. 5140b57cec5SDimitry Andric bool enableSplitLTOUnit(Module &M) { 5150b57cec5SDimitry Andric bool EnableSplitLTOUnit = false; 5160b57cec5SDimitry Andric if (auto *MD = mdconst::extract_or_null<ConstantInt>( 5170b57cec5SDimitry Andric M.getModuleFlag("EnableSplitLTOUnit"))) 5180b57cec5SDimitry Andric EnableSplitLTOUnit = MD->getZExtValue(); 5190b57cec5SDimitry Andric return EnableSplitLTOUnit; 5200b57cec5SDimitry Andric } 5210b57cec5SDimitry Andric 5220b57cec5SDimitry Andric // Returns whether this module needs to be split because it uses type metadata. 5230b57cec5SDimitry Andric bool hasTypeMetadata(Module &M) { 5240b57cec5SDimitry Andric for (auto &GO : M.global_objects()) { 5250b57cec5SDimitry Andric if (GO.hasMetadata(LLVMContext::MD_type)) 5260b57cec5SDimitry Andric return true; 5270b57cec5SDimitry Andric } 5280b57cec5SDimitry Andric return false; 5290b57cec5SDimitry Andric } 5300b57cec5SDimitry Andric 531*fe013be4SDimitry Andric bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS, 5320b57cec5SDimitry Andric function_ref<AAResults &(Function &)> AARGetter, 5330b57cec5SDimitry Andric Module &M, const ModuleSummaryIndex *Index) { 5340b57cec5SDimitry Andric std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr; 5350b57cec5SDimitry Andric // See if this module has any type metadata. If so, we try to split it 5360b57cec5SDimitry Andric // or at least promote type ids to enable WPD. 5370b57cec5SDimitry Andric if (hasTypeMetadata(M)) { 538*fe013be4SDimitry Andric if (enableSplitLTOUnit(M)) { 539*fe013be4SDimitry Andric splitAndWriteThinLTOBitcode(OS, ThinLinkOS, AARGetter, M); 540*fe013be4SDimitry Andric return true; 541*fe013be4SDimitry Andric } 5420b57cec5SDimitry Andric // Promote type ids as needed for index-based WPD. 5430b57cec5SDimitry Andric std::string ModuleId = getUniqueModuleId(&M); 5440b57cec5SDimitry Andric if (!ModuleId.empty()) { 5450b57cec5SDimitry Andric promoteTypeIds(M, ModuleId); 5460b57cec5SDimitry Andric // Need to rebuild the index so that it contains type metadata 5470b57cec5SDimitry Andric // for the newly promoted type ids. 5480b57cec5SDimitry Andric // FIXME: Probably should not bother building the index at all 5490b57cec5SDimitry Andric // in the caller of writeThinLTOBitcode (which does so via the 5500b57cec5SDimitry Andric // ModuleSummaryIndexAnalysis pass), since we have to rebuild it 5510b57cec5SDimitry Andric // anyway whenever there is type metadata (here or in 5520b57cec5SDimitry Andric // splitAndWriteThinLTOBitcode). Just always build it once via the 5530b57cec5SDimitry Andric // buildModuleSummaryIndex when Module(s) are ready. 5540b57cec5SDimitry Andric ProfileSummaryInfo PSI(M); 5558bcb0991SDimitry Andric NewIndex = std::make_unique<ModuleSummaryIndex>( 5560b57cec5SDimitry Andric buildModuleSummaryIndex(M, nullptr, &PSI)); 5570b57cec5SDimitry Andric Index = NewIndex.get(); 5580b57cec5SDimitry Andric } 5590b57cec5SDimitry Andric } 5600b57cec5SDimitry Andric 5610b57cec5SDimitry Andric // Write it out as an unsplit ThinLTO module. 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric // Save the module hash produced for the full bitcode, which will 5640b57cec5SDimitry Andric // be used in the backends, and use that in the minimized bitcode 5650b57cec5SDimitry Andric // produced for the full link. 5660b57cec5SDimitry Andric ModuleHash ModHash = {{0}}; 5670b57cec5SDimitry Andric WriteBitcodeToFile(M, OS, /*ShouldPreserveUseListOrder=*/false, Index, 5680b57cec5SDimitry Andric /*GenerateHash=*/true, &ModHash); 5690b57cec5SDimitry Andric // If a minimized bitcode module was requested for the thin link, only 5700b57cec5SDimitry Andric // the information that is needed by thin link will be written in the 5710b57cec5SDimitry Andric // given OS. 5720b57cec5SDimitry Andric if (ThinLinkOS && Index) 5731fd87a68SDimitry Andric writeThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash); 574*fe013be4SDimitry Andric return false; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric } // anonymous namespace 5780b57cec5SDimitry Andric 5790b57cec5SDimitry Andric PreservedAnalyses 5800b57cec5SDimitry Andric llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) { 5810b57cec5SDimitry Andric FunctionAnalysisManager &FAM = 5820b57cec5SDimitry Andric AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager(); 583*fe013be4SDimitry Andric bool Changed = writeThinLTOBitcode( 584*fe013be4SDimitry Andric OS, ThinLinkOS, 5850b57cec5SDimitry Andric [&FAM](Function &F) -> AAResults & { 5860b57cec5SDimitry Andric return FAM.getResult<AAManager>(F); 5870b57cec5SDimitry Andric }, 5880b57cec5SDimitry Andric M, &AM.getResult<ModuleSummaryIndexAnalysis>(M)); 589*fe013be4SDimitry Andric return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all(); 5900b57cec5SDimitry Andric } 591