LLVM 23.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
26#include "llvm/IR/Constants.h"
27#include "llvm/IR/DebugInfo.h"
31#include "llvm/IR/Metadata.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/PassManager.h"
34#include "llvm/IR/TypeFinder.h"
39
40using namespace llvm;
41
42static cl::opt<bool>
43 StripGlobalConstants("strip-global-constants", cl::init(false), cl::Hidden,
44 cl::desc("Removes debug compile units which reference "
45 "to non-existing global constants"));
46
47/// OnlyUsedBy - Return true if V is only used by Usr.
48static bool OnlyUsedBy(Value *V, Value *Usr) {
49 for (User *U : V->users())
50 if (U != Usr)
51 return false;
52
53 return true;
54}
55
57 assert(C->use_empty() && "Constant is not dead!");
59 for (Value *Op : C->operands())
60 if (OnlyUsedBy(Op, C))
61 Operands.insert(cast<Constant>(Op));
63 if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
64 GV->eraseFromParent();
65 } else if (!isa<Function>(C)) {
66 // FIXME: Why does the type of the constant matter here?
67 if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType()) ||
68 isa<VectorType>(C->getType()))
69 C->destroyConstant();
70 }
71
72 // If the constant referenced anything, see if we can delete it as well.
73 for (Constant *O : Operands)
75}
76
77// Strip the symbol table of its names.
78//
79static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
80 // Collect the values to rename first: setName("") removes the value from the
81 // symbol table, which invalidates iterators into it.
83 for (const ValueName &VN : ST) {
84 Value *V = VN.getValue();
85 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage())
86 if (!PreserveDbgInfo || !V->getName().starts_with("llvm.dbg"))
87 ToStrip.push_back(V);
88 }
89 for (Value *V : ToStrip)
90 V->setName("");
91}
92
93// Strip any named types of their names.
94static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
95 TypeFinder StructTypes;
96 StructTypes.run(M, false);
97
98 for (StructType *STy : StructTypes) {
99 if (STy->isLiteral() || STy->getName().empty()) continue;
100
101 if (PreserveDbgInfo && STy->getName().starts_with("llvm.dbg"))
102 continue;
103
104 STy->setName("");
105 }
106}
107
108/// Find values that are marked as llvm.used.
109static void findUsedValues(GlobalVariable *LLVMUsed,
111 if (!LLVMUsed) return;
112 UsedValues.insert(LLVMUsed);
113
114 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
115
116 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
117 if (GlobalValue *GV =
119 UsedValues.insert(GV);
120}
121
122/// StripSymbolNames - Strip symbol names.
123static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
124
126 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
127 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
128
129 for (GlobalVariable &GV : M.globals()) {
130 if (GV.hasLocalLinkage() && !llvmUsedValues.contains(&GV))
131 if (!PreserveDbgInfo || !GV.getName().starts_with("llvm.dbg"))
132 GV.setName(""); // Internal symbols can't participate in linkage
133 }
134
135 for (Function &I : M) {
136 if (I.hasLocalLinkage() && !llvmUsedValues.contains(&I))
137 if (!PreserveDbgInfo || !I.getName().starts_with("llvm.dbg"))
138 I.setName(""); // Internal symbols can't participate in linkage
139 if (auto *Symtab = I.getValueSymbolTable())
140 StripSymtab(*Symtab, PreserveDbgInfo);
141 }
142
143 // Remove all names from types.
144 StripTypeNames(M, PreserveDbgInfo);
145
146 return true;
147}
148
150 Function *Declare =
151 Intrinsic::getDeclarationIfExists(&M, Intrinsic::dbg_declare);
152 std::vector<Constant*> DeadConstants;
153
154 if (Declare) {
155 while (!Declare->use_empty()) {
156 CallInst *CI = cast<CallInst>(Declare->user_back());
157 Value *Arg1 = CI->getArgOperand(0);
158 Value *Arg2 = CI->getArgOperand(1);
159 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
160 CI->eraseFromParent();
161 if (Arg1->use_empty()) {
162 if (Constant *C = dyn_cast<Constant>(Arg1))
163 DeadConstants.push_back(C);
164 else
166 }
167 if (Arg2->use_empty())
168 if (Constant *C = dyn_cast<Constant>(Arg2))
169 DeadConstants.push_back(C);
170 }
171 Declare->eraseFromParent();
172 }
173
174 while (!DeadConstants.empty()) {
175 Constant *C = DeadConstants.back();
176 DeadConstants.pop_back();
178 if (GV->hasLocalLinkage())
180 } else
182 }
183
184 return true;
185}
186
188 bool Changed = false;
189
190 LLVMContext &C = M.getContext();
191
192 // Find all debug info in F. This is actually overkill in terms of what we
193 // want to do, but we want to try and be as resilient as possible in the face
194 // of potential debug info changes by using the formal interfaces given to us
195 // as much as possible.
197 F.processModule(M);
198
199 // For each compile unit, find the live set of global variables/functions and
200 // replace the current list of potentially dead global variables/functions
201 // with the live list.
202 SmallVector<Metadata *, 64> LiveGlobalVariables;
204
205 std::set<DIGlobalVariableExpression *> LiveGVs;
206 for (GlobalVariable &GV : M.globals()) {
208 GV.getDebugInfo(GVEs);
209 for (auto *GVE : GVEs)
210 LiveGVs.insert(GVE);
211 }
212
213 std::set<DICompileUnit *> LiveCUs;
214 DebugInfoFinder LiveCUFinder;
215 for (const Function &F : M.functions()) {
216 if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
217 LiveCUFinder.processSubprogram(SP);
218 for (const Instruction &I : instructions(F))
219 LiveCUFinder.processInstruction(M, I);
220 }
221 auto FoundCUs = LiveCUFinder.compile_units();
222 LiveCUs.insert(FoundCUs.begin(), FoundCUs.end());
223
224 bool HasDeadCUs = false;
225 for (DICompileUnit *DIC : F.compile_units()) {
226 // Create our live global variable list.
227 bool GlobalVariableChange = false;
228 for (auto *DIG : DIC->getGlobalVariables()) {
229 if (DIG->getExpression() && DIG->getExpression()->isConstant() &&
231 LiveGVs.insert(DIG);
232
233 // Make sure we only visit each global variable only once.
234 if (!VisitedSet.insert(DIG).second)
235 continue;
236
237 // If a global variable references DIG, the global variable is live.
238 if (LiveGVs.count(DIG))
239 LiveGlobalVariables.push_back(DIG);
240 else
241 GlobalVariableChange = true;
242 }
243
244 if (!LiveGlobalVariables.empty())
245 LiveCUs.insert(DIC);
246 else if (!LiveCUs.count(DIC))
247 HasDeadCUs = true;
248
249 // If we found dead global variables, replace the current global
250 // variable list with our new live global variable list.
251 if (GlobalVariableChange) {
252 DIC->replaceGlobalVariables(MDTuple::get(C, LiveGlobalVariables));
253 Changed = true;
254 }
255
256 // Reset lists for the next iteration.
257 LiveGlobalVariables.clear();
258 }
259
260 if (HasDeadCUs) {
261 // Delete the old node and replace it with a new one
262 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
263 NMD->clearOperands();
264 if (!LiveCUs.empty()) {
265 for (DICompileUnit *CU : LiveCUs)
266 NMD->addOperand(CU);
267 }
268 Changed = true;
269 }
270
271 return Changed;
272}
273
281
289
297
305
308 auto *CGProf = dyn_cast_or_null<MDTuple>(M.getModuleFlag("CG Profile"));
309 if (!CGProf)
310 return PreservedAnalyses::all();
311
312 SmallVector<Metadata *, 16> ValidCGEdges;
313 for (Metadata *Edge : CGProf->operands()) {
314 if (auto *EdgeAsNode = dyn_cast_or_null<MDNode>(Edge))
315 if (!llvm::is_contained(EdgeAsNode->operands(), nullptr))
316 ValidCGEdges.push_back(Edge);
317 }
318 M.setModuleFlag(Module::Append, "CG Profile",
319 MDTuple::getDistinct(M.getContext(), ValidCGEdges));
321}
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:54
#define I(x, y, z)
Definition MD5.cpp:57
This file contains the declarations for metadata subclasses.
This file defines the SmallPtrSet class.
This file defines the SmallVector 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)
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
ConstantArray - Constant Array Declarations.
Definition Constants.h:584
This is an important base class in LLVM.
Definition Constant.h:43
Utility to find all debug info in a module.
Definition DebugInfo.h:105
LLVM_ABI void processInstruction(const Module &M, const Instruction &I)
Process a single instruction and collect debug info anchors.
LLVM_ABI void processSubprogram(DISubprogram *SP)
Process subprogram.
iterator_range< compile_unit_iterator > compile_units() const
Definition DebugInfo.h:150
Implements a dense probed hash-table based set.
Definition DenseSet.h:289
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Function.cpp:445
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:1529
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1518
Root of the metadata hierarchy.
Definition Metadata.h:64
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:1749
LLVM_ABI void clearOperands()
Drop all references to this node's operands.
LLVM_ABI void addOperand(MDNode *M)
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...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Class to represent struct types.
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)
Value * getOperand(unsigned i) const
Definition User.h:207
unsigned getNumOperands() const
Definition User.h:229
This class provides a symbol table of name/value pairs.
LLVM Value Representation.
Definition Value.h:75
iterator_range< user_iterator > users()
Definition Value.h:426
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:712
bool use_empty() const
Definition Value.h:346
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:212
Changed
@ 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.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
StringMapEntry< Value * > ValueName
Definition Value.h:56
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:535
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto cast_or_null(const Y &Val)
Definition Casting.h:714
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool StripDebugInfo(Module &M)
Strip debug info in the module if it exists.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1946
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
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)