aboutsummaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-10-17 06:31:58 +0000
committerBill Wendling <isanbard@gmail.com>2011-10-17 06:31:58 +0000
commit40930e0c2d30e8726f2f0b30119ec782f7d7254d (patch)
tree91b05188a1af93ec4438f5d268e633707486b642 /docs
parentbeac60d66fd884604ead751ba6faf8f08bcb4ff4 (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.html111
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> &mdash;
+ 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> &mdash; 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&lt;Value*&gt; 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-&gt;addClause(TypeInfo);
+
+<i><b>// Adding a C++ catch-all</b></i>
+LPadInst-&gt;addClause(Constant::getNullValue(Builder.getInt8PtrTy()));
+
+<i><b>// Adding a cleanup</b></i>
+LPadInst-&gt;setCleanup(true);
+
+<i><b>// Adding a filter clause</b></i>
+std::vector&lt;Constant*&gt; TypeInfos;
+Constant *TypeInfo = getFilterTypeInfo();
+TypeInfos.push_back(Builder.CreateBitCast(TypeInfo, Builder.getInt8PtrTy()));
+
+ArrayType *FilterTy = ArrayType::get(Int8PtrTy, TypeInfos.size());
+LPadInst-&gt;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>
<!--=========================================================================-->