LLVM 20.0.0git
ExtractGV.cpp
Go to the documentation of this file.
1//===-- ExtractGV.cpp - Global Value extraction pass ----------------------===//
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 extracts global values
10//
11//===----------------------------------------------------------------------===//
12
14#include "llvm/IR/Module.h"
15#include "llvm/IR/PassManager.h"
16
17using namespace llvm;
18
19/// Make sure GV is visible from both modules. Delete is true if it is
20/// being deleted from this module.
21/// This also makes sure GV cannot be dropped so that references from
22/// the split module remain valid.
23static void makeVisible(GlobalValue &GV, bool Delete) {
24 bool Local = GV.hasLocalLinkage();
25 if (Local || Delete) {
27 if (Local)
29 return;
30 }
31
32 if (!GV.hasLinkOnceLinkage()) {
34 return;
35 }
36
37 // Map linkonce* to weak* so that llvm doesn't drop this GV.
38 switch (GV.getLinkage()) {
39 default:
40 llvm_unreachable("Unexpected linkage");
43 return;
46 return;
47 }
48}
49
50/// If deleteS is true, this pass deletes the specified global values.
51/// Otherwise, it deletes as much of the module as possible, except for the
52/// global values specified.
53ExtractGVPass::ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS,
54 bool keepConstInit)
55 : Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
56 keepConstInit(keepConstInit) {}
57
59 // Visit the global inline asm.
60 if (!deleteStuff)
61 M.setModuleInlineAsm("");
62
63 // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
64 // implementation could figure out which GlobalValues are actually
65 // referenced by the Named set, and which GlobalValues in the rest of
66 // the module are referenced by the NamedSet, and get away with leaving
67 // more internal and private things internal and private. But for now,
68 // be conservative and simple.
69
70 // Visit the GlobalVariables.
71 for (GlobalVariable &GV : M.globals()) {
72 bool Delete = deleteStuff == (bool)Named.count(&GV) &&
73 !GV.isDeclaration() && (!GV.isConstant() || !keepConstInit);
74 if (!Delete) {
75 if (GV.hasAvailableExternallyLinkage())
76 continue;
77 if (GV.getName() == "llvm.global_ctors")
78 continue;
79 }
80
81 makeVisible(GV, Delete);
82
83 if (Delete) {
84 // Make this a declaration and drop it's comdat.
85 GV.setInitializer(nullptr);
86 GV.setComdat(nullptr);
87 }
88 }
89
90 // Visit the Functions.
91 for (Function &F : M) {
92 bool Delete = deleteStuff == (bool)Named.count(&F) && !F.isDeclaration();
93 if (!Delete) {
94 if (F.hasAvailableExternallyLinkage())
95 continue;
96 }
97
98 makeVisible(F, Delete);
99
100 if (Delete) {
101 // Make this a declaration and drop it's comdat.
102 F.deleteBody();
103 F.setComdat(nullptr);
104 }
105 }
106
107 // Visit the Aliases.
108 for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
109 bool Delete = deleteStuff == (bool)Named.count(&GA);
110 makeVisible(GA, Delete);
111
112 if (Delete) {
113 Type *Ty = GA.getValueType();
114
115 GA.removeFromParent();
116 llvm::Value *Declaration;
117 if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
119 GA.getAddressSpace(), GA.getName(), &M);
120
121 } else {
122 Declaration = new GlobalVariable(
123 M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GA.getName());
124 }
125 GA.replaceAllUsesWith(Declaration);
126 delete &GA;
127 }
128 }
129
130 // Visit the IFuncs.
131 for (GlobalIFunc &IF : llvm::make_early_inc_range(M.ifuncs())) {
132 bool Delete = deleteStuff == (bool)Named.count(&IF);
133 makeVisible(IF, Delete);
134
135 if (!Delete)
136 continue;
137
138 auto *FuncType = dyn_cast<FunctionType>(IF.getValueType());
139 IF.removeFromParent();
140 llvm::Value *Declaration =
142 IF.getAddressSpace(), IF.getName(), &M);
143 IF.replaceAllUsesWith(Declaration);
144 delete &IF;
145 }
146
148}
static void makeVisible(GlobalValue &GV, bool Delete)
Make sure GV is visible from both modules.
Definition: ExtractGV.cpp:23
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
ExtractGVPass(std::vector< GlobalValue * > &GVs, bool deleteS=true, bool keepConstInit=false)
If deleteS is true, this pass deletes the specified global values.
Definition: ExtractGV.cpp:53
PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
Definition: ExtractGV.cpp:58
Class to represent function types.
Definition: DerivedTypes.h:105
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:173
bool hasLinkOnceLinkage() const
Definition: GlobalValue.h:515
LinkageTypes getLinkage() const
Definition: GlobalValue.h:546
bool hasLocalLinkage() const
Definition: GlobalValue.h:528
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:537
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:68
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:254
static bool isDiscardableIfUnused(LinkageTypes Linkage)
Whether the definition of this global may be discarded if it is not used in its compilation unit.
Definition: GlobalValue.h:449
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:54
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:57
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:52
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:56
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:55
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
LLVM Value Representation.
Definition: Value.h:74
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:657