Revert the new EH instructions

This reverts commits r241888-r241891, I didn't mean to commit them.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@241893 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
David Majnemer 2015-07-10 07:15:17 +00:00
parent d09a1e42ca
commit eddf9e2057
35 changed files with 93 additions and 2129 deletions

View File

@ -4727,12 +4727,7 @@ control flow, not values (the one exception being the
The terminator instructions are: ':ref:`ret <i_ret>`',
':ref:`br <i_br>`', ':ref:`switch <i_switch>`',
':ref:`indirectbr <i_indirectbr>`', ':ref:`invoke <i_invoke>`',
':ref:`resume <i_resume>`', ':ref:`catchblock <i_catchblock>`',
':ref:`catchendblock <i_catchendblock>`',
':ref:`catchret <i_catchret>`',
':ref:`cleanupret <i_cleanupret>`',
':ref:`terminateblock <i_terminateblock>`',
and ':ref:`unreachable <i_unreachable>`'.
':ref:`resume <i_resume>`', and ':ref:`unreachable <i_unreachable>`'.
.. _i_ret:
@ -5086,294 +5081,6 @@ Example:
resume { i8*, i32 } %exn
.. _i_catchblock:
'``catchblock``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
<resultval> = catchblock <resultty> [<args>*]
to label <normal label> unwind label <exception label>
Overview:
"""""""""
The '``catchblock``' instruction is used by `LLVM's exception handling
system <ExceptionHandling.html#overview>`_ to specify that a basic block
is a catch block --- one where a personality routine attempts to transfer
control to catch an exception.
The ``args`` correspond to whatever information the personality
routine requires to know if this is an appropriate place to catch the
exception. Control is tranfered to the ``exception`` label if the
``catchblock`` is not an appropriate handler for the in-flight exception.
The ``normal`` label should contain the code found in the ``catch``
portion of a ``try``/``catch`` sequence. It defines values supplied by
the :ref:`personality function <personalityfn>` upon re-entry to the
function. The ``resultval`` has the type ``resultty``.
Arguments:
""""""""""
The instruction takes a list of arbitrary values which are interpreted
by the :ref:`personality function <personalityfn>`.
The ``catchblock`` must be provided a ``normal`` label to transfer control
to if the ``catchblock`` matches the exception and an ``exception``
label to transfer control to if it doesn't.
Semantics:
""""""""""
The '``catchblock``' instruction defines the values which are set by the
:ref:`personality function <personalityfn>` upon re-entry to the function, and
therefore the "result type" of the ``catchblock`` instruction. As with
calling conventions, how the personality function results are
represented in LLVM IR is target specific.
When the call stack is being unwound due to an exception being thrown,
the exception is compared against the ``args``. If it doesn't match,
then control is transfered to the ``exception`` basic block.
The ``catchblock`` instruction has several restrictions:
- A catch block is a basic block which is the unwind destination of
an exceptional instruction.
- A catch block must have a '``catchblock``' instruction as its
first non-PHI instruction.
- A catch block's ``exception`` edge must refer to a catch block or a
catch-end block.
- There can be only one '``catchblock``' instruction within the
catch block.
- A basic block that is not a catch block may not include a
'``catchblock``' instruction.
Example:
""""""""
.. code-block:: llvm
;; A catch block which can catch an integer.
%res = catchblock { i8*, i32 } [i8** @_ZTIi]
to label %int.handler unwind label %terminate
.. _i_catchendblock:
'``catchendblock``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
catchendblock unwind label <nextaction>
catchendblock unwind to caller
Overview:
"""""""""
The '``catchendblock``' instruction is used by `LLVM's exception handling
system <ExceptionHandling.html#overview>`_ to communicate to the
:ref:`personality function <personalityfn>` which invokes are associated
with a chain of :ref:`catchblock <i_catchblock>` instructions.
The ``nextaction`` label indicates where control should transfer to if
none of the ``catchblock`` instructions are suitable for catching the
in-flight exception.
If a ``nextaction`` label is not present, the instruction unwinds out of
its parent function. The
:ref:`personality function <personalityfn>` will continue processing
exception handling actions in the caller.
Arguments:
""""""""""
The instruction optionally takes a label, ``nextaction``, indicating
where control should transfer to if none of the preceding
``catchblock`` instructions are suitable for the in-flight exception.
Semantics:
""""""""""
When the call stack is being unwound due to an exception being thrown
and none of the constituent ``catchblock`` instructions match, then
control is transfered to ``nextaction`` if it is present. If it is not
present, control is transfered to the caller.
The ``catchendblock`` instruction has several restrictions:
- A catch-end block is a basic block which is the unwind destination of
an exceptional instruction.
- A catch-end block must have a '``catchendblock``' instruction as its
first non-PHI instruction.
- There can be only one '``catchendblock``' instruction within the
catch block.
- A basic block that is not a catch-end block may not include a
'``catchendblock``' instruction.
- Exactly one catch block may unwind to a ``catchendblock``.
Example:
""""""""
.. code-block:: llvm
catchendblock unwind label %terminate
catchendblock unwind to caller
.. _i_catchret:
'``catchret``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
catchret label <normal>
Overview:
"""""""""
The '``catchret``' instruction is a terminator instruction that has a
single successor.
Arguments:
""""""""""
The '``catchret``' instruction requires one argument which specifies
where control will transfer to next.
Semantics:
""""""""""
The '``catchret``' instruction ends the existing (in-flight) exception
whose unwinding was interrupted with a
:ref:`catchblock <i_catchblock>` instruction.
The :ref:`personality function <personalityfn>` gets a chance to execute
arbitrary code to, for example, run a C++ destructor.
Control then transfers to ``normal``.
Example:
""""""""
.. code-block:: llvm
catchret label %continue
.. _i_cleanupret:
'``cleanupret``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
cleanupret <type> <value> unwind label <continue>
cleanupret <type> <value> unwind to caller
Overview:
"""""""""
The '``cleanupret``' instruction is a terminator instruction that has
an optional successor.
Arguments:
""""""""""
The '``cleanupret``' instruction requires one argument, which must have the
same type as the result of any '``cleanupblock``' instruction in the same
function. It also has an optional successor, ``continue``.
Semantics:
""""""""""
The '``cleanupret``' instruction indicates to the
:ref:`personality function <personalityfn>` that one
:ref:`cleanupblock <i_cleanupblock>` it transferred control to has ended.
It transfers control to ``continue`` or unwinds out of the function.
Example:
""""""""
.. code-block:: llvm
cleanupret void unwind to caller
cleanupret { i8*, i32 } %exn unwind label %continue
.. _i_terminateblock:
'``terminateblock``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
terminateblock [<args>*] unwind label <exception label>
terminateblock [<args>*] unwind to caller
Overview:
"""""""""
The '``terminateblock``' instruction is used by `LLVM's exception handling
system <ExceptionHandling.html#overview>`_ to specify that a basic block
is a terminate block --- one where a personality routine may decide to
terminate the program.
The ``args`` correspond to whatever information the personality
routine requires to know if this is an appropriate place to terminate the
program. Control is transferred to the ``exception`` label if the
personality routine decides not to terminate the program for the
in-flight exception.
Arguments:
""""""""""
The instruction takes a list of arbitrary values which are interpreted
by the :ref:`personality function <personalityfn>`.
The ``terminateblock`` may be given an ``exception`` label to
transfer control to if the in-flight exception matches the ``args``.
Semantics:
""""""""""
When the call stack is being unwound due to an exception being thrown,
the exception is compared against the ``args``. If it matches,
then control is transfered to the ``exception`` basic block. Otherwise,
the program is terminated via personality-specific means. Typically,
the first argument to ``terminateblock`` specifies what function the
personality should defer to in order to terminate the program.
The ``terminateblock`` instruction has several restrictions:
- A terminate block is a basic block which is the unwind destination of
an exceptional instruction.
- A terminate block must have a '``terminateblock``' instruction as its
first non-PHI instruction.
- There can be only one '``terminateblock``' instruction within the
terminate block.
- A basic block that is not a terminate block may not include a
'``terminateblock``' instruction.
Example:
""""""""
.. code-block:: llvm
;; A terminate block which only permits integers.
terminateblock [i8** @_ZTIi] unwind label %continue
.. _i_unreachable:
'``unreachable``' Instruction
@ -8322,67 +8029,6 @@ Example:
catch i8** @_ZTIi
filter [1 x i8**] [@_ZTId]
.. _i_cleanupblock:
'``cleanupblock``' Instruction
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Syntax:
"""""""
::
<resultval> = cleanupblock <resultty> [<args>*]
Overview:
"""""""""
The '``cleanupblock``' instruction is used by `LLVM's exception handling
system <ExceptionHandling.html#overview>`_ to specify that a basic block
is a cleanup block --- one where a personality routine attempts to
transfer control to run cleanup actions.
The ``args`` correspond to whatever additional
information the :ref:`personality function <personalityfn>` requires to
execute the cleanup.
The ``resultval`` has the type ``resultty``.
Arguments:
""""""""""
The instruction takes a list of arbitrary values which are interpreted
by the :ref:`personality function <personalityfn>`.
Semantics:
""""""""""
The '``cleanupblock``' instruction defines the values which are set by the
:ref:`personality function <personalityfn>` upon re-entry to the function, and
therefore the "result type" of the ``cleanupblock`` instruction. As with
calling conventions, how the personality function results are
represented in LLVM IR is target specific.
When the call stack is being unwound due to an exception being thrown,
the :ref:`personality function <personalityfn>` transfers control to the
``cleanupblock`` with the aid of the personality-specific arguments.
The ``cleanupblock`` instruction has several restrictions:
- A cleanup block is a basic block which is the unwind destination of
an exceptional instruction.
- A cleanup block must have a '``cleanupblock``' instruction as its
first non-PHI instruction.
- There can be only one '``cleanupblock``' instruction within the
cleanup block.
- A basic block that is not a cleanup block may not include a
'``cleanupblock``' instruction.
Example:
""""""""
.. code-block:: llvm
%res = cleanupblock { i8*, i32 } [label %nextaction]
.. _intrinsics:
Intrinsic Functions

View File

@ -248,13 +248,7 @@ typedef enum {
/* Exception Handling Operators */
LLVMResume = 58,
LLVMLandingPad = 59,
LLVMCleanupRet = 61,
LLVMCatchRet = 62,
LLVMCatchBlock = 63,
LLVMTerminateBlock = 64,
LLVMCleanupBlock = 65,
LLVMCatchEndBlock = 66
LLVMLandingPad = 59
} LLVMOpcode;
@ -1209,7 +1203,6 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(InsertElementInst) \
macro(InsertValueInst) \
macro(LandingPadInst) \
macro(CleanupBlockInst) \
macro(PHINode) \
macro(SelectInst) \
macro(ShuffleVectorInst) \
@ -1222,11 +1215,6 @@ LLVMTypeRef LLVMX86MMXType(void);
macro(SwitchInst) \
macro(UnreachableInst) \
macro(ResumeInst) \
macro(CleanupReturnInst) \
macro(CatchReturnInst) \
macro(CatchBlockInst) \
macro(TerminateBlockInst) \
macro(CatchEndBlockInst) \
macro(UnaryInstruction) \
macro(AllocaInst) \
macro(CastInst) \

View File

@ -354,12 +354,6 @@ namespace bitc {
FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align,
// vol,ordering,synchscope]
FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [] or [val] or [bb#] or [val,bb#]
FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [bb#]
FUNC_CODE_INST_CATCHBLOCK = 50, // CATCHBLOCK: [ty,val,val,num,args...]
FUNC_CODE_INST_TERMINATEBLOCK = 51, // TERMINATEBLOCK: [bb#,num,args...]
FUNC_CODE_INST_CLEANUPBLOCK = 52, // CLEANUPBLOCK: [num,args...]
FUNC_CODE_INST_CATCHENDBLOCK = 53, // CATCHENDBLOCK: [] or [bb#]
};
enum UseListCodes {

View File

@ -309,9 +309,6 @@ public:
/// basic block \p New instead of to it.
void replaceSuccessorsPhiUsesWith(BasicBlock *New);
/// \brief Return true if this basic block is an exception handling block.
bool isEHBlock() const { return getFirstNonPHI()->isEHBlock(); }
/// \brief Return true if this basic block is a landing pad.
///
/// Being a ``landing pad'' means that the basic block is the destination of

View File

@ -672,38 +672,6 @@ public:
return Insert(ResumeInst::Create(Exn));
}
CleanupReturnInst *CreateCleanupRet(BasicBlock *UnwindBB = nullptr,
Value *RetVal = nullptr) {
return Insert(CleanupReturnInst::Create(Context, RetVal, UnwindBB));
}
CatchBlockInst *CreateCatchBlock(Type *Ty, BasicBlock *NormalDest,
BasicBlock *UnwindDest,
ArrayRef<Value *> Args,
const Twine &Name = "") {
return Insert(CatchBlockInst::Create(Ty, NormalDest, UnwindDest, Args),
Name);
}
CatchEndBlockInst *CreateCatchEndBlock(BasicBlock *UnwindBB = nullptr) {
return Insert(CatchEndBlockInst::Create(Context, UnwindBB));
}
TerminateBlockInst *CreateTerminateBlock(BasicBlock *NormalDest = nullptr,
ArrayRef<Value *> Args = {},
const Twine &Name = "") {
return Insert(TerminateBlockInst::Create(Context, NormalDest, Args), Name);
}
CleanupBlockInst *CreateCleanupBlock(Type *Ty, ArrayRef<Value *> Args,
const Twine &Name = "") {
return Insert(CleanupBlockInst::Create(Ty, Args), Name);
}
CatchReturnInst *CreateCatchRet(BasicBlock *BB) {
return Insert(CatchReturnInst::Create(BB));
}
UnreachableInst *CreateUnreachable() {
return Insert(new UnreachableInst(Context));
}

View File

@ -169,11 +169,6 @@ public:
RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);}
RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);}
RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);}
RetTy visitCleanupReturnInst(CleanupReturnInst &I) { DELEGATE(TerminatorInst);}
RetTy visitCatchReturnInst(CatchReturnInst &I) { DELEGATE(TerminatorInst);}
RetTy visitCatchBlockInst(CatchBlockInst &I) { DELEGATE(TerminatorInst);}
RetTy visitCatchEndBlockInst(CatchEndBlockInst &I) { DELEGATE(TerminatorInst); }
RetTy visitTerminateBlockInst(TerminateBlockInst &I) { DELEGATE(TerminatorInst);}
RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);}
RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);}
RetTy visitAllocaInst(AllocaInst &I) { DELEGATE(UnaryInstruction);}
@ -205,7 +200,6 @@ public:
RetTy visitExtractValueInst(ExtractValueInst &I){ DELEGATE(UnaryInstruction);}
RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); }
RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); }
RetTy visitCleanupBlockInst(CleanupBlockInst &I) { DELEGATE(Instruction); }
// Handle the special instrinsic instruction classes.
RetTy visitDbgDeclareInst(DbgDeclareInst &I) { DELEGATE(DbgInfoIntrinsic);}

View File

@ -75,22 +75,6 @@ public:
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
// \brief Returns true if this terminator relates to exception handling.
bool isExceptional() const {
switch (getOpcode()) {
case Instruction::CatchBlock:
case Instruction::CatchEndBlock:
case Instruction::CatchRet:
case Instruction::CleanupRet:
case Instruction::Invoke:
case Instruction::Resume:
case Instruction::TerminateBlock:
return true;
default:
return false;
}
}
};

View File

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

View File

@ -388,20 +388,6 @@ public:
return mayWriteToMemory() || mayThrow() || !mayReturn();
}
/// \brief Return true if the instruction is a variety of EH-block.
bool isEHBlock() const {
switch (getOpcode()) {
case Instruction::CatchBlock:
case Instruction::CatchEndBlock:
case Instruction::CleanupBlock:
case Instruction::LandingPad:
case Instruction::TerminateBlock:
return true;
default:
return false;
}
}
/// clone() - Create a copy of 'this' instruction that is identical in all
/// ways except the following:
/// * The instruction has no parent

View File

@ -3551,526 +3551,6 @@ struct OperandTraits<ResumeInst> :
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
//===----------------------------------------------------------------------===//
// CleanupReturnInst Class
//===----------------------------------------------------------------------===//
class CleanupReturnInst : public TerminatorInst {
CleanupReturnInst(const CleanupReturnInst &RI);
private:
void init(Value *RetVal, BasicBlock *UnwindBB);
CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
unsigned Values, Instruction *InsertBefore = nullptr);
CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
unsigned Values, BasicBlock *InsertAtEnd);
int getUnwindLabelOpIdx() const {
assert(hasUnwindDest());
return 0;
}
int getRetValOpIdx() const {
assert(hasReturnValue());
if (hasUnwindDest())
return 1;
return 0;
}
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
CleanupReturnInst *cloneImpl() const;
public:
static CleanupReturnInst *Create(LLVMContext &C,
Value *RetVal = nullptr,
BasicBlock *UnwindBB = nullptr,
Instruction *InsertBefore = nullptr) {
unsigned Values = 0;
if (RetVal)
++Values;
if (UnwindBB)
++Values;
return new (Values)
CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertBefore);
}
static CleanupReturnInst *Create(LLVMContext &C, Value *RetVal,
BasicBlock *UnwindBB,
BasicBlock *InsertAtEnd) {
unsigned Values = 0;
if (RetVal)
++Values;
if (UnwindBB)
++Values;
return new (Values)
CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
bool unwindsToCaller() const { return !hasUnwindDest(); }
bool hasReturnValue() const { return getSubclassDataFromInstruction() & 2; }
/// Convenience accessor. Returns null if there is no return value.
Value *getReturnValue() const {
if (!hasReturnValue())
return nullptr;
return getOperand(getRetValOpIdx());
}
void setReturnValue(Value *RetVal) {
assert(hasReturnValue());
setOperand(getRetValOpIdx(), RetVal);
}
unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
BasicBlock *getUnwindDest() const;
void setUnwindDest(BasicBlock *NewDest);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::CleanupRet);
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
BasicBlock *getSuccessorV(unsigned Idx) const override;
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
};
template <>
struct OperandTraits<CleanupReturnInst>
: public VariadicOperandTraits<CleanupReturnInst> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
//===----------------------------------------------------------------------===//
// CatchEndBlockInst Class
//===----------------------------------------------------------------------===//
class CatchEndBlockInst : public TerminatorInst {
CatchEndBlockInst(const CatchEndBlockInst &RI);
private:
void init(BasicBlock *UnwindBB);
CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
Instruction *InsertBefore = nullptr);
CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values,
BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
CatchEndBlockInst *cloneImpl() const;
public:
static CatchEndBlockInst *Create(LLVMContext &C,
BasicBlock *UnwindBB = nullptr,
Instruction *InsertBefore = nullptr) {
unsigned Values = UnwindBB ? 1 : 0;
return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertBefore);
}
static CatchEndBlockInst *Create(LLVMContext &C, BasicBlock *UnwindBB,
BasicBlock *InsertAtEnd) {
unsigned Values = UnwindBB ? 1 : 0;
return new (Values) CatchEndBlockInst(C, UnwindBB, Values, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
bool unwindsToCaller() const { return !hasUnwindDest(); }
/// Convenience accessor. Returns null if there is no return value.
unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
void setUnwindDest(BasicBlock *NewDest) {
assert(NewDest);
Op<-1>() = NewDest;
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::CatchEndBlock);
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
BasicBlock *getSuccessorV(unsigned Idx) const override;
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
private:
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
};
template <>
struct OperandTraits<CatchEndBlockInst>
: public VariadicOperandTraits<CatchEndBlockInst> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndBlockInst, Value)
//===----------------------------------------------------------------------===//
// CatchBlockInst Class
//===----------------------------------------------------------------------===//
class CatchBlockInst : public TerminatorInst {
private:
void init(BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, const Twine &NameStr);
CatchBlockInst(const CatchBlockInst &CBI);
explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
unsigned Values, const Twine &NameStr,
Instruction *InsertBefore);
explicit CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
unsigned Values, const Twine &NameStr,
BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
CatchBlockInst *cloneImpl() const;
public:
static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = unsigned(Args.size()) + 2;
return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
Values, NameStr, InsertBefore);
}
static CatchBlockInst *Create(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd) {
unsigned Values = unsigned(Args.size()) + 2;
return new (Values) CatchBlockInst(RetTy, IfNormal, IfException, Args,
Values, NameStr, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// getNumArgOperands - Return the number of catchblock arguments.
///
unsigned getNumArgOperands() const { return getNumOperands() - 2; }
/// getArgOperand/setArgOperand - Return/set the i-th catchblock argument.
///
Value *getArgOperand(unsigned i) const { return getOperand(i); }
void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
/// arg_operands - iteration adapter for range-for loops.
iterator_range<op_iterator> arg_operands() {
return iterator_range<op_iterator>(op_begin(), op_end() - 2);
}
/// arg_operands - iteration adapter for range-for loops.
iterator_range<const_op_iterator> arg_operands() const {
return iterator_range<const_op_iterator>(op_begin(), op_end() - 2);
}
/// \brief Wrappers for getting the \c Use of a catchblock argument.
const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
// get*Dest - Return the destination basic blocks...
BasicBlock *getNormalDest() const { return cast<BasicBlock>(Op<-2>()); }
BasicBlock *getUnwindDest() const { return cast<BasicBlock>(Op<-1>()); }
void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast<Value *>(B); }
void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast<Value *>(B); }
BasicBlock *getSuccessor(unsigned i) const {
assert(i < 2 && "Successor # out of range for catchblock!");
return i == 0 ? getNormalDest() : getUnwindDest();
}
void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
assert(idx < 2 && "Successor # out of range for catchblock!");
*(&Op<-2>() + idx) = reinterpret_cast<Value *>(NewSucc);
}
unsigned getNumSuccessors() const { return 2; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::CatchBlock;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
BasicBlock *getSuccessorV(unsigned idx) const override;
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned idx, BasicBlock *B) override;
};
template <>
struct OperandTraits<CatchBlockInst>
: public VariadicOperandTraits<CatchBlockInst, /*MINARITY=*/2> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchBlockInst, Value)
//===----------------------------------------------------------------------===//
// TerminateBlockInst Class
//===----------------------------------------------------------------------===//
class TerminateBlockInst : public TerminatorInst {
private:
void init(BasicBlock *BB, ArrayRef<Value *> Args, const Twine &NameStr);
TerminateBlockInst(const TerminateBlockInst &TBI);
explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, Instruction *InsertBefore);
explicit TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
TerminateBlockInst *cloneImpl() const;
public:
static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB = nullptr,
ArrayRef<Value *> Args = {},
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
unsigned Values = unsigned(Args.size());
if (BB)
++Values;
return new (Values)
TerminateBlockInst(C, BB, Args, Values, NameStr, InsertBefore);
}
static TerminateBlockInst *Create(LLVMContext &C, BasicBlock *BB,
ArrayRef<Value *> Args,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
unsigned Values = unsigned(Args.size());
if (BB)
++Values;
return new (Values)
TerminateBlockInst(C, BB, Args, Values, NameStr, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
bool unwindsToCaller() const { return !hasUnwindDest(); }
/// getNumArgOperands - Return the number of terminateblock arguments.
///
unsigned getNumArgOperands() const {
unsigned NumOperands = getNumOperands();
if (hasUnwindDest())
return NumOperands - 1;
return NumOperands;
}
/// getArgOperand/setArgOperand - Return/set the i-th terminateblock argument.
///
Value *getArgOperand(unsigned i) const { return getOperand(i); }
void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
const_op_iterator arg_end() const {
if (hasUnwindDest())
return op_end() - 1;
return op_end();
}
op_iterator arg_end() {
if (hasUnwindDest())
return op_end() - 1;
return op_end();
}
/// arg_operands - iteration adapter for range-for loops.
iterator_range<op_iterator> arg_operands() {
return iterator_range<op_iterator>(op_begin(), arg_end());
}
/// arg_operands - iteration adapter for range-for loops.
iterator_range<const_op_iterator> arg_operands() const {
return iterator_range<const_op_iterator>(op_begin(), arg_end());
}
/// \brief Wrappers for getting the \c Use of a terminateblock argument.
const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); }
Use &getArgOperandUse(unsigned i) { return getOperandUse(i); }
// get*Dest - Return the destination basic blocks...
BasicBlock *getUnwindDest() const {
if (!hasUnwindDest())
return nullptr;
return cast<BasicBlock>(Op<-1>());
}
void setUnwindDest(BasicBlock *B) {
assert(B && hasUnwindDest());
Op<-1>() = reinterpret_cast<Value *>(B);
}
unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::TerminateBlock;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
BasicBlock *getSuccessorV(unsigned idx) const override;
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned idx, BasicBlock *B) override;
// Shadow Instruction::setInstructionSubclassData with a private forwarding
// method so that subclasses cannot accidentally use it.
void setInstructionSubclassData(unsigned short D) {
Instruction::setInstructionSubclassData(D);
}
};
template <>
struct OperandTraits<TerminateBlockInst>
: public VariadicOperandTraits<TerminateBlockInst, /*MINARITY=*/1> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminateBlockInst, Value)
//===----------------------------------------------------------------------===//
// CleanupBlockInst Class
//===----------------------------------------------------------------------===//
class CleanupBlockInst : public Instruction {
private:
void init(ArrayRef<Value *> Args, const Twine &NameStr);
CleanupBlockInst(const CleanupBlockInst &TBI);
explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr, Instruction *InsertBefore);
explicit CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr, BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
CleanupBlockInst *cloneImpl() const;
public:
static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr = "",
Instruction *InsertBefore = nullptr) {
return new (Args.size())
CleanupBlockInst(RetTy, Args, NameStr, InsertBefore);
}
static CleanupBlockInst *Create(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr,
BasicBlock *InsertAtEnd) {
return new (Args.size())
CleanupBlockInst(RetTy, Args, NameStr, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return I->getOpcode() == Instruction::CleanupBlock;
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
};
template <>
struct OperandTraits<CleanupBlockInst>
: public VariadicOperandTraits<CleanupBlockInst, /*MINARITY=*/0> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupBlockInst, Value)
//===----------------------------------------------------------------------===//
// CatchReturnInst Class
//===----------------------------------------------------------------------===//
class CatchReturnInst : public TerminatorInst {
CatchReturnInst(const CatchReturnInst &RI);
private:
void init(Value *RetVal, BasicBlock *UnwindBB);
CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore = nullptr);
CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd);
protected:
// Note: Instruction needs to be a friend here to call cloneImpl.
friend class Instruction;
CatchReturnInst *cloneImpl() const;
public:
static CatchReturnInst *Create(BasicBlock *BB,
Instruction *InsertBefore = nullptr) {
return new (1) CatchReturnInst(BB, InsertBefore);
}
static CatchReturnInst *Create(BasicBlock *BB, BasicBlock *InsertAtEnd) {
return new (1) CatchReturnInst(BB, InsertAtEnd);
}
/// Provide fast operand accessors
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// Convenience accessors.
BasicBlock *getSuccessor() const { return cast<BasicBlock>(Op<0>()); }
void setSuccessor(BasicBlock *NewSucc) { Op<0>() = (Value *)NewSucc; }
unsigned getNumSuccessors() const { return 1; }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
return (I->getOpcode() == Instruction::CatchRet);
}
static inline bool classof(const Value *V) {
return isa<Instruction>(V) && classof(cast<Instruction>(V));
}
private:
BasicBlock *getSuccessorV(unsigned Idx) const override;
unsigned getNumSuccessorsV() const override;
void setSuccessorV(unsigned Idx, BasicBlock *B) override;
};
template <>
struct OperandTraits<CatchReturnInst>
: public FixedNumOperandTraits<CatchReturnInst, /*ARITY=*/1> {};
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
//===----------------------------------------------------------------------===//
// UnreachableInst Class
//===----------------------------------------------------------------------===//

View File

@ -156,8 +156,6 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> {
bool visitSwitchInst(SwitchInst &SI);
bool visitIndirectBrInst(IndirectBrInst &IBI);
bool visitResumeInst(ResumeInst &RI);
bool visitCleanupReturnInst(CleanupReturnInst &RI);
bool visitCatchReturnInst(CatchReturnInst &RI);
bool visitUnreachableInst(UnreachableInst &I);
public:
@ -905,18 +903,6 @@ bool CallAnalyzer::visitResumeInst(ResumeInst &RI) {
return false;
}
bool CallAnalyzer::visitCleanupReturnInst(CleanupReturnInst &CRI) {
// FIXME: It's not clear that a single instruction is an accurate model for
// the inline cost of a cleanupret instruction.
return false;
}
bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
// FIXME: It's not clear that a single instruction is an accurate model for
// the inline cost of a cleanupret instruction.
return false;
}
bool CallAnalyzer::visitUnreachableInst(UnreachableInst &I) {
// FIXME: It might be reasonably to discount the cost of instructions leading
// to unreachable as they have the lowest possible impact on both runtime and

View File

@ -524,7 +524,6 @@ lltok::Kind LLLexer::LexIdentifier() {
KEYWORD(undef);
KEYWORD(null);
KEYWORD(to);
KEYWORD(caller);
KEYWORD(tail);
KEYWORD(musttail);
KEYWORD(target);
@ -749,12 +748,6 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(extractvalue, ExtractValue);
INSTKEYWORD(insertvalue, InsertValue);
INSTKEYWORD(landingpad, LandingPad);
INSTKEYWORD(cleanupret, CleanupRet);
INSTKEYWORD(catchret, CatchRet);
INSTKEYWORD(catchblock, CatchBlock);
INSTKEYWORD(terminateblock, TerminateBlock);
INSTKEYWORD(cleanupblock, CleanupBlock);
INSTKEYWORD(catchendblock, CatchEndBlock);
#undef INSTKEYWORD
#define DWKEYWORD(TYPE, TOKEN) \

View File

@ -4489,12 +4489,6 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB,
case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS);
case lltok::kw_invoke: return ParseInvoke(Inst, PFS);
case lltok::kw_resume: return ParseResume(Inst, PFS);
case lltok::kw_cleanupret: return ParseCleanupRet(Inst, PFS);
case lltok::kw_catchret: return ParseCatchRet(Inst, PFS);
case lltok::kw_catchblock: return ParseCatchBlock(Inst, PFS);
case lltok::kw_terminateblock: return ParseTerminateBlock(Inst, PFS);
case lltok::kw_cleanupblock: return ParseCleanupBlock(Inst, PFS);
case lltok::kw_catchendblock: return ParseCatchEndBlock(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
@ -4888,161 +4882,6 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
PerFunctionState &PFS) {
if (ParseToken(lltok::lsquare, "expected '[' in cleanupblock"))
return true;
while (Lex.getKind() != lltok::rsquare) {
// If this isn't the first argument, we need a comma.
if (!Args.empty() &&
ParseToken(lltok::comma, "expected ',' in argument list"))
return true;
// Parse the argument.
LocTy ArgLoc;
Type *ArgTy = nullptr;
if (ParseType(ArgTy, ArgLoc))
return true;
Value *V;
if (ArgTy->isMetadataTy()) {
if (ParseMetadataAsValue(V, PFS))
return true;
} else {
if (ParseValue(ArgTy, V, PFS))
return true;
}
Args.push_back(V);
}
Lex.Lex(); // Lex the ']'.
return false;
}
/// ParseCleanupRet
/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue)
bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
Type *RetTy = nullptr;
Value *RetVal = nullptr;
if (ParseType(RetTy, /*AllowVoid=*/true))
return true;
if (!RetTy->isVoidTy())
if (ParseValue(RetTy, RetVal, PFS))
return true;
if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
return true;
BasicBlock *UnwindBB = nullptr;
if (Lex.getKind() == lltok::kw_to) {
Lex.Lex();
if (ParseToken(lltok::kw_caller, "expected 'caller' in cleanupret"))
return true;
} else {
if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
return true;
}
}
Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB);
return false;
}
/// ParseCatchRet
/// ::= 'catchret' TypeAndValue
bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
BasicBlock *BB;
if (ParseTypeAndBasicBlock(BB, PFS))
return true;
Inst = CatchReturnInst::Create(BB);
return false;
}
/// ParseCatchBlock
/// ::= 'catchblock' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
bool LLParser::ParseCatchBlock(Instruction *&Inst, PerFunctionState &PFS) {
Type *RetType = nullptr;
SmallVector<Value *, 8> Args;
if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
return true;
BasicBlock *NormalBB, *UnwindBB;
if (ParseToken(lltok::kw_to, "expected 'to' in catchblock") ||
ParseTypeAndBasicBlock(NormalBB, PFS) ||
ParseToken(lltok::kw_unwind, "expected 'unwind' in catchblock") ||
ParseTypeAndBasicBlock(UnwindBB, PFS))
return true;
Inst = CatchBlockInst::Create(RetType, NormalBB, UnwindBB, Args);
return false;
}
/// ParseTerminateBlock
/// ::= 'terminateblock' ParamList 'to' TypeAndValue
bool LLParser::ParseTerminateBlock(Instruction *&Inst, PerFunctionState &PFS) {
SmallVector<Value *, 8> Args;
if (ParseExceptionArgs(Args, PFS))
return true;
if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminateblock"))
return true;
BasicBlock *UnwindBB = nullptr;
if (Lex.getKind() == lltok::kw_to) {
Lex.Lex();
if (ParseToken(lltok::kw_caller, "expected 'caller' in terminateblock"))
return true;
} else {
if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
return true;
}
}
Inst = TerminateBlockInst::Create(Context, UnwindBB, Args);
return false;
}
/// ParseCleanupBlock
/// ::= 'cleanupblock' ParamList
bool LLParser::ParseCleanupBlock(Instruction *&Inst, PerFunctionState &PFS) {
Type *RetType = nullptr;
SmallVector<Value *, 8> Args;
if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
return true;
Inst = CleanupBlockInst::Create(RetType, Args);
return false;
}
/// ParseCatchEndBlock
/// ::= 'catchendblock' unwind ('to' 'caller' | TypeAndValue)
bool LLParser::ParseCatchEndBlock(Instruction *&Inst, PerFunctionState &PFS) {
if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendblock"))
return true;
BasicBlock *UnwindBB = nullptr;
if (Lex.getKind() == lltok::kw_to) {
Lex.Lex();
if (Lex.getKind() == lltok::kw_caller) {
Lex.Lex();
} else {
return true;
}
} else {
if (ParseTypeAndBasicBlock(UnwindBB, PFS)) {
return true;
}
}
Inst = CatchEndBlockInst::Create(Context, UnwindBB);
return false;
}
//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//

View File

@ -381,9 +381,6 @@ namespace llvm {
bool IsMustTailCall = false,
bool InVarArgsFunc = false);
bool ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
PerFunctionState &PFS);
// Constant Parsing.
bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr);
bool ParseGlobalValue(Type *Ty, Constant *&V);
@ -444,12 +441,6 @@ namespace llvm {
bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS);
bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS);
bool ParseResume(Instruction *&Inst, PerFunctionState &PFS);
bool ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS);
bool ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS);
bool ParseCatchBlock(Instruction *&Inst, PerFunctionState &PFS);
bool ParseTerminateBlock(Instruction *&Inst, PerFunctionState &PFS);
bool ParseCleanupBlock(Instruction *&Inst, PerFunctionState &PFS);
bool ParseCatchEndBlock(Instruction *&Inst, PerFunctionState &PFS);
bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc,
unsigned OperandType);

View File

@ -51,7 +51,6 @@ namespace lltok {
kw_zeroinitializer,
kw_undef, kw_null,
kw_to,
kw_caller,
kw_tail,
kw_musttail,
kw_target,
@ -177,8 +176,7 @@ namespace lltok {
kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter,
kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_resume,
kw_unreachable, kw_cleanupret, kw_catchret, kw_catchblock,
kw_terminateblock, kw_cleanupblock, kw_catchendblock,
kw_unreachable,
kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw,
kw_getelementptr,

View File

@ -3793,134 +3793,6 @@ std::error_code BitcodeReader::parseFunctionBody(Function *F) {
}
break;
}
// CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#]
case bitc::FUNC_CODE_INST_CLEANUPRET: {
if (Record.size() < 2)
return error("Invalid record");
unsigned Idx = 0;
bool HasReturnValue = !!Record[Idx++];
bool HasUnwindDest = !!Record[Idx++];
Value *RetVal = nullptr;
BasicBlock *UnwindDest = nullptr;
if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal))
return error("Invalid record");
if (HasUnwindDest) {
if (Idx == Record.size())
return error("Invalid record");
UnwindDest = getBasicBlock(Record[Idx++]);
if (!UnwindDest)
return error("Invalid record");
}
if (Record.size() != Idx)
return error("Invalid record");
I = CleanupReturnInst::Create(Context, RetVal, UnwindDest);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#]
if (Record.size() != 1)
return error("Invalid record");
BasicBlock *BB = getBasicBlock(Record[0]);
if (!BB)
return error("Invalid record");
I = CatchReturnInst::Create(BB);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_CATCHBLOCK: { // CATCHBLOCK: [ty,bb#,bb#,num,(ty,val)*]
if (Record.size() < 4)
return error("Invalid record");
unsigned Idx = 0;
Type *Ty = getTypeByID(Record[Idx++]);
if (!Ty)
return error("Invalid record");
BasicBlock *NormalBB = getBasicBlock(Record[Idx++]);
if (!NormalBB)
return error("Invalid record");
BasicBlock *UnwindBB = getBasicBlock(Record[Idx++]);
if (!UnwindBB)
return error("Invalid record");
unsigned NumArgOperands = Record[Idx++];
SmallVector<Value *, 2> Args;
for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
Value *Val;
if (getValueTypePair(Record, Idx, NextValueNo, Val))
return error("Invalid record");
Args.push_back(Val);
}
if (Record.size() != Idx)
return error("Invalid record");
I = CatchBlockInst::Create(Ty, NormalBB, UnwindBB, Args);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_TERMINATEBLOCK: { // TERMINATEBLOCK: [bb#,num,(ty,val)*]
if (Record.size() < 1)
return error("Invalid record");
unsigned Idx = 0;
bool HasUnwindDest = !!Record[Idx++];
BasicBlock *UnwindDest = nullptr;
if (HasUnwindDest) {
if (Idx == Record.size())
return error("Invalid record");
UnwindDest = getBasicBlock(Record[Idx++]);
if (!UnwindDest)
return error("Invalid record");
}
unsigned NumArgOperands = Record[Idx++];
SmallVector<Value *, 2> Args;
for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
Value *Val;
if (getValueTypePair(Record, Idx, NextValueNo, Val))
return error("Invalid record");
Args.push_back(Val);
}
if (Record.size() != Idx)
return error("Invalid record");
I = TerminateBlockInst::Create(Context, UnwindDest, Args);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_CLEANUPBLOCK: { // CLEANUPBLOCK: [ty, num,(ty,val)*]
if (Record.size() < 2)
return error("Invalid record");
unsigned Idx = 0;
Type *Ty = getTypeByID(Record[Idx++]);
if (!Ty)
return error("Invalid record");
unsigned NumArgOperands = Record[Idx++];
SmallVector<Value *, 2> Args;
for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
Value *Val;
if (getValueTypePair(Record, Idx, NextValueNo, Val))
return error("Invalid record");
Args.push_back(Val);
}
if (Record.size() != Idx)
return error("Invalid record");
I = CleanupBlockInst::Create(Ty, Args);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_CATCHENDBLOCK: { // CATCHENDBLOCKINST: [bb#] or []
if (Record.size() > 1)
return error("Invalid record");
BasicBlock *BB = nullptr;
if (Record.size() == 1) {
BB = getBasicBlock(Record[0]);
if (!BB)
return error("Invalid record");
}
I = CatchEndBlockInst::Create(Context, BB);
InstructionList.push_back(I);
break;
}
case bitc::FUNC_CODE_INST_SWITCH: { // SWITCH: [opty, op0, op1, ...]
// Check magic
if ((Record[0] >> 16) == SWITCH_INST_MAGIC) {

View File

@ -1845,64 +1845,6 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
Code = bitc::FUNC_CODE_INST_RESUME;
PushValueAndType(I.getOperand(0), InstID, Vals, VE);
break;
case Instruction::CleanupRet: {
Code = bitc::FUNC_CODE_INST_CLEANUPRET;
const auto &CRI = cast<CleanupReturnInst>(I);
Vals.push_back(CRI.hasReturnValue());
Vals.push_back(CRI.hasUnwindDest());
if (CRI.hasReturnValue())
PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
if (CRI.hasUnwindDest())
Vals.push_back(VE.getValueID(CRI.getUnwindDest()));
break;
}
case Instruction::CatchRet: {
Code = bitc::FUNC_CODE_INST_CATCHRET;
const auto &CRI = cast<CatchReturnInst>(I);
Vals.push_back(VE.getValueID(CRI.getSuccessor()));
break;
}
case Instruction::CatchBlock: {
Code = bitc::FUNC_CODE_INST_CATCHBLOCK;
const auto &CBI = cast<CatchBlockInst>(I);
Vals.push_back(VE.getTypeID(CBI.getType()));
Vals.push_back(VE.getValueID(CBI.getNormalDest()));
Vals.push_back(VE.getValueID(CBI.getUnwindDest()));
unsigned NumArgOperands = CBI.getNumArgOperands();
Vals.push_back(NumArgOperands);
for (unsigned Op = 0; Op != NumArgOperands; ++Op)
PushValueAndType(CBI.getArgOperand(Op), InstID, Vals, VE);
break;
}
case Instruction::TerminateBlock: {
Code = bitc::FUNC_CODE_INST_TERMINATEBLOCK;
const auto &TBI = cast<TerminateBlockInst>(I);
Vals.push_back(TBI.hasUnwindDest());
if (TBI.hasUnwindDest())
Vals.push_back(VE.getValueID(TBI.getUnwindDest()));
unsigned NumArgOperands = TBI.getNumArgOperands();
Vals.push_back(NumArgOperands);
for (unsigned Op = 0; Op != NumArgOperands; ++Op)
PushValueAndType(TBI.getArgOperand(Op), InstID, Vals, VE);
break;
}
case Instruction::CleanupBlock: {
Code = bitc::FUNC_CODE_INST_CLEANUPBLOCK;
const auto &CBI = cast<CleanupBlockInst>(I);
Vals.push_back(VE.getTypeID(CBI.getType()));
unsigned NumOperands = CBI.getNumOperands();
Vals.push_back(NumOperands);
for (unsigned Op = 0; Op != NumOperands; ++Op)
PushValueAndType(CBI.getOperand(Op), InstID, Vals, VE);
break;
}
case Instruction::CatchEndBlock: {
Code = bitc::FUNC_CODE_INST_CATCHENDBLOCK;
const auto &CEBI = cast<CatchEndBlockInst>(I);
if (CEBI.hasUnwindDest())
Vals.push_back(VE.getValueID(CEBI.getUnwindDest()));
break;
}
case Instruction::Unreachable:
Code = bitc::FUNC_CODE_INST_UNREACHABLE;
AbbrevToUse = FUNCTION_INST_UNREACHABLE_ABBREV;

View File

@ -1168,30 +1168,6 @@ SDValue SelectionDAGBuilder::getValueImpl(const Value *V) {
llvm_unreachable("Can't get register for value!");
}
void SelectionDAGBuilder::visitCleanupRet(const CleanupReturnInst &I) {
report_fatal_error("visitCleanupRet not yet implemented!");
}
void SelectionDAGBuilder::visitCatchEndBlock(const CatchEndBlockInst &I) {
report_fatal_error("visitCatchEndBlock not yet implemented!");
}
void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
report_fatal_error("visitCatchRet not yet implemented!");
}
void SelectionDAGBuilder::visitCatchBlock(const CatchBlockInst &I) {
report_fatal_error("visitCatchBlock not yet implemented!");
}
void SelectionDAGBuilder::visitTerminateBlock(const TerminateBlockInst &TBI) {
report_fatal_error("visitTerminateBlock not yet implemented!");
}
void SelectionDAGBuilder::visitCleanupBlock(const CleanupBlockInst &TBI) {
report_fatal_error("visitCleanupBlock not yet implemented!");
}
void SelectionDAGBuilder::visitRet(const ReturnInst &I) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
auto &DL = DAG.getDataLayout();

View File

@ -734,12 +734,6 @@ private:
void visitSwitch(const SwitchInst &I);
void visitIndirectBr(const IndirectBrInst &I);
void visitUnreachable(const UnreachableInst &I);
void visitCleanupRet(const CleanupReturnInst &I);
void visitCatchEndBlock(const CatchEndBlockInst &I);
void visitCatchRet(const CatchReturnInst &I);
void visitCatchBlock(const CatchBlockInst &I);
void visitTerminateBlock(const TerminateBlockInst &TBI);
void visitCleanupBlock(const CleanupBlockInst &CBI);
uint32_t getEdgeWeight(const MachineBasicBlock *Src,
const MachineBasicBlock *Dst) const;

View File

@ -1546,12 +1546,6 @@ int TargetLoweringBase::InstructionOpcodeToISD(unsigned Opcode) const {
case Invoke: return 0;
case Resume: return 0;
case Unreachable: return 0;
case CleanupRet: return 0;
case CatchEndBlock: return 0;
case CatchRet: return 0;
case CatchBlock: return 0;
case TerminateBlock: return 0;
case CleanupBlock: return 0;
case Add: return ISD::ADD;
case FAdd: return ISD::FADD;
case Sub: return ISD::SUB;

View File

@ -2848,66 +2848,8 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
writeOperand(LPI->getClause(i), true);
}
} else if (const auto *CBI = dyn_cast<CatchBlockInst>(&I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << " [";
for (unsigned Op = 0, NumOps = CBI->getNumArgOperands(); Op < NumOps;
++Op) {
if (Op > 0)
Out << ", ";
writeOperand(CBI->getArgOperand(Op), /*PrintType=*/true);
}
Out << "] to ";
writeOperand(CBI->getNormalDest(), /*PrintType=*/true);
Out << " unwind ";
writeOperand(CBI->getUnwindDest(), /*PrintType=*/true);
} else if (const auto *TBI = dyn_cast<TerminateBlockInst>(&I)) {
Out << " [";
for (unsigned Op = 0, NumOps = TBI->getNumArgOperands(); Op < NumOps;
++Op) {
if (Op > 0)
Out << ", ";
writeOperand(TBI->getArgOperand(Op), /*PrintType=*/true);
}
Out << "] unwind ";
if (TBI->hasUnwindDest())
writeOperand(TBI->getUnwindDest(), /*PrintType=*/true);
else
Out << "to caller";
} else if (const auto *CBI = dyn_cast<CleanupBlockInst>(&I)) {
Out << ' ';
TypePrinter.print(I.getType(), Out);
Out << " [";
for (unsigned Op = 0, NumOps = CBI->getNumOperands(); Op < NumOps; ++Op) {
if (Op > 0)
Out << ", ";
writeOperand(CBI->getOperand(Op), /*PrintType=*/true);
}
Out << "]";
} else if (isa<ReturnInst>(I) && !Operand) {
Out << " void";
} else if (const auto *CRI = dyn_cast<CleanupReturnInst>(&I)) {
if (CRI->hasReturnValue()) {
Out << ' ';
writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
} else {
Out << " void";
}
Out << " unwind ";
if (CRI->hasUnwindDest())
writeOperand(CRI->getUnwindDest(), /*PrintType=*/true);
else
Out << "to caller";
} else if (const auto *CEBI = dyn_cast<CatchEndBlockInst>(&I)) {
Out << " unwind ";
if (CEBI->hasUnwindDest())
writeOperand(CEBI->getUnwindDest(), /*PrintType=*/true);
else
Out << "to caller";
} else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
// Print the calling convention being used.
if (CI->getCallingConv() != CallingConv::C) {

View File

@ -197,7 +197,7 @@ BasicBlock::iterator BasicBlock::getFirstInsertionPt() {
return end();
iterator InsertPt = FirstNonPHI;
if (InsertPt->isEHBlock()) ++InsertPt;
if (isa<LandingPadInst>(InsertPt)) ++InsertPt;
return InsertPt;
}

View File

@ -196,11 +196,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case Invoke: return "invoke";
case Resume: return "resume";
case Unreachable: return "unreachable";
case CleanupRet: return "cleanupret";
case CatchEndBlock: return "catchendblock";
case CatchRet: return "catchret";
case CatchBlock: return "catchblock";
case TerminateBlock: return "terminateblock";
// Standard binary operators...
case Add: return "add";
@ -261,7 +256,6 @@ const char *Instruction::getOpcodeName(unsigned OpCode) {
case ExtractValue: return "extractvalue";
case InsertValue: return "insertvalue";
case LandingPad: return "landingpad";
case CleanupBlock: return "cleanupblock";
default: return "<Invalid operator> ";
}
@ -413,8 +407,6 @@ bool Instruction::mayReadFromMemory() const {
case Instruction::Fence: // FIXME: refine definition of mayReadFromMemory
case Instruction::AtomicCmpXchg:
case Instruction::AtomicRMW:
case Instruction::CatchRet:
case Instruction::TerminateBlock:
return true;
case Instruction::Call:
return !cast<CallInst>(this)->doesNotAccessMemory();
@ -435,8 +427,6 @@ bool Instruction::mayWriteToMemory() const {
case Instruction::VAArg:
case Instruction::AtomicCmpXchg:
case Instruction::AtomicRMW:
case Instruction::CatchRet:
case Instruction::TerminateBlock:
return true;
case Instruction::Call:
return !cast<CallInst>(this)->onlyReadsMemory();
@ -465,12 +455,6 @@ bool Instruction::isAtomic() const {
bool Instruction::mayThrow() const {
if (const CallInst *CI = dyn_cast<CallInst>(this))
return !CI->doesNotThrow();
if (const auto *CRI = dyn_cast<CleanupReturnInst>(this))
return CRI->unwindsToCaller();
if (const auto *CEBI = dyn_cast<CatchEndBlockInst>(this))
return CEBI->unwindsToCaller();
if (const auto *TBI = dyn_cast<TerminateBlockInst>(this))
return TBI->unwindsToCaller();
return isa<ResumeInst>(this);
}

View File

@ -670,303 +670,6 @@ BasicBlock *ResumeInst::getSuccessorV(unsigned idx) const {
llvm_unreachable("ResumeInst has no successors!");
}
//===----------------------------------------------------------------------===//
// CleanupReturnInst Implementation
//===----------------------------------------------------------------------===//
CleanupReturnInst::CleanupReturnInst(const CleanupReturnInst &CRI)
: TerminatorInst(CRI.getType(), Instruction::CleanupRet,
OperandTraits<CleanupReturnInst>::op_end(this) -
CRI.getNumOperands(),
CRI.getNumOperands()) {
SubclassOptionalData = CRI.SubclassOptionalData;
if (Value *RetVal = CRI.getReturnValue())
setReturnValue(RetVal);
if (BasicBlock *UnwindDest = CRI.getUnwindDest())
setUnwindDest(UnwindDest);
}
void CleanupReturnInst::init(Value *RetVal, BasicBlock *UnwindBB) {
SubclassOptionalData = 0;
if (UnwindBB)
setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
if (RetVal)
setInstructionSubclassData(getSubclassDataFromInstruction() | 2);
if (UnwindBB)
setUnwindDest(UnwindBB);
if (RetVal)
setReturnValue(RetVal);
}
CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
BasicBlock *UnwindBB, unsigned Values,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
OperandTraits<CleanupReturnInst>::op_end(this) - Values,
Values, InsertBefore) {
init(RetVal, UnwindBB);
}
CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
BasicBlock *UnwindBB, unsigned Values,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
OperandTraits<CleanupReturnInst>::op_end(this) - Values,
Values, InsertAtEnd) {
init(RetVal, UnwindBB);
}
BasicBlock *CleanupReturnInst::getUnwindDest() const {
if (hasUnwindDest())
return cast<BasicBlock>(getOperand(getUnwindLabelOpIdx()));
return nullptr;
}
void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
assert(NewDest);
setOperand(getUnwindLabelOpIdx(), NewDest);
}
BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const {
assert(Idx == 0);
return getUnwindDest();
}
unsigned CleanupReturnInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void CleanupReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
assert(Idx == 0);
setUnwindDest(B);
}
//===----------------------------------------------------------------------===//
// CatchEndBlockInst Implementation
//===----------------------------------------------------------------------===//
CatchEndBlockInst::CatchEndBlockInst(const CatchEndBlockInst &CRI)
: TerminatorInst(CRI.getType(), Instruction::CatchEndBlock,
OperandTraits<CatchEndBlockInst>::op_end(this) -
CRI.getNumOperands(),
CRI.getNumOperands()) {
SubclassOptionalData = CRI.SubclassOptionalData;
if (BasicBlock *UnwindDest = CRI.getUnwindDest())
setUnwindDest(UnwindDest);
}
void CatchEndBlockInst::init(BasicBlock *UnwindBB) {
SubclassOptionalData = 0;
if (UnwindBB) {
setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
setUnwindDest(UnwindBB);
}
}
CatchEndBlockInst::CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB,
unsigned Values, Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(C), Instruction::CatchEndBlock,
OperandTraits<CatchEndBlockInst>::op_end(this) - Values,
Values, InsertBefore) {
init(UnwindBB);
}
CatchEndBlockInst::CatchEndBlockInst(LLVMContext &C, BasicBlock *UnwindBB,
unsigned Values, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(C), Instruction::CatchEndBlock,
OperandTraits<CatchEndBlockInst>::op_end(this) - Values,
Values, InsertAtEnd) {
init(UnwindBB);
}
BasicBlock *CatchEndBlockInst::getSuccessorV(unsigned Idx) const {
assert(Idx == 0);
return getUnwindDest();
}
unsigned CatchEndBlockInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void CatchEndBlockInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
assert(Idx == 0);
setUnwindDest(B);
}
//===----------------------------------------------------------------------===//
// CatchReturnInst Implementation
//===----------------------------------------------------------------------===//
CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
: TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
OperandTraits<CatchReturnInst>::op_end(this) -
CRI.getNumOperands(),
CRI.getNumOperands()) {
Op<0>() = CRI.Op<0>();
}
CatchReturnInst::CatchReturnInst(BasicBlock *BB, Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
OperandTraits<CatchReturnInst>::op_begin(this), 1,
InsertBefore) {
Op<0>() = BB;
}
CatchReturnInst::CatchReturnInst(BasicBlock *BB, BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
OperandTraits<CatchReturnInst>::op_begin(this), 1,
InsertAtEnd) {
Op<0>() = BB;
}
BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
assert(Idx == 0);
return getSuccessor();
}
unsigned CatchReturnInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void CatchReturnInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
assert(Idx == 0);
setSuccessor(B);
}
//===----------------------------------------------------------------------===//
// CatchBlockInst Implementation
//===----------------------------------------------------------------------===//
void CatchBlockInst::init(BasicBlock *IfNormal, BasicBlock *IfException,
ArrayRef<Value *> Args, const Twine &NameStr) {
assert(getNumOperands() == 2 + Args.size() && "NumOperands not set up?");
Op<-2>() = IfNormal;
Op<-1>() = IfException;
std::copy(Args.begin(), Args.end(), op_begin());
setName(NameStr);
}
CatchBlockInst::CatchBlockInst(const CatchBlockInst &CBI)
: TerminatorInst(CBI.getType(), Instruction::CatchBlock,
OperandTraits<CatchBlockInst>::op_end(this) -
CBI.getNumOperands(),
CBI.getNumOperands()) {
std::copy(CBI.op_begin(), CBI.op_end(), op_begin());
}
CatchBlockInst::CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
unsigned Values, const Twine &NameStr,
Instruction *InsertBefore)
: TerminatorInst(RetTy, Instruction::CatchBlock,
OperandTraits<CatchBlockInst>::op_end(this) - Values,
Values, InsertBefore) {
init(IfNormal, IfException, Args, NameStr);
}
CatchBlockInst::CatchBlockInst(Type *RetTy, BasicBlock *IfNormal,
BasicBlock *IfException, ArrayRef<Value *> Args,
unsigned Values, const Twine &NameStr,
BasicBlock *InsertAtEnd)
: TerminatorInst(RetTy, Instruction::CatchBlock,
OperandTraits<CatchBlockInst>::op_end(this) - Values,
Values, InsertAtEnd) {
init(IfNormal, IfException, Args, NameStr);
}
BasicBlock *CatchBlockInst::getSuccessorV(unsigned Idx) const {
return getSuccessor(Idx);
}
unsigned CatchBlockInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void CatchBlockInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
return setSuccessor(Idx, B);
}
//===----------------------------------------------------------------------===//
// TerminateBlockInst Implementation
//===----------------------------------------------------------------------===//
void TerminateBlockInst::init(BasicBlock *BB, ArrayRef<Value *> Args,
const Twine &NameStr) {
SubclassOptionalData = 0;
if (BB)
setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
if (BB)
Op<-1>() = BB;
std::copy(Args.begin(), Args.end(), op_begin());
setName(NameStr);
}
TerminateBlockInst::TerminateBlockInst(const TerminateBlockInst &TBI)
: TerminatorInst(TBI.getType(), Instruction::TerminateBlock,
OperandTraits<TerminateBlockInst>::op_end(this) -
TBI.getNumOperands(),
TBI.getNumOperands()) {
SubclassOptionalData = TBI.SubclassOptionalData;
std::copy(TBI.op_begin(), TBI.op_end(), op_begin());
}
TerminateBlockInst::TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr,
Instruction *InsertBefore)
: TerminatorInst(Type::getVoidTy(C), Instruction::TerminateBlock,
OperandTraits<TerminateBlockInst>::op_end(this) - Values,
Values, InsertBefore) {
init(BB, Args, NameStr);
}
TerminateBlockInst::TerminateBlockInst(LLVMContext &C, BasicBlock *BB,
ArrayRef<Value *> Args, unsigned Values,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
: TerminatorInst(Type::getVoidTy(C), Instruction::TerminateBlock,
OperandTraits<TerminateBlockInst>::op_end(this) - Values,
Values, InsertAtEnd) {
init(BB, Args, NameStr);
}
BasicBlock *TerminateBlockInst::getSuccessorV(unsigned Idx) const {
assert(Idx == 0);
return getUnwindDest();
}
unsigned TerminateBlockInst::getNumSuccessorsV() const {
return getNumSuccessors();
}
void TerminateBlockInst::setSuccessorV(unsigned Idx, BasicBlock *B) {
assert(Idx == 0);
return setUnwindDest(B);
}
//===----------------------------------------------------------------------===//
// CleanupBlockInst Implementation
//===----------------------------------------------------------------------===//
void CleanupBlockInst::init(ArrayRef<Value *> Args, const Twine &NameStr) {
assert(getNumOperands() == Args.size() && "NumOperands not set up?");
std::copy(Args.begin(), Args.end(), op_begin());
setName(NameStr);
}
CleanupBlockInst::CleanupBlockInst(const CleanupBlockInst &CBI)
: Instruction(CBI.getType(), Instruction::CleanupBlock,
OperandTraits<CleanupBlockInst>::op_end(this) -
CBI.getNumOperands(),
CBI.getNumOperands()) {
std::copy(CBI.op_begin(), CBI.op_end(), op_begin());
}
CleanupBlockInst::CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr,
Instruction *InsertBefore)
: Instruction(RetTy, Instruction::CleanupBlock,
OperandTraits<CleanupBlockInst>::op_end(this) - Args.size(),
Args.size(), InsertBefore) {
init(Args, NameStr);
}
CleanupBlockInst::CleanupBlockInst(Type *RetTy, ArrayRef<Value *> Args,
const Twine &NameStr,
BasicBlock *InsertAtEnd)
: Instruction(RetTy, Instruction::CleanupBlock,
OperandTraits<CleanupBlockInst>::op_end(this) - Args.size(),
Args.size(), InsertAtEnd) {
init(Args, NameStr);
}
//===----------------------------------------------------------------------===//
// UnreachableInst Implementation
//===----------------------------------------------------------------------===//
@ -3915,30 +3618,6 @@ InvokeInst *InvokeInst::cloneImpl() const {
ResumeInst *ResumeInst::cloneImpl() const { return new (1) ResumeInst(*this); }
CleanupReturnInst *CleanupReturnInst::cloneImpl() const {
return new (getNumOperands()) CleanupReturnInst(*this);
}
CatchEndBlockInst *CatchEndBlockInst::cloneImpl() const {
return new (getNumOperands()) CatchEndBlockInst(*this);
}
CatchReturnInst *CatchReturnInst::cloneImpl() const {
return new (1) CatchReturnInst(*this);
}
CatchBlockInst *CatchBlockInst::cloneImpl() const {
return new (getNumOperands()) CatchBlockInst(*this);
}
TerminateBlockInst *TerminateBlockInst::cloneImpl() const {
return new (getNumOperands()) TerminateBlockInst(*this);
}
CleanupBlockInst *CleanupBlockInst::cloneImpl() const {
return new (getNumOperands()) CleanupBlockInst(*this);
}
UnreachableInst *UnreachableInst::cloneImpl() const {
LLVMContext &Context = getContext();
return new UnreachableInst(Context);

View File

@ -184,9 +184,6 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
/// \brief Track unresolved string-based type references.
SmallDenseMap<const MDString *, const MDNode *, 32> UnresolvedTypeRefs;
/// \brief The result value from the personality function.
Type *PersonalityFnResultTy;
/// \brief Whether we've seen a call to @llvm.localescape in this function
/// already.
bool SawFrameEscape;
@ -197,8 +194,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport {
public:
explicit Verifier(raw_ostream &OS)
: VerifierSupport(OS), Context(nullptr), PersonalityFnResultTy(nullptr),
SawFrameEscape(false) {}
: VerifierSupport(OS), Context(nullptr), SawFrameEscape(false) {}
bool verify(const Function &F) {
M = F.getParent();
@ -232,7 +228,6 @@ public:
// FIXME: We strip const here because the inst visitor strips const.
visit(const_cast<Function &>(F));
InstsInThisBlock.clear();
PersonalityFnResultTy = nullptr;
SawFrameEscape = false;
return !Broken;
@ -385,11 +380,6 @@ private:
void visitExtractValueInst(ExtractValueInst &EVI);
void visitInsertValueInst(InsertValueInst &IVI);
void visitLandingPadInst(LandingPadInst &LPI);
void visitCatchBlockInst(CatchBlockInst &CBI);
void visitCatchEndBlockInst(CatchEndBlockInst &CEBI);
void visitCleanupBlockInst(CleanupBlockInst &CBI);
void visitCleanupReturnInst(CleanupReturnInst &CRI);
void visitTerminateBlockInst(TerminateBlockInst &TBI);
void VerifyCallSite(CallSite CS);
void verifyMustTailCall(CallInst &CI);
@ -2414,12 +2404,10 @@ void Verifier::visitCallInst(CallInst &CI) {
void Verifier::visitInvokeInst(InvokeInst &II) {
VerifyCallSite(&II);
// Verify that the first non-PHI instruction of the unwind destination is an
// exception handling instruction.
Assert(
II.getUnwindDest()->isEHBlock(),
"The unwind destination does not have an exception handling instruction!",
&II);
// Verify that there is a landingpad instruction as the first non-PHI
// instruction of the 'unwind' destination.
Assert(II.getUnwindDest()->isLandingPad(),
"The unwind destination does not have a landingpad instruction!", &II);
visitTerminatorInst(II);
}
@ -2805,14 +2793,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
&LPI);
}
if (!PersonalityFnResultTy)
PersonalityFnResultTy = LPI.getType();
else
Assert(PersonalityFnResultTy == LPI.getType(),
"The personality routine should have a consistent result type "
"inside a function.",
&LPI);
Function *F = LPI.getParent()->getParent();
Assert(F->hasPersonalityFn(),
"LandingPadInst needs to be in a function with a personality.", &LPI);
@ -2838,132 +2818,6 @@ void Verifier::visitLandingPadInst(LandingPadInst &LPI) {
visitInstruction(LPI);
}
void Verifier::visitCatchBlockInst(CatchBlockInst &CBI) {
BasicBlock *BB = CBI.getParent();
if (!PersonalityFnResultTy)
PersonalityFnResultTy = CBI.getType();
else
Assert(PersonalityFnResultTy == CBI.getType(),
"The personality routine should have a consistent result type "
"inside a function.",
&CBI);
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
"CatchBlockInst needs to be in a function with a personality.", &CBI);
// The catchblock instruction must be the first non-PHI instruction in the
// block.
Assert(BB->getFirstNonPHI() == &CBI,
"CatchBlockInst not the first non-PHI instruction in the block.",
&CBI);
BasicBlock *UnwindDest = CBI.getUnwindDest();
Instruction *I = UnwindDest->getFirstNonPHI();
Assert(
isa<CatchBlockInst>(I) || isa<CatchEndBlockInst>(I),
"CatchBlockInst must unwind to a CatchBlockInst or a CatchEndBlockInst.",
&CBI);
visitTerminatorInst(CBI);
}
void Verifier::visitCatchEndBlockInst(CatchEndBlockInst &CEBI) {
BasicBlock *BB = CEBI.getParent();
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
"CatchEndBlockInst needs to be in a function with a personality.",
&CEBI);
// The catchendblock instruction must be the first non-PHI instruction in the
// block.
Assert(BB->getFirstNonPHI() == &CEBI,
"CatchEndBlockInst not the first non-PHI instruction in the block.",
&CEBI);
unsigned CatchBlocksSeen = 0;
for (BasicBlock *PredBB : predecessors(BB))
if (isa<CatchBlockInst>(PredBB->getTerminator()))
++CatchBlocksSeen;
Assert(CatchBlocksSeen <= 1, "CatchEndBlockInst must have no more than one "
"CatchBlockInst predecessor.",
&CEBI);
if (BasicBlock *UnwindDest = CEBI.getUnwindDest()) {
Instruction *I = UnwindDest->getFirstNonPHI();
Assert(
I->isEHBlock() && !isa<LandingPadInst>(I),
"CatchEndBlock must unwind to an EH block which is not a landingpad.",
&CEBI);
}
visitTerminatorInst(CEBI);
}
void Verifier::visitCleanupBlockInst(CleanupBlockInst &CBI) {
BasicBlock *BB = CBI.getParent();
if (!PersonalityFnResultTy)
PersonalityFnResultTy = CBI.getType();
else
Assert(PersonalityFnResultTy == CBI.getType(),
"The personality routine should have a consistent result type "
"inside a function.",
&CBI);
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
"CleanupBlockInst needs to be in a function with a personality.", &CBI);
// The cleanupblock instruction must be the first non-PHI instruction in the
// block.
Assert(BB->getFirstNonPHI() == &CBI,
"CleanupBlockInst not the first non-PHI instruction in the block.",
&CBI);
visitInstruction(CBI);
}
void Verifier::visitCleanupReturnInst(CleanupReturnInst &CRI) {
if (BasicBlock *UnwindDest = CRI.getUnwindDest()) {
Instruction *I = UnwindDest->getFirstNonPHI();
Assert(I->isEHBlock() && !isa<LandingPadInst>(I),
"CleanupReturnInst must unwind to an EH block which is not a "
"landingpad.",
&CRI);
}
visitTerminatorInst(CRI);
}
void Verifier::visitTerminateBlockInst(TerminateBlockInst &TBI) {
BasicBlock *BB = TBI.getParent();
Function *F = BB->getParent();
Assert(F->hasPersonalityFn(),
"TerminateBlockInst needs to be in a function with a personality.",
&TBI);
// The terminateblock instruction must be the first non-PHI instruction in the
// block.
Assert(BB->getFirstNonPHI() == &TBI,
"TerminateBlockInst not the first non-PHI instruction in the block.",
&TBI);
if (BasicBlock *UnwindDest = TBI.getUnwindDest()) {
Instruction *I = UnwindDest->getFirstNonPHI();
Assert(I->isEHBlock() && !isa<LandingPadInst>(I),
"TerminateBlockInst must unwind to an EH block which is not a "
"landingpad.",
&TBI);
}
visitTerminatorInst(TBI);
}
void Verifier::verifyDominatesUse(Instruction &I, unsigned i) {
Instruction *Op = cast<Instruction>(I.getOperand(i));
// If the we have an invalid invoke, don't try to compute the dominance.

View File

@ -2653,30 +2653,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
setOrigin(&I, getCleanOrigin());
}
void visitCleanupBlockInst(CleanupBlockInst &I) {
if (!I.getType()->isVoidTy()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
}
}
void visitCatchBlock(CatchBlockInst &I) {
if (!I.getType()->isVoidTy()) {
setShadow(&I, getCleanShadow(&I));
setOrigin(&I, getCleanOrigin());
}
}
void visitTerminateBlock(TerminateBlockInst &I) {
DEBUG(dbgs() << "TerminateBlock: " << I << "\n");
// Nothing to do here.
}
void visitCatchEndBlockInst(CatchEndBlockInst &I) {
DEBUG(dbgs() << "CatchEndBlock: " << I << "\n");
// Nothing to do here.
}
void visitGetElementPtrInst(GetElementPtrInst &I) {
handleShadowOr(I);
}
@ -2720,16 +2696,6 @@ struct MemorySanitizerVisitor : public InstVisitor<MemorySanitizerVisitor> {
// Nothing to do here.
}
void visitCleanupReturnInst(CleanupReturnInst &CRI) {
DEBUG(dbgs() << "CleanupReturn: " << CRI << "\n");
// Nothing to do here.
}
void visitCatchReturnInst(CatchReturnInst &CRI) {
DEBUG(dbgs() << "CatchReturn: " << CRI << "\n");
// Nothing to do here.
}
void visitInstruction(Instruction &I) {
// Everything else: stop propagating and check for poisoned shadow.
if (ClDumpStrictInstructions)

View File

@ -58,8 +58,8 @@ bool ADCE::runOnFunction(Function& F) {
// Collect the set of "root" instructions that are known live.
for (Instruction &I : inst_range(F)) {
if (isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) || I.isEHBlock() ||
I.mayHaveSideEffects()) {
if (isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) ||
isa<LandingPadInst>(I) || I.mayHaveSideEffects()) {
Alive.insert(&I);
Worklist.push_back(&I);
}

View File

@ -77,8 +77,8 @@ INITIALIZE_PASS_END(BDCE, "bdce", "Bit-Tracking Dead Code Elimination",
false, false)
static bool isAlwaysLive(Instruction *I) {
return isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) || I->isEHBlock() ||
I->mayHaveSideEffects();
return isa<TerminatorInst>(I) || isa<DbgInfoIntrinsic>(I) ||
isa<LandingPadInst>(I) || I->mayHaveSideEffects();
}
void BDCE::determineLiveOperandBits(const Instruction *UserI,

View File

@ -669,8 +669,7 @@ bool JumpThreading::ProcessBlock(BasicBlock *BB) {
// because now the condition in this block can be threaded through
// predecessors of our predecessor block.
if (BasicBlock *SinglePred = BB->getSinglePredecessor()) {
const TerminatorInst *TI = SinglePred->getTerminator();
if (!TI->isExceptional() && TI->getNumSuccessors() == 1 &&
if (SinglePred->getTerminator()->getNumSuccessors() == 1 &&
SinglePred != BB && !hasAddressTakenAndUsed(BB)) {
// If SinglePred was a loop header, BB becomes one.
if (LoopHeaders.erase(SinglePred))

View File

@ -539,9 +539,9 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
return;
}
// Unwinding instructions successors are always executable.
if (TI.isExceptional()) {
Succs.assign(TI.getNumSuccessors(), true);
if (isa<InvokeInst>(TI)) {
// Invoke instructions successors are always executable.
Succs[0] = Succs[1] = true;
return;
}
@ -605,8 +605,8 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
return BI->getSuccessor(CI->isZero()) == To;
}
// Unwinding instructions successors are always executable.
if (TI->isExceptional())
// Invoke instructions successors are always executable.
if (isa<InvokeInst>(TI))
return true;
if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {

View File

@ -119,9 +119,8 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock *BB, DominatorTree *DT,
// Don't break self-loops.
if (PredBB == BB) return false;
// Don't break unwinding instructions.
if (PredBB->getTerminator()->isExceptional())
return false;
// Don't break invokes.
if (isa<InvokeInst>(PredBB->getTerminator())) return false;
succ_iterator SI(succ_begin(PredBB)), SE(succ_end(PredBB));
BasicBlock *OnlySucc = BB;

View File

@ -283,9 +283,8 @@ bool llvm::isInstructionTriviallyDead(Instruction *I,
const TargetLibraryInfo *TLI) {
if (!I->use_empty() || isa<TerminatorInst>(I)) return false;
// We don't want the landingpad-like instructions removed by anything this
// general.
if (I->isEHBlock())
// We don't want the landingpad instruction removed by anything this general.
if (isa<LandingPadInst>(I))
return false;
// We don't want debug info removed by anything this general, unless

View File

@ -25,72 +25,3 @@ lpad: ; preds = %entry
declare void @_Z3quxv() optsize
declare i32 @__gxx_personality_v0(...)
define void @cleanupret0() personality i32 (...)* @__gxx_personality_v0 {
entry:
cleanupret i8 0 unwind label %bb
bb:
ret void
}
define void @cleanupret1() personality i32 (...)* @__gxx_personality_v0 {
entry:
cleanupret void unwind label %bb
bb:
ret void
}
define void @cleanupret2() personality i32 (...)* @__gxx_personality_v0 {
entry:
cleanupret i8 0 unwind to caller
}
define void @cleanupret3() personality i32 (...)* @__gxx_personality_v0 {
cleanupret void unwind to caller
}
define void @catchret() personality i32 (...)* @__gxx_personality_v0 {
entry:
br label %bb
bb:
catchret label %bb
}
define i8 @catchblock() personality i32 (...)* @__gxx_personality_v0 {
entry:
br label %bb2
bb:
ret i8 %cbv
bb2:
%cbv = catchblock i8 [i7 4] to label %bb unwind label %bb2
}
define void @terminateblock0() personality i32 (...)* @__gxx_personality_v0 {
entry:
br label %bb
bb:
terminateblock [i7 4] unwind label %bb
}
define void @terminateblock1() personality i32 (...)* @__gxx_personality_v0 {
entry:
terminateblock [i7 4] unwind to caller
}
define void @cleanupblock() personality i32 (...)* @__gxx_personality_v0 {
entry:
cleanupblock void [i7 4]
ret void
}
define void @catchendblock0() personality i32 (...)* @__gxx_personality_v0 {
entry:
br label %bb
bb:
catchendblock unwind label %bb
}
define void @catchendblock1() personality i32 (...)* @__gxx_personality_v0 {
entry:
catchendblock unwind to caller
}

View File

@ -2,7 +2,7 @@
; PR1042
define i32 @foo() {
; CHECK: The unwind destination does not have an exception handling instruction
; CHECK: The unwind destination does not have a landingpad instruction
%A = invoke i32 @foo( )
to label %L unwind label %L ; <i32> [#uses=1]
L: ; preds = %0, %0
@ -18,7 +18,7 @@ L1: ; preds = %0
L2: ; preds = %0
br label %L
L: ; preds = %L2, %L1, %L1
; CHECK: The unwind destination does not have an exception handling instruction
; CHECK: The unwind destination does not have a landingpad instruction
ret i32 %A
}

View File

@ -241,11 +241,6 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
STRINGIFY_CODE(FUNC_CODE, INST_SWITCH)
STRINGIFY_CODE(FUNC_CODE, INST_INVOKE)
STRINGIFY_CODE(FUNC_CODE, INST_UNREACHABLE)
STRINGIFY_CODE(FUNC_CODE, INST_CLEANUPRET)
STRINGIFY_CODE(FUNC_CODE, INST_CATCHRET)
STRINGIFY_CODE(FUNC_CODE, INST_CATCHBLOCK)
STRINGIFY_CODE(FUNC_CODE, INST_CATCHENDBLOCK)
STRINGIFY_CODE(FUNC_CODE, INST_TERMINATEBLOCK)
STRINGIFY_CODE(FUNC_CODE, INST_PHI)
STRINGIFY_CODE(FUNC_CODE, INST_ALLOCA)
STRINGIFY_CODE(FUNC_CODE, INST_LOAD)