137 lines
5.7 KiB
C++
137 lines
5.7 KiB
C++
//===- FunctionImportUtils.h - Importing support utilities -----*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines the FunctionImportGlobalProcessing class which is used
|
|
// to perform the necessary global value handling for function importing.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H
|
|
#define LLVM_TRANSFORMS_UTILS_FUNCTIONIMPORTUTILS_H
|
|
|
|
#include "llvm/ADT/SetVector.h"
|
|
#include "llvm/IR/ModuleSummaryIndex.h"
|
|
|
|
namespace llvm {
|
|
class Module;
|
|
|
|
/// Class to handle necessary GlobalValue changes required by ThinLTO
|
|
/// function importing, including linkage changes and any necessary renaming.
|
|
class FunctionImportGlobalProcessing {
|
|
/// The Module which we are exporting or importing functions from.
|
|
Module &M;
|
|
|
|
/// Module summary index passed in for function importing/exporting handling.
|
|
const ModuleSummaryIndex &ImportIndex;
|
|
|
|
/// Globals to import from this module, all other functions will be
|
|
/// imported as declarations instead of definitions.
|
|
SetVector<GlobalValue *> *GlobalsToImport;
|
|
|
|
/// Set to true if the given ModuleSummaryIndex contains any functions
|
|
/// from this source module, in which case we must conservatively assume
|
|
/// that any of its functions may be imported into another module
|
|
/// as part of a different backend compilation process.
|
|
bool HasExportedFunctions = false;
|
|
|
|
/// Set to true (only applicatable to ELF -fpic) if dso_local should be
|
|
/// dropped for a declaration.
|
|
///
|
|
/// On ELF, the assembler is conservative and assumes a global default
|
|
/// visibility symbol can be interposable. No direct access relocation is
|
|
/// allowed, if the definition is not in the translation unit, even if the
|
|
/// definition is available in the linkage unit. Thus we need to clear
|
|
/// dso_local to disable direct access.
|
|
///
|
|
/// This flag should not be set for -fno-pic or -fpie, which would
|
|
/// unnecessarily disable direct access.
|
|
bool ClearDSOLocalOnDeclarations;
|
|
|
|
/// Set of llvm.*used values, in order to validate that we don't try
|
|
/// to promote any non-renamable values.
|
|
SmallPtrSet<GlobalValue *, 8> Used;
|
|
|
|
/// Keep track of any COMDATs that require renaming (because COMDAT
|
|
/// leader was promoted and renamed). Maps from original COMDAT to one
|
|
/// with new name.
|
|
DenseMap<const Comdat *, Comdat *> RenamedComdats;
|
|
|
|
/// Check if we should promote the given local value to global scope.
|
|
bool shouldPromoteLocalToGlobal(const GlobalValue *SGV, ValueInfo VI);
|
|
|
|
#ifndef NDEBUG
|
|
/// Check if the given value is a local that can't be renamed (promoted).
|
|
/// Only used in assertion checking, and disabled under NDEBUG since the Used
|
|
/// set will not be populated.
|
|
bool isNonRenamableLocal(const GlobalValue &GV) const;
|
|
#endif
|
|
|
|
/// Helper methods to check if we are importing from or potentially
|
|
/// exporting from the current source module.
|
|
bool isPerformingImport() const { return GlobalsToImport != nullptr; }
|
|
bool isModuleExporting() const { return HasExportedFunctions; }
|
|
|
|
/// If we are importing from the source module, checks if we should
|
|
/// import SGV as a definition, otherwise import as a declaration.
|
|
bool doImportAsDefinition(const GlobalValue *SGV);
|
|
|
|
/// Get the name for a local SGV that should be promoted and renamed to global
|
|
/// scope in the linked destination module.
|
|
std::string getPromotedName(const GlobalValue *SGV);
|
|
|
|
/// Process globals so that they can be used in ThinLTO. This includes
|
|
/// promoting local variables so that they can be reference externally by
|
|
/// thin lto imported globals and converting strong external globals to
|
|
/// available_externally.
|
|
void processGlobalsForThinLTO();
|
|
void processGlobalForThinLTO(GlobalValue &GV);
|
|
|
|
/// Get the new linkage for SGV that should be used in the linked destination
|
|
/// module. Specifically, for ThinLTO importing or exporting it may need
|
|
/// to be adjusted. When \p DoPromote is true then we must adjust the
|
|
/// linkage for a required promotion of a local to global scope.
|
|
GlobalValue::LinkageTypes getLinkage(const GlobalValue *SGV, bool DoPromote);
|
|
|
|
public:
|
|
FunctionImportGlobalProcessing(Module &M, const ModuleSummaryIndex &Index,
|
|
SetVector<GlobalValue *> *GlobalsToImport,
|
|
bool ClearDSOLocalOnDeclarations)
|
|
: M(M), ImportIndex(Index), GlobalsToImport(GlobalsToImport),
|
|
ClearDSOLocalOnDeclarations(ClearDSOLocalOnDeclarations) {
|
|
// If we have a ModuleSummaryIndex but no function to import,
|
|
// then this is the primary module being compiled in a ThinLTO
|
|
// backend compilation, and we need to see if it has functions that
|
|
// may be exported to another backend compilation.
|
|
if (!GlobalsToImport)
|
|
HasExportedFunctions = ImportIndex.hasExportedFunctions(M);
|
|
|
|
#ifndef NDEBUG
|
|
// First collect those in the llvm.used set.
|
|
collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false);
|
|
// Next collect those in the llvm.compiler.used set.
|
|
collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ true);
|
|
#endif
|
|
}
|
|
|
|
bool run();
|
|
};
|
|
|
|
/// Perform in-place global value handling on the given Module for
|
|
/// exported local functions renamed and promoted for ThinLTO.
|
|
bool renameModuleForThinLTO(
|
|
Module &M, const ModuleSummaryIndex &Index,
|
|
bool ClearDSOLocalOnDeclarations,
|
|
SetVector<GlobalValue *> *GlobalsToImport = nullptr);
|
|
|
|
/// Compute synthetic function entry counts.
|
|
void computeSyntheticCounts(ModuleSummaryIndex &Index);
|
|
|
|
} // End llvm namespace
|
|
|
|
#endif
|