X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FOperator.h;h=3aae586f1448c778bdfa59e6b8dd865846b28ac2;hb=d8c5ec6aece5732c766bd7d773ff75976d364168;hp=4da19219d2f4fbbfa724e377b593d38e47c29abb;hpb=ca178908c8dc2303a1fb54a8a93bab0f0b964e11;p=oota-llvm.git diff --git a/include/llvm/Operator.h b/include/llvm/Operator.h index 4da19219d2f..3aae586f144 100644 --- a/include/llvm/Operator.h +++ b/include/llvm/Operator.h @@ -20,6 +20,10 @@ namespace llvm { +class GetElementPtrInst; +class BinaryOperator; +class ConstantExpr; + /// Operator - This is a utility class that provides an abstraction for the /// common functionality between Instructions and ConstantExprs. /// @@ -53,34 +57,49 @@ public: } static inline bool classof(const Operator *) { return true; } - static inline bool classof(const Instruction *I) { return true; } - static inline bool classof(const ConstantExpr *I) { return true; } + static inline bool classof(const Instruction *) { return true; } + static inline bool classof(const ConstantExpr *) { return true; } static inline bool classof(const Value *V) { return isa(V) || isa(V); } }; /// OverflowingBinaryOperator - Utility class for integer arithmetic operators -/// which may exhibit overflow - Add, Sub, and Mul. +/// which may exhibit overflow - Add, Sub, and Mul. It does not include SDiv, +/// despite that operator having the potential for overflow. /// class OverflowingBinaryOperator : public Operator { public: - /// hasNoSignedOverflow - Test whether this operation is known to never - /// undergo signed overflow. - bool hasNoSignedOverflow() const { - return SubclassOptionalData & (1 << 0); + enum { + NoUnsignedWrap = (1 << 0), + NoSignedWrap = (1 << 1) + }; + +private: + ~OverflowingBinaryOperator(); // do not implement + + friend class BinaryOperator; + friend class ConstantExpr; + void setHasNoUnsignedWrap(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap); } - void setHasNoSignedOverflow(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0); + void setHasNoSignedWrap(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); } - /// hasNoUnsignedOverflow - Test whether this operation is known to never - /// undergo unsigned overflow. - bool hasNoUnsignedOverflow() const { - return SubclassOptionalData & (1 << 1); +public: + /// hasNoUnsignedWrap - Test whether this operation is known to never + /// undergo unsigned overflow, aka the nuw property. + bool hasNoUnsignedWrap() const { + return SubclassOptionalData & NoUnsignedWrap; } - void setHasNoUnsignedOverflow(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 1)) | (B << 1); + + /// hasNoSignedWrap - Test whether this operation is known to never + /// undergo signed overflow, aka the nsw property. + bool hasNoSignedWrap() const { + return (SubclassOptionalData & NoSignedWrap) != 0; } static inline bool classof(const OverflowingBinaryOperator *) { return true; } @@ -100,26 +119,181 @@ public: } }; -/// UDivOperator - An Operator with opcode Instruction::UDiv. +/// AddOperator - Utility class for integer addition operators. +/// +class AddOperator : public OverflowingBinaryOperator { + ~AddOperator(); // do not implement +public: + static inline bool classof(const AddOperator *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Add; + } + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::Add; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + +/// SubOperator - Utility class for integer subtraction operators. +/// +class SubOperator : public OverflowingBinaryOperator { + ~SubOperator(); // do not implement +public: + static inline bool classof(const SubOperator *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Sub; + } + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::Sub; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + +/// MulOperator - Utility class for integer multiplication operators. +/// +class MulOperator : public OverflowingBinaryOperator { + ~MulOperator(); // do not implement +public: + static inline bool classof(const MulOperator *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Mul; + } + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::Mul; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + +/// SDivOperator - An Operator with opcode Instruction::SDiv. /// -class UDivOperator : public Operator { +class SDivOperator : public Operator { +public: + enum { + IsExact = (1 << 0) + }; + +private: + ~SDivOperator(); // do not implement + + friend class BinaryOperator; + friend class ConstantExpr; + void setIsExact(bool B) { + SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); + } + public: /// isExact - Test whether this division is known to be exact, with /// zero remainder. bool isExact() const { - return SubclassOptionalData & (1 << 0); + return SubclassOptionalData & IsExact; } - void setIsExact(bool B) { - SubclassOptionalData = (SubclassOptionalData & ~(1 << 0)) | (B << 0); + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const SDivOperator *) { return true; } + static inline bool classof(const ConstantExpr *CE) { + return CE->getOpcode() == Instruction::SDiv; + } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::SDiv; + } + static inline bool classof(const Value *V) { + return (isa(V) && classof(cast(V))) || + (isa(V) && classof(cast(V))); + } +}; + +class GEPOperator : public Operator { + enum { + IsInBounds = (1 << 0) + }; + + ~GEPOperator(); // do not implement + + friend class GetElementPtrInst; + friend class ConstantExpr; + void setIsInBounds(bool B) { + SubclassOptionalData = + (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds); + } + +public: + /// isInBounds - Test whether this is an inbounds GEP, as defined + /// by LangRef.html. + bool isInBounds() const { + return SubclassOptionalData & IsInBounds; + } + + inline op_iterator idx_begin() { return op_begin()+1; } + inline const_op_iterator idx_begin() const { return op_begin()+1; } + inline op_iterator idx_end() { return op_end(); } + inline const_op_iterator idx_end() const { return op_end(); } + + Value *getPointerOperand() { + return getOperand(0); + } + const Value *getPointerOperand() const { + return getOperand(0); + } + static unsigned getPointerOperandIndex() { + return 0U; // get index for modifying correct operand + } + + /// getPointerOperandType - Method to return the pointer operand as a + /// PointerType. + const PointerType *getPointerOperandType() const { + return reinterpret_cast(getPointerOperand()->getType()); + } + + unsigned getNumIndices() const { // Note: always non-negative + return getNumOperands() - 1; + } + + bool hasIndices() const { + return getNumOperands() > 1; + } + + /// hasAllZeroIndices - Return true if all of the indices of this GEP are + /// zeros. If so, the result pointer and the first operand have the same + /// value, just potentially different types. + bool hasAllZeroIndices() const { + for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { + if (Constant *C = dyn_cast(I)) + if (C->isNullValue()) + continue; + return false; + } + return true; + } + + /// hasAllConstantIndices - Return true if all of the indices of this GEP are + /// constant integers. If so, the result pointer and the first operand have + /// a constant offset between them. + bool hasAllConstantIndices() const { + for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) { + if (!isa(I)) + return false; + } + return true; } + // Methods for support type inquiry through isa, cast, and dyn_cast: - static inline bool classof(const UDivOperator *) { return true; } + static inline bool classof(const GEPOperator *) { return true; } + static inline bool classof(const GetElementPtrInst *) { return true; } static inline bool classof(const ConstantExpr *CE) { - return CE->getOpcode() == Instruction::UDiv; + return CE->getOpcode() == Instruction::GetElementPtr; } static inline bool classof(const Instruction *I) { - return I->getOpcode() == Instruction::UDiv; + return I->getOpcode() == Instruction::GetElementPtr; } static inline bool classof(const Value *V) { return (isa(V) && classof(cast(V))) ||