37
37
#include " llvm/Transforms/Utils/BasicBlockUtils.h"
38
38
#include " llvm/Transforms/Utils/Local.h"
39
39
#include " llvm/Transforms/NaCl.h"
40
+ #include < vector>
41
+
42
+ #include " llvm/Support/raw_ostream.h"
43
+ #include < stdio.h>
44
+ #define dump (x ) fprintf(stderr, x " \n " )
45
+ #define dumpv (x, ...) fprintf(stderr, x " \n " , __VA_ARGS__)
46
+ #define dumpfail (x ) { fprintf (stderr, x " \n " ); fprintf (stderr, " %s : %d\n " , __FILE__, __LINE__); report_fatal_error (" fail" ); }
47
+ #define dumpfailv (x, ...) { fprintf (stderr, x " \n " , __VA_ARGS__); fprintf (stderr, " %s : %d\n " , __FILE__, __LINE__); report_fatal_error (" fail" ); }
48
+ #define dumpIR (value ) { \
49
+ std::string temp; \
50
+ raw_string_ostream stream (temp); \
51
+ stream << *(value); \
52
+ fprintf (stderr, " %s\n " , temp.c_str ()); \
53
+ }
54
+ #undef assert
55
+ #define assert (x ) { if (!(x)) dumpfail (#x); }
40
56
41
57
using namespace llvm ;
42
58
43
59
namespace {
44
60
class LowerEmExceptions : public ModulePass {
45
- Function *PreInvoke, *PostInvoke;
61
+ Function *GetHigh, * PreInvoke, *PostInvoke, *LandingPad ;
46
62
Module *TheModule;
47
63
48
64
public:
49
65
static char ID; // Pass identification, replacement for typeid
50
- explicit LowerEmExceptions () : ModulePass(ID), PreInvoke(NULL ), PostInvoke(NULL ), TheModule(NULL ) {
66
+ explicit LowerEmExceptions () : ModulePass(ID), GetHigh( NULL ), PreInvoke(NULL ), PostInvoke( NULL ), LandingPad (NULL ), TheModule(NULL ) {
51
67
initializeLowerEmExceptionsPass (*PassRegistry::getPassRegistry ());
52
68
}
53
69
bool runOnModule (Module &M);
@@ -59,56 +75,89 @@ INITIALIZE_PASS(LowerEmExceptions, "loweremexceptions",
59
75
" Lower invoke and unwind for js/emscripten" ,
60
76
false , false )
61
77
62
- Instruction *getSingleUse(Instruction *I) {
63
- Instruction *Ret = NULL ;
64
- for (Instruction::use_iterator UI = I->use_begin (), UE = I->use_end (); UI != UE; ++UI) {
65
- assert (Ret == NULL );
66
- Ret = cast<ExtractElementInst>(*UI);
67
- }
68
- assert (Ret != NULL );
69
- return Ret;
70
- }
71
-
72
78
bool LowerEmExceptions::runOnModule(Module &M) {
73
79
TheModule = &M;
74
80
75
- Type *Void = Type::getVoidTy (M.getContext ());
81
+ // Add functions
82
+
76
83
Type *i32 = Type::getInt32Ty (M.getContext ());
84
+ Type *i8 = Type::getInt8Ty (M.getContext ());
85
+ Type *i1 = Type::getInt1Ty (M.getContext ());
86
+ Type *i8P = i8->getPointerTo ();
87
+ Type *Void = Type::getVoidTy (M.getContext ());
88
+
89
+ if (!TheModule->getFunction (" getHigh32" )) {
90
+ FunctionType *GetHighFunc = FunctionType::get (i32, false );
91
+ GetHigh = Function::Create (GetHighFunc, GlobalValue::ExternalLinkage,
92
+ " getHigh32" , TheModule);
93
+ }
77
94
78
- SmallVector<Type*, 0 > ArgTypes;
79
- FunctionType *VoidFunc = FunctionType::get (Void, ArgTypes, false );
80
- FunctionType *IntFunc = FunctionType::get (i32, ArgTypes, false );
95
+ FunctionType *VoidFunc = FunctionType::get (Void, false );
96
+ PreInvoke = Function::Create (VoidFunc, GlobalValue::ExternalLinkage, " emscripten_preinvoke" , TheModule);
81
97
82
- PreInvoke = Function::Create (VoidFunc, GlobalValue::ExternalLinkage, " preInvoke" , TheModule);
83
- PostInvoke = Function::Create (IntFunc, GlobalValue::ExternalLinkage, " postInvoke" , TheModule);
98
+ FunctionType *Int1Func = FunctionType::get (i1, false );
99
+ PostInvoke = Function::Create (Int1Func, GlobalValue::ExternalLinkage, " emscripten_postinvoke" , TheModule);
100
+
101
+ FunctionType *LandingPadFunc = FunctionType::get (i32, true );
102
+ LandingPad = Function::Create (LandingPadFunc, GlobalValue::ExternalLinkage, " emscripten_landingpad" , TheModule);
103
+
104
+ // Process
84
105
85
106
bool Changed = false ;
86
107
108
+ std::vector<Instruction*> ToErase;
109
+
87
110
for (Module::iterator Iter = M.begin (), E = M.end (); Iter != E; ) {
88
111
Function *F = Iter++;
89
112
for (Function::iterator BB = F->begin (), E = F->end (); BB != E; ++BB) {
90
113
if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator ())) {
91
- // Fix up the landingpad. First, make a copy returning just an integer
114
+ // Insert a normal call instruction folded in between pre- and post-invoke
115
+ CallInst *Pre = CallInst::Create (PreInvoke, " " , II);
116
+
117
+ SmallVector<Value*,16 > CallArgs (II->op_begin (), II->op_end () - 3 );
118
+ CallInst *NewCall = CallInst::Create (II->getCalledValue (),
119
+ CallArgs, " " , II);
120
+ NewCall->takeName (II);
121
+ NewCall->setCallingConv (II->getCallingConv ());
122
+ NewCall->setAttributes (II->getAttributes ());
123
+ NewCall->setDebugLoc (II->getDebugLoc ());
124
+ II->replaceAllUsesWith (NewCall);
125
+ ToErase.push_back (II);
126
+
127
+ CallInst *Post = CallInst::Create (PostInvoke, " " , II);
128
+
129
+ // Insert a branch based on the postInvoke
130
+ BranchInst::Create (II->getNormalDest (), II->getUnwindDest (), Post, II);
131
+
132
+ // Replace the landingpad with a landingpad call to get the low part, and a getHigh for the high
92
133
LandingPadInst *LP = II->getLandingPadInst ();
93
134
unsigned Num = LP->getNumClauses ();
94
- LandingPadInst *NewLP = LandingPadInst::Create (i32, LP->getPersonalityFn (), Num, " " , LP);
95
- NewLP->setCleanup (LP->isCleanup ());
96
- for (unsigned i = 0 ; i < Num; i++) NewLP->addClause (LP->getClause (i));
135
+ SmallVector<Value*,16 > NewLPArgs;
136
+ NewLPArgs.push_back (LP->getPersonalityFn ());
137
+ for (unsigned i = 0 ; i < Num; i++) NewLPArgs.push_back (LP->getClause (i));
138
+ NewLPArgs.push_back (LP->isCleanup () ? ConstantInt::getTrue (i1) : ConstantInt::getFalse (i1));
139
+ CallInst *NewLP = CallInst::Create (LandingPad, NewLPArgs, " " , LP);
97
140
98
- // Next, replace the old LP's single use, which is an extractelement, to eliminate the ee's and use the value directly
99
- ExtractElementInst *EE = cast<ExtractElementInst>(getSingleUse (LP));
100
- EE->replaceAllUsesWith (NewLP);
101
- EE->eraseFromParent ();
141
+ Instruction *High = CallInst::Create (GetHigh, " " , LP);
102
142
103
- // Finish the LP by replacing it
104
- LP->replaceAllUsesWith (NewLP);
105
- LP->eraseFromParent ();
143
+ // New recreate an aggregate for them, which will be all simplified later (simplification cannot handle landingpad, hence all this)
144
+ SmallVector<unsigned , 1 > IVArgsA;
145
+ IVArgsA.push_back (0 );
146
+ InsertValueInst *IVA = InsertValueInst::Create (UndefValue::get (LP->getType ()), NewLP, IVArgsA, " " , LP);
147
+ SmallVector<unsigned , 1 > IVArgsB;
148
+ IVArgsB.push_back (1 );
149
+ InsertValueInst *IVB = InsertValueInst::Create (IVA, High, IVArgsB, " " , LP);
150
+
151
+ LP->replaceAllUsesWith (IVB);
152
+ ToErase.push_back (LP);
106
153
107
154
Changed = true ;
108
155
}
109
156
}
110
157
}
111
158
159
+ for (unsigned i = 0 ; i < ToErase.size (); i++) ToErase[i]->eraseFromParent ();
160
+
112
161
return Changed;
113
162
}
114
163
0 commit comments