384 lines · cpp
1//===- lib/Transforms/Utils/FunctionImportUtils.cpp - Importing utilities -===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the FunctionImportGlobalProcessing class, used10// to perform the necessary global value handling for function importing.11//12//===----------------------------------------------------------------------===//13 14#include "llvm/Transforms/Utils/FunctionImportUtils.h"15#include "llvm/Support/CommandLine.h"16#include "llvm/Support/TimeProfiler.h"17 18using namespace llvm;19 20namespace llvm {21 22/// Uses the "source_filename" instead of a Module hash ID for the suffix of23/// promoted locals during LTO. NOTE: This requires that the source filename24/// has a unique name / path to avoid name collisions.25static cl::opt<bool> UseSourceFilenameForPromotedLocals(26 "use-source-filename-for-promoted-locals", cl::Hidden,27 cl::desc("Uses the source file name instead of the Module hash. "28 "This requires that the source filename has a unique name / "29 "path to avoid name collisions."));30 31cl::list<GlobalValue::GUID> MoveSymbolGUID(32 "thinlto-move-symbols",33 cl::desc(34 "Move the symbols with the given name. This will delete these symbols "35 "wherever they are originally defined, and make sure their "36 "linkage is External where they are imported. It is meant to be "37 "used with the name of contextual profiling roots."),38 cl::Hidden);39 40} // end namespace llvm41 42FunctionImportGlobalProcessing::FunctionImportGlobalProcessing(43 Module &M, const ModuleSummaryIndex &Index,44 SetVector<GlobalValue *> *GlobalsToImport, bool ClearDSOLocalOnDeclarations)45 : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport),46 ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {47 // If we have a ModuleSummaryIndex but no function to import,48 // then this is the primary module being compiled in a ThinLTO49 // backend compilation, and we need to see if it has functions that50 // may be exported to another backend compilation.51 if (!GlobalsToImport)52 HasExportedFunctions = ImportIndex.hasExportedFunctions(M);53 54#ifndef NDEBUG55 SmallVector<GlobalValue *, 4> Vec;56 // First collect those in the llvm.used set.57 collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/false);58 // Next collect those in the llvm.compiler.used set.59 collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/true);60 Used = {llvm::from_range, Vec};61#endif62 SymbolsToMove.insert_range(MoveSymbolGUID);63}64 65/// Checks if we should import SGV as a definition, otherwise import as a66/// declaration.67bool FunctionImportGlobalProcessing::doImportAsDefinition(68 const GlobalValue *SGV) {69 if (!isPerformingImport())70 return false;71 72 // Only import the globals requested for importing.73 if (!GlobalsToImport->count(const_cast<GlobalValue *>(SGV)))74 return false;75 76 assert(!isa<GlobalAlias>(SGV) &&77 "Unexpected global alias in the import list.");78 79 // Otherwise yes.80 return true;81}82 83bool FunctionImportGlobalProcessing::shouldPromoteLocalToGlobal(84 const GlobalValue *SGV, ValueInfo VI) {85 assert(SGV->hasLocalLinkage());86 87 // Ifuncs and ifunc alias does not have summary.88 if (isa<GlobalIFunc>(SGV) ||89 (isa<GlobalAlias>(SGV) &&90 isa<GlobalIFunc>(cast<GlobalAlias>(SGV)->getAliaseeObject())))91 return false;92 93 // Both the imported references and the original local variable must94 // be promoted.95 if (!isPerformingImport() && !isModuleExporting())96 return false;97 98 if (isPerformingImport()) {99 assert((!GlobalsToImport->count(const_cast<GlobalValue *>(SGV)) ||100 !isNonRenamableLocal(*SGV)) &&101 "Attempting to promote non-renamable local");102 // We don't know for sure yet if we are importing this value (as either103 // a reference or a def), since we are simply walking all values in the104 // module. But by necessity if we end up importing it and it is local,105 // it must be promoted, so unconditionally promote all values in the106 // importing module.107 return true;108 }109 110 // When exporting, consult the index. We can have more than one local111 // with the same GUID, in the case of same-named locals in different but112 // same-named source files that were compiled in their respective directories113 // (so the source file name and resulting GUID is the same). Find the one114 // in this module.115 auto Summary = ImportIndex.findSummaryInModule(116 VI, SGV->getParent()->getModuleIdentifier());117 assert(Summary && "Missing summary for global value when exporting");118 auto Linkage = Summary->linkage();119 if (!GlobalValue::isLocalLinkage(Linkage)) {120 assert(!isNonRenamableLocal(*SGV) &&121 "Attempting to promote non-renamable local");122 return true;123 }124 125 return false;126}127 128#ifndef NDEBUG129bool FunctionImportGlobalProcessing::isNonRenamableLocal(130 const GlobalValue &GV) const {131 if (!GV.hasLocalLinkage())132 return false;133 // This needs to stay in sync with the logic in buildModuleSummaryIndex.134 if (GV.hasSection())135 return true;136 if (Used.count(const_cast<GlobalValue *>(&GV)))137 return true;138 return false;139}140#endif141 142std::string143FunctionImportGlobalProcessing::getPromotedName(const GlobalValue *SGV) {144 assert(SGV->hasLocalLinkage());145 146 // For locals that must be promoted to global scope, ensure that147 // the promoted name uniquely identifies the copy in the original module,148 // using the ID assigned during combined index creation.149 if (UseSourceFilenameForPromotedLocals &&150 !SGV->getParent()->getSourceFileName().empty()) {151 SmallString<256> Suffix(SGV->getParent()->getSourceFileName());152 std::replace_if(std::begin(Suffix), std::end(Suffix),153 [&](char ch) { return !isAlnum(ch); }, '_');154 return ModuleSummaryIndex::getGlobalNameForLocal(155 SGV->getName(), Suffix);156 }157 158 return ModuleSummaryIndex::getGlobalNameForLocal(159 SGV->getName(),160 ImportIndex.getModuleHash(SGV->getParent()->getModuleIdentifier()));161}162 163GlobalValue::LinkageTypes164FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,165 bool DoPromote) {166 // Any local variable that is referenced by an exported function needs167 // to be promoted to global scope. Since we don't currently know which168 // functions reference which local variables/functions, we must treat169 // all as potentially exported if this module is exporting anything.170 if (isModuleExporting()) {171 if (SGV->hasLocalLinkage() && DoPromote)172 return GlobalValue::ExternalLinkage;173 return SGV->getLinkage();174 }175 176 // Otherwise, if we aren't importing, no linkage change is needed.177 if (!isPerformingImport())178 return SGV->getLinkage();179 180 switch (SGV->getLinkage()) {181 case GlobalValue::LinkOnceODRLinkage:182 case GlobalValue::ExternalLinkage:183 // External and linkonce definitions are converted to available_externally184 // definitions upon import, so that they are available for inlining185 // and/or optimization, but are turned into declarations later186 // during the EliminateAvailableExternally pass.187 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))188 return SymbolsToMove.contains(SGV->getGUID())189 ? GlobalValue::ExternalLinkage190 : GlobalValue::AvailableExternallyLinkage;191 // An imported external declaration stays external.192 return SGV->getLinkage();193 194 case GlobalValue::AvailableExternallyLinkage:195 // An imported available_externally definition converts196 // to external if imported as a declaration.197 if (!doImportAsDefinition(SGV))198 return GlobalValue::ExternalLinkage;199 // An imported available_externally declaration stays that way.200 return SGV->getLinkage();201 202 case GlobalValue::LinkOnceAnyLinkage:203 case GlobalValue::WeakAnyLinkage:204 // Can't import linkonce_any/weak_any definitions correctly, or we might205 // change the program semantics, since the linker will pick the first206 // linkonce_any/weak_any definition and importing would change the order207 // they are seen by the linker. The module linking caller needs to enforce208 // this.209 assert(!doImportAsDefinition(SGV));210 // If imported as a declaration, it becomes external_weak.211 return SGV->getLinkage();212 213 case GlobalValue::WeakODRLinkage:214 // For weak_odr linkage, there is a guarantee that all copies will be215 // equivalent, so the issue described above for weak_any does not exist,216 // and the definition can be imported. It can be treated similarly217 // to an imported externally visible global value.218 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))219 return GlobalValue::AvailableExternallyLinkage;220 else221 return GlobalValue::ExternalLinkage;222 223 case GlobalValue::AppendingLinkage:224 // It would be incorrect to import an appending linkage variable,225 // since it would cause global constructors/destructors to be226 // executed multiple times. This should have already been handled227 // by linkIfNeeded, and we will assert in shouldLinkFromSource228 // if we try to import, so we simply return AppendingLinkage.229 return GlobalValue::AppendingLinkage;230 231 case GlobalValue::InternalLinkage:232 case GlobalValue::PrivateLinkage:233 // If we are promoting the local to global scope, it is handled234 // similarly to a normal externally visible global.235 if (DoPromote) {236 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))237 return GlobalValue::AvailableExternallyLinkage;238 else239 return GlobalValue::ExternalLinkage;240 }241 // A non-promoted imported local definition stays local.242 // The ThinLTO pass will eventually force-import their definitions.243 return SGV->getLinkage();244 245 case GlobalValue::ExternalWeakLinkage:246 // External weak doesn't apply to definitions, must be a declaration.247 assert(!doImportAsDefinition(SGV));248 // Linkage stays external_weak.249 return SGV->getLinkage();250 251 case GlobalValue::CommonLinkage:252 // Linkage stays common on definitions.253 // The ThinLTO pass will eventually force-import their definitions.254 return SGV->getLinkage();255 }256 257 llvm_unreachable("unknown linkage type");258}259 260void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {261 262 ValueInfo VI;263 if (GV.hasName())264 VI = ImportIndex.getValueInfo(GV.getGUID());265 266 // We should always have a ValueInfo (i.e. GV in index) for definitions when267 // we are exporting, and also when importing that value.268 assert(VI || GV.isDeclaration() ||269 (isPerformingImport() && !doImportAsDefinition(&GV)));270 271 // Mark read/write-only variables which can be imported with specific272 // attribute. We can't internalize them now because IRMover will fail273 // to link variable definitions to their external declarations during274 // ThinLTO import. We'll internalize read-only variables later, after275 // import is finished. See internalizeGVsAfterImport.276 //277 // If global value dead stripping is not enabled in summary then278 // propagateConstants hasn't been run. We can't internalize GV279 // in such case.280 if (!GV.isDeclaration() && VI && ImportIndex.withAttributePropagation()) {281 if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {282 // We can have more than one local with the same GUID, in the case of283 // same-named locals in different but same-named source files that were284 // compiled in their respective directories (so the source file name285 // and resulting GUID is the same). Find the one in this module.286 // Handle the case where there is no summary found in this module. That287 // can happen in the distributed ThinLTO backend, because the index only288 // contains summaries from the source modules if they are being imported.289 // We might have a non-null VI and get here even in that case if the name290 // matches one in this module (e.g. weak or appending linkage).291 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(292 ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier()));293 if (GVS &&294 (ImportIndex.isReadOnly(GVS) || ImportIndex.isWriteOnly(GVS))) {295 V->addAttribute("thinlto-internalize");296 // Objects referenced by writeonly GV initializer should not be297 // promoted, because there is no any kind of read access to them298 // on behalf of this writeonly GV. To avoid promotion we convert299 // GV initializer to 'zeroinitializer'. This effectively drops300 // references in IR module (not in combined index), so we can301 // ignore them when computing import. We do not export references302 // of writeonly object. See computeImportForReferencedGlobals303 if (ImportIndex.isWriteOnly(GVS))304 V->setInitializer(Constant::getNullValue(V->getValueType()));305 }306 }307 }308 309 if (GV.hasLocalLinkage() && shouldPromoteLocalToGlobal(&GV, VI)) {310 // Save the original name string before we rename GV below.311 auto Name = GV.getName().str();312 GV.setName(getPromotedName(&GV));313 GV.setLinkage(getLinkage(&GV, /* DoPromote */ true));314 assert(!GV.hasLocalLinkage());315 GV.setVisibility(GlobalValue::HiddenVisibility);316 317 // If we are renaming a COMDAT leader, ensure that we record the COMDAT318 // for later renaming as well. This is required for COFF.319 if (const auto *C = GV.getComdat())320 if (C->getName() == Name)321 RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName()));322 } else323 GV.setLinkage(getLinkage(&GV, /* DoPromote */ false));324 325 // When ClearDSOLocalOnDeclarations is true, clear dso_local if GV is326 // converted to a declaration, to disable direct access. Don't do this if GV327 // is implicitly dso_local due to a non-default visibility.328 if (ClearDSOLocalOnDeclarations &&329 (GV.isDeclarationForLinker() ||330 (isPerformingImport() && !doImportAsDefinition(&GV))) &&331 !GV.isImplicitDSOLocal()) {332 GV.setDSOLocal(false);333 } else if (VI && VI.isDSOLocal(ImportIndex.withDSOLocalPropagation())) {334 // If all summaries are dso_local, symbol gets resolved to a known local335 // definition.336 GV.setDSOLocal(true);337 if (GV.hasDLLImportStorageClass())338 GV.setDLLStorageClass(GlobalValue::DefaultStorageClass);339 }340 341 // Remove functions imported as available externally defs from comdats,342 // as this is a declaration for the linker, and will be dropped eventually.343 // It is illegal for comdats to contain declarations.344 auto *GO = dyn_cast<GlobalObject>(&GV);345 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {346 // The IRMover should not have placed any imported declarations in347 // a comdat, so the only declaration that should be in a comdat348 // at this point would be a definition imported as available_externally.349 assert(GO->hasAvailableExternallyLinkage() &&350 "Expected comdat on definition (possibly available external)");351 GO->setComdat(nullptr);352 }353}354 355void FunctionImportGlobalProcessing::processGlobalsForThinLTO() {356 for (GlobalVariable &GV : M.globals())357 processGlobalForThinLTO(GV);358 for (Function &SF : M)359 processGlobalForThinLTO(SF);360 for (GlobalAlias &GA : M.aliases())361 processGlobalForThinLTO(GA);362 363 // Replace any COMDATS that required renaming (because the COMDAT leader was364 // promoted and renamed).365 if (!RenamedComdats.empty())366 for (auto &GO : M.global_objects())367 if (auto *C = GO.getComdat()) {368 auto Replacement = RenamedComdats.find(C);369 if (Replacement != RenamedComdats.end())370 GO.setComdat(Replacement->second);371 }372}373 374void FunctionImportGlobalProcessing::run() { processGlobalsForThinLTO(); }375 376void llvm::renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index,377 bool ClearDSOLocalOnDeclarations,378 SetVector<GlobalValue *> *GlobalsToImport) {379 llvm::TimeTraceScope timeScope("Rename module for ThinLTO");380 FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport,381 ClearDSOLocalOnDeclarations);382 ThinLTOProcessing.run();383}384