LLVM 17.0.0git
StripSymbols.cpp
Go to the documentation of this file.
1//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
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// The StripSymbols transformation implements code stripping. Specifically, it
10// can delete:
11//
12// * names for virtual registers
13// * symbols for internal globals and functions
14// * debug information
15//
16// Note that this transformation makes code much less readable, so it should
17// only be used in situations where the 'strip' utility would be used, such as
18// reducing code size or making it harder to reverse engineer code.
19//
20//===----------------------------------------------------------------------===//
21
24#include "llvm/IR/Constants.h"
25#include "llvm/IR/DebugInfo.h"
29#include "llvm/IR/Module.h"
30#include "llvm/IR/PassManager.h"
31#include "llvm/IR/TypeFinder.h"
33#include "llvm/Transforms/IPO.h"
36
37using namespace llvm;
38
39/// OnlyUsedBy - Return true if V is only used by Usr.
40static bool OnlyUsedBy(Value *V, Value *Usr) {
41 for (User *U : V->users())
42 if (U != Usr)
43 return false;
44
45 return true;
46}
47
49 assert(C->use_empty() && "Constant is not dead!");
51 for (Value *Op : C->operands())
52 if (OnlyUsedBy(Op, C))
53 Operands.insert(cast<Constant>(Op));
54 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
55 if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
56 GV->eraseFromParent();
57 } else if (!isa<Function>(C)) {
58 // FIXME: Why does the type of the constant matter here?
59 if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType()) ||
60 isa<VectorType>(C->getType()))
61 C->destroyConstant();
62 }
63
64 // If the constant referenced anything, see if we can delete it as well.
65 for (Constant *O : Operands)
67}
68
69// Strip the symbol table of its names.
70//
71static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
72 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
73 Value *V = VI->getValue();
74 ++VI;
75 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
76 if (!PreserveDbgInfo || !V->getName().startswith("llvm.dbg"))
77 // Set name to "", removing from symbol table!
78 V->setName("");
79 }
80 }
81}
82
83// Strip any named types of their names.
84static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
85 TypeFinder StructTypes;
86 StructTypes.run(M, false);
87
88 for (StructType *STy : StructTypes) {
89 if (STy->isLiteral() || STy->getName().empty()) continue;
90
91 if (PreserveDbgInfo && STy->getName().startswith("llvm.dbg"))
92 continue;
93
94 STy->setName("");
95 }
96}
97
98/// Find values that are marked as llvm.used.
99static void findUsedValues(GlobalVariable *LLVMUsed,
101 if (!LLVMUsed) return;
102 UsedValues.insert(LLVMUsed);
103
104 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
105
106 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
107 if (GlobalValue *GV =
108 dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
109 UsedValues.insert(GV);
110}
111
112/// StripSymbolNames - Strip symbol names.
113static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
114
116 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
117 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
118
119 for (GlobalVariable &GV : M.globals()) {
120 if (GV.hasLocalLinkage() && !llvmUsedValues.contains(&GV))
121 if (!PreserveDbgInfo || !GV.getName().startswith("llvm.dbg"))
122 GV.setName(""); // Internal symbols can't participate in linkage
123 }
124
125 for (Function &I : M) {
126 if (I.hasLocalLinkage() && !llvmUsedValues.contains(&I))
127 if (!PreserveDbgInfo || !I.getName().startswith("llvm.dbg"))
128 I.setName(""); // Internal symbols can't participate in linkage
129 if (auto *Symtab = I.getValueSymbolTable())
130 StripSymtab(*Symtab, PreserveDbgInfo);
131 }
132
133 // Remove all names from types.
134 StripTypeNames(M, PreserveDbgInfo);
135
136 return true;
137}
138
140
141 Function *Declare = M.getFunction("llvm.dbg.declare");
142 std::vector<Constant*> DeadConstants;
143
144 if (Declare) {
145 while (!Declare->use_empty()) {
146 CallInst *CI = cast<CallInst>(Declare->user_back());
147 Value *Arg1 = CI->getArgOperand(0);
148 Value *Arg2 = CI->getArgOperand(1);
149 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
150 CI->eraseFromParent();
151 if (Arg1->use_empty()) {
152 if (Constant *C = dyn_cast<Constant>(Arg1))
153 DeadConstants.push_back(C);
154 else
156 }
157 if (Arg2->use_empty())
158 if (Constant *C = dyn_cast<Constant>(Arg2))
159 DeadConstants.push_back(C);
160 }
161 Declare->eraseFromParent();
162 }
163
164 while (!DeadConstants.empty()) {
165 Constant *C = DeadConstants.back();
166 DeadConstants.pop_back();
167 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
168 if (GV->hasLocalLinkage())
170 } else
172 }
173
174 return true;
175}
176
178 bool Changed = false;
179
180 LLVMContext &C = M.getContext();
181
182 // Find all debug info in F. This is actually overkill in terms of what we
183 // want to do, but we want to try and be as resilient as possible in the face
184 // of potential debug info changes by using the formal interfaces given to us
185 // as much as possible.
187 F.processModule(M);
188
189 // For each compile unit, find the live set of global variables/functions and
190 // replace the current list of potentially dead global variables/functions
191 // with the live list.
192 SmallVector<Metadata *, 64> LiveGlobalVariables;
194
195 std::set<DIGlobalVariableExpression *> LiveGVs;
196 for (GlobalVariable &GV : M.globals()) {
198 GV.getDebugInfo(GVEs);
199 for (auto *GVE : GVEs)
200 LiveGVs.insert(GVE);
201 }
202
203 std::set<DICompileUnit *> LiveCUs;
204 DebugInfoFinder LiveCUFinder;
205 for (const Function &F : M.functions()) {
206 if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
207 LiveCUFinder.processSubprogram(SP);
208 for (const Instruction &I : instructions(F))
209 LiveCUFinder.processInstruction(M, I);
210 }
211 auto FoundCUs = LiveCUFinder.compile_units();
212 LiveCUs.insert(FoundCUs.begin(), FoundCUs.end());
213
214 bool HasDeadCUs = false;
215 for (DICompileUnit *DIC : F.compile_units()) {
216 // Create our live global variable list.
217 bool GlobalVariableChange = false;
218 for (auto *DIG : DIC->getGlobalVariables()) {
219 if (DIG->getExpression() && DIG->getExpression()->isConstant())
220 LiveGVs.insert(DIG);
221
222 // Make sure we only visit each global variable only once.
223 if (!VisitedSet.insert(DIG).second)
224 continue;
225
226 // If a global variable references DIG, the global variable is live.
227 if (LiveGVs.count(DIG))
228 LiveGlobalVariables.push_back(DIG);
229 else
230 GlobalVariableChange = true;
231 }
232
233 if (!LiveGlobalVariables.empty())
234 LiveCUs.insert(DIC);
235 else if (!LiveCUs.count(DIC))
236 HasDeadCUs = true;
237
238 // If we found dead global variables, replace the current global
239 // variable list with our new live global variable list.
240 if (GlobalVariableChange) {
241 DIC->replaceGlobalVariables(MDTuple::get(C, LiveGlobalVariables));
242 Changed = true;
243 }
244
245 // Reset lists for the next iteration.
246 LiveGlobalVariables.clear();
247 }
248
249 if (HasDeadCUs) {
250 // Delete the old node and replace it with a new one
251 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
252 NMD->clearOperands();
253 if (!LiveCUs.empty()) {
254 for (DICompileUnit *CU : LiveCUs)
255 NMD->addOperand(CU);
256 }
257 Changed = true;
258 }
259
260 return Changed;
261}
262
265 StripSymbolNames(M, false);
268 return PA;
269}
270
273 StripSymbolNames(M, true);
276 return PA;
277}
278
284 return PA;
285}
286
292 return PA;
293}
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
Module.h This file contains the declarations for the Module class.
print must be executed print the must be executed context for all instructions
This header defines various interfaces for pass management in LLVM.
@ VI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
static bool stripDeadDebugInfoImpl(Module &M)
static bool stripDebugDeclareImpl(Module &M)
static bool OnlyUsedBy(Value *V, Value *Usr)
OnlyUsedBy - Return true if V is only used by Usr.
static void findUsedValues(GlobalVariable *LLVMUsed, SmallPtrSetImpl< const GlobalValue * > &UsedValues)
Find values that are marked as llvm.used.
static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo)
static void StripTypeNames(Module &M, bool PreserveDbgInfo)
static bool StripSymbolNames(Module &M, bool PreserveDbgInfo)
StripSymbolNames - Strip symbol names.
static void RemoveDeadConstant(Constant *C)
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:620
Represents analyses that only rely on functions' control flow.
Definition: PassManager.h:113
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1357
This class represents a function call, abstracting a target machine's calling convention.
ConstantArray - Constant Array Declarations.
Definition: Constants.h:408
This is an important base class in LLVM.
Definition: Constant.h:41
Utility to find all debug info in a module.
Definition: DebugInfo.h:93
void processInstruction(const Module &M, const Instruction &I)
Process a single instruction and collect debug info anchors.
Definition: DebugInfo.cpp:183
void processSubprogram(DISubprogram *SP)
Process subprogram.
Definition: DebugInfo.cpp:249
iterator_range< compile_unit_iterator > compile_units() const
Definition: DebugInfo.h:130
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Function.cpp:366
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Definition: Instruction.cpp:82
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:67
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1373
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A tuple of MDNodes.
Definition: Metadata.h:1604
void clearOperands()
Drop all references to this node's operands.
Definition: Metadata.cpp:1296
void addOperand(MDNode *M)
Definition: Metadata.cpp:1287
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
void preserveSet()
Mark an analysis set as preserved.
Definition: PassManager.h:188
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:344
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:365
bool contains(ConstPtrType Ptr) const
Definition: SmallPtrSet.h:389
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:450
bool empty() const
Definition: SmallVector.h:94
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:809
void push_back(const T &Elt)
Definition: SmallVector.h:416
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
Class to represent struct types.
Definition: DerivedTypes.h:213
TypeFinder - Walk over a module, identifying all of the types that are used by the module.
Definition: TypeFinder.h:31
void run(const Module &M, bool onlyNamed)
Definition: TypeFinder.cpp:34
Value * getOperand(unsigned i) const
Definition: User.h:169
unsigned getNumOperands() const
Definition: User.h:191
This class provides a symbol table of name/value pairs.
LLVM Value Representation.
Definition: Value.h:74
User * user_back()
Definition: Value.h:407
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:688
bool use_empty() const
Definition: Value.h:344
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
void push_back(pointer val)
Definition: ilist.h:250
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition: Local.cpp:529
bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Definition: DebugInfo.cpp:533
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)