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/FPEnv.h" 29 #include "llvm/IR/Function.h" 30 #include "llvm/IR/GlobalVariable.h" 31 #include "llvm/IR/Instructions.h" 32 #include "llvm/IR/Intrinsics.h" 33 #include "llvm/IR/Metadata.h" 34 #include "llvm/IR/Value.h" 35 #include "llvm/Support/Casting.h" 36 #include <cassert> 37 #include <cstdint> 38 39 namespace llvm { 40 41 /// A wrapper class for inspecting calls to intrinsic functions. 42 /// This allows the standard isa/dyncast/cast functionality to work with calls 43 /// to intrinsic functions. 44 class IntrinsicInst : public CallInst { 45 public: 46 IntrinsicInst() = delete; 47 IntrinsicInst(const IntrinsicInst &) = delete; 48 IntrinsicInst &operator=(const IntrinsicInst &) = delete; 49 50 /// Return the intrinsic ID of this intrinsic. 51 Intrinsic::ID getIntrinsicID() const { 52 return getCalledFunction()->getIntrinsicID(); 53 } 54 55 /// Return true if swapping the first two arguments to the intrinsic produces 56 /// the same result. 57 bool isCommutative() const { 58 switch (getIntrinsicID()) { 59 case Intrinsic::maxnum: 60 case Intrinsic::minnum: 61 case Intrinsic::maximum: 62 case Intrinsic::minimum: 63 case Intrinsic::smax: 64 case Intrinsic::smin: 65 case Intrinsic::umax: 66 case Intrinsic::umin: 67 case Intrinsic::sadd_sat: 68 case Intrinsic::uadd_sat: 69 case Intrinsic::sadd_with_overflow: 70 case Intrinsic::uadd_with_overflow: 71 case Intrinsic::smul_with_overflow: 72 case Intrinsic::umul_with_overflow: 73 case Intrinsic::smul_fix: 74 case Intrinsic::umul_fix: 75 case Intrinsic::smul_fix_sat: 76 case Intrinsic::umul_fix_sat: 77 case Intrinsic::fma: 78 case Intrinsic::fmuladd: 79 return true; 80 default: 81 return false; 82 } 83 } 84 85 // Methods for support type inquiry through isa, cast, and dyn_cast: 86 static bool classof(const CallInst *I) { 87 if (const Function *CF = I->getCalledFunction()) 88 return CF->isIntrinsic(); 89 return false; 90 } 91 static bool classof(const Value *V) { 92 return isa<CallInst>(V) && classof(cast<CallInst>(V)); 93 } 94 }; 95 96 /// Check if \p ID corresponds to a debug info intrinsic. 97 static inline bool isDbgInfoIntrinsic(Intrinsic::ID ID) { 98 switch (ID) { 99 case Intrinsic::dbg_declare: 100 case Intrinsic::dbg_value: 101 case Intrinsic::dbg_addr: 102 case Intrinsic::dbg_label: 103 return true; 104 default: 105 return false; 106 } 107 } 108 109 /// This is the common base class for debug info intrinsics. 110 class DbgInfoIntrinsic : public IntrinsicInst { 111 public: 112 /// \name Casting methods 113 /// @{ 114 static bool classof(const IntrinsicInst *I) { 115 return isDbgInfoIntrinsic(I->getIntrinsicID()); 116 } 117 static bool classof(const Value *V) { 118 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 119 } 120 /// @} 121 }; 122 123 /// This is the common base class for debug info intrinsics for variables. 124 class DbgVariableIntrinsic : public DbgInfoIntrinsic { 125 public: 126 /// Get the location corresponding to the variable referenced by the debug 127 /// info intrinsic. Depending on the intrinsic, this could be the 128 /// variable's value or its address. 129 Value *getVariableLocation(bool AllowNullOp = true) const; 130 131 /// Does this describe the address of a local variable. True for dbg.addr 132 /// and dbg.declare, but not dbg.value, which describes its value. 133 bool isAddressOfVariable() const { 134 return getIntrinsicID() != Intrinsic::dbg_value; 135 } 136 137 DILocalVariable *getVariable() const { 138 return cast<DILocalVariable>(getRawVariable()); 139 } 140 141 DIExpression *getExpression() const { 142 return cast<DIExpression>(getRawExpression()); 143 } 144 145 Metadata *getRawVariable() const { 146 return cast<MetadataAsValue>(getArgOperand(1))->getMetadata(); 147 } 148 149 Metadata *getRawExpression() const { 150 return cast<MetadataAsValue>(getArgOperand(2))->getMetadata(); 151 } 152 153 /// Get the size (in bits) of the variable, or fragment of the variable that 154 /// is described. 155 Optional<uint64_t> getFragmentSizeInBits() const; 156 157 /// \name Casting methods 158 /// @{ 159 static bool classof(const IntrinsicInst *I) { 160 switch (I->getIntrinsicID()) { 161 case Intrinsic::dbg_declare: 162 case Intrinsic::dbg_value: 163 case Intrinsic::dbg_addr: 164 return true; 165 default: 166 return false; 167 } 168 } 169 static bool classof(const Value *V) { 170 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 171 } 172 /// @} 173 }; 174 175 /// This represents the llvm.dbg.declare instruction. 176 class DbgDeclareInst : public DbgVariableIntrinsic { 177 public: 178 Value *getAddress() const { return getVariableLocation(); } 179 180 /// \name Casting methods 181 /// @{ 182 static bool classof(const IntrinsicInst *I) { 183 return I->getIntrinsicID() == Intrinsic::dbg_declare; 184 } 185 static bool classof(const Value *V) { 186 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 187 } 188 /// @} 189 }; 190 191 /// This represents the llvm.dbg.addr instruction. 192 class DbgAddrIntrinsic : public DbgVariableIntrinsic { 193 public: 194 Value *getAddress() const { return getVariableLocation(); } 195 196 /// \name Casting methods 197 /// @{ 198 static bool classof(const IntrinsicInst *I) { 199 return I->getIntrinsicID() == Intrinsic::dbg_addr; 200 } 201 static bool classof(const Value *V) { 202 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 203 } 204 }; 205 206 /// This represents the llvm.dbg.value instruction. 207 class DbgValueInst : public DbgVariableIntrinsic { 208 public: 209 Value *getValue() const { 210 return getVariableLocation(/* AllowNullOp = */ false); 211 } 212 213 /// \name Casting methods 214 /// @{ 215 static bool classof(const IntrinsicInst *I) { 216 return I->getIntrinsicID() == Intrinsic::dbg_value; 217 } 218 static bool classof(const Value *V) { 219 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 220 } 221 /// @} 222 }; 223 224 /// This represents the llvm.dbg.label instruction. 225 class DbgLabelInst : public DbgInfoIntrinsic { 226 public: 227 DILabel *getLabel() const { return cast<DILabel>(getRawLabel()); } 228 229 Metadata *getRawLabel() const { 230 return cast<MetadataAsValue>(getArgOperand(0))->getMetadata(); 231 } 232 233 /// Methods for support type inquiry through isa, cast, and dyn_cast: 234 /// @{ 235 static bool classof(const IntrinsicInst *I) { 236 return I->getIntrinsicID() == Intrinsic::dbg_label; 237 } 238 static bool classof(const Value *V) { 239 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 240 } 241 /// @} 242 }; 243 244 /// This is the common base class for vector predication intrinsics. 245 class VPIntrinsic : public IntrinsicInst { 246 public: 247 static Optional<int> GetMaskParamPos(Intrinsic::ID IntrinsicID); 248 static Optional<int> GetVectorLengthParamPos(Intrinsic::ID IntrinsicID); 249 250 /// The llvm.vp.* intrinsics for this instruction Opcode 251 static Intrinsic::ID GetForOpcode(unsigned OC); 252 253 // Whether \p ID is a VP intrinsic ID. 254 static bool IsVPIntrinsic(Intrinsic::ID); 255 256 /// \return the mask parameter or nullptr. 257 Value *getMaskParam() const; 258 259 /// \return the vector length parameter or nullptr. 260 Value *getVectorLengthParam() const; 261 262 /// \return whether the vector length param can be ignored. 263 bool canIgnoreVectorLengthParam() const; 264 265 /// \return the static element count (vector number of elements) the vector 266 /// length parameter applies to. 267 ElementCount getStaticVectorLength() const; 268 269 // Methods for support type inquiry through isa, cast, and dyn_cast: 270 static bool classof(const IntrinsicInst *I) { 271 return IsVPIntrinsic(I->getIntrinsicID()); 272 } 273 static bool classof(const Value *V) { 274 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 275 } 276 277 // Equivalent non-predicated opcode 278 unsigned getFunctionalOpcode() const { 279 return GetFunctionalOpcodeForVP(getIntrinsicID()); 280 } 281 282 // Equivalent non-predicated opcode 283 static unsigned GetFunctionalOpcodeForVP(Intrinsic::ID ID); 284 }; 285 286 /// This is the common base class for constrained floating point intrinsics. 287 class ConstrainedFPIntrinsic : public IntrinsicInst { 288 public: 289 bool isUnaryOp() const; 290 bool isTernaryOp() const; 291 Optional<RoundingMode> getRoundingMode() const; 292 Optional<fp::ExceptionBehavior> getExceptionBehavior() const; 293 294 // Methods for support type inquiry through isa, cast, and dyn_cast: 295 static bool classof(const IntrinsicInst *I); 296 static bool classof(const Value *V) { 297 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 298 } 299 }; 300 301 /// Constrained floating point compare intrinsics. 302 class ConstrainedFPCmpIntrinsic : public ConstrainedFPIntrinsic { 303 public: 304 FCmpInst::Predicate getPredicate() const; 305 306 // Methods for support type inquiry through isa, cast, and dyn_cast: 307 static bool classof(const IntrinsicInst *I) { 308 switch (I->getIntrinsicID()) { 309 case Intrinsic::experimental_constrained_fcmp: 310 case Intrinsic::experimental_constrained_fcmps: 311 return true; 312 default: 313 return false; 314 } 315 } 316 static bool classof(const Value *V) { 317 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 318 } 319 }; 320 321 /// This class represents an intrinsic that is based on a binary operation. 322 /// This includes op.with.overflow and saturating add/sub intrinsics. 323 class BinaryOpIntrinsic : public IntrinsicInst { 324 public: 325 static bool classof(const IntrinsicInst *I) { 326 switch (I->getIntrinsicID()) { 327 case Intrinsic::uadd_with_overflow: 328 case Intrinsic::sadd_with_overflow: 329 case Intrinsic::usub_with_overflow: 330 case Intrinsic::ssub_with_overflow: 331 case Intrinsic::umul_with_overflow: 332 case Intrinsic::smul_with_overflow: 333 case Intrinsic::uadd_sat: 334 case Intrinsic::sadd_sat: 335 case Intrinsic::usub_sat: 336 case Intrinsic::ssub_sat: 337 return true; 338 default: 339 return false; 340 } 341 } 342 static bool classof(const Value *V) { 343 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 344 } 345 346 Value *getLHS() const { return const_cast<Value *>(getArgOperand(0)); } 347 Value *getRHS() const { return const_cast<Value *>(getArgOperand(1)); } 348 349 /// Returns the binary operation underlying the intrinsic. 350 Instruction::BinaryOps getBinaryOp() const; 351 352 /// Whether the intrinsic is signed or unsigned. 353 bool isSigned() const; 354 355 /// Returns one of OBO::NoSignedWrap or OBO::NoUnsignedWrap. 356 unsigned getNoWrapKind() const; 357 }; 358 359 /// Represents an op.with.overflow intrinsic. 360 class WithOverflowInst : public BinaryOpIntrinsic { 361 public: 362 static bool classof(const IntrinsicInst *I) { 363 switch (I->getIntrinsicID()) { 364 case Intrinsic::uadd_with_overflow: 365 case Intrinsic::sadd_with_overflow: 366 case Intrinsic::usub_with_overflow: 367 case Intrinsic::ssub_with_overflow: 368 case Intrinsic::umul_with_overflow: 369 case Intrinsic::smul_with_overflow: 370 return true; 371 default: 372 return false; 373 } 374 } 375 static bool classof(const Value *V) { 376 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 377 } 378 }; 379 380 /// Represents a saturating add/sub intrinsic. 381 class SaturatingInst : public BinaryOpIntrinsic { 382 public: 383 static bool classof(const IntrinsicInst *I) { 384 switch (I->getIntrinsicID()) { 385 case Intrinsic::uadd_sat: 386 case Intrinsic::sadd_sat: 387 case Intrinsic::usub_sat: 388 case Intrinsic::ssub_sat: 389 return true; 390 default: 391 return false; 392 } 393 } 394 static bool classof(const Value *V) { 395 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 396 } 397 }; 398 399 /// Common base class for all memory intrinsics. Simply provides 400 /// common methods. 401 /// Written as CRTP to avoid a common base class amongst the 402 /// three atomicity hierarchies. 403 template <typename Derived> class MemIntrinsicBase : public IntrinsicInst { 404 private: 405 enum { ARG_DEST = 0, ARG_LENGTH = 2 }; 406 407 public: 408 Value *getRawDest() const { 409 return const_cast<Value *>(getArgOperand(ARG_DEST)); 410 } 411 const Use &getRawDestUse() const { return getArgOperandUse(ARG_DEST); } 412 Use &getRawDestUse() { return getArgOperandUse(ARG_DEST); } 413 414 Value *getLength() const { 415 return const_cast<Value *>(getArgOperand(ARG_LENGTH)); 416 } 417 const Use &getLengthUse() const { return getArgOperandUse(ARG_LENGTH); } 418 Use &getLengthUse() { return getArgOperandUse(ARG_LENGTH); } 419 420 /// This is just like getRawDest, but it strips off any cast 421 /// instructions (including addrspacecast) that feed it, giving the 422 /// original input. The returned value is guaranteed to be a pointer. 423 Value *getDest() const { return getRawDest()->stripPointerCasts(); } 424 425 unsigned getDestAddressSpace() const { 426 return cast<PointerType>(getRawDest()->getType())->getAddressSpace(); 427 } 428 429 /// FIXME: Remove this function once transition to Align is over. 430 /// Use getDestAlign() instead. 431 unsigned getDestAlignment() const { 432 if (auto MA = getParamAlign(ARG_DEST)) 433 return MA->value(); 434 return 0; 435 } 436 MaybeAlign getDestAlign() const { return getParamAlign(ARG_DEST); } 437 438 /// Set the specified arguments of the instruction. 439 void setDest(Value *Ptr) { 440 assert(getRawDest()->getType() == Ptr->getType() && 441 "setDest called with pointer of wrong type!"); 442 setArgOperand(ARG_DEST, Ptr); 443 } 444 445 /// FIXME: Remove this function once transition to Align is over. 446 /// Use the version that takes MaybeAlign instead of this one. 447 void setDestAlignment(unsigned Alignment) { 448 setDestAlignment(MaybeAlign(Alignment)); 449 } 450 void setDestAlignment(MaybeAlign Alignment) { 451 removeParamAttr(ARG_DEST, Attribute::Alignment); 452 if (Alignment) 453 addParamAttr(ARG_DEST, 454 Attribute::getWithAlignment(getContext(), *Alignment)); 455 } 456 void setDestAlignment(Align Alignment) { 457 removeParamAttr(ARG_DEST, Attribute::Alignment); 458 addParamAttr(ARG_DEST, 459 Attribute::getWithAlignment(getContext(), Alignment)); 460 } 461 462 void setLength(Value *L) { 463 assert(getLength()->getType() == L->getType() && 464 "setLength called with value of wrong type!"); 465 setArgOperand(ARG_LENGTH, L); 466 } 467 }; 468 469 /// Common base class for all memory transfer intrinsics. Simply provides 470 /// common methods. 471 template <class BaseCL> class MemTransferBase : public BaseCL { 472 private: 473 enum { ARG_SOURCE = 1 }; 474 475 public: 476 /// Return the arguments to the instruction. 477 Value *getRawSource() const { 478 return const_cast<Value *>(BaseCL::getArgOperand(ARG_SOURCE)); 479 } 480 const Use &getRawSourceUse() const { 481 return BaseCL::getArgOperandUse(ARG_SOURCE); 482 } 483 Use &getRawSourceUse() { return BaseCL::getArgOperandUse(ARG_SOURCE); } 484 485 /// This is just like getRawSource, but it strips off any cast 486 /// instructions that feed it, giving the original input. The returned 487 /// value is guaranteed to be a pointer. 488 Value *getSource() const { return getRawSource()->stripPointerCasts(); } 489 490 unsigned getSourceAddressSpace() const { 491 return cast<PointerType>(getRawSource()->getType())->getAddressSpace(); 492 } 493 494 /// FIXME: Remove this function once transition to Align is over. 495 /// Use getSourceAlign() instead. 496 unsigned getSourceAlignment() const { 497 if (auto MA = BaseCL::getParamAlign(ARG_SOURCE)) 498 return MA->value(); 499 return 0; 500 } 501 502 MaybeAlign getSourceAlign() const { 503 return BaseCL::getParamAlign(ARG_SOURCE); 504 } 505 506 void setSource(Value *Ptr) { 507 assert(getRawSource()->getType() == Ptr->getType() && 508 "setSource called with pointer of wrong type!"); 509 BaseCL::setArgOperand(ARG_SOURCE, Ptr); 510 } 511 512 /// FIXME: Remove this function once transition to Align is over. 513 /// Use the version that takes MaybeAlign instead of this one. 514 void setSourceAlignment(unsigned Alignment) { 515 setSourceAlignment(MaybeAlign(Alignment)); 516 } 517 void setSourceAlignment(MaybeAlign Alignment) { 518 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 519 if (Alignment) 520 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 521 BaseCL::getContext(), *Alignment)); 522 } 523 void setSourceAlignment(Align Alignment) { 524 BaseCL::removeParamAttr(ARG_SOURCE, Attribute::Alignment); 525 BaseCL::addParamAttr(ARG_SOURCE, Attribute::getWithAlignment( 526 BaseCL::getContext(), Alignment)); 527 } 528 }; 529 530 /// Common base class for all memset intrinsics. Simply provides 531 /// common methods. 532 template <class BaseCL> class MemSetBase : public BaseCL { 533 private: 534 enum { ARG_VALUE = 1 }; 535 536 public: 537 Value *getValue() const { 538 return const_cast<Value *>(BaseCL::getArgOperand(ARG_VALUE)); 539 } 540 const Use &getValueUse() const { return BaseCL::getArgOperandUse(ARG_VALUE); } 541 Use &getValueUse() { return BaseCL::getArgOperandUse(ARG_VALUE); } 542 543 void setValue(Value *Val) { 544 assert(getValue()->getType() == Val->getType() && 545 "setValue called with value of wrong type!"); 546 BaseCL::setArgOperand(ARG_VALUE, Val); 547 } 548 }; 549 550 // The common base class for the atomic memset/memmove/memcpy intrinsics 551 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 552 class AtomicMemIntrinsic : public MemIntrinsicBase<AtomicMemIntrinsic> { 553 private: 554 enum { ARG_ELEMENTSIZE = 3 }; 555 556 public: 557 Value *getRawElementSizeInBytes() const { 558 return const_cast<Value *>(getArgOperand(ARG_ELEMENTSIZE)); 559 } 560 561 ConstantInt *getElementSizeInBytesCst() const { 562 return cast<ConstantInt>(getRawElementSizeInBytes()); 563 } 564 565 uint32_t getElementSizeInBytes() const { 566 return getElementSizeInBytesCst()->getZExtValue(); 567 } 568 569 void setElementSizeInBytes(Constant *V) { 570 assert(V->getType() == Type::getInt8Ty(getContext()) && 571 "setElementSizeInBytes called with value of wrong type!"); 572 setArgOperand(ARG_ELEMENTSIZE, V); 573 } 574 575 static bool classof(const IntrinsicInst *I) { 576 switch (I->getIntrinsicID()) { 577 case Intrinsic::memcpy_element_unordered_atomic: 578 case Intrinsic::memmove_element_unordered_atomic: 579 case Intrinsic::memset_element_unordered_atomic: 580 return true; 581 default: 582 return false; 583 } 584 } 585 static bool classof(const Value *V) { 586 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 587 } 588 }; 589 590 /// This class represents atomic memset intrinsic 591 // i.e. llvm.element.unordered.atomic.memset 592 class AtomicMemSetInst : public MemSetBase<AtomicMemIntrinsic> { 593 public: 594 static bool classof(const IntrinsicInst *I) { 595 return I->getIntrinsicID() == Intrinsic::memset_element_unordered_atomic; 596 } 597 static bool classof(const Value *V) { 598 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 599 } 600 }; 601 602 // This class wraps the atomic memcpy/memmove intrinsics 603 // i.e. llvm.element.unordered.atomic.memcpy/memmove 604 class AtomicMemTransferInst : public MemTransferBase<AtomicMemIntrinsic> { 605 public: 606 static bool classof(const IntrinsicInst *I) { 607 switch (I->getIntrinsicID()) { 608 case Intrinsic::memcpy_element_unordered_atomic: 609 case Intrinsic::memmove_element_unordered_atomic: 610 return true; 611 default: 612 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 represents the atomic memcpy intrinsic 621 /// i.e. llvm.element.unordered.atomic.memcpy 622 class AtomicMemCpyInst : public AtomicMemTransferInst { 623 public: 624 static bool classof(const IntrinsicInst *I) { 625 return I->getIntrinsicID() == Intrinsic::memcpy_element_unordered_atomic; 626 } 627 static bool classof(const Value *V) { 628 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 629 } 630 }; 631 632 /// This class represents the atomic memmove intrinsic 633 /// i.e. llvm.element.unordered.atomic.memmove 634 class AtomicMemMoveInst : public AtomicMemTransferInst { 635 public: 636 static bool classof(const IntrinsicInst *I) { 637 return I->getIntrinsicID() == Intrinsic::memmove_element_unordered_atomic; 638 } 639 static bool classof(const Value *V) { 640 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 641 } 642 }; 643 644 /// This is the common base class for memset/memcpy/memmove. 645 class MemIntrinsic : public MemIntrinsicBase<MemIntrinsic> { 646 private: 647 enum { ARG_VOLATILE = 3 }; 648 649 public: 650 ConstantInt *getVolatileCst() const { 651 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(ARG_VOLATILE))); 652 } 653 654 bool isVolatile() const { return !getVolatileCst()->isZero(); } 655 656 void setVolatile(Constant *V) { setArgOperand(ARG_VOLATILE, V); } 657 658 // Methods for support type inquiry through isa, cast, and dyn_cast: 659 static bool classof(const IntrinsicInst *I) { 660 switch (I->getIntrinsicID()) { 661 case Intrinsic::memcpy: 662 case Intrinsic::memmove: 663 case Intrinsic::memset: 664 case Intrinsic::memcpy_inline: 665 return true; 666 default: 667 return false; 668 } 669 } 670 static bool classof(const Value *V) { 671 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 672 } 673 }; 674 675 /// This class wraps the llvm.memset intrinsic. 676 class MemSetInst : public MemSetBase<MemIntrinsic> { 677 public: 678 // Methods for support type inquiry through isa, cast, and dyn_cast: 679 static bool classof(const IntrinsicInst *I) { 680 return I->getIntrinsicID() == Intrinsic::memset; 681 } 682 static bool classof(const Value *V) { 683 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 684 } 685 }; 686 687 /// This class wraps the llvm.memcpy/memmove intrinsics. 688 class MemTransferInst : public MemTransferBase<MemIntrinsic> { 689 public: 690 // Methods for support type inquiry through isa, cast, and dyn_cast: 691 static bool classof(const IntrinsicInst *I) { 692 switch (I->getIntrinsicID()) { 693 case Intrinsic::memcpy: 694 case Intrinsic::memmove: 695 case Intrinsic::memcpy_inline: 696 return true; 697 default: 698 return false; 699 } 700 } 701 static bool classof(const Value *V) { 702 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 703 } 704 }; 705 706 /// This class wraps the llvm.memcpy intrinsic. 707 class MemCpyInst : public MemTransferInst { 708 public: 709 // Methods for support type inquiry through isa, cast, and dyn_cast: 710 static bool classof(const IntrinsicInst *I) { 711 return I->getIntrinsicID() == Intrinsic::memcpy; 712 } 713 static bool classof(const Value *V) { 714 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 715 } 716 }; 717 718 /// This class wraps the llvm.memmove intrinsic. 719 class MemMoveInst : public MemTransferInst { 720 public: 721 // Methods for support type inquiry through isa, cast, and dyn_cast: 722 static bool classof(const IntrinsicInst *I) { 723 return I->getIntrinsicID() == Intrinsic::memmove; 724 } 725 static bool classof(const Value *V) { 726 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 727 } 728 }; 729 730 /// This class wraps the llvm.memcpy.inline intrinsic. 731 class MemCpyInlineInst : public MemTransferInst { 732 public: 733 ConstantInt *getLength() const { 734 return cast<ConstantInt>(MemTransferInst::getLength()); 735 } 736 // Methods for support type inquiry through isa, cast, and dyn_cast: 737 static bool classof(const IntrinsicInst *I) { 738 return I->getIntrinsicID() == Intrinsic::memcpy_inline; 739 } 740 static bool classof(const Value *V) { 741 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 742 } 743 }; 744 745 // The common base class for any memset/memmove/memcpy intrinsics; 746 // whether they be atomic or non-atomic. 747 // i.e. llvm.element.unordered.atomic.memset/memcpy/memmove 748 // and llvm.memset/memcpy/memmove 749 class AnyMemIntrinsic : public MemIntrinsicBase<AnyMemIntrinsic> { 750 public: 751 bool isVolatile() const { 752 // Only the non-atomic intrinsics can be volatile 753 if (auto *MI = dyn_cast<MemIntrinsic>(this)) 754 return MI->isVolatile(); 755 return false; 756 } 757 758 static bool classof(const IntrinsicInst *I) { 759 switch (I->getIntrinsicID()) { 760 case Intrinsic::memcpy: 761 case Intrinsic::memcpy_inline: 762 case Intrinsic::memmove: 763 case Intrinsic::memset: 764 case Intrinsic::memcpy_element_unordered_atomic: 765 case Intrinsic::memmove_element_unordered_atomic: 766 case Intrinsic::memset_element_unordered_atomic: 767 return true; 768 default: 769 return false; 770 } 771 } 772 static bool classof(const Value *V) { 773 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 774 } 775 }; 776 777 /// This class represents any memset intrinsic 778 // i.e. llvm.element.unordered.atomic.memset 779 // and llvm.memset 780 class AnyMemSetInst : public MemSetBase<AnyMemIntrinsic> { 781 public: 782 static bool classof(const IntrinsicInst *I) { 783 switch (I->getIntrinsicID()) { 784 case Intrinsic::memset: 785 case Intrinsic::memset_element_unordered_atomic: 786 return true; 787 default: 788 return false; 789 } 790 } 791 static bool classof(const Value *V) { 792 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 793 } 794 }; 795 796 // This class wraps any memcpy/memmove intrinsics 797 // i.e. llvm.element.unordered.atomic.memcpy/memmove 798 // and llvm.memcpy/memmove 799 class AnyMemTransferInst : public MemTransferBase<AnyMemIntrinsic> { 800 public: 801 static bool classof(const IntrinsicInst *I) { 802 switch (I->getIntrinsicID()) { 803 case Intrinsic::memcpy: 804 case Intrinsic::memcpy_inline: 805 case Intrinsic::memmove: 806 case Intrinsic::memcpy_element_unordered_atomic: 807 case Intrinsic::memmove_element_unordered_atomic: 808 return true; 809 default: 810 return false; 811 } 812 } 813 static bool classof(const Value *V) { 814 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 815 } 816 }; 817 818 /// This class represents any memcpy intrinsic 819 /// i.e. llvm.element.unordered.atomic.memcpy 820 /// and llvm.memcpy 821 class AnyMemCpyInst : public AnyMemTransferInst { 822 public: 823 static bool classof(const IntrinsicInst *I) { 824 switch (I->getIntrinsicID()) { 825 case Intrinsic::memcpy: 826 case Intrinsic::memcpy_inline: 827 case Intrinsic::memcpy_element_unordered_atomic: 828 return true; 829 default: 830 return false; 831 } 832 } 833 static bool classof(const Value *V) { 834 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 835 } 836 }; 837 838 /// This class represents any memmove intrinsic 839 /// i.e. llvm.element.unordered.atomic.memmove 840 /// and llvm.memmove 841 class AnyMemMoveInst : public AnyMemTransferInst { 842 public: 843 static bool classof(const IntrinsicInst *I) { 844 switch (I->getIntrinsicID()) { 845 case Intrinsic::memmove: 846 case Intrinsic::memmove_element_unordered_atomic: 847 return true; 848 default: 849 return false; 850 } 851 } 852 static bool classof(const Value *V) { 853 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 854 } 855 }; 856 857 /// This represents the llvm.va_start intrinsic. 858 class VAStartInst : public IntrinsicInst { 859 public: 860 static bool classof(const IntrinsicInst *I) { 861 return I->getIntrinsicID() == Intrinsic::vastart; 862 } 863 static bool classof(const Value *V) { 864 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 865 } 866 867 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 868 }; 869 870 /// This represents the llvm.va_end intrinsic. 871 class VAEndInst : public IntrinsicInst { 872 public: 873 static bool classof(const IntrinsicInst *I) { 874 return I->getIntrinsicID() == Intrinsic::vaend; 875 } 876 static bool classof(const Value *V) { 877 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 878 } 879 880 Value *getArgList() const { return const_cast<Value *>(getArgOperand(0)); } 881 }; 882 883 /// This represents the llvm.va_copy intrinsic. 884 class VACopyInst : public IntrinsicInst { 885 public: 886 static bool classof(const IntrinsicInst *I) { 887 return I->getIntrinsicID() == Intrinsic::vacopy; 888 } 889 static bool classof(const Value *V) { 890 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 891 } 892 893 Value *getDest() const { return const_cast<Value *>(getArgOperand(0)); } 894 Value *getSrc() const { return const_cast<Value *>(getArgOperand(1)); } 895 }; 896 897 /// This represents the llvm.instrprof_increment intrinsic. 898 class InstrProfIncrementInst : public IntrinsicInst { 899 public: 900 static bool classof(const IntrinsicInst *I) { 901 return I->getIntrinsicID() == Intrinsic::instrprof_increment; 902 } 903 static bool classof(const Value *V) { 904 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 905 } 906 907 GlobalVariable *getName() const { 908 return cast<GlobalVariable>( 909 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 910 } 911 912 ConstantInt *getHash() const { 913 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 914 } 915 916 ConstantInt *getNumCounters() const { 917 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 918 } 919 920 ConstantInt *getIndex() const { 921 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 922 } 923 924 Value *getStep() const; 925 }; 926 927 class InstrProfIncrementInstStep : public InstrProfIncrementInst { 928 public: 929 static bool classof(const IntrinsicInst *I) { 930 return I->getIntrinsicID() == Intrinsic::instrprof_increment_step; 931 } 932 static bool classof(const Value *V) { 933 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 934 } 935 }; 936 937 /// This represents the llvm.instrprof_value_profile intrinsic. 938 class InstrProfValueProfileInst : public IntrinsicInst { 939 public: 940 static bool classof(const IntrinsicInst *I) { 941 return I->getIntrinsicID() == Intrinsic::instrprof_value_profile; 942 } 943 static bool classof(const Value *V) { 944 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 945 } 946 947 GlobalVariable *getName() const { 948 return cast<GlobalVariable>( 949 const_cast<Value *>(getArgOperand(0))->stripPointerCasts()); 950 } 951 952 ConstantInt *getHash() const { 953 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 954 } 955 956 Value *getTargetValue() const { 957 return cast<Value>(const_cast<Value *>(getArgOperand(2))); 958 } 959 960 ConstantInt *getValueKind() const { 961 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 962 } 963 964 // Returns the value site index. 965 ConstantInt *getIndex() const { 966 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(4))); 967 } 968 }; 969 970 class PseudoProbeInst : public IntrinsicInst { 971 public: 972 static bool classof(const IntrinsicInst *I) { 973 return I->getIntrinsicID() == Intrinsic::pseudoprobe; 974 } 975 976 static bool classof(const Value *V) { 977 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 978 } 979 980 ConstantInt *getFuncGuid() const { 981 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(0))); 982 } 983 984 ConstantInt *getIndex() const { 985 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(1))); 986 } 987 988 ConstantInt *getAttributes() const { 989 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(2))); 990 } 991 992 ConstantInt *getFactor() const { 993 return cast<ConstantInt>(const_cast<Value *>(getArgOperand(3))); 994 } 995 }; 996 997 class NoAliasScopeDeclInst : public IntrinsicInst { 998 public: 999 static bool classof(const IntrinsicInst *I) { 1000 return I->getIntrinsicID() == Intrinsic::experimental_noalias_scope_decl; 1001 } 1002 1003 static bool classof(const Value *V) { 1004 return isa<IntrinsicInst>(V) && classof(cast<IntrinsicInst>(V)); 1005 } 1006 1007 MDNode *getScopeList() const { 1008 auto *MV = 1009 cast<MetadataAsValue>(getOperand(Intrinsic::NoAliasScopeDeclScopeArg)); 1010 return cast<MDNode>(MV->getMetadata()); 1011 } 1012 1013 void setScopeList(MDNode *ScopeList) { 1014 setOperand(Intrinsic::NoAliasScopeDeclScopeArg, 1015 MetadataAsValue::get(getContext(), ScopeList)); 1016 } 1017 }; 1018 1019 } // end namespace llvm 1020 1021 #endif // LLVM_IR_INTRINSICINST_H 1022