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