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