LLVM  16.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/Module.h"
15 #include "llvm/Pass.h"
16 #include "llvm/Transforms/IPO.h"
17 #include <algorithm>
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) {
28  if (Local)
30  return;
31  }
32 
33  if (!GV.hasLinkOnceLinkage()) {
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");
44  return;
47  return;
48  }
49 }
50 
51 namespace {
52  /// A pass to extract specific global values and their dependencies.
53  class GVExtractorPass : public ModulePass {
55  bool deleteStuff;
56  bool keepConstInit;
57  public:
58  static char ID; // Pass identification, replacement for typeid
59 
60  /// If deleteS is true, this pass deletes the specified global values.
61  /// Otherwise, it deletes as much of the module as possible, except for the
62  /// global values specified.
63  explicit GVExtractorPass(std::vector<GlobalValue*> &GVs,
64  bool deleteS = true, bool keepConstInit = false)
65  : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS),
66  keepConstInit(keepConstInit) {}
67 
68  bool runOnModule(Module &M) override {
69  if (skipModule(M))
70  return false;
71 
72  // Visit the global inline asm.
73  if (!deleteStuff)
74  M.setModuleInlineAsm("");
75 
76  // For simplicity, just give all GlobalValues ExternalLinkage. A trickier
77  // implementation could figure out which GlobalValues are actually
78  // referenced by the Named set, and which GlobalValues in the rest of
79  // the module are referenced by the NamedSet, and get away with leaving
80  // more internal and private things internal and private. But for now,
81  // be conservative and simple.
82 
83  // Visit the GlobalVariables.
84  for (GlobalVariable &GV : M.globals()) {
85  bool Delete = deleteStuff == (bool)Named.count(&GV) &&
86  !GV.isDeclaration() &&
87  (!GV.isConstant() || !keepConstInit);
88  if (!Delete) {
89  if (GV.hasAvailableExternallyLinkage())
90  continue;
91  if (GV.getName() == "llvm.global_ctors")
92  continue;
93  }
94 
95  makeVisible(GV, Delete);
96 
97  if (Delete) {
98  // Make this a declaration and drop it's comdat.
99  GV.setInitializer(nullptr);
100  GV.setComdat(nullptr);
101  }
102  }
103 
104  // Visit the Functions.
105  for (Function &F : M) {
106  bool Delete =
107  deleteStuff == (bool)Named.count(&F) && !F.isDeclaration();
108  if (!Delete) {
109  if (F.hasAvailableExternallyLinkage())
110  continue;
111  }
112 
113  makeVisible(F, Delete);
114 
115  if (Delete) {
116  // Make this a declaration and drop it's comdat.
117  F.deleteBody();
118  F.setComdat(nullptr);
119  }
120  }
121 
122  // Visit the Aliases.
123  for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) {
124  bool Delete = deleteStuff == (bool)Named.count(&GA);
125  makeVisible(GA, Delete);
126 
127  if (Delete) {
128  Type *Ty = GA.getValueType();
129 
130  GA.removeFromParent();
131  llvm::Value *Declaration;
132  if (FunctionType *FTy = dyn_cast<FunctionType>(Ty)) {
133  Declaration =
135  GA.getAddressSpace(), GA.getName(), &M);
136 
137  } else {
138  Declaration =
140  nullptr, GA.getName());
141  }
142  GA.replaceAllUsesWith(Declaration);
143  delete &GA;
144  }
145  }
146 
147  return true;
148  }
149  };
150 
151  char GVExtractorPass::ID = 0;
152 }
153 
154 ModulePass *llvm::createGVExtractionPass(std::vector<GlobalValue *> &GVs,
155  bool deleteFn, bool keepConstInit) {
156  return new GVExtractorPass(GVs, deleteFn, keepConstInit);
157 }
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::AArch64PACKey::ID
ID
Definition: AArch64BaseInfo.h:818
llvm::GlobalValue::LinkOnceAnyLinkage
@ LinkOnceAnyLinkage
Keep one copy of function when linking (inline)
Definition: GlobalValue.h:50
llvm::ModulePass
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
Definition: Pass.h:248
llvm::GlobalValue::getLinkage
LinkageTypes getLinkage() const
Definition: GlobalValue.h:539
llvm::GlobalValue::HiddenVisibility
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:64
llvm::Function
Definition: Function.h:60
Pass.h
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::GlobalAlias
Definition: GlobalAlias.h:28
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:235
llvm::sys::path::begin
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:226
llvm::ms_demangle::IntrinsicFunctionKind::Delete
@ Delete
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::GlobalValue
Definition: GlobalValue.h:44
IPO.h
llvm::GlobalValue::WeakAnyLinkage
@ WeakAnyLinkage
Keep one copy of named function when linking (weak)
Definition: GlobalValue.h:52
llvm::make_early_inc_range
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:716
llvm::GlobalValue::setLinkage
void setLinkage(LinkageTypes LT)
Definition: GlobalValue.h:530
llvm::GlobalValue::isDiscardableIfUnused
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:442
llvm::Function::Create
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:137
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::GlobalValue::hasLocalLinkage
bool hasLocalLinkage() const
Definition: GlobalValue.h:521
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::GlobalValue::WeakODRLinkage
@ WeakODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:53
llvm::SetVector::count
size_type count(const key_type &key) const
Count the number of elements of a given key in the SetVector.
Definition: SetVector.h:215
makeVisible
static void makeVisible(GlobalValue &GV, bool Delete)
Make sure GV is visible from both modules.
Definition: ExtractGV.cpp:24
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::GlobalValue::hasLinkOnceLinkage
bool hasLinkOnceLinkage() const
Definition: GlobalValue.h:508
llvm::SetVector
A vector that has set insertion semantics.
Definition: SetVector.h:40
llvm::createGVExtractionPass
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:154
llvm::GlobalValue::LinkOnceODRLinkage
@ LinkOnceODRLinkage
Same, but only replaced by something equivalent.
Definition: GlobalValue.h:51
llvm::GlobalValue::setVisibility
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:248
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
SetVector.h
llvm::FunctionType
Class to represent function types.
Definition: DerivedTypes.h:103