LCOV - code coverage report
Current view: top level - include/llvm/IR - Operator.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 105 111 94.6 %
Date: 2018-10-20 13:21:21 Functions: 7 20 35.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 :   static bool classof(const Instruction *) { return true; }
      58             :   static bool classof(const ConstantExpr *) { return true; }
      59             :   static bool classof(const Value *V) {
      60   180003650 :     return isa<Instruction>(V) || isa<ConstantExpr>(V);
      61             :   }
      62             : };
      63             : 
      64             : /// Utility class for integer operators which may exhibit overflow - Add, Sub,
      65             : /// Mul, and Shl. It does not include SDiv, despite that operator having the
      66             : /// 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      307277 :     SubclassOptionalData =
      80      307277 :       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
      81             :   }
      82             :   void setHasNoSignedWrap(bool B) {
      83      418340 :     SubclassOptionalData =
      84          55 :       (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     1054602 :     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     6694917 :     return (SubclassOptionalData & NoSignedWrap) != 0;
      98             :   }
      99             : 
     100             :   static bool classof(const Instruction *I) {
     101     3523216 :     return I->getOpcode() == Instruction::Add ||
     102     3230557 :            I->getOpcode() == Instruction::Sub ||
     103     8577604 :            I->getOpcode() == Instruction::Mul ||
     104             :            I->getOpcode() == Instruction::Shl;
     105             :   }
     106             :   static bool classof(const ConstantExpr *CE) {
     107      107528 :     return CE->getOpcode() == Instruction::Add ||
     108      106302 :            CE->getOpcode() == Instruction::Sub ||
     109      215553 :            CE->getOpcode() == Instruction::Mul ||
     110             :            CE->getOpcode() == Instruction::Shl;
     111             :   }
     112     4648077 :   static bool classof(const Value *V) {
     113     7281585 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     114     4648077 :            (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           3 :     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      208673 :     return SubclassOptionalData & IsExact;
     138             :   }
     139             : 
     140             :   static bool isPossiblyExactOpcode(unsigned OpC) {
     141     6068761 :     return OpC == Instruction::SDiv ||
     142     6068761 :            OpC == Instruction::UDiv ||
     143     6069657 :            OpC == Instruction::AShr ||
     144             :            OpC == Instruction::LShr;
     145             :   }
     146             : 
     147             :   static bool classof(const ConstantExpr *CE) {
     148             :     return isPossiblyExactOpcode(CE->getOpcode());
     149             :   }
     150             :   static bool classof(const Instruction *I) {
     151             :     return isPossiblyExactOpcode(I->getOpcode());
     152             :   }
     153     6245831 :   static bool classof(const Value *V) {
     154    11841787 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     155     6245831 :            (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) {
     167             :     // If all 7 bits are set, turn this into -1. If the number of bits grows,
     168             :     // this must be updated. This is intended to provide some forward binary
     169             :     // compatibility insurance for the meaning of 'fast' in case bits are added.
     170      123552 :     if (F == 0x7F) Flags = ~0U;
     171             :     else Flags = F;
     172             :   }
     173             : 
     174             : public:
     175             :   // This is how the bits are used in Value::SubclassOptionalData so they
     176             :   // should fit there too.
     177             :   // WARNING: We're out of space. SubclassOptionalData only has 7 bits. New
     178             :   // functionality will require a change in how this information is stored.
     179             :   enum {
     180             :     AllowReassoc    = (1 << 0),
     181             :     NoNaNs          = (1 << 1),
     182             :     NoInfs          = (1 << 2),
     183             :     NoSignedZeros   = (1 << 3),
     184             :     AllowReciprocal = (1 << 4),
     185             :     AllowContract   = (1 << 5),
     186             :     ApproxFunc      = (1 << 6)
     187             :   };
     188             : 
     189    18000773 :   FastMathFlags() = default;
     190             : 
     191           7 :   bool any() const { return Flags != 0; }
     192             :   bool none() const { return Flags == 0; }
     193           2 :   bool all() const { return Flags == ~0U; }
     194             : 
     195           4 :   void clear() { Flags = 0; }
     196        1396 :   void set()   { Flags = ~0U; }
     197             : 
     198             :   /// Flag queries
     199         112 :   bool allowReassoc() const    { return 0 != (Flags & AllowReassoc); }
     200       20084 :   bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
     201         126 :   bool noInfs() const          { return 0 != (Flags & NoInfs); }
     202        5412 :   bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
     203         161 :   bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
     204         112 :   bool allowContract() const   { return 0 != (Flags & AllowContract); }
     205         112 :   bool approxFunc() const      { return 0 != (Flags & ApproxFunc); }
     206             :   /// 'Fast' means all bits are set.
     207         584 :   bool isFast() const          { return all(); }
     208             : 
     209             :   /// Flag setters
     210             :   void setAllowReassoc(bool B = true) {
     211         438 :     Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
     212             :   }
     213             :   void setNoNaNs(bool B = true) {
     214        1098 :     Flags = (Flags & ~NoNaNs) | B * NoNaNs;
     215             :   }
     216             :   void setNoInfs(bool B = true) {
     217         300 :     Flags = (Flags & ~NoInfs) | B * NoInfs;
     218             :   }
     219             :   void setNoSignedZeros(bool B = true) {
     220         724 :     Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
     221             :   }
     222             :   void setAllowReciprocal(bool B = true) {
     223         214 :     Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
     224             :   }
     225             :   void setAllowContract(bool B = true) {
     226         266 :     Flags = (Flags & ~AllowContract) | B * AllowContract;
     227             :   }
     228             :   void setApproxFunc(bool B = true) {
     229         115 :     Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
     230             :   }
     231             :   void setFast(bool B = true) { B ? set() : clear(); }
     232             : 
     233           0 :   void operator&=(const FastMathFlags &OtherFlags) {
     234        7431 :     Flags &= OtherFlags.Flags;
     235           0 :   }
     236             : };
     237             : 
     238             : /// Utility class for floating point operations which can have
     239             : /// information about relaxed accuracy requirements attached to them.
     240             : class FPMathOperator : public Operator {
     241             : private:
     242             :   friend class Instruction;
     243             : 
     244             :   /// 'Fast' means all bits are set.
     245           1 :   void setFast(bool B) {
     246             :     setHasAllowReassoc(B);
     247             :     setHasNoNaNs(B);
     248             :     setHasNoInfs(B);
     249             :     setHasNoSignedZeros(B);
     250             :     setHasAllowReciprocal(B);
     251             :     setHasAllowContract(B);
     252             :     setHasApproxFunc(B);
     253           1 :   }
     254             : 
     255             :   void setHasAllowReassoc(bool B) {
     256           0 :     SubclassOptionalData =
     257           1 :     (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
     258             :     (B * FastMathFlags::AllowReassoc);
     259             :   }
     260             : 
     261             :   void setHasNoNaNs(bool B) {
     262           3 :     SubclassOptionalData =
     263           3 :       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
     264             :       (B * FastMathFlags::NoNaNs);
     265             :   }
     266             : 
     267             :   void setHasNoInfs(bool B) {
     268           2 :     SubclassOptionalData =
     269           2 :       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
     270             :       (B * FastMathFlags::NoInfs);
     271             :   }
     272             : 
     273             :   void setHasNoSignedZeros(bool B) {
     274           1 :     SubclassOptionalData =
     275           1 :       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
     276             :       (B * FastMathFlags::NoSignedZeros);
     277             :   }
     278             : 
     279             :   void setHasAllowReciprocal(bool B) {
     280           3 :     SubclassOptionalData =
     281           3 :       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
     282             :       (B * FastMathFlags::AllowReciprocal);
     283             :   }
     284             : 
     285             :   void setHasAllowContract(bool B) {
     286           1 :     SubclassOptionalData =
     287           1 :         (SubclassOptionalData & ~FastMathFlags::AllowContract) |
     288             :         (B * FastMathFlags::AllowContract);
     289             :   }
     290             : 
     291             :   void setHasApproxFunc(bool B) {
     292           1 :     SubclassOptionalData =
     293           1 :         (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
     294             :         (B * FastMathFlags::ApproxFunc);
     295             :   }
     296             : 
     297             :   /// Convenience function for setting multiple fast-math flags.
     298             :   /// FMF is a mask of the bits to set.
     299             :   void setFastMathFlags(FastMathFlags FMF) {
     300       81069 :     SubclassOptionalData |= FMF.Flags;
     301             :   }
     302             : 
     303             :   /// Convenience function for copying all fast-math flags.
     304             :   /// All values in FMF are transferred to this operator.
     305             :   void copyFastMathFlags(FastMathFlags FMF) {
     306       10107 :     SubclassOptionalData = FMF.Flags;
     307             :   }
     308             : 
     309             : public:
     310             :   /// Test if this operation allows all non-strict floating-point transforms.
     311             :   bool isFast() const {
     312      121541 :     return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
     313             :             (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
     314             :             (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
     315             :             (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
     316             :             (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
     317      121543 :             (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
     318             :             (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
     319             :   }
     320             : 
     321             :   /// Test if this operation may be simplified with reassociative transforms.
     322             :   bool hasAllowReassoc() const {
     323      173168 :     return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
     324             :   }
     325             : 
     326             :   /// Test if this operation's arguments and results are assumed not-NaN.
     327             :   bool hasNoNaNs() const {
     328      174367 :     return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
     329             :   }
     330             : 
     331             :   /// Test if this operation's arguments and results are assumed not-infinite.
     332             :   bool hasNoInfs() const {
     333      241431 :     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
     334             :   }
     335             : 
     336             :   /// Test if this operation can ignore the sign of zero.
     337             :   bool hasNoSignedZeros() const {
     338      249496 :     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
     339             :   }
     340             : 
     341             :   /// Test if this operation can use reciprocal multiply instead of division.
     342             :   bool hasAllowReciprocal() const {
     343      241944 :     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
     344             :   }
     345             : 
     346             :   /// Test if this operation can be floating-point contracted (FMA).
     347             :   bool hasAllowContract() const {
     348      241359 :     return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
     349             :   }
     350             : 
     351             :   /// Test if this operation allows approximations of math library functions or
     352             :   /// intrinsics.
     353             :   bool hasApproxFunc() const {
     354      241357 :     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
     355             :   }
     356             : 
     357             :   /// Convenience function for getting all the fast-math flags
     358             :   FastMathFlags getFastMathFlags() const {
     359      123552 :     return FastMathFlags(SubclassOptionalData);
     360             :   }
     361             : 
     362             :   /// Get the maximum error permitted by this operation in ULPs. An accuracy of
     363             :   /// 0.0 means that the operation should be performed with the default
     364             :   /// precision.
     365             :   float getFPAccuracy() const;
     366             : 
     367    23524842 :   static bool classof(const Value *V) {
     368             :     unsigned Opcode;
     369             :     if (auto *I = dyn_cast<Instruction>(V))
     370             :       Opcode = I->getOpcode();
     371             :     else if (auto *CE = dyn_cast<ConstantExpr>(V))
     372             :       Opcode = CE->getOpcode();
     373             :     else
     374             :       return false;
     375             : 
     376    23521799 :     switch (Opcode) {
     377             :     case Instruction::FCmp:
     378             :       return true;
     379             :     // non math FP Operators (no FMF)
     380      162110 :     case Instruction::ExtractElement:
     381             :     case Instruction::ShuffleVector:
     382             :     case Instruction::InsertElement:
     383      162110 :       return false;
     384    23323288 :     default:
     385    23323288 :       return V->getType()->isFPOrFPVectorTy();
     386             :     }
     387             :   }
     388             : };
     389             : 
     390             : /// A helper template for defining operators for individual opcodes.
     391             : template<typename SuperClass, unsigned Opc>
     392             : class ConcreteOperator : public SuperClass {
     393             : public:
     394             :   static bool classof(const Instruction *I) {
     395           0 :     return I->getOpcode() == Opc;
     396             :   }
     397             :   static bool classof(const ConstantExpr *CE) {
     398           0 :     return CE->getOpcode() == Opc;
     399             :   }
     400             :   static bool classof(const Value *V) {
     401   560522778 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     402   232515580 :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     403             :   }
     404             : };
     405             : 
     406             : class AddOperator
     407             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
     408             : };
     409             : class SubOperator
     410             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
     411             : };
     412             : class MulOperator
     413             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
     414             : };
     415             : class ShlOperator
     416             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
     417             : };
     418             : 
     419             : class SDivOperator
     420             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
     421             : };
     422             : class UDivOperator
     423             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
     424             : };
     425             : class AShrOperator
     426             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
     427             : };
     428             : class LShrOperator
     429             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
     430             : };
     431             : 
     432             : class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
     433             : 
     434             : class GEPOperator
     435             :   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
     436             :   friend class GetElementPtrInst;
     437             :   friend class ConstantExpr;
     438             : 
     439             :   enum {
     440             :     IsInBounds = (1 << 0),
     441             :     // InRangeIndex: bits 1-6
     442             :   };
     443             : 
     444             :   void setIsInBounds(bool B) {
     445     1848725 :     SubclassOptionalData =
     446     1848725 :       (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
     447             :   }
     448             : 
     449             : public:
     450             :   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
     451             :   bool isInBounds() const {
     452    37288635 :     return SubclassOptionalData & IsInBounds;
     453             :   }
     454             : 
     455             :   /// Returns the offset of the index with an inrange attachment, or None if
     456             :   /// none.
     457             :   Optional<unsigned> getInRangeIndex() const {
     458    33448158 :     if (SubclassOptionalData >> 1 == 0) return None;
     459       66504 :     return (SubclassOptionalData >> 1) - 1;
     460             :   }
     461             : 
     462      383216 :   inline op_iterator       idx_begin()       { return op_begin()+1; }
     463    88022932 :   inline const_op_iterator idx_begin() const { return op_begin()+1; }
     464             :   inline op_iterator       idx_end()         { return op_end(); }
     465         188 :   inline const_op_iterator idx_end()   const { return op_end(); }
     466             : 
     467             :   Value *getPointerOperand() {
     468    73732359 :     return getOperand(0);
     469             :   }
     470             :   const Value *getPointerOperand() const {
     471    44974686 :     return getOperand(0);
     472             :   }
     473             :   static unsigned getPointerOperandIndex() {
     474             :     return 0U;                      // get index for modifying correct operand
     475             :   }
     476             : 
     477             :   /// Method to return the pointer operand as a PointerType.
     478             :   Type *getPointerOperandType() const {
     479    21347039 :     return getPointerOperand()->getType();
     480             :   }
     481             : 
     482             :   Type *getSourceElementType() const;
     483             :   Type *getResultElementType() const;
     484             : 
     485             :   /// Method to return the address space of the pointer operand.
     486             :   unsigned getPointerAddressSpace() const {
     487             :     return getPointerOperandType()->getPointerAddressSpace();
     488             :   }
     489             : 
     490             :   unsigned getNumIndices() const {  // Note: always non-negative
     491      271635 :     return getNumOperands() - 1;
     492             :   }
     493             : 
     494             :   bool hasIndices() const {
     495             :     return getNumOperands() > 1;
     496             :   }
     497             : 
     498             :   /// Return true if all of the indices of this GEP are zeros.
     499             :   /// If so, the result pointer and the first operand have the same
     500             :   /// value, just potentially different types.
     501    87972697 :   bool hasAllZeroIndices() const {
     502   198183827 :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     503             :       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
     504   173516997 :         if (C->isZero())
     505             :           continue;
     506             :       return false;
     507             :     }
     508             :     return true;
     509             :   }
     510             : 
     511             :   /// Return true if all of the indices of this GEP are constant integers.
     512             :   /// If so, the result pointer and the first operand have
     513             :   /// a constant offset between them.
     514       50047 :   bool hasAllConstantIndices() const {
     515      110236 :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     516       67713 :       if (!isa<ConstantInt>(I))
     517             :         return false;
     518             :     }
     519             :     return true;
     520             :   }
     521             : 
     522         188 :   unsigned countNonConstantIndices() const {
     523             :     return count_if(make_range(idx_begin(), idx_end()), [](const Use& use) {
     524         208 :         return !isa<ConstantInt>(*use);
     525         188 :       });
     526             :   }
     527             : 
     528             :   /// Accumulate the constant address offset of this GEP if possible.
     529             :   ///
     530             :   /// This routine accepts an APInt into which it will accumulate the constant
     531             :   /// offset of this GEP if the GEP is in fact constant. If the GEP is not
     532             :   /// all-constant, it returns false and the value of the offset APInt is
     533             :   /// undefined (it is *not* preserved!). The APInt passed into this routine
     534             :   /// must be at exactly as wide as the IntPtr type for the address space of the
     535             :   /// base GEP pointer.
     536             :   bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
     537             : };
     538             : 
     539             : class PtrToIntOperator
     540             :     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
     541             :   friend class PtrToInt;
     542             :   friend class ConstantExpr;
     543             : 
     544             : public:
     545             :   Value *getPointerOperand() {
     546             :     return getOperand(0);
     547             :   }
     548             :   const Value *getPointerOperand() const {
     549        1282 :     return getOperand(0);
     550             :   }
     551             : 
     552             :   static unsigned getPointerOperandIndex() {
     553             :     return 0U;                      // get index for modifying correct operand
     554             :   }
     555             : 
     556             :   /// Method to return the pointer operand as a PointerType.
     557             :   Type *getPointerOperandType() const {
     558        1282 :     return getPointerOperand()->getType();
     559             :   }
     560             : 
     561             :   /// Method to return the address space of the pointer operand.
     562             :   unsigned getPointerAddressSpace() const {
     563             :     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
     564             :   }
     565             : };
     566             : 
     567             : class BitCastOperator
     568             :     : public ConcreteOperator<Operator, Instruction::BitCast> {
     569             :   friend class BitCastInst;
     570             :   friend class ConstantExpr;
     571             : 
     572             : public:
     573             :   Type *getSrcTy() const {
     574             :     return getOperand(0)->getType();
     575             :   }
     576             : 
     577             :   Type *getDestTy() const {
     578           2 :     return getType();
     579             :   }
     580             : };
     581             : 
     582             : } // end namespace llvm
     583             : 
     584             : #endif // LLVM_IR_OPERATOR_H

Generated by: LCOV version 1.13