diff options
| -rw-r--r-- | include/llvm/InitializePasses.h | 4 | ||||
| -rw-r--r-- | include/llvm/Transforms/NaCl.h | 2 | ||||
| -rw-r--r-- | lib/Transforms/NaCl/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lib/Transforms/NaCl/GlobalCleanup.cpp | 109 | ||||
| -rw-r--r-- | test/Transforms/NaCl/globalcleanup.ll | 34 | ||||
| -rw-r--r-- | test/Transforms/NaCl/resolve-aliases.ll | 36 | ||||
| -rw-r--r-- | tools/opt/opt.cpp | 4 |
7 files changed, 189 insertions, 1 deletions
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index 0655c22545..9934ff3a9a 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -279,12 +279,14 @@ void initializeMachineFunctionPrinterPassPass(PassRegistry&); // @LOCALMOD-BEGIN void initializeExpandConstantExprPass(PassRegistry&); void initializeExpandCtorsPass(PassRegistry&); -void initializeExpandTlsPass(PassRegistry&); void initializeExpandTlsConstantExprPass(PassRegistry&); +void initializeExpandTlsPass(PassRegistry&); void initializeExpandVarArgsPass(PassRegistry&); +void initializeGlobalCleanupPass(PassRegistry&); void initializeNaClCcRewritePass(PassRegistry&); void initializePNaClABIVerifyModulePass(PassRegistry&); void initializePNaClABIVerifyFunctionsPass(PassRegistry&); +void initializeResolveAliasesPass(PassRegistry&); // @LOCALMOD-END } diff --git a/include/llvm/Transforms/NaCl.h b/include/llvm/Transforms/NaCl.h index 6494200f6d..b5108fbf32 100644 --- a/include/llvm/Transforms/NaCl.h +++ b/include/llvm/Transforms/NaCl.h @@ -20,6 +20,8 @@ ModulePass *createExpandCtorsPass(); ModulePass *createExpandTlsPass(); ModulePass *createExpandTlsConstantExprPass(); ModulePass *createExpandVarArgsPass(); +ModulePass *createGlobalCleanupPass(); +ModulePass *createResolveAliasesPass(); } 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(); +} diff --git a/test/Transforms/NaCl/globalcleanup.ll b/test/Transforms/NaCl/globalcleanup.ll new file mode 100644 index 0000000000..3af5df003e --- /dev/null +++ b/test/Transforms/NaCl/globalcleanup.ll @@ -0,0 +1,34 @@ +; RUN: opt < %s -nacl-global-cleanup -S | FileCheck %s +; RUN: opt < %s -nacl-global-cleanup -S | FileCheck -check-prefix=GV %s + +@llvm.compiler.used = appending global [0 x i8*] zeroinitializer, section "llvm.metadata" +@llvm.used = appending global [0 x i8*] zeroinitializer, section "llvm.metadata" + +; GV-NOT: llvm.used +; GV-NOT: llvm.compiler.used + +@extern_weak_const = extern_weak constant i32 +@extern_weak_gv = extern_weak global i32 + +; GV-NOT: @extern_weak_const +; GV-NOT: @extern_weak_gv + +; CHECK define void @_start +define void @_start() { + ret void +} + +define i32* @ewgv() { +; CHECK: %bc = getelementptr i8* null, i32 0 + %bc = getelementptr i8* bitcast (i32* @extern_weak_gv to i8*), i32 0 +; CHECK: ret i32* null + ret i32* @extern_weak_gv +} + +define i32* @ewc() { +; CHECK: %bc = getelementptr i8* null, i32 0 + %bc = getelementptr i8* bitcast (i32* @extern_weak_const to i8*), i32 0 +; CHECK: ret i32* null + ret i32* @extern_weak_gv +} + diff --git a/test/Transforms/NaCl/resolve-aliases.ll b/test/Transforms/NaCl/resolve-aliases.ll new file mode 100644 index 0000000000..82ad54d74e --- /dev/null +++ b/test/Transforms/NaCl/resolve-aliases.ll @@ -0,0 +1,36 @@ +; RUN: opt < %s -resolve-aliases -S | FileCheck %s + +; CHECK-NOT: @alias + +@r1 = internal global i32 zeroinitializer +@a1 = alias i32* @r1 +define i32* @usea1() { +; CHECK: ret i32* @r1 + ret i32* @a1 +} + +@funcalias = alias i32* ()* @usea1 +; CHECK: @usefuncalias +define void @usefuncalias() { +; CHECK: call i32* @usea1 + %1 = call i32* @funcalias() + ret void +} + +@bc1 = global i8* bitcast (i32* @r1 to i8*) +@bcalias = alias i8* bitcast (i32* @r1 to i8*) + +; CHECK: @usebcalias +define i8* @usebcalias() { +; CHECK: ret i8* bitcast (i32* @r1 to i8*) + ret i8* @bcalias +} + + +@fa2 = alias i32* ()* @funcalias +; CHECK: @usefa2 +define void @usefa2() { +; CHECK: call i32* @usea1 + call i32* @fa2() + ret void +} diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 04fa332266..337419553a 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -576,11 +576,15 @@ int main(int argc, char **argv) { initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); + // @LOCALMOD-BEGIN initializeExpandConstantExprPass(Registry); initializeExpandCtorsPass(Registry); initializeExpandTlsPass(Registry); initializeExpandTlsConstantExprPass(Registry); initializeExpandVarArgsPass(Registry); + initializeGlobalCleanupPass(Registry); + initializeResolveAliasesPass(Registry); + // @LOCALMOD-END cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); |
