OLD | NEW |
(Empty) | |
| 1 //===- GlobalCleanup.cpp - Cleanup global symbols post-bitcode-link -------===// |
| 2 // |
| 3 // The LLVM Compiler Infrastructure |
| 4 // |
| 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. |
| 7 // |
| 8 // ===---------------------------------------------------------------------===// |
| 9 // |
| 10 // PNaCl executables should have no external symbols or aliases. These passes |
| 11 // internalize (or otherwise remove/resolve) GlobalValues and resolve all |
| 12 // GlobalAliases. |
| 13 // |
| 14 //===----------------------------------------------------------------------===// |
| 15 |
| 16 #include "llvm/IR/Constants.h" |
| 17 #include "llvm/IR/DerivedTypes.h" |
| 18 #include "llvm/IR/Instructions.h" |
| 19 #include "llvm/IR/Module.h" |
| 20 #include "llvm/Pass.h" |
| 21 #include "llvm/Transforms/NaCl.h" |
| 22 |
| 23 using namespace llvm; |
| 24 |
| 25 namespace { |
| 26 class GlobalCleanup : public ModulePass { |
| 27 public: |
| 28 static char ID; |
| 29 GlobalCleanup() : ModulePass(ID) { |
| 30 initializeGlobalCleanupPass(*PassRegistry::getPassRegistry()); |
| 31 } |
| 32 virtual bool runOnModule(Module &M); |
| 33 }; |
| 34 |
| 35 class ResolveAliases : public ModulePass { |
| 36 public: |
| 37 static char ID; |
| 38 ResolveAliases() : ModulePass(ID) { |
| 39 initializeResolveAliasesPass(*PassRegistry::getPassRegistry()); |
| 40 } |
| 41 virtual bool runOnModule(Module &M); |
| 42 }; |
| 43 } |
| 44 |
| 45 char GlobalCleanup::ID = 0; |
| 46 INITIALIZE_PASS(GlobalCleanup, "nacl-global-cleanup", |
| 47 "GlobalValue cleanup for PNaCl " |
| 48 "(assumes all of the binary is linked statically)", |
| 49 false, false) |
| 50 |
| 51 static bool CleanUpLinkage(GlobalValue *GV) { |
| 52 // TODO(dschuff): handle the rest of the linkage types as necessary without |
| 53 // running afoul of the IR verifier or breaking the native link |
| 54 switch (GV->getLinkage()) { |
| 55 case GlobalValue::ExternalWeakLinkage: { |
| 56 Constant *NullRef = Constant::getNullValue(GV->getType()); |
| 57 GV->replaceAllUsesWith(NullRef); |
| 58 GV->eraseFromParent(); |
| 59 return true; |
| 60 } |
| 61 case GlobalValue::WeakAnyLinkage: { |
| 62 GV->setLinkage(GlobalValue::InternalLinkage); |
| 63 return true; |
| 64 } |
| 65 default: |
| 66 // default with fall through to avoid compiler warning |
| 67 return false; |
| 68 } |
| 69 return false; |
| 70 } |
| 71 |
| 72 bool GlobalCleanup::runOnModule(Module &M) { |
| 73 bool Modified = false; |
| 74 |
| 75 if (GlobalVariable *GV = M.getNamedGlobal("llvm.compiler.used")) { |
| 76 GV->eraseFromParent(); |
| 77 Modified = true; |
| 78 } |
| 79 if (GlobalVariable *GV = M.getNamedGlobal("llvm.used")) { |
| 80 GV->eraseFromParent(); |
| 81 Modified = true; |
| 82 } |
| 83 |
| 84 for (Module::global_iterator I = M.global_begin(), E = M.global_end(); |
| 85 I != E; ) { |
| 86 GlobalVariable *GV = I++; |
| 87 Modified |= CleanUpLinkage(GV); |
| 88 } |
| 89 |
| 90 for (Module::iterator I = M.begin(), E = M.end(); I != E; ) { |
| 91 Function *F = I++; |
| 92 Modified |= CleanUpLinkage(F); |
| 93 } |
| 94 return Modified; |
| 95 } |
| 96 |
| 97 ModulePass *llvm::createGlobalCleanupPass() { |
| 98 return new GlobalCleanup(); |
| 99 } |
| 100 |
| 101 char ResolveAliases::ID = 0; |
| 102 INITIALIZE_PASS(ResolveAliases, "resolve-aliases", |
| 103 "resolve global variable and function aliases", false, false) |
| 104 |
| 105 bool ResolveAliases::runOnModule(Module &M) { |
| 106 bool Modified = false; |
| 107 |
| 108 for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); |
| 109 I != E; ) { |
| 110 GlobalAlias *Alias = I++; |
| 111 Alias->replaceAllUsesWith(Alias->getAliasee()); |
| 112 Alias->eraseFromParent(); |
| 113 Modified = true; |
| 114 } |
| 115 return Modified; |
| 116 } |
| 117 |
| 118 ModulePass *llvm::createResolveAliasesPass() { |
| 119 return new ResolveAliases(); |
| 120 } |
OLD | NEW |