Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/lib/Transforms/IPO/ExtractGV.cpp
35266 views
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
13
#include "llvm/Transforms/IPO/ExtractGV.h"
14
#include "llvm/IR/Module.h"
15
#include "llvm/IR/PassManager.h"
16
#include <algorithm>
17
18
using namespace llvm;
19
20
/// Make sure GV is visible from both modules. Delete is true if it is
21
/// being deleted from this module.
22
/// This also makes sure GV cannot be dropped so that references from
23
/// the split module remain valid.
24
static void makeVisible(GlobalValue &GV, bool Delete) {
25
bool Local = GV.hasLocalLinkage();
26
if (Local || Delete) {
27
GV.setLinkage(GlobalValue::ExternalLinkage);
28
if (Local)
29
GV.setVisibility(GlobalValue::HiddenVisibility);
30
return;
31
}
32
33
if (!GV.hasLinkOnceLinkage()) {
34
assert(!GV.isDiscardableIfUnused());
35
return;
36
}
37
38
// Map linkonce* to weak* so that llvm doesn't drop this GV.
39
switch (GV.getLinkage()) {
40
default:
41
llvm_unreachable("Unexpected linkage");
42
case GlobalValue::LinkOnceAnyLinkage:
43
GV.setLinkage(GlobalValue::WeakAnyLinkage);
44
return;
45
case GlobalValue::LinkOnceODRLinkage:
46
GV.setLinkage(GlobalValue::WeakODRLinkage);
47
return;
48
}
49
}
50
51
/// If deleteS is true, this pass deletes the specified global values.
52
/// Otherwise, it deletes as much of the module as possible, except for the
53
/// global values specified.
54
ExtractGVPass::ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS,
55
bool keepConstInit)
56
: Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
57
keepConstInit(keepConstInit) {}
58
59
PreservedAnalyses ExtractGVPass::run(Module &M, ModuleAnalysisManager &) {
60
// Visit the global inline asm.
61
if (!deleteStuff)
62
M.setModuleInlineAsm("");
63
64
// For simplicity, just give all GlobalValues ExternalLinkage. A trickier
65
// implementation could figure out which GlobalValues are actually
66
// referenced by the Named set, and which GlobalValues in the rest of
67
// the module are referenced by the NamedSet, and get away with leaving
68
// more internal and private things internal and private. But for now,
69
// be conservative and simple.
70
71
// Visit the GlobalVariables.
72
for (GlobalVariable &GV : M.globals()) {
73
bool Delete = deleteStuff == (bool)Named.count(&GV) &&
74
!GV.isDeclaration() && (!GV.isConstant() || !keepConstInit);
75
if (!Delete) {
76
if (GV.hasAvailableExternallyLinkage())
77
continue;
78
if (GV.getName() == "llvm.global_ctors")
79
continue;
80
}
81
82
makeVisible(GV, Delete);
83
84
if (Delete) {
85
// Make this a declaration and drop it's comdat.
86
GV.setInitializer(nullptr);
87
GV.setComdat(nullptr);
88
}
89
}
90
91
// Visit the Functions.
92
for (Function &F : M) {
93
bool Delete = deleteStuff == (bool)Named.count(&F) && !F.isDeclaration();
94
if (!Delete) {
95
if (F.hasAvailableExternallyLinkage())
96
continue;
97
}
98
99
makeVisible(F, Delete);
100
101
if (Delete) {
102
// Make this a declaration and drop it's comdat.
103
F.deleteBody();
104
F.setComdat(nullptr);
105
}
106
}
107
108
// Visit the Aliases.
109
for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
110
bool Delete = deleteStuff == (bool)Named.count(&GA);
111
makeVisible(GA, Delete);
112
113
if (Delete) {
114
Type *Ty = GA.getValueType();
115
116
GA.removeFromParent();
117
llvm::Value *Declaration;
118
if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
119
Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
120
GA.getAddressSpace(), GA.getName(), &M);
121
122
} else {
123
Declaration = new GlobalVariable(
124
M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GA.getName());
125
}
126
GA.replaceAllUsesWith(Declaration);
127
delete &GA;
128
}
129
}
130
131
// Visit the IFuncs.
132
for (GlobalIFunc &IF : llvm::make_early_inc_range(M.ifuncs())) {
133
bool Delete = deleteStuff == (bool)Named.count(&IF);
134
makeVisible(IF, Delete);
135
136
if (!Delete)
137
continue;
138
139
auto *FuncType = dyn_cast<FunctionType>(IF.getValueType());
140
IF.removeFromParent();
141
llvm::Value *Declaration =
142
Function::Create(FuncType, GlobalValue::ExternalLinkage,
143
IF.getAddressSpace(), IF.getName(), &M);
144
IF.replaceAllUsesWith(Declaration);
145
delete &IF;
146
}
147
148
return PreservedAnalyses::none();
149
}
150
151