Home | History | Annotate | Download | only in IR
      1 //===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines various classes for working with Instructions and
     11 // ConstantExprs.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_IR_OPERATOR_H
     16 #define LLVM_IR_OPERATOR_H
     17 
     18 #include "llvm/IR/Constants.h"
     19 #include "llvm/IR/DataLayout.h"
     20 #include "llvm/IR/DerivedTypes.h"
     21 #include "llvm/IR/Instruction.h"
     22 #include "llvm/IR/Type.h"
     23 
     24 namespace llvm {
     25 
     26 class GetElementPtrInst;
     27 class BinaryOperator;
     28 class ConstantExpr;
     29 
     30 /// This is a utility class that provides an abstraction for the common
     31 /// functionality between Instructions and ConstantExprs.
     32 class Operator : public User {
     33 private:
     34   // The Operator class is intended to be used as a utility, and is never itself
     35   // instantiated.
     36   void *operator new(size_t, unsigned) = delete;
     37   void *operator new(size_t s) = delete;
     38   Operator() = delete;
     39 
     40 protected:
     41   // NOTE: Cannot use = delete because it's not legal to delete
     42   // an overridden method that's not deleted in the base class. Cannot leave
     43   // this unimplemented because that leads to an ODR-violation.
     44   ~Operator() override;
     45 
     46 public:
     47   /// Return the opcode for this Instruction or ConstantExpr.
     48   unsigned getOpcode() const {
     49     if (const Instruction *I = dyn_cast<Instruction>(this))
     50       return I->getOpcode();
     51     return cast<ConstantExpr>(this)->getOpcode();
     52   }
     53 
     54   /// If V is an Instruction or ConstantExpr, return its opcode.
     55   /// Otherwise return UserOp1.
     56   static unsigned getOpcode(const Value *V) {
     57     if (const Instruction *I = dyn_cast<Instruction>(V))
     58       return I->getOpcode();
     59     if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
     60       return CE->getOpcode();
     61     return Instruction::UserOp1;
     62   }
     63 
     64   static inline bool classof(const Instruction *) { return true; }
     65   static inline bool classof(const ConstantExpr *) { return true; }
     66   static inline bool classof(const Value *V) {
     67     return isa<Instruction>(V) || isa<ConstantExpr>(V);
     68   }
     69 };
     70 
     71 /// Utility class for integer arithmetic operators which may exhibit overflow -
     72 /// Add, Sub, and Mul. It does not include SDiv, despite that operator having
     73 /// the potential for overflow.
     74 class OverflowingBinaryOperator : public Operator {
     75 public:
     76   enum {
     77     NoUnsignedWrap = (1 << 0),
     78     NoSignedWrap   = (1 << 1)
     79   };
     80 
     81 private:
     82   friend class Instruction;
     83   friend class ConstantExpr;
     84   void setHasNoUnsignedWrap(bool B) {
     85     SubclassOptionalData =
     86       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
     87   }
     88   void setHasNoSignedWrap(bool B) {
     89     SubclassOptionalData =
     90       (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
     91   }
     92 
     93 public:
     94   /// Test whether this operation is known to never
     95   /// undergo unsigned overflow, aka the nuw property.
     96   bool hasNoUnsignedWrap() const {
     97     return SubclassOptionalData & NoUnsignedWrap;
     98   }
     99 
    100   /// Test whether this operation is known to never
    101   /// undergo signed overflow, aka the nsw property.
    102   bool hasNoSignedWrap() const {
    103     return (SubclassOptionalData & NoSignedWrap) != 0;
    104   }
    105 
    106   static inline bool classof(const Instruction *I) {
    107     return I->getOpcode() == Instruction::Add ||
    108            I->getOpcode() == Instruction::Sub ||
    109            I->getOpcode() == Instruction::Mul ||
    110            I->getOpcode() == Instruction::Shl;
    111   }
    112   static inline bool classof(const ConstantExpr *CE) {
    113     return CE->getOpcode() == Instruction::Add ||
    114            CE->getOpcode() == Instruction::Sub ||
    115            CE->getOpcode() == Instruction::Mul ||
    116            CE->getOpcode() == Instruction::Shl;
    117   }
    118   static inline bool classof(const Value *V) {
    119     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
    120            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
    121   }
    122 };
    123 
    124 /// A udiv or sdiv instruction, which can be marked as "exact",
    125 /// indicating that no bits are destroyed.
    126 class PossiblyExactOperator : public Operator {
    127 public:
    128   enum {
    129     IsExact = (1 << 0)
    130   };
    131 
    132 private:
    133   friend class Instruction;
    134   friend class ConstantExpr;
    135   void setIsExact(bool B) {
    136     SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
    137   }
    138 
    139 public:
    140   /// Test whether this division is known to be exact, with zero remainder.
    141   bool isExact() const {
    142     return SubclassOptionalData & IsExact;
    143   }
    144 
    145   static bool isPossiblyExactOpcode(unsigned OpC) {
    146     return OpC == Instruction::SDiv ||
    147            OpC == Instruction::UDiv ||
    148            OpC == Instruction::AShr ||
    149            OpC == Instruction::LShr;
    150   }
    151   static inline bool classof(const ConstantExpr *CE) {
    152     return isPossiblyExactOpcode(CE->getOpcode());
    153   }
    154   static inline bool classof(const Instruction *I) {
    155     return isPossiblyExactOpcode(I->getOpcode());
    156   }
    157   static inline bool classof(const Value *V) {
    158     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
    159            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
    160   }
    161 };
    162 
    163 /// Convenience struct for specifying and reasoning about fast-math flags.
    164 class FastMathFlags {
    165 private:
    166   friend class FPMathOperator;
    167   unsigned Flags;
    168   FastMathFlags(unsigned F) : Flags(F) { }
    169 
    170 public:
    171   enum {
    172     UnsafeAlgebra   = (1 << 0),
    173     NoNaNs          = (1 << 1),
    174     NoInfs          = (1 << 2),
    175     NoSignedZeros   = (1 << 3),
    176     AllowReciprocal = (1 << 4)
    177   };
    178 
    179   FastMathFlags() : Flags(0)
    180   { }
    181 
    182   /// Whether any flag is set
    183   bool any() const { return Flags != 0; }
    184 
    185   /// Set all the flags to false
    186   void clear() { Flags = 0; }
    187 
    188   /// Flag queries
    189   bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
    190   bool noInfs() const          { return 0 != (Flags & NoInfs); }
    191   bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
    192   bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
    193   bool unsafeAlgebra() const   { return 0 != (Flags & UnsafeAlgebra); }
    194 
    195   /// Flag setters
    196   void setNoNaNs()          { Flags |= NoNaNs; }
    197   void setNoInfs()          { Flags |= NoInfs; }
    198   void setNoSignedZeros()   { Flags |= NoSignedZeros; }
    199   void setAllowReciprocal() { Flags |= AllowReciprocal; }
    200   void setUnsafeAlgebra() {
    201     Flags |= UnsafeAlgebra;
    202     setNoNaNs();
    203     setNoInfs();
    204     setNoSignedZeros();
    205     setAllowReciprocal();
    206   }
    207 
    208   void operator&=(const FastMathFlags &OtherFlags) {
    209     Flags &= OtherFlags.Flags;
    210   }
    211 };
    212 
    213 
    214 /// Utility class for floating point operations which can have
    215 /// information about relaxed accuracy requirements attached to them.
    216 class FPMathOperator : public Operator {
    217 private:
    218   friend class Instruction;
    219 
    220   void setHasUnsafeAlgebra(bool B) {
    221     SubclassOptionalData =
    222       (SubclassOptionalData & ~FastMathFlags::UnsafeAlgebra) |
    223       (B * FastMathFlags::UnsafeAlgebra);
    224 
    225     // Unsafe algebra implies all the others
    226     if (B) {
    227       setHasNoNaNs(true);
    228       setHasNoInfs(true);
    229       setHasNoSignedZeros(true);
    230       setHasAllowReciprocal(true);
    231     }
    232   }
    233   void setHasNoNaNs(bool B) {
    234     SubclassOptionalData =
    235       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
    236       (B * FastMathFlags::NoNaNs);
    237   }
    238   void setHasNoInfs(bool B) {
    239     SubclassOptionalData =
    240       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
    241       (B * FastMathFlags::NoInfs);
    242   }
    243   void setHasNoSignedZeros(bool B) {
    244     SubclassOptionalData =
    245       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
    246       (B * FastMathFlags::NoSignedZeros);
    247   }
    248   void setHasAllowReciprocal(bool B) {
    249     SubclassOptionalData =
    250       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
    251       (B * FastMathFlags::AllowReciprocal);
    252   }
    253 
    254   /// Convenience function for setting multiple fast-math flags.
    255   /// FMF is a mask of the bits to set.
    256   void setFastMathFlags(FastMathFlags FMF) {
    257     SubclassOptionalData |= FMF.Flags;
    258   }
    259 
    260   /// Convenience function for copying all fast-math flags.
    261   /// All values in FMF are transferred to this operator.
    262   void copyFastMathFlags(FastMathFlags FMF) {
    263     SubclassOptionalData = FMF.Flags;
    264   }
    265 
    266 public:
    267   /// Test whether this operation is permitted to be
    268   /// algebraically transformed, aka the 'A' fast-math property.
    269   bool hasUnsafeAlgebra() const {
    270     return (SubclassOptionalData & FastMathFlags::UnsafeAlgebra) != 0;
    271   }
    272 
    273   /// Test whether this operation's arguments and results are to be
    274   /// treated as non-NaN, aka the 'N' fast-math property.
    275   bool hasNoNaNs() const {
    276     return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
    277   }
    278 
    279   /// Test whether this operation's arguments and results are to be
    280   /// treated as NoN-Inf, aka the 'I' fast-math property.
    281   bool hasNoInfs() const {
    282     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
    283   }
    284 
    285   /// Test whether this operation can treat the sign of zero
    286   /// as insignificant, aka the 'S' fast-math property.
    287   bool hasNoSignedZeros() const {
    288     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
    289   }
    290 
    291   /// Test whether this operation is permitted to use
    292   /// reciprocal instead of division, aka the 'R' fast-math property.
    293   bool hasAllowReciprocal() const {
    294     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
    295   }
    296 
    297   /// Convenience function for getting all the fast-math flags
    298   FastMathFlags getFastMathFlags() const {
    299     return FastMathFlags(SubclassOptionalData);
    300   }
    301 
    302   /// \brief Get the maximum error permitted by this operation in ULPs.  An
    303   /// accuracy of 0.0 means that the operation should be performed with the
    304   /// default precision.
    305   float getFPAccuracy() const;
    306 
    307   static inline bool classof(const Instruction *I) {
    308     return I->getType()->isFPOrFPVectorTy() ||
    309       I->getOpcode() == Instruction::FCmp;
    310   }
    311   static inline bool classof(const Value *V) {
    312     return isa<Instruction>(V) && classof(cast<Instruction>(V));
    313   }
    314 };
    315 
    316 
    317 /// A helper template for defining operators for individual opcodes.
    318 template<typename SuperClass, unsigned Opc>
    319 class ConcreteOperator : public SuperClass {
    320 public:
    321   static inline bool classof(const Instruction *I) {
    322     return I->getOpcode() == Opc;
    323   }
    324   static inline bool classof(const ConstantExpr *CE) {
    325     return CE->getOpcode() == Opc;
    326   }
    327   static inline bool classof(const Value *V) {
    328     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
    329            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
    330   }
    331 };
    332 
    333 class AddOperator
    334   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
    335 };
    336 class SubOperator
    337   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
    338 };
    339 class MulOperator
    340   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
    341 };
    342 class ShlOperator
    343   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
    344 };
    345 
    346 
    347 class SDivOperator
    348   : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
    349 };
    350 class UDivOperator
    351   : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
    352 };
    353 class AShrOperator
    354   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
    355 };
    356 class LShrOperator
    357   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
    358 };
    359 
    360 
    361 class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
    362 
    363 
    364 class GEPOperator
    365   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
    366   enum {
    367     IsInBounds = (1 << 0)
    368   };
    369 
    370   friend class GetElementPtrInst;
    371   friend class ConstantExpr;
    372   void setIsInBounds(bool B) {
    373     SubclassOptionalData =
    374       (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
    375   }
    376 
    377 public:
    378   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
    379   bool isInBounds() const {
    380     return SubclassOptionalData & IsInBounds;
    381   }
    382 
    383   inline op_iterator       idx_begin()       { return op_begin()+1; }
    384   inline const_op_iterator idx_begin() const { return op_begin()+1; }
    385   inline op_iterator       idx_end()         { return op_end(); }
    386   inline const_op_iterator idx_end()   const { return op_end(); }
    387 
    388   Value *getPointerOperand() {
    389     return getOperand(0);
    390   }
    391   const Value *getPointerOperand() const {
    392     return getOperand(0);
    393   }
    394   static unsigned getPointerOperandIndex() {
    395     return 0U;                      // get index for modifying correct operand
    396   }
    397 
    398   /// Method to return the pointer operand as a PointerType.
    399   Type *getPointerOperandType() const {
    400     return getPointerOperand()->getType();
    401   }
    402 
    403   Type *getSourceElementType() const;
    404   Type *getResultElementType() const;
    405 
    406   /// Method to return the address space of the pointer operand.
    407   unsigned getPointerAddressSpace() const {
    408     return getPointerOperandType()->getPointerAddressSpace();
    409   }
    410 
    411   unsigned getNumIndices() const {  // Note: always non-negative
    412     return getNumOperands() - 1;
    413   }
    414 
    415   bool hasIndices() const {
    416     return getNumOperands() > 1;
    417   }
    418 
    419   /// Return true if all of the indices of this GEP are zeros.
    420   /// If so, the result pointer and the first operand have the same
    421   /// value, just potentially different types.
    422   bool hasAllZeroIndices() const {
    423     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
    424       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
    425         if (C->isZero())
    426           continue;
    427       return false;
    428     }
    429     return true;
    430   }
    431 
    432   /// Return true if all of the indices of this GEP are constant integers.
    433   /// If so, the result pointer and the first operand have
    434   /// a constant offset between them.
    435   bool hasAllConstantIndices() const {
    436     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
    437       if (!isa<ConstantInt>(I))
    438         return false;
    439     }
    440     return true;
    441   }
    442 
    443   /// \brief Accumulate the constant address offset of this GEP if possible.
    444   ///
    445   /// This routine accepts an APInt into which it will accumulate the constant
    446   /// offset of this GEP if the GEP is in fact constant. If the GEP is not
    447   /// all-constant, it returns false and the value of the offset APInt is
    448   /// undefined (it is *not* preserved!). The APInt passed into this routine
    449   /// must be at exactly as wide as the IntPtr type for the address space of the
    450   /// base GEP pointer.
    451   bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
    452 };
    453 
    454 class PtrToIntOperator
    455     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
    456   friend class PtrToInt;
    457   friend class ConstantExpr;
    458 
    459 public:
    460   Value *getPointerOperand() {
    461     return getOperand(0);
    462   }
    463   const Value *getPointerOperand() const {
    464     return getOperand(0);
    465   }
    466   static unsigned getPointerOperandIndex() {
    467     return 0U;                      // get index for modifying correct operand
    468   }
    469 
    470   /// Method to return the pointer operand as a PointerType.
    471   Type *getPointerOperandType() const {
    472     return getPointerOperand()->getType();
    473   }
    474 
    475   /// Method to return the address space of the pointer operand.
    476   unsigned getPointerAddressSpace() const {
    477     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
    478   }
    479 };
    480 
    481 class BitCastOperator
    482     : public ConcreteOperator<Operator, Instruction::BitCast> {
    483   friend class BitCastInst;
    484   friend class ConstantExpr;
    485 
    486 public:
    487   Type *getSrcTy() const {
    488     return getOperand(0)->getType();
    489   }
    490 
    491   Type *getDestTy() const {
    492     return getType();
    493   }
    494 };
    495 
    496 } // End llvm namespace
    497 
    498 #endif
    499