X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstructions.h;h=aba48ca6fa9e09f7fb95cd50ca92753ac6bed13c;hp=5119749ba73ce2a4c1cd4e193f6d7d7ca9eac7f5;hb=db61103ea811b2fc0443e6438da3067a19ba1793;hpb=4e6293afeb829a33137df86f5d58b010121bf8cd diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 5119749ba73..aba48ca6fa9 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -18,6 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/CallingConv.h" @@ -838,6 +839,8 @@ class GetElementPtrInst : public Instruction { Type *SourceElementType; Type *ResultElementType; + void anchor() override; + GetElementPtrInst(const GetElementPtrInst &GEPI); void init(Value *Ptr, ArrayRef IdxList, const Twine &NameStr); @@ -1096,6 +1099,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) /// must be identical types. /// \brief Represent an integer comparison operator. class ICmpInst: public CmpInst { + void anchor() override; + void AssertOK() { assert(getPredicate() >= CmpInst::FIRST_ICMP_PREDICATE && getPredicate() <= CmpInst::LAST_ICMP_PREDICATE && @@ -1543,18 +1548,32 @@ public: setOperand(i, v); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() { - // The last operand in the op list is the callee - it's not one of the args - // so we don't want to iterate over it. - return iterator_range( - op_begin(), op_end() - getNumTotalBundleOperands() - 1); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ call args ], [ operand bundles ], callee + return op_end() - getNumTotalBundleOperands() - 1; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range( - op_begin(), op_end() - getNumTotalBundleOperands() - 1); + return make_range(arg_begin(), arg_end()); } /// \brief Wrappers for getting the \c Use of a call argument. @@ -2213,7 +2232,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { - return iterator_range(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -2330,7 +2349,7 @@ public: inline idx_iterator idx_begin() const { return Indices.begin(); } inline idx_iterator idx_end() const { return Indices.end(); } inline iterator_range indices() const { - return iterator_range(idx_begin(), idx_end()); + return make_range(idx_begin(), idx_end()); } Value *getAggregateOperand() { @@ -2411,6 +2430,8 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(InsertValueInst, Value) // scientist's overactive imagination. // class PHINode : public Instruction { + void anchor() override; + void *operator new(size_t, unsigned) = delete; /// ReservedSpace - The number of operands actually allocated. NumOperands is /// the number actually in use. @@ -3105,12 +3126,12 @@ public: /// cases - iteration adapter for range-for loops. iterator_range cases() { - return iterator_range(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// cases - iteration adapter for range-for loops. iterator_range cases() const { - return iterator_range(case_begin(), case_end()); + return make_range(case_begin(), case_end()); } /// Returns an iterator that points to the default case. @@ -3452,16 +3473,32 @@ public: setOperand(i, v); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + op_iterator arg_begin() { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + op_iterator arg_end() { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() { - return iterator_range( - op_begin(), op_end() - getNumTotalBundleOperands() - 3); + return make_range(arg_begin(), arg_end()); } - /// arg_operands - iteration adapter for range-for loops. + /// \brief Return the iterator pointing to the beginning of the argument list. + const_op_iterator arg_begin() const { return op_begin(); } + + /// \brief Return the iterator pointing to the end of the argument list. + const_op_iterator arg_end() const { + // [ invoke args ], [ operand bundles ], normal dest, unwind dest, callee + return op_end() - getNumTotalBundleOperands() - 3; + }; + + /// \brief Iteration adapter for range-for loops. iterator_range arg_operands() const { - return iterator_range( - op_begin(), op_end() - getNumTotalBundleOperands() - 3); + return make_range(arg_begin(), arg_end()); } /// \brief Wrappers for getting the \c Use of a invoke argument. @@ -3513,6 +3550,11 @@ public: return hasFnAttrImpl(A); } + /// \brief Determine whether this call has the given attribute. + bool hasFnAttr(StringRef A) const { + return hasFnAttrImpl(A); + } + /// \brief Determine whether the call or the callee has the given attributes. bool paramHasAttr(unsigned i, Attribute::AttrKind A) const; @@ -3697,7 +3739,19 @@ private: unsigned getNumSuccessorsV() const override; void setSuccessorV(unsigned idx, BasicBlock *B) override; - bool hasFnAttrImpl(Attribute::AttrKind A) const; + template bool hasFnAttrImpl(AttrKind A) const { + if (AttributeList.hasAttribute(AttributeSet::FunctionIndex, A)) + return true; + + // Operand bundles override attributes on the called function, but don't + // override attributes directly present on the invoke instruction. + if (isFnAttrDisallowedByOpBundle(A)) + return false; + + if (const Function *F = getCalledFunction()) + return F->getAttributes().hasAttribute(AttributeSet::FunctionIndex, A); + return false; + } // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -3789,356 +3843,268 @@ struct OperandTraits : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) //===----------------------------------------------------------------------===// -// CatchEndPadInst Class +// CatchSwitchInst Class //===----------------------------------------------------------------------===// +class CatchSwitchInst : public TerminatorInst { + void *operator new(size_t, unsigned) = delete; + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + // Operand[0] = Outer scope + // Operand[1] = Unwind block destination + // Operand[n] = BasicBlock to go to on match + CatchSwitchInst(const CatchSwitchInst &CSI); + void init(Value *ParentPad, BasicBlock *UnwindDest, unsigned NumReserved); + void growOperands(unsigned Size); + // allocate space for exactly zero operands + void *operator new(size_t s) { return User::operator new(s); } + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor can also autoinsert before another instruction. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, + Instruction *InsertBefore); -class CatchEndPadInst : public TerminatorInst { -private: - CatchEndPadInst(const CatchEndPadInst &RI); - - void init(BasicBlock *UnwindBB); - CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values, - Instruction *InsertBefore = nullptr); - CatchEndPadInst(LLVMContext &C, BasicBlock *UnwindBB, unsigned Values, + /// CatchSwitchInst ctor - Create a new switch instruction, specifying a + /// default destination. The number of additional handlers can be specified + /// here to make memory allocation more efficient. + /// This constructor also autoinserts at the end of the specified BasicBlock. + CatchSwitchInst(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. friend class Instruction; - CatchEndPadInst *cloneImpl() const; + CatchSwitchInst *cloneImpl() const; public: - static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB = nullptr, + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, + const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertBefore); + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertBefore); } - static CatchEndPadInst *Create(LLVMContext &C, BasicBlock *UnwindBB, + static CatchSwitchInst *Create(Value *ParentPad, BasicBlock *UnwindDest, + unsigned NumHandlers, const Twine &NameStr, BasicBlock *InsertAtEnd) { - unsigned Values = UnwindBB ? 1 : 0; - return new (Values) CatchEndPadInst(C, UnwindBB, Values, InsertAtEnd); + return new CatchSwitchInst(ParentPad, UnwindDest, NumHandlers, NameStr, + InsertAtEnd); } /// Provide fast operand accessors DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // Accessor Methods for CatchSwitch stmt + Value *getParentPad() const { return getOperand(0); } + void setParentPad(Value *ParentPad) { setOperand(0, ParentPad); } + + // Accessor Methods for CatchSwitch stmt 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 hasUnwindDest() ? cast(Op<-1>()) : nullptr; + if (hasUnwindDest()) + return cast(getOperand(1)); + return nullptr; } - void setUnwindDest(BasicBlock *NewDest) { - assert(NewDest); - Op<-1>() = NewDest; + void setUnwindDest(BasicBlock *UnwindDest) { + assert(UnwindDest); + assert(hasUnwindDest()); + setOperand(1, UnwindDest); } - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::CatchEndPad); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(V)); + /// getNumHandlers - return the number of 'handlers' in this catchswitch + /// instruction, except the default handler + unsigned getNumHandlers() const { + if (hasUnwindDest()) + return getNumOperands() - 2; + return getNumOperands() - 1; } 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); + static BasicBlock *handler_helper(Value *V) { return cast(V); } + static const BasicBlock *handler_helper(const Value *V) { + return cast(V); } -}; - -template <> -struct OperandTraits - : public VariadicOperandTraits {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchEndPadInst, Value) - -//===----------------------------------------------------------------------===// -// CatchPadInst Class -//===----------------------------------------------------------------------===// - -class CatchPadInst : public TerminatorInst { -private: - void init(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, const Twine &NameStr); - CatchPadInst(const CatchPadInst &CPI); +public: + typedef std::pointer_to_unary_function DerefFnTy; + typedef mapped_iterator handler_iterator; + typedef iterator_range handler_range; - explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, - const Twine &NameStr, Instruction *InsertBefore); - explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, unsigned Values, - const Twine &NameStr, BasicBlock *InsertAtEnd); -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - CatchPadInst *cloneImpl() const; + typedef std::pointer_to_unary_function + ConstDerefFnTy; + typedef mapped_iterator const_handler_iterator; + typedef iterator_range const_handler_range; -public: - static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { - unsigned Values = unsigned(Args.size()) + 2; - return new (Values) CatchPadInst(IfNormal, IfException, Args, Values, - NameStr, InsertBefore); - } - static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException, - ArrayRef Args, const Twine &NameStr, - BasicBlock *InsertAtEnd) { - unsigned Values = unsigned(Args.size()) + 2; - return new (Values) - CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd); + /// Returns an iterator that points to the first handler in CatchSwitchInst. + handler_iterator handler_begin() { + op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return handler_iterator(It, DerefFnTy(handler_helper)); + } + /// Returns an iterator that points to the first handler in the + /// CatchSwitchInst. + const_handler_iterator handler_begin() const { + const_op_iterator It = op_begin() + 1; + if (hasUnwindDest()) + ++It; + return const_handler_iterator(It, ConstDerefFnTy(handler_helper)); } - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - - /// getNumArgOperands - Return the number of catchpad arguments. - /// - unsigned getNumArgOperands() const { return getNumOperands() - 2; } - - /// getArgOperand/setArgOperand - Return/set the i-th catchpad argument. - /// - Value *getArgOperand(unsigned i) const { return getOperand(i); } - void setArgOperand(unsigned i, Value *v) { setOperand(i, v); } + /// Returns a read-only iterator that points one past the last + /// handler in the CatchSwitchInst. + handler_iterator handler_end() { + return handler_iterator(op_end(), DerefFnTy(handler_helper)); + } + /// Returns an iterator that points one past the last handler in the + /// CatchSwitchInst. + const_handler_iterator handler_end() const { + return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper)); + } - /// arg_operands - iteration adapter for range-for loops. - iterator_range arg_operands() { - return iterator_range(op_begin(), op_end() - 2); + /// handlers - iteration adapter for range-for loops. + handler_range handlers() { + return make_range(handler_begin(), handler_end()); } - /// arg_operands - iteration adapter for range-for loops. - iterator_range arg_operands() const { - return iterator_range(op_begin(), op_end() - 2); + /// handlers - iteration adapter for range-for loops. + const_handler_range handlers() const { + return make_range(handler_begin(), handler_end()); } - /// \brief Wrappers for getting the \c Use of a catchpad argument. - const Use &getArgOperandUse(unsigned i) const { return getOperandUse(i); } - Use &getArgOperandUse(unsigned i) { return getOperandUse(i); } + /// addHandler - Add an entry to the switch instruction... + /// Note: + /// This action invalidates handler_end(). Old handler_end() iterator will + /// point to the added handler. + void addHandler(BasicBlock *Dest); - // get*Dest - Return the destination basic blocks... - BasicBlock *getNormalDest() const { return cast(Op<-2>()); } - BasicBlock *getUnwindDest() const { return cast(Op<-1>()); } - void setNormalDest(BasicBlock *B) { Op<-2>() = B; } - void setUnwindDest(BasicBlock *B) { Op<-1>() = B; } + void removeHandler(handler_iterator HI); - BasicBlock *getSuccessor(unsigned i) const { - assert(i < 2 && "Successor # out of range for catchpad!"); - return i == 0 ? getNormalDest() : getUnwindDest(); + unsigned getNumSuccessors() const { return getNumOperands() - 1; } + BasicBlock *getSuccessor(unsigned Idx) const { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + return cast(getOperand(Idx + 1)); } - - void setSuccessor(unsigned idx, BasicBlock *NewSucc) { - assert(idx < 2 && "Successor # out of range for catchpad!"); - *(&Op<-2>() + idx) = NewSucc; + void setSuccessor(unsigned Idx, BasicBlock *NewSucc) { + assert(Idx < getNumSuccessors() && + "Successor # out of range for catchswitch!"); + setOperand(Idx + 1, 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::CatchPad; + return I->getOpcode() == Instruction::CatchSwitch; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } private: - BasicBlock *getSuccessorV(unsigned idx) const override; + BasicBlock *getSuccessorV(unsigned Idx) const override; unsigned getNumSuccessorsV() const override; - void setSuccessorV(unsigned idx, BasicBlock *B) override; + void setSuccessorV(unsigned Idx, BasicBlock *B) override; }; template <> -struct OperandTraits - : public VariadicOperandTraits {}; +struct OperandTraits : public HungoffOperandTraits<2> {}; -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchPadInst, Value) +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchSwitchInst, Value) //===----------------------------------------------------------------------===// -// TerminatePadInst Class +// CleanupPadInst Class //===----------------------------------------------------------------------===// - -class TerminatePadInst : public TerminatorInst { +class CleanupPadInst : public FuncletPadInst { private: - void init(BasicBlock *BB, ArrayRef Args); - - TerminatePadInst(const TerminatePadInst &TPI); - - explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, unsigned Values, - Instruction *InsertBefore); - explicit TerminatePadInst(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, unsigned Values, - BasicBlock *InsertAtEnd); - -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - TerminatePadInst *cloneImpl() const; + explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertBefore) {} + explicit CleanupPadInst(Value *ParentPad, ArrayRef Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CleanupPad, ParentPad, Args, Values, + NameStr, InsertAtEnd) {} public: - static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB = nullptr, - ArrayRef Args = None, - Instruction *InsertBefore = nullptr) { - unsigned Values = unsigned(Args.size()); - if (BB) - ++Values; - return new (Values) TerminatePadInst(C, BB, Args, Values, InsertBefore); - } - static TerminatePadInst *Create(LLVMContext &C, BasicBlock *BB, - ArrayRef Args, - BasicBlock *InsertAtEnd) { - unsigned Values = unsigned(Args.size()); - if (BB) - ++Values; - return new (Values) TerminatePadInst(C, BB, Args, Values, 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 terminatepad arguments. - /// - unsigned getNumArgOperands() const { - unsigned NumOperands = getNumOperands(); - if (hasUnwindDest()) - return NumOperands - 1; - return NumOperands; - } - - /// getArgOperand/setArgOperand - Return/set the i-th terminatepad 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 arg_operands() { - return iterator_range(op_begin(), arg_end()); - } - - /// arg_operands - iteration adapter for range-for loops. - iterator_range arg_operands() const { - return iterator_range(op_begin(), arg_end()); - } - - /// \brief Wrappers for getting the \c Use of a terminatepad 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(Op<-1>()); + static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertBefore); } - void setUnwindDest(BasicBlock *B) { - assert(B && hasUnwindDest()); - Op<-1>() = B; + static CleanupPadInst *Create(Value *ParentPad, ArrayRef Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CleanupPadInst(ParentPad, Args, Values, NameStr, InsertAtEnd); } - unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } - - // Methods for support type inquiry through isa, cast, and dyn_cast: + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::TerminatePad; + return I->getOpcode() == Instruction::CleanupPad; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(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 - : public VariadicOperandTraits {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(TerminatePadInst, Value) - //===----------------------------------------------------------------------===// -// CleanupPadInst Class +// CatchPadInst Class //===----------------------------------------------------------------------===// - -class CleanupPadInst : public Instruction { +class CatchPadInst : public FuncletPadInst { private: - void init(ArrayRef Args, const Twine &NameStr); - - CleanupPadInst(const CleanupPadInst &CPI); - - explicit CleanupPadInst(LLVMContext &C, ArrayRef Args, - const Twine &NameStr, Instruction *InsertBefore); - explicit CleanupPadInst(LLVMContext &C, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd); - -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - CleanupPadInst *cloneImpl() const; + explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, + unsigned Values, const Twine &NameStr, + Instruction *InsertBefore) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertBefore) {} + explicit CatchPadInst(Value *CatchSwitch, ArrayRef Args, + unsigned Values, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : FuncletPadInst(Instruction::CatchPad, CatchSwitch, Args, Values, + NameStr, InsertAtEnd) {} public: - static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args, - const Twine &NameStr = "", - Instruction *InsertBefore = nullptr) { - return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore); + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef Args, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertBefore); } - static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args, - const Twine &NameStr, BasicBlock *InsertAtEnd) { - return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd); + static CatchPadInst *Create(Value *CatchSwitch, ArrayRef Args, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + unsigned Values = 1 + Args.size(); + return new (Values) + CatchPadInst(CatchSwitch, Args, Values, NameStr, InsertAtEnd); } - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + /// Convenience accessors + CatchSwitchInst *getCatchSwitch() const { + return cast(Op<-1>()); + } + void setCatchSwitch(Value *CatchSwitch) { + assert(CatchSwitch); + Op<-1>() = CatchSwitch; + } - // Methods for support type inquiry through isa, cast, and dyn_cast: + /// \brief Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::CleanupPad; + return I->getOpcode() == Instruction::CatchPad; } static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } }; -template <> -struct OperandTraits - : public VariadicOperandTraits {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value) - //===----------------------------------------------------------------------===// // CatchReturnInst Class //===----------------------------------------------------------------------===// @@ -4146,11 +4112,9 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupPadInst, Value) class CatchReturnInst : public TerminatorInst { CatchReturnInst(const CatchReturnInst &RI); - void init(CatchPadInst *CatchPad, BasicBlock *BB); - CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, - Instruction *InsertBefore); - CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB, - BasicBlock *InsertAtEnd); + void init(Value *CatchPad, BasicBlock *BB); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore); + CatchReturnInst(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. @@ -4158,13 +4122,13 @@ protected: CatchReturnInst *cloneImpl() const; public: - static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, Instruction *InsertBefore = nullptr) { assert(CatchPad); assert(BB); return new (2) CatchReturnInst(CatchPad, BB, InsertBefore); } - static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB, + static CatchReturnInst *Create(Value *CatchPad, BasicBlock *BB, BasicBlock *InsertAtEnd) { assert(CatchPad); assert(BB); @@ -4188,6 +4152,10 @@ public: } unsigned getNumSuccessors() const { return 1; } + Value *getParentPad() const { + return getCatchPad()->getCatchSwitch()->getParentPad(); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return (I->getOpcode() == Instruction::CatchRet); @@ -4208,93 +4176,6 @@ struct OperandTraits DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value) -//===----------------------------------------------------------------------===// -// CleanupEndPadInst Class -//===----------------------------------------------------------------------===// - -class CleanupEndPadInst : public TerminatorInst { -private: - CleanupEndPadInst(const CleanupEndPadInst &CEPI); - - void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB); - CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, Instruction *InsertBefore = nullptr); - CleanupEndPadInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, BasicBlock *InsertAtEnd); - -protected: - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - CleanupEndPadInst *cloneImpl() const; - -public: - static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB = nullptr, - Instruction *InsertBefore = nullptr) { - unsigned Values = UnwindBB ? 2 : 1; - return new (Values) - CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertBefore); - } - static CleanupEndPadInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, - BasicBlock *InsertAtEnd) { - unsigned Values = UnwindBB ? 2 : 1; - return new (Values) - CleanupEndPadInst(CleanupPad, UnwindBB, Values, InsertAtEnd); - } - - /// Provide fast operand accessors - DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - - bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; } - bool unwindsToCaller() const { return !hasUnwindDest(); } - - unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } - - /// Convenience accessors - CleanupPadInst *getCleanupPad() const { - return cast(Op<-1>()); - } - void setCleanupPad(CleanupPadInst *CleanupPad) { - assert(CleanupPad); - Op<-1>() = CleanupPad; - } - - BasicBlock *getUnwindDest() const { - return hasUnwindDest() ? cast(Op<-2>()) : nullptr; - } - void setUnwindDest(BasicBlock *NewDest) { - assert(hasUnwindDest()); - assert(NewDest); - Op<-2>() = NewDest; - } - - // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const Instruction *I) { - return (I->getOpcode() == Instruction::CleanupEndPad); - } - static inline bool classof(const Value *V) { - return isa(V) && classof(cast(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 - : public VariadicOperandTraits {}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupEndPadInst, Value) - //===----------------------------------------------------------------------===// // CleanupReturnInst Class //===----------------------------------------------------------------------===// @@ -4303,11 +4184,11 @@ class CleanupReturnInst : public TerminatorInst { private: CleanupReturnInst(const CleanupReturnInst &RI); - void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB); - CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, Instruction *InsertBefore = nullptr); - CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB, - unsigned Values, BasicBlock *InsertAtEnd); + void init(Value *CleanupPad, BasicBlock *UnwindBB); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + Instruction *InsertBefore = nullptr); + CleanupReturnInst(Value *CleanupPad, BasicBlock *UnwindBB, unsigned Values, + BasicBlock *InsertAtEnd); protected: // Note: Instruction needs to be a friend here to call cloneImpl. @@ -4315,7 +4196,7 @@ protected: CleanupReturnInst *cloneImpl() const; public: - static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, + static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB = nullptr, Instruction *InsertBefore = nullptr) { assert(CleanupPad); @@ -4325,8 +4206,7 @@ public: return new (Values) CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore); } - static CleanupReturnInst *Create(CleanupPadInst *CleanupPad, - BasicBlock *UnwindBB, + static CleanupReturnInst *Create(Value *CleanupPad, BasicBlock *UnwindBB, BasicBlock *InsertAtEnd) { assert(CleanupPad); unsigned Values = 1; @@ -4344,22 +4224,22 @@ public: /// Convenience accessor. CleanupPadInst *getCleanupPad() const { - return cast(Op<-1>()); + return cast(Op<0>()); } void setCleanupPad(CleanupPadInst *CleanupPad) { assert(CleanupPad); - Op<-1>() = CleanupPad; + Op<0>() = CleanupPad; } unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; } BasicBlock *getUnwindDest() const { - return hasUnwindDest() ? cast(Op<-2>()) : nullptr; + return hasUnwindDest() ? cast(Op<1>()) : nullptr; } void setUnwindDest(BasicBlock *NewDest) { assert(NewDest); assert(hasUnwindDest()); - Op<-2>() = NewDest; + Op<1>() = NewDest; } // Methods for support type inquiry through isa, cast, and dyn_cast: