Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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=*/false); |
||
117 | // Next collect those in the llvm.compiler.used set. |
||
118 | collectUsedGlobalVariables(M, Vec, /*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 |