1 //===-- llvm/IntrinsicInst.h - Intrinsic Instruction Wrappers ---*- 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 classes that make it really easy to deal with intrinsic 10 // functions with the isa/dyncast family of functions. In particular, this 11 // allows you to do things like: 12 // 13 // if (MemCpyInst *MCI = dyn_cast<MemCpyInst>(Inst)) 14 // ... MCI->getDest() ... MCI->getSource() ... 15 // 16 // All intrinsic function calls are instances of the call instruction, so these 17 // are all subclasses of the CallInst class. Note that none of these classes 18 // has state or virtual methods, which is an important part of this gross/neat 19 // hack working. 20 // 21 //===----------------------------------------------------------------------===// 22 23 #ifndef LLVM_IR_INTRINSICINST_H 24 #define LLVM_IR_INTRINSICINST_H 25 26 #include "llvm/IR/Constants.h" 27 #include "llvm/IR/DerivedTypes.h" 28 #include "llvm/IR/Function.h" 29 #include "llvm/IR/GlobalVariable.h" 30 #include "llvm/IR/Instructions.h" 31 #include "llvm/IR/Intrinsics.h" 32 #include "llvm/IR/Metadata.h" 33 #include "llvm/IR/Value.h" 34 #include "llvm/Support/Casting.h" 35 #include <cassert> 36 #include <cstdint> 37 38 namespace llvm { 39 40 /// A wrapper class for inspecting calls to intrinsic functions. 41 /// This allows the standard isa/dyncast/cast functionality to work with calls 42 /// to intrinsic functions. 43 class IntrinsicInst : public CallInst { 44 public: 45 IntrinsicInst() = delete; 46 IntrinsicInst(const IntrinsicInst &) = delete; 47 IntrinsicInst &operator=(const IntrinsicInst &) = delete; 48 49 /// Return the intrinsic ID of this intrinsic. 50 Intrinsic::ID getIntrinsicID() const { 51 return getCalledFunction()->getIntrinsicID(); 52 } 53 54 // Methods for support type inquiry through isa, cast, and dyn_cast: 55 static bool classof(const CallInst *I) { 56 if (const Function *CF = I->getCalledFunction()) 57 return CF->isIntrinsic(); 58 return false; 59 } 60 static bool classof(const Value *V) { 61 return isa<CallInst>(V) && classof(cast<CallInst>(V)); 62 } 63 }; 64 65 /// This is the common base class for debug info intrinsics. 66 class DbgInfoIntrinsic : public IntrinsicInst { 67 public: 68 /// \name Casting methods 69 /// @{ 70 static bool classof(const IntrinsicInst *I) { 71 switch (I->getIntrinsicID()) { 72 case Intrinsic::dbg_declare: 73 case Intrinsic::dbg_value: 74 case Intrinsic::dbg_addr: 75 case Intrinsic::dbg_label: 76 return true; 77 default: return false; 78 } 79 } 80 static bool classof(const Value *V) { 81 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 82 } 83 /// @} 84 }; 85 86 /// This is the common base class for debug info intrinsics for variables. 87 class DbgVariableIntrinsic : public DbgInfoIntrinsic { 88 public: 89 /// Get the location corresponding to the variable referenced by the debug 90 /// info intrinsic. Depending on the intrinsic, this could be the 91 /// variable's value or its address. 92 Value *getVariableLocation(bool AllowNullOp = true) const; 93 94 /// Does this describe the address of a local variable. True for dbg.addr 95 /// and dbg.declare, but not dbg.value, which describes its value. 96 bool isAddressOfVariable() const { 97 return getIntrinsicID() != Intrinsic::dbg_value; 98 } 99 100 DILocalVariable *getVariable() const { 101 return cast<DILocalVariable>(getRawVariable()); 102 } 103 104 DIExpression *getExpression() const { 105 return cast<DIExpression>(getRawExpression()); 106 } 107 108 Metadata *getRawVariable() const { 109 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 110 } 111 112 Metadata *getRawExpression() const { 113 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 114 } 115 116 /// Get the size (in bits) of the variable, or fragment of the variable that 117 /// is described. 118 Optional<uint64_t> getFragmentSizeInBits() const; 119 120 /// \name Casting methods 121 /// @{ 122 static bool classof(const IntrinsicInst *I) { 123 switch (I->getIntrinsicID()) { 124 case Intrinsic::dbg_declare: 125 case Intrinsic::dbg_value: 126 case Intrinsic::dbg_addr: 127 return true; 128 default: return false; 129 } 130 } 131 static bool classof(const Value *V) { 132 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 133 } 134 /// @} 135 }; 136 137 /// This represents the llvm.dbg.declare instruction. 138 class DbgDeclareInst : public DbgVariableIntrinsic { 139 public: 140 Value *getAddress() const { return getVariableLocation(); } 141 142 /// \name Casting methods 143 /// @{ 144 static bool classof(const IntrinsicInst *I) { 145 return I->getIntrinsicID() == Intrinsic::dbg_declare; 146 } 147 static bool classof(const Value *V) { 148 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 149 } 150 /// @} 151 }; 152 153 /// This represents the llvm.dbg.addr instruction. 154 class DbgAddrIntrinsic : public DbgVariableIntrinsic { 155 public: 156 Value *getAddress() const { return getVariableLocation(); } 157 158 /// \name Casting methods 159 /// @{ 160 static bool classof(const IntrinsicInst *I) { 161 return I->getIntrinsicID() == Intrinsic::dbg_addr; 162 } 163 static bool classof(const Value *V) { 164 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 165 } 166 }; 167 168 /// This represents the llvm.dbg.value instruction. 169 class DbgValueInst : public DbgVariableIntrinsic { 170 public: 171 Value *getValue() const { 172 return getVariableLocation(/* AllowNullOp = */ false); 173 } 174 175 /// \name Casting methods 176 /// @{ 177 static bool classof(const IntrinsicInst *I) { 178 return I->getIntrinsicID() == Intrinsic::dbg_value; 179 } 180 static bool classof(const Value *V) { 181 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 182 } 183 /// @} 184 }; 185 186 /// This represents the llvm.dbg.label instruction. 187 class DbgLabelInst : public DbgInfoIntrinsic { 188 public: 189 DILabel *getLabel() const { 190 return cast<DILabel>(getRawLabel()); 191 } 192 193 Metadata *getRawLabel() const { 194 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 195 } 196 197 /// Methods for support type inquiry through isa, cast, and dyn_cast: 198 /// @{ 199 static bool classof(const IntrinsicInst *I) { 200 return I->getIntrinsicID() == Intrinsic::dbg_label; 201 } 202 static bool classof(const Value *V) { 203 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 204 } 205 /// @} 206 }; 207 208 /// This is the common base class for constrained floating point intrinsics. 209 class ConstrainedFPIntrinsic : public IntrinsicInst { 210 public: 211 /// Specifies the rounding mode to be assumed. This is only used when 212 /// when constrained floating point is enabled. See the LLVM Language 213 /// Reference Manual for details. 214 enum RoundingMode : uint8_t { 215 rmDynamic, ///< This corresponds to "fpround.dynamic". 216 rmToNearest, ///< This corresponds to "fpround.tonearest". 217 rmDownward, ///< This corresponds to "fpround.downward". 218 rmUpward, ///< This corresponds to "fpround.upward". 219 rmTowardZero ///< This corresponds to "fpround.tozero". 220 }; 221 222 /// Specifies the required exception behavior. This is only used when 223 /// when constrained floating point is used. See the LLVM Language 224 /// Reference Manual for details. 225 enum ExceptionBehavior : uint8_t { 226 ebIgnore, ///< This corresponds to "fpexcept.ignore". 227 ebMayTrap, ///< This corresponds to "fpexcept.maytrap". 228 ebStrict ///< This corresponds to "fpexcept.strict". 229 }; 230 231 bool isUnaryOp() const; 232 bool isTernaryOp() const; 233 Optional<RoundingMode> getRoundingMode() const; 234 Optional<ExceptionBehavior> getExceptionBehavior() const; 235 236 /// Returns a valid RoundingMode enumerator when given a string 237 /// that is valid as input in constrained intrinsic rounding mode 238 /// metadata. 239 static Optional<RoundingMode> StrToRoundingMode(StringRef); 240 241 /// For any RoundingMode enumerator, returns a string valid as input in 242 /// constrained intrinsic rounding mode metadata. 243 static Optional<StringRef> RoundingModeToStr(RoundingMode); 244 245 /// Returns a valid ExceptionBehavior enumerator when given a string 246 /// valid as input in constrained intrinsic exception behavior metadata. 247 static Optional<ExceptionBehavior> StrToExceptionBehavior(StringRef); 248 249 /// For any ExceptionBehavior enumerator, returns a string valid as 250 /// input in constrained intrinsic exception behavior metadata. 251 static Optional<StringRef> ExceptionBehaviorToStr(ExceptionBehavior); 252 253 // Methods for support type inquiry through isa, cast, and dyn_cast: 254 static bool classof(const IntrinsicInst *I) { 255 switch (I->getIntrinsicID()) { 256 case Intrinsic::experimental_constrained_fadd: 257 case Intrinsic::experimental_constrained_fsub: 258 case Intrinsic::experimental_constrained_fmul: 259 case Intrinsic::experimental_constrained_fdiv: 260 case Intrinsic::experimental_constrained_frem: 261 case Intrinsic::experimental_constrained_fma: 262 case Intrinsic::experimental_constrained_fptosi: 263 case Intrinsic::experimental_constrained_fptoui: 264 case Intrinsic::experimental_constrained_fptrunc: 265 case Intrinsic::experimental_constrained_fpext: 266 case Intrinsic::experimental_constrained_sqrt: 267 case Intrinsic::experimental_constrained_pow: 268 case Intrinsic::experimental_constrained_powi: 269 case Intrinsic::experimental_constrained_sin: 270 case Intrinsic::experimental_constrained_cos: 271 case Intrinsic::experimental_constrained_exp: 272 case Intrinsic::experimental_constrained_exp2: 273 case Intrinsic::experimental_constrained_log: 274 case Intrinsic::experimental_constrained_log10: 275 case Intrinsic::experimental_constrained_log2: 276 case Intrinsic::experimental_constrained_lrint: 277 case Intrinsic::experimental_constrained_llrint: 278 case Intrinsic::experimental_constrained_rint: 279 case Intrinsic::experimental_constrained_nearbyint: 280 case Intrinsic::experimental_constrained_maxnum: 281 case Intrinsic::experimental_constrained_minnum: 282 case Intrinsic::experimental_constrained_ceil: 283 case Intrinsic::experimental_constrained_floor: 284 case Intrinsic::experimental_constrained_lround: 285 case Intrinsic::experimental_constrained_llround: 286 case Intrinsic::experimental_constrained_round: 287 case Intrinsic::experimental_constrained_trunc: 288 return true; 289 default: return false; 290 } 291 } 292 static bool classof(const Value *V) { 293 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 294 } 295 }; 296 297 /// This class represents an intrinsic that is based on a binary operation. 298 /// This includes op.with.overflow and saturating add/sub intrinsics. 299 class BinaryOpIntrinsic : public IntrinsicInst { 300 public: 301 static bool classof(const IntrinsicInst *I) { 302 switch (I->getIntrinsicID()) { 303 case Intrinsic::uadd_with_overflow: 304 case Intrinsic::sadd_with_overflow: 305 case Intrinsic::usub_with_overflow: 306 case Intrinsic::ssub_with_overflow: 307 case Intrinsic::umul_with_overflow: 308 case Intrinsic::smul_with_overflow: 309 case Intrinsic::uadd_sat: 310 case Intrinsic::sadd_sat: 311 case Intrinsic::usub_sat: 312 case Intrinsic::ssub_sat: 313 return true; 314 default: 315 return false; 316 } 317 } 318 static bool classof(const Value *V) { 319 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 320 } 321 322 Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); } 323 Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); } 324 325 /// Returns the binary operation underlying the intrinsic. 326 Instruction::BinaryOps getBinaryOp() const; 327 328 /// Whether the intrinsic is signed or unsigned. 329 bool isSigned() const; 330 331 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. 332 unsigned getNoWrapKind() const; 333 }; 334 335 /// Represents an op.with.overflow intrinsic. 336 class WithOverflowInst : public BinaryOpIntrinsic { 337 public: 338 static bool classof(const IntrinsicInst *I) { 339 switch (I->getIntrinsicID()) { 340 case Intrinsic::uadd_with_overflow: 341 case Intrinsic::sadd_with_overflow: 342 case Intrinsic::usub_with_overflow: 343 case Intrinsic::ssub_with_overflow: 344 case Intrinsic::umul_with_overflow: 345 case Intrinsic::smul_with_overflow: 346 return true; 347 default: 348 return false; 349 } 350 } 351 static bool classof(const Value *V) { 352 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 353 } 354 }; 355 356 /// Represents a saturating add/sub intrinsic. 357 class SaturatingInst : public BinaryOpIntrinsic { 358 public: 359 static bool classof(const IntrinsicInst *I) { 360 switch (I->getIntrinsicID()) { 361 case Intrinsic::uadd_sat: 362 case Intrinsic::sadd_sat: 363 case Intrinsic::usub_sat: 364 case Intrinsic::ssub_sat: 365 return true; 366 default: 367 return false; 368 } 369 } 370 static bool classof(const Value *V) { 371 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 372 } 373 }; 374 375 /// Common base class for all memory intrinsics. Simply provides 376 /// common methods. 377 /// Written as CRTP to avoid a common base class amongst the 378 /// three atomicity hierarchies. 379 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 380 private: 381 enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 382 383 public: 384 Value *getRawDest() const { 385 return const_cast<Value *>(getArgOperand(ARG_DEST)); 386 } 387 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } 388 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 389 390 Value *getLength() const { 391 return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 392 } 393 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } 394 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 395 396 /// This is just like getRawDest, but it strips off any cast 397 /// instructions (including addrspacecast) that feed it, giving the 398 /// original input. The returned value is guaranteed to be a pointer. 399 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 400 401 unsigned getDestAddressSpace() const { 402 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 403 } 404 405 unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); } 406 407 /// Set the specified arguments of the instruction. 408 void setDest(Value *Ptr) { 409 assert(getRawDest()->getType() == Ptr->getType() && 410 "setDest called with pointer of wrong type!"); 411 setArgOperand(ARG_DEST, Ptr); 412 } 413 414 void setDestAlignment(unsigned Alignment) { 415 removeParamAttr(ARG_DEST, Attribute::Alignment); 416 if (Alignment > 0) 417 addParamAttr(ARG_DEST, Attribute::getWithAlignment(getContext(), 418 Align(Alignment))); 419 } 420 421 void setLength(Value *L) { 422 assert(getLength()->getType() == L->getType() && 423 "setLength called with value of wrong type!"); 424 setArgOperand(ARG_LENGTH, L); 425 } 426 }; 427 428 /// Common base class for all memory transfer intrinsics. Simply provides 429 /// common methods. 430 template <class BaseCL> class MemTransferBase : public BaseCL { 431 private: 432 enum { ARG_SOURCE = 1 }; 433 434 public: 435 /// Return the arguments to the instruction. 436 Value *getRawSource() const { 437 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 438 } 439 const Use &getRawSourceUse() const { 440 return BaseCL::getArgOperandUse(ARG_SOURCE); 441 } 442 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 443 444 /// This is just like getRawSource, but it strips off any cast 445 /// instructions that feed it, giving the original input. The returned 446 /// value is guaranteed to be a pointer. 447 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 448 449 unsigned getSourceAddressSpace() const { 450 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 451 } 452 453 unsigned getSourceAlignment() const { 454 return BaseCL::getParamAlignment(ARG_SOURCE); 455 } 456 457 void setSource(Value *Ptr) { 458 assert(getRawSource()->getType() == Ptr->getType() && 459 "setSource called with pointer of wrong type!"); 460 BaseCL::setArgOperand(ARG_SOURCE, Ptr); 461 } 462 463 void setSourceAlignment(unsigned Alignment) { 464 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 465 if (Alignment > 0) 466 BaseCL::addParamAttr(ARG_SOURCE, 467 Attribute::getWithAlignment(BaseCL::getContext(), 468 Align(Alignment))); 469 } 470 }; 471 472 /// Common base class for all memset intrinsics. Simply provides 473 /// common methods. 474 template <class BaseCL> class MemSetBase : public BaseCL { 475 private: 476 enum { ARG_VALUE = 1 }; 477 478 public: 479 Value *getValue() const { 480 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 481 } 482 const Use &getValueUse() const { 483 return BaseCL::getArgOperandUse(ARG_VALUE); 484 } 485 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 486 487 void setValue(Value *Val) { 488 assert(getValue()->getType() == Val->getType() && 489 "setValue called with value of wrong type!"); 490 BaseCL::setArgOperand(ARG_VALUE, Val); 491 } 492 }; 493 494 // The common base class for the atomic memset/memmove/memcpy intrinsics 495 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 496 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 497 private: 498 enum { ARG_ELEMENTSIZE = 3 }; 499 500 public: 501 Value *getRawElementSizeInBytes() const { 502 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 503 } 504 505 ConstantInt *getElementSizeInBytesCst() const { 506 return cast<ConstantInt>(getRawElementSizeInBytes()); 507 } 508 509 uint32_t getElementSizeInBytes() const { 510 return getElementSizeInBytesCst()->getZExtValue(); 511 } 512 513 void setElementSizeInBytes(Constant *V) { 514 assert(V->getType() == Type::getInt8Ty(getContext()) && 515 "setElementSizeInBytes called with value of wrong type!"); 516 setArgOperand(ARG_ELEMENTSIZE, V); 517 } 518 519 static bool classof(const IntrinsicInst *I) { 520 switch (I->getIntrinsicID()) { 521 case Intrinsic::memcpy_element_unordered_atomic: 522 case Intrinsic::memmove_element_unordered_atomic: 523 case Intrinsic::memset_element_unordered_atomic: 524 return true; 525 default: 526 return false; 527 } 528 } 529 static bool classof(const Value *V) { 530 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 531 } 532 }; 533 534 /// This class represents atomic memset intrinsic 535 // i.e. llvm.element.unordered.atomic.memset 536 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 537 public: 538 static bool classof(const IntrinsicInst *I) { 539 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 540 } 541 static bool classof(const Value *V) { 542 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 543 } 544 }; 545 546 // This class wraps the atomic memcpy/memmove intrinsics 547 // i.e. llvm.element.unordered.atomic.memcpy/memmove 548 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 549 public: 550 static bool classof(const IntrinsicInst *I) { 551 switch (I->getIntrinsicID()) { 552 case Intrinsic::memcpy_element_unordered_atomic: 553 case Intrinsic::memmove_element_unordered_atomic: 554 return true; 555 default: 556 return false; 557 } 558 } 559 static bool classof(const Value *V) { 560 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 561 } 562 }; 563 564 /// This class represents the atomic memcpy intrinsic 565 /// i.e. llvm.element.unordered.atomic.memcpy 566 class AtomicMemCpyInst : public AtomicMemTransferInst { 567 public: 568 static bool classof(const IntrinsicInst *I) { 569 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 570 } 571 static bool classof(const Value *V) { 572 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 573 } 574 }; 575 576 /// This class represents the atomic memmove intrinsic 577 /// i.e. llvm.element.unordered.atomic.memmove 578 class AtomicMemMoveInst : public AtomicMemTransferInst { 579 public: 580 static bool classof(const IntrinsicInst *I) { 581 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 582 } 583 static bool classof(const Value *V) { 584 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 585 } 586 }; 587 588 /// This is the common base class for memset/memcpy/memmove. 589 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 590 private: 591 enum { ARG_VOLATILE = 3 }; 592 593 public: 594 ConstantInt *getVolatileCst() const { 595 return cast<ConstantInt>( 596 const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 597 } 598 599 bool isVolatile() const { 600 return !getVolatileCst()->isZero(); 601 } 602 603 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 604 605 // Methods for support type inquiry through isa, cast, and dyn_cast: 606 static bool classof(const IntrinsicInst *I) { 607 switch (I->getIntrinsicID()) { 608 case Intrinsic::memcpy: 609 case Intrinsic::memmove: 610 case Intrinsic::memset: 611 return true; 612 default: return false; 613 } 614 } 615 static bool classof(const Value *V) { 616 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 617 } 618 }; 619 620 /// This class wraps the llvm.memset intrinsic. 621 class MemSetInst : public MemSetBase<MemIntrinsic> { 622 public: 623 // Methods for support type inquiry through isa, cast, and dyn_cast: 624 static bool classof(const IntrinsicInst *I) { 625 return I->getIntrinsicID() == Intrinsic::memset; 626 } 627 static bool classof(const Value *V) { 628 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 629 } 630 }; 631 632 /// This class wraps the llvm.memcpy/memmove intrinsics. 633 class MemTransferInst : public MemTransferBase<MemIntrinsic> { 634 public: 635 // Methods for support type inquiry through isa, cast, and dyn_cast: 636 static bool classof(const IntrinsicInst *I) { 637 return I->getIntrinsicID() == Intrinsic::memcpy || 638 I->getIntrinsicID() == Intrinsic::memmove; 639 } 640 static bool classof(const Value *V) { 641 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 642 } 643 }; 644 645 /// This class wraps the llvm.memcpy intrinsic. 646 class MemCpyInst : public MemTransferInst { 647 public: 648 // Methods for support type inquiry through isa, cast, and dyn_cast: 649 static bool classof(const IntrinsicInst *I) { 650 return I->getIntrinsicID() == Intrinsic::memcpy; 651 } 652 static bool classof(const Value *V) { 653 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 654 } 655 }; 656 657 /// This class wraps the llvm.memmove intrinsic. 658 class MemMoveInst : public MemTransferInst { 659 public: 660 // Methods for support type inquiry through isa, cast, and dyn_cast: 661 static bool classof(const IntrinsicInst *I) { 662 return I->getIntrinsicID() == Intrinsic::memmove; 663 } 664 static bool classof(const Value *V) { 665 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 666 } 667 }; 668 669 // The common base class for any memset/memmove/memcpy intrinsics; 670 // whether they be atomic or non-atomic. 671 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 672 // and llvm.memset/memcpy/memmove 673 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 674 public: 675 bool isVolatile() const { 676 // Only the non-atomic intrinsics can be volatile 677 if (auto *MI = dyn_cast<MemIntrinsic>(this)) 678 return MI->isVolatile(); 679 return false; 680 } 681 682 static bool classof(const IntrinsicInst *I) { 683 switch (I->getIntrinsicID()) { 684 case Intrinsic::memcpy: 685 case Intrinsic::memmove: 686 case Intrinsic::memset: 687 case Intrinsic::memcpy_element_unordered_atomic: 688 case Intrinsic::memmove_element_unordered_atomic: 689 case Intrinsic::memset_element_unordered_atomic: 690 return true; 691 default: 692 return false; 693 } 694 } 695 static bool classof(const Value *V) { 696 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 697 } 698 }; 699 700 /// This class represents any memset intrinsic 701 // i.e. llvm.element.unordered.atomic.memset 702 // and llvm.memset 703 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 704 public: 705 static bool classof(const IntrinsicInst *I) { 706 switch (I->getIntrinsicID()) { 707 case Intrinsic::memset: 708 case Intrinsic::memset_element_unordered_atomic: 709 return true; 710 default: 711 return false; 712 } 713 } 714 static bool classof(const Value *V) { 715 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 716 } 717 }; 718 719 // This class wraps any memcpy/memmove intrinsics 720 // i.e. llvm.element.unordered.atomic.memcpy/memmove 721 // and llvm.memcpy/memmove 722 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 723 public: 724 static bool classof(const IntrinsicInst *I) { 725 switch (I->getIntrinsicID()) { 726 case Intrinsic::memcpy: 727 case Intrinsic::memmove: 728 case Intrinsic::memcpy_element_unordered_atomic: 729 case Intrinsic::memmove_element_unordered_atomic: 730 return true; 731 default: 732 return false; 733 } 734 } 735 static bool classof(const Value *V) { 736 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 737 } 738 }; 739 740 /// This class represents any memcpy intrinsic 741 /// i.e. llvm.element.unordered.atomic.memcpy 742 /// and llvm.memcpy 743 class AnyMemCpyInst : public AnyMemTransferInst { 744 public: 745 static bool classof(const IntrinsicInst *I) { 746 switch (I->getIntrinsicID()) { 747 case Intrinsic::memcpy: 748 case Intrinsic::memcpy_element_unordered_atomic: 749 return true; 750 default: 751 return false; 752 } 753 } 754 static bool classof(const Value *V) { 755 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 756 } 757 }; 758 759 /// This class represents any memmove intrinsic 760 /// i.e. llvm.element.unordered.atomic.memmove 761 /// and llvm.memmove 762 class AnyMemMoveInst : public AnyMemTransferInst { 763 public: 764 static bool classof(const IntrinsicInst *I) { 765 switch (I->getIntrinsicID()) { 766 case Intrinsic::memmove: 767 case Intrinsic::memmove_element_unordered_atomic: 768 return true; 769 default: 770 return false; 771 } 772 } 773 static bool classof(const Value *V) { 774 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 775 } 776 }; 777 778 /// This represents the llvm.va_start intrinsic. 779 class VAStartInst : public IntrinsicInst { 780 public: 781 static bool classof(const IntrinsicInst *I) { 782 return I->getIntrinsicID() == Intrinsic::vastart; 783 } 784 static bool classof(const Value *V) { 785 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 786 } 787 788 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 789 }; 790 791 /// This represents the llvm.va_end intrinsic. 792 class VAEndInst : public IntrinsicInst { 793 public: 794 static bool classof(const IntrinsicInst *I) { 795 return I->getIntrinsicID() == Intrinsic::vaend; 796 } 797 static bool classof(const Value *V) { 798 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 799 } 800 801 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 802 }; 803 804 /// This represents the llvm.va_copy intrinsic. 805 class VACopyInst : public IntrinsicInst { 806 public: 807 static bool classof(const IntrinsicInst *I) { 808 return I->getIntrinsicID() == Intrinsic::vacopy; 809 } 810 static bool classof(const Value *V) { 811 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 812 } 813 814 Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } 815 Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 816 }; 817 818 /// This represents the llvm.instrprof_increment intrinsic. 819 class InstrProfIncrementInst : public IntrinsicInst { 820 public: 821 static bool classof(const IntrinsicInst *I) { 822 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 823 } 824 static bool classof(const Value *V) { 825 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 826 } 827 828 GlobalVariable *getName() const { 829 return cast<GlobalVariable>( 830 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 831 } 832 833 ConstantInt *getHash() const { 834 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 835 } 836 837 ConstantInt *getNumCounters() const { 838 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 839 } 840 841 ConstantInt *getIndex() const { 842 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 843 } 844 845 Value *getStep() const; 846 }; 847 848 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 849 public: 850 static bool classof(const IntrinsicInst *I) { 851 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 852 } 853 static bool classof(const Value *V) { 854 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 855 } 856 }; 857 858 /// This represents the llvm.instrprof_value_profile intrinsic. 859 class InstrProfValueProfileInst : public IntrinsicInst { 860 public: 861 static bool classof(const IntrinsicInst *I) { 862 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 863 } 864 static bool classof(const Value *V) { 865 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 866 } 867 868 GlobalVariable *getName() const { 869 return cast<GlobalVariable>( 870 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 871 } 872 873 ConstantInt *getHash() const { 874 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 875 } 876 877 Value *getTargetValue() const { 878 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 879 } 880 881 ConstantInt *getValueKind() const { 882 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 883 } 884 885 // Returns the value site index. 886 ConstantInt *getIndex() const { 887 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 888 } 889 }; 890 891 } // end namespace llvm 892 893 #endif // LLVM_IR_INTRINSICINST_H 894