Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:08

0001 //===-- llvm/Operator.h - Operator utility subclass -------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines various classes for working with Instructions and
0010 // ConstantExprs.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_IR_OPERATOR_H
0015 #define LLVM_IR_OPERATOR_H
0016 
0017 #include "llvm/ADT/MapVector.h"
0018 #include "llvm/IR/Constants.h"
0019 #include "llvm/IR/FMF.h"
0020 #include "llvm/IR/GEPNoWrapFlags.h"
0021 #include "llvm/IR/Instruction.h"
0022 #include "llvm/IR/Type.h"
0023 #include "llvm/IR/Value.h"
0024 #include "llvm/Support/Casting.h"
0025 #include <cstddef>
0026 #include <optional>
0027 
0028 namespace llvm {
0029 
0030 /// This is a utility class that provides an abstraction for the common
0031 /// functionality between Instructions and ConstantExprs.
0032 class Operator : public User {
0033 public:
0034   // The Operator class is intended to be used as a utility, and is never itself
0035   // instantiated.
0036   Operator() = delete;
0037   ~Operator() = delete;
0038 
0039   void *operator new(size_t s) = delete;
0040 
0041   /// Return the opcode for this Instruction or ConstantExpr.
0042   unsigned getOpcode() const {
0043     if (const Instruction *I = dyn_cast<Instruction>(this))
0044       return I->getOpcode();
0045     return cast<ConstantExpr>(this)->getOpcode();
0046   }
0047 
0048   /// If V is an Instruction or ConstantExpr, return its opcode.
0049   /// Otherwise return UserOp1.
0050   static unsigned getOpcode(const Value *V) {
0051     if (const Instruction *I = dyn_cast<Instruction>(V))
0052       return I->getOpcode();
0053     if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
0054       return CE->getOpcode();
0055     return Instruction::UserOp1;
0056   }
0057 
0058   static bool classof(const Instruction *) { return true; }
0059   static bool classof(const ConstantExpr *) { return true; }
0060   static bool classof(const Value *V) {
0061     return isa<Instruction>(V) || isa<ConstantExpr>(V);
0062   }
0063 
0064   /// Return true if this operator has flags which may cause this operator
0065   /// to evaluate to poison despite having non-poison inputs.
0066   bool hasPoisonGeneratingFlags() const;
0067 
0068   /// Return true if this operator has poison-generating flags,
0069   /// return attributes or metadata. The latter two is only possible for
0070   /// instructions.
0071   bool hasPoisonGeneratingAnnotations() const;
0072 };
0073 
0074 /// Utility class for integer operators which may exhibit overflow - Add, Sub,
0075 /// Mul, and Shl. It does not include SDiv, despite that operator having the
0076 /// potential for overflow.
0077 class OverflowingBinaryOperator : public Operator {
0078 public:
0079   enum {
0080     AnyWrap        = 0,
0081     NoUnsignedWrap = (1 << 0),
0082     NoSignedWrap   = (1 << 1)
0083   };
0084 
0085 private:
0086   friend class Instruction;
0087   friend class ConstantExpr;
0088 
0089   void setHasNoUnsignedWrap(bool B) {
0090     SubclassOptionalData =
0091       (SubclassOptionalData & ~NoUnsignedWrap) | (B * NoUnsignedWrap);
0092   }
0093   void setHasNoSignedWrap(bool B) {
0094     SubclassOptionalData =
0095       (SubclassOptionalData & ~NoSignedWrap) | (B * NoSignedWrap);
0096   }
0097 
0098 public:
0099   /// Transparently provide more efficient getOperand methods.
0100   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0101 
0102   /// Test whether this operation is known to never
0103   /// undergo unsigned overflow, aka the nuw property.
0104   bool hasNoUnsignedWrap() const {
0105     return SubclassOptionalData & NoUnsignedWrap;
0106   }
0107 
0108   /// Test whether this operation is known to never
0109   /// undergo signed overflow, aka the nsw property.
0110   bool hasNoSignedWrap() const {
0111     return (SubclassOptionalData & NoSignedWrap) != 0;
0112   }
0113 
0114   /// Returns the no-wrap kind of the operation.
0115   unsigned getNoWrapKind() const {
0116     unsigned NoWrapKind = 0;
0117     if (hasNoUnsignedWrap())
0118       NoWrapKind |= NoUnsignedWrap;
0119 
0120     if (hasNoSignedWrap())
0121       NoWrapKind |= NoSignedWrap;
0122 
0123     return NoWrapKind;
0124   }
0125 
0126   /// Return true if the instruction is commutative
0127   bool isCommutative() const { return Instruction::isCommutative(getOpcode()); }
0128 
0129   static bool classof(const Instruction *I) {
0130     return I->getOpcode() == Instruction::Add ||
0131            I->getOpcode() == Instruction::Sub ||
0132            I->getOpcode() == Instruction::Mul ||
0133            I->getOpcode() == Instruction::Shl;
0134   }
0135   static bool classof(const ConstantExpr *CE) {
0136     return CE->getOpcode() == Instruction::Add ||
0137            CE->getOpcode() == Instruction::Sub ||
0138            CE->getOpcode() == Instruction::Mul ||
0139            CE->getOpcode() == Instruction::Shl;
0140   }
0141   static bool classof(const Value *V) {
0142     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
0143            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
0144   }
0145 };
0146 
0147 template <>
0148 struct OperandTraits<OverflowingBinaryOperator>
0149     : public FixedNumOperandTraits<OverflowingBinaryOperator, 2> {};
0150 
0151 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(OverflowingBinaryOperator, Value)
0152 
0153 /// A udiv or sdiv instruction, which can be marked as "exact",
0154 /// indicating that no bits are destroyed.
0155 class PossiblyExactOperator : public Operator {
0156 public:
0157   enum {
0158     IsExact = (1 << 0)
0159   };
0160 
0161 private:
0162   friend class Instruction;
0163   friend class ConstantExpr;
0164 
0165   void setIsExact(bool B) {
0166     SubclassOptionalData = (SubclassOptionalData & ~IsExact) | (B * IsExact);
0167   }
0168 
0169 public:
0170   /// Transparently provide more efficient getOperand methods.
0171   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0172 
0173   /// Test whether this division is known to be exact, with zero remainder.
0174   bool isExact() const {
0175     return SubclassOptionalData & IsExact;
0176   }
0177 
0178   static bool isPossiblyExactOpcode(unsigned OpC) {
0179     return OpC == Instruction::SDiv ||
0180            OpC == Instruction::UDiv ||
0181            OpC == Instruction::AShr ||
0182            OpC == Instruction::LShr;
0183   }
0184 
0185   static bool classof(const ConstantExpr *CE) {
0186     return isPossiblyExactOpcode(CE->getOpcode());
0187   }
0188   static bool classof(const Instruction *I) {
0189     return isPossiblyExactOpcode(I->getOpcode());
0190   }
0191   static bool classof(const Value *V) {
0192     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
0193            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
0194   }
0195 };
0196 
0197 template <>
0198 struct OperandTraits<PossiblyExactOperator>
0199     : public FixedNumOperandTraits<PossiblyExactOperator, 2> {};
0200 
0201 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PossiblyExactOperator, Value)
0202 
0203 /// Utility class for floating point operations which can have
0204 /// information about relaxed accuracy requirements attached to them.
0205 class FPMathOperator : public Operator {
0206 private:
0207   friend class Instruction;
0208 
0209   /// 'Fast' means all bits are set.
0210   void setFast(bool B) {
0211     setHasAllowReassoc(B);
0212     setHasNoNaNs(B);
0213     setHasNoInfs(B);
0214     setHasNoSignedZeros(B);
0215     setHasAllowReciprocal(B);
0216     setHasAllowContract(B);
0217     setHasApproxFunc(B);
0218   }
0219 
0220   void setHasAllowReassoc(bool B) {
0221     SubclassOptionalData =
0222     (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
0223     (B * FastMathFlags::AllowReassoc);
0224   }
0225 
0226   void setHasNoNaNs(bool B) {
0227     SubclassOptionalData =
0228       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
0229       (B * FastMathFlags::NoNaNs);
0230   }
0231 
0232   void setHasNoInfs(bool B) {
0233     SubclassOptionalData =
0234       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
0235       (B * FastMathFlags::NoInfs);
0236   }
0237 
0238   void setHasNoSignedZeros(bool B) {
0239     SubclassOptionalData =
0240       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
0241       (B * FastMathFlags::NoSignedZeros);
0242   }
0243 
0244   void setHasAllowReciprocal(bool B) {
0245     SubclassOptionalData =
0246       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
0247       (B * FastMathFlags::AllowReciprocal);
0248   }
0249 
0250   void setHasAllowContract(bool B) {
0251     SubclassOptionalData =
0252         (SubclassOptionalData & ~FastMathFlags::AllowContract) |
0253         (B * FastMathFlags::AllowContract);
0254   }
0255 
0256   void setHasApproxFunc(bool B) {
0257     SubclassOptionalData =
0258         (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
0259         (B * FastMathFlags::ApproxFunc);
0260   }
0261 
0262   /// Convenience function for setting multiple fast-math flags.
0263   /// FMF is a mask of the bits to set.
0264   void setFastMathFlags(FastMathFlags FMF) {
0265     SubclassOptionalData |= FMF.Flags;
0266   }
0267 
0268   /// Convenience function for copying all fast-math flags.
0269   /// All values in FMF are transferred to this operator.
0270   void copyFastMathFlags(FastMathFlags FMF) {
0271     SubclassOptionalData = FMF.Flags;
0272   }
0273 
0274   /// Returns true if `Ty` is composed of a single kind of float-poing type
0275   /// (possibly repeated within an aggregate).
0276   static bool isComposedOfHomogeneousFloatingPointTypes(Type *Ty) {
0277     if (auto *StructTy = dyn_cast<StructType>(Ty)) {
0278       if (!StructTy->isLiteral() || !StructTy->containsHomogeneousTypes())
0279         return false;
0280       Ty = StructTy->elements().front();
0281     } else if (auto *ArrayTy = dyn_cast<ArrayType>(Ty)) {
0282       do {
0283         Ty = ArrayTy->getElementType();
0284       } while ((ArrayTy = dyn_cast<ArrayType>(Ty)));
0285     }
0286     return Ty->isFPOrFPVectorTy();
0287   };
0288 
0289 public:
0290   /// Test if this operation allows all non-strict floating-point transforms.
0291   bool isFast() const {
0292     return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
0293             (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
0294             (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
0295             (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
0296             (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
0297             (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
0298             (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
0299   }
0300 
0301   /// Test if this operation may be simplified with reassociative transforms.
0302   bool hasAllowReassoc() const {
0303     return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
0304   }
0305 
0306   /// Test if this operation's arguments and results are assumed not-NaN.
0307   bool hasNoNaNs() const {
0308     return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
0309   }
0310 
0311   /// Test if this operation's arguments and results are assumed not-infinite.
0312   bool hasNoInfs() const {
0313     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
0314   }
0315 
0316   /// Test if this operation can ignore the sign of zero.
0317   bool hasNoSignedZeros() const {
0318     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
0319   }
0320 
0321   /// Test if this operation can use reciprocal multiply instead of division.
0322   bool hasAllowReciprocal() const {
0323     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
0324   }
0325 
0326   /// Test if this operation can be floating-point contracted (FMA).
0327   bool hasAllowContract() const {
0328     return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
0329   }
0330 
0331   /// Test if this operation allows approximations of math library functions or
0332   /// intrinsics.
0333   bool hasApproxFunc() const {
0334     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
0335   }
0336 
0337   /// Convenience function for getting all the fast-math flags
0338   FastMathFlags getFastMathFlags() const {
0339     return FastMathFlags(SubclassOptionalData);
0340   }
0341 
0342   /// Get the maximum error permitted by this operation in ULPs. An accuracy of
0343   /// 0.0 means that the operation should be performed with the default
0344   /// precision.
0345   float getFPAccuracy() const;
0346 
0347   /// Returns true if `Ty` is a supported floating-point type for phi, select,
0348   /// or call FPMathOperators.
0349   static bool isSupportedFloatingPointType(Type *Ty) {
0350     return Ty->isFPOrFPVectorTy() ||
0351            isComposedOfHomogeneousFloatingPointTypes(Ty);
0352   }
0353 
0354   static bool classof(const Value *V) {
0355     unsigned Opcode;
0356     if (auto *I = dyn_cast<Instruction>(V))
0357       Opcode = I->getOpcode();
0358     else
0359       return false;
0360 
0361     switch (Opcode) {
0362     case Instruction::FNeg:
0363     case Instruction::FAdd:
0364     case Instruction::FSub:
0365     case Instruction::FMul:
0366     case Instruction::FDiv:
0367     case Instruction::FRem:
0368     case Instruction::FPTrunc:
0369     case Instruction::FPExt:
0370     // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp
0371     //        should not be treated as a math op, but the other opcodes should.
0372     //        This would make things consistent with Select/PHI (FP value type
0373     //        determines whether they are math ops and, therefore, capable of
0374     //        having fast-math-flags).
0375     case Instruction::FCmp:
0376       return true;
0377     case Instruction::PHI:
0378     case Instruction::Select:
0379     case Instruction::Call: {
0380       return isSupportedFloatingPointType(V->getType());
0381     }
0382     default:
0383       return false;
0384     }
0385   }
0386 };
0387 
0388 /// A helper template for defining operators for individual opcodes.
0389 template<typename SuperClass, unsigned Opc>
0390 class ConcreteOperator : public SuperClass {
0391 public:
0392   static bool classof(const Instruction *I) {
0393     return I->getOpcode() == Opc;
0394   }
0395   static bool classof(const ConstantExpr *CE) {
0396     return CE->getOpcode() == Opc;
0397   }
0398   static bool classof(const Value *V) {
0399     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
0400            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
0401   }
0402 };
0403 
0404 class AddOperator
0405   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
0406 };
0407 class SubOperator
0408   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
0409 };
0410 class MulOperator
0411   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
0412 };
0413 class ShlOperator
0414   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
0415 };
0416 
0417 class AShrOperator
0418   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
0419 };
0420 class LShrOperator
0421   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
0422 };
0423 
0424 class GEPOperator
0425     : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
0426 public:
0427   /// Transparently provide more efficient getOperand methods.
0428   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0429 
0430   GEPNoWrapFlags getNoWrapFlags() const {
0431     return GEPNoWrapFlags::fromRaw(SubclassOptionalData);
0432   }
0433 
0434   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
0435   bool isInBounds() const { return getNoWrapFlags().isInBounds(); }
0436 
0437   bool hasNoUnsignedSignedWrap() const {
0438     return getNoWrapFlags().hasNoUnsignedSignedWrap();
0439   }
0440 
0441   bool hasNoUnsignedWrap() const {
0442     return getNoWrapFlags().hasNoUnsignedWrap();
0443   }
0444 
0445   /// Returns the offset of the index with an inrange attachment, or
0446   /// std::nullopt if none.
0447   std::optional<ConstantRange> getInRange() const;
0448 
0449   inline op_iterator       idx_begin()       { return op_begin()+1; }
0450   inline const_op_iterator idx_begin() const { return op_begin()+1; }
0451   inline op_iterator       idx_end()         { return op_end(); }
0452   inline const_op_iterator idx_end()   const { return op_end(); }
0453 
0454   inline iterator_range<op_iterator> indices() {
0455     return make_range(idx_begin(), idx_end());
0456   }
0457 
0458   inline iterator_range<const_op_iterator> indices() const {
0459     return make_range(idx_begin(), idx_end());
0460   }
0461 
0462   Value *getPointerOperand() {
0463     return getOperand(0);
0464   }
0465   const Value *getPointerOperand() const {
0466     return getOperand(0);
0467   }
0468   static unsigned getPointerOperandIndex() {
0469     return 0U;                      // get index for modifying correct operand
0470   }
0471 
0472   /// Method to return the pointer operand as a PointerType.
0473   Type *getPointerOperandType() const {
0474     return getPointerOperand()->getType();
0475   }
0476 
0477   Type *getSourceElementType() const;
0478   Type *getResultElementType() const;
0479 
0480   /// Method to return the address space of the pointer operand.
0481   unsigned getPointerAddressSpace() const {
0482     return getPointerOperandType()->getPointerAddressSpace();
0483   }
0484 
0485   unsigned getNumIndices() const {  // Note: always non-negative
0486     return getNumOperands() - 1;
0487   }
0488 
0489   bool hasIndices() const {
0490     return getNumOperands() > 1;
0491   }
0492 
0493   /// Return true if all of the indices of this GEP are zeros.
0494   /// If so, the result pointer and the first operand have the same
0495   /// value, just potentially different types.
0496   bool hasAllZeroIndices() const {
0497     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
0498       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
0499         if (C->isZero())
0500           continue;
0501       return false;
0502     }
0503     return true;
0504   }
0505 
0506   /// Return true if all of the indices of this GEP are constant integers.
0507   /// If so, the result pointer and the first operand have
0508   /// a constant offset between them.
0509   bool hasAllConstantIndices() const {
0510     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
0511       if (!isa<ConstantInt>(I))
0512         return false;
0513     }
0514     return true;
0515   }
0516 
0517   unsigned countNonConstantIndices() const {
0518     return count_if(indices(), [](const Use& use) {
0519         return !isa<ConstantInt>(*use);
0520       });
0521   }
0522 
0523   /// Compute the maximum alignment that this GEP is garranteed to preserve.
0524   Align getMaxPreservedAlignment(const DataLayout &DL) const;
0525 
0526   /// Accumulate the constant address offset of this GEP if possible.
0527   ///
0528   /// This routine accepts an APInt into which it will try to accumulate the
0529   /// constant offset of this GEP.
0530   ///
0531   /// If \p ExternalAnalysis is provided it will be used to calculate a offset
0532   /// when a operand of GEP is not constant.
0533   /// For example, for a value \p ExternalAnalysis might try to calculate a
0534   /// lower bound. If \p ExternalAnalysis is successful, it should return true.
0535   ///
0536   /// If the \p ExternalAnalysis returns false or the value returned by \p
0537   /// ExternalAnalysis results in a overflow/underflow, this routine returns
0538   /// false and the value of the offset APInt is undefined (it is *not*
0539   /// preserved!).
0540   ///
0541   /// The APInt passed into this routine must be at exactly as wide as the
0542   /// IntPtr type for the address space of the base GEP pointer.
0543   bool accumulateConstantOffset(
0544       const DataLayout &DL, APInt &Offset,
0545       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
0546 
0547   static bool accumulateConstantOffset(
0548       Type *SourceType, ArrayRef<const Value *> Index, const DataLayout &DL,
0549       APInt &Offset,
0550       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr);
0551 
0552   /// Collect the offset of this GEP as a map of Values to their associated
0553   /// APInt multipliers, as well as a total Constant Offset.
0554   bool collectOffset(const DataLayout &DL, unsigned BitWidth,
0555                      SmallMapVector<Value *, APInt, 4> &VariableOffsets,
0556                      APInt &ConstantOffset) const;
0557 };
0558 
0559 template <>
0560 struct OperandTraits<GEPOperator> : public VariadicOperandTraits<GEPOperator> {
0561 };
0562 
0563 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GEPOperator, Value)
0564 
0565 class PtrToIntOperator
0566     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
0567   friend class PtrToInt;
0568   friend class ConstantExpr;
0569 
0570 public:
0571   /// Transparently provide more efficient getOperand methods.
0572   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0573 
0574   Value *getPointerOperand() {
0575     return getOperand(0);
0576   }
0577   const Value *getPointerOperand() const {
0578     return getOperand(0);
0579   }
0580 
0581   static unsigned getPointerOperandIndex() {
0582     return 0U;                      // get index for modifying correct operand
0583   }
0584 
0585   /// Method to return the pointer operand as a PointerType.
0586   Type *getPointerOperandType() const {
0587     return getPointerOperand()->getType();
0588   }
0589 
0590   /// Method to return the address space of the pointer operand.
0591   unsigned getPointerAddressSpace() const {
0592     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
0593   }
0594 };
0595 
0596 template <>
0597 struct OperandTraits<PtrToIntOperator>
0598     : public FixedNumOperandTraits<PtrToIntOperator, 1> {};
0599 
0600 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PtrToIntOperator, Value)
0601 
0602 class BitCastOperator
0603     : public ConcreteOperator<Operator, Instruction::BitCast> {
0604   friend class BitCastInst;
0605   friend class ConstantExpr;
0606 
0607 public:
0608   /// Transparently provide more efficient getOperand methods.
0609   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0610 
0611   Type *getSrcTy() const {
0612     return getOperand(0)->getType();
0613   }
0614 
0615   Type *getDestTy() const {
0616     return getType();
0617   }
0618 };
0619 
0620 template <>
0621 struct OperandTraits<BitCastOperator>
0622     : public FixedNumOperandTraits<BitCastOperator, 1> {};
0623 
0624 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitCastOperator, Value)
0625 
0626 class AddrSpaceCastOperator
0627     : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
0628   friend class AddrSpaceCastInst;
0629   friend class ConstantExpr;
0630 
0631 public:
0632   /// Transparently provide more efficient getOperand methods.
0633   DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
0634 
0635   Value *getPointerOperand() { return getOperand(0); }
0636 
0637   const Value *getPointerOperand() const { return getOperand(0); }
0638 
0639   unsigned getSrcAddressSpace() const {
0640     return getPointerOperand()->getType()->getPointerAddressSpace();
0641   }
0642 
0643   unsigned getDestAddressSpace() const {
0644     return getType()->getPointerAddressSpace();
0645   }
0646 };
0647 
0648 template <>
0649 struct OperandTraits<AddrSpaceCastOperator>
0650     : public FixedNumOperandTraits<AddrSpaceCastOperator, 1> {};
0651 
0652 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(AddrSpaceCastOperator, Value)
0653 
0654 } // end namespace llvm
0655 
0656 #endif // LLVM_IR_OPERATOR_H