LLVM  12.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 
13 #include "llvm/ADT/SetVector.h"
14 #include "llvm/IR/LLVMContext.h"
15 #include "llvm/IR/Module.h"
16 #include "llvm/Pass.h"
17 #include "llvm/Transforms/IPO.h"
18 #include <algorithm>
19 using namespace llvm;
20 
21 /// Make sure GV is visible from both modules. Delete is true if it is
22 /// being deleted from this module.
23 /// This also makes sure GV cannot be dropped so that references from
24 /// the split module remain valid.
25 static void makeVisible(GlobalValue &GV, bool Delete) {
26  bool Local = GV.hasLocalLinkage();
27  if (Local || Delete) {
29  if (Local)
31  return;
32  }
33 
34  if (!GV.hasLinkOnceLinkage()) {
36  return;
37  }
38 
39  // Map linkonce* to weak* so that llvm doesn't drop this GV.
40  switch(GV.getLinkage()) {
41  default:
42  llvm_unreachable("Unexpected linkage");
45  return;
48  return;
49  }
50 }
51 
52 namespace {
53  /// A pass to extract specific global values and their dependencies.
54  class GVExtractorPass : public ModulePass {
56  bool deleteStuff;
57  bool keepConstInit;
58  public:
59  static char ID; // Pass identification, replacement for typeid
60 
61  /// If deleteS is true, this pass deletes the specified global values.
62  /// Otherwise, it deletes as much of the module as possible, except for the
63  /// global values specified.
64  explicit GVExtractorPass(std::vector<GlobalValue*> &GVs,
65  bool deleteS = true, bool keepConstInit = false)
66  : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
67  keepConstInit(keepConstInit) {}
68 
69  bool runOnModule(Module &M) override {
70  if (skipModule(M))
71  return false;
72 
73  // Visit the global inline asm.
74  if (!deleteStuff)
75  M.setModuleInlineAsm("");
76 
77  // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
78  // implementation could figure out which GlobalValues are actually
79  // referenced by the Named set, and which GlobalValues in the rest of
80  // the module are referenced by the NamedSet, and get away with leaving
81  // more internal and private things internal and private. But for now,
82  // be conservative and simple.
83 
84  // Visit the GlobalVariables.
86  I != E; ++I) {
87  bool Delete =
88  deleteStuff == (bool)Named.count(&*I) && !I->isDeclaration() &&
89  (!I->isConstant() || !keepConstInit);
90  if (!Delete) {
91  if (I->hasAvailableExternallyLinkage())
92  continue;
93  if (I->getName() == "llvm.global_ctors")
94  continue;
95  }
96 
97  makeVisible(*I, Delete);
98 
99  if (Delete) {
100  // Make this a declaration and drop it's comdat.
101  I->setInitializer(nullptr);
102  I->setComdat(nullptr);
103  }
104  }
105 
106  // Visit the Functions.
107  for (Function &F : M) {
108  bool Delete =
109  deleteStuff == (bool)Named.count(&F) && !F.isDeclaration();
110  if (!Delete) {
111  if (F.hasAvailableExternallyLinkage())
112  continue;
113  }
114 
115  makeVisible(F, Delete);
116 
117  if (Delete) {
118  // Make this a declaration and drop it's comdat.
119  F.deleteBody();
120  F.setComdat(nullptr);
121  }
122  }
123 
124  // Visit the Aliases.
125  for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
126  I != E;) {
127  Module::alias_iterator CurI = I;
128  ++I;
129 
130  bool Delete = deleteStuff == (bool)Named.count(&*CurI);
131  makeVisible(*CurI, Delete);
132 
133  if (Delete) {
134  Type *Ty = CurI->getValueType();
135 
136  CurI->removeFromParent();
137  llvm::Value *Declaration;
138  if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
140  CurI->getAddressSpace(),
141  CurI->getName(), &M);
142 
143  } else {
144  Declaration =
146  nullptr, CurI->getName());
147 
148  }
149  CurI->replaceAllUsesWith(Declaration);
150  delete &*CurI;
151  }
152  }
153 
154  return true;
155  }
156  };
157 
158  char GVExtractorPass::ID = 0;
159 }
160 
161 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
162  bool deleteFn, bool keepConstInit) {
163  return new GVExtractorPass(GVs, deleteFn, keepConstInit);
164 }
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:235
bool hasLocalLinkage() const
Definition: GlobalValue.h:445
This class represents lattice values for constants.
Definition: AllocatorList.h:23
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:67
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:53
ModulePass * createGVExtractionPass(std::vector< GlobalValue *> &GVs, bool deleteFn=false, bool keepConstInit=false)
createGVExtractionPass - If deleteFn is true, this pass deletes the specified global values...
Definition: ExtractGV.cpp:161
Externally visible function.
Definition: GlobalValue.h:48
F(f)
void setModuleInlineAsm(StringRef Asm)
Set the module-scope inline assembly blocks.
Definition: Module.h:296
global_iterator global_begin()
Definition: Module.h:592
Class to represent function types.
Definition: DerivedTypes.h:108
LinkageTypes getLinkage() const
Definition: GlobalValue.h:461
bool hasLinkOnceLinkage() const
Definition: GlobalValue.h:435
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:210
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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:369
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
global_iterator global_end()
Definition: Module.h:594
Iterator for intrusive lists based on ilist_node.
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:50
Module.h This file contains the declarations for the Module class.
static void makeVisible(GlobalValue &GV, bool Delete)
Make sure GV is visible from both modules.
Definition: ExtractGV.cpp:25
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:454
#define I(x, y, z)
Definition: MD5.cpp:59
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:224
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:74
A vector that has set insertion semantics.
Definition: SetVector.h:40