diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-02-25 18:02:31 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-02-26 09:37:10 -0800 |
commit | 547e6d4d13108f7b9a9c0c81451b623017dd7eff (patch) | |
tree | e415c7aa57e52ed65d1927ecbc8ef2696c298bfc | |
parent | 59cf0306b1c564bbe7b9aa1ea69657fe603615b1 (diff) |
NoExitRuntime
-rw-r--r-- | include/llvm/InitializePasses.h | 1 | ||||
-rw-r--r-- | include/llvm/Transforms/NaCl.h | 1 | ||||
-rw-r--r-- | lib/Transforms/NaCl/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Transforms/NaCl/LowerEmSetjmp.cpp | 2 | ||||
-rw-r--r-- | lib/Transforms/NaCl/NoExitRuntime.cpp | 97 | ||||
-rw-r--r-- | tools/opt/opt.cpp | 1 |
6 files changed, 102 insertions, 1 deletions
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index d08719291f..f109263894 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -308,6 +308,7 @@ void initializeStripMetadataPass(PassRegistry&); void initializeExpandI64Pass(PassRegistry&); // XXX EMSCRIPTEN void initializeLowerEmExceptionsPass(PassRegistry&); // XXX EMSCRIPTEN void initializeLowerEmSetjmpPass(PassRegistry&); // XXX EMSCRIPTEN +void initializeNoExitRuntimePass(PassRegistry&); // XXX EMSCRIPTEN // @LOCALMOD-END } diff --git a/include/llvm/Transforms/NaCl.h b/include/llvm/Transforms/NaCl.h index 1829265c12..7449dab969 100644 --- a/include/llvm/Transforms/NaCl.h +++ b/include/llvm/Transforms/NaCl.h @@ -53,6 +53,7 @@ ModulePass *createStripMetadataPass(); ModulePass *createExpandI64Pass(); // XXX EMSCRIPTEN ModulePass *createLowerEmExceptionsPass(); // XXX EMSCRIPTEN ModulePass *createLowerEmSetjmpPass(); // XXX EMSCRIPTEN +ModulePass *createNoExitRuntimePass(); // XXX EMSCRIPTEN void PNaClABISimplifyAddPreOptPasses(PassManager &PM); void PNaClABISimplifyAddPostOptPasses(PassManager &PM); diff --git a/lib/Transforms/NaCl/CMakeLists.txt b/lib/Transforms/NaCl/CMakeLists.txt index 31932a42bb..05cef0857e 100644 --- a/lib/Transforms/NaCl/CMakeLists.txt +++ b/lib/Transforms/NaCl/CMakeLists.txt @@ -31,6 +31,7 @@ add_llvm_library(LLVMNaClTransforms ExpandI64.cpp LowerEmExceptionsPass.cpp LowerEmSetjmp.cpp + NoExitRuntime.cpp ) add_dependencies(LLVMNaClTransforms intrinsics_gen) diff --git a/lib/Transforms/NaCl/LowerEmSetjmp.cpp b/lib/Transforms/NaCl/LowerEmSetjmp.cpp index 469bf02daf..0a22d122bc 100644 --- a/lib/Transforms/NaCl/LowerEmSetjmp.cpp +++ b/lib/Transforms/NaCl/LowerEmSetjmp.cpp @@ -297,7 +297,7 @@ bool LowerEmSetjmp::runOnModule(Module &M) { } } - for (int i = 0; i < ToErase.size(); i++) { + for (unsigned i = 0; i < ToErase.size(); i++) { ToErase[i]->eraseFromParent(); } diff --git a/lib/Transforms/NaCl/NoExitRuntime.cpp b/lib/Transforms/NaCl/NoExitRuntime.cpp new file mode 100644 index 0000000000..ca622d3c06 --- /dev/null +++ b/lib/Transforms/NaCl/NoExitRuntime.cpp @@ -0,0 +1,97 @@ +//===- NoExitRuntime.cpp - Expand i64 and wider integer types -------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===------------------------------------------------------------------===// +// +//===------------------------------------------------------------------===// + +#include "llvm/ADT/PostOrderIterator.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Analysis/ConstantFolding.h" +#include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/IRBuilder.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/Pass.h" +#include "llvm/Support/CFG.h" +#include "llvm/Target/TargetLibraryInfo.h" +#include "llvm/Transforms/NaCl.h" +#include "llvm/Transforms/Utils/Local.h" +#include <map> + +#include "llvm/Support/raw_ostream.h" + +#ifdef NDEBUG +#undef assert +#define assert(x) { if (!(x)) report_fatal_error(#x); } +#endif + +using namespace llvm; + +namespace { + class NoExitRuntime : public ModulePass { + Module *TheModule; + + public: + static char ID; + NoExitRuntime() : ModulePass(ID) { + initializeNoExitRuntimePass(*PassRegistry::getPassRegistry()); + } + + virtual bool runOnModule(Module &M); + }; +} + +char NoExitRuntime::ID = 0; +INITIALIZE_PASS(NoExitRuntime, "emscripten-no-exit-runtime", + "Generate code which assumes the runtime is never exited (so atexit etc. is unneeded; see emscripten NO_EXIT_RUNTIME setting)", + false, false) + + +// Implementation of NoExitRuntime + +bool NoExitRuntime::runOnModule(Module &M) { + TheModule = &M; + + Function *AtExit = TheModule->getFunction("__cxa_atexit"); + if (!AtExit || !AtExit->isDeclaration() || AtExit->getNumUses() == 0) return false; + + // The system atexit is used - let's remove calls to it + + Type *i32 = Type::getInt32Ty(TheModule->getContext()); + Value *Zero = Constant::getNullValue(i32); + + std::vector<Instruction*> ToErase; + + for (Instruction::use_iterator UI = AtExit->use_begin(), UE = AtExit->use_end(); UI != UE; ++UI) { + if (CallInst *CI = dyn_cast<CallInst>(*UI)) { + if (CI->getCalledValue() == AtExit) { + // calls to atexit can just be removed + CI->replaceAllUsesWith(Zero); + ToErase.push_back(CI); + continue; + } + } + // Possibly other uses of atexit are done - ptrtoint, etc. - but we leave those alone + } + + for (unsigned i = 0; i < ToErase.size(); i++) { + ToErase[i]->eraseFromParent(); + } + + return true; +} + +ModulePass *llvm::createNoExitRuntimePass() { + return new NoExitRuntime(); +} + diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 7dd71a41b7..9536e7efc7 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -642,6 +642,7 @@ int main(int argc, char **argv) { initializeStripAttributesPass(Registry); initializeStripMetadataPass(Registry); initializeExpandI64Pass(Registry); + initializeNoExitRuntimePass(Registry); // @LOCALMOD-END cl::ParseCommandLineOptions(argc, argv, |