From: Bill Wendling Date: Wed, 26 Oct 2011 18:33:01 +0000 (+0000) Subject: Add the blurb about the new exception handling. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=bc5f6ddfbab753900482a4a5850d54951213336e;p=oota-llvm.git Add the blurb about the new exception handling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@143042 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index 20413485e28..03217ad9781 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -689,12 +689,117 @@ in this section.

LLVM IR has several new features for better support of new targets and that expose new optimization opportunities:

+

One of the biggest changes is that 3.0 has a new exception handling + system. The old system used LLVM intrinsics to convey the exception handling + information to the code generator. It worked in most cases, but not + all. Inlining was especially difficult to get right. Also, the intrinsics + could be moved away from the invoke instruction, making it hard + to recover that information.

+ +

The new EH system makes exception handling a first-class member of the IR. It + adds two new instructions:

+ +

Converting from the old EH API to the new EH API is rather simple, because a + lot of complexity has been removed. The two intrinsics, + @llvm.eh.exception and @llvm.eh.selector have been + superceded by the landingpad instruction. Instead of generating + a call to @llvm.eh.exception and @llvm.eh.selector: + +

+
+Function *ExcIntr = Intrinsic::getDeclaration(TheModule,
+                                              Intrinsic::eh_exception);
+Function *SlctrIntr = Intrinsic::getDeclaration(TheModule,
+                                                Intrinsic::eh_selector);
+
+// The exception pointer.
+Value *ExnPtr = Builder.CreateCall(ExcIntr, "exc_ptr");
+
+std::vector<Value*> Args;
+Args.push_back(ExnPtr);
+Args.push_back(Builder.CreateBitCast(Personality,
+                                     Type::getInt8PtrTy(Context)));
+
+// Add selector clauses to Args.
+
+// The selector call.
+Builder.CreateCall(SlctrIntr, Args, "exc_sel");
+
+
+ +

You should instead generate a landingpad instruction, that + returns an exception object and selector value:

+ +
+
+LandingPadInst *LPadInst =
+  Builder.CreateLandingPad(StructType::get(Int8PtrTy, Int32Ty, NULL),
+                           Personality, 0);
+
+Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
+Builder.CreateStore(LPadExn, getExceptionSlot());
+
+Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
+Builder.CreateStore(LPadSel, getEHSelectorSlot());
+
+
+ +

It's now trivial to add the individual clauses to the landingpad + instruction.

+ +
+
+// Adding a catch clause
+Constant *TypeInfo = getTypeInfo();
+LPadInst->addClause(TypeInfo);
+
+// Adding a C++ catch-all
+LPadInst->addClause(Constant::getNullValue(Builder.getInt8PtrTy()));
+
+// Adding a cleanup
+LPadInst->setCleanup(true);
+
+// Adding a filter clause
+std::vector<Constant*> TypeInfos;
+Constant *TypeInfo = getFilterTypeInfo();
+TypeInfos.push_back(Builder.CreateBitCast(TypeInfo, Builder.getInt8PtrTy()));
+
+ArrayType *FilterTy = ArrayType::get(Int8PtrTy, TypeInfos.size());
+LPadInst->addClause(ConstantArray::get(FilterTy, TypeInfos));
+
+
+ +

Converting from using the @llvm.eh.resume intrinsic to + the resume instruction is trivial. It takes the exception + pointer and exception selector values returned by + the landingpad instruction:

+ +
+
+Type *UnwindDataTy = StructType::get(Builder.getInt8PtrTy(),
+                                     Builder.getInt32Ty(), NULL);
+Value *UnwindData = UndefValue::get(UnwindDataTy);
+Value *ExcPtr = Builder.CreateLoad(getExceptionObjSlot());
+Value *ExcSel = Builder.CreateLoad(getExceptionSelSlot());
+UnwindData = Builder.CreateInsertValue(UnwindData, ExcPtr, 0, "exc_ptr");
+UnwindData = Builder.CreateInsertValue(UnwindData, ExcSel, 1, "exc_sel");
+Builder.CreateResume(UnwindData);
+
+
+