LCOV - code coverage report
Current view: top level - /usr/lib/llvm-19/include/llvm/IR - Operator.h (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 0.0 % 14 0
Test Date: 2026-02-27 05:14:50 Functions: 0.0 % 1 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : //===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
       2              : //
       3              : // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4              : // See https://llvm.org/LICENSE.txt for license information.
       5              : // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6              : //
       7              : //===----------------------------------------------------------------------===//
       8              : //
       9              : // This file defines various classes for working with Instructions and
      10              : // ConstantExprs.
      11              : //
      12              : //===----------------------------------------------------------------------===//
      13              : 
      14              : #ifndef LLVM_IR_OPERATOR_H
      15              : #define LLVM_IR_OPERATOR_H
      16              : 
      17              : #include "llvm/ADT/MapVector.h"
      18              : #include "llvm/IR/Constants.h"
      19              : #include "llvm/IR/FMF.h"
      20              : #include "llvm/IR/GEPNoWrapFlags.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              : #include <optional>
      27              : 
      28              : namespace llvm {
      29              : 
      30              : /// This is a utility class that provides an abstraction for the common
      31              : /// functionality between Instructions and ConstantExprs.
      32              : class Operator : public User {
      33              : public:
      34              :   // The Operator class is intended to be used as a utility, and is never itself
      35              :   // instantiated.
      36              :   Operator() = delete;
      37              :   ~Operator() = delete;
      38              : 
      39              :   void *operator new(size_t s) = delete;
      40              : 
      41              :   /// Return the opcode for this Instruction or ConstantExpr.
      42              :   unsigned getOpcode() const {
      43              :     if (const Instruction *I = dyn_cast<Instruction>(this))
      44              :       return I->getOpcode();
      45              :     return cast<ConstantExpr>(this)->getOpcode();
      46              :   }
      47              : 
      48              :   /// If V is an Instruction or ConstantExpr, return its opcode.
      49              :   /// Otherwise return UserOp1.
      50              :   static unsigned getOpcode(const Value *V) {
      51              :     if (const Instruction *I = dyn_cast<Instruction>(V))
      52              :       return I->getOpcode();
      53              :     if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
      54              :       return CE->getOpcode();
      55              :     return Instruction::UserOp1;
      56              :   }
      57              : 
      58              :   static bool classof(const Instruction *) { return true; }
      59              :   static bool classof(const ConstantExpr *) { return true; }
      60              :   static bool classof(const Value *V) {
      61              :     return isa<Instruction>(V) || isa<ConstantExpr>(V);
      62              :   }
      63              : 
      64              :   /// Return true if this operator has flags which may cause this operator
      65              :   /// to evaluate to poison despite having non-poison inputs.
      66              :   bool hasPoisonGeneratingFlags() const;
      67              : 
      68              :   /// Return true if this operator has poison-generating flags,
      69              :   /// return attributes or metadata. The latter two is only possible for
      70              :   /// instructions.
      71              :   bool hasPoisonGeneratingAnnotations() const;
      72              : };
      73              : 
      74              : /// Utility class for integer operators which may exhibit overflow - Add, Sub,
      75              : /// Mul, and Shl. It does not include SDiv, despite that operator having the
      76              : /// potential for overflow.
      77              : class OverflowingBinaryOperator : public Operator {
      78              : public:
      79              :   enum {
      80              :     AnyWrap        = 0,
      81              :     NoUnsignedWrap = (1 << 0),
      82              :     NoSignedWrap   = (1 << 1)
      83              :   };
      84              : 
      85              : private:
      86              :   friend class Instruction;
      87              :   friend class ConstantExpr;
      88              : 
      89              :   void setHasNoUnsignedWrap(bool B) {
      90              :     SubclassOptionalData =
      91              :       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
      92              :   }
      93              :   void setHasNoSignedWrap(bool B) {
      94              :     SubclassOptionalData =
      95              :       (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
      96              :   }
      97              : 
      98              : public:
      99              :   /// Transparently provide more efficient getOperand methods.
     100              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     101              : 
     102              :   /// Test whether this operation is known to never
     103              :   /// undergo unsigned overflow, aka the nuw property.
     104              :   bool hasNoUnsignedWrap() const {
     105              :     return SubclassOptionalData & NoUnsignedWrap;
     106              :   }
     107              : 
     108              :   /// Test whether this operation is known to never
     109              :   /// undergo signed overflow, aka the nsw property.
     110              :   bool hasNoSignedWrap() const {
     111              :     return (SubclassOptionalData & NoSignedWrap) != 0;
     112              :   }
     113              : 
     114              :   /// Returns the no-wrap kind of the operation.
     115              :   unsigned getNoWrapKind() const {
     116              :     unsigned NoWrapKind = 0;
     117              :     if (hasNoUnsignedWrap())
     118              :       NoWrapKind |= NoUnsignedWrap;
     119              : 
     120              :     if (hasNoSignedWrap())
     121              :       NoWrapKind |= NoSignedWrap;
     122              : 
     123              :     return NoWrapKind;
     124              :   }
     125              : 
     126              :   static bool classof(const Instruction *I) {
     127              :     return I->getOpcode() == Instruction::Add ||
     128              :            I->getOpcode() == Instruction::Sub ||
     129              :            I->getOpcode() == Instruction::Mul ||
     130              :            I->getOpcode() == Instruction::Shl;
     131              :   }
     132              :   static bool classof(const ConstantExpr *CE) {
     133              :     return CE->getOpcode() == Instruction::Add ||
     134              :            CE->getOpcode() == Instruction::Sub ||
     135              :            CE->getOpcode() == Instruction::Mul ||
     136              :            CE->getOpcode() == Instruction::Shl;
     137              :   }
     138              :   static bool classof(const Value *V) {
     139              :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     140              :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     141              :   }
     142              : };
     143              : 
     144              : template <>
     145              : struct OperandTraits<OverflowingBinaryOperator>
     146              :     : public FixedNumOperandTraits<OverflowingBinaryOperator, 2> {};
     147              : 
     148              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(OverflowingBinaryOperator, Value)
     149              : 
     150              : /// A udiv or sdiv instruction, which can be marked as "exact",
     151              : /// indicating that no bits are destroyed.
     152              : class PossiblyExactOperator : public Operator {
     153              : public:
     154              :   enum {
     155              :     IsExact = (1 << 0)
     156              :   };
     157              : 
     158              : private:
     159              :   friend class Instruction;
     160              :   friend class ConstantExpr;
     161              : 
     162              :   void setIsExact(bool B) {
     163              :     SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
     164              :   }
     165              : 
     166              : public:
     167              :   /// Transparently provide more efficient getOperand methods.
     168              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     169              : 
     170              :   /// Test whether this division is known to be exact, with zero remainder.
     171              :   bool isExact() const {
     172              :     return SubclassOptionalData & IsExact;
     173              :   }
     174              : 
     175              :   static bool isPossiblyExactOpcode(unsigned OpC) {
     176              :     return OpC == Instruction::SDiv ||
     177              :            OpC == Instruction::UDiv ||
     178              :            OpC == Instruction::AShr ||
     179              :            OpC == Instruction::LShr;
     180              :   }
     181              : 
     182              :   static bool classof(const ConstantExpr *CE) {
     183              :     return isPossiblyExactOpcode(CE->getOpcode());
     184              :   }
     185              :   static bool classof(const Instruction *I) {
     186              :     return isPossiblyExactOpcode(I->getOpcode());
     187              :   }
     188              :   static bool classof(const Value *V) {
     189              :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     190              :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     191              :   }
     192              : };
     193              : 
     194              : template <>
     195              : struct OperandTraits<PossiblyExactOperator>
     196              :     : public FixedNumOperandTraits<PossiblyExactOperator, 2> {};
     197              : 
     198              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PossiblyExactOperator, Value)
     199              : 
     200              : /// Utility class for floating point operations which can have
     201              : /// information about relaxed accuracy requirements attached to them.
     202              : class FPMathOperator : public Operator {
     203              : private:
     204              :   friend class Instruction;
     205              : 
     206              :   /// 'Fast' means all bits are set.
     207              :   void setFast(bool B) {
     208              :     setHasAllowReassoc(B);
     209              :     setHasNoNaNs(B);
     210              :     setHasNoInfs(B);
     211              :     setHasNoSignedZeros(B);
     212              :     setHasAllowReciprocal(B);
     213              :     setHasAllowContract(B);
     214              :     setHasApproxFunc(B);
     215              :   }
     216              : 
     217              :   void setHasAllowReassoc(bool B) {
     218              :     SubclassOptionalData =
     219              :     (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
     220              :     (B * FastMathFlags::AllowReassoc);
     221              :   }
     222              : 
     223              :   void setHasNoNaNs(bool B) {
     224              :     SubclassOptionalData =
     225              :       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
     226              :       (B * FastMathFlags::NoNaNs);
     227              :   }
     228              : 
     229              :   void setHasNoInfs(bool B) {
     230              :     SubclassOptionalData =
     231              :       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
     232              :       (B * FastMathFlags::NoInfs);
     233              :   }
     234              : 
     235              :   void setHasNoSignedZeros(bool B) {
     236              :     SubclassOptionalData =
     237              :       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
     238              :       (B * FastMathFlags::NoSignedZeros);
     239              :   }
     240              : 
     241              :   void setHasAllowReciprocal(bool B) {
     242              :     SubclassOptionalData =
     243              :       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
     244              :       (B * FastMathFlags::AllowReciprocal);
     245              :   }
     246              : 
     247              :   void setHasAllowContract(bool B) {
     248              :     SubclassOptionalData =
     249              :         (SubclassOptionalData & ~FastMathFlags::AllowContract) |
     250              :         (B * FastMathFlags::AllowContract);
     251              :   }
     252              : 
     253              :   void setHasApproxFunc(bool B) {
     254              :     SubclassOptionalData =
     255              :         (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
     256              :         (B * FastMathFlags::ApproxFunc);
     257              :   }
     258              : 
     259              :   /// Convenience function for setting multiple fast-math flags.
     260              :   /// FMF is a mask of the bits to set.
     261              :   void setFastMathFlags(FastMathFlags FMF) {
     262              :     SubclassOptionalData |= FMF.Flags;
     263              :   }
     264              : 
     265              :   /// Convenience function for copying all fast-math flags.
     266              :   /// All values in FMF are transferred to this operator.
     267              :   void copyFastMathFlags(FastMathFlags FMF) {
     268              :     SubclassOptionalData = FMF.Flags;
     269              :   }
     270              : 
     271              : public:
     272              :   /// Test if this operation allows all non-strict floating-point transforms.
     273              :   bool isFast() const {
     274              :     return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
     275              :             (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
     276              :             (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
     277              :             (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
     278              :             (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
     279              :             (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
     280              :             (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
     281              :   }
     282              : 
     283              :   /// Test if this operation may be simplified with reassociative transforms.
     284              :   bool hasAllowReassoc() const {
     285              :     return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
     286              :   }
     287              : 
     288              :   /// Test if this operation's arguments and results are assumed not-NaN.
     289              :   bool hasNoNaNs() const {
     290              :     return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
     291              :   }
     292              : 
     293              :   /// Test if this operation's arguments and results are assumed not-infinite.
     294              :   bool hasNoInfs() const {
     295              :     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
     296              :   }
     297              : 
     298              :   /// Test if this operation can ignore the sign of zero.
     299              :   bool hasNoSignedZeros() const {
     300              :     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
     301              :   }
     302              : 
     303              :   /// Test if this operation can use reciprocal multiply instead of division.
     304              :   bool hasAllowReciprocal() const {
     305              :     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
     306              :   }
     307              : 
     308              :   /// Test if this operation can be floating-point contracted (FMA).
     309              :   bool hasAllowContract() const {
     310              :     return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
     311              :   }
     312              : 
     313              :   /// Test if this operation allows approximations of math library functions or
     314              :   /// intrinsics.
     315              :   bool hasApproxFunc() const {
     316              :     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
     317              :   }
     318              : 
     319              :   /// Convenience function for getting all the fast-math flags
     320              :   FastMathFlags getFastMathFlags() const {
     321              :     return FastMathFlags(SubclassOptionalData);
     322              :   }
     323              : 
     324              :   /// Get the maximum error permitted by this operation in ULPs. An accuracy of
     325              :   /// 0.0 means that the operation should be performed with the default
     326              :   /// precision.
     327              :   float getFPAccuracy() const;
     328              : 
     329            0 :   static bool classof(const Value *V) {
     330              :     unsigned Opcode;
     331            0 :     if (auto *I = dyn_cast<Instruction>(V))
     332            0 :       Opcode = I->getOpcode();
     333              :     else
     334            0 :       return false;
     335              : 
     336            0 :     switch (Opcode) {
     337            0 :     case Instruction::FNeg:
     338              :     case Instruction::FAdd:
     339              :     case Instruction::FSub:
     340              :     case Instruction::FMul:
     341              :     case Instruction::FDiv:
     342              :     case Instruction::FRem:
     343              :     // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp
     344              :     //        should not be treated as a math op, but the other opcodes should.
     345              :     //        This would make things consistent with Select/PHI (FP value type
     346              :     //        determines whether they are math ops and, therefore, capable of
     347              :     //        having fast-math-flags).
     348              :     case Instruction::FCmp:
     349            0 :       return true;
     350            0 :     case Instruction::PHI:
     351              :     case Instruction::Select:
     352              :     case Instruction::Call: {
     353            0 :       Type *Ty = V->getType();
     354            0 :       while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
     355            0 :         Ty = ArrTy->getElementType();
     356            0 :       return Ty->isFPOrFPVectorTy();
     357              :     }
     358            0 :     default:
     359            0 :       return false;
     360              :     }
     361              :   }
     362              : };
     363              : 
     364              : /// A helper template for defining operators for individual opcodes.
     365              : template<typename SuperClass, unsigned Opc>
     366              : class ConcreteOperator : public SuperClass {
     367              : public:
     368              :   static bool classof(const Instruction *I) {
     369              :     return I->getOpcode() == Opc;
     370              :   }
     371              :   static bool classof(const ConstantExpr *CE) {
     372              :     return CE->getOpcode() == Opc;
     373              :   }
     374              :   static bool classof(const Value *V) {
     375              :     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
     376              :            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
     377              :   }
     378              : };
     379              : 
     380              : class AddOperator
     381              :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
     382              : };
     383              : class SubOperator
     384              :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
     385              : };
     386              : class MulOperator
     387              :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
     388              : };
     389              : class ShlOperator
     390              :   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
     391              : };
     392              : 
     393              : class AShrOperator
     394              :   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
     395              : };
     396              : class LShrOperator
     397              :   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
     398              : };
     399              : 
     400              : class GEPOperator
     401              :     : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
     402              : public:
     403              :   /// Transparently provide more efficient getOperand methods.
     404              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     405              : 
     406              :   GEPNoWrapFlags getNoWrapFlags() const {
     407              :     return GEPNoWrapFlags::fromRaw(SubclassOptionalData);
     408              :   }
     409              : 
     410              :   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
     411              :   bool isInBounds() const { return getNoWrapFlags().isInBounds(); }
     412              : 
     413              :   bool hasNoUnsignedSignedWrap() const {
     414              :     return getNoWrapFlags().hasNoUnsignedSignedWrap();
     415              :   }
     416              : 
     417              :   bool hasNoUnsignedWrap() const {
     418              :     return getNoWrapFlags().hasNoUnsignedWrap();
     419              :   }
     420              : 
     421              :   /// Returns the offset of the index with an inrange attachment, or
     422              :   /// std::nullopt if none.
     423              :   std::optional<ConstantRange> getInRange() const;
     424              : 
     425              :   inline op_iterator       idx_begin()       { return op_begin()+1; }
     426              :   inline const_op_iterator idx_begin() const { return op_begin()+1; }
     427              :   inline op_iterator       idx_end()         { return op_end(); }
     428              :   inline const_op_iterator idx_end()   const { return op_end(); }
     429              : 
     430              :   inline iterator_range<op_iterator> indices() {
     431              :     return make_range(idx_begin(), idx_end());
     432              :   }
     433              : 
     434              :   inline iterator_range<const_op_iterator> indices() const {
     435              :     return make_range(idx_begin(), idx_end());
     436              :   }
     437              : 
     438              :   Value *getPointerOperand() {
     439              :     return getOperand(0);
     440              :   }
     441              :   const Value *getPointerOperand() const {
     442              :     return getOperand(0);
     443              :   }
     444              :   static unsigned getPointerOperandIndex() {
     445              :     return 0U;                      // get index for modifying correct operand
     446              :   }
     447              : 
     448              :   /// Method to return the pointer operand as a PointerType.
     449              :   Type *getPointerOperandType() const {
     450              :     return getPointerOperand()->getType();
     451              :   }
     452              : 
     453              :   Type *getSourceElementType() const;
     454              :   Type *getResultElementType() const;
     455              : 
     456              :   /// Method to return the address space of the pointer operand.
     457              :   unsigned getPointerAddressSpace() const {
     458              :     return getPointerOperandType()->getPointerAddressSpace();
     459              :   }
     460              : 
     461              :   unsigned getNumIndices() const {  // Note: always non-negative
     462              :     return getNumOperands() - 1;
     463              :   }
     464              : 
     465              :   bool hasIndices() const {
     466              :     return getNumOperands() > 1;
     467              :   }
     468              : 
     469              :   /// Return true if all of the indices of this GEP are zeros.
     470              :   /// If so, the result pointer and the first operand have the same
     471              :   /// value, just potentially different types.
     472              :   bool hasAllZeroIndices() const {
     473              :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     474              :       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
     475              :         if (C->isZero())
     476              :           continue;
     477              :       return false;
     478              :     }
     479              :     return true;
     480              :   }
     481              : 
     482              :   /// Return true if all of the indices of this GEP are constant integers.
     483              :   /// If so, the result pointer and the first operand have
     484              :   /// a constant offset between them.
     485              :   bool hasAllConstantIndices() const {
     486              :     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
     487              :       if (!isa<ConstantInt>(I))
     488              :         return false;
     489              :     }
     490              :     return true;
     491              :   }
     492              : 
     493              :   unsigned countNonConstantIndices() const {
     494              :     return count_if(indices(), [](const Use& use) {
     495              :         return !isa<ConstantInt>(*use);
     496              :       });
     497              :   }
     498              : 
     499              :   /// Compute the maximum alignment that this GEP is garranteed to preserve.
     500              :   Align getMaxPreservedAlignment(const DataLayout &DL) const;
     501              : 
     502              :   /// Accumulate the constant address offset of this GEP if possible.
     503              :   ///
     504              :   /// This routine accepts an APInt into which it will try to accumulate the
     505              :   /// constant offset of this GEP.
     506              :   ///
     507              :   /// If \p ExternalAnalysis is provided it will be used to calculate a offset
     508              :   /// when a operand of GEP is not constant.
     509              :   /// For example, for a value \p ExternalAnalysis might try to calculate a
     510              :   /// lower bound. If \p ExternalAnalysis is successful, it should return true.
     511              :   ///
     512              :   /// If the \p ExternalAnalysis returns false or the value returned by \p
     513              :   /// ExternalAnalysis results in a overflow/underflow, this routine returns
     514              :   /// false and the value of the offset APInt is undefined (it is *not*
     515              :   /// preserved!).
     516              :   ///
     517              :   /// The APInt passed into this routine must be at exactly as wide as the
     518              :   /// IntPtr type for the address space of the base GEP pointer.
     519              :   bool accumulateConstantOffset(
     520              :       const DataLayout &DL, APInt &Offset,
     521              :       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
     522              : 
     523              :   static bool accumulateConstantOffset(
     524              :       Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
     525              :       APInt &Offset,
     526              :       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
     527              : 
     528              :   /// Collect the offset of this GEP as a map of Values to their associated
     529              :   /// APInt multipliers, as well as a total Constant Offset.
     530              :   bool collectOffset(const DataLayout &DL, unsigned BitWidth,
     531              :                      MapVector<Value *, APInt> &VariableOffsets,
     532              :                      APInt &ConstantOffset) const;
     533              : };
     534              : 
     535              : template <>
     536              : struct OperandTraits<GEPOperator>
     537              :     : public VariadicOperandTraits<GEPOperator, 1> {};
     538              : 
     539              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GEPOperator, Value)
     540              : 
     541              : class PtrToIntOperator
     542              :     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
     543              :   friend class PtrToInt;
     544              :   friend class ConstantExpr;
     545              : 
     546              : public:
     547              :   /// Transparently provide more efficient getOperand methods.
     548              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     549              : 
     550              :   Value *getPointerOperand() {
     551              :     return getOperand(0);
     552              :   }
     553              :   const Value *getPointerOperand() const {
     554              :     return getOperand(0);
     555              :   }
     556              : 
     557              :   static unsigned getPointerOperandIndex() {
     558              :     return 0U;                      // get index for modifying correct operand
     559              :   }
     560              : 
     561              :   /// Method to return the pointer operand as a PointerType.
     562              :   Type *getPointerOperandType() const {
     563              :     return getPointerOperand()->getType();
     564              :   }
     565              : 
     566              :   /// Method to return the address space of the pointer operand.
     567              :   unsigned getPointerAddressSpace() const {
     568              :     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
     569              :   }
     570              : };
     571              : 
     572              : template <>
     573              : struct OperandTraits<PtrToIntOperator>
     574              :     : public FixedNumOperandTraits<PtrToIntOperator, 1> {};
     575              : 
     576              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PtrToIntOperator, Value)
     577              : 
     578              : class BitCastOperator
     579              :     : public ConcreteOperator<Operator, Instruction::BitCast> {
     580              :   friend class BitCastInst;
     581              :   friend class ConstantExpr;
     582              : 
     583              : public:
     584              :   /// Transparently provide more efficient getOperand methods.
     585              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     586              : 
     587              :   Type *getSrcTy() const {
     588              :     return getOperand(0)->getType();
     589              :   }
     590              : 
     591              :   Type *getDestTy() const {
     592              :     return getType();
     593              :   }
     594              : };
     595              : 
     596              : template <>
     597              : struct OperandTraits<BitCastOperator>
     598              :     : public FixedNumOperandTraits<BitCastOperator, 1> {};
     599              : 
     600              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitCastOperator, Value)
     601              : 
     602              : class AddrSpaceCastOperator
     603              :     : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
     604              :   friend class AddrSpaceCastInst;
     605              :   friend class ConstantExpr;
     606              : 
     607              : public:
     608              :   /// Transparently provide more efficient getOperand methods.
     609              :   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
     610              : 
     611              :   Value *getPointerOperand() { return getOperand(0); }
     612              : 
     613              :   const Value *getPointerOperand() const { return getOperand(0); }
     614              : 
     615              :   unsigned getSrcAddressSpace() const {
     616              :     return getPointerOperand()->getType()->getPointerAddressSpace();
     617              :   }
     618              : 
     619              :   unsigned getDestAddressSpace() const {
     620              :     return getType()->getPointerAddressSpace();
     621              :   }
     622              : };
     623              : 
     624              : template <>
     625              : struct OperandTraits<AddrSpaceCastOperator>
     626              :     : public FixedNumOperandTraits<AddrSpaceCastOperator, 1> {};
     627              : 
     628              : DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AddrSpaceCastOperator, Value)
     629              : 
     630              : } // end namespace llvm
     631              : 
     632              : #endif // LLVM_IR_OPERATOR_H
        

Generated by: LCOV version 2.0-1