blob: fc9af5bc57fdc88c8d711a9f9e93cf256d99343c [file] [log] [blame]
Chris Lattner6f99eb52003-09-15 04:56:27 +00001//===- LowerSetJmp.cpp - Code pertaining to lowering set/long jumps -------===//
2//
3// This file implements the lowering of setjmp and longjmp to use the
Chris Lattner40b66212003-09-15 05:43:05 +00004// LLVM invoke and unwind instructions as necessary.
Chris Lattner6f99eb52003-09-15 04:56:27 +00005//
6// Lowering of longjmp is fairly trivial. We replace the call with a
7// call to the LLVM library function "__llvm_sjljeh_throw_longjmp()".
8// This unwinds the stack for us calling all of the destructors for
9// objects allocated on the stack.
10//
11// At a setjmp call, the basic block is split and the setjmp removed.
12// The calls in a function that have a setjmp are converted to invoke
13// where the except part checks to see if it's a longjmp exception and,
14// if so, if it's handled in the function. If it is, then it gets the
15// value returned by the longjmp and goes to where the basic block was
16// split. Invoke instructions are handled in a similar fashion with the
17// original except block being executed if it isn't a longjmp except
18// that is handled by that function.
19//
Chris Lattner40b66212003-09-15 05:43:05 +000020// This pass was contributed to LLVM by Bill Wendling.
21//
Chris Lattner6f99eb52003-09-15 04:56:27 +000022//===----------------------------------------------------------------------===//
23
24//===----------------------------------------------------------------------===//
25// FIXME: This pass doesn't deal with PHI statements just yet. That is,
26// we expect this to occur before SSAification is done. This would seem
27// to make sense, but in general, it might be a good idea to make this
28// pass invokable via the "opt" command at will.
29//===----------------------------------------------------------------------===//
30
31#include "llvm/Constants.h"
32#include "llvm/DerivedTypes.h"
33#include "llvm/Instructions.h"
34#include "llvm/Intrinsics.h"
35#include "llvm/Module.h"
36#include "llvm/Pass.h"
37#include "llvm/Support/InstIterator.h"
38#include "llvm/Support/InstVisitor.h"
39#include "Support/Statistic.h"
40#include "Support/StringExtras.h"
41#include "Support/VectorExtras.h"
42
43#include <set>
44
45namespace {
46 Statistic<> LongJmpsTransformed("lowersetjmp",
47 "Number of longjmps transformed");
48 Statistic<> SetJmpsTransformed("lowersetjmp",
49 "Number of setjmps transformed");
50
51 //===--------------------------------------------------------------------===//
52 // LowerSetJmp pass implementation. This is subclassed from the "Pass"
53 // class because it works on a module as a whole, not a function at a
54 // time.
55
56 class LowerSetJmp : public Pass,
57 public InstVisitor<LowerSetJmp> {
58 // LLVM library functions...
59 Function* InitSJMap; // __llvm_sjljeh_init_setjmpmap
60 Function* DestroySJMap; // __llvm_sjljeh_destroy_setjmpmap
61 Function* AddSJToMap; // __llvm_sjljeh_add_setjmp_to_map
62 Function* ThrowLongJmp; // __llvm_sjljeh_throw_longjmp
63 Function* TryCatchLJ; // __llvm_sjljeh_try_catching_longjmp_exception
64 Function* IsLJException; // __llvm_sjljeh_is_longjmp_exception
65 Function* GetLJValue; // __llvm_sjljeh_get_longjmp_value
66
67 typedef std::pair<SwitchInst*, CallInst*> SwitchValuePair;
68
69 // The setjmp map is going to hold information about which setjmps
70 // were called (each setjmp gets its own number) and with which
71 // buffer it was called.
72 std::map<Function*, AllocaInst*> SJMap;
73
74 // The rethrow basic block map holds the basic block to branch to if
75 // the exception isn't handled in the current function and needs to
76 // be rethrown.
77 std::map<const Function*, BasicBlock*> RethrowBBMap;
78
79 // The preliminary basic block map holds a basic block that grabs the
80 // exception and determines if it's handled by the current function.
81 std::map<const Function*, BasicBlock*> PrelimBBMap;
82
83 // The switch/value map holds a switch inst/call inst pair. The
84 // switch inst controls which handler (if any) gets called and the
85 // value is the value returned to that handler by the call to
86 // __llvm_sjljeh_get_longjmp_value.
87 std::map<const Function*, SwitchValuePair> SwitchValMap;
88
89 // A map of which setjmps we've seen so far in a function.
90 std::map<const Function*, unsigned> SetJmpIDMap;
91
92 AllocaInst* GetSetJmpMap(Function* Func);
93 BasicBlock* GetRethrowBB(Function* Func);
94 SwitchValuePair GetSJSwitch(Function* Func, BasicBlock* Rethrow);
95
96 void TransformLongJmpCall(CallInst* Inst);
97 void TransformSetJmpCall(CallInst* Inst);
98
99 bool IsTransformableFunction(const std::string& Name);
100 public:
101 void visitCallInst(CallInst& CI);
102 void visitInvokeInst(InvokeInst& II);
103 void visitReturnInst(ReturnInst& RI);
104 void visitUnwindInst(UnwindInst& UI);
105
106 bool run(Module& M);
107 bool doInitialization(Module& M);
108 };
109
110 RegisterOpt<LowerSetJmp> X("lowersetjmp", "Lower Set Jump");
111} // end anonymous namespace
112
113// run - Run the transformation on the program. We grab the function
114// prototypes for longjmp and setjmp. If they are used in the program,
115// then we can go directly to the places they're at and transform them.
116bool LowerSetJmp::run(Module& M)
117{
118 bool Changed = false;
119
120 // These are what the functions are called.
121 Function* SetJmp = M.getNamedFunction("llvm.setjmp");
122 Function* LongJmp = M.getNamedFunction("llvm.longjmp");
123
124 // This program doesn't have longjmp and setjmp calls.
125 if ((!LongJmp || LongJmp->use_empty()) &&
126 (!SetJmp || SetJmp->use_empty())) return false;
127
128 // Initialize some values and functions we'll need to transform the
129 // setjmp/longjmp functions.
130 doInitialization(M);
131
132 if (SetJmp)
133 while (!SetJmp->use_empty()) {
134 assert(isa<CallInst>(SetJmp->use_back()) &&
135 "User of setjmp intrinsic not a call?");
136 TransformSetJmpCall(cast<CallInst>(SetJmp->use_back()));
137 Changed = true;
138 }
139
140 if (LongJmp)
141 while (!LongJmp->use_empty()) {
142 assert(isa<CallInst>(LongJmp->use_back()) &&
143 "User of longjmp intrinsic not a call?");
144 TransformLongJmpCall(cast<CallInst>(LongJmp->use_back()));
145 Changed = true;
146 }
147
148 // Now go through the affected functions and convert calls and invokes
149 // to new invokes...
150 for (std::map<Function*, AllocaInst*>::iterator
151 B = SJMap.begin(), E = SJMap.end(); B != E; ++B) {
152 Function* F = B->first;
153 for (Function::iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB)
154 for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ) {
155 visit(*IB++);
156 if (IB != BB->end() && IB->getParent() != BB)
157 break; // The next instruction got moved to a different block!
158 }
159 }
160
161 SJMap.clear();
162 RethrowBBMap.clear();
163 PrelimBBMap.clear();
164 SwitchValMap.clear();
165 SetJmpIDMap.clear();
166
167 return Changed;
168}
169
170// doInitialization - For the lower long/setjmp pass, this ensures that a
171// module contains a declaration for the intrisic functions we are going
172// to call to convert longjmp and setjmp calls.
173//
174// This function is always successful, unless it isn't.
175bool LowerSetJmp::doInitialization(Module& M)
176{
177 const Type *SBPTy = PointerType::get(Type::SByteTy);
178 const Type *SBPPTy = PointerType::get(SBPTy);
179
180 // N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
181 // a description of the following library functions.
182
183 // void __llvm_sjljeh_init_setjmpmap(void**)
184 InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap",
185 Type::VoidTy, SBPPTy, 0);
186 // void __llvm_sjljeh_destroy_setjmpmap(void**)
187 DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap",
188 Type::VoidTy, SBPPTy, 0);
189
190 // void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned)
191 AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map",
192 Type::VoidTy, SBPPTy, SBPTy,
193 Type::UIntTy, 0);
194
195 // void __llvm_sjljeh_throw_longjmp(int*, int)
196 ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp",
197 Type::VoidTy, SBPTy, Type::IntTy, 0);
198
199 // unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **)
200 TryCatchLJ =
201 M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception",
202 Type::UIntTy, SBPPTy, 0);
203
204 // bool __llvm_sjljeh_is_longjmp_exception()
205 IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception",
206 Type::BoolTy, 0);
207
208 // int __llvm_sjljeh_get_longjmp_value()
209 GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value",
210 Type::IntTy, 0);
211 return true;
212}
213
214// IsTransformableFunction - Return true if the function name isn't one
215// of the ones we don't want transformed. Currently, don't transform any
216// "llvm.{setjmp,longjmp}" functions and none of the setjmp/longjmp error
217// handling functions (beginning with __llvm_sjljeh_...they don't throw
218// exceptions).
219bool LowerSetJmp::IsTransformableFunction(const std::string& Name)
220{
221 std::string SJLJEh("__llvm_sjljeh");
222
Chris Lattner40b66212003-09-15 05:43:05 +0000223 if (Name.size() > SJLJEh.size())
224 return std::string(Name.begin(), Name.begin() + SJLJEh.size()) != SJLJEh;
Chris Lattner6f99eb52003-09-15 04:56:27 +0000225
226 return true;
227}
228
229// TransformLongJmpCall - Transform a longjmp call into a call to the
230// internal __llvm_sjljeh_throw_longjmp function. It then takes care of
231// throwing the exception for us.
232void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
233{
234 const Type* SBPTy = PointerType::get(Type::SByteTy);
235
236 // Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
237 // same parameters as "longjmp", except that the buffer is cast to a
238 // char*. It returns "void", so it doesn't need to replace any of
239 // Inst's uses and doesn't get a name.
240 CastInst* CI = new CastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst);
241 new CallInst(ThrowLongJmp, make_vector<Value*>(CI, Inst->getOperand(2), 0),
242 "", Inst);
243
244 SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()];
245
246 // If the function has a setjmp call in it (they are transformed first)
247 // we should branch to the basic block that determines if this longjmp
248 // is applicable here. Otherwise, issue an unwind.
249 if (SVP.first)
250 new BranchInst(SVP.first->getParent(), Inst);
251 else
252 new UnwindInst(Inst);
253
254 // Remove all insts after the branch/unwind inst.
255 Inst->getParent()->getInstList().erase(Inst,
256 Inst->getParent()->getInstList().end());
257
258 ++LongJmpsTransformed;
259}
260
261// GetSetJmpMap - Retrieve (create and initialize, if necessary) the
262// setjmp map. This map is going to hold information about which setjmps
263// were called (each setjmp gets its own number) and with which buffer it
264// was called. There can be only one!
265AllocaInst* LowerSetJmp::GetSetJmpMap(Function* Func)
266{
267 if (SJMap[Func]) return SJMap[Func];
268
269 // Insert the setjmp map initialization before the first instruction in
270 // the function.
271 Instruction* Inst = Func->getEntryNode().begin();
272 assert(Inst && "Couldn't find even ONE instruction in entry block!");
273
274 // Fill in the alloca and call to initialize the SJ map.
275 const Type *SBPTy = PointerType::get(Type::SByteTy);
276 AllocaInst* Map = new AllocaInst(SBPTy, 0, "SJMap", Inst);
277 new CallInst(InitSJMap, make_vector<Value*>(Map, 0), "", Inst);
278 return SJMap[Func] = Map;
279}
280
281// GetRethrowBB - Only one rethrow basic block is needed per function.
282// If this is a longjmp exception but not handled in this block, this BB
283// performs the rethrow.
284BasicBlock* LowerSetJmp::GetRethrowBB(Function* Func)
285{
286 if (RethrowBBMap[Func]) return RethrowBBMap[Func];
287
288 // The basic block we're going to jump to if we need to rethrow the
289 // exception.
290 BasicBlock* Rethrow = new BasicBlock("RethrowExcept", Func);
291 BasicBlock::InstListType& RethrowBlkIL = Rethrow->getInstList();
292
293 // Fill in the "Rethrow" BB with a call to rethrow the exception. This
294 // is the last instruction in the BB since at this point the runtime
295 // should exit this function and go to the next function.
296 RethrowBlkIL.push_back(new UnwindInst());
297 return RethrowBBMap[Func] = Rethrow;
298}
299
300// GetSJSwitch - Return the switch statement that controls which handler
301// (if any) gets called and the value returned to that handler.
302LowerSetJmp::SwitchValuePair LowerSetJmp::GetSJSwitch(Function* Func,
303 BasicBlock* Rethrow)
304{
305 if (SwitchValMap[Func].first) return SwitchValMap[Func];
306
307 BasicBlock* LongJmpPre = new BasicBlock("LongJmpBlkPre", Func);
308 BasicBlock::InstListType& LongJmpPreIL = LongJmpPre->getInstList();
309
310 // Keep track of the preliminary basic block for some of the other
311 // transformations.
312 PrelimBBMap[Func] = LongJmpPre;
313
314 // Grab the exception.
315 CallInst* Cond = new
316 CallInst(IsLJException, std::vector<Value*>(), "IsLJExcept");
317 LongJmpPreIL.push_back(Cond);
318
319 // The "decision basic block" gets the number associated with the
320 // setjmp call returning to switch on and the value returned by
321 // longjmp.
322 BasicBlock* DecisionBB = new BasicBlock("LJDecisionBB", Func);
323 BasicBlock::InstListType& DecisionBBIL = DecisionBB->getInstList();
324
325 LongJmpPreIL.push_back(new BranchInst(DecisionBB, Rethrow, Cond));
326
327 // Fill in the "decision" basic block.
328 CallInst* LJVal = new CallInst(GetLJValue, std::vector<Value*>(), "LJVal");
329 DecisionBBIL.push_back(LJVal);
330 CallInst* SJNum = new
331 CallInst(TryCatchLJ, make_vector<Value*>(GetSetJmpMap(Func), 0), "SJNum");
332 DecisionBBIL.push_back(SJNum);
333
334 SwitchInst* SI = new SwitchInst(SJNum, Rethrow);
335 DecisionBBIL.push_back(SI);
336 return SwitchValMap[Func] = SwitchValuePair(SI, LJVal);
337}
338
339// TransformSetJmpCall - The setjmp call is a bit trickier to transform.
340// We're going to convert all setjmp calls to nops. Then all "call" and
341// "invoke" instructions in the function are converted to "invoke" where
342// the "except" branch is used when returning from a longjmp call.
343void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
344{
345 BasicBlock* ABlock = Inst->getParent();
346 Function* Func = ABlock->getParent();
347
348 // Add this setjmp to the setjmp map.
349 const Type* SBPTy = PointerType::get(Type::SByteTy);
350 CastInst* BufPtr = new CastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
351 new CallInst(AddSJToMap,
352 make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
353 ConstantUInt::get(Type::UIntTy,
354 SetJmpIDMap[Func]++), 0),
355 "", Inst);
356
Chris Lattner6f99eb52003-09-15 04:56:27 +0000357 // Change the setjmp call into a branch statement. We'll remove the
358 // setjmp call in a little bit. No worries.
359 BasicBlock* SetJmpContBlock = ABlock->splitBasicBlock(Inst);
360 assert(SetJmpContBlock && "Couldn't split setjmp BB!!");
361
362 SetJmpContBlock->setName("SetJmpContBlock");
363
364 // Reposition the split BB in the BB list to make things tidier.
365 Func->getBasicBlockList().remove(SetJmpContBlock);
366 Func->getBasicBlockList().insert(++Function::iterator(ABlock),
367 SetJmpContBlock);
368
369 // This PHI node will be in the new block created from the
370 // splitBasicBlock call.
371 PHINode* PHI = new PHINode(Type::IntTy, "SetJmpReturn", Inst);
372
373 // Coming from a call to setjmp, the return is 0.
374 PHI->addIncoming(ConstantInt::getNullValue(Type::IntTy), ABlock);
375
376 // Add the case for this setjmp's number...
377 SwitchValuePair SVP = GetSJSwitch(Func, GetRethrowBB(Func));
378 SVP.first->addCase(ConstantUInt::get(Type::UIntTy, SetJmpIDMap[Func] - 1),
379 SetJmpContBlock);
380
381 // Value coming from the handling of the exception.
382 PHI->addIncoming(SVP.second, SVP.second->getParent());
383
384 // Replace all uses of this instruction with the PHI node created by
385 // the eradication of setjmp.
386 Inst->replaceAllUsesWith(PHI);
387 Inst->getParent()->getInstList().erase(Inst);
388
389 ++SetJmpsTransformed;
390}
391
392// visitCallInst - This converts all LLVM call instructions into invoke
393// instructions. The except part of the invoke goes to the "LongJmpBlkPre"
394// that grabs the exception and proceeds to determine if it's a longjmp
395// exception or not.
396void LowerSetJmp::visitCallInst(CallInst& CI)
397{
398 if (CI.getCalledFunction())
399 if (!IsTransformableFunction(CI.getCalledFunction()->getName()) ||
400 CI.getCalledFunction()->isIntrinsic()) return;
401
402 BasicBlock* OldBB = CI.getParent();
403 BasicBlock* NewBB = OldBB->splitBasicBlock(CI);
404 assert(NewBB && "Couldn't split BB of \"call\" instruction!!");
405 NewBB->setName("Call2Invoke");
406
407 // Reposition the split BB in the BB list to make things tidier.
408 Function* Func = OldBB->getParent();
409 Func->getBasicBlockList().remove(NewBB);
410 Func->getBasicBlockList().insert(++Function::iterator(OldBB), NewBB);
411
412 // Construct the new "invoke" instruction.
413 TerminatorInst* Term = OldBB->getTerminator();
414 std::vector<Value*> Params(CI.op_begin() + 1, CI.op_end());
415 InvokeInst* II = new
416 InvokeInst(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
417 Params, CI.getName(), Term);
418
419 // Replace the old call inst with the invoke inst and remove the call.
420 CI.replaceAllUsesWith(II);
421 CI.getParent()->getInstList().erase(&CI);
422
423 // The old terminator is useless now that we have the invoke inst.
424 Term->getParent()->getInstList().erase(Term);
425}
426
427// visitInvokeInst - Converting the "invoke" instruction is fairly
428// straight-forward. The old exception part is replaced by a query asking
429// if this is a longjmp exception. If it is, then it goes to the longjmp
430// exception blocks. Otherwise, control is passed the old exception.
431void LowerSetJmp::visitInvokeInst(InvokeInst& II)
432{
433 if (II.getCalledFunction())
434 if (!IsTransformableFunction(II.getCalledFunction()->getName()) ||
435 II.getCalledFunction()->isIntrinsic()) return;
436
437 Function* Func = II.getParent()->getParent();
438
439 BasicBlock* NormalBB = II.getNormalDest();
440 BasicBlock* ExceptBB = II.getExceptionalDest();
441
442 BasicBlock* NewExceptBB = new BasicBlock("InvokeExcept", Func);
443 BasicBlock::InstListType& InstList = NewExceptBB->getInstList();
444
445 // If this is a longjmp exception, then branch to the preliminary BB of
446 // the longjmp exception handling. Otherwise, go to the old exception.
447 CallInst* IsLJExcept = new
448 CallInst(IsLJException, std::vector<Value*>(), "IsLJExcept");
449 InstList.push_back(IsLJExcept);
450
451 BranchInst* BR = new BranchInst(PrelimBBMap[Func], ExceptBB, IsLJExcept);
452 InstList.push_back(BR);
453
454 II.setExceptionalDest(NewExceptBB);
455}
456
457// visitReturnInst - We want to destroy the setjmp map upon exit from the
458// function.
459void LowerSetJmp::visitReturnInst(ReturnInst& RI)
460{
461 Function* Func = RI.getParent()->getParent();
462 new CallInst(DestroySJMap, make_vector<Value*>(GetSetJmpMap(Func), 0),
463 "", &RI);
464}
465
466// visitUnwindInst - We want to destroy the setjmp map upon exit from the
467// function.
468void LowerSetJmp::visitUnwindInst(UnwindInst& UI)
469{
470 Function* Func = UI.getParent()->getParent();
471 new CallInst(DestroySJMap, make_vector<Value*>(GetSetJmpMap(Func), 0),
472 "", &UI);
473}
474
475Pass* createLowerSetJmpPass()
476{
477 return new LowerSetJmp();
478}