Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 1 | //====- Internalize.h - Internalization API ---------------------*- C++ -*-===// |
| 2 | // |
||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
| 6 | // |
||
| 7 | //===----------------------------------------------------------------------===// |
||
| 8 | // |
||
| 9 | // This pass loops over all of the functions and variables in the input module. |
||
| 10 | // If the function or variable does not need to be preserved according to the |
||
| 11 | // client supplied callback, it is marked as internal. |
||
| 12 | // |
||
| 13 | // This transformation would not be legal in a regular compilation, but it gets |
||
| 14 | // extra information from the linker about what is safe. |
||
| 15 | // |
||
| 16 | // For example: Internalizing a function with external linkage. Only if we are |
||
| 17 | // told it is only used from within this module, it is safe to do it. |
||
| 18 | // |
||
| 19 | //===----------------------------------------------------------------------===// |
||
| 20 | |||
| 21 | #ifndef LLVM_TRANSFORMS_IPO_INTERNALIZE_H |
||
| 22 | #define LLVM_TRANSFORMS_IPO_INTERNALIZE_H |
||
| 23 | |||
| 24 | #include "llvm/ADT/DenseMap.h" |
||
| 25 | #include "llvm/ADT/StringSet.h" |
||
| 26 | #include "llvm/IR/PassManager.h" |
||
| 27 | #include <functional> |
||
| 28 | |||
| 29 | namespace llvm { |
||
| 30 | class Module; |
||
| 31 | class CallGraph; |
||
| 32 | |||
| 33 | /// A pass that internalizes all functions and variables other than those that |
||
| 34 | /// must be preserved according to \c MustPreserveGV. |
||
| 35 | class InternalizePass : public PassInfoMixin<InternalizePass> { |
||
| 36 | struct ComdatInfo { |
||
| 37 | // The number of members. A comdat with one member which is not externally |
||
| 38 | // visible can be freely dropped. |
||
| 39 | size_t Size = 0; |
||
| 40 | // Whether the comdat has an externally visible member. |
||
| 41 | bool External = false; |
||
| 42 | }; |
||
| 43 | |||
| 44 | bool IsWasm = false; |
||
| 45 | |||
| 46 | /// Client supplied callback to control wheter a symbol must be preserved. |
||
| 47 | const std::function<bool(const GlobalValue &)> MustPreserveGV; |
||
| 48 | /// Set of symbols private to the compiler that this pass should not touch. |
||
| 49 | StringSet<> AlwaysPreserved; |
||
| 50 | |||
| 51 | /// Return false if we're allowed to internalize this GV. |
||
| 52 | bool shouldPreserveGV(const GlobalValue &GV); |
||
| 53 | /// Internalize GV if it is possible to do so, i.e. it is not externally |
||
| 54 | /// visible and is not a member of an externally visible comdat. |
||
| 55 | bool maybeInternalize(GlobalValue &GV, |
||
| 56 | DenseMap<const Comdat *, ComdatInfo> &ComdatMap); |
||
| 57 | /// If GV is part of a comdat and is externally visible, keep track of its |
||
| 58 | /// comdat so that we don't internalize any of its members. |
||
| 59 | void checkComdat(GlobalValue &GV, |
||
| 60 | DenseMap<const Comdat *, ComdatInfo> &ComdatMap); |
||
| 61 | |||
| 62 | public: |
||
| 63 | InternalizePass(); |
||
| 64 | InternalizePass(std::function<bool(const GlobalValue &)> MustPreserveGV) |
||
| 65 | : MustPreserveGV(std::move(MustPreserveGV)) {} |
||
| 66 | |||
| 67 | /// Run the internalizer on \p TheModule, returns true if any changes was |
||
| 68 | /// made. |
||
| 69 | /// |
||
| 70 | /// If the CallGraph \p CG is supplied, it will be updated when |
||
| 71 | /// internalizing a function (by removing any edge from the "external node") |
||
| 72 | bool internalizeModule(Module &TheModule, CallGraph *CG = nullptr); |
||
| 73 | |||
| 74 | PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); |
||
| 75 | }; |
||
| 76 | |||
| 77 | /// Helper function to internalize functions and variables in a Module. |
||
| 78 | inline bool |
||
| 79 | internalizeModule(Module &TheModule, |
||
| 80 | std::function<bool(const GlobalValue &)> MustPreserveGV, |
||
| 81 | CallGraph *CG = nullptr) { |
||
| 82 | return InternalizePass(std::move(MustPreserveGV)) |
||
| 83 | .internalizeModule(TheModule, CG); |
||
| 84 | } |
||
| 85 | } // end namespace llvm |
||
| 86 | |||
| 87 | #endif // LLVM_TRANSFORMS_IPO_INTERNALIZE_H |