aaecc2f252692ca837e3df9253174edd6115348d
[oota-llvm.git] / lib / Transforms / IPO / StripSymbols.cpp
1 //===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements stripping symbols out of symbol tables.
11 //
12 // Specifically, this allows you to strip all of the symbols out of:
13 //   * All functions in a module
14 //   * All non-essential symbols in a module (all function symbols + all module
15 //     scope symbols)
16 //   * Debug information.
17 //
18 // Notice that:
19 //   * This pass makes code much less readable, so it should only be used in
20 //     situations where the 'strip' utility would be used (such as reducing
21 //     code size, and making it harder to reverse engineer code).
22 //
23 //===----------------------------------------------------------------------===//
24
25 #include "llvm/Transforms/IPO.h"
26 #include "llvm/Constants.h"
27 #include "llvm/DerivedTypes.h"
28 #include "llvm/Instructions.h"
29 #include "llvm/Module.h"
30 #include "llvm/Pass.h"
31 #include "llvm/ValueSymbolTable.h"
32 #include "llvm/TypeSymbolTable.h"
33 #include "llvm/Support/Compiler.h"
34 using namespace llvm;
35
36 namespace {
37   class VISIBILITY_HIDDEN StripSymbols : public ModulePass {
38     bool OnlyDebugInfo;
39   public:
40     static char ID; // Pass identification, replacement for typeid
41     explicit StripSymbols(bool ODI = false) 
42       : ModulePass((intptr_t)&ID), OnlyDebugInfo(ODI) {}
43
44     virtual bool runOnModule(Module &M);
45
46     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
47       AU.setPreservesAll();
48     }
49   };
50
51   char StripSymbols::ID = 0;
52   RegisterPass<StripSymbols> X("strip", "Strip all symbols from a module");
53 }
54
55 ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
56   return new StripSymbols(OnlyDebugInfo);
57 }
58
59 static void RemoveDeadConstant(Constant *C) {
60   assert(C->use_empty() && "Constant is not dead!");
61   std::vector<Constant*> Operands;
62   for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
63     if (isa<DerivedType>(C->getOperand(i)->getType()) &&
64         C->getOperand(i)->hasOneUse())
65       Operands.push_back(C->getOperand(i));
66   if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
67     if (!GV->hasInternalLinkage()) return;   // Don't delete non static globals.
68     GV->eraseFromParent();
69   }
70   else if (!isa<Function>(C))
71     C->destroyConstant();
72
73   // If the constant referenced anything, see if we can delete it as well.
74   while (!Operands.empty()) {
75     RemoveDeadConstant(Operands.back());
76     Operands.pop_back();
77   }
78 }
79
80 // Strip the symbol table of its names.
81 //
82 static void StripSymtab(ValueSymbolTable &ST) {
83   for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
84     Value *V = VI->getValue();
85     ++VI;
86     if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
87       // Set name to "", removing from symbol table!
88       V->setName("");
89     }
90   }
91 }
92
93 // Strip the symbol table of its names.
94 static void StripTypeSymtab(TypeSymbolTable &ST) {
95   for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; )
96     ST.remove(TI++);
97 }
98
99
100
101 bool StripSymbols::runOnModule(Module &M) {
102   // If we're not just stripping debug info, strip all symbols from the
103   // functions and the names from any internal globals.
104   if (!OnlyDebugInfo) {
105     for (Module::global_iterator I = M.global_begin(), E = M.global_end();
106          I != E; ++I)
107       if (I->hasInternalLinkage())
108         I->setName("");     // Internal symbols can't participate in linkage
109
110     for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
111       if (I->hasInternalLinkage())
112         I->setName("");     // Internal symbols can't participate in linkage
113       StripSymtab(I->getValueSymbolTable());
114     }
115     
116     // Remove all names from types.
117     StripTypeSymtab(M.getTypeSymbolTable());
118   }
119
120   // Strip debug info in the module if it exists.  To do this, we remove
121   // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and
122   // any globals they point to if now dead.
123   Function *FuncStart = M.getFunction("llvm.dbg.func.start");
124   Function *StopPoint = M.getFunction("llvm.dbg.stoppoint");
125   Function *RegionStart = M.getFunction("llvm.dbg.region.start");
126   Function *RegionEnd = M.getFunction("llvm.dbg.region.end");
127   Function *Declare = M.getFunction("llvm.dbg.declare");
128   if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare)
129     return true;
130
131   std::vector<GlobalVariable*> DeadGlobals;
132
133   // Remove all of the calls to the debugger intrinsics, and remove them from
134   // the module.
135   if (FuncStart) {
136     while (!FuncStart->use_empty()) {
137       CallInst *CI = cast<CallInst>(FuncStart->use_back());
138       Value *Arg = CI->getOperand(1);
139       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
140       CI->eraseFromParent();
141       if (Arg->use_empty())
142         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
143           DeadGlobals.push_back(GV);
144     }
145     FuncStart->eraseFromParent();
146   }
147   if (StopPoint) {
148     while (!StopPoint->use_empty()) {
149       CallInst *CI = cast<CallInst>(StopPoint->use_back());
150       Value *Arg = CI->getOperand(3);
151       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
152       CI->eraseFromParent();
153       if (Arg->use_empty())
154         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
155           DeadGlobals.push_back(GV);
156     }
157     StopPoint->eraseFromParent();
158   }
159   if (RegionStart) {
160     while (!RegionStart->use_empty()) {
161       CallInst *CI = cast<CallInst>(RegionStart->use_back());
162       Value *Arg = CI->getOperand(1);
163       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
164       CI->eraseFromParent();
165       if (Arg->use_empty())
166         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
167           DeadGlobals.push_back(GV);
168     }
169     RegionStart->eraseFromParent();
170   }
171   if (RegionEnd) {
172     while (!RegionEnd->use_empty()) {
173       CallInst *CI = cast<CallInst>(RegionEnd->use_back());
174       Value *Arg = CI->getOperand(1);
175       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
176       CI->eraseFromParent();
177       if (Arg->use_empty())
178         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
179           DeadGlobals.push_back(GV);
180     }
181     RegionEnd->eraseFromParent();
182   }
183   if (Declare) {
184     while (!Declare->use_empty()) {
185       CallInst *CI = cast<CallInst>(Declare->use_back());
186       Value *Arg = CI->getOperand(2);
187       assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
188       CI->eraseFromParent();
189       if (Arg->use_empty())
190         if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
191           DeadGlobals.push_back(GV);
192     }
193     Declare->eraseFromParent();
194   }
195
196   // Finally, delete any internal globals that were only used by the debugger
197   // intrinsics.
198   while (!DeadGlobals.empty()) {
199     GlobalVariable *GV = DeadGlobals.back();
200     DeadGlobals.pop_back();
201     if (GV->hasInternalLinkage())
202       RemoveDeadConstant(GV);
203   }
204
205   return true;
206 }