• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 };
243 
244 /// Utility class for floating point operations which can have
245 /// information about relaxed accuracy requirements attached to them.
246 class FPMathOperator : public Operator {
247 private:
248   friend class Instruction;
249 
250   /// 'Fast' means all bits are set.
setFast(bool B)251   void setFast(bool B) {
252     setHasAllowReassoc(B);
253     setHasNoNaNs(B);
254     setHasNoInfs(B);
255     setHasNoSignedZeros(B);
256     setHasAllowReciprocal(B);
257     setHasAllowContract(B);
258     setHasApproxFunc(B);
259   }
260 
setHasAllowReassoc(bool B)261   void setHasAllowReassoc(bool B) {
262     SubclassOptionalData =
263     (SubclassOptionalData & ~FastMathFlags::AllowReassoc) |
264     (B * FastMathFlags::AllowReassoc);
265   }
266 
setHasNoNaNs(bool B)267   void setHasNoNaNs(bool B) {
268     SubclassOptionalData =
269       (SubclassOptionalData & ~FastMathFlags::NoNaNs) |
270       (B * FastMathFlags::NoNaNs);
271   }
272 
setHasNoInfs(bool B)273   void setHasNoInfs(bool B) {
274     SubclassOptionalData =
275       (SubclassOptionalData & ~FastMathFlags::NoInfs) |
276       (B * FastMathFlags::NoInfs);
277   }
278 
setHasNoSignedZeros(bool B)279   void setHasNoSignedZeros(bool B) {
280     SubclassOptionalData =
281       (SubclassOptionalData & ~FastMathFlags::NoSignedZeros) |
282       (B * FastMathFlags::NoSignedZeros);
283   }
284 
setHasAllowReciprocal(bool B)285   void setHasAllowReciprocal(bool B) {
286     SubclassOptionalData =
287       (SubclassOptionalData & ~FastMathFlags::AllowReciprocal) |
288       (B * FastMathFlags::AllowReciprocal);
289   }
290 
setHasAllowContract(bool B)291   void setHasAllowContract(bool B) {
292     SubclassOptionalData =
293         (SubclassOptionalData & ~FastMathFlags::AllowContract) |
294         (B * FastMathFlags::AllowContract);
295   }
296 
setHasApproxFunc(bool B)297   void setHasApproxFunc(bool B) {
298     SubclassOptionalData =
299         (SubclassOptionalData & ~FastMathFlags::ApproxFunc) |
300         (B * FastMathFlags::ApproxFunc);
301   }
302 
303   /// Convenience function for setting multiple fast-math flags.
304   /// FMF is a mask of the bits to set.
setFastMathFlags(FastMathFlags FMF)305   void setFastMathFlags(FastMathFlags FMF) {
306     SubclassOptionalData |= FMF.Flags;
307   }
308 
309   /// Convenience function for copying all fast-math flags.
310   /// All values in FMF are transferred to this operator.
copyFastMathFlags(FastMathFlags FMF)311   void copyFastMathFlags(FastMathFlags FMF) {
312     SubclassOptionalData = FMF.Flags;
313   }
314 
315 public:
316   /// Test if this operation allows all non-strict floating-point transforms.
isFast()317   bool isFast() const {
318     return ((SubclassOptionalData & FastMathFlags::AllowReassoc) != 0 &&
319             (SubclassOptionalData & FastMathFlags::NoNaNs) != 0 &&
320             (SubclassOptionalData & FastMathFlags::NoInfs) != 0 &&
321             (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0 &&
322             (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0 &&
323             (SubclassOptionalData & FastMathFlags::AllowContract) != 0 &&
324             (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0);
325   }
326 
327   /// Test if this operation may be simplified with reassociative transforms.
hasAllowReassoc()328   bool hasAllowReassoc() const {
329     return (SubclassOptionalData & FastMathFlags::AllowReassoc) != 0;
330   }
331 
332   /// Test if this operation's arguments and results are assumed not-NaN.
hasNoNaNs()333   bool hasNoNaNs() const {
334     return (SubclassOptionalData & FastMathFlags::NoNaNs) != 0;
335   }
336 
337   /// Test if this operation's arguments and results are assumed not-infinite.
hasNoInfs()338   bool hasNoInfs() const {
339     return (SubclassOptionalData & FastMathFlags::NoInfs) != 0;
340   }
341 
342   /// Test if this operation can ignore the sign of zero.
hasNoSignedZeros()343   bool hasNoSignedZeros() const {
344     return (SubclassOptionalData & FastMathFlags::NoSignedZeros) != 0;
345   }
346 
347   /// Test if this operation can use reciprocal multiply instead of division.
hasAllowReciprocal()348   bool hasAllowReciprocal() const {
349     return (SubclassOptionalData & FastMathFlags::AllowReciprocal) != 0;
350   }
351 
352   /// Test if this operation can be floating-point contracted (FMA).
hasAllowContract()353   bool hasAllowContract() const {
354     return (SubclassOptionalData & FastMathFlags::AllowContract) != 0;
355   }
356 
357   /// Test if this operation allows approximations of math library functions or
358   /// intrinsics.
hasApproxFunc()359   bool hasApproxFunc() const {
360     return (SubclassOptionalData & FastMathFlags::ApproxFunc) != 0;
361   }
362 
363   /// Convenience function for getting all the fast-math flags
getFastMathFlags()364   FastMathFlags getFastMathFlags() const {
365     return FastMathFlags(SubclassOptionalData);
366   }
367 
368   /// Get the maximum error permitted by this operation in ULPs. An accuracy of
369   /// 0.0 means that the operation should be performed with the default
370   /// precision.
371   float getFPAccuracy() const;
372 
classof(const Value * V)373   static bool classof(const Value *V) {
374     unsigned Opcode;
375     if (auto *I = dyn_cast<Instruction>(V))
376       Opcode = I->getOpcode();
377     else if (auto *CE = dyn_cast<ConstantExpr>(V))
378       Opcode = CE->getOpcode();
379     else
380       return false;
381 
382     switch (Opcode) {
383     case Instruction::FNeg:
384     case Instruction::FAdd:
385     case Instruction::FSub:
386     case Instruction::FMul:
387     case Instruction::FDiv:
388     case Instruction::FRem:
389     // FIXME: To clean up and correct the semantics of fast-math-flags, FCmp
390     //        should not be treated as a math op, but the other opcodes should.
391     //        This would make things consistent with Select/PHI (FP value type
392     //        determines whether they are math ops and, therefore, capable of
393     //        having fast-math-flags).
394     case Instruction::FCmp:
395       return true;
396     case Instruction::PHI:
397     case Instruction::Select:
398     case Instruction::Call: {
399       Type *Ty = V->getType();
400       while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
401         Ty = ArrTy->getElementType();
402       return Ty->isFPOrFPVectorTy();
403     }
404     default:
405       return false;
406     }
407   }
408 };
409 
410 /// A helper template for defining operators for individual opcodes.
411 template<typename SuperClass, unsigned Opc>
412 class ConcreteOperator : public SuperClass {
413 public:
classof(const Instruction * I)414   static bool classof(const Instruction *I) {
415     return I->getOpcode() == Opc;
416   }
classof(const ConstantExpr * CE)417   static bool classof(const ConstantExpr *CE) {
418     return CE->getOpcode() == Opc;
419   }
classof(const Value * V)420   static bool classof(const Value *V) {
421     return (isa<Instruction>(V) && classof(cast<Instruction>(V))) ||
422            (isa<ConstantExpr>(V) && classof(cast<ConstantExpr>(V)));
423   }
424 };
425 
426 class AddOperator
427   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Add> {
428 };
429 class SubOperator
430   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Sub> {
431 };
432 class MulOperator
433   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Mul> {
434 };
435 class ShlOperator
436   : public ConcreteOperator<OverflowingBinaryOperator, Instruction::Shl> {
437 };
438 
439 class SDivOperator
440   : public ConcreteOperator<PossiblyExactOperator, Instruction::SDiv> {
441 };
442 class UDivOperator
443   : public ConcreteOperator<PossiblyExactOperator, Instruction::UDiv> {
444 };
445 class AShrOperator
446   : public ConcreteOperator<PossiblyExactOperator, Instruction::AShr> {
447 };
448 class LShrOperator
449   : public ConcreteOperator<PossiblyExactOperator, Instruction::LShr> {
450 };
451 
452 class ZExtOperator : public ConcreteOperator<Operator, Instruction::ZExt> {};
453 
454 class GEPOperator
455   : public ConcreteOperator<Operator, Instruction::GetElementPtr> {
456   friend class GetElementPtrInst;
457   friend class ConstantExpr;
458 
459   enum {
460     IsInBounds = (1 << 0),
461     // InRangeIndex: bits 1-6
462   };
463 
setIsInBounds(bool B)464   void setIsInBounds(bool B) {
465     SubclassOptionalData =
466       (SubclassOptionalData & ~IsInBounds) | (B * IsInBounds);
467   }
468 
469 public:
470   /// Test whether this is an inbounds GEP, as defined by LangRef.html.
isInBounds()471   bool isInBounds() const {
472     return SubclassOptionalData & IsInBounds;
473   }
474 
475   /// Returns the offset of the index with an inrange attachment, or None if
476   /// none.
getInRangeIndex()477   Optional<unsigned> getInRangeIndex() const {
478     if (SubclassOptionalData >> 1 == 0) return None;
479     return (SubclassOptionalData >> 1) - 1;
480   }
481 
idx_begin()482   inline op_iterator       idx_begin()       { return op_begin()+1; }
idx_begin()483   inline const_op_iterator idx_begin() const { return op_begin()+1; }
idx_end()484   inline op_iterator       idx_end()         { return op_end(); }
idx_end()485   inline const_op_iterator idx_end()   const { return op_end(); }
486 
getPointerOperand()487   Value *getPointerOperand() {
488     return getOperand(0);
489   }
getPointerOperand()490   const Value *getPointerOperand() const {
491     return getOperand(0);
492   }
getPointerOperandIndex()493   static unsigned getPointerOperandIndex() {
494     return 0U;                      // get index for modifying correct operand
495   }
496 
497   /// Method to return the pointer operand as a PointerType.
getPointerOperandType()498   Type *getPointerOperandType() const {
499     return getPointerOperand()->getType();
500   }
501 
502   Type *getSourceElementType() const;
503   Type *getResultElementType() const;
504 
505   /// Method to return the address space of the pointer operand.
getPointerAddressSpace()506   unsigned getPointerAddressSpace() const {
507     return getPointerOperandType()->getPointerAddressSpace();
508   }
509 
getNumIndices()510   unsigned getNumIndices() const {  // Note: always non-negative
511     return getNumOperands() - 1;
512   }
513 
hasIndices()514   bool hasIndices() const {
515     return getNumOperands() > 1;
516   }
517 
518   /// Return true if all of the indices of this GEP are zeros.
519   /// If so, the result pointer and the first operand have the same
520   /// value, just potentially different types.
hasAllZeroIndices()521   bool hasAllZeroIndices() const {
522     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
523       if (ConstantInt *C = dyn_cast<ConstantInt>(I))
524         if (C->isZero())
525           continue;
526       return false;
527     }
528     return true;
529   }
530 
531   /// Return true if all of the indices of this GEP are constant integers.
532   /// If so, the result pointer and the first operand have
533   /// a constant offset between them.
hasAllConstantIndices()534   bool hasAllConstantIndices() const {
535     for (const_op_iterator I = idx_begin(), E = idx_end(); I != E; ++I) {
536       if (!isa<ConstantInt>(I))
537         return false;
538     }
539     return true;
540   }
541 
countNonConstantIndices()542   unsigned countNonConstantIndices() const {
543     return count_if(make_range(idx_begin(), idx_end()), [](const Use& use) {
544         return !isa<ConstantInt>(*use);
545       });
546   }
547 
548   /// Compute the maximum alignment that this GEP is garranteed to preserve.
549   Align getMaxPreservedAlignment(const DataLayout &DL) const;
550 
551   /// Accumulate the constant address offset of this GEP if possible.
552   ///
553   /// This routine accepts an APInt into which it will try to accumulate the
554   /// constant offset of this GEP.
555   ///
556   /// If \p ExternalAnalysis is provided it will be used to calculate a offset
557   /// when a operand of GEP is not constant.
558   /// For example, for a value \p ExternalAnalysis might try to calculate a
559   /// lower bound. If \p ExternalAnalysis is successful, it should return true.
560   ///
561   /// If the \p ExternalAnalysis returns false or the value returned by \p
562   /// ExternalAnalysis results in a overflow/underflow, this routine returns
563   /// false and the value of the offset APInt is undefined (it is *not*
564   /// preserved!).
565   ///
566   /// The APInt passed into this routine must be at exactly as wide as the
567   /// IntPtr type for the address space of the base GEP pointer.
568   bool accumulateConstantOffset(
569       const DataLayout &DL, APInt &Offset,
570       function_ref<bool(Value &, APInt &)> ExternalAnalysis = nullptr) const;
571 };
572 
573 class PtrToIntOperator
574     : public ConcreteOperator<Operator, Instruction::PtrToInt> {
575   friend class PtrToInt;
576   friend class ConstantExpr;
577 
578 public:
getPointerOperand()579   Value *getPointerOperand() {
580     return getOperand(0);
581   }
getPointerOperand()582   const Value *getPointerOperand() const {
583     return getOperand(0);
584   }
585 
getPointerOperandIndex()586   static unsigned getPointerOperandIndex() {
587     return 0U;                      // get index for modifying correct operand
588   }
589 
590   /// Method to return the pointer operand as a PointerType.
getPointerOperandType()591   Type *getPointerOperandType() const {
592     return getPointerOperand()->getType();
593   }
594 
595   /// Method to return the address space of the pointer operand.
getPointerAddressSpace()596   unsigned getPointerAddressSpace() const {
597     return cast<PointerType>(getPointerOperandType())->getAddressSpace();
598   }
599 };
600 
601 class BitCastOperator
602     : public ConcreteOperator<Operator, Instruction::BitCast> {
603   friend class BitCastInst;
604   friend class ConstantExpr;
605 
606 public:
getSrcTy()607   Type *getSrcTy() const {
608     return getOperand(0)->getType();
609   }
610 
getDestTy()611   Type *getDestTy() const {
612     return getType();
613   }
614 };
615 
616 class AddrSpaceCastOperator
617     : public ConcreteOperator<Operator, Instruction::AddrSpaceCast> {
618   friend class AddrSpaceCastInst;
619   friend class ConstantExpr;
620 
621 public:
getPointerOperand()622   Value *getPointerOperand() { return getOperand(0); }
623 
getPointerOperand()624   const Value *getPointerOperand() const { return getOperand(0); }
625 
getSrcAddressSpace()626   unsigned getSrcAddressSpace() const {
627     return getPointerOperand()->getType()->getPointerAddressSpace();
628   }
629 
getDestAddressSpace()630   unsigned getDestAddressSpace() const {
631     return getType()->getPointerAddressSpace();
632   }
633 };
634 
635 } // end namespace llvm
636 
637 #endif // LLVM_IR_OPERATOR_H
638