Add the 'resume' instruction for the new EH rewrite.

This adds the 'resume' instruction class, IR parsing, and bitcode reading and
writing. The 'resume' instruction resumes propagation of an existing (in-flight)
exception whose unwinding was interrupted with a 'landingpad' instruction (to be
added later).


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136589 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2011-07-31 06:30:59 +00:00
parent 6762dc1fb3
commit dccc03b242
24 changed files with 257 additions and 73 deletions

View File

@ -124,6 +124,7 @@
<li><a href="#i_indirectbr">'<tt>indirectbr</tt>' Instruction</a></li>
<li><a href="#i_invoke">'<tt>invoke</tt>' Instruction</a></li>
<li><a href="#i_unwind">'<tt>unwind</tt>' Instruction</a></li>
<li><a href="#i_resume">'<tt>resume</tt>' Instruction</a></li>
<li><a href="#i_unreachable">'<tt>unreachable</tt>' Instruction</a></li>
</ol>
</li>
@ -3023,13 +3024,14 @@ should not be exposed to source languages.</p>
control flow, not values (the one exception being the
'<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p>
<p>There are seven different terminator instructions: the
<p>There are eight different terminator instructions: the
'<a href="#i_ret"><tt>ret</tt></a>' instruction, the
'<a href="#i_br"><tt>br</tt></a>' instruction, the
'<a href="#i_switch"><tt>switch</tt></a>' instruction, the
'<a href="#i_indirectbr">'<tt>indirectbr</tt></a>' Instruction, the
'<a href="#i_invoke"><tt>invoke</tt></a>' instruction, the
'<a href="#i_unwind"><tt>unwind</tt></a>' instruction, and the
'<a href="#i_unwind"><tt>unwind</tt></a>' instruction, the
'<a href="#i_resume"><tt>resume</tt></a>' instruction, and the
'<a href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p>
<!-- _______________________________________________________________________ -->
@ -3348,6 +3350,39 @@ that the invoke/unwind semantics are likely to change in future versions.</p>
<p>Note that the code generator does not yet completely support unwind, and
that the invoke/unwind semantics are likely to change in future versions.</p>
</div>
<!-- _______________________________________________________________________ -->
<h4>
<a name="i_resume">'<tt>resume</tt>' Instruction</a>
</h4>
<div>
<h5>Syntax:</h5>
<pre>
resume &lt;type&gt; &lt;value&gt;
</pre>
<h5>Overview:</h5>
<p>The '<tt>resume</tt>' instruction is a terminator instruction that has no
successors.</p>
<h5>Arguments:</h5>
<p>The '<tt>resume</tt>' instruction's argument must have the same type as the
result of any '<tt>landingpad</tt>' instruction in the same function.</p>
<h5>Semantics:</h5>
<p>The '<tt>resume</tt>' instruction resumes propagation of an existing
(in-flight) exception whose unwinding was interrupted with
a landingpad instruction.</p>
<h5>Example:</h5>
<pre>
resume { i8*, i32 } %exn
</pre>
</div>
<!-- _______________________________________________________________________ -->

View File

@ -188,7 +188,10 @@ typedef enum {
/* Atomic operators */
LLVMFence = 55,
LLVMAtomicCmpXchg = 56,
LLVMAtomicRMW = 57
LLVMAtomicRMW = 57,
/* Exception Handling Operators */
LLVMResume = 58
} LLVMOpcode;
@ -477,6 +480,7 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(SwitchInst) \
macro(UnreachableInst) \
macro(UnwindInst) \
macro(ResumeInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \
@ -825,6 +829,7 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn,
LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch,
const char *Name);
LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef);
LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn);
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef);
/* Add a case to the switch instruction */

View File

@ -304,9 +304,10 @@ namespace bitc {
FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope]
FUNC_CODE_INST_CMPXCHG = 37, // CMPXCHG: [ptrty,ptr,cmp,new, align, vol,
// ordering, synchscope]
FUNC_CODE_INST_ATOMICRMW = 38 // ATOMICRMW: [ptrty,ptr,val, operation,
FUNC_CODE_INST_ATOMICRMW = 38, // ATOMICRMW: [ptrty,ptr,val, operation,
// align, vol,
// ordering, synchscope]
FUNC_CODE_INST_RESUME = 39 // RESUME: [opval]
};
} // End bitc namespace
} // End llvm namespace

View File

@ -100,79 +100,79 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst)
HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst)
HANDLE_TERM_INST ( 5, Invoke , InvokeInst)
HANDLE_TERM_INST ( 6, Unwind , UnwindInst)
HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst)
LAST_TERM_INST ( 7)
HANDLE_TERM_INST ( 7, Resume , ResumeInst)
HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst)
LAST_TERM_INST ( 8)
// Standard binary operators...
FIRST_BINARY_INST( 8)
HANDLE_BINARY_INST( 8, Add , BinaryOperator)
HANDLE_BINARY_INST( 9, FAdd , BinaryOperator)
HANDLE_BINARY_INST(10, Sub , BinaryOperator)
HANDLE_BINARY_INST(11, FSub , BinaryOperator)
HANDLE_BINARY_INST(12, Mul , BinaryOperator)
HANDLE_BINARY_INST(13, FMul , BinaryOperator)
HANDLE_BINARY_INST(14, UDiv , BinaryOperator)
HANDLE_BINARY_INST(15, SDiv , BinaryOperator)
HANDLE_BINARY_INST(16, FDiv , BinaryOperator)
HANDLE_BINARY_INST(17, URem , BinaryOperator)
HANDLE_BINARY_INST(18, SRem , BinaryOperator)
HANDLE_BINARY_INST(19, FRem , BinaryOperator)
FIRST_BINARY_INST( 9)
HANDLE_BINARY_INST( 9, Add , BinaryOperator)
HANDLE_BINARY_INST(10, FAdd , BinaryOperator)
HANDLE_BINARY_INST(11, Sub , BinaryOperator)
HANDLE_BINARY_INST(12, FSub , BinaryOperator)
HANDLE_BINARY_INST(13, Mul , BinaryOperator)
HANDLE_BINARY_INST(14, FMul , BinaryOperator)
HANDLE_BINARY_INST(15, UDiv , BinaryOperator)
HANDLE_BINARY_INST(16, SDiv , BinaryOperator)
HANDLE_BINARY_INST(17, FDiv , BinaryOperator)
HANDLE_BINARY_INST(18, URem , BinaryOperator)
HANDLE_BINARY_INST(19, SRem , BinaryOperator)
HANDLE_BINARY_INST(20, FRem , BinaryOperator)
// Logical operators (integer operands)
HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(23, And , BinaryOperator)
HANDLE_BINARY_INST(24, Or , BinaryOperator)
HANDLE_BINARY_INST(25, Xor , BinaryOperator)
LAST_BINARY_INST(25)
HANDLE_BINARY_INST(21, Shl , BinaryOperator) // Shift left (logical)
HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical)
HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic)
HANDLE_BINARY_INST(24, And , BinaryOperator)
HANDLE_BINARY_INST(25, Or , BinaryOperator)
HANDLE_BINARY_INST(26, Xor , BinaryOperator)
LAST_BINARY_INST(26)
// Memory operators...
FIRST_MEMORY_INST(26)
HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(28, Store , StoreInst )
HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst)
HANDLE_MEMORY_INST(30, Fence , FenceInst )
HANDLE_MEMORY_INST(31, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(32, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(32)
FIRST_MEMORY_INST(27)
HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management
HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs
HANDLE_MEMORY_INST(29, Store , StoreInst )
HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst)
HANDLE_MEMORY_INST(31, Fence , FenceInst )
HANDLE_MEMORY_INST(32, AtomicCmpXchg , AtomicCmpXchgInst )
HANDLE_MEMORY_INST(33, AtomicRMW , AtomicRMWInst )
LAST_MEMORY_INST(33)
// Cast operators ...
// NOTE: The order matters here because CastInst::isEliminableCastPair
// NOTE: (see Instructions.cpp) encodes a table based on this ordering.
FIRST_CAST_INST(33)
HANDLE_CAST_INST(33, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(34, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(35, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(36, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(37, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(38, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(39, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(40, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(41, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(42, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(43, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(44, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(44)
FIRST_CAST_INST(34)
HANDLE_CAST_INST(34, Trunc , TruncInst ) // Truncate integers
HANDLE_CAST_INST(35, ZExt , ZExtInst ) // Zero extend integers
HANDLE_CAST_INST(36, SExt , SExtInst ) // Sign extend integers
HANDLE_CAST_INST(37, FPToUI , FPToUIInst ) // floating point -> UInt
HANDLE_CAST_INST(38, FPToSI , FPToSIInst ) // floating point -> SInt
HANDLE_CAST_INST(39, UIToFP , UIToFPInst ) // UInt -> floating point
HANDLE_CAST_INST(40, SIToFP , SIToFPInst ) // SInt -> floating point
HANDLE_CAST_INST(41, FPTrunc , FPTruncInst ) // Truncate floating point
HANDLE_CAST_INST(42, FPExt , FPExtInst ) // Extend floating point
HANDLE_CAST_INST(43, PtrToInt, PtrToIntInst) // Pointer -> Integer
HANDLE_CAST_INST(44, IntToPtr, IntToPtrInst) // Integer -> Pointer
HANDLE_CAST_INST(45, BitCast , BitCastInst ) // Type cast
LAST_CAST_INST(45)
// Other operators...
FIRST_OTHER_INST(45)
HANDLE_OTHER_INST(45, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(46, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(47, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(48, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(49, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(50, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(51, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(52, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(53, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate
LAST_OTHER_INST(57)
FIRST_OTHER_INST(46)
HANDLE_OTHER_INST(46, ICmp , ICmpInst ) // Integer comparison instruction
HANDLE_OTHER_INST(47, FCmp , FCmpInst ) // Floating point comparison instr.
HANDLE_OTHER_INST(48, PHI , PHINode ) // PHI node instruction
HANDLE_OTHER_INST(49, Call , CallInst ) // Call a function
HANDLE_OTHER_INST(50, Select , SelectInst ) // select instruction
HANDLE_OTHER_INST(51, UserOp1, Instruction) // May be used internally in a pass
HANDLE_OTHER_INST(52, UserOp2, Instruction) // Internal to passes only
HANDLE_OTHER_INST(53, VAArg , VAArgInst ) // vaarg instruction
HANDLE_OTHER_INST(54, ExtractElement, ExtractElementInst)// extract from vector
HANDLE_OTHER_INST(55, InsertElement, InsertElementInst) // insert into vector
HANDLE_OTHER_INST(56, ShuffleVector, ShuffleVectorInst) // shuffle two vectors.
HANDLE_OTHER_INST(57, ExtractValue, ExtractValueInst)// extract from aggregate
HANDLE_OTHER_INST(58, InsertValue, InsertValueInst) // insert into aggregate
LAST_OTHER_INST(58)
#undef FIRST_TERM_INST
#undef HANDLE_TERM_INST

View File

@ -2715,6 +2715,57 @@ private:
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
};
//===----------------------------------------------------------------------===//
// ResumeInst Class
//===----------------------------------------------------------------------===//
//===---------------------------------------------------------------------------
/// ResumeInst - Resume the propagation of an exception.
///
class ResumeInst : public TerminatorInst {
ResumeInst(const ResumeInst &RI);
explicit ResumeInst(Value *Exn, Instruction *InsertBefore=0);
ResumeInst(Value *Exn, BasicBlock *InsertAtEnd);
protected:
virtual ResumeInst *clone_impl() const;
public:
static ResumeInst *Create(Value *Exn, Instruction *InsertBefore = 0) {
return new(1) ResumeInst(Exn, InsertBefore);
}
static ResumeInst *Create(Value *Exn, BasicBlock *InsertAtEnd) {
return new(1) ResumeInst(Exn, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Convenience accessor.
Value *getValue() const { return Op<0>(); }
unsigned getNumSuccessors() const { return 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const ResumeInst *) { return true; }
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::Resume;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
virtual BasicBlock *getSuccessorV(unsigned idx) const;
virtual unsigned getNumSuccessorsV() const;
virtual void setSuccessorV(unsigned idx, BasicBlock *B);
};
template <>
struct OperandTraits<ResumeInst> :
public FixedNumOperandTraits<ResumeInst, 1> {
};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
//===----------------------------------------------------------------------===//
// UnreachableInst Class
//===----------------------------------------------------------------------===//

View File

@ -479,6 +479,10 @@ public:
return Insert(new UnwindInst(Context));
}
ResumeInst *CreateResume(Value *Exn) {
return Insert(ResumeInst::Create(Exn));
}
UnreachableInst *CreateUnreachable() {
return Insert(new UnreachableInst(Context));
}

View File

@ -163,6 +163,7 @@ public:
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);}
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}

View File

@ -636,6 +636,7 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(switch, Switch);
INSTKEYWORD(indirectbr, IndirectBr);
INSTKEYWORD(invoke, Invoke);
INSTKEYWORD(resume, Resume);
INSTKEYWORD(unwind, Unwind);
INSTKEYWORD(unreachable, Unreachable);

View File

@ -2885,6 +2885,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_switch: return ParseSwitch(Inst, PFS);
case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS);
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
case lltok::kw_resume: return ParseResume(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
@ -3253,7 +3254,18 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
/// ParseResume
/// ::= 'resume' TypeAndValue
bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
Value *Exn; LocTy ExnLoc;
LocTy Loc = Lex.getLoc();
if (ParseTypeAndValue(Exn, ExnLoc, PFS))
return true;
ResumeInst *RI = ResumeInst::Create(Exn);
Inst = RI;
return false;
}
//===----------------------------------------------------------------------===//
// Binary Operators.

View File

@ -347,6 +347,7 @@ namespace llvm {
bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS);
bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS);
bool ParseResume(Instruction *&Inst, PerFunctionState &PFS);
bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc,
unsigned OperandType);

View File

@ -124,7 +124,7 @@ namespace lltok {
kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast,
kw_select, kw_va_arg,
kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind,
kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume,
kw_unreachable,
kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw,

View File

@ -2508,6 +2508,14 @@ bool BitcodeReader::ParseFunctionBody(Function *F) {
cast<InvokeInst>(I)->setAttributes(PAL);
break;
}
case bitc::FUNC_CODE_INST_RESUME: { // RESUME: [opval]
unsigned Idx = 0;
Value *Val = 0;
if (getValueTypePair(Record, Idx, NextValueNo, Val))
return Error("Invalid RESUME record");
I = ResumeInst::Create(Val);
break;
}
case bitc::FUNC_CODE_INST_UNWIND: // UNWIND
I = new UnwindInst(Context);
InstructionList.push_back(I);

View File

@ -1143,6 +1143,10 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
}
break;
}
case Instruction::Resume:
Code = bitc::FUNC_CODE_INST_RESUME;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
break;
case Instruction::Unwind:
Code = bitc::FUNC_CODE_INST_UNWIND;
break;

View File

@ -1810,6 +1810,10 @@ void SelectionDAGBuilder::visitInvoke(const InvokeInst &I) {
void SelectionDAGBuilder::visitUnwind(const UnwindInst &I) {
}
void SelectionDAGBuilder::visitResume(const ResumeInst &RI) {
llvm_unreachable("SelectionDAGBuilder shouldn't visit resume instructions!");
}
/// handleSmallSwitchCaseRange - Emit a series of specific tests (suitable for
/// small case ranges).
bool SelectionDAGBuilder::handleSmallSwitchRange(CaseRec& CR,

View File

@ -467,6 +467,7 @@ public:
private:
// These all get lowered before this pass.
void visitInvoke(const InvokeInst &I);
void visitResume(const ResumeInst &I);
void visitUnwind(const UnwindInst &I);
void visitBinary(const User &I, unsigned OpCode);

View File

@ -113,9 +113,11 @@ namespace {
while (StateBB != StateE) {
BasicBlock *CurBB = StateBB++;
// Branches and invokes do not escape, only unwind and return do.
// Branches and invokes do not escape, only unwind, resume, and return
// do.
TerminatorInst *TI = CurBB->getTerminator();
if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI))
if (!isa<UnwindInst>(TI) && !isa<ReturnInst>(TI) &&
!isa<ResumeInst>(TI))
continue;
Builder.SetInsertPoint(TI->getParent(), TI);

View File

@ -288,10 +288,12 @@ namespace {
void visitInvokeInst(InvokeInst &I) {
llvm_unreachable("Lowerinvoke pass didn't work!");
}
void visitUnwindInst(UnwindInst &I) {
llvm_unreachable("Lowerinvoke pass didn't work!");
}
void visitResumeInst(ResumeInst &I) {
llvm_unreachable("DwarfEHPrepare pass didn't work!");
}
void visitUnreachableInst(UnreachableInst &I);
void visitPHINode(PHINode &I);

View File

@ -1064,6 +1064,11 @@ void CppWriter::printInstruction(const Instruction *I,
}
break;
}
case Instruction::Resume: {
Out << "ResumeInst::Create(mod->getContext(), " << opNames[0]
<< ", " << bbname << ");";
break;
}
case Instruction::Invoke: {
const InvokeInst* inv = cast<InvokeInst>(I);
Out << "std::vector<Value*> " << iName << "_params;";

View File

@ -2506,7 +2506,7 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
CallStack.pop_back(); // return from fn.
return true; // We succeeded at evaluating this ctor!
} else {
// invoke, unwind, unreachable.
// invoke, unwind, resume, unreachable.
return false; // Cannot handle this terminator.
}

View File

@ -732,9 +732,11 @@ Instruction *InstCombiner::visitCallInst(CallInst &CI) {
}
}
// If the stack restore is in a return/unwind block and if there are no
// allocas or calls between the restore and the return, nuke the restore.
if (!CannotRemove && (isa<ReturnInst>(TI) || isa<UnwindInst>(TI)))
// If the stack restore is in a return, resume, or unwind block and if there
// are no allocas or calls between the restore and the return, nuke the
// restore.
if (!CannotRemove && (isa<ReturnInst>(TI) || isa<ResumeInst>(TI) ||
isa<UnwindInst>(TI)))
return EraseInstFromFunction(CI);
break;
}

View File

@ -528,6 +528,7 @@ private:
visitTerminatorInst(II);
}
void visitCallSite (CallSite CS);
void visitResumeInst (TerminatorInst &I) { /*returns void*/ }
void visitUnwindInst (TerminatorInst &I) { /*returns void*/ }
void visitUnreachableInst(TerminatorInst &I) { /*returns void*/ }
void visitFenceInst (FenceInst &I) { /*returns void*/ }

View File

@ -1687,6 +1687,10 @@ LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef B) {
return wrap(unwrap(B)->CreateUnwind());
}
LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) {
return wrap(unwrap(B)->CreateResume(unwrap(Exn)));
}
LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef B) {
return wrap(unwrap(B)->CreateUnreachable());
}

View File

@ -101,6 +101,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Switch: return "switch";
case IndirectBr: return "indirectbr";
case Invoke: return "invoke";
case Resume: return "resume";
case Unwind: return "unwind";
case Unreachable: return "unreachable";

View File

@ -573,6 +573,41 @@ BasicBlock *UnwindInst::getSuccessorV(unsigned idx) const {
return 0;
}
//===----------------------------------------------------------------------===//
// ResumeInst Implementation
//===----------------------------------------------------------------------===//
ResumeInst::ResumeInst(const ResumeInst &RI)
: TerminatorInst(Type::getVoidTy(RI.getContext()), Instruction::Resume,
OperandTraits<ResumeInst>::op_begin(this), 1) {
Op<0>() = RI.Op<0>();
}
ResumeInst::ResumeInst(Value *Exn, Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume,
OperandTraits<ResumeInst>::op_begin(this), 1, InsertBefore) {
Op<0>() = Exn;
}
ResumeInst::ResumeInst(Value *Exn, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(Exn->getContext()), Instruction::Resume,
OperandTraits<ResumeInst>::op_begin(this), 1, InsertAtEnd) {
Op<0>() = Exn;
}
unsigned ResumeInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void ResumeInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
llvm_unreachable("ResumeInst has no successors!");
}
BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const {
llvm_unreachable("ResumeInst has no successors!");
return 0;
}
//===----------------------------------------------------------------------===//
// UnreachableInst Implementation
//===----------------------------------------------------------------------===//
@ -3254,6 +3289,10 @@ InvokeInst *InvokeInst::clone_impl() const {
return new(getNumOperands()) InvokeInst(*this);
}
ResumeInst *ResumeInst::clone_impl() const {
return new(1) ResumeInst(*this);
}
UnwindInst *UnwindInst::clone_impl() const {
LLVMContext &Context = getContext();
return new UnwindInst(Context);