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));
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 =
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();
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
278
286
294
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.
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)
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:433
This is an important base class in LLVM.
Definition Constant.h:43
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.
LLVM_ABI void processSubprogram(DISubprogram *SP)
Process subprogram.
iterator_range< compile_unit_iterator > compile_units() const
Definition DebugInfo.h:143
Implements a dense probed hash-table based set.
Definition DenseSet.h:261
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Function.cpp:448
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.
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:232
unsigned getNumOperands() const
Definition User.h:254
This class provides a symbol table of name/value pairs.
ValueMap::iterator iterator
An iterator over a ValueMap.
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:701
bool use_empty() const
Definition Value.h:346
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:194
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.
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
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
auto cast_or_null(const Y &Val)
Definition Casting.h:720
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:759
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:548
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:565
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1899
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)