1 //===- FunctionImportUtils.h - Importing support utilities -----*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file defines the FunctionImportGlobalProcessing class which is used 11 // to perform the necessary global value handling for function importing. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #ifndef LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H 16 #define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H 17 18 #include "llvm/ADT/SetVector.h" 19 #include "llvm/IR/ModuleSummaryIndex.h" 20 21 namespace llvm { 22 class Module; 23 24 /// Class to handle necessary GlobalValue changes required by ThinLTO 25 /// function importing, including linkage changes and any necessary renaming. 26 class FunctionImportGlobalProcessing { 27 /// The Module which we are exporting or importing functions from. 28 Module &M; 29 30 /// Module summary index passed in for function importing/exporting handling. 31 const ModuleSummaryIndex &ImportIndex; 32 33 /// Globals to import from this module, all other functions will be 34 /// imported as declarations instead of definitions. 35 DenseSet<const GlobalValue *> *GlobalsToImport; 36 37 /// Set to true if the given ModuleSummaryIndex contains any functions 38 /// from this source module, in which case we must conservatively assume 39 /// that any of its functions may be imported into another module 40 /// as part of a different backend compilation process. 41 bool HasExportedFunctions = false; 42 43 /// Check if we should promote the given local value to global scope. 44 bool doPromoteLocalToGlobal(const GlobalValue *SGV); 45 46 /// Helper methods to check if we are importing from or potentially 47 /// exporting from the current source module. isPerformingImport()48 bool isPerformingImport() const { return GlobalsToImport != nullptr; } isModuleExporting()49 bool isModuleExporting() const { return HasExportedFunctions; } 50 51 /// If we are importing from the source module, checks if we should 52 /// import SGV as a definition, otherwise import as a declaration. 53 bool doImportAsDefinition(const GlobalValue *SGV); 54 55 /// Get the name for SGV that should be used in the linked destination 56 /// module. Specifically, this handles the case where we need to rename 57 /// a local that is being promoted to global scope. 58 std::string getName(const GlobalValue *SGV); 59 60 /// Process globals so that they can be used in ThinLTO. This includes 61 /// promoting local variables so that they can be reference externally by 62 /// thin lto imported globals and converting strong external globals to 63 /// available_externally. 64 void processGlobalsForThinLTO(); 65 void processGlobalForThinLTO(GlobalValue &GV); 66 67 /// Get the new linkage for SGV that should be used in the linked destination 68 /// module. Specifically, for ThinLTO importing or exporting it may need 69 /// to be adjusted. 70 GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV); 71 72 public: 73 FunctionImportGlobalProcessing( 74 Module &M, const ModuleSummaryIndex &Index, 75 DenseSet<const GlobalValue *> *GlobalsToImport = nullptr) M(M)76 : M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport) { 77 // If we have a ModuleSummaryIndex but no function to import, 78 // then this is the primary module being compiled in a ThinLTO 79 // backend compilation, and we need to see if it has functions that 80 // may be exported to another backend compilation. 81 if (!GlobalsToImport) 82 HasExportedFunctions = ImportIndex.hasExportedFunctions(M); 83 } 84 85 bool run(); 86 87 static bool 88 doImportAsDefinition(const GlobalValue *SGV, 89 DenseSet<const GlobalValue *> *GlobalsToImport); 90 }; 91 92 /// Perform in-place global value handling on the given Module for 93 /// exported local functions renamed and promoted for ThinLTO. 94 bool renameModuleForThinLTO( 95 Module &M, const ModuleSummaryIndex &Index, 96 DenseSet<const GlobalValue *> *GlobalsToImport = nullptr); 97 98 } // End llvm namespace 99 100 #endif 101