LLVM 22.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
23
25#include "llvm/IR/Constants.h"
26#include "llvm/IR/DebugInfo.h"
30#include "llvm/IR/Metadata.h"
31#include "llvm/IR/Module.h"
32#include "llvm/IR/PassManager.h"
33#include "llvm/IR/TypeFinder.h"
38
39using namespace llvm;
40
41static cl::opt<bool>
42 StripGlobalConstants("strip-global-constants", cl::init(false), cl::Hidden,
43 cl::desc("Removes debug compile units which reference "
44 "to non-existing global constants"));
45
46/// OnlyUsedBy - Return true if V is only used by Usr.
47static bool OnlyUsedBy(Value *V, Value *Usr) {
48 for (User *U : V->users())
49 if (U != Usr)
50 return false;
51
52 return true;
53}
54
56 assert(C->use_empty() && "Constant is not dead!");
58 for (Value *Op : C->operands())
59 if (OnlyUsedBy(Op, C))
60 Operands.insert(cast<Constant>(Op));
61 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
62 if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
63 GV->eraseFromParent();
64 } else if (!isa<Function>(C)) {
65 // FIXME: Why does the type of the constant matter here?
66 if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType()) ||
67 isa<VectorType>(C->getType()))
68 C->destroyConstant();
69 }
70
71 // If the constant referenced anything, see if we can delete it as well.
72 for (Constant *O : Operands)
74}
75
76// Strip the symbol table of its names.
77//
78static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
79 for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
80 Value *V = VI->getValue();
81 ++VI;
82 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage()) {
83 if (!PreserveDbgInfo || !V->getName().starts_with("llvm.dbg"))
84 // Set name to "", removing from symbol table!
85 V->setName("");
86 }
87 }
88}
89
90// Strip any named types of their names.
91static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
92 TypeFinder StructTypes;
93 StructTypes.run(M, false);
94
95 for (StructType *STy : StructTypes) {
96 if (STy->isLiteral() || STy->getName().empty()) continue;
97
98 if (PreserveDbgInfo && STy->getName().starts_with("llvm.dbg"))
99 continue;
100
101 STy->setName("");
102 }
103}
104
105/// Find values that are marked as llvm.used.
106static void findUsedValues(GlobalVariable *LLVMUsed,
108 if (!LLVMUsed) return;
109 UsedValues.insert(LLVMUsed);
110
111 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
112
113 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
114 if (GlobalValue *GV =
115 dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
116 UsedValues.insert(GV);
117}
118
119/// StripSymbolNames - Strip symbol names.
120static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
121
123 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
124 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
125
126 for (GlobalVariable &GV : M.globals()) {
127 if (GV.hasLocalLinkage() && !llvmUsedValues.contains(&GV))
128 if (!PreserveDbgInfo || !GV.getName().starts_with("llvm.dbg"))
129 GV.setName(""); // Internal symbols can't participate in linkage
130 }
131
132 for (Function &I : M) {
133 if (I.hasLocalLinkage() && !llvmUsedValues.contains(&I))
134 if (!PreserveDbgInfo || !I.getName().starts_with("llvm.dbg"))
135 I.setName(""); // Internal symbols can't participate in linkage
136 if (auto *Symtab = I.getValueSymbolTable())
137 StripSymtab(*Symtab, PreserveDbgInfo);
138 }
139
140 // Remove all names from types.
141 StripTypeNames(M, PreserveDbgInfo);
142
143 return true;
144}
145
147 Function *Declare =
148 Intrinsic::getDeclarationIfExists(&M, Intrinsic::dbg_declare);
149 std::vector<Constant*> DeadConstants;
150
151 if (Declare) {
152 while (!Declare->use_empty()) {
153 CallInst *CI = cast<CallInst>(Declare->user_back());
154 Value *Arg1 = CI->getArgOperand(0);
155 Value *Arg2 = CI->getArgOperand(1);
156 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
157 CI->eraseFromParent();
158 if (Arg1->use_empty()) {
159 if (Constant *C = dyn_cast<Constant>(Arg1))
160 DeadConstants.push_back(C);
161 else
163 }
164 if (Arg2->use_empty())
165 if (Constant *C = dyn_cast<Constant>(Arg2))
166 DeadConstants.push_back(C);
167 }
168 Declare->eraseFromParent();
169 }
170
171 while (!DeadConstants.empty()) {
172 Constant *C = DeadConstants.back();
173 DeadConstants.pop_back();
174 if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
175 if (GV->hasLocalLinkage())
177 } else
179 }
180
181 return true;
182}
183
185 bool Changed = false;
186
187 LLVMContext &C = M.getContext();
188
189 // Find all debug info in F. This is actually overkill in terms of what we
190 // want to do, but we want to try and be as resilient as possible in the face
191 // of potential debug info changes by using the formal interfaces given to us
192 // as much as possible.
194 F.processModule(M);
195
196 // For each compile unit, find the live set of global variables/functions and
197 // replace the current list of potentially dead global variables/functions
198 // with the live list.
199 SmallVector<Metadata *, 64> LiveGlobalVariables;
201
202 std::set<DIGlobalVariableExpression *> LiveGVs;
203 for (GlobalVariable &GV : M.globals()) {
205 GV.getDebugInfo(GVEs);
206 for (auto *GVE : GVEs)
207 LiveGVs.insert(GVE);
208 }
209
210 std::set<DICompileUnit *> LiveCUs;
211 DebugInfoFinder LiveCUFinder;
212 for (const Function &F : M.functions()) {
213 if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
214 LiveCUFinder.processSubprogram(SP);
215 for (const Instruction &I : instructions(F))
216 LiveCUFinder.processInstruction(M, I);
217 }
218 auto FoundCUs = LiveCUFinder.compile_units();
219 LiveCUs.insert(FoundCUs.begin(), FoundCUs.end());
220
221 bool HasDeadCUs = false;
222 for (DICompileUnit *DIC : F.compile_units()) {
223 // Create our live global variable list.
224 bool GlobalVariableChange = false;
225 for (auto *DIG : DIC->getGlobalVariables()) {
226 if (DIG->getExpression() && DIG->getExpression()->isConstant() &&
228 LiveGVs.insert(DIG);
229
230 // Make sure we only visit each global variable only once.
231 if (!VisitedSet.insert(DIG).second)
232 continue;
233
234 // If a global variable references DIG, the global variable is live.
235 if (LiveGVs.count(DIG))
236 LiveGlobalVariables.push_back(DIG);
237 else
238 GlobalVariableChange = true;
239 }
240
241 if (!LiveGlobalVariables.empty())
242 LiveCUs.insert(DIC);
243 else if (!LiveCUs.count(DIC))
244 HasDeadCUs = true;
245
246 // If we found dead global variables, replace the current global
247 // variable list with our new live global variable list.
248 if (GlobalVariableChange) {
249 DIC->replaceGlobalVariables(MDTuple::get(C, LiveGlobalVariables));
250 Changed = true;
251 }
252
253 // Reset lists for the next iteration.
254 LiveGlobalVariables.clear();
255 }
256
257 if (HasDeadCUs) {
258 // Delete the old node and replace it with a new one
259 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
260 NMD->clearOperands();
261 if (!LiveCUs.empty()) {
262 for (DICompileUnit *CU : LiveCUs)
263 NMD->addOperand(CU);
264 }
265 Changed = true;
266 }
267
268 return Changed;
269}
270
273 StripSymbolNames(M, false);
276 return PA;
277}
278
281 StripSymbolNames(M, true);
284 return PA;
285}
286
292 return PA;
293}
294
300 return PA;
301}
302
305 auto *CGProf = dyn_cast_or_null<MDTuple>(M.getModuleFlag("CG Profile"));
306 if (!CGProf)
307 return PreservedAnalyses::all();
308
309 SmallVector<Metadata *, 16> ValidCGEdges;
310 for (Metadata *Edge : CGProf->operands()) {
311 if (auto *EdgeAsNode = dyn_cast_or_null<MDNode>(Edge))
312 if (!llvm::is_contained(EdgeAsNode->operands(), nullptr))
313 ValidCGEdges.push_back(Edge);
314 }
315 M.setModuleFlag(Module::Append, "CG Profile",
316 MDTuple::getDistinct(M.getContext(), ValidCGEdges));
318}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
mir Rename Register Operands
This file contains the declarations for metadata subclasses.
std::pair< BasicBlock *, BasicBlock * > Edge
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 cl::opt< bool > StripGlobalConstants("strip-global-constants", cl::init(false), cl::Hidden, cl::desc("Removes debug compile units which reference " "to non-existing global constants"))
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:255
Represents analyses that only rely on functions' control flow.
Definition: Analysis.h:73
Value * getArgOperand(unsigned i) const
Definition: InstrTypes.h:1292
This class represents a function call, abstracting a target machine's calling convention.
ConstantArray - Constant Array Declarations.
Definition: Constants.h:433
This is an important base class in LLVM.
Definition: Constant.h:43
This class represents an Operation in the Expression.
Utility to find all debug info in a module.
Definition: DebugInfo.h:103
LLVM_ABI void processInstruction(const Module &M, const Instruction &I)
Process a single instruction and collect debug info anchors.
Definition: DebugInfo.cpp:200
LLVM_ABI void processSubprogram(DISubprogram *SP)
Process subprogram.
Definition: DebugInfo.cpp:287
iterator_range< compile_unit_iterator > compile_units() const
Definition: DebugInfo.h:143
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition: Function.cpp:448
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Return a distinct node.
Definition: Metadata.h:1533
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1522
Root of the metadata hierarchy.
Definition: Metadata.h:63
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
@ Append
Appends the two values, which are required to be metadata nodes.
Definition: Module.h:141
A tuple of MDNodes.
Definition: Metadata.h:1753
LLVM_ABI void clearOperands()
Drop all references to this node's operands.
Definition: Metadata.cpp:1480
LLVM_ABI void addOperand(MDNode *M)
Definition: Metadata.cpp:1471
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition: Analysis.h:151
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
Definition: SmallPtrSet.h:380
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:401
bool contains(ConstPtrType Ptr) const
Definition: SmallPtrSet.h:476
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
bool empty() const
Definition: SmallVector.h:82
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:806
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
Class to represent struct types.
Definition: DerivedTypes.h:218
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:232
unsigned getNumOperands() const
Definition: User.h:254
This class provides a symbol table of name/value pairs.
LLVM Value Representation.
Definition: Value.h:75
User * user_back()
Definition: Value.h:412
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition: Value.cpp:701
bool use_empty() const
Definition: Value.h:346
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
Definition: Intrinsics.cpp:762
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI 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:533
LLVM_ABI bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
Definition: DebugInfo.cpp:565
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1916
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)