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