aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-02-25 18:02:31 -0800
committerAlon Zakai <alonzakai@gmail.com>2014-02-26 09:37:10 -0800
commit547e6d4d13108f7b9a9c0c81451b623017dd7eff (patch)
treee415c7aa57e52ed65d1927ecbc8ef2696c298bfc
parent59cf0306b1c564bbe7b9aa1ea69657fe603615b1 (diff)
NoExitRuntime
-rw-r--r--include/llvm/InitializePasses.h1
-rw-r--r--include/llvm/Transforms/NaCl.h1
-rw-r--r--lib/Transforms/NaCl/CMakeLists.txt1
-rw-r--r--lib/Transforms/NaCl/LowerEmSetjmp.cpp2
-rw-r--r--lib/Transforms/NaCl/NoExitRuntime.cpp97
-rw-r--r--tools/opt/opt.cpp1
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,