diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-10-17 06:31:58 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-10-17 06:31:58 +0000 |
commit | 40930e0c2d30e8726f2f0b30119ec782f7d7254d (patch) | |
tree | 91b05188a1af93ec4438f5d268e633707486b642 /docs | |
parent | beac60d66fd884604ead751ba6faf8f08bcb4ff4 (diff) |
Rough out the EH changes. Include here a sketch on how to use the new APIs.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_30@142181 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'docs')
-rw-r--r-- | docs/ReleaseNotes.html | 111 |
1 files changed, 108 insertions, 3 deletions
diff --git a/docs/ReleaseNotes.html b/docs/ReleaseNotes.html index 100010c31b..05f1619151 100644 --- a/docs/ReleaseNotes.html +++ b/docs/ReleaseNotes.html @@ -480,12 +480,117 @@ be used to verify some algorithms. <p>LLVM IR has several new features for better support of new targets and that expose new optimization opportunities:</p> +<p>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 <code>invoke</code> instruction, making it hard + to recover that information.</p> + +<p>The new EH system makes exception handling a first-class member of the IR. It + adds two new instructions:</p> + <ul> -<!-- -<li></li> ---> + <li><a href="LangRef.html#i_landingpad"><code>landingpad</code></a> — + this instruction defines a landing pad basic block. It contains all of the + information that's needed by the code generator. It's also required to be + the first non-PHI instruction in the landing pad. In addition, a landing + pad may be jumped to only by the unwind edge of an <code>invoke</code> + instruction.</li> + + <li><a href="LangRef.html#i_resume"><code>resume</code></a> — this + instruction causes the current exception to resume traveling up the + stack. It replaces the <code>@llvm.eh.resume</code> intrinsic.</li> </ul> +<p>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, + <code>@llvm.eh.exception</code> and <code>@llvm.eh.selector</code> have been + superceded by the <code>landingpad</code> instruction. Instead of generating + a call to <code>@llvm.eh.exception</code> and <code>@llvm.eh.selector</code>: + +<div class="doc_code"> +<pre> +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))); + +<i>// Add selector clauses to Args.</i> + +// The selector call. +Builder.CreateCall(SlctrIntr, Args, "exc_sel"); +</pre> +</div> + +<p>You should instead generate a <code>landingpad</code> instruction, that + returns an exception object and selector value:</p> + +<div class="doc_code"> +<pre> +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()); +</pre> +</div> + +<p>It's now trivial to add the individual clauses to the <code>landingpad</code> + instruction.</p> + +<div class="doc_code"> +<pre> +<i><b>// Adding a catch clause</b></i> +Constant *TypeInfo = getTypeInfo(); +LPadInst->addClause(TypeInfo); + +<i><b>// Adding a C++ catch-all</b></i> +LPadInst->addClause(Constant::getNullValue(Builder.getInt8PtrTy())); + +<i><b>// Adding a cleanup</b></i> +LPadInst->setCleanup(true); + +<i><b>// Adding a filter clause</b></i> +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)); +</pre> +</div> + +<p>Converting from using the <code>@llvm.eh.resume</code> intrinsic to + the <code>resume</code> instruction is trivial. It takes the exception + pointer and exception selector values returned by + the <code>landingpad</code> instruction:</p> + +<div class="doc_code"> +<pre> +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); +</pre> +</div> + </div> <!--=========================================================================--> |