LLVM 20.0.0git
FunctionImportUtils.cpp
Go to the documentation of this file.
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the FunctionImportGlobalProcessing class, used
10// to perform the necessary global value handling for function importing.
11//
12//===----------------------------------------------------------------------===//
13
16using namespace llvm;
17
18/// Uses the "source_filename" instead of a Module hash ID for the suffix of
19/// promoted locals during LTO. NOTE: This requires that the source filename
20/// has a unique name / path to avoid name collisions.
22 "use-source-filename-for-promoted-locals", cl::Hidden,
23 cl::desc("Uses the source file name instead of the Module hash. "
24 "This requires that the source filename has a unique name / "
25 "path to avoid name collisions."));
26
27/// Checks if we should import SGV as a definition, otherwise import as a
28/// declaration.
29bool FunctionImportGlobalProcessing::doImportAsDefinition(
30 const GlobalValue *SGV) {
31 if (!isPerformingImport())
32 return false;
33
34 // Only import the globals requested for importing.
35 if (!GlobalsToImport->count(const_cast<GlobalValue *>(SGV)))
36 return false;
37
38 assert(!isa<GlobalAlias>(SGV) &&
39 "Unexpected global alias in the import list.");
40
41 // Otherwise yes.
42 return true;
43}
44
45bool FunctionImportGlobalProcessing::shouldPromoteLocalToGlobal(
46 const GlobalValue *SGV, ValueInfo VI) {
47 assert(SGV->hasLocalLinkage());
48
49 // Ifuncs and ifunc alias does not have summary.
50 if (isa<GlobalIFunc>(SGV) ||
51 (isa<GlobalAlias>(SGV) &&
52 isa<GlobalIFunc>(cast<GlobalAlias>(SGV)->getAliaseeObject())))
53 return false;
54
55 // Both the imported references and the original local variable must
56 // be promoted.
57 if (!isPerformingImport() && !isModuleExporting())
58 return false;
59
60 if (isPerformingImport()) {
61 assert((!GlobalsToImport->count(const_cast<GlobalValue *>(SGV)) ||
62 !isNonRenamableLocal(*SGV)) &&
63 "Attempting to promote non-renamable local");
64 // We don't know for sure yet if we are importing this value (as either
65 // a reference or a def), since we are simply walking all values in the
66 // module. But by necessity if we end up importing it and it is local,
67 // it must be promoted, so unconditionally promote all values in the
68 // importing module.
69 return true;
70 }
71
72 // When exporting, consult the index. We can have more than one local
73 // with the same GUID, in the case of same-named locals in different but
74 // same-named source files that were compiled in their respective directories
75 // (so the source file name and resulting GUID is the same). Find the one
76 // in this module.
77 auto Summary = ImportIndex.findSummaryInModule(
78 VI, SGV->getParent()->getModuleIdentifier());
79 assert(Summary && "Missing summary for global value when exporting");
80 auto Linkage = Summary->linkage();
81 if (!GlobalValue::isLocalLinkage(Linkage)) {
82 assert(!isNonRenamableLocal(*SGV) &&
83 "Attempting to promote non-renamable local");
84 return true;
85 }
86
87 return false;
88}
89
90#ifndef NDEBUG
91bool FunctionImportGlobalProcessing::isNonRenamableLocal(
92 const GlobalValue &GV) const {
93 if (!GV.hasLocalLinkage())
94 return false;
95 // This needs to stay in sync with the logic in buildModuleSummaryIndex.
96 if (GV.hasSection())
97 return true;
98 if (Used.count(const_cast<GlobalValue *>(&GV)))
99 return true;
100 return false;
101}
102#endif
103
104std::string
105FunctionImportGlobalProcessing::getPromotedName(const GlobalValue *SGV) {
106 assert(SGV->hasLocalLinkage());
107
108 // For locals that must be promoted to global scope, ensure that
109 // the promoted name uniquely identifies the copy in the original module,
110 // using the ID assigned during combined index creation.
112 !SGV->getParent()->getSourceFileName().empty()) {
114 std::replace_if(std::begin(Suffix), std::end(Suffix),
115 [&](char ch) { return !isAlnum(ch); }, '_');
117 SGV->getName(), Suffix);
118 }
119
121 SGV->getName(),
122 ImportIndex.getModuleHash(SGV->getParent()->getModuleIdentifier()));
123}
124
126FunctionImportGlobalProcessing::getLinkage(const GlobalValue *SGV,
127 bool DoPromote) {
128 // Any local variable that is referenced by an exported function needs
129 // to be promoted to global scope. Since we don't currently know which
130 // functions reference which local variables/functions, we must treat
131 // all as potentially exported if this module is exporting anything.
132 if (isModuleExporting()) {
133 if (SGV->hasLocalLinkage() && DoPromote)
135 return SGV->getLinkage();
136 }
137
138 // Otherwise, if we aren't importing, no linkage change is needed.
139 if (!isPerformingImport())
140 return SGV->getLinkage();
141
142 switch (SGV->getLinkage()) {
145 // External and linkonce definitions are converted to available_externally
146 // definitions upon import, so that they are available for inlining
147 // and/or optimization, but are turned into declarations later
148 // during the EliminateAvailableExternally pass.
149 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))
151 // An imported external declaration stays external.
152 return SGV->getLinkage();
153
155 // An imported available_externally definition converts
156 // to external if imported as a declaration.
157 if (!doImportAsDefinition(SGV))
159 // An imported available_externally declaration stays that way.
160 return SGV->getLinkage();
161
164 // Can't import linkonce_any/weak_any definitions correctly, or we might
165 // change the program semantics, since the linker will pick the first
166 // linkonce_any/weak_any definition and importing would change the order
167 // they are seen by the linker. The module linking caller needs to enforce
168 // this.
169 assert(!doImportAsDefinition(SGV));
170 // If imported as a declaration, it becomes external_weak.
171 return SGV->getLinkage();
172
174 // For weak_odr linkage, there is a guarantee that all copies will be
175 // equivalent, so the issue described above for weak_any does not exist,
176 // and the definition can be imported. It can be treated similarly
177 // to an imported externally visible global value.
178 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))
180 else
182
184 // It would be incorrect to import an appending linkage variable,
185 // since it would cause global constructors/destructors to be
186 // executed multiple times. This should have already been handled
187 // by linkIfNeeded, and we will assert in shouldLinkFromSource
188 // if we try to import, so we simply return AppendingLinkage.
190
193 // If we are promoting the local to global scope, it is handled
194 // similarly to a normal externally visible global.
195 if (DoPromote) {
196 if (doImportAsDefinition(SGV) && !isa<GlobalAlias>(SGV))
198 else
200 }
201 // A non-promoted imported local definition stays local.
202 // The ThinLTO pass will eventually force-import their definitions.
203 return SGV->getLinkage();
204
206 // External weak doesn't apply to definitions, must be a declaration.
207 assert(!doImportAsDefinition(SGV));
208 // Linkage stays external_weak.
209 return SGV->getLinkage();
210
212 // Linkage stays common on definitions.
213 // The ThinLTO pass will eventually force-import their definitions.
214 return SGV->getLinkage();
215 }
216
217 llvm_unreachable("unknown linkage type");
218}
219
220void FunctionImportGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
221
223 if (GV.hasName())
224 VI = ImportIndex.getValueInfo(GV.getGUID());
225
226 // We should always have a ValueInfo (i.e. GV in index) for definitions when
227 // we are exporting, and also when importing that value.
228 assert(VI || GV.isDeclaration() ||
229 (isPerformingImport() && !doImportAsDefinition(&GV)));
230
231 // Mark read/write-only variables which can be imported with specific
232 // attribute. We can't internalize them now because IRMover will fail
233 // to link variable definitions to their external declarations during
234 // ThinLTO import. We'll internalize read-only variables later, after
235 // import is finished. See internalizeGVsAfterImport.
236 //
237 // If global value dead stripping is not enabled in summary then
238 // propagateConstants hasn't been run. We can't internalize GV
239 // in such case.
240 if (!GV.isDeclaration() && VI && ImportIndex.withAttributePropagation()) {
241 if (GlobalVariable *V = dyn_cast<GlobalVariable>(&GV)) {
242 // We can have more than one local with the same GUID, in the case of
243 // same-named locals in different but same-named source files that were
244 // compiled in their respective directories (so the source file name
245 // and resulting GUID is the same). Find the one in this module.
246 // Handle the case where there is no summary found in this module. That
247 // can happen in the distributed ThinLTO backend, because the index only
248 // contains summaries from the source modules if they are being imported.
249 // We might have a non-null VI and get here even in that case if the name
250 // matches one in this module (e.g. weak or appending linkage).
251 auto *GVS = dyn_cast_or_null<GlobalVarSummary>(
252 ImportIndex.findSummaryInModule(VI, M.getModuleIdentifier()));
253 if (GVS &&
254 (ImportIndex.isReadOnly(GVS) || ImportIndex.isWriteOnly(GVS))) {
255 V->addAttribute("thinlto-internalize");
256 // Objects referenced by writeonly GV initializer should not be
257 // promoted, because there is no any kind of read access to them
258 // on behalf of this writeonly GV. To avoid promotion we convert
259 // GV initializer to 'zeroinitializer'. This effectively drops
260 // references in IR module (not in combined index), so we can
261 // ignore them when computing import. We do not export references
262 // of writeonly object. See computeImportForReferencedGlobals
263 if (ImportIndex.isWriteOnly(GVS))
264 V->setInitializer(Constant::getNullValue(V->getValueType()));
265 }
266 }
267 }
268
269 if (GV.hasLocalLinkage() && shouldPromoteLocalToGlobal(&GV, VI)) {
270 // Save the original name string before we rename GV below.
271 auto Name = GV.getName().str();
272 GV.setName(getPromotedName(&GV));
273 GV.setLinkage(getLinkage(&GV, /* DoPromote */ true));
274 assert(!GV.hasLocalLinkage());
276
277 // If we are renaming a COMDAT leader, ensure that we record the COMDAT
278 // for later renaming as well. This is required for COFF.
279 if (const auto *C = GV.getComdat())
280 if (C->getName() == Name)
281 RenamedComdats.try_emplace(C, M.getOrInsertComdat(GV.getName()));
282 } else
283 GV.setLinkage(getLinkage(&GV, /* DoPromote */ false));
284
285 // When ClearDSOLocalOnDeclarations is true, clear dso_local if GV is
286 // converted to a declaration, to disable direct access. Don't do this if GV
287 // is implicitly dso_local due to a non-default visibility.
288 if (ClearDSOLocalOnDeclarations &&
290 (isPerformingImport() && !doImportAsDefinition(&GV))) &&
291 !GV.isImplicitDSOLocal()) {
292 GV.setDSOLocal(false);
293 } else if (VI && VI.isDSOLocal(ImportIndex.withDSOLocalPropagation())) {
294 // If all summaries are dso_local, symbol gets resolved to a known local
295 // definition.
296 GV.setDSOLocal(true);
299 }
300
301 // Remove functions imported as available externally defs from comdats,
302 // as this is a declaration for the linker, and will be dropped eventually.
303 // It is illegal for comdats to contain declarations.
304 auto *GO = dyn_cast<GlobalObject>(&GV);
305 if (GO && GO->isDeclarationForLinker() && GO->hasComdat()) {
306 // The IRMover should not have placed any imported declarations in
307 // a comdat, so the only declaration that should be in a comdat
308 // at this point would be a definition imported as available_externally.
309 assert(GO->hasAvailableExternallyLinkage() &&
310 "Expected comdat on definition (possibly available external)");
311 GO->setComdat(nullptr);
312 }
313}
314
315void FunctionImportGlobalProcessing::processGlobalsForThinLTO() {
316 for (GlobalVariable &GV : M.globals())
317 processGlobalForThinLTO(GV);
318 for (Function &SF : M)
319 processGlobalForThinLTO(SF);
320 for (GlobalAlias &GA : M.aliases())
321 processGlobalForThinLTO(GA);
322
323 // Replace any COMDATS that required renaming (because the COMDAT leader was
324 // promoted and renamed).
325 if (!RenamedComdats.empty())
326 for (auto &GO : M.global_objects())
327 if (auto *C = GO.getComdat()) {
328 auto Replacement = RenamedComdats.find(C);
329 if (Replacement != RenamedComdats.end())
330 GO.setComdat(Replacement->second);
331 }
332}
333
335 processGlobalsForThinLTO();
336 return false;
337}
338
340 bool ClearDSOLocalOnDeclarations,
341 SetVector<GlobalValue *> *GlobalsToImport) {
342 FunctionImportGlobalProcessing ThinLTOProcessing(M, Index, GlobalsToImport,
343 ClearDSOLocalOnDeclarations);
344 return ThinLTOProcessing.run();
345}
std::string Name
static cl::opt< bool > UseSourceFilenameForPromotedLocals("use-source-filename-for-promoted-locals", cl::Hidden, cl::desc("Uses the source file name instead of the Module hash. " "This requires that the source filename has a unique name / " "path to avoid name collisions."))
Uses the "source_filename" instead of a Module hash ID for the suffix of promoted locals during LTO.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:373
Class to handle necessary GlobalValue changes required by ThinLTO function importing,...
bool isImplicitDSOLocal() const
Definition: GlobalValue.h:298
static bool isLocalLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:409
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition: Globals.cpp:296
LinkageTypes getLinkage() const
Definition: GlobalValue.h:546
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
void setDLLStorageClass(DLLStorageClassTypes C)
Definition: GlobalValue.h:284
const Comdat * getComdat() const
Definition: Globals.cpp:199
bool hasDLLImportStorageClass() const
Definition: GlobalValue.h:278
static GUID getGUID(StringRef GlobalName)
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: Globals.cpp:75
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:537
bool isDeclarationForLinker() const
Definition: GlobalValue.h:618
Module * getParent()
Get the module that this global value is contained inside of...
Definition: GlobalValue.h:656
void setDSOLocal(bool Local)
Definition: GlobalValue.h:303
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:68
bool hasSection() const
Definition: GlobalValue.h:290
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:254
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition: GlobalValue.h:51
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:60
@ CommonLinkage
Tentative definitions.
Definition: GlobalValue.h:62
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:59
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:54
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:57
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:56
@ AppendingLinkage
Special purpose, only applies to global arrays.
Definition: GlobalValue.h:58
@ AvailableExternallyLinkage
Available for inspection, not emission.
Definition: GlobalValue.h:53
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition: GlobalValue.h:61
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:55
Class to hold module path string table and global value map, and encapsulate methods for operating on...
bool isReadOnly(const GlobalVarSummary *GVS) const
bool isWriteOnly(const GlobalVarSummary *GVS) const
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash)
Convenience method for creating a promoted global name for the given value name of a local,...
GlobalValueSummary * findSummaryInModule(ValueInfo VI, StringRef ModuleId) const
Find the summary for ValueInfo VI in module ModuleId, or nullptr if not found.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
const std::string & getSourceFileName() const
Get the module's original source file name.
Definition: Module.h:279
iterator_range< global_iterator > globals()
Definition: Module.h:702
const std::string & getModuleIdentifier() const
Get the module identifier which is, essentially, the name of the module.
Definition: Module.h:268
Comdat * getOrInsertComdat(StringRef Name)
Return the Comdat in the module with the specified name.
Definition: Module.cpp:611
A vector that has set insertion semantics.
Definition: SetVector.h:57
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition: SmallString.h:26
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:229
void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:377
bool hasName() const
Definition: Value.h:261
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:309
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool renameModuleForThinLTO(Module &M, const ModuleSummaryIndex &Index, bool ClearDSOLocalOnDeclarations, SetVector< GlobalValue * > *GlobalsToImport=nullptr)
Perform in-place global value handling on the given Module for exported local functions renamed and p...
Struct that holds a reference to a particular GUID in a global value summary.