| Index: lib/Transforms/NaCl/GlobalCleanup.cpp
|
| diff --git a/lib/Transforms/NaCl/GlobalCleanup.cpp b/lib/Transforms/NaCl/GlobalCleanup.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d489fefc1dcb6c311e3febae63f12758817db874
|
| --- /dev/null
|
| +++ b/lib/Transforms/NaCl/GlobalCleanup.cpp
|
| @@ -0,0 +1,120 @@
|
| +//===- 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 "
|
| + "(assumes all of the binary is linked statically)",
|
| + 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;
|
| + }
|
| + case GlobalValue::WeakAnyLinkage: {
|
| + GV->setLinkage(GlobalValue::InternalLinkage);
|
| + 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);
|
| + }
|
| +
|
| + for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
|
| + Function *F = I++;
|
| + Modified |= CleanUpLinkage(F);
|
| + }
|
| + 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 *llvm::createResolveAliasesPass() {
|
| + return new ResolveAliases();
|
| +}
|
|
|