| //===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines various classes for working with Instructions and |
| // ConstantExprs. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_OPERATOR_H |
| #define LLVM_OPERATOR_H |
| |
| #include "llvm/Instruction.h" |
| #include "llvm/Constants.h" |
| |
| 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. |
| /// |
| class Operator : public User { |
| private: |
| // Do not implement any of these. The Operator class is intended to be used |
| // as a utility, and is never itself instantiated. |
| void *operator new(size_t, unsigned); |
| void *operator new(size_t s); |
| Operator(); |
| ~Operator(); |
| |
| public: |
| /// getOpcode - Return the opcode for this Instruction or ConstantExpr. |
| /// |
| unsigned getOpcode() const { |
| if (const Instruction *I = dyn_cast<Instruction>(this)) |
| return I->getOpcode(); |
| return cast<ConstantExpr>(this)->getOpcode(); |
| } |
| |
| /// getOpcode - If V is an Instruction or ConstantExpr, return its |
| /// opcode. Otherwise return UserOp1. |
| /// |
| static unsigned getOpcode(const Value *V) { |
| if (const Instruction *I = dyn_cast<Instruction>(V)) |
| return I->getOpcode(); |
| if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) |
| return CE->getOpcode(); |
| return Instruction::UserOp1; |
| } |
| |
| static inline bool classof(const Operator *) { 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<Instruction>(V) || isa<ConstantExpr>(V); |
| } |
| }; |
| |
| /// OverflowingBinaryOperator - Utility class for integer arithmetic operators |
| /// 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: |
| 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 setHasNoSignedWrap(bool B) { |
| SubclassOptionalData = |
| (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap); |
| } |
| |
| public: |
| /// hasNoUnsignedWrap - Test whether this operation is known to never |
| /// undergo unsigned overflow, aka the nuw property. |
| bool hasNoUnsignedWrap() const { |
| return SubclassOptionalData & NoUnsignedWrap; |
| } |
| |
| /// 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; } |
| static inline bool classof(const Instruction *I) { |
| return I->getOpcode() == Instruction::Add || |
| I->getOpcode() == Instruction::Sub || |
| I->getOpcode() == Instruction::Mul || |
| I->getOpcode() == Instruction::Shl; |
| } |
| static inline bool classof(const ConstantExpr *CE) { |
| return CE->getOpcode() == Instruction::Add || |
| CE->getOpcode() == Instruction::Sub || |
| CE->getOpcode() == Instruction::Mul || |
| CE->getOpcode() == Instruction::Shl; |
| } |
| static inline bool classof(const Value *V) { |
| return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || |
| (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); |
| } |
| }; |
| |
| /// PossiblyExactOperator - A udiv or sdiv instruction, which can be marked as |
| /// "exact", indicating that no bits are destroyed. |
| class PossiblyExactOperator : public Operator { |
| public: |
| enum { |
| IsExact = (1 << 0) |
| }; |
| |
| friend class BinaryOperator; |
| friend class ConstantExpr; |
| void setIsExact(bool B) { |
| SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact); |
| } |
| |
| private: |
| ~PossiblyExactOperator(); // do not implement |
| public: |
| /// isExact - Test whether this division is known to be exact, with |
| /// zero remainder. |
| bool isExact() const { |
| return SubclassOptionalData & IsExact; |
| } |
| |
| static bool isPossiblyExactOpcode(unsigned OpC) { |
| return OpC == Instruction::SDiv || |
| OpC == Instruction::UDiv || |
| OpC == Instruction::AShr || |
| OpC == Instruction::LShr; |
| } |
| static inline bool classof(const ConstantExpr *CE) { |
| return isPossiblyExactOpcode(CE->getOpcode()); |
| } |
| static inline bool classof(const Instruction *I) { |
| return isPossiblyExactOpcode(I->getOpcode()); |
| } |
| static inline bool classof(const Value *V) { |
| return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || |
| (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); |
| } |
| }; |
| |
| |
| |
| /// ConcreteOperator - A helper template for defining operators for individual |
| /// opcodes. |
| template<typename SuperClass, unsigned Opc> |
| class ConcreteOperator : public SuperClass { |
| ~ConcreteOperator(); // DO NOT IMPLEMENT |
| public: |
| static inline bool classof(const ConcreteOperator<SuperClass, Opc> *) { |
| return true; |
| } |
| static inline bool classof(const Instruction *I) { |
| return I->getOpcode() == Opc; |
| } |
| static inline bool classof(const ConstantExpr *CE) { |
| return CE->getOpcode() == Opc; |
| } |
| static inline bool classof(const Value *V) { |
| return (isa<Instruction>(V) && classof(cast<Instruction>(V))) || |
| (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V))); |
| } |
| }; |
| |
| class AddOperator |
| : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> { |
| ~AddOperator(); // DO NOT IMPLEMENT |
| }; |
| class SubOperator |
| : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> { |
| ~SubOperator(); // DO NOT IMPLEMENT |
| }; |
| class MulOperator |
| : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> { |
| ~MulOperator(); // DO NOT IMPLEMENT |
| }; |
| class ShlOperator |
| : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> { |
| ~ShlOperator(); // DO NOT IMPLEMENT |
| }; |
| |
| |
| class SDivOperator |
| : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> { |
| ~SDivOperator(); // DO NOT IMPLEMENT |
| }; |
| class UDivOperator |
| : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> { |
| ~UDivOperator(); // DO NOT IMPLEMENT |
| }; |
| class AShrOperator |
| : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> { |
| ~AShrOperator(); // DO NOT IMPLEMENT |
| }; |
| class LShrOperator |
| : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> { |
| ~LShrOperator(); // DO NOT IMPLEMENT |
| }; |
| |
| |
| |
| class GEPOperator |
| : public ConcreteOperator<Operator, Instruction::GetElementPtr> { |
| ~GEPOperator(); // DO NOT IMPLEMENT |
| |
| enum { |
| IsInBounds = (1 << 0) |
| }; |
| |
| 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. |
| PointerType *getPointerOperandType() const { |
| return reinterpret_cast<PointerType*>(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 (ConstantInt *C = dyn_cast<ConstantInt>(I)) |
| if (C->isZero()) |
| 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<ConstantInt>(I)) |
| return false; |
| } |
| return true; |
| } |
| }; |
| |
| } // End llvm namespace |
| |
| #endif |