Hi Chris, Chris Lattner wrote:>> We can not use current exception handling in llvm, see >> http://www.nondot.org/sabre/LLVMNotes/ExceptionHandlingChanges.txt. >> > > Why not? > >Like you say, it's not functional for non-calls instructions. Besides, having to change all CalInst to InvokeInst is just too much pain in our current vm.> There are two separate issues here: > > 1. catching exceptions from function calls > 2. catching exceptions from "non call" instructions like divides, etc. > > The LLVM IR, as it stands now, is expressive enough to describe #1, but > not #2. The notes above talk solely about how to extend the IR to support > #2. Reid has an interest in implementing #2 at some point, which will be > a great improvement for some applications. > > There is an extra wrinkle here though. Zero-cost C++ exception handling > (i.e. #1) is about 3/4 of the way implemented in the C front-end and code > generator, but it is not yet completed (notably, JIT support is missing). > This work is also currently stalled. > >Actually, why is it missing? What's the difference between the code generator and the JIT?> If you'd be interested in helping with any of these projects, please let > me know! >The thing is, I know very little on exception handling (our setjmp/longjmp mechanism in our vms is functional but not really optimized) and zip on LLVM. I looked at Reid's notes for implementing #2, and I'm not sure I can help without having a month or two (of spare time) to learn LLVM's internals. However, I'd be interested to look at how exception handling can be implemented in the JIT. What's the current situation? Nicolas
On Fri, 6 Apr 2007, Nicolas Geoffray wrote:> Like you say, it's not functional for non-calls instructions. Besides, > having to change all CalInst to InvokeInst is just too much pain in our > current vm.ok.> Actually, why is it missing? What's the difference between the code > generator and the JIT?There are two things missing: 1. Testing and working out the set of remaining bugs 2. Extending the JIT to emit the EH tables to memory somewhere, and register them with the EH runtime.> The thing is, I know very little on exception handling (our > setjmp/longjmp mechanism in our vms is functional but not really > optimized) and zip on LLVM.I don't know, you seem to know something about the code generator :)> I looked at Reid's notes for implementing #2, and I'm not sure I can > help without having a month or two (of spare time) to learn LLVM's > internals.Right, I wouldn't suggest tackling this unless you are willing to see it through all the way.> However, I'd be interested to look at how exception handling can be > implemented in the JIT. What's the current situation?The static code generator works for many simple cases, but it is currently disabled. To enable it, uncomment this line in llvm-gcc/gcc/llvm-convert.cpp: //#define ITANIUM_STYLE_EXCEPTIONS Based on that, you should be able to compile simple C++ codes that throw and catch exceptions. The next step would be to make a .bc file, run it through the JIT, see how it explodes :) -Chris -- http://nondot.org/sabre/ http://llvm.org/
Hi Chris,> The static code generator works for many simple cases, but it is currently > disabled. To enable it, uncomment this line in > llvm-gcc/gcc/llvm-convert.cpp: > > //#define ITANIUM_STYLE_EXCEPTIONS > > > Based on that, you should be able to compile simple C++ codes that throw > and catch exceptions. The next step would be to make a .bc file, run it > through the JIT, see how it explodes :)the compiler fails to build if you do that :-/ The attached patch helps a bit but it needs more work. Also, I suppose you might need to uncomment this bit in llvm-backend.cpp as well: // Disabled until PR1224 is resolved. //if (flag_exceptions) // Args.push_back("--enable-eh"); Some comments on the patch: (1) new UnreachableInst(CurBB); + } else { + new UnwindInst(UnwindBB); } -#endif +#else new UnwindInst(UnwindBB); +#endif This avoid generating an unwind instruction straight after an unreachable instruction, i.e. two terminators in a row. (2) - FuncCPPPersonality = cast<Function>( + FuncCPPPersonality TheModule->getOrInsertFunction("__gxx_personality_v0", Type::getPrimitiveType(Type::VoidTyID), - NULL)); - FuncCPPPersonality->setLinkage(Function::ExternalLinkage); - FuncCPPPersonality->setCallingConv(CallingConv::C); + NULL); - FuncUnwindResume = cast<Function>( + FuncUnwindResume TheModule->getOrInsertFunction("_Unwind_Resume", Type::getPrimitiveType(Type::VoidTyID), PointerType::get(Type::Int8Ty), - NULL)); - FuncUnwindResume->setLinkage(Function::ExternalLinkage); - FuncUnwindResume->setCallingConv(CallingConv::C); + NULL); When compiling the C++ file in which __gxx_personality_v0 is defined, getOrInsertFunction returns a bitcast of the real function (a bitcast, because the prototype of the real function is not "void (void)"). This is a constant expression, thus cast<Function> asserts. Also, there seems to be no need to set the CC and linkage because the values set are the defaults. By the way, I like the use of the C++ only __gxx_personality_v0 here! (3) + TypeInfo = BitCastToType(TypeInfo, PointerType::get(Type::Int8Ty)); This argument is, as far as I can see, just a "cookie" and certainly need not be an i8*, thus the bitcast. Also, since it is a cookie, shouldn't the intrinsic be taking an opaque* rather than an i8*? Ciao, Duncan. -------------- next part -------------- A non-text attachment was scrubbed... Name: eon.diff Type: text/x-diff Size: 2665 bytes Desc: not available URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20070406/7c58cac3/attachment.diff>
Reasonably Related Threads
- [LLVMdev] Integrating LLVM in an existing project
- [LLVMdev] Integrating LLVM in an existing project
- [LLVMdev] llvm-gcc Bug, Looking for Advice on Fix
- [LLVMdev] automatically generating intrinsic declarations
- [LLVMdev] automatically generating intrinsic declarations