1 | //===- FunctionImportUtils.h - Importing support utilities -----*- C++ -*-===// |
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 defines the FunctionImportGlobalProcessing class which is used |
10 | // to perform the necessary global value handling for function importing. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H |
15 | #define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H |
16 | |
17 | #include "llvm/ADT/SetVector.h" |
18 | #include "llvm/IR/ModuleSummaryIndex.h" |
19 | |
20 | namespace llvm { |
21 | class Module; |
22 | |
23 | /// Class to handle necessary GlobalValue changes required by ThinLTO |
24 | /// function importing, including linkage changes and any necessary renaming. |
25 | class FunctionImportGlobalProcessing { |
26 | /// The Module which we are exporting or importing functions from. |
27 | Module &M; |
28 | |
29 | /// Module summary index passed in for function importing/exporting handling. |
30 | const ModuleSummaryIndex &ImportIndex; |
31 | |
32 | /// Globals to import from this module, all other functions will be |
33 | /// imported as declarations instead of definitions. |
34 | SetVector<GlobalValue *> *GlobalsToImport; |
35 | |
36 | /// Set to true if the given ModuleSummaryIndex contains any functions |
37 | /// from this source module, in which case we must conservatively assume |
38 | /// that any of its functions may be imported into another module |
39 | /// as part of a different backend compilation process. |
40 | bool HasExportedFunctions = false; |
41 | |
42 | /// Set to true (only applicatable to ELF -fpic) if dso_local should be |
43 | /// dropped for a declaration. |
44 | /// |
45 | /// On ELF, the assembler is conservative and assumes a global default |
46 | /// visibility symbol can be interposable. No direct access relocation is |
47 | /// allowed, if the definition is not in the translation unit, even if the |
48 | /// definition is available in the linkage unit. Thus we need to clear |
49 | /// dso_local to disable direct access. |
50 | /// |
51 | /// This flag should not be set for -fno-pic or -fpie, which would |
52 | /// unnecessarily disable direct access. |
53 | bool ClearDSOLocalOnDeclarations; |
54 | |
55 | /// Set of llvm.*used values, in order to validate that we don't try |
56 | /// to promote any non-renamable values. |
57 | SmallPtrSet<GlobalValue *, 4> Used; |
58 | |
59 | /// Keep track of any COMDATs that require renaming (because COMDAT |
60 | /// leader was promoted and renamed). Maps from original COMDAT to one |
61 | /// with new name. |
62 | DenseMap<const Comdat *, Comdat *> RenamedComdats; |
63 | |
64 | /// Check if we should promote the given local value to global scope. |
65 | bool shouldPromoteLocalToGlobal(const GlobalValue *SGV, ValueInfo VI); |
66 | |
67 | #ifndef NDEBUG |
68 | /// Check if the given value is a local that can't be renamed (promoted). |
69 | /// Only used in assertion checking, and disabled under NDEBUG since the Used |
70 | /// set will not be populated. |
71 | bool isNonRenamableLocal(const GlobalValue &GV) const; |
72 | #endif |
73 | |
74 | /// Helper methods to check if we are importing from or potentially |
75 | /// exporting from the current source module. |
76 | bool isPerformingImport() const { return GlobalsToImport != nullptr; } |
77 | bool isModuleExporting() const { return HasExportedFunctions; } |
78 | |
79 | /// If we are importing from the source module, checks if we should |
80 | /// import SGV as a definition, otherwise import as a declaration. |
81 | bool doImportAsDefinition(const GlobalValue *SGV); |
82 | |
83 | /// Get the name for a local SGV that should be promoted and renamed to global |
84 | /// scope in the linked destination module. |
85 | std::string getPromotedName(const GlobalValue *SGV); |
86 | |
87 | /// Process globals so that they can be used in ThinLTO. This includes |
88 | /// promoting local variables so that they can be reference externally by |
89 | /// thin lto imported globals and converting strong external globals to |
90 | /// available_externally. |
91 | void processGlobalsForThinLTO(); |
92 | void processGlobalForThinLTO(GlobalValue &GV); |
93 | |
94 | /// Get the new linkage for SGV that should be used in the linked destination |
95 | /// module. Specifically, for ThinLTO importing or exporting it may need |
96 | /// to be adjusted. When \p DoPromote is true then we must adjust the |
97 | /// linkage for a required promotion of a local to global scope. |
98 | GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV, bool DoPromote); |
99 | |
100 | public: |
101 | FunctionImportGlobalProcessing(Module &M, const ModuleSummaryIndex &Index, |
102 | SetVector<GlobalValue *> *GlobalsToImport, |
103 | bool ClearDSOLocalOnDeclarations) |
104 | : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport), |
105 | ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) { |
106 | // If we have a ModuleSummaryIndex but no function to import, |
107 | // then this is the primary module being compiled in a ThinLTO |
108 | // backend compilation, and we need to see if it has functions that |
109 | // may be exported to another backend compilation. |
110 | if (!GlobalsToImport) |
111 | HasExportedFunctions = ImportIndex.hasExportedFunctions(M); |
112 | |
113 | #ifndef NDEBUG |
114 | SmallVector<GlobalValue *, 4> Vec; |
115 | // First collect those in the llvm.used set. |
116 | collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/CompilerUsed: false); |
117 | // Next collect those in the llvm.compiler.used set. |
118 | collectUsedGlobalVariables(M, Vec, /*CompilerUsed=*/CompilerUsed: true); |
119 | Used = {Vec.begin(), Vec.end()}; |
120 | #endif |
121 | } |
122 | |
123 | bool run(); |
124 | }; |
125 | |
126 | /// Perform in-place global value handling on the given Module for |
127 | /// exported local functions renamed and promoted for ThinLTO. |
128 | bool renameModuleForThinLTO( |
129 | Module &M, const ModuleSummaryIndex &Index, |
130 | bool ClearDSOLocalOnDeclarations, |
131 | SetVector<GlobalValue *> *GlobalsToImport = nullptr); |
132 | |
133 | } // End llvm namespace |
134 | |
135 | #endif |
136 | |