X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FIR%2FInstrTypes.h;h=d84e66c50a3e798dadc064b6f891634a6a0c3bda;hb=deae4ec251bf05937d30db527d1de6685e3f453d;hp=a27859edb59f45e2f1c03a831e868fecdc6971c1;hpb=ec0f0bc6afa8d2c1f427ec55264fc78738b83ef6;p=oota-llvm.git diff --git a/include/llvm/IR/InstrTypes.h b/include/llvm/IR/InstrTypes.h index a27859edb59..d84e66c50a3 100644 --- a/include/llvm/IR/InstrTypes.h +++ b/include/llvm/IR/InstrTypes.h @@ -29,8 +29,8 @@ class LLVMContext; // TerminatorInst Class //===----------------------------------------------------------------------===// -/// TerminatorInst - Subclasses of this class are all able to terminate a basic -/// block. Thus, these are all the flow control type of operations. +/// Subclasses of this class are all able to terminate a basic +/// block. Thus, these are all the flow control type of operations. /// class TerminatorInst : public Instruction { protected: @@ -44,30 +44,26 @@ protected: : Instruction(Ty, iType, Ops, NumOps, InsertAtEnd) {} // Out of line virtual method, so the vtable, etc has a home. - ~TerminatorInst(); + ~TerminatorInst() override; /// Virtual methods - Terminators should overload these and provide inline /// overrides of non-V methods. virtual BasicBlock *getSuccessorV(unsigned idx) const = 0; virtual unsigned getNumSuccessorsV() const = 0; virtual void setSuccessorV(unsigned idx, BasicBlock *B) = 0; - TerminatorInst *clone_impl() const override = 0; public: - /// getNumSuccessors - Return the number of successors that this terminator - /// has. + /// Return the number of successors that this terminator has. unsigned getNumSuccessors() const { return getNumSuccessorsV(); } - /// getSuccessor - Return the specified successor. - /// + /// Return the specified successor. BasicBlock *getSuccessor(unsigned idx) const { return getSuccessorV(idx); } - /// setSuccessor - Update the specified successor to point at the provided - /// block. + /// Update the specified successor to point at the provided block. void setSuccessor(unsigned idx, BasicBlock *B) { setSuccessorV(idx, B); } @@ -79,6 +75,200 @@ public: static inline bool classof(const Value *V) { return isa(V) && classof(cast(V)); } + + // \brief Returns true if this terminator relates to exception handling. + bool isExceptional() const { + switch (getOpcode()) { + case Instruction::CatchPad: + case Instruction::CatchEndPad: + case Instruction::CatchRet: + case Instruction::CleanupEndPad: + case Instruction::CleanupRet: + case Instruction::Invoke: + case Instruction::Resume: + case Instruction::TerminatePad: + return true; + default: + return false; + } + } + + //===--------------------------------------------------------------------===// + // succ_iterator definition + //===--------------------------------------------------------------------===// + + template // Successor Iterator + class SuccIterator : public std::iterator { + typedef std::iterator + super; + + public: + typedef typename super::pointer pointer; + typedef typename super::reference reference; + + private: + Term TermInst; + unsigned idx; + typedef SuccIterator Self; + + inline bool index_is_valid(unsigned idx) { + return idx < TermInst->getNumSuccessors(); + } + + /// \brief Proxy object to allow write access in operator[] + class SuccessorProxy { + Self it; + + public: + explicit SuccessorProxy(const Self &it) : it(it) {} + + SuccessorProxy(const SuccessorProxy &) = default; + + SuccessorProxy &operator=(SuccessorProxy r) { + *this = reference(r); + return *this; + } + + SuccessorProxy &operator=(reference r) { + it.TermInst->setSuccessor(it.idx, r); + return *this; + } + + operator reference() const { return *it; } + }; + + public: + // begin iterator + explicit inline SuccIterator(Term T) : TermInst(T), idx(0) {} + // end iterator + inline SuccIterator(Term T, bool) : TermInst(T) { + if (TermInst) + idx = TermInst->getNumSuccessors(); + else + // Term == NULL happens, if a basic block is not fully constructed and + // consequently getTerminator() returns NULL. In this case we construct + // a SuccIterator which describes a basic block that has zero + // successors. + // Defining SuccIterator for incomplete and malformed CFGs is especially + // useful for debugging. + idx = 0; + } + + /// This is used to interface between code that wants to + /// operate on terminator instructions directly. + unsigned getSuccessorIndex() const { return idx; } + + inline bool operator==(const Self &x) const { return idx == x.idx; } + inline bool operator!=(const Self &x) const { return !operator==(x); } + + inline reference operator*() const { return TermInst->getSuccessor(idx); } + inline pointer operator->() const { return operator*(); } + + inline Self &operator++() { + ++idx; + return *this; + } // Preincrement + + inline Self operator++(int) { // Postincrement + Self tmp = *this; + ++*this; + return tmp; + } + + inline Self &operator--() { + --idx; + return *this; + } // Predecrement + inline Self operator--(int) { // Postdecrement + Self tmp = *this; + --*this; + return tmp; + } + + inline bool operator<(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx < x.idx; + } + + inline bool operator<=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx <= x.idx; + } + inline bool operator>=(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx >= x.idx; + } + + inline bool operator>(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot compare iterators of different blocks!"); + return idx > x.idx; + } + + inline Self &operator+=(int Right) { + unsigned new_idx = idx + Right; + assert(index_is_valid(new_idx) && "Iterator index out of bound"); + idx = new_idx; + return *this; + } + + inline Self operator+(int Right) const { + Self tmp = *this; + tmp += Right; + return tmp; + } + + inline Self &operator-=(int Right) { return operator+=(-Right); } + + inline Self operator-(int Right) const { return operator+(-Right); } + + inline int operator-(const Self &x) const { + assert(TermInst == x.TermInst && + "Cannot work on iterators of different blocks!"); + int distance = idx - x.idx; + return distance; + } + + inline SuccessorProxy operator[](int offset) { + Self tmp = *this; + tmp += offset; + return SuccessorProxy(tmp); + } + + /// Get the source BB of this iterator. + inline BB *getSource() { + assert(TermInst && "Source not available, if basic block was malformed"); + return TermInst->getParent(); + } + }; + + typedef SuccIterator succ_iterator; + typedef SuccIterator + succ_const_iterator; + typedef llvm::iterator_range succ_range; + typedef llvm::iterator_range succ_const_range; + +private: + inline succ_iterator succ_begin() { return succ_iterator(this); } + inline succ_const_iterator succ_begin() const { + return succ_const_iterator(this); + } + inline succ_iterator succ_end() { return succ_iterator(this, true); } + inline succ_const_iterator succ_end() const { + return succ_const_iterator(this, true); + } + +public: + inline succ_range successors() { + return succ_range(succ_begin(), succ_end()); + } + inline succ_const_range successors() const { + return succ_const_range(succ_begin(), succ_end()); + } }; @@ -87,7 +277,7 @@ public: //===----------------------------------------------------------------------===// class UnaryInstruction : public Instruction { - void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + void *operator new(size_t, unsigned) = delete; protected: UnaryInstruction(Type *Ty, unsigned iType, Value *V, @@ -106,7 +296,7 @@ public: } // Out of line virtual method, so the vtable, etc has a home. - ~UnaryInstruction(); + ~UnaryInstruction() override; /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); @@ -136,14 +326,18 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value) //===----------------------------------------------------------------------===// class BinaryOperator : public Instruction { - void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; + void *operator new(size_t, unsigned) = delete; protected: void init(BinaryOps iType); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, Instruction *InsertBefore); BinaryOperator(BinaryOps iType, Value *S1, Value *S2, Type *Ty, const Twine &Name, BasicBlock *InsertAtEnd); - BinaryOperator *clone_impl() const override; + + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + BinaryOperator *cloneImpl() const; + public: // allocate space for exactly two operands void *operator new(size_t s) { @@ -153,7 +347,7 @@ public: /// Transparently provide more efficient getOperand methods. DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); - /// Create() - Construct a binary instruction, given the opcode and the two + /// Construct a binary instruction, given the opcode and the two /// operands. Optionally (if InstBefore is specified) insert the instruction /// into a BasicBlock right before the specified instruction. The specified /// Instruction is allowed to be a dereferenced end iterator. @@ -162,14 +356,14 @@ public: const Twine &Name = Twine(), Instruction *InsertBefore = nullptr); - /// Create() - Construct a binary instruction, given the opcode and the two + /// Construct a binary instruction, given the opcode and the two /// operands. Also automatically insert this instruction to the end of the /// BasicBlock specified. /// static BinaryOperator *Create(BinaryOps Op, Value *S1, Value *S2, const Twine &Name, BasicBlock *InsertAtEnd); - /// Create* - These methods just forward to Create, and are useful when you + /// These methods just forward to Create, and are useful when you /// statically know what type of instruction you're going to create. These /// helpers just save some typing. #define HANDLE_BINARY_INST(N, OPC, CLASS) \ @@ -281,8 +475,7 @@ public: /// Helper functions to construct and inspect unary operations (NEG and NOT) /// via binary operators SUB and XOR: /// - /// CreateNeg, CreateNot - Create the NEG and NOT - /// instructions out of SUB and XOR instructions. + /// Create the NEG and NOT instructions out of SUB and XOR instructions. /// static BinaryOperator *CreateNeg(Value *Op, const Twine &Name = "", Instruction *InsertBefore = nullptr); @@ -305,16 +498,14 @@ public: static BinaryOperator *CreateNot(Value *Op, const Twine &Name, BasicBlock *InsertAtEnd); - /// isNeg, isFNeg, isNot - Check if the given Value is a - /// NEG, FNeg, or NOT instruction. + /// Check if the given Value is a NEG, FNeg, or NOT instruction. /// static bool isNeg(const Value *V); static bool isFNeg(const Value *V, bool IgnoreZeroSign=false); static bool isNot(const Value *V); - /// getNegArgument, getNotArgument - Helper functions to extract the - /// unary argument of a NEG, FNEG or NOT operation implemented via - /// Sub, FSub, or Xor. + /// Helper functions to extract the unary argument of a NEG, FNEG or NOT + /// operation implemented via Sub, FSub, or Xor. /// static const Value *getNegArgument(const Value *BinOp); static Value *getNegArgument( Value *BinOp); @@ -327,37 +518,42 @@ public: return static_cast(Instruction::getOpcode()); } - /// swapOperands - Exchange the two operands to this instruction. + /// Exchange the two operands to this instruction. /// This instruction is safe to use on any binary instruction and /// does not modify the semantics of the instruction. If the instruction /// cannot be reversed (ie, it's a Div), then return true. /// bool swapOperands(); - /// setHasNoUnsignedWrap - Set or clear the nsw flag on this instruction, - /// which must be an operator which supports this flag. See LangRef.html - /// for the meaning of this flag. + /// Set or clear the nsw flag on this instruction, which must be an operator + /// which supports this flag. See LangRef.html for the meaning of this flag. void setHasNoUnsignedWrap(bool b = true); - /// setHasNoSignedWrap - Set or clear the nsw flag on this instruction, - /// which must be an operator which supports this flag. See LangRef.html - /// for the meaning of this flag. + /// Set or clear the nsw flag on this instruction, which must be an operator + /// which supports this flag. See LangRef.html for the meaning of this flag. void setHasNoSignedWrap(bool b = true); - /// setIsExact - Set or clear the exact flag on this instruction, - /// which must be an operator which supports this flag. See LangRef.html - /// for the meaning of this flag. + /// Set or clear the exact flag on this instruction, which must be an operator + /// which supports this flag. See LangRef.html for the meaning of this flag. void setIsExact(bool b = true); - /// hasNoUnsignedWrap - Determine whether the no unsigned wrap flag is set. + /// Determine whether the no unsigned wrap flag is set. bool hasNoUnsignedWrap() const; - /// hasNoSignedWrap - Determine whether the no signed wrap flag is set. + /// Determine whether the no signed wrap flag is set. bool hasNoSignedWrap() const; - /// isExact - Determine whether the exact flag is set. + /// Determine whether the exact flag is set. bool isExact() const; + /// Convenience method to copy supported wrapping, exact, and fast-math flags + /// from V to this instruction. + void copyIRFlags(const Value *V); + + /// Logical 'and' of any supported wrapping, exact, and fast-math flags of + /// V and this instruction. + void andIRFlags(const Value *V); + // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const Instruction *I) { return I->isBinaryOp(); @@ -378,7 +574,7 @@ DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value) // CastInst Class //===----------------------------------------------------------------------===// -/// CastInst - This is the base class for all instructions that perform data +/// This is the base class for all instructions that perform data /// casts. It is simply provided so that instruction category testing /// can be performed with code like: /// @@ -459,7 +655,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a BitCast or a PtrToInt cast instruction + /// @brief Create a BitCast AddrSpaceCast, or a PtrToInt cast instruction. static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which operand is casted @@ -467,7 +663,7 @@ public: BasicBlock *InsertAtEnd ///< The block to insert the instruction into ); - /// @brief Create a BitCast or a PtrToInt cast instruction + /// @brief Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction. static CastInst *CreatePointerCast( Value *S, ///< The pointer value to be casted (operand 0) Type *Ty, ///< The type to which cast should be made @@ -475,6 +671,35 @@ public: Instruction *InsertBefore = nullptr ///< Place to insert the instruction ); + /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + static CastInst *CreatePointerBitCastOrAddrSpaceCast( + Value *S, ///< The pointer value to be casted (operand 0) + Type *Ty, ///< The type to which operand is casted + const Twine &Name, ///< The name for the instruction + BasicBlock *InsertAtEnd ///< The block to insert the instruction into + ); + + /// @brief Create a BitCast or an AddrSpaceCast cast instruction. + static CastInst *CreatePointerBitCastOrAddrSpaceCast( + Value *S, ///< The pointer value to be casted (operand 0) + Type *Ty, ///< The type to which cast should be made + const Twine &Name = "", ///< Name for the instruction + Instruction *InsertBefore = 0 ///< Place to insert the instruction + ); + + /// @brief Create a BitCast, a PtrToInt, or an IntToPTr cast instruction. + /// + /// If the value is a pointer type and the destination an integer type, + /// creates a PtrToInt cast. If the value is an integer type and the + /// destination a pointer type, creates an IntToPtr cast. Otherwise, creates + /// a bitcast. + static CastInst *CreateBitOrPointerCast( + Value *S, ///< The pointer value to be casted (operand 0) + Type *Ty, ///< The type to which cast should be made + const Twine &Name = "", ///< Name for the instruction + Instruction *InsertBefore = 0 ///< Place to insert the instruction + ); + /// @brief Create a ZExt, BitCast, or Trunc for int -> int casts. static CastInst *CreateIntegerCast( Value *S, ///< The pointer value to be casted (operand 0) @@ -537,6 +762,16 @@ public: Type *DestTy ///< The Type to which the value should be cast. ); + /// @brief Check whether a bitcast, inttoptr, or ptrtoint cast between these + /// types is valid and a no-op. + /// + /// This ensures that any pointer<->integer cast has enough bits in the + /// integer and any other cast is a bitcast. + static bool isBitOrNoopPointerCastable( + Type *SrcTy, ///< The Type from which the value should be cast. + Type *DestTy, ///< The Type to which the value should be cast. + const DataLayout &DL); + /// Returns the opcode necessary to cast Val into Ty using usual casting /// rules. /// @brief Infer the opcode for cast operand and type @@ -583,9 +818,9 @@ public: ) const; /// @brief Determine if this cast is a no-op cast. - bool isNoopCast( - const DataLayout *DL ///< DataLayout to get the Int Ptr type from. - ) const; + /// + /// \param DL is the DataLayout to get the Int Ptr type from. + bool isNoopCast(const DataLayout &DL) const; /// Determine how a pair of casts can be eliminated, if they can be at all. /// This is a helper function for both CastInst and ConstantExpr. @@ -636,8 +871,8 @@ public: /// This class is the base class for the comparison instructions. /// @brief Abstract base class of comparison instructions. class CmpInst : public Instruction { - void *operator new(size_t, unsigned) LLVM_DELETED_FUNCTION; - CmpInst() LLVM_DELETED_FUNCTION; + void *operator new(size_t, unsigned) = delete; + CmpInst() = delete; protected: CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS, const Twine &Name = "",