1303231Sdim//====- Internalize.h - Internalization API ---------------------*- C++ -*-===// 2303231Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6303231Sdim// 7303231Sdim//===----------------------------------------------------------------------===// 8303231Sdim// 9303231Sdim// This pass loops over all of the functions and variables in the input module. 10303231Sdim// If the function or variable does not need to be preserved according to the 11303231Sdim// client supplied callback, it is marked as internal. 12303231Sdim// 13303231Sdim// This transformation would not be legal in a regular compilation, but it gets 14303231Sdim// extra information from the linker about what is safe. 15303231Sdim// 16303231Sdim// For example: Internalizing a function with external linkage. Only if we are 17303231Sdim// told it is only used from within this module, it is safe to do it. 18303231Sdim// 19303231Sdim//===----------------------------------------------------------------------===// 20303231Sdim 21303231Sdim#ifndef LLVM_TRANSFORMS_IPO_INTERNALIZE_H 22303231Sdim#define LLVM_TRANSFORMS_IPO_INTERNALIZE_H 23303231Sdim 24353358Sdim#include "llvm/ADT/DenseSet.h" 25303231Sdim#include "llvm/ADT/StringSet.h" 26303231Sdim#include "llvm/IR/GlobalValue.h" 27303231Sdim#include "llvm/IR/PassManager.h" 28303231Sdim#include <functional> 29303231Sdim 30303231Sdimnamespace llvm { 31303231Sdimclass Module; 32303231Sdimclass CallGraph; 33303231Sdim 34303231Sdim/// A pass that internalizes all functions and variables other than those that 35303231Sdim/// must be preserved according to \c MustPreserveGV. 36303231Sdimclass InternalizePass : public PassInfoMixin<InternalizePass> { 37303231Sdim /// Client supplied callback to control wheter a symbol must be preserved. 38303231Sdim const std::function<bool(const GlobalValue &)> MustPreserveGV; 39303231Sdim /// Set of symbols private to the compiler that this pass should not touch. 40303231Sdim StringSet<> AlwaysPreserved; 41303231Sdim 42303231Sdim /// Return false if we're allowed to internalize this GV. 43303231Sdim bool shouldPreserveGV(const GlobalValue &GV); 44303231Sdim /// Internalize GV if it is possible to do so, i.e. it is not externally 45303231Sdim /// visible and is not a member of an externally visible comdat. 46303231Sdim bool maybeInternalize(GlobalValue &GV, 47353358Sdim const DenseSet<const Comdat *> &ExternalComdats); 48303231Sdim /// If GV is part of a comdat and is externally visible, keep track of its 49303231Sdim /// comdat so that we don't internalize any of its members. 50303231Sdim void checkComdatVisibility(GlobalValue &GV, 51353358Sdim DenseSet<const Comdat *> &ExternalComdats); 52303231Sdim 53303231Sdimpublic: 54303231Sdim InternalizePass(); 55303231Sdim InternalizePass(std::function<bool(const GlobalValue &)> MustPreserveGV) 56303231Sdim : MustPreserveGV(std::move(MustPreserveGV)) {} 57303231Sdim 58303231Sdim /// Run the internalizer on \p TheModule, returns true if any changes was 59303231Sdim /// made. 60303231Sdim /// 61303231Sdim /// If the CallGraph \p CG is supplied, it will be updated when 62303231Sdim /// internalizing a function (by removing any edge from the "external node") 63303231Sdim bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr); 64303231Sdim 65314564Sdim PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); 66303231Sdim}; 67303231Sdim 68303231Sdim/// Helper function to internalize functions and variables in a Module. 69303231Sdiminline bool 70303231SdiminternalizeModule(Module &TheModule, 71303231Sdim std::function<bool(const GlobalValue &)> MustPreserveGV, 72303231Sdim CallGraph *CG = nullptr) { 73303231Sdim return InternalizePass(std::move(MustPreserveGV)) 74303231Sdim .internalizeModule(TheModule, CG); 75303231Sdim} 76303231Sdim} // end namespace llvm 77303231Sdim 78303231Sdim#endif // LLVM_TRANSFORMS_IPO_INTERNALIZE_H 79