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