llvm.org GIT mirror llvm / 73ef481
[ThinLTO] Enable in-place symbol changes for exporting module Summary: Move ThinLTO global value processing functions out of ModuleLinker and into a new ThinLTOGlobalProcessor class, which performs any necessary linkage and naming changes on the given module in place. As a result, renameModuleForThinLTO no longer needs to create a new Module when performing any necessary local to global promotion on a module that we are possibly exporting from during a ThinLTO backend compilation. During function importing the ThinLTO processing is still invoked from the ModuleLinker (via the new class), as it needs to perform renaming and linkage changes on the source module, e.g. in order to get the correct renaming during local to global promotion. Reviewers: joker.eph Subscribers: davidxl, llvm-commits, joker.eph Differential Revision: http://reviews.llvm.org/D15696 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257174 91177308-0d34-0410-b5e6-96231b3b80d8 Teresa Johnson 4 years ago
2 changed file(s) with 125 addition(s) and 50 deletion(s). Raw diff Collapse all Expand all
6666 DenseMap *ValIDToTempMDMap);
6767 };
6868
69 /// Create a new module with exported local functions renamed and promoted
70 /// for ThinLTO.
69 /// Perform in-place global value handling on the given Module for
70 /// exported local functions renamed and promoted for ThinLTO.
7171 std::unique_ptr renameModuleForThinLTO(std::unique_ptr M,
7272 const FunctionInfoIndex *Index);
7373
6363 bool shouldInternalizeLinkedSymbols() {
6464 return Flags & Linker::InternalizeLinkedSymbols;
6565 }
66
67 /// Check if we should promote the given local value to global scope.
68 bool doPromoteLocalToGlobal(const GlobalValue *SGV);
6966
7067 bool shouldLinkFromSource(bool &LinkFromSrc, const GlobalValue &Dest,
7168 const GlobalValue &Src);
9693 Module &DstM = Mover.getModule();
9794 // If the source has no name it can't link. If it has local linkage,
9895 // there is no name match-up going on.
99 if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(getLinkage(SrcGV)))
96 if (!SrcGV->hasName() || GlobalValue::isLocalLinkage(SrcGV->getLinkage()))
10097 return nullptr;
10198
10299 // Otherwise see if we have a match in the destination module's symtab.
103 GlobalValue *DGV = DstM.getNamedValue(getName(SrcGV));
100 GlobalValue *DGV = DstM.getNamedValue(SrcGV->getName());
104101 if (!DGV)
105102 return nullptr;
106103
115112
116113 bool linkIfNeeded(GlobalValue &GV);
117114
118 /// Helper methods to check if we are importing from or potentially
119 /// exporting from the current source module.
115 /// Helper method to check if we are importing from the current source
116 /// module.
120117 bool isPerformingImport() const { return FunctionsToImport != nullptr; }
121 bool isModuleExporting() const { return HasExportedFunctions; }
122118
123119 /// If we are importing from the source module, checks if we should
124120 /// import SGV as a definition, otherwise import as a declaration.
125121 bool doImportAsDefinition(const GlobalValue *SGV);
126
127 /// Get the name for SGV that should be used in the linked destination
128 /// module. Specifically, this handles the case where we need to rename
129 /// a local that is being promoted to global scope.
130 std::string getName(const GlobalValue *SGV);
131
132 /// Process globals so that they can be used in ThinLTO. This includes
133 /// promoting local variables so that they can be reference externally by
134 /// thin lto imported globals and converting strong external globals to
135 /// available_externally.
136 void processGlobalsForThinLTO();
137 void processGlobalForThinLTO(GlobalValue &GV);
138
139 /// Get the new linkage for SGV that should be used in the linked destination
140 /// module. Specifically, for ThinLTO importing or exporting it may need
141 /// to be adjusted.
142 GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV);
143122
144123 public:
145124 ModuleLinker(IRMover &Mover, Module &SrcM, unsigned Flags,
163142
164143 bool run();
165144 };
166 }
167
168 bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
169 if (!isPerformingImport())
170 return false;
145
146 /// Class to handle necessary GlobalValue changes required by ThinLTO including
147 /// linkage changes and any necessary renaming.
148 class ThinLTOGlobalProcessing {
149 /// The Module which we are exporting or importing functions from.
150 Module &M;
151
152 /// Function index passed in for function importing/exporting handling.
153 const FunctionInfoIndex *ImportIndex;
154
155 /// Functions to import from this module, all other functions will be
156 /// imported as declarations instead of definitions.
157 DenseSet *FunctionsToImport;
158
159 /// Set to true if the given FunctionInfoIndex contains any functions
160 /// from this source module, in which case we must conservatively assume
161 /// that any of its functions may be imported into another module
162 /// as part of a different backend compilation process.
163 bool HasExportedFunctions = false;
164
165 /// Populated during ThinLTO global processing with locals promoted
166 /// to global scope in an exporting module, which now need to be linked
167 /// in if calling from the ModuleLinker.
168 SetVector NewExportedValues;
169
170 /// Check if we should promote the given local value to global scope.
171 bool doPromoteLocalToGlobal(const GlobalValue *SGV);
172
173 /// Helper methods to check if we are importing from or potentially
174 /// exporting from the current source module.
175 bool isPerformingImport() const { return FunctionsToImport != nullptr; }
176 bool isModuleExporting() const { return HasExportedFunctions; }
177
178 /// If we are importing from the source module, checks if we should
179 /// import SGV as a definition, otherwise import as a declaration.
180 bool doImportAsDefinition(const GlobalValue *SGV);
181
182 /// Get the name for SGV that should be used in the linked destination
183 /// module. Specifically, this handles the case where we need to rename
184 /// a local that is being promoted to global scope.
185 std::string getName(const GlobalValue *SGV);
186
187 /// Process globals so that they can be used in ThinLTO. This includes
188 /// promoting local variables so that they can be reference externally by
189 /// thin lto imported globals and converting strong external globals to
190 /// available_externally.
191 void processGlobalsForThinLTO();
192 void processGlobalForThinLTO(GlobalValue &GV);
193
194 /// Get the new linkage for SGV that should be used in the linked destination
195 /// module. Specifically, for ThinLTO importing or exporting it may need
196 /// to be adjusted.
197 GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV);
198
199 public:
200 ThinLTOGlobalProcessing(
201 Module &M, const FunctionInfoIndex *Index,
202 DenseSet *FunctionsToImport = nullptr)
203 : M(M), ImportIndex(Index), FunctionsToImport(FunctionsToImport) {
204 // If we have a FunctionInfoIndex but no function to import,
205 // then this is the primary module being compiled in a ThinLTO
206 // backend compilation, and we need to see if it has functions that
207 // may be exported to another backend compilation.
208 if (!FunctionsToImport)
209 HasExportedFunctions = ImportIndex->hasExportedFunctions(M);
210 }
211
212 bool run();
213
214 /// Access the promoted globals that are now exported and need to be linked.
215 SetVector &getNewExportedValues() { return NewExportedValues; }
216 };
217 }
218
219 /// Checks if we should import SGV as a definition, otherwise import as a
220 /// declaration.
221 static bool
222 doImportAsDefinitionImpl(const GlobalValue *SGV,
223 DenseSet *FunctionsToImport) {
171224 auto *GA = dyn_cast(SGV);
172225 if (GA) {
173226 if (GA->hasWeakAnyLinkage())
175228 const GlobalObject *GO = GA->getBaseObject();
176229 if (!GO->hasLinkOnceODRLinkage())
177230 return false;
178 return doImportAsDefinition(GO);
231 return doImportAsDefinitionImpl(GO, FunctionsToImport);
179232 }
180233 // Always import GlobalVariable definitions, except for the special
181234 // case of WeakAny which are imported as ExternalWeak declarations
195248 return false;
196249 }
197250
198 bool ModuleLinker::doPromoteLocalToGlobal(const GlobalValue *SGV) {
251 bool ThinLTOGlobalProcessing::doImportAsDefinition(const GlobalValue *SGV) {
252 if (!isPerformingImport())
253 return false;
254 return doImportAsDefinitionImpl(SGV, FunctionsToImport);
255 }
256
257 bool ModuleLinker::doImportAsDefinition(const GlobalValue *SGV) {
258 if (!isPerformingImport())
259 return false;
260 return doImportAsDefinitionImpl(SGV, FunctionsToImport);
261 }
262
263 bool ThinLTOGlobalProcessing::doPromoteLocalToGlobal(const GlobalValue *SGV) {
199264 assert(SGV->hasLocalLinkage());
200265 // Both the imported references and the original local variable must
201266 // be promoted.
219284 return true;
220285 }
221286
222 std::string ModuleLinker::getName(const GlobalValue *SGV) {
287 std::string ThinLTOGlobalProcessing::getName(const GlobalValue *SGV) {
223288 // For locals that must be promoted to global scope, ensure that
224289 // the promoted name uniquely identifies the copy in the original module,
225290 // using the ID assigned during combined index creation. When importing,
233298 return SGV->getName();
234299 }
235300
236 GlobalValue::LinkageTypes ModuleLinker::getLinkage(const GlobalValue *SGV) {
301 GlobalValue::LinkageTypes
302 ThinLTOGlobalProcessing::getLinkage(const GlobalValue *SGV) {
237303 // Any local variable that is referenced by an exported function needs
238304 // to be promoted to global scope. Since we don't currently know which
239305 // functions reference which local variables/functions, we must treat
297363 // since it would cause global constructors/destructors to be
298364 // executed multiple times. This should have already been handled
299365 // by linkIfNeeded, and we will assert in shouldLinkFromSource
300 // if we try to import, so we simply return AppendingLinkage here
301 // as this helper is called more widely in getLinkedToGlobal.
366 // if we try to import, so we simply return AppendingLinkage.
302367 return GlobalValue::AppendingLinkage;
303368
304369 case GlobalValue::InternalLinkage:
651716 }
652717 }
653718
654 void ModuleLinker::processGlobalForThinLTO(GlobalValue &GV) {
719 void ThinLTOGlobalProcessing::processGlobalForThinLTO(GlobalValue &GV) {
655720 if (GV.hasLocalLinkage() &&
656721 (doPromoteLocalToGlobal(&GV) || isPerformingImport())) {
657722 GV.setName(getName(&GV));
659724 if (!GV.hasLocalLinkage())
660725 GV.setVisibility(GlobalValue::HiddenVisibility);
661726 if (isModuleExporting())
662 ValuesToLink.insert(&GV);
727 NewExportedValues.insert(&GV);
663728 return;
664729 }
665730 GV.setLinkage(getLinkage(&GV));
666731 }
667732
668 void ModuleLinker::processGlobalsForThinLTO() {
669 for (GlobalVariable &GV : SrcM.globals())
733 void ThinLTOGlobalProcessing::processGlobalsForThinLTO() {
734 for (GlobalVariable &GV : M.globals())
670735 processGlobalForThinLTO(GV);
671 for (Function &SF : SrcM)
736 for (Function &SF : M)
672737 processGlobalForThinLTO(SF);
673 for (GlobalAlias &GA : SrcM.aliases())
738 for (GlobalAlias &GA : M.aliases())
674739 processGlobalForThinLTO(GA);
740 }
741
742 bool ThinLTOGlobalProcessing::run() {
743 processGlobalsForThinLTO();
744 return false;
675745 }
676746
677747 bool ModuleLinker::run() {
712782 if (linkIfNeeded(GA))
713783 return true;
714784
715 processGlobalsForThinLTO();
785 if (ImportIndex) {
786 ThinLTOGlobalProcessing ThinLTOProcessing(SrcM, ImportIndex,
787 FunctionsToImport);
788 if (ThinLTOProcessing.run())
789 return true;
790 for (auto *GV : ThinLTOProcessing.getNewExportedValues())
791 ValuesToLink.insert(GV);
792 }
716793
717794 for (unsigned I = 0; I < ValuesToLink.size(); ++I) {
718795 GlobalValue *GV = ValuesToLink[I];
788865 std::unique_ptr
789866 llvm::renameModuleForThinLTO(std::unique_ptr M,
790867 const FunctionInfoIndex *Index) {
791 std::unique_ptr RenamedModule(
792 new llvm::Module(M->getModuleIdentifier(), M->getContext()));
793 Linker L(*RenamedModule.get());
794 if (L.linkInModule(std::move(M), llvm::Linker::Flags::None, Index))
868 ThinLTOGlobalProcessing ThinLTOProcessing(*M, Index);
869 if (ThinLTOProcessing.run())
795870 return nullptr;
796 return RenamedModule;
871 return M;
797872 }
798873
799874 //===----------------------------------------------------------------------===//