LCOV - code coverage report
Current view: top level - include/llvm/IR - Operator.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 104 105 99.0 %
Date: 2018-06-17 00:07:59 Functions: 9 9 100.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             :   static bool classof(const Instruction *) { return true; }
      58             :   static bool classof(const ConstantExpr *) { return true; }
      59             :   static bool classof(const Value *V) {
      60    95149376 :     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      238306 :     SubclassOptionalData =
      80      238306 :       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
      81             :   }
      82             :   void setHasNoSignedWrap(bool B) {
      83      319059 :     SubclassOptionalData =
      84      319059 :       (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     9620105 :     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    12732080 :     return (SubclassOptionalData & NoSignedWrap) != 0;
      98             :   }
      99             : 
     100             :   static bool classof(const Instruction *I) {
     101     2916126 :     return I->getOpcode() == Instruction::Add ||
     102     2813750 :            I->getOpcode() == Instruction::Sub ||
     103     7059719 :            I->getOpcode() == Instruction::Mul ||
     104             :            I->getOpcode() == Instruction::Shl;
     105             :   }
     106             :   static bool classof(const ConstantExpr *CE) {
     107      102039 :     return CE->getOpcode() == Instruction::Add ||
     108      100915 :            CE->getOpcode() == Instruction::Sub ||
     109      203302 :            CE->getOpcode() == Instruction::Mul ||
     110             :            CE->getOpcode() == Instruction::Shl;
     111             :   }
     112     3681331 :   static bool classof(const Value *V) {
     113     6184013 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     114     3681331 :            (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        5092 :     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      181494 :     return SubclassOptionalData & IsExact;
     138             :   }
     139             : 
     140             :   static bool isPossiblyExactOpcode(unsigned OpC) {
     141     4336435 :     return OpC == Instruction::SDiv ||
     142     4336435 :            OpC == Instruction::UDiv ||
     143     8869946 :            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     4485723 :   static bool classof(const Value *V) {
     154     8933468 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     155     4485723 :            (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       91239 :     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    11852003 :   FastMathFlags() = default;
     190             : 
     191       48081 :   bool any() const { return Flags != 0; }
     192             :   bool none() const { return Flags == 0; }
     193         586 :   bool all() const { return Flags == ~0U; }
     194             : 
     195           4 :   void clear() { Flags = 0; }
     196        1346 :   void set()   { Flags = ~0U; }
     197             : 
     198             :   /// Flag queries
     199         556 :   bool allowReassoc() const    { return 0 != (Flags & AllowReassoc); }
     200       64099 :   bool noNaNs() const          { return 0 != (Flags & NoNaNs); }
     201          14 :   bool noInfs() const          { return 0 != (Flags & NoInfs); }
     202       13342 :   bool noSignedZeros() const   { return 0 != (Flags & NoSignedZeros); }
     203          49 :   bool allowReciprocal() const { return 0 != (Flags & AllowReciprocal); }
     204             :   bool allowContract() const   { return 0 != (Flags & AllowContract); }
     205             :   bool approxFunc() const      { return 0 != (Flags & ApproxFunc); }
     206             :   /// 'Fast' means all bits are set.
     207             :   bool isFast() const          { return all(); }
     208             : 
     209             :   /// Flag setters
     210             :   void setAllowReassoc(bool B = true) {
     211         389 :     Flags = (Flags & ~AllowReassoc) | B * AllowReassoc;
     212             :   }
     213             :   void setNoNaNs(bool B = true) {
     214         964 :     Flags = (Flags & ~NoNaNs) | B * NoNaNs;
     215             :   }
     216             :   void setNoInfs(bool B = true) {
     217         235 :     Flags = (Flags & ~NoInfs) | B * NoInfs;
     218             :   }
     219             :   void setNoSignedZeros(bool B = true) {
     220         583 :     Flags = (Flags & ~NoSignedZeros) | B * NoSignedZeros;
     221             :   }
     222             :   void setAllowReciprocal(bool B = true) {
     223         194 :     Flags = (Flags & ~AllowReciprocal) | B * AllowReciprocal;
     224             :   }
     225             :   void setAllowContract(bool B = true) {
     226        5300 :     Flags = (Flags & ~AllowContract) | B * AllowContract;
     227             :   }
     228             :   void setApproxFunc(bool B = true) {
     229          80 :     Flags = (Flags & ~ApproxFunc) | B * ApproxFunc;
     230             :   }
     231             :   void setFast(bool B = true) { B ? set() : clear(); }
     232             : 
     233             :   void operator&=(const FastMathFlags &OtherFlags) {
     234        7176 :     Flags &= OtherFlags.Flags;
     235             :   }
     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           2 :     SubclassOptionalData =
     263           2 :       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
     264             :       (B * FastMathFlags::NoNaNs);
     265             :   }
     266             : 
     267             :   void setHasNoInfs(bool B) {
     268           1 :     SubclassOptionalData =
     269           1 :       (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       37487 :     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        9042 :     SubclassOptionalData = FMF.Flags;
     307             :   }
     308             : 
     309             : public:
     310             :   /// Test if this operation allows all non-strict floating-point transforms.
     311             :   bool isFast() const {
     312      124216 :     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      124218 :             (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      168517 :     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      313787 :     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      226804 :     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
     334             :   }
     335             : 
     336             :   /// Test if this operation can ignore the sign of zero.
     337             :   bool hasNoSignedZeros() const {
     338      233756 :     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
     339             :   }
     340             : 
     341             :   /// Test if this operation can use reciprocal multiply instead of division.
     342             :   bool hasAllowReciprocal() const {
     343      227323 :     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
     344             :   }
     345             : 
     346             :   /// Test if this operation can be floating-point contracted (FMA).
     347             :   bool hasAllowContract() const {
     348      226808 :     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      226806 :     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
     355             :   }
     356             : 
     357             :   /// Convenience function for getting all the fast-math flags
     358             :   FastMathFlags getFastMathFlags() const {
     359       91239 :     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    11783670 :   static bool classof(const Instruction *I) {
     368    23294804 :     return I->getType()->isFPOrFPVectorTy() ||
     369    11783670 :       I->getOpcode() == Instruction::FCmp;
     370             :   }
     371             : 
     372      102255 :   static bool classof(const ConstantExpr *CE) {
     373      204430 :     return CE->getType()->isFPOrFPVectorTy() ||
     374      102255 :            CE->getOpcode() == Instruction::FCmp;
     375             :   }
     376             : 
     377     2664522 :   static bool classof(const Value *V) {
     378     2664522 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     379      102255 :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     380             :   }
     381             : };
     382             : 
     383             : /// A helper template for defining operators for individual opcodes.
     384             : template<typename SuperClass, unsigned Opc>
     385             : class ConcreteOperator : public SuperClass {
     386             : public:
     387             :   static bool classof(const Instruction *I) {
     388             :     return I->getOpcode() == Opc;
     389             :   }
     390             :   static bool classof(const ConstantExpr *CE) {
     391             :     return CE->getOpcode() == Opc;
     392             :   }
     393             :   static bool classof(const Value *V) {
     394   279231294 :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     395    97727244 :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     396             :   }
     397             : };
     398             : 
     399             : class AddOperator
     400             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
     401             : };
     402             : class SubOperator
     403             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
     404             : };
     405             : class MulOperator
     406             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
     407             : };
     408             : class ShlOperator
     409             :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
     410             : };
     411             : 
     412             : class SDivOperator
     413             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
     414             : };
     415             : class UDivOperator
     416             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
     417             : };
     418             : class AShrOperator
     419             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
     420             : };
     421             : class LShrOperator
     422             :   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
     423             : };
     424             : 
     425             : class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
     426             : 
     427             : class GEPOperator
     428             :   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
     429             :   friend class GetElementPtrInst;
     430             :   friend class ConstantExpr;
     431             : 
     432             :   enum {
     433             :     IsInBounds = (1 << 0),
     434             :     // InRangeIndex: bits 1-6
     435             :   };
     436             : 
     437             :   void setIsInBounds(bool B) {
     438      384113 :     SubclassOptionalData =
     439      384113 :       (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
     440             :   }
     441             : 
     442             : public:
     443             :   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
     444             :   bool isInBounds() const {
     445    18161748 :     return SubclassOptionalData & IsInBounds;
     446             :   }
     447             : 
     448             :   /// Returns the offset of the index with an inrange attachment, or None if
     449             :   /// none.
     450             :   Optional<unsigned> getInRangeIndex() const {
     451    20696445 :     if (SubclassOptionalData >> 1 == 0) return None;
     452       46637 :     return (SubclassOptionalData >> 1) - 1;
     453             :   }
     454             : 
     455      340454 :   inline op_iterator       idx_begin()       { return op_begin()+1; }
     456    86543772 :   inline const_op_iterator idx_begin() const { return op_begin()+1; }
     457             :   inline op_iterator       idx_end()         { return op_end(); }
     458          18 :   inline const_op_iterator idx_end()   const { return op_end(); }
     459             : 
     460             :   Value *getPointerOperand() {
     461    34986889 :     return getOperand(0);
     462             :   }
     463             :   const Value *getPointerOperand() const {
     464    22158678 :     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     5359961 :     return getPointerOperand()->getType();
     473             :   }
     474             : 
     475             :   Type *getSourceElementType() const;
     476             :   Type *getResultElementType() const;
     477             : 
     478             :   /// Method to return the address space of the pointer operand.
     479             :   unsigned getPointerAddressSpace() const {
     480             :     return getPointerOperandType()->getPointerAddressSpace();
     481             :   }
     482             : 
     483             :   unsigned getNumIndices() const {  // Note: always non-negative
     484     1208679 :     return getNumOperands() - 1;
     485             :   }
     486             : 
     487             :   bool hasIndices() const {
     488             :     return getNumOperands() > 1;
     489             :   }
     490             : 
     491             :   /// Return true if all of the indices of this GEP are zeros.
     492             :   /// If so, the result pointer and the first operand have the same
     493             :   /// value, just potentially different types.
     494    43257490 :   bool hasAllZeroIndices() const {
     495   161550502 :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     496             :       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
     497    83243919 :         if (C->isZero())
     498             :           continue;
     499             :       return false;
     500             :     }
     501             :     return true;
     502             :   }
     503             : 
     504             :   /// Return true if all of the indices of this GEP are constant integers.
     505             :   /// If so, the result pointer and the first operand have
     506             :   /// a constant offset between them.
     507       14387 :   bool hasAllConstantIndices() const {
     508       51093 :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     509       19909 :       if (!isa<ConstantInt>(I))
     510             :         return false;
     511             :     }
     512             :     return true;
     513             :   }
     514             : 
     515          18 :   unsigned countNonConstantIndices() const {
     516             :     return count_if(make_range(idx_begin(), idx_end()), [](const Use& use) {
     517          38 :         return !isa<ConstantInt>(*use);
     518          18 :       });
     519             :   }
     520             : 
     521             :   /// Accumulate the constant address offset of this GEP if possible.
     522             :   ///
     523             :   /// This routine accepts an APInt into which it will accumulate the constant
     524             :   /// offset of this GEP if the GEP is in fact constant. If the GEP is not
     525             :   /// all-constant, it returns false and the value of the offset APInt is
     526             :   /// undefined (it is *not* preserved!). The APInt passed into this routine
     527             :   /// must be at exactly as wide as the IntPtr type for the address space of the
     528             :   /// base GEP pointer.
     529             :   bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const;
     530             : };
     531             : 
     532             : class PtrToIntOperator
     533             :     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
     534             :   friend class PtrToInt;
     535             :   friend class ConstantExpr;
     536             : 
     537             : public:
     538             :   Value *getPointerOperand() {
     539             :     return getOperand(0);
     540             :   }
     541             :   const Value *getPointerOperand() const {
     542         454 :     return getOperand(0);
     543             :   }
     544             : 
     545             :   static unsigned getPointerOperandIndex() {
     546             :     return 0U;                      // get index for modifying correct operand
     547             :   }
     548             : 
     549             :   /// Method to return the pointer operand as a PointerType.
     550             :   Type *getPointerOperandType() const {
     551         454 :     return getPointerOperand()->getType();
     552             :   }
     553             : 
     554             :   /// Method to return the address space of the pointer operand.
     555             :   unsigned getPointerAddressSpace() const {
     556             :     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
     557             :   }
     558             : };
     559             : 
     560             : class BitCastOperator
     561             :     : public ConcreteOperator<Operator, Instruction::BitCast> {
     562             :   friend class BitCastInst;
     563             :   friend class ConstantExpr;
     564             : 
     565             : public:
     566             :   Type *getSrcTy() const {
     567             :     return getOperand(0)->getType();
     568             :   }
     569             : 
     570             :   Type *getDestTy() const {
     571             :     return getType();
     572             :   }
     573             : };
     574             : 
     575             : } // end namespace llvm
     576             : 
     577             : #endif // LLVM_IR_OPERATOR_H

Generated by: LCOV version 1.13