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_fptrunc: 263 case Intrinsic::experimental_constrained_fpext: 264 case Intrinsic::experimental_constrained_sqrt: 265 case Intrinsic::experimental_constrained_pow: 266 case Intrinsic::experimental_constrained_powi: 267 case Intrinsic::experimental_constrained_sin: 268 case Intrinsic::experimental_constrained_cos: 269 case Intrinsic::experimental_constrained_exp: 270 case Intrinsic::experimental_constrained_exp2: 271 case Intrinsic::experimental_constrained_log: 272 case Intrinsic::experimental_constrained_log10: 273 case Intrinsic::experimental_constrained_log2: 274 case Intrinsic::experimental_constrained_rint: 275 case Intrinsic::experimental_constrained_nearbyint: 276 case Intrinsic::experimental_constrained_maxnum: 277 case Intrinsic::experimental_constrained_minnum: 278 case Intrinsic::experimental_constrained_ceil: 279 case Intrinsic::experimental_constrained_floor: 280 case Intrinsic::experimental_constrained_round: 281 case Intrinsic::experimental_constrained_trunc: 282 return true; 283 default: return false; 284 } 285 } 286 static bool classof(const Value *V) { 287 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 288 } 289 }; 290 291 /// This class represents an intrinsic that is based on a binary operation. 292 /// This includes op.with.overflow and saturating add/sub intrinsics. 293 class BinaryOpIntrinsic : public IntrinsicInst { 294 public: 295 static bool classof(const IntrinsicInst *I) { 296 switch (I->getIntrinsicID()) { 297 case Intrinsic::uadd_with_overflow: 298 case Intrinsic::sadd_with_overflow: 299 case Intrinsic::usub_with_overflow: 300 case Intrinsic::ssub_with_overflow: 301 case Intrinsic::umul_with_overflow: 302 case Intrinsic::smul_with_overflow: 303 case Intrinsic::uadd_sat: 304 case Intrinsic::sadd_sat: 305 case Intrinsic::usub_sat: 306 case Intrinsic::ssub_sat: 307 return true; 308 default: 309 return false; 310 } 311 } 312 static bool classof(const Value *V) { 313 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 314 } 315 316 Value *getLHS() const { return const_cast<Value*>(getArgOperand(0)); } 317 Value *getRHS() const { return const_cast<Value*>(getArgOperand(1)); } 318 319 /// Returns the binary operation underlying the intrinsic. 320 Instruction::BinaryOps getBinaryOp() const; 321 322 /// Whether the intrinsic is signed or unsigned. 323 bool isSigned() const; 324 325 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. 326 unsigned getNoWrapKind() const; 327 }; 328 329 /// Represents an op.with.overflow intrinsic. 330 class WithOverflowInst : public BinaryOpIntrinsic { 331 public: 332 static bool classof(const IntrinsicInst *I) { 333 switch (I->getIntrinsicID()) { 334 case Intrinsic::uadd_with_overflow: 335 case Intrinsic::sadd_with_overflow: 336 case Intrinsic::usub_with_overflow: 337 case Intrinsic::ssub_with_overflow: 338 case Intrinsic::umul_with_overflow: 339 case Intrinsic::smul_with_overflow: 340 return true; 341 default: 342 return false; 343 } 344 } 345 static bool classof(const Value *V) { 346 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 347 } 348 }; 349 350 /// Represents a saturating add/sub intrinsic. 351 class SaturatingInst : public BinaryOpIntrinsic { 352 public: 353 static bool classof(const IntrinsicInst *I) { 354 switch (I->getIntrinsicID()) { 355 case Intrinsic::uadd_sat: 356 case Intrinsic::sadd_sat: 357 case Intrinsic::usub_sat: 358 case Intrinsic::ssub_sat: 359 return true; 360 default: 361 return false; 362 } 363 } 364 static bool classof(const Value *V) { 365 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 366 } 367 }; 368 369 /// Common base class for all memory intrinsics. Simply provides 370 /// common methods. 371 /// Written as CRTP to avoid a common base class amongst the 372 /// three atomicity hierarchies. 373 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 374 private: 375 enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 376 377 public: 378 Value *getRawDest() const { 379 return const_cast<Value *>(getArgOperand(ARG_DEST)); 380 } 381 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } 382 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 383 384 Value *getLength() const { 385 return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 386 } 387 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } 388 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 389 390 /// This is just like getRawDest, but it strips off any cast 391 /// instructions (including addrspacecast) that feed it, giving the 392 /// original input. The returned value is guaranteed to be a pointer. 393 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 394 395 unsigned getDestAddressSpace() const { 396 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 397 } 398 399 unsigned getDestAlignment() const { return getParamAlignment(ARG_DEST); } 400 401 /// Set the specified arguments of the instruction. 402 void setDest(Value *Ptr) { 403 assert(getRawDest()->getType() == Ptr->getType() && 404 "setDest called with pointer of wrong type!"); 405 setArgOperand(ARG_DEST, Ptr); 406 } 407 408 void setDestAlignment(unsigned Align) { 409 removeParamAttr(ARG_DEST, Attribute::Alignment); 410 if (Align > 0) 411 addParamAttr(ARG_DEST, 412 Attribute::getWithAlignment(getContext(), Align)); 413 } 414 415 void setLength(Value *L) { 416 assert(getLength()->getType() == L->getType() && 417 "setLength called with value of wrong type!"); 418 setArgOperand(ARG_LENGTH, L); 419 } 420 }; 421 422 /// Common base class for all memory transfer intrinsics. Simply provides 423 /// common methods. 424 template <class BaseCL> class MemTransferBase : public BaseCL { 425 private: 426 enum { ARG_SOURCE = 1 }; 427 428 public: 429 /// Return the arguments to the instruction. 430 Value *getRawSource() const { 431 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 432 } 433 const Use &getRawSourceUse() const { 434 return BaseCL::getArgOperandUse(ARG_SOURCE); 435 } 436 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 437 438 /// This is just like getRawSource, but it strips off any cast 439 /// instructions that feed it, giving the original input. The returned 440 /// value is guaranteed to be a pointer. 441 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 442 443 unsigned getSourceAddressSpace() const { 444 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 445 } 446 447 unsigned getSourceAlignment() const { 448 return BaseCL::getParamAlignment(ARG_SOURCE); 449 } 450 451 void setSource(Value *Ptr) { 452 assert(getRawSource()->getType() == Ptr->getType() && 453 "setSource called with pointer of wrong type!"); 454 BaseCL::setArgOperand(ARG_SOURCE, Ptr); 455 } 456 457 void setSourceAlignment(unsigned Align) { 458 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 459 if (Align > 0) 460 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 461 BaseCL::getContext(), Align)); 462 } 463 }; 464 465 /// Common base class for all memset intrinsics. Simply provides 466 /// common methods. 467 template <class BaseCL> class MemSetBase : public BaseCL { 468 private: 469 enum { ARG_VALUE = 1 }; 470 471 public: 472 Value *getValue() const { 473 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 474 } 475 const Use &getValueUse() const { 476 return BaseCL::getArgOperandUse(ARG_VALUE); 477 } 478 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 479 480 void setValue(Value *Val) { 481 assert(getValue()->getType() == Val->getType() && 482 "setValue called with value of wrong type!"); 483 BaseCL::setArgOperand(ARG_VALUE, Val); 484 } 485 }; 486 487 // The common base class for the atomic memset/memmove/memcpy intrinsics 488 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 489 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 490 private: 491 enum { ARG_ELEMENTSIZE = 3 }; 492 493 public: 494 Value *getRawElementSizeInBytes() const { 495 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 496 } 497 498 ConstantInt *getElementSizeInBytesCst() const { 499 return cast<ConstantInt>(getRawElementSizeInBytes()); 500 } 501 502 uint32_t getElementSizeInBytes() const { 503 return getElementSizeInBytesCst()->getZExtValue(); 504 } 505 506 void setElementSizeInBytes(Constant *V) { 507 assert(V->getType() == Type::getInt8Ty(getContext()) && 508 "setElementSizeInBytes called with value of wrong type!"); 509 setArgOperand(ARG_ELEMENTSIZE, V); 510 } 511 512 static bool classof(const IntrinsicInst *I) { 513 switch (I->getIntrinsicID()) { 514 case Intrinsic::memcpy_element_unordered_atomic: 515 case Intrinsic::memmove_element_unordered_atomic: 516 case Intrinsic::memset_element_unordered_atomic: 517 return true; 518 default: 519 return false; 520 } 521 } 522 static bool classof(const Value *V) { 523 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 524 } 525 }; 526 527 /// This class represents atomic memset intrinsic 528 // i.e. llvm.element.unordered.atomic.memset 529 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 530 public: 531 static bool classof(const IntrinsicInst *I) { 532 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 533 } 534 static bool classof(const Value *V) { 535 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 536 } 537 }; 538 539 // This class wraps the atomic memcpy/memmove intrinsics 540 // i.e. llvm.element.unordered.atomic.memcpy/memmove 541 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 542 public: 543 static bool classof(const IntrinsicInst *I) { 544 switch (I->getIntrinsicID()) { 545 case Intrinsic::memcpy_element_unordered_atomic: 546 case Intrinsic::memmove_element_unordered_atomic: 547 return true; 548 default: 549 return false; 550 } 551 } 552 static bool classof(const Value *V) { 553 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 554 } 555 }; 556 557 /// This class represents the atomic memcpy intrinsic 558 /// i.e. llvm.element.unordered.atomic.memcpy 559 class AtomicMemCpyInst : public AtomicMemTransferInst { 560 public: 561 static bool classof(const IntrinsicInst *I) { 562 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 563 } 564 static bool classof(const Value *V) { 565 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 566 } 567 }; 568 569 /// This class represents the atomic memmove intrinsic 570 /// i.e. llvm.element.unordered.atomic.memmove 571 class AtomicMemMoveInst : public AtomicMemTransferInst { 572 public: 573 static bool classof(const IntrinsicInst *I) { 574 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 575 } 576 static bool classof(const Value *V) { 577 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 578 } 579 }; 580 581 /// This is the common base class for memset/memcpy/memmove. 582 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 583 private: 584 enum { ARG_VOLATILE = 3 }; 585 586 public: 587 ConstantInt *getVolatileCst() const { 588 return cast<ConstantInt>( 589 const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 590 } 591 592 bool isVolatile() const { 593 return !getVolatileCst()->isZero(); 594 } 595 596 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 597 598 // Methods for support type inquiry through isa, cast, and dyn_cast: 599 static bool classof(const IntrinsicInst *I) { 600 switch (I->getIntrinsicID()) { 601 case Intrinsic::memcpy: 602 case Intrinsic::memmove: 603 case Intrinsic::memset: 604 return true; 605 default: return false; 606 } 607 } 608 static bool classof(const Value *V) { 609 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 610 } 611 }; 612 613 /// This class wraps the llvm.memset intrinsic. 614 class MemSetInst : public MemSetBase<MemIntrinsic> { 615 public: 616 // Methods for support type inquiry through isa, cast, and dyn_cast: 617 static bool classof(const IntrinsicInst *I) { 618 return I->getIntrinsicID() == Intrinsic::memset; 619 } 620 static bool classof(const Value *V) { 621 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 622 } 623 }; 624 625 /// This class wraps the llvm.memcpy/memmove intrinsics. 626 class MemTransferInst : public MemTransferBase<MemIntrinsic> { 627 public: 628 // Methods for support type inquiry through isa, cast, and dyn_cast: 629 static bool classof(const IntrinsicInst *I) { 630 return I->getIntrinsicID() == Intrinsic::memcpy || 631 I->getIntrinsicID() == Intrinsic::memmove; 632 } 633 static bool classof(const Value *V) { 634 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 635 } 636 }; 637 638 /// This class wraps the llvm.memcpy intrinsic. 639 class MemCpyInst : public MemTransferInst { 640 public: 641 // Methods for support type inquiry through isa, cast, and dyn_cast: 642 static bool classof(const IntrinsicInst *I) { 643 return I->getIntrinsicID() == Intrinsic::memcpy; 644 } 645 static bool classof(const Value *V) { 646 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 647 } 648 }; 649 650 /// This class wraps the llvm.memmove intrinsic. 651 class MemMoveInst : public MemTransferInst { 652 public: 653 // Methods for support type inquiry through isa, cast, and dyn_cast: 654 static bool classof(const IntrinsicInst *I) { 655 return I->getIntrinsicID() == Intrinsic::memmove; 656 } 657 static bool classof(const Value *V) { 658 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 659 } 660 }; 661 662 // The common base class for any memset/memmove/memcpy intrinsics; 663 // whether they be atomic or non-atomic. 664 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 665 // and llvm.memset/memcpy/memmove 666 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 667 public: 668 bool isVolatile() const { 669 // Only the non-atomic intrinsics can be volatile 670 if (auto *MI = dyn_cast<MemIntrinsic>(this)) 671 return MI->isVolatile(); 672 return false; 673 } 674 675 static bool classof(const IntrinsicInst *I) { 676 switch (I->getIntrinsicID()) { 677 case Intrinsic::memcpy: 678 case Intrinsic::memmove: 679 case Intrinsic::memset: 680 case Intrinsic::memcpy_element_unordered_atomic: 681 case Intrinsic::memmove_element_unordered_atomic: 682 case Intrinsic::memset_element_unordered_atomic: 683 return true; 684 default: 685 return false; 686 } 687 } 688 static bool classof(const Value *V) { 689 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 690 } 691 }; 692 693 /// This class represents any memset intrinsic 694 // i.e. llvm.element.unordered.atomic.memset 695 // and llvm.memset 696 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 697 public: 698 static bool classof(const IntrinsicInst *I) { 699 switch (I->getIntrinsicID()) { 700 case Intrinsic::memset: 701 case Intrinsic::memset_element_unordered_atomic: 702 return true; 703 default: 704 return false; 705 } 706 } 707 static bool classof(const Value *V) { 708 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 709 } 710 }; 711 712 // This class wraps any memcpy/memmove intrinsics 713 // i.e. llvm.element.unordered.atomic.memcpy/memmove 714 // and llvm.memcpy/memmove 715 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 716 public: 717 static bool classof(const IntrinsicInst *I) { 718 switch (I->getIntrinsicID()) { 719 case Intrinsic::memcpy: 720 case Intrinsic::memmove: 721 case Intrinsic::memcpy_element_unordered_atomic: 722 case Intrinsic::memmove_element_unordered_atomic: 723 return true; 724 default: 725 return false; 726 } 727 } 728 static bool classof(const Value *V) { 729 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 730 } 731 }; 732 733 /// This class represents any memcpy intrinsic 734 /// i.e. llvm.element.unordered.atomic.memcpy 735 /// and llvm.memcpy 736 class AnyMemCpyInst : public AnyMemTransferInst { 737 public: 738 static bool classof(const IntrinsicInst *I) { 739 switch (I->getIntrinsicID()) { 740 case Intrinsic::memcpy: 741 case Intrinsic::memcpy_element_unordered_atomic: 742 return true; 743 default: 744 return false; 745 } 746 } 747 static bool classof(const Value *V) { 748 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 749 } 750 }; 751 752 /// This class represents any memmove intrinsic 753 /// i.e. llvm.element.unordered.atomic.memmove 754 /// and llvm.memmove 755 class AnyMemMoveInst : public AnyMemTransferInst { 756 public: 757 static bool classof(const IntrinsicInst *I) { 758 switch (I->getIntrinsicID()) { 759 case Intrinsic::memmove: 760 case Intrinsic::memmove_element_unordered_atomic: 761 return true; 762 default: 763 return false; 764 } 765 } 766 static bool classof(const Value *V) { 767 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 768 } 769 }; 770 771 /// This represents the llvm.va_start intrinsic. 772 class VAStartInst : public IntrinsicInst { 773 public: 774 static bool classof(const IntrinsicInst *I) { 775 return I->getIntrinsicID() == Intrinsic::vastart; 776 } 777 static bool classof(const Value *V) { 778 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 779 } 780 781 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 782 }; 783 784 /// This represents the llvm.va_end intrinsic. 785 class VAEndInst : public IntrinsicInst { 786 public: 787 static bool classof(const IntrinsicInst *I) { 788 return I->getIntrinsicID() == Intrinsic::vaend; 789 } 790 static bool classof(const Value *V) { 791 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 792 } 793 794 Value *getArgList() const { return const_cast<Value*>(getArgOperand(0)); } 795 }; 796 797 /// This represents the llvm.va_copy intrinsic. 798 class VACopyInst : public IntrinsicInst { 799 public: 800 static bool classof(const IntrinsicInst *I) { 801 return I->getIntrinsicID() == Intrinsic::vacopy; 802 } 803 static bool classof(const Value *V) { 804 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 805 } 806 807 Value *getDest() const { return const_cast<Value*>(getArgOperand(0)); } 808 Value *getSrc() const { return const_cast<Value*>(getArgOperand(1)); } 809 }; 810 811 /// This represents the llvm.instrprof_increment intrinsic. 812 class InstrProfIncrementInst : public IntrinsicInst { 813 public: 814 static bool classof(const IntrinsicInst *I) { 815 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 816 } 817 static bool classof(const Value *V) { 818 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 819 } 820 821 GlobalVariable *getName() const { 822 return cast<GlobalVariable>( 823 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 824 } 825 826 ConstantInt *getHash() const { 827 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 828 } 829 830 ConstantInt *getNumCounters() const { 831 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 832 } 833 834 ConstantInt *getIndex() const { 835 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 836 } 837 838 Value *getStep() const; 839 }; 840 841 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 842 public: 843 static bool classof(const IntrinsicInst *I) { 844 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 845 } 846 static bool classof(const Value *V) { 847 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 848 } 849 }; 850 851 /// This represents the llvm.instrprof_value_profile intrinsic. 852 class InstrProfValueProfileInst : public IntrinsicInst { 853 public: 854 static bool classof(const IntrinsicInst *I) { 855 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 856 } 857 static bool classof(const Value *V) { 858 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 859 } 860 861 GlobalVariable *getName() const { 862 return cast<GlobalVariable>( 863 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 864 } 865 866 ConstantInt *getHash() const { 867 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 868 } 869 870 Value *getTargetValue() const { 871 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 872 } 873 874 ConstantInt *getValueKind() const { 875 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 876 } 877 878 // Returns the value site index. 879 ConstantInt *getIndex() const { 880 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 881 } 882 }; 883 884 } // end namespace llvm 885 886 #endif // LLVM_IR_INTRINSICINST_H 887