Skip to content
This repository was archived by the owner on Nov 1, 2021. It is now read-only.

Commit daf116d

Browse files
committed
wip better approach to exceptions
1 parent 523fed1 commit daf116d

File tree

4 files changed

+90
-34
lines changed

4 files changed

+90
-34
lines changed

lib/Target/JSBackend/JSBackend.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1256,6 +1256,10 @@ void JSWriter::generateInstruction(const Instruction *I, raw_string_ostream& Cod
12561256
Code << ")|0;";
12571257
break;
12581258
}
1259+
case Instruction::Resume: {
1260+
Code << "___resumeException(" + getValueAsStr(I->getOperand(0)) + "|0);";
1261+
break;
1262+
}
12591263
}
12601264
// append debug info
12611265
if (MDNode *N = I->getMetadata("dbg")) {

lib/Transforms/NaCl/ExpandI64.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -829,10 +829,12 @@ void ExpandI64::ensureFuncs() {
829829
Shl = Function::Create(FourFunc, GlobalValue::ExternalLinkage,
830830
"bitshift64Shl", TheModule);
831831

832-
SmallVector<Type*, 0> GetHighArgTypes;
833-
FunctionType *GetHighFunc = FunctionType::get(i32, GetHighArgTypes, false);
834-
GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
835-
"getHigh32", TheModule);
832+
if (!TheModule->getFunction("getHigh32")) {
833+
SmallVector<Type*, 0> GetHighArgTypes;
834+
FunctionType *GetHighFunc = FunctionType::get(i32, GetHighArgTypes, false);
835+
GetHigh = Function::Create(GetHighFunc, GlobalValue::ExternalLinkage,
836+
"getHigh32", TheModule);
837+
}
836838

837839
Type *V = Type::getVoidTy(TheModule->getContext());
838840

lib/Transforms/NaCl/ExpandVarArgs.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ INITIALIZE_PASS(ExpandVarArgs, "expand-varargs",
6868

6969
static bool isEmscriptenJSArgsFunc(StringRef Name) {
7070
return Name.equals("emscripten_asm_const_int") ||
71-
Name.equals("emscripten_asm_const_double");
71+
Name.equals("emscripten_asm_const_double") ||
72+
Name.equals("emscripten_landingpad");
7273
}
7374

7475
static void ExpandVarArgFunc(Function *Func) {

lib/Transforms/NaCl/LowerEmExceptionsPass.cpp

+78-29
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,33 @@
3737
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
3838
#include "llvm/Transforms/Utils/Local.h"
3939
#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); }
4056

4157
using namespace llvm;
4258

4359
namespace {
4460
class LowerEmExceptions : public ModulePass {
45-
Function *PreInvoke, *PostInvoke;
61+
Function *GetHigh, *PreInvoke, *PostInvoke, *LandingPad;
4662
Module *TheModule;
4763

4864
public:
4965
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) {
5167
initializeLowerEmExceptionsPass(*PassRegistry::getPassRegistry());
5268
}
5369
bool runOnModule(Module &M);
@@ -59,56 +75,89 @@ INITIALIZE_PASS(LowerEmExceptions, "loweremexceptions",
5975
"Lower invoke and unwind for js/emscripten",
6076
false, false)
6177

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-
7278
bool LowerEmExceptions::runOnModule(Module &M) {
7379
TheModule = &M;
7480

75-
Type *Void = Type::getVoidTy(M.getContext());
81+
// Add functions
82+
7683
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+
}
7794

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);
8197

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
84105

85106
bool Changed = false;
86107

108+
std::vector<Instruction*> ToErase;
109+
87110
for (Module::iterator Iter = M.begin(), E = M.end(); Iter != E; ) {
88111
Function *F = Iter++;
89112
for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
90113
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
92133
LandingPadInst *LP = II->getLandingPadInst();
93134
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);
97140

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);
102142

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);
106153

107154
Changed = true;
108155
}
109156
}
110157
}
111158

159+
for (unsigned i = 0; i < ToErase.size(); i++) ToErase[i]->eraseFromParent();
160+
112161
return Changed;
113162
}
114163

0 commit comments

Comments
 (0)