blob: ca622d3c06693d18ae835c22165d7b7a223d7f4a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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();
}
|