[NFC][RISCV] Remove CFIIndex argument from allocateStack (#117871)
[llvm-project.git] / llvm / lib / Transforms / IPO / ExtractGV.cpp
blob7b374536110320cc02214cc6aadea386e2484626
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
11 //===----------------------------------------------------------------------===//
13 #include "llvm/Transforms/IPO/ExtractGV.h"
14 #include "llvm/IR/Module.h"
15 #include "llvm/IR/PassManager.h"
17 using namespace llvm;
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.
23 static void makeVisible(GlobalValue &GV, bool Delete) {
24 bool Local = GV.hasLocalLinkage();
25 if (Local || Delete) {
26 GV.setLinkage(GlobalValue::ExternalLinkage);
27 if (Local)
28 GV.setVisibility(GlobalValue::HiddenVisibility);
29 return;
32 if (!GV.hasLinkOnceLinkage()) {
33 assert(!GV.isDiscardableIfUnused());
34 return;
37 // Map linkonce* to weak* so that llvm doesn't drop this GV.
38 switch (GV.getLinkage()) {
39 default:
40 llvm_unreachable("Unexpected linkage");
41 case GlobalValue::LinkOnceAnyLinkage:
42 GV.setLinkage(GlobalValue::WeakAnyLinkage);
43 return;
44 case GlobalValue::LinkOnceODRLinkage:
45 GV.setLinkage(GlobalValue::WeakODRLinkage);
46 return;
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.
53 ExtractGVPass::ExtractGVPass(std::vector<GlobalValue *> &GVs, bool deleteS,
54 bool keepConstInit)
55 : Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
56 keepConstInit(keepConstInit) {}
58 PreservedAnalyses ExtractGVPass::run(Module &M, ModuleAnalysisManager &) {
59 // Visit the global inline asm.
60 if (!deleteStuff)
61 M.setModuleInlineAsm("");
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.
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;
81 makeVisible(GV, Delete);
83 if (Delete) {
84 // Make this a declaration and drop it's comdat.
85 GV.setInitializer(nullptr);
86 GV.setComdat(nullptr);
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;
98 makeVisible(F, Delete);
100 if (Delete) {
101 // Make this a declaration and drop it's comdat.
102 F.deleteBody();
103 F.setComdat(nullptr);
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);
112 if (Delete) {
113 Type *Ty = GA.getValueType();
115 GA.removeFromParent();
116 llvm::Value *Declaration;
117 if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
118 Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage,
119 GA.getAddressSpace(), GA.getName(), &M);
121 } else {
122 Declaration = new GlobalVariable(
123 M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GA.getName());
125 GA.replaceAllUsesWith(Declaration);
126 delete &GA;
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);
135 if (!Delete)
136 continue;
138 auto *FuncType = dyn_cast<FunctionType>(IF.getValueType());
139 IF.removeFromParent();
140 llvm::Value *Declaration =
141 Function::Create(FuncType, GlobalValue::ExternalLinkage,
142 IF.getAddressSpace(), IF.getName(), &M);
143 IF.replaceAllUsesWith(Declaration);
144 delete &IF;
147 return PreservedAnalyses::none();