LLVM 24.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#include "IPOOptions.h"
24
27#include "llvm/IR/Constants.h"
28#include "llvm/IR/DebugInfo.h"
32#include "llvm/IR/Metadata.h"
33#include "llvm/IR/Module.h"
34#include "llvm/IR/PassManager.h"
35#include "llvm/IR/TypeFinder.h"
39
40using namespace llvm;
41
42/// OnlyUsedBy - Return true if V is only used by Usr.
43static bool OnlyUsedBy(Value *V, Value *Usr) {
44 for (User *U : V->users())
45 if (U != Usr)
46 return false;
47
48 return true;
49}
50
52 assert(C->use_empty() && "Constant is not dead!");
54 for (Value *Op : C->operands())
55 if (OnlyUsedBy(Op, C))
56 Operands.insert(cast<Constant>(Op));
58 if (!GV->hasLocalLinkage()) return; // Don't delete non-static globals.
59 GV->eraseFromParent();
60 } else if (!isa<Function>(C)) {
61 // FIXME: Why does the type of the constant matter here?
62 if (isa<StructType>(C->getType()) || isa<ArrayType>(C->getType()) ||
63 isa<VectorType>(C->getType()))
64 C->destroyConstant();
65 }
66
67 // If the constant referenced anything, see if we can delete it as well.
68 for (Constant *O : Operands)
70}
71
72// Strip the symbol table of its names.
73//
74static void StripSymtab(ValueSymbolTable &ST, bool PreserveDbgInfo) {
75 // Collect the values to rename first: setName("") removes the value from the
76 // symbol table, which invalidates iterators into it.
78 for (const ValueName &VN : ST) {
79 Value *V = VN.getValue();
80 if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasLocalLinkage())
81 if (!PreserveDbgInfo || !V->getName().starts_with("llvm.dbg"))
82 ToStrip.push_back(V);
83 }
84 for (Value *V : ToStrip)
85 V->setName("");
86}
87
88// Strip any named types of their names.
89static void StripTypeNames(Module &M, bool PreserveDbgInfo) {
90 TypeFinder StructTypes;
91 StructTypes.run(M, false);
92
93 for (StructType *STy : StructTypes) {
94 if (STy->isLiteral() || STy->getName().empty()) continue;
95
96 if (PreserveDbgInfo && STy->getName().starts_with("llvm.dbg"))
97 continue;
98
99 STy->setName("");
100 }
101}
102
103/// Find values that are marked as llvm.used.
104static void findUsedValues(GlobalVariable *LLVMUsed,
106 if (!LLVMUsed) return;
107 UsedValues.insert(LLVMUsed);
108
109 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
110
111 for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
112 if (GlobalValue *GV =
114 UsedValues.insert(GV);
115}
116
117/// StripSymbolNames - Strip symbol names.
118static bool StripSymbolNames(Module &M, bool PreserveDbgInfo) {
119
121 findUsedValues(M.getGlobalVariable("llvm.used"), llvmUsedValues);
122 findUsedValues(M.getGlobalVariable("llvm.compiler.used"), llvmUsedValues);
123
124 for (GlobalVariable &GV : M.globals()) {
125 if (GV.hasLocalLinkage() && !llvmUsedValues.contains(&GV))
126 if (!PreserveDbgInfo || !GV.getName().starts_with("llvm.dbg"))
127 GV.setName(""); // Internal symbols can't participate in linkage
128 }
129
130 for (Function &I : M) {
131 if (I.hasLocalLinkage() && !llvmUsedValues.contains(&I))
132 if (!PreserveDbgInfo || !I.getName().starts_with("llvm.dbg"))
133 I.setName(""); // Internal symbols can't participate in linkage
134 if (auto *Symtab = I.getValueSymbolTable())
135 StripSymtab(*Symtab, PreserveDbgInfo);
136 }
137
138 // Remove all names from types.
139 StripTypeNames(M, PreserveDbgInfo);
140
141 return true;
142}
143
145 Function *Declare =
146 Intrinsic::getDeclarationIfExists(&M, Intrinsic::dbg_declare);
147 std::vector<Constant*> DeadConstants;
148
149 if (Declare) {
150 while (!Declare->use_empty()) {
151 CallInst *CI = cast<CallInst>(Declare->user_back());
152 Value *Arg1 = CI->getArgOperand(0);
153 Value *Arg2 = CI->getArgOperand(1);
154 assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
155 CI->eraseFromParent();
156 if (Arg1->use_empty()) {
157 if (Constant *C = dyn_cast<Constant>(Arg1))
158 DeadConstants.push_back(C);
159 else
161 }
162 if (Arg2->use_empty())
163 if (Constant *C = dyn_cast<Constant>(Arg2))
164 DeadConstants.push_back(C);
165 }
166 Declare->eraseFromParent();
167 }
168
169 while (!DeadConstants.empty()) {
170 Constant *C = DeadConstants.back();
171 DeadConstants.pop_back();
173 if (GV->hasLocalLinkage())
175 } else
177 }
178
179 return true;
180}
181
183 const IPOOptions &Opts = getIPOOptions(M);
184 bool Changed = false;
185
186 LLVMContext &C = M.getContext();
187
188 // Find all debug info in F. This is actually overkill in terms of what we
189 // want to do, but we want to try and be as resilient as possible in the face
190 // of potential debug info changes by using the formal interfaces given to us
191 // as much as possible.
193 F.processModule(M);
194
195 // For each compile unit, find the live set of global variables/functions and
196 // replace the current list of potentially dead global variables/functions
197 // with the live list.
198 SmallVector<Metadata *, 64> LiveGlobalVariables;
200
201 std::set<DIGlobalVariableExpression *> LiveGVs;
202 for (GlobalVariable &GV : M.globals()) {
204 GV.getDebugInfo(GVEs);
205 for (auto *GVE : GVEs)
206 LiveGVs.insert(GVE);
207 }
208
209 std::set<DICompileUnit *> LiveCUs;
210 DebugInfoFinder LiveCUFinder;
211 for (const Function &F : M.functions()) {
212 if (auto *SP = cast_or_null<DISubprogram>(F.getSubprogram()))
213 LiveCUFinder.processSubprogram(SP);
214 for (const Instruction &I : instructions(F))
215 LiveCUFinder.processInstruction(M, I);
216 }
217 auto FoundCUs = LiveCUFinder.compile_units();
218 LiveCUs.insert(FoundCUs.begin(), FoundCUs.end());
219
220 bool HasDeadCUs = false;
221 for (DICompileUnit *DIC : F.compile_units()) {
222 // Create our live global variable list.
223 bool GlobalVariableChange = false;
224 for (auto *DIG : DIC->getGlobalVariables()) {
225 if (DIG->getExpression() && DIG->getExpression()->isConstant() &&
226 !Opts.strip_global_constants)
227 LiveGVs.insert(DIG);
228
229 // Make sure we only visit each global variable only once.
230 if (!VisitedSet.insert(DIG).second)
231 continue;
232
233 // If a global variable references DIG, the global variable is live.
234 if (LiveGVs.count(DIG))
235 LiveGlobalVariables.push_back(DIG);
236 else
237 GlobalVariableChange = true;
238 }
239
240 if (!LiveGlobalVariables.empty())
241 LiveCUs.insert(DIC);
242 else if (!LiveCUs.count(DIC))
243 HasDeadCUs = true;
244
245 // If we found dead global variables, replace the current global
246 // variable list with our new live global variable list.
247 if (GlobalVariableChange) {
248 DIC->replaceGlobalVariables(MDTuple::get(C, LiveGlobalVariables));
249 Changed = true;
250 }
251
252 // Reset lists for the next iteration.
253 LiveGlobalVariables.clear();
254 }
255
256 if (HasDeadCUs) {
257 // Delete the old node and replace it with a new one
258 NamedMDNode *NMD = M.getOrInsertNamedMetadata("llvm.dbg.cu");
259 NMD->clearOperands();
260 if (!LiveCUs.empty()) {
261 for (DICompileUnit *CU : LiveCUs)
262 NMD->addOperand(CU);
263 }
264 Changed = true;
265 }
266
267 return Changed;
268}
269
277
285
293
301
304 auto *CGProf = dyn_cast_or_null<MDTuple>(M.getModuleFlag("CG Profile"));
305 if (!CGProf)
306 return PreservedAnalyses::all();
307
308 SmallVector<Metadata *, 16> ValidCGEdges;
309 for (Metadata *Edge : CGProf->operands()) {
310 if (auto *EdgeAsNode = dyn_cast_or_null<MDNode>(Edge))
311 if (!llvm::is_contained(EdgeAsNode->operands(), nullptr))
312 ValidCGEdges.push_back(Edge);
313 }
314 M.setModuleFlag(Module::Append, "CG Profile",
315 MDTuple::getDistinct(M.getContext(), ValidCGEdges));
317}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Expand Atomic instructions
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
SI Fold Operands
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 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:590
This is an important base class in LLVM.
Definition Constant.h:44
Utility to find all debug info in a module.
Definition DebugInfo.h:102
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:148
Implements a dense probed hash-table based set.
Definition DenseSet.h:283
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Function.cpp:451
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:76
static MDTuple * getDistinct(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Return a distinct node.
Definition Metadata.h:1536
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1525
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:68
@ Append
Appends the two values, which are required to be metadata nodes.
Definition Module.h:142
A tuple of MDNodes.
Definition Metadata.h:1797
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
LLVM_ABI 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
User * user_back()
Definition Value.h:414
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:707
bool use_empty() const
Definition Value.h:348
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:210
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.
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:522
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
const IPOOptions & getIPOOptions(const LLVMContext &C)
Definition IPOOptions.h:33
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:1963
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)