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