diff options
| author | Derek Schuff <dschuff@chromium.org> | 2013-03-25 16:51:51 -0700 |
|---|---|---|
| committer | Derek Schuff <dschuff@chromium.org> | 2013-03-25 16:51:51 -0700 |
| commit | 77fc541fc5b17685047aa296f7669a2ddc2bfd89 (patch) | |
| tree | 906e4da1ebed28a0e1d582eea0e20b74ee9058f6 /lib/Transforms | |
| parent | 14a8889a009e84ba18ab200d590cf76bb47000b1 (diff) | |
PNaCl ABI: add passes to cleanup/finalize some linkage types and resolve aliases.
R=mseaborn@chromium.org,eliben@chromium.org
BUG= https://code.google.com/p/nativeclient/issues/detail?id=3339
Review URL: https://codereview.chromium.org/13036005
Diffstat (limited to 'lib/Transforms')
| -rw-r--r-- | lib/Transforms/NaCl/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/Transforms/NaCl/GlobalCleanup.cpp | 109 |
2 files changed, 110 insertions, 0 deletions
diff --git a/lib/Transforms/NaCl/CMakeLists.txt b/lib/Transforms/NaCl/CMakeLists.txt index 6ba9dcc68b..5b1de88dc4 100644 --- a/lib/Transforms/NaCl/CMakeLists.txt +++ b/lib/Transforms/NaCl/CMakeLists.txt @@ -4,6 +4,7 @@ add_llvm_library(LLVMTransformsNaCl ExpandTls.cpp ExpandTlsConstantExpr.cpp ExpandVarArgs.cpp + GlobalCleanup.cpp ) add_dependencies(LLVMTransformsNaCl intrinsics_gen) diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp new file mode 100644 index 0000000000..9a28063af6 --- /dev/null +++ b/lib/Transforms/NaCl/GlobalCleanup.cpp @@ -0,0 +1,109 @@ +//===- GlobalCleanup.cpp - Cleanup global symbols post-bitcode-link -------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// ===---------------------------------------------------------------------===// +// +// PNaCl executables should have no external symbols or aliases. These passes +// internalize (or otherwise remove/resolve) GlobalValues and resolve all +// GlobalAliases. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Transforms/NaCl.h" + +using namespace llvm; + +namespace { + class GlobalCleanup : public ModulePass { + public: + static char ID; + GlobalCleanup() : ModulePass(ID) { + initializeGlobalCleanupPass(*PassRegistry::getPassRegistry()); + } + virtual bool runOnModule(Module &M); + }; + + class ResolveAliases : public ModulePass { + public: + static char ID; + ResolveAliases() : ModulePass(ID) { + initializeResolveAliasesPass(*PassRegistry::getPassRegistry()); + } + virtual bool runOnModule(Module &M); + }; +} + +char GlobalCleanup::ID = 0; +INITIALIZE_PASS(GlobalCleanup, "nacl-global-cleanup", + "GlobalValue cleanup for PNaCl", false, false) + +static bool CleanUpLinkage(GlobalValue *GV) { + // TODO(dschuff): handle the rest of the linkage types as necessary without + // running afoul of the IR verifier or breaking the native link + switch (GV->getLinkage()) { + case GlobalValue::ExternalWeakLinkage: { + Constant *NullRef = Constant::getNullValue(GV->getType()); + GV->replaceAllUsesWith(NullRef); + GV->eraseFromParent(); + return true; + } + default: + // default with fall through to avoid compiler warning + return false; + } + return false; +} + +bool GlobalCleanup::runOnModule(Module &M) { + bool Modified = false; + + if (GlobalVariable *GV = M.getNamedGlobal("llvm.compiler.used")) { + GV->eraseFromParent(); + Modified = true; + } + if (GlobalVariable *GV = M.getNamedGlobal("llvm.used")) { + GV->eraseFromParent(); + Modified = true; + } + + for (Module::global_iterator I = M.global_begin(), E = M.global_end(); + I != E; ) { + GlobalVariable *GV = I++; + Modified |= CleanUpLinkage(GV); + } + return Modified; +} + +ModulePass *llvm::createGlobalCleanupPass() { + return new GlobalCleanup(); +} + +char ResolveAliases::ID = 0; +INITIALIZE_PASS(ResolveAliases, "resolve-aliases", + "resolve global variable and function aliases", false, false) + +bool ResolveAliases::runOnModule(Module &M) { + bool Modified = false; + + for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end(); + I != E; ) { + GlobalAlias *Alias = I++; + Alias->replaceAllUsesWith(Alias->getAliasee()); + Alias->eraseFromParent(); + Modified = true; + } + return Modified; +} + +ModulePass *createResolveAliasesPass() { + return new ResolveAliases(); +} |
