mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-16 14:31:59 +00:00
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
This commit is contained in:
parent
65d1f415c7
commit
bc5f6ddfba
@ -689,12 +689,117 @@ in this section.
|
||||
<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>
|
||||
|
||||
<!--=========================================================================-->
|
||||
|
Loading…
x
Reference in New Issue
Block a user