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 |