File indexing completed on 2026-05-10 08:44:26
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_SANDBOXIR_INSTRUCTION_H
0010 #define LLVM_SANDBOXIR_INSTRUCTION_H
0011
0012 #include "llvm/IR/IRBuilder.h"
0013 #include "llvm/IR/Instructions.h"
0014 #include "llvm/IR/Module.h"
0015 #include "llvm/IR/PatternMatch.h"
0016 #include "llvm/SandboxIR/BasicBlock.h"
0017 #include "llvm/SandboxIR/Constant.h"
0018 #include "llvm/SandboxIR/User.h"
0019
0020 namespace llvm::sandboxir {
0021
0022
0023 class IntrinsicInst;
0024
0025 class InsertPosition {
0026 BBIterator InsertAt;
0027
0028 public:
0029 InsertPosition(BasicBlock *InsertAtEnd) {
0030 assert(InsertAtEnd != nullptr && "Expected non-null!");
0031 InsertAt = InsertAtEnd->end();
0032 }
0033 InsertPosition(BBIterator InsertAt) : InsertAt(InsertAt) {}
0034 operator BBIterator() { return InsertAt; }
0035 const BBIterator &getIterator() const { return InsertAt; }
0036 Instruction &operator*() { return *InsertAt; }
0037 BasicBlock *getBasicBlock() const { return InsertAt.getNodeParent(); }
0038 };
0039
0040
0041
0042 class Instruction : public User {
0043 public:
0044 enum class Opcode {
0045 #define OP(OPC) OPC,
0046 #define OPCODES(...) __VA_ARGS__
0047 #define DEF_INSTR(ID, OPC, CLASS) OPC
0048 #include "llvm/SandboxIR/Values.def"
0049 };
0050
0051 protected:
0052 Instruction(ClassID ID, Opcode Opc, llvm::Instruction *I,
0053 sandboxir::Context &SBCtx)
0054 : User(ID, I, SBCtx), Opc(Opc) {}
0055
0056 Opcode Opc;
0057
0058
0059
0060 llvm::Instruction *getTopmostLLVMInstruction() const;
0061 friend class VAArgInst;
0062 friend class FreezeInst;
0063 friend class FenceInst;
0064 friend class SelectInst;
0065 friend class ExtractElementInst;
0066 friend class InsertElementInst;
0067 friend class ShuffleVectorInst;
0068 friend class ExtractValueInst;
0069 friend class InsertValueInst;
0070 friend class BranchInst;
0071 friend class LoadInst;
0072 friend class StoreInst;
0073 friend class ReturnInst;
0074 friend class CallInst;
0075 friend class InvokeInst;
0076 friend class CallBrInst;
0077 friend class LandingPadInst;
0078 friend class CatchPadInst;
0079 friend class CleanupPadInst;
0080 friend class CatchReturnInst;
0081 friend class CleanupReturnInst;
0082 friend class GetElementPtrInst;
0083 friend class ResumeInst;
0084 friend class CatchSwitchInst;
0085 friend class SwitchInst;
0086 friend class UnaryOperator;
0087 friend class BinaryOperator;
0088 friend class AtomicRMWInst;
0089 friend class AtomicCmpXchgInst;
0090 friend class AllocaInst;
0091 friend class CastInst;
0092 friend class PHINode;
0093 friend class UnreachableInst;
0094 friend class CmpInst;
0095
0096
0097
0098 virtual SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const = 0;
0099 friend class EraseFromParent;
0100
0101
0102
0103 static IRBuilder<> &setInsertPos(InsertPosition Pos) {
0104 auto *WhereBB = Pos.getBasicBlock();
0105 auto WhereIt = Pos.getIterator();
0106 auto &Ctx = WhereBB->getContext();
0107 auto &Builder = Ctx.getLLVMIRBuilder();
0108 if (WhereIt != WhereBB->end())
0109 Builder.SetInsertPoint((*Pos).getTopmostLLVMInstruction());
0110 else
0111 Builder.SetInsertPoint(cast<llvm::BasicBlock>(WhereBB->Val));
0112 return Builder;
0113 }
0114
0115 public:
0116 static const char *getOpcodeName(Opcode Opc);
0117
0118 virtual unsigned getNumOfIRInstrs() const = 0;
0119
0120 BBIterator getIterator() const;
0121
0122
0123 Instruction *getNextNode() const;
0124
0125
0126 Instruction *getPrevNode() const;
0127
0128
0129 Opcode getOpcode() const { return Opc; }
0130
0131 const char *getOpcodeName() const { return getOpcodeName(Opc); }
0132
0133 const DataLayout &getDataLayout() const {
0134 return cast<llvm::Instruction>(Val)->getModule()->getDataLayout();
0135 }
0136
0137
0138
0139
0140
0141
0142 bool isTerminator() const {
0143 return cast<llvm::Instruction>(Val)->isTerminator();
0144 }
0145 bool isUnaryOp() const { return cast<llvm::Instruction>(Val)->isUnaryOp(); }
0146 bool isBinaryOp() const { return cast<llvm::Instruction>(Val)->isBinaryOp(); }
0147 bool isIntDivRem() const {
0148 return cast<llvm::Instruction>(Val)->isIntDivRem();
0149 }
0150 bool isShift() const { return cast<llvm::Instruction>(Val)->isShift(); }
0151 bool isCast() const { return cast<llvm::Instruction>(Val)->isCast(); }
0152 bool isFuncletPad() const {
0153 return cast<llvm::Instruction>(Val)->isFuncletPad();
0154 }
0155 bool isSpecialTerminator() const {
0156 return cast<llvm::Instruction>(Val)->isSpecialTerminator();
0157 }
0158 bool isOnlyUserOfAnyOperand() const {
0159 return cast<llvm::Instruction>(Val)->isOnlyUserOfAnyOperand();
0160 }
0161 bool isLogicalShift() const {
0162 return cast<llvm::Instruction>(Val)->isLogicalShift();
0163 }
0164
0165
0166
0167
0168
0169
0170 bool hasMetadata() const {
0171 return cast<llvm::Instruction>(Val)->hasMetadata();
0172 }
0173
0174
0175
0176 bool hasMetadataOtherThanDebugLoc() const {
0177 return cast<llvm::Instruction>(Val)->hasMetadataOtherThanDebugLoc();
0178 }
0179
0180
0181 bool hasMetadata(unsigned KindID) const {
0182 return cast<llvm::Instruction>(Val)->hasMetadata(KindID);
0183 }
0184
0185
0186
0187
0188
0189
0190
0191 void removeFromParent();
0192
0193 void eraseFromParent();
0194
0195 void insertBefore(Instruction *BeforeI);
0196
0197 void insertAfter(Instruction *AfterI);
0198
0199 void insertInto(BasicBlock *BB, const BBIterator &WhereIt);
0200
0201 void moveBefore(BasicBlock &BB, const BBIterator &WhereIt);
0202
0203 void moveBefore(Instruction *Before) {
0204 moveBefore(*Before->getParent(), Before->getIterator());
0205 }
0206
0207 void moveAfter(Instruction *After) {
0208 moveBefore(*After->getParent(), std::next(After->getIterator()));
0209 }
0210
0211
0212
0213
0214 bool comesBefore(const Instruction *Other) const {
0215 return cast<llvm::Instruction>(Val)->comesBefore(
0216 cast<llvm::Instruction>(Other->Val));
0217 }
0218
0219
0220 BasicBlock *getParent() const;
0221
0222 static bool classof(const sandboxir::Value *From);
0223
0224
0225 bool hasNoUnsignedWrap() const {
0226 return cast<llvm::Instruction>(Val)->hasNoUnsignedWrap();
0227 }
0228
0229
0230 void setHasNoUnsignedWrap(bool B = true);
0231
0232 bool hasNoSignedWrap() const {
0233 return cast<llvm::Instruction>(Val)->hasNoSignedWrap();
0234 }
0235
0236
0237 void setHasNoSignedWrap(bool B = true);
0238
0239 bool isFast() const { return cast<llvm::Instruction>(Val)->isFast(); }
0240
0241
0242
0243 void setFast(bool B);
0244
0245 bool hasAllowReassoc() const {
0246 return cast<llvm::Instruction>(Val)->hasAllowReassoc();
0247 }
0248
0249
0250
0251 void setHasAllowReassoc(bool B);
0252
0253 bool isExact() const { return cast<llvm::Instruction>(Val)->isExact(); }
0254
0255
0256 void setIsExact(bool B = true);
0257
0258 bool hasNoNaNs() const { return cast<llvm::Instruction>(Val)->hasNoNaNs(); }
0259
0260
0261
0262 void setHasNoNaNs(bool B);
0263
0264 bool hasNoInfs() const { return cast<llvm::Instruction>(Val)->hasNoInfs(); }
0265
0266
0267
0268 void setHasNoInfs(bool B);
0269
0270 bool hasNoSignedZeros() const {
0271 return cast<llvm::Instruction>(Val)->hasNoSignedZeros();
0272 }
0273
0274
0275
0276 void setHasNoSignedZeros(bool B);
0277
0278 bool hasAllowReciprocal() const {
0279 return cast<llvm::Instruction>(Val)->hasAllowReciprocal();
0280 }
0281
0282
0283
0284 void setHasAllowReciprocal(bool B);
0285
0286 bool hasAllowContract() const {
0287 return cast<llvm::Instruction>(Val)->hasAllowContract();
0288 }
0289
0290
0291
0292 void setHasAllowContract(bool B);
0293
0294 bool hasApproxFunc() const {
0295 return cast<llvm::Instruction>(Val)->hasApproxFunc();
0296 }
0297
0298
0299
0300 void setHasApproxFunc(bool B);
0301
0302
0303
0304 FastMathFlags getFastMathFlags() const {
0305 return cast<llvm::Instruction>(Val)->getFastMathFlags();
0306 }
0307
0308
0309
0310 void setFastMathFlags(FastMathFlags FMF);
0311
0312
0313
0314 void copyFastMathFlags(FastMathFlags FMF);
0315
0316 bool isAssociative() const {
0317 return cast<llvm::Instruction>(Val)->isAssociative();
0318 }
0319
0320 bool isCommutative() const {
0321 return cast<llvm::Instruction>(Val)->isCommutative();
0322 }
0323
0324 bool isIdempotent() const {
0325 return cast<llvm::Instruction>(Val)->isIdempotent();
0326 }
0327
0328 bool isNilpotent() const {
0329 return cast<llvm::Instruction>(Val)->isNilpotent();
0330 }
0331
0332 bool mayWriteToMemory() const {
0333 return cast<llvm::Instruction>(Val)->mayWriteToMemory();
0334 }
0335
0336 bool mayReadFromMemory() const {
0337 return cast<llvm::Instruction>(Val)->mayReadFromMemory();
0338 }
0339 bool mayReadOrWriteMemory() const {
0340 return cast<llvm::Instruction>(Val)->mayReadOrWriteMemory();
0341 }
0342
0343 bool isAtomic() const { return cast<llvm::Instruction>(Val)->isAtomic(); }
0344
0345 bool hasAtomicLoad() const {
0346 return cast<llvm::Instruction>(Val)->hasAtomicLoad();
0347 }
0348
0349 bool hasAtomicStore() const {
0350 return cast<llvm::Instruction>(Val)->hasAtomicStore();
0351 }
0352
0353 bool isVolatile() const { return cast<llvm::Instruction>(Val)->isVolatile(); }
0354
0355 Type *getAccessType() const;
0356
0357 bool mayThrow(bool IncludePhaseOneUnwind = false) const {
0358 return cast<llvm::Instruction>(Val)->mayThrow(IncludePhaseOneUnwind);
0359 }
0360
0361 bool isFenceLike() const {
0362 return cast<llvm::Instruction>(Val)->isFenceLike();
0363 }
0364
0365 bool mayHaveSideEffects() const {
0366 return cast<llvm::Instruction>(Val)->mayHaveSideEffects();
0367 }
0368
0369
0370
0371 #ifndef NDEBUG
0372 void dumpOS(raw_ostream &OS) const override;
0373 #endif
0374 };
0375
0376
0377 template <typename LLVMT> class SingleLLVMInstructionImpl : public Instruction {
0378 SingleLLVMInstructionImpl(ClassID ID, Opcode Opc, llvm::Instruction *I,
0379 sandboxir::Context &SBCtx)
0380 : Instruction(ID, Opc, I, SBCtx) {}
0381
0382
0383 #define DEF_INSTR(ID, OPC, CLASS) friend class CLASS;
0384 #include "llvm/SandboxIR/Values.def"
0385 friend class UnaryInstruction;
0386 friend class CallBase;
0387 friend class FuncletPadInst;
0388 friend class CmpInst;
0389
0390 Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
0391 return getOperandUseDefault(OpIdx, Verify);
0392 }
0393 SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
0394 return {cast<llvm::Instruction>(Val)};
0395 }
0396
0397 public:
0398 unsigned getUseOperandNo(const Use &Use) const final {
0399 return getUseOperandNoDefault(Use);
0400 }
0401 unsigned getNumOfIRInstrs() const final { return 1u; }
0402 #ifndef NDEBUG
0403 void verify() const final { assert(isa<LLVMT>(Val) && "Expected LLVMT!"); }
0404 void dumpOS(raw_ostream &OS) const override {
0405 dumpCommonPrefix(OS);
0406 dumpCommonSuffix(OS);
0407 }
0408 #endif
0409 };
0410
0411 class FenceInst : public SingleLLVMInstructionImpl<llvm::FenceInst> {
0412 FenceInst(llvm::FenceInst *FI, Context &Ctx)
0413 : SingleLLVMInstructionImpl(ClassID::Fence, Opcode::Fence, FI, Ctx) {}
0414 friend Context;
0415
0416 public:
0417 static FenceInst *create(AtomicOrdering Ordering, InsertPosition Pos,
0418 Context &Ctx,
0419 SyncScope::ID SSID = SyncScope::System);
0420
0421 AtomicOrdering getOrdering() const {
0422 return cast<llvm::FenceInst>(Val)->getOrdering();
0423 }
0424
0425
0426 void setOrdering(AtomicOrdering Ordering);
0427
0428 SyncScope::ID getSyncScopeID() const {
0429 return cast<llvm::FenceInst>(Val)->getSyncScopeID();
0430 }
0431
0432 void setSyncScopeID(SyncScope::ID SSID);
0433 static bool classof(const Value *From) {
0434 return From->getSubclassID() == ClassID::Fence;
0435 }
0436 };
0437
0438 class SelectInst : public SingleLLVMInstructionImpl<llvm::SelectInst> {
0439
0440
0441 SelectInst(llvm::SelectInst *CI, Context &Ctx)
0442 : SingleLLVMInstructionImpl(ClassID::Select, Opcode::Select, CI, Ctx) {}
0443 friend Context;
0444
0445 public:
0446 static Value *create(Value *Cond, Value *True, Value *False,
0447 InsertPosition Pos, Context &Ctx,
0448 const Twine &Name = "");
0449
0450 const Value *getCondition() const { return getOperand(0); }
0451 const Value *getTrueValue() const { return getOperand(1); }
0452 const Value *getFalseValue() const { return getOperand(2); }
0453 Value *getCondition() { return getOperand(0); }
0454 Value *getTrueValue() { return getOperand(1); }
0455 Value *getFalseValue() { return getOperand(2); }
0456
0457 void setCondition(Value *New) { setOperand(0, New); }
0458 void setTrueValue(Value *New) { setOperand(1, New); }
0459 void setFalseValue(Value *New) { setOperand(2, New); }
0460 void swapValues();
0461
0462
0463
0464 static const char *areInvalidOperands(Value *Cond, Value *True,
0465 Value *False) {
0466 return llvm::SelectInst::areInvalidOperands(Cond->Val, True->Val,
0467 False->Val);
0468 }
0469
0470
0471 static bool classof(const Value *From);
0472 };
0473
0474 class InsertElementInst final
0475 : public SingleLLVMInstructionImpl<llvm::InsertElementInst> {
0476
0477 InsertElementInst(llvm::Instruction *I, Context &Ctx)
0478 : SingleLLVMInstructionImpl(ClassID::InsertElement, Opcode::InsertElement,
0479 I, Ctx) {}
0480 friend class Context;
0481
0482 public:
0483 static Value *create(Value *Vec, Value *NewElt, Value *Idx,
0484 InsertPosition Pos, Context &Ctx,
0485 const Twine &Name = "");
0486 static bool classof(const Value *From) {
0487 return From->getSubclassID() == ClassID::InsertElement;
0488 }
0489 static bool isValidOperands(const Value *Vec, const Value *NewElt,
0490 const Value *Idx) {
0491 return llvm::InsertElementInst::isValidOperands(Vec->Val, NewElt->Val,
0492 Idx->Val);
0493 }
0494 };
0495
0496 class ExtractElementInst final
0497 : public SingleLLVMInstructionImpl<llvm::ExtractElementInst> {
0498
0499 ExtractElementInst(llvm::Instruction *I, Context &Ctx)
0500 : SingleLLVMInstructionImpl(ClassID::ExtractElement,
0501 Opcode::ExtractElement, I, Ctx) {}
0502 friend class Context;
0503
0504
0505 public:
0506 static Value *create(Value *Vec, Value *Idx, InsertPosition Pos, Context &Ctx,
0507 const Twine &Name = "");
0508 static bool classof(const Value *From) {
0509 return From->getSubclassID() == ClassID::ExtractElement;
0510 }
0511
0512 static bool isValidOperands(const Value *Vec, const Value *Idx) {
0513 return llvm::ExtractElementInst::isValidOperands(Vec->Val, Idx->Val);
0514 }
0515 Value *getVectorOperand() { return getOperand(0); }
0516 Value *getIndexOperand() { return getOperand(1); }
0517 const Value *getVectorOperand() const { return getOperand(0); }
0518 const Value *getIndexOperand() const { return getOperand(1); }
0519 VectorType *getVectorOperandType() const;
0520 };
0521
0522 class ShuffleVectorInst final
0523 : public SingleLLVMInstructionImpl<llvm::ShuffleVectorInst> {
0524
0525 ShuffleVectorInst(llvm::Instruction *I, Context &Ctx)
0526 : SingleLLVMInstructionImpl(ClassID::ShuffleVector, Opcode::ShuffleVector,
0527 I, Ctx) {}
0528 friend class Context;
0529
0530 public:
0531 static Value *create(Value *V1, Value *V2, Value *Mask, InsertPosition Pos,
0532 Context &Ctx, const Twine &Name = "");
0533 static Value *create(Value *V1, Value *V2, ArrayRef<int> Mask,
0534 InsertPosition Pos, Context &Ctx,
0535 const Twine &Name = "");
0536 static bool classof(const Value *From) {
0537 return From->getSubclassID() == ClassID::ShuffleVector;
0538 }
0539
0540
0541
0542 void commute();
0543
0544
0545
0546 static bool isValidOperands(const Value *V1, const Value *V2,
0547 const Value *Mask) {
0548 return llvm::ShuffleVectorInst::isValidOperands(V1->Val, V2->Val,
0549 Mask->Val);
0550 }
0551 static bool isValidOperands(const Value *V1, const Value *V2,
0552 ArrayRef<int> Mask) {
0553 return llvm::ShuffleVectorInst::isValidOperands(V1->Val, V2->Val, Mask);
0554 }
0555
0556
0557 VectorType *getType() const;
0558
0559
0560
0561 int getMaskValue(unsigned Elt) const {
0562 return cast<llvm::ShuffleVectorInst>(Val)->getMaskValue(Elt);
0563 }
0564
0565
0566
0567 static void getShuffleMask(const Constant *Mask,
0568 SmallVectorImpl<int> &Result) {
0569 llvm::ShuffleVectorInst::getShuffleMask(cast<llvm::Constant>(Mask->Val),
0570 Result);
0571 }
0572
0573
0574
0575 void getShuffleMask(SmallVectorImpl<int> &Result) const {
0576 cast<llvm::ShuffleVectorInst>(Val)->getShuffleMask(Result);
0577 }
0578
0579
0580 Constant *getShuffleMaskForBitcode() const;
0581
0582 static Constant *convertShuffleMaskForBitcode(ArrayRef<int> Mask,
0583 Type *ResultTy);
0584
0585 void setShuffleMask(ArrayRef<int> Mask);
0586
0587 ArrayRef<int> getShuffleMask() const {
0588 return cast<llvm::ShuffleVectorInst>(Val)->getShuffleMask();
0589 }
0590
0591
0592
0593
0594
0595 bool changesLength() const {
0596 return cast<llvm::ShuffleVectorInst>(Val)->changesLength();
0597 }
0598
0599
0600
0601
0602 bool increasesLength() const {
0603 return cast<llvm::ShuffleVectorInst>(Val)->increasesLength();
0604 }
0605
0606
0607
0608
0609
0610
0611 static bool isSingleSourceMask(ArrayRef<int> Mask, int NumSrcElts) {
0612 return llvm::ShuffleVectorInst::isSingleSourceMask(Mask, NumSrcElts);
0613 }
0614 static bool isSingleSourceMask(const Constant *Mask, int NumSrcElts) {
0615 return llvm::ShuffleVectorInst::isSingleSourceMask(
0616 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0617 }
0618
0619
0620
0621
0622 bool isSingleSource() const {
0623 return cast<llvm::ShuffleVectorInst>(Val)->isSingleSource();
0624 }
0625
0626
0627
0628
0629
0630
0631 static bool isIdentityMask(ArrayRef<int> Mask, int NumSrcElts) {
0632 return llvm::ShuffleVectorInst::isIdentityMask(Mask, NumSrcElts);
0633 }
0634 static bool isIdentityMask(const Constant *Mask, int NumSrcElts) {
0635 return llvm::ShuffleVectorInst::isIdentityMask(
0636 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0637 }
0638
0639
0640
0641
0642
0643 bool isIdentity() const {
0644 return cast<llvm::ShuffleVectorInst>(Val)->isIdentity();
0645 }
0646
0647
0648
0649 bool isIdentityWithPadding() const {
0650 return cast<llvm::ShuffleVectorInst>(Val)->isIdentityWithPadding();
0651 }
0652
0653
0654
0655 bool isIdentityWithExtract() const {
0656 return cast<llvm::ShuffleVectorInst>(Val)->isIdentityWithExtract();
0657 }
0658
0659
0660
0661
0662 bool isConcat() const {
0663 return cast<llvm::ShuffleVectorInst>(Val)->isConcat();
0664 }
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674 static bool isSelectMask(ArrayRef<int> Mask, int NumSrcElts) {
0675 return llvm::ShuffleVectorInst::isSelectMask(Mask, NumSrcElts);
0676 }
0677 static bool isSelectMask(const Constant *Mask, int NumSrcElts) {
0678 return llvm::ShuffleVectorInst::isSelectMask(
0679 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0680 }
0681
0682
0683
0684
0685
0686
0687
0688
0689 bool isSelect() const {
0690 return cast<llvm::ShuffleVectorInst>(Val)->isSelect();
0691 }
0692
0693
0694
0695
0696
0697
0698 static bool isReverseMask(ArrayRef<int> Mask, int NumSrcElts) {
0699 return llvm::ShuffleVectorInst::isReverseMask(Mask, NumSrcElts);
0700 }
0701 static bool isReverseMask(const Constant *Mask, int NumSrcElts) {
0702 return llvm::ShuffleVectorInst::isReverseMask(
0703 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0704 }
0705
0706
0707
0708
0709 bool isReverse() const {
0710 return cast<llvm::ShuffleVectorInst>(Val)->isReverse();
0711 }
0712
0713
0714
0715
0716
0717
0718 static bool isZeroEltSplatMask(ArrayRef<int> Mask, int NumSrcElts) {
0719 return llvm::ShuffleVectorInst::isZeroEltSplatMask(Mask, NumSrcElts);
0720 }
0721 static bool isZeroEltSplatMask(const Constant *Mask, int NumSrcElts) {
0722 return llvm::ShuffleVectorInst::isZeroEltSplatMask(
0723 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0724 }
0725
0726
0727
0728
0729
0730 bool isZeroEltSplat() const {
0731 return cast<llvm::ShuffleVectorInst>(Val)->isZeroEltSplat();
0732 }
0733
0734
0735
0736
0737
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766 static bool isTransposeMask(ArrayRef<int> Mask, int NumSrcElts) {
0767 return llvm::ShuffleVectorInst::isTransposeMask(Mask, NumSrcElts);
0768 }
0769 static bool isTransposeMask(const Constant *Mask, int NumSrcElts) {
0770 return llvm::ShuffleVectorInst::isTransposeMask(
0771 cast<llvm::Constant>(Mask->Val), NumSrcElts);
0772 }
0773
0774
0775
0776
0777
0778
0779 bool isTranspose() const {
0780 return cast<llvm::ShuffleVectorInst>(Val)->isTranspose();
0781 }
0782
0783
0784
0785
0786
0787
0788
0789 static bool isSpliceMask(ArrayRef<int> Mask, int NumSrcElts, int &Index) {
0790 return llvm::ShuffleVectorInst::isSpliceMask(Mask, NumSrcElts, Index);
0791 }
0792 static bool isSpliceMask(const Constant *Mask, int NumSrcElts, int &Index) {
0793 return llvm::ShuffleVectorInst::isSpliceMask(
0794 cast<llvm::Constant>(Mask->Val), NumSrcElts, Index);
0795 }
0796
0797
0798
0799
0800
0801 bool isSplice(int &Index) const {
0802 return cast<llvm::ShuffleVectorInst>(Val)->isSplice(Index);
0803 }
0804
0805
0806
0807
0808 static bool isExtractSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
0809 int &Index) {
0810 return llvm::ShuffleVectorInst::isExtractSubvectorMask(Mask, NumSrcElts,
0811 Index);
0812 }
0813 static bool isExtractSubvectorMask(const Constant *Mask, int NumSrcElts,
0814 int &Index) {
0815 return llvm::ShuffleVectorInst::isExtractSubvectorMask(
0816 cast<llvm::Constant>(Mask->Val), NumSrcElts, Index);
0817 }
0818
0819
0820 bool isExtractSubvectorMask(int &Index) const {
0821 return cast<llvm::ShuffleVectorInst>(Val)->isExtractSubvectorMask(Index);
0822 }
0823
0824
0825
0826
0827
0828 static bool isInsertSubvectorMask(ArrayRef<int> Mask, int NumSrcElts,
0829 int &NumSubElts, int &Index) {
0830 return llvm::ShuffleVectorInst::isInsertSubvectorMask(Mask, NumSrcElts,
0831 NumSubElts, Index);
0832 }
0833 static bool isInsertSubvectorMask(const Constant *Mask, int NumSrcElts,
0834 int &NumSubElts, int &Index) {
0835 return llvm::ShuffleVectorInst::isInsertSubvectorMask(
0836 cast<llvm::Constant>(Mask->Val), NumSrcElts, NumSubElts, Index);
0837 }
0838
0839
0840 bool isInsertSubvectorMask(int &NumSubElts, int &Index) const {
0841 return cast<llvm::ShuffleVectorInst>(Val)->isInsertSubvectorMask(NumSubElts,
0842 Index);
0843 }
0844
0845
0846
0847
0848
0849 static bool isReplicationMask(ArrayRef<int> Mask, int &ReplicationFactor,
0850 int &VF) {
0851 return llvm::ShuffleVectorInst::isReplicationMask(Mask, ReplicationFactor,
0852 VF);
0853 }
0854 static bool isReplicationMask(const Constant *Mask, int &ReplicationFactor,
0855 int &VF) {
0856 return llvm::ShuffleVectorInst::isReplicationMask(
0857 cast<llvm::Constant>(Mask->Val), ReplicationFactor, VF);
0858 }
0859
0860
0861 bool isReplicationMask(int &ReplicationFactor, int &VF) const {
0862 return cast<llvm::ShuffleVectorInst>(Val)->isReplicationMask(
0863 ReplicationFactor, VF);
0864 }
0865
0866
0867
0868
0869
0870
0871
0872
0873
0874
0875 static bool isOneUseSingleSourceMask(ArrayRef<int> Mask, int VF) {
0876 return llvm::ShuffleVectorInst::isOneUseSingleSourceMask(Mask, VF);
0877 }
0878
0879
0880
0881 bool isOneUseSingleSourceMask(int VF) const {
0882 return cast<llvm::ShuffleVectorInst>(Val)->isOneUseSingleSourceMask(VF);
0883 }
0884
0885
0886
0887 static void commuteShuffleMask(MutableArrayRef<int> Mask,
0888 unsigned InVecNumElts) {
0889 llvm::ShuffleVectorInst::commuteShuffleMask(Mask, InVecNumElts);
0890 }
0891
0892
0893 bool isInterleave(unsigned Factor) const {
0894 return cast<llvm::ShuffleVectorInst>(Val)->isInterleave(Factor);
0895 }
0896
0897
0898
0899
0900
0901
0902
0903
0904
0905
0906
0907
0908
0909
0910
0911
0912
0913
0914
0915
0916 static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
0917 unsigned NumInputElts,
0918 SmallVectorImpl<unsigned> &StartIndexes) {
0919 return llvm::ShuffleVectorInst::isInterleaveMask(Mask, Factor, NumInputElts,
0920 StartIndexes);
0921 }
0922 static bool isInterleaveMask(ArrayRef<int> Mask, unsigned Factor,
0923 unsigned NumInputElts) {
0924 return llvm::ShuffleVectorInst::isInterleaveMask(Mask, Factor,
0925 NumInputElts);
0926 }
0927
0928
0929
0930
0931 static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor,
0932 unsigned &Index) {
0933 return llvm::ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor,
0934 Index);
0935 }
0936 static bool isDeInterleaveMaskOfFactor(ArrayRef<int> Mask, unsigned Factor) {
0937 return llvm::ShuffleVectorInst::isDeInterleaveMaskOfFactor(Mask, Factor);
0938 }
0939
0940
0941
0942
0943
0944
0945
0946
0947
0948
0949
0950
0951 static bool isBitRotateMask(ArrayRef<int> Mask, unsigned EltSizeInBits,
0952 unsigned MinSubElts, unsigned MaxSubElts,
0953 unsigned &NumSubElts, unsigned &RotateAmt) {
0954 return llvm::ShuffleVectorInst::isBitRotateMask(
0955 Mask, EltSizeInBits, MinSubElts, MaxSubElts, NumSubElts, RotateAmt);
0956 }
0957 };
0958
0959 class InsertValueInst
0960 : public SingleLLVMInstructionImpl<llvm::InsertValueInst> {
0961
0962 InsertValueInst(llvm::InsertValueInst *IVI, Context &Ctx)
0963 : SingleLLVMInstructionImpl(ClassID::InsertValue, Opcode::InsertValue,
0964 IVI, Ctx) {}
0965 friend Context;
0966
0967 public:
0968 static Value *create(Value *Agg, Value *Val, ArrayRef<unsigned> Idxs,
0969 InsertPosition Pos, Context &Ctx,
0970 const Twine &Name = "");
0971
0972 static bool classof(const Value *From) {
0973 return From->getSubclassID() == ClassID::InsertValue;
0974 }
0975
0976 using idx_iterator = llvm::InsertValueInst::idx_iterator;
0977 inline idx_iterator idx_begin() const {
0978 return cast<llvm::InsertValueInst>(Val)->idx_begin();
0979 }
0980 inline idx_iterator idx_end() const {
0981 return cast<llvm::InsertValueInst>(Val)->idx_end();
0982 }
0983 inline iterator_range<idx_iterator> indices() const {
0984 return cast<llvm::InsertValueInst>(Val)->indices();
0985 }
0986
0987 Value *getAggregateOperand() {
0988 return getOperand(getAggregateOperandIndex());
0989 }
0990 const Value *getAggregateOperand() const {
0991 return getOperand(getAggregateOperandIndex());
0992 }
0993 static unsigned getAggregateOperandIndex() {
0994 return llvm::InsertValueInst::getAggregateOperandIndex();
0995 }
0996
0997 Value *getInsertedValueOperand() {
0998 return getOperand(getInsertedValueOperandIndex());
0999 }
1000 const Value *getInsertedValueOperand() const {
1001 return getOperand(getInsertedValueOperandIndex());
1002 }
1003 static unsigned getInsertedValueOperandIndex() {
1004 return llvm::InsertValueInst::getInsertedValueOperandIndex();
1005 }
1006
1007 ArrayRef<unsigned> getIndices() const {
1008 return cast<llvm::InsertValueInst>(Val)->getIndices();
1009 }
1010
1011 unsigned getNumIndices() const {
1012 return cast<llvm::InsertValueInst>(Val)->getNumIndices();
1013 }
1014
1015 unsigned hasIndices() const {
1016 return cast<llvm::InsertValueInst>(Val)->hasIndices();
1017 }
1018 };
1019
1020 class BranchInst : public SingleLLVMInstructionImpl<llvm::BranchInst> {
1021
1022 BranchInst(llvm::BranchInst *BI, Context &Ctx)
1023 : SingleLLVMInstructionImpl(ClassID::Br, Opcode::Br, BI, Ctx) {}
1024 friend Context;
1025
1026 public:
1027 static BranchInst *create(BasicBlock *IfTrue, InsertPosition Pos,
1028 Context &Ctx);
1029 static BranchInst *create(BasicBlock *IfTrue, BasicBlock *IfFalse,
1030 Value *Cond, InsertPosition Pos, Context &Ctx);
1031
1032 static bool classof(const Value *From);
1033 bool isUnconditional() const {
1034 return cast<llvm::BranchInst>(Val)->isUnconditional();
1035 }
1036 bool isConditional() const {
1037 return cast<llvm::BranchInst>(Val)->isConditional();
1038 }
1039 Value *getCondition() const;
1040 void setCondition(Value *V) { setOperand(0, V); }
1041 unsigned getNumSuccessors() const { return 1 + isConditional(); }
1042 BasicBlock *getSuccessor(unsigned SuccIdx) const;
1043 void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
1044 void swapSuccessors() { swapOperandsInternal(1, 2); }
1045
1046 private:
1047 struct LLVMBBToSBBB {
1048 Context &Ctx;
1049 LLVMBBToSBBB(Context &Ctx) : Ctx(Ctx) {}
1050 BasicBlock *operator()(llvm::BasicBlock *BB) const;
1051 };
1052
1053 struct ConstLLVMBBToSBBB {
1054 Context &Ctx;
1055 ConstLLVMBBToSBBB(Context &Ctx) : Ctx(Ctx) {}
1056 const BasicBlock *operator()(const llvm::BasicBlock *BB) const;
1057 };
1058
1059 public:
1060 using sb_succ_op_iterator =
1061 mapped_iterator<llvm::BranchInst::succ_op_iterator, LLVMBBToSBBB>;
1062 iterator_range<sb_succ_op_iterator> successors() {
1063 iterator_range<llvm::BranchInst::succ_op_iterator> LLVMRange =
1064 cast<llvm::BranchInst>(Val)->successors();
1065 LLVMBBToSBBB BBMap(Ctx);
1066 sb_succ_op_iterator MappedBegin = map_iterator(LLVMRange.begin(), BBMap);
1067 sb_succ_op_iterator MappedEnd = map_iterator(LLVMRange.end(), BBMap);
1068 return make_range(MappedBegin, MappedEnd);
1069 }
1070
1071 using const_sb_succ_op_iterator =
1072 mapped_iterator<llvm::BranchInst::const_succ_op_iterator,
1073 ConstLLVMBBToSBBB>;
1074 iterator_range<const_sb_succ_op_iterator> successors() const {
1075 iterator_range<llvm::BranchInst::const_succ_op_iterator> ConstLLVMRange =
1076 static_cast<const llvm::BranchInst *>(cast<llvm::BranchInst>(Val))
1077 ->successors();
1078 ConstLLVMBBToSBBB ConstBBMap(Ctx);
1079 const_sb_succ_op_iterator ConstMappedBegin =
1080 map_iterator(ConstLLVMRange.begin(), ConstBBMap);
1081 const_sb_succ_op_iterator ConstMappedEnd =
1082 map_iterator(ConstLLVMRange.end(), ConstBBMap);
1083 return make_range(ConstMappedBegin, ConstMappedEnd);
1084 }
1085 };
1086
1087
1088 class UnaryInstruction
1089 : public SingleLLVMInstructionImpl<llvm::UnaryInstruction> {
1090 protected:
1091 UnaryInstruction(ClassID ID, Opcode Opc, llvm::Instruction *LLVMI,
1092 Context &Ctx)
1093 : SingleLLVMInstructionImpl(ID, Opc, LLVMI, Ctx) {}
1094
1095 public:
1096 static bool classof(const Instruction *I) {
1097 return isa<LoadInst>(I) || isa<CastInst>(I) || isa<FreezeInst>(I);
1098 }
1099 static bool classof(const Value *V) {
1100 return isa<Instruction>(V) && classof(cast<Instruction>(V));
1101 }
1102 };
1103
1104 class ExtractValueInst : public UnaryInstruction {
1105
1106 ExtractValueInst(llvm::ExtractValueInst *EVI, Context &Ctx)
1107 : UnaryInstruction(ClassID::ExtractValue, Opcode::ExtractValue, EVI,
1108 Ctx) {}
1109 friend Context;
1110
1111 public:
1112 static Value *create(Value *Agg, ArrayRef<unsigned> Idxs, InsertPosition Pos,
1113 Context &Ctx, const Twine &Name = "");
1114
1115 static bool classof(const Value *From) {
1116 return From->getSubclassID() == ClassID::ExtractValue;
1117 }
1118
1119
1120
1121
1122
1123 static Type *getIndexedType(Type *Agg, ArrayRef<unsigned> Idxs);
1124
1125 using idx_iterator = llvm::ExtractValueInst::idx_iterator;
1126
1127 inline idx_iterator idx_begin() const {
1128 return cast<llvm::ExtractValueInst>(Val)->idx_begin();
1129 }
1130 inline idx_iterator idx_end() const {
1131 return cast<llvm::ExtractValueInst>(Val)->idx_end();
1132 }
1133 inline iterator_range<idx_iterator> indices() const {
1134 return cast<llvm::ExtractValueInst>(Val)->indices();
1135 }
1136
1137 Value *getAggregateOperand() {
1138 return getOperand(getAggregateOperandIndex());
1139 }
1140 const Value *getAggregateOperand() const {
1141 return getOperand(getAggregateOperandIndex());
1142 }
1143 static unsigned getAggregateOperandIndex() {
1144 return llvm::ExtractValueInst::getAggregateOperandIndex();
1145 }
1146
1147 ArrayRef<unsigned> getIndices() const {
1148 return cast<llvm::ExtractValueInst>(Val)->getIndices();
1149 }
1150
1151 unsigned getNumIndices() const {
1152 return cast<llvm::ExtractValueInst>(Val)->getNumIndices();
1153 }
1154
1155 unsigned hasIndices() const {
1156 return cast<llvm::ExtractValueInst>(Val)->hasIndices();
1157 }
1158 };
1159
1160 class VAArgInst : public UnaryInstruction {
1161 VAArgInst(llvm::VAArgInst *FI, Context &Ctx)
1162 : UnaryInstruction(ClassID::VAArg, Opcode::VAArg, FI, Ctx) {}
1163 friend Context;
1164
1165 public:
1166 static VAArgInst *create(Value *List, Type *Ty, InsertPosition Pos,
1167 Context &Ctx, const Twine &Name = "");
1168 Value *getPointerOperand();
1169 const Value *getPointerOperand() const {
1170 return const_cast<VAArgInst *>(this)->getPointerOperand();
1171 }
1172 static unsigned getPointerOperandIndex() {
1173 return llvm::VAArgInst::getPointerOperandIndex();
1174 }
1175 static bool classof(const Value *From) {
1176 return From->getSubclassID() == ClassID::VAArg;
1177 }
1178 };
1179
1180 class FreezeInst : public UnaryInstruction {
1181 FreezeInst(llvm::FreezeInst *FI, Context &Ctx)
1182 : UnaryInstruction(ClassID::Freeze, Opcode::Freeze, FI, Ctx) {}
1183 friend Context;
1184
1185 public:
1186 static FreezeInst *create(Value *V, InsertPosition Pos, Context &Ctx,
1187 const Twine &Name = "");
1188 static bool classof(const Value *From) {
1189 return From->getSubclassID() == ClassID::Freeze;
1190 }
1191 };
1192
1193 class LoadInst final : public UnaryInstruction {
1194
1195 LoadInst(llvm::LoadInst *LI, Context &Ctx)
1196 : UnaryInstruction(ClassID::Load, Opcode::Load, LI, Ctx) {}
1197 friend Context;
1198
1199 public:
1200
1201 bool isVolatile() const { return cast<llvm::LoadInst>(Val)->isVolatile(); }
1202
1203 void setVolatile(bool V);
1204
1205 static LoadInst *create(Type *Ty, Value *Ptr, MaybeAlign Align,
1206 InsertPosition Pos, bool IsVolatile, Context &Ctx,
1207 const Twine &Name = "");
1208 static LoadInst *create(Type *Ty, Value *Ptr, MaybeAlign Align,
1209 InsertPosition Pos, Context &Ctx,
1210 const Twine &Name = "") {
1211 return create(Ty, Ptr, Align, Pos, false, Ctx, Name);
1212 }
1213
1214
1215 static bool classof(const Value *From);
1216 Value *getPointerOperand() const;
1217 Align getAlign() const { return cast<llvm::LoadInst>(Val)->getAlign(); }
1218 bool isUnordered() const { return cast<llvm::LoadInst>(Val)->isUnordered(); }
1219 bool isSimple() const { return cast<llvm::LoadInst>(Val)->isSimple(); }
1220 };
1221
1222 class StoreInst final : public SingleLLVMInstructionImpl<llvm::StoreInst> {
1223
1224 StoreInst(llvm::StoreInst *SI, Context &Ctx)
1225 : SingleLLVMInstructionImpl(ClassID::Store, Opcode::Store, SI, Ctx) {}
1226 friend Context;
1227
1228 public:
1229
1230 bool isVolatile() const { return cast<llvm::StoreInst>(Val)->isVolatile(); }
1231
1232 void setVolatile(bool V);
1233
1234 static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
1235 InsertPosition Pos, bool IsVolatile, Context &Ctx);
1236 static StoreInst *create(Value *V, Value *Ptr, MaybeAlign Align,
1237 InsertPosition Pos, Context &Ctx) {
1238 return create(V, Ptr, Align, Pos, false, Ctx);
1239 }
1240
1241
1242 static bool classof(const Value *From);
1243 Value *getValueOperand() const;
1244 Value *getPointerOperand() const;
1245 Align getAlign() const { return cast<llvm::StoreInst>(Val)->getAlign(); }
1246 bool isSimple() const { return cast<llvm::StoreInst>(Val)->isSimple(); }
1247 bool isUnordered() const { return cast<llvm::StoreInst>(Val)->isUnordered(); }
1248 };
1249
1250 class UnreachableInst final : public Instruction {
1251
1252 UnreachableInst(llvm::UnreachableInst *I, Context &Ctx)
1253 : Instruction(ClassID::Unreachable, Opcode::Unreachable, I, Ctx) {}
1254 friend Context;
1255 Use getOperandUseInternal(unsigned OpIdx, bool Verify) const final {
1256 return getOperandUseDefault(OpIdx, Verify);
1257 }
1258 SmallVector<llvm::Instruction *, 1> getLLVMInstrs() const final {
1259 return {cast<llvm::Instruction>(Val)};
1260 }
1261
1262 public:
1263 static UnreachableInst *create(InsertPosition Pos, Context &Ctx);
1264 static bool classof(const Value *From);
1265 unsigned getNumSuccessors() const { return 0; }
1266 unsigned getUseOperandNo(const Use &Use) const final {
1267 llvm_unreachable("UnreachableInst has no operands!");
1268 }
1269 unsigned getNumOfIRInstrs() const final { return 1u; }
1270 };
1271
1272 class ReturnInst final : public SingleLLVMInstructionImpl<llvm::ReturnInst> {
1273
1274 ReturnInst(llvm::Instruction *I, Context &Ctx)
1275 : SingleLLVMInstructionImpl(ClassID::Ret, Opcode::Ret, I, Ctx) {}
1276 ReturnInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
1277 : SingleLLVMInstructionImpl(SubclassID, Opcode::Ret, I, Ctx) {}
1278 friend class Context;
1279 static ReturnInst *createCommon(Value *RetVal, IRBuilder<> &Builder,
1280 Context &Ctx);
1281
1282 public:
1283 static ReturnInst *create(Value *RetVal, InsertPosition Pos, Context &Ctx);
1284 static bool classof(const Value *From) {
1285 return From->getSubclassID() == ClassID::Ret;
1286 }
1287
1288 Value *getReturnValue() const;
1289 };
1290
1291 class CallBase : public SingleLLVMInstructionImpl<llvm::CallBase> {
1292 CallBase(ClassID ID, Opcode Opc, llvm::Instruction *I, Context &Ctx)
1293 : SingleLLVMInstructionImpl(ID, Opc, I, Ctx) {}
1294 friend class CallInst;
1295 friend class InvokeInst;
1296 friend class CallBrInst;
1297
1298 public:
1299 static bool classof(const Value *From) {
1300 auto Opc = From->getSubclassID();
1301 return Opc == Instruction::ClassID::Call ||
1302 Opc == Instruction::ClassID::Invoke ||
1303 Opc == Instruction::ClassID::CallBr;
1304 }
1305
1306 FunctionType *getFunctionType() const;
1307
1308 op_iterator data_operands_begin() { return op_begin(); }
1309 const_op_iterator data_operands_begin() const {
1310 return const_cast<CallBase *>(this)->data_operands_begin();
1311 }
1312 op_iterator data_operands_end() {
1313 auto *LLVMCB = cast<llvm::CallBase>(Val);
1314 auto Dist = LLVMCB->data_operands_end() - LLVMCB->data_operands_begin();
1315 return op_begin() + Dist;
1316 }
1317 const_op_iterator data_operands_end() const {
1318 auto *LLVMCB = cast<llvm::CallBase>(Val);
1319 auto Dist = LLVMCB->data_operands_end() - LLVMCB->data_operands_begin();
1320 return op_begin() + Dist;
1321 }
1322 iterator_range<op_iterator> data_ops() {
1323 return make_range(data_operands_begin(), data_operands_end());
1324 }
1325 iterator_range<const_op_iterator> data_ops() const {
1326 return make_range(data_operands_begin(), data_operands_end());
1327 }
1328 bool data_operands_empty() const {
1329 return data_operands_end() == data_operands_begin();
1330 }
1331 unsigned data_operands_size() const {
1332 return std::distance(data_operands_begin(), data_operands_end());
1333 }
1334 bool isDataOperand(Use U) const {
1335 assert(this == U.getUser() &&
1336 "Only valid to query with a use of this instruction!");
1337 return cast<llvm::CallBase>(Val)->isDataOperand(U.LLVMUse);
1338 }
1339 unsigned getDataOperandNo(Use U) const {
1340 assert(isDataOperand(U) && "Data operand # out of range!");
1341 return cast<llvm::CallBase>(Val)->getDataOperandNo(U.LLVMUse);
1342 }
1343
1344
1345
1346 unsigned getNumTotalBundleOperands() const {
1347 return cast<llvm::CallBase>(Val)->getNumTotalBundleOperands();
1348 }
1349
1350 op_iterator arg_begin() { return op_begin(); }
1351 const_op_iterator arg_begin() const { return op_begin(); }
1352 op_iterator arg_end() {
1353 return data_operands_end() - getNumTotalBundleOperands();
1354 }
1355 const_op_iterator arg_end() const {
1356 return const_cast<CallBase *>(this)->arg_end();
1357 }
1358 iterator_range<op_iterator> args() {
1359 return make_range(arg_begin(), arg_end());
1360 }
1361 iterator_range<const_op_iterator> args() const {
1362 return make_range(arg_begin(), arg_end());
1363 }
1364 bool arg_empty() const { return arg_end() == arg_begin(); }
1365 unsigned arg_size() const { return arg_end() - arg_begin(); }
1366
1367 Value *getArgOperand(unsigned OpIdx) const {
1368 assert(OpIdx < arg_size() && "Out of bounds!");
1369 return getOperand(OpIdx);
1370 }
1371 void setArgOperand(unsigned OpIdx, Value *NewOp) {
1372 assert(OpIdx < arg_size() && "Out of bounds!");
1373 setOperand(OpIdx, NewOp);
1374 }
1375
1376 Use getArgOperandUse(unsigned Idx) const {
1377 assert(Idx < arg_size() && "Out of bounds!");
1378 return getOperandUse(Idx);
1379 }
1380 Use getArgOperandUse(unsigned Idx) {
1381 assert(Idx < arg_size() && "Out of bounds!");
1382 return getOperandUse(Idx);
1383 }
1384
1385 bool isArgOperand(Use U) const {
1386 return cast<llvm::CallBase>(Val)->isArgOperand(U.LLVMUse);
1387 }
1388 unsigned getArgOperandNo(Use U) const {
1389 return cast<llvm::CallBase>(Val)->getArgOperandNo(U.LLVMUse);
1390 }
1391 bool hasArgument(const Value *V) const { return is_contained(args(), V); }
1392
1393 Value *getCalledOperand() const;
1394 Use getCalledOperandUse() const;
1395
1396 Function *getCalledFunction() const;
1397 bool isIndirectCall() const {
1398 return cast<llvm::CallBase>(Val)->isIndirectCall();
1399 }
1400 bool isCallee(Use U) const {
1401 return cast<llvm::CallBase>(Val)->isCallee(U.LLVMUse);
1402 }
1403 Function *getCaller();
1404 const Function *getCaller() const {
1405 return const_cast<CallBase *>(this)->getCaller();
1406 }
1407 bool isMustTailCall() const {
1408 return cast<llvm::CallBase>(Val)->isMustTailCall();
1409 }
1410 bool isTailCall() const { return cast<llvm::CallBase>(Val)->isTailCall(); }
1411 Intrinsic::ID getIntrinsicID() const {
1412 return cast<llvm::CallBase>(Val)->getIntrinsicID();
1413 }
1414 void setCalledOperand(Value *V) { getCalledOperandUse().set(V); }
1415 void setCalledFunction(Function *F);
1416 CallingConv::ID getCallingConv() const {
1417 return cast<llvm::CallBase>(Val)->getCallingConv();
1418 }
1419 bool isInlineAsm() const { return cast<llvm::CallBase>(Val)->isInlineAsm(); }
1420 };
1421
1422 class CallInst : public CallBase {
1423
1424
1425 CallInst(llvm::Instruction *I, Context &Ctx)
1426 : CallBase(ClassID::Call, Opcode::Call, I, Ctx) {}
1427 friend class Context;
1428 friend class IntrinsicInst;
1429
1430 public:
1431 static CallInst *create(FunctionType *FTy, Value *Func,
1432 ArrayRef<Value *> Args, InsertPosition Pos,
1433 Context &Ctx, const Twine &NameStr = "");
1434
1435 static bool classof(const Value *From) {
1436 return From->getSubclassID() == ClassID::Call;
1437 }
1438 };
1439
1440 class InvokeInst final : public CallBase {
1441
1442
1443 InvokeInst(llvm::Instruction *I, Context &Ctx)
1444 : CallBase(ClassID::Invoke, Opcode::Invoke, I, Ctx) {}
1445 friend class Context;
1446
1447
1448 public:
1449 static InvokeInst *create(FunctionType *FTy, Value *Func,
1450 BasicBlock *IfNormal, BasicBlock *IfException,
1451 ArrayRef<Value *> Args, InsertPosition Pos,
1452 Context &Ctx, const Twine &NameStr = "");
1453
1454 static bool classof(const Value *From) {
1455 return From->getSubclassID() == ClassID::Invoke;
1456 }
1457 BasicBlock *getNormalDest() const;
1458 BasicBlock *getUnwindDest() const;
1459 void setNormalDest(BasicBlock *BB);
1460 void setUnwindDest(BasicBlock *BB);
1461 LandingPadInst *getLandingPadInst() const;
1462 BasicBlock *getSuccessor(unsigned SuccIdx) const;
1463 void setSuccessor(unsigned SuccIdx, BasicBlock *NewSucc) {
1464 assert(SuccIdx < 2 && "Successor # out of range for invoke!");
1465 if (SuccIdx == 0)
1466 setNormalDest(NewSucc);
1467 else
1468 setUnwindDest(NewSucc);
1469 }
1470 unsigned getNumSuccessors() const {
1471 return cast<llvm::InvokeInst>(Val)->getNumSuccessors();
1472 }
1473 };
1474
1475 class CallBrInst final : public CallBase {
1476
1477
1478 CallBrInst(llvm::Instruction *I, Context &Ctx)
1479 : CallBase(ClassID::CallBr, Opcode::CallBr, I, Ctx) {}
1480 friend class Context;
1481
1482
1483 public:
1484 static CallBrInst *create(FunctionType *FTy, Value *Func,
1485 BasicBlock *DefaultDest,
1486 ArrayRef<BasicBlock *> IndirectDests,
1487 ArrayRef<Value *> Args, InsertPosition Pos,
1488 Context &Ctx, const Twine &NameStr = "");
1489 static bool classof(const Value *From) {
1490 return From->getSubclassID() == ClassID::CallBr;
1491 }
1492 unsigned getNumIndirectDests() const {
1493 return cast<llvm::CallBrInst>(Val)->getNumIndirectDests();
1494 }
1495 Value *getIndirectDestLabel(unsigned Idx) const;
1496 Value *getIndirectDestLabelUse(unsigned Idx) const;
1497 BasicBlock *getDefaultDest() const;
1498 BasicBlock *getIndirectDest(unsigned Idx) const;
1499 SmallVector<BasicBlock *, 16> getIndirectDests() const;
1500 void setDefaultDest(BasicBlock *BB);
1501 void setIndirectDest(unsigned Idx, BasicBlock *BB);
1502 BasicBlock *getSuccessor(unsigned Idx) const;
1503 unsigned getNumSuccessors() const {
1504 return cast<llvm::CallBrInst>(Val)->getNumSuccessors();
1505 }
1506 };
1507
1508 class LandingPadInst : public SingleLLVMInstructionImpl<llvm::LandingPadInst> {
1509 LandingPadInst(llvm::LandingPadInst *LP, Context &Ctx)
1510 : SingleLLVMInstructionImpl(ClassID::LandingPad, Opcode::LandingPad, LP,
1511 Ctx) {}
1512 friend class Context;
1513
1514 public:
1515 static LandingPadInst *create(Type *RetTy, unsigned NumReservedClauses,
1516 InsertPosition Pos, Context &Ctx,
1517 const Twine &Name = "");
1518
1519
1520
1521 bool isCleanup() const {
1522 return cast<llvm::LandingPadInst>(Val)->isCleanup();
1523 }
1524
1525 void setCleanup(bool V);
1526
1527
1528
1529
1530
1531
1532 Constant *getClause(unsigned Idx) const;
1533
1534
1535 bool isCatch(unsigned Idx) const {
1536 return cast<llvm::LandingPadInst>(Val)->isCatch(Idx);
1537 }
1538
1539 bool isFilter(unsigned Idx) const {
1540 return cast<llvm::LandingPadInst>(Val)->isFilter(Idx);
1541 }
1542
1543 unsigned getNumClauses() const {
1544 return cast<llvm::LandingPadInst>(Val)->getNumOperands();
1545 }
1546
1547 static bool classof(const Value *From) {
1548 return From->getSubclassID() == ClassID::LandingPad;
1549 }
1550 };
1551
1552 class FuncletPadInst : public SingleLLVMInstructionImpl<llvm::FuncletPadInst> {
1553 FuncletPadInst(ClassID SubclassID, Opcode Opc, llvm::Instruction *I,
1554 Context &Ctx)
1555 : SingleLLVMInstructionImpl(SubclassID, Opc, I, Ctx) {}
1556 friend class CatchPadInst;
1557 friend class CleanupPadInst;
1558
1559 public:
1560
1561 unsigned arg_size() const {
1562 return cast<llvm::FuncletPadInst>(Val)->arg_size();
1563 }
1564
1565
1566
1567
1568 Value *getParentPad() const;
1569 void setParentPad(Value *ParentPad);
1570
1571 Value *getArgOperand(unsigned Idx) const;
1572
1573 void setArgOperand(unsigned Idx, Value *V);
1574
1575
1576 static bool classof(const Value *From) {
1577 return From->getSubclassID() == ClassID::CatchPad ||
1578 From->getSubclassID() == ClassID::CleanupPad;
1579 }
1580 };
1581
1582 class CatchPadInst : public FuncletPadInst {
1583 CatchPadInst(llvm::CatchPadInst *CPI, Context &Ctx)
1584 : FuncletPadInst(ClassID::CatchPad, Opcode::CatchPad, CPI, Ctx) {}
1585 friend class Context;
1586
1587 public:
1588 CatchSwitchInst *getCatchSwitch() const;
1589
1590
1591
1592 static CatchPadInst *create(Value *ParentPad, ArrayRef<Value *> Args,
1593 InsertPosition Pos, Context &Ctx,
1594 const Twine &Name = "");
1595 static bool classof(const Value *From) {
1596 return From->getSubclassID() == ClassID::CatchPad;
1597 }
1598 };
1599
1600 class CleanupPadInst : public FuncletPadInst {
1601 CleanupPadInst(llvm::CleanupPadInst *CPI, Context &Ctx)
1602 : FuncletPadInst(ClassID::CleanupPad, Opcode::CleanupPad, CPI, Ctx) {}
1603 friend class Context;
1604
1605 public:
1606 static CleanupPadInst *create(Value *ParentPad, ArrayRef<Value *> Args,
1607 InsertPosition Pos, Context &Ctx,
1608 const Twine &Name = "");
1609 static bool classof(const Value *From) {
1610 return From->getSubclassID() == ClassID::CleanupPad;
1611 }
1612 };
1613
1614 class CatchReturnInst
1615 : public SingleLLVMInstructionImpl<llvm::CatchReturnInst> {
1616 CatchReturnInst(llvm::CatchReturnInst *CRI, Context &Ctx)
1617 : SingleLLVMInstructionImpl(ClassID::CatchRet, Opcode::CatchRet, CRI,
1618 Ctx) {}
1619 friend class Context;
1620
1621 public:
1622 static CatchReturnInst *create(CatchPadInst *CatchPad, BasicBlock *BB,
1623 InsertPosition Pos, Context &Ctx);
1624 CatchPadInst *getCatchPad() const;
1625 void setCatchPad(CatchPadInst *CatchPad);
1626 BasicBlock *getSuccessor() const;
1627 void setSuccessor(BasicBlock *NewSucc);
1628 unsigned getNumSuccessors() {
1629 return cast<llvm::CatchReturnInst>(Val)->getNumSuccessors();
1630 }
1631 Value *getCatchSwitchParentPad() const;
1632 static bool classof(const Value *From) {
1633 return From->getSubclassID() == ClassID::CatchRet;
1634 }
1635 };
1636
1637 class CleanupReturnInst
1638 : public SingleLLVMInstructionImpl<llvm::CleanupReturnInst> {
1639 CleanupReturnInst(llvm::CleanupReturnInst *CRI, Context &Ctx)
1640 : SingleLLVMInstructionImpl(ClassID::CleanupRet, Opcode::CleanupRet, CRI,
1641 Ctx) {}
1642 friend class Context;
1643
1644 public:
1645 static CleanupReturnInst *create(CleanupPadInst *CleanupPad,
1646 BasicBlock *UnwindBB, InsertPosition Pos,
1647 Context &Ctx);
1648 bool hasUnwindDest() const {
1649 return cast<llvm::CleanupReturnInst>(Val)->hasUnwindDest();
1650 }
1651 bool unwindsToCaller() const {
1652 return cast<llvm::CleanupReturnInst>(Val)->unwindsToCaller();
1653 }
1654 CleanupPadInst *getCleanupPad() const;
1655 void setCleanupPad(CleanupPadInst *CleanupPad);
1656 unsigned getNumSuccessors() const {
1657 return cast<llvm::CleanupReturnInst>(Val)->getNumSuccessors();
1658 }
1659 BasicBlock *getUnwindDest() const;
1660 void setUnwindDest(BasicBlock *NewDest);
1661
1662 static bool classof(const Value *From) {
1663 return From->getSubclassID() == ClassID::CleanupRet;
1664 }
1665 };
1666
1667 class GetElementPtrInst final
1668 : public SingleLLVMInstructionImpl<llvm::GetElementPtrInst> {
1669
1670
1671 GetElementPtrInst(llvm::Instruction *I, Context &Ctx)
1672 : SingleLLVMInstructionImpl(ClassID::GetElementPtr, Opcode::GetElementPtr,
1673 I, Ctx) {}
1674 GetElementPtrInst(ClassID SubclassID, llvm::Instruction *I, Context &Ctx)
1675 : SingleLLVMInstructionImpl(SubclassID, Opcode::GetElementPtr, I, Ctx) {}
1676 friend class Context;
1677
1678
1679 public:
1680 static Value *create(Type *Ty, Value *Ptr, ArrayRef<Value *> IdxList,
1681 InsertPosition Pos, Context &Ctx,
1682 const Twine &NameStr = "");
1683
1684 static bool classof(const Value *From) {
1685 return From->getSubclassID() == ClassID::GetElementPtr;
1686 }
1687
1688 Type *getSourceElementType() const;
1689 Type *getResultElementType() const;
1690 unsigned getAddressSpace() const {
1691 return cast<llvm::GetElementPtrInst>(Val)->getAddressSpace();
1692 }
1693
1694 inline op_iterator idx_begin() { return op_begin() + 1; }
1695 inline const_op_iterator idx_begin() const {
1696 return const_cast<GetElementPtrInst *>(this)->idx_begin();
1697 }
1698 inline op_iterator idx_end() { return op_end(); }
1699 inline const_op_iterator idx_end() const {
1700 return const_cast<GetElementPtrInst *>(this)->idx_end();
1701 }
1702 inline iterator_range<op_iterator> indices() {
1703 return make_range(idx_begin(), idx_end());
1704 }
1705 inline iterator_range<const_op_iterator> indices() const {
1706 return const_cast<GetElementPtrInst *>(this)->indices();
1707 }
1708
1709 Value *getPointerOperand() const;
1710 static unsigned getPointerOperandIndex() {
1711 return llvm::GetElementPtrInst::getPointerOperandIndex();
1712 }
1713 Type *getPointerOperandType() const;
1714 unsigned getPointerAddressSpace() const {
1715 return cast<llvm::GetElementPtrInst>(Val)->getPointerAddressSpace();
1716 }
1717 unsigned getNumIndices() const {
1718 return cast<llvm::GetElementPtrInst>(Val)->getNumIndices();
1719 }
1720 bool hasIndices() const {
1721 return cast<llvm::GetElementPtrInst>(Val)->hasIndices();
1722 }
1723 bool hasAllConstantIndices() const {
1724 return cast<llvm::GetElementPtrInst>(Val)->hasAllConstantIndices();
1725 }
1726 GEPNoWrapFlags getNoWrapFlags() const {
1727 return cast<llvm::GetElementPtrInst>(Val)->getNoWrapFlags();
1728 }
1729 bool isInBounds() const {
1730 return cast<llvm::GetElementPtrInst>(Val)->isInBounds();
1731 }
1732 bool hasNoUnsignedSignedWrap() const {
1733 return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedSignedWrap();
1734 }
1735 bool hasNoUnsignedWrap() const {
1736 return cast<llvm::GetElementPtrInst>(Val)->hasNoUnsignedWrap();
1737 }
1738 bool accumulateConstantOffset(const DataLayout &DL, APInt &Offset) const {
1739 return cast<llvm::GetElementPtrInst>(Val)->accumulateConstantOffset(DL,
1740 Offset);
1741 }
1742
1743 };
1744
1745 class CatchSwitchInst
1746 : public SingleLLVMInstructionImpl<llvm::CatchSwitchInst> {
1747 CatchSwitchInst(llvm::CatchSwitchInst *CSI, Context &Ctx)
1748 : SingleLLVMInstructionImpl(ClassID::CatchSwitch, Opcode::CatchSwitch,
1749 CSI, Ctx) {}
1750 friend class Context;
1751
1752 public:
1753 static CatchSwitchInst *create(Value *ParentPad, BasicBlock *UnwindBB,
1754 unsigned NumHandlers, InsertPosition Pos,
1755 Context &Ctx, const Twine &Name = "");
1756
1757 Value *getParentPad() const;
1758 void setParentPad(Value *ParentPad);
1759
1760 bool hasUnwindDest() const {
1761 return cast<llvm::CatchSwitchInst>(Val)->hasUnwindDest();
1762 }
1763 bool unwindsToCaller() const {
1764 return cast<llvm::CatchSwitchInst>(Val)->unwindsToCaller();
1765 }
1766 BasicBlock *getUnwindDest() const;
1767 void setUnwindDest(BasicBlock *UnwindDest);
1768
1769 unsigned getNumHandlers() const {
1770 return cast<llvm::CatchSwitchInst>(Val)->getNumHandlers();
1771 }
1772
1773 private:
1774 static BasicBlock *handler_helper(Value *V) { return cast<BasicBlock>(V); }
1775 static const BasicBlock *handler_helper(const Value *V) {
1776 return cast<BasicBlock>(V);
1777 }
1778
1779 public:
1780 using DerefFnTy = BasicBlock *(*)(Value *);
1781 using handler_iterator = mapped_iterator<op_iterator, DerefFnTy>;
1782 using handler_range = iterator_range<handler_iterator>;
1783 using ConstDerefFnTy = const BasicBlock *(*)(const Value *);
1784 using const_handler_iterator =
1785 mapped_iterator<const_op_iterator, ConstDerefFnTy>;
1786 using const_handler_range = iterator_range<const_handler_iterator>;
1787
1788 handler_iterator handler_begin() {
1789 op_iterator It = op_begin() + 1;
1790 if (hasUnwindDest())
1791 ++It;
1792 return handler_iterator(It, DerefFnTy(handler_helper));
1793 }
1794 const_handler_iterator handler_begin() const {
1795 const_op_iterator It = op_begin() + 1;
1796 if (hasUnwindDest())
1797 ++It;
1798 return const_handler_iterator(It, ConstDerefFnTy(handler_helper));
1799 }
1800 handler_iterator handler_end() {
1801 return handler_iterator(op_end(), DerefFnTy(handler_helper));
1802 }
1803 const_handler_iterator handler_end() const {
1804 return const_handler_iterator(op_end(), ConstDerefFnTy(handler_helper));
1805 }
1806 handler_range handlers() {
1807 return make_range(handler_begin(), handler_end());
1808 }
1809 const_handler_range handlers() const {
1810 return make_range(handler_begin(), handler_end());
1811 }
1812
1813 void addHandler(BasicBlock *Dest);
1814
1815
1816
1817
1818
1819 unsigned getNumSuccessors() const { return getNumOperands() - 1; }
1820 BasicBlock *getSuccessor(unsigned Idx) const {
1821 assert(Idx < getNumSuccessors() &&
1822 "Successor # out of range for catchswitch!");
1823 return cast<BasicBlock>(getOperand(Idx + 1));
1824 }
1825 void setSuccessor(unsigned Idx, BasicBlock *NewSucc) {
1826 assert(Idx < getNumSuccessors() &&
1827 "Successor # out of range for catchswitch!");
1828 setOperand(Idx + 1, NewSucc);
1829 }
1830
1831 static bool classof(const Value *From) {
1832 return From->getSubclassID() == ClassID::CatchSwitch;
1833 }
1834 };
1835
1836 class ResumeInst : public SingleLLVMInstructionImpl<llvm::ResumeInst> {
1837 ResumeInst(llvm::ResumeInst *CSI, Context &Ctx)
1838 : SingleLLVMInstructionImpl(ClassID::Resume, Opcode::Resume, CSI, Ctx) {}
1839 friend class Context;
1840
1841 public:
1842 static ResumeInst *create(Value *Exn, InsertPosition Pos, Context &Ctx);
1843 Value *getValue() const;
1844 unsigned getNumSuccessors() const {
1845 return cast<llvm::ResumeInst>(Val)->getNumSuccessors();
1846 }
1847 static bool classof(const Value *From) {
1848 return From->getSubclassID() == ClassID::Resume;
1849 }
1850 };
1851
1852 class SwitchInst : public SingleLLVMInstructionImpl<llvm::SwitchInst> {
1853 SwitchInst(llvm::SwitchInst *SI, Context &Ctx)
1854 : SingleLLVMInstructionImpl(ClassID::Switch, Opcode::Switch, SI, Ctx) {}
1855 friend class Context;
1856
1857 public:
1858 static constexpr const unsigned DefaultPseudoIndex =
1859 llvm::SwitchInst::DefaultPseudoIndex;
1860
1861 static SwitchInst *create(Value *V, BasicBlock *Dest, unsigned NumCases,
1862 InsertPosition Pos, Context &Ctx,
1863 const Twine &Name = "");
1864
1865 Value *getCondition() const;
1866 void setCondition(Value *V);
1867 BasicBlock *getDefaultDest() const;
1868 bool defaultDestUndefined() const {
1869 return cast<llvm::SwitchInst>(Val)->defaultDestUndefined();
1870 }
1871 void setDefaultDest(BasicBlock *DefaultCase);
1872 unsigned getNumCases() const {
1873 return cast<llvm::SwitchInst>(Val)->getNumCases();
1874 }
1875
1876 using CaseHandle =
1877 llvm::SwitchInst::CaseHandleImpl<SwitchInst, ConstantInt, BasicBlock>;
1878 using ConstCaseHandle =
1879 llvm::SwitchInst::CaseHandleImpl<const SwitchInst, const ConstantInt,
1880 const BasicBlock>;
1881 using CaseIt = llvm::SwitchInst::CaseIteratorImpl<CaseHandle>;
1882 using ConstCaseIt = llvm::SwitchInst::CaseIteratorImpl<ConstCaseHandle>;
1883
1884
1885
1886 CaseIt case_begin() { return CaseIt(this, 0); }
1887 ConstCaseIt case_begin() const { return ConstCaseIt(this, 0); }
1888
1889
1890 CaseIt case_end() { return CaseIt(this, getNumCases()); }
1891 ConstCaseIt case_end() const { return ConstCaseIt(this, getNumCases()); }
1892
1893 iterator_range<CaseIt> cases() {
1894 return make_range(case_begin(), case_end());
1895 }
1896 iterator_range<ConstCaseIt> cases() const {
1897 return make_range(case_begin(), case_end());
1898 }
1899 CaseIt case_default() { return CaseIt(this, DefaultPseudoIndex); }
1900 ConstCaseIt case_default() const {
1901 return ConstCaseIt(this, DefaultPseudoIndex);
1902 }
1903 CaseIt findCaseValue(const ConstantInt *C) {
1904 return CaseIt(
1905 this,
1906 const_cast<const SwitchInst *>(this)->findCaseValue(C)->getCaseIndex());
1907 }
1908 ConstCaseIt findCaseValue(const ConstantInt *C) const {
1909 ConstCaseIt I = llvm::find_if(cases(), [C](const ConstCaseHandle &Case) {
1910 return Case.getCaseValue() == C;
1911 });
1912 if (I != case_end())
1913 return I;
1914 return case_default();
1915 }
1916 ConstantInt *findCaseDest(BasicBlock *BB);
1917
1918 void addCase(ConstantInt *OnVal, BasicBlock *Dest);
1919
1920
1921
1922
1923
1924
1925
1926 CaseIt removeCase(CaseIt It);
1927
1928 unsigned getNumSuccessors() const {
1929 return cast<llvm::SwitchInst>(Val)->getNumSuccessors();
1930 }
1931 BasicBlock *getSuccessor(unsigned Idx) const;
1932 void setSuccessor(unsigned Idx, BasicBlock *NewSucc);
1933 static bool classof(const Value *From) {
1934 return From->getSubclassID() == ClassID::Switch;
1935 }
1936 };
1937
1938 class UnaryOperator : public UnaryInstruction {
1939 static Opcode getUnaryOpcode(llvm::Instruction::UnaryOps UnOp) {
1940 switch (UnOp) {
1941 case llvm::Instruction::FNeg:
1942 return Opcode::FNeg;
1943 case llvm::Instruction::UnaryOpsEnd:
1944 llvm_unreachable("Bad UnOp!");
1945 }
1946 llvm_unreachable("Unhandled UnOp!");
1947 }
1948 UnaryOperator(llvm::UnaryOperator *UO, Context &Ctx)
1949 : UnaryInstruction(ClassID::UnOp, getUnaryOpcode(UO->getOpcode()), UO,
1950 Ctx) {}
1951 friend Context;
1952 public:
1953 static Value *create(Instruction::Opcode Op, Value *OpV, InsertPosition Pos,
1954 Context &Ctx, const Twine &Name = "");
1955 static Value *createWithCopiedFlags(Instruction::Opcode Op, Value *OpV,
1956 Value *CopyFrom, InsertPosition Pos,
1957 Context &Ctx, const Twine &Name = "");
1958
1959 static bool classof(const Value *From) {
1960 return From->getSubclassID() == ClassID::UnOp;
1961 }
1962 };
1963
1964 class BinaryOperator : public SingleLLVMInstructionImpl<llvm::BinaryOperator> {
1965 protected:
1966 static Opcode getBinOpOpcode(llvm::Instruction::BinaryOps BinOp) {
1967 switch (BinOp) {
1968 case llvm::Instruction::Add:
1969 return Opcode::Add;
1970 case llvm::Instruction::FAdd:
1971 return Opcode::FAdd;
1972 case llvm::Instruction::Sub:
1973 return Opcode::Sub;
1974 case llvm::Instruction::FSub:
1975 return Opcode::FSub;
1976 case llvm::Instruction::Mul:
1977 return Opcode::Mul;
1978 case llvm::Instruction::FMul:
1979 return Opcode::FMul;
1980 case llvm::Instruction::UDiv:
1981 return Opcode::UDiv;
1982 case llvm::Instruction::SDiv:
1983 return Opcode::SDiv;
1984 case llvm::Instruction::FDiv:
1985 return Opcode::FDiv;
1986 case llvm::Instruction::URem:
1987 return Opcode::URem;
1988 case llvm::Instruction::SRem:
1989 return Opcode::SRem;
1990 case llvm::Instruction::FRem:
1991 return Opcode::FRem;
1992 case llvm::Instruction::Shl:
1993 return Opcode::Shl;
1994 case llvm::Instruction::LShr:
1995 return Opcode::LShr;
1996 case llvm::Instruction::AShr:
1997 return Opcode::AShr;
1998 case llvm::Instruction::And:
1999 return Opcode::And;
2000 case llvm::Instruction::Or:
2001 return Opcode::Or;
2002 case llvm::Instruction::Xor:
2003 return Opcode::Xor;
2004 case llvm::Instruction::BinaryOpsEnd:
2005 llvm_unreachable("Bad BinOp!");
2006 }
2007 llvm_unreachable("Unhandled BinOp!");
2008 }
2009 BinaryOperator(llvm::BinaryOperator *BinOp, Context &Ctx)
2010 : SingleLLVMInstructionImpl(ClassID::BinaryOperator,
2011 getBinOpOpcode(BinOp->getOpcode()), BinOp,
2012 Ctx) {}
2013 friend class Context;
2014
2015 public:
2016 static Value *create(Instruction::Opcode Op, Value *LHS, Value *RHS,
2017 InsertPosition Pos, Context &Ctx,
2018 const Twine &Name = "");
2019
2020 static Value *createWithCopiedFlags(Instruction::Opcode Op, Value *LHS,
2021 Value *RHS, Value *CopyFrom,
2022 InsertPosition Pos, Context &Ctx,
2023 const Twine &Name = "");
2024
2025 static bool classof(const Value *From) {
2026 return From->getSubclassID() == ClassID::BinaryOperator;
2027 }
2028 void swapOperands() { swapOperandsInternal(0, 1); }
2029 };
2030
2031
2032
2033
2034 class PossiblyDisjointInst : public BinaryOperator {
2035 public:
2036 void setIsDisjoint(bool B);
2037 bool isDisjoint() const {
2038 return cast<llvm::PossiblyDisjointInst>(Val)->isDisjoint();
2039 }
2040
2041 static bool classof(const Value *From) {
2042 return isa<Instruction>(From) &&
2043 cast<Instruction>(From)->getOpcode() == Opcode::Or;
2044 }
2045 };
2046
2047 class AtomicRMWInst : public SingleLLVMInstructionImpl<llvm::AtomicRMWInst> {
2048 AtomicRMWInst(llvm::AtomicRMWInst *Atomic, Context &Ctx)
2049 : SingleLLVMInstructionImpl(ClassID::AtomicRMW,
2050 Instruction::Opcode::AtomicRMW, Atomic, Ctx) {
2051 }
2052 friend class Context;
2053
2054 public:
2055 using BinOp = llvm::AtomicRMWInst::BinOp;
2056 BinOp getOperation() const {
2057 return cast<llvm::AtomicRMWInst>(Val)->getOperation();
2058 }
2059 static StringRef getOperationName(BinOp Op) {
2060 return llvm::AtomicRMWInst::getOperationName(Op);
2061 }
2062 static bool isFPOperation(BinOp Op) {
2063 return llvm::AtomicRMWInst::isFPOperation(Op);
2064 }
2065 void setOperation(BinOp Op) {
2066 cast<llvm::AtomicRMWInst>(Val)->setOperation(Op);
2067 }
2068 Align getAlign() const { return cast<llvm::AtomicRMWInst>(Val)->getAlign(); }
2069 void setAlignment(Align Align);
2070 bool isVolatile() const {
2071 return cast<llvm::AtomicRMWInst>(Val)->isVolatile();
2072 }
2073 void setVolatile(bool V);
2074 AtomicOrdering getOrdering() const {
2075 return cast<llvm::AtomicRMWInst>(Val)->getOrdering();
2076 }
2077 void setOrdering(AtomicOrdering Ordering);
2078 SyncScope::ID getSyncScopeID() const {
2079 return cast<llvm::AtomicRMWInst>(Val)->getSyncScopeID();
2080 }
2081 void setSyncScopeID(SyncScope::ID SSID);
2082 Value *getPointerOperand();
2083 const Value *getPointerOperand() const {
2084 return const_cast<AtomicRMWInst *>(this)->getPointerOperand();
2085 }
2086 Value *getValOperand();
2087 const Value *getValOperand() const {
2088 return const_cast<AtomicRMWInst *>(this)->getValOperand();
2089 }
2090 unsigned getPointerAddressSpace() const {
2091 return cast<llvm::AtomicRMWInst>(Val)->getPointerAddressSpace();
2092 }
2093 bool isFloatingPointOperation() const {
2094 return cast<llvm::AtomicRMWInst>(Val)->isFloatingPointOperation();
2095 }
2096 static bool classof(const Value *From) {
2097 return From->getSubclassID() == ClassID::AtomicRMW;
2098 }
2099
2100 static AtomicRMWInst *create(BinOp Op, Value *Ptr, Value *Val,
2101 MaybeAlign Align, AtomicOrdering Ordering,
2102 InsertPosition Pos, Context &Ctx,
2103 SyncScope::ID SSID = SyncScope::System,
2104 const Twine &Name = "");
2105 };
2106
2107 class AtomicCmpXchgInst
2108 : public SingleLLVMInstructionImpl<llvm::AtomicCmpXchgInst> {
2109 AtomicCmpXchgInst(llvm::AtomicCmpXchgInst *Atomic, Context &Ctx)
2110 : SingleLLVMInstructionImpl(ClassID::AtomicCmpXchg,
2111 Instruction::Opcode::AtomicCmpXchg, Atomic,
2112 Ctx) {}
2113 friend class Context;
2114
2115 public:
2116
2117
2118 Align getAlign() const {
2119 return cast<llvm::AtomicCmpXchgInst>(Val)->getAlign();
2120 }
2121
2122 void setAlignment(Align Align);
2123
2124
2125 bool isVolatile() const {
2126 return cast<llvm::AtomicCmpXchgInst>(Val)->isVolatile();
2127 }
2128
2129 void setVolatile(bool V);
2130
2131 bool isWeak() const { return cast<llvm::AtomicCmpXchgInst>(Val)->isWeak(); }
2132 void setWeak(bool IsWeak);
2133 static bool isValidSuccessOrdering(AtomicOrdering Ordering) {
2134 return llvm::AtomicCmpXchgInst::isValidSuccessOrdering(Ordering);
2135 }
2136 static bool isValidFailureOrdering(AtomicOrdering Ordering) {
2137 return llvm::AtomicCmpXchgInst::isValidFailureOrdering(Ordering);
2138 }
2139 AtomicOrdering getSuccessOrdering() const {
2140 return cast<llvm::AtomicCmpXchgInst>(Val)->getSuccessOrdering();
2141 }
2142 void setSuccessOrdering(AtomicOrdering Ordering);
2143
2144 AtomicOrdering getFailureOrdering() const {
2145 return cast<llvm::AtomicCmpXchgInst>(Val)->getFailureOrdering();
2146 }
2147 void setFailureOrdering(AtomicOrdering Ordering);
2148 AtomicOrdering getMergedOrdering() const {
2149 return cast<llvm::AtomicCmpXchgInst>(Val)->getMergedOrdering();
2150 }
2151 SyncScope::ID getSyncScopeID() const {
2152 return cast<llvm::AtomicCmpXchgInst>(Val)->getSyncScopeID();
2153 }
2154 void setSyncScopeID(SyncScope::ID SSID);
2155 Value *getPointerOperand();
2156 const Value *getPointerOperand() const {
2157 return const_cast<AtomicCmpXchgInst *>(this)->getPointerOperand();
2158 }
2159
2160 Value *getCompareOperand();
2161 const Value *getCompareOperand() const {
2162 return const_cast<AtomicCmpXchgInst *>(this)->getCompareOperand();
2163 }
2164
2165 Value *getNewValOperand();
2166 const Value *getNewValOperand() const {
2167 return const_cast<AtomicCmpXchgInst *>(this)->getNewValOperand();
2168 }
2169
2170
2171 unsigned getPointerAddressSpace() const {
2172 return cast<llvm::AtomicCmpXchgInst>(Val)->getPointerAddressSpace();
2173 }
2174
2175 static AtomicCmpXchgInst *
2176 create(Value *Ptr, Value *Cmp, Value *New, MaybeAlign Align,
2177 AtomicOrdering SuccessOrdering, AtomicOrdering FailureOrdering,
2178 InsertPosition Pos, Context &Ctx,
2179 SyncScope::ID SSID = SyncScope::System, const Twine &Name = "");
2180
2181 static bool classof(const Value *From) {
2182 return From->getSubclassID() == ClassID::AtomicCmpXchg;
2183 }
2184 };
2185
2186 class AllocaInst final : public UnaryInstruction {
2187 AllocaInst(llvm::AllocaInst *AI, Context &Ctx)
2188 : UnaryInstruction(ClassID::Alloca, Instruction::Opcode::Alloca, AI,
2189 Ctx) {}
2190 friend class Context;
2191
2192 public:
2193 static AllocaInst *create(Type *Ty, unsigned AddrSpace, InsertPosition Pos,
2194 Context &Ctx, Value *ArraySize = nullptr,
2195 const Twine &Name = "");
2196
2197
2198
2199 bool isArrayAllocation() const {
2200 return cast<llvm::AllocaInst>(Val)->isArrayAllocation();
2201 }
2202
2203
2204 Value *getArraySize();
2205 const Value *getArraySize() const {
2206 return const_cast<AllocaInst *>(this)->getArraySize();
2207 }
2208
2209 PointerType *getType() const;
2210
2211 unsigned getAddressSpace() const {
2212 return cast<llvm::AllocaInst>(Val)->getAddressSpace();
2213 }
2214
2215
2216 std::optional<TypeSize> getAllocationSize(const DataLayout &DL) const {
2217 return cast<llvm::AllocaInst>(Val)->getAllocationSize(DL);
2218 }
2219
2220
2221 std::optional<TypeSize> getAllocationSizeInBits(const DataLayout &DL) const {
2222 return cast<llvm::AllocaInst>(Val)->getAllocationSizeInBits(DL);
2223 }
2224
2225 Type *getAllocatedType() const;
2226
2227
2228 void setAllocatedType(Type *Ty);
2229
2230
2231 Align getAlign() const { return cast<llvm::AllocaInst>(Val)->getAlign(); }
2232 void setAlignment(Align Align);
2233
2234
2235
2236 bool isStaticAlloca() const {
2237 return cast<llvm::AllocaInst>(Val)->isStaticAlloca();
2238 }
2239
2240
2241 bool isUsedWithInAlloca() const {
2242 return cast<llvm::AllocaInst>(Val)->isUsedWithInAlloca();
2243 }
2244
2245 void setUsedWithInAlloca(bool V);
2246
2247 static bool classof(const Value *From) {
2248 if (auto *I = dyn_cast<Instruction>(From))
2249 return I->getSubclassID() == Instruction::ClassID::Alloca;
2250 return false;
2251 }
2252 };
2253
2254 class CastInst : public UnaryInstruction {
2255 static Opcode getCastOpcode(llvm::Instruction::CastOps CastOp) {
2256 switch (CastOp) {
2257 case llvm::Instruction::ZExt:
2258 return Opcode::ZExt;
2259 case llvm::Instruction::SExt:
2260 return Opcode::SExt;
2261 case llvm::Instruction::FPToUI:
2262 return Opcode::FPToUI;
2263 case llvm::Instruction::FPToSI:
2264 return Opcode::FPToSI;
2265 case llvm::Instruction::FPExt:
2266 return Opcode::FPExt;
2267 case llvm::Instruction::PtrToInt:
2268 return Opcode::PtrToInt;
2269 case llvm::Instruction::IntToPtr:
2270 return Opcode::IntToPtr;
2271 case llvm::Instruction::SIToFP:
2272 return Opcode::SIToFP;
2273 case llvm::Instruction::UIToFP:
2274 return Opcode::UIToFP;
2275 case llvm::Instruction::Trunc:
2276 return Opcode::Trunc;
2277 case llvm::Instruction::FPTrunc:
2278 return Opcode::FPTrunc;
2279 case llvm::Instruction::BitCast:
2280 return Opcode::BitCast;
2281 case llvm::Instruction::AddrSpaceCast:
2282 return Opcode::AddrSpaceCast;
2283 case llvm::Instruction::CastOpsEnd:
2284 llvm_unreachable("Bad CastOp!");
2285 }
2286 llvm_unreachable("Unhandled CastOp!");
2287 }
2288
2289
2290 CastInst(llvm::CastInst *CI, Context &Ctx)
2291 : UnaryInstruction(ClassID::Cast, getCastOpcode(CI->getOpcode()), CI,
2292 Ctx) {}
2293 friend Context;
2294
2295 public:
2296 static Value *create(Type *DestTy, Opcode Op, Value *Operand,
2297 InsertPosition Pos, Context &Ctx,
2298 const Twine &Name = "");
2299
2300 static bool classof(const Value *From);
2301 Type *getSrcTy() const;
2302 Type *getDestTy() const;
2303 };
2304
2305
2306 class PossiblyNonNegInst : public CastInst {
2307 public:
2308 bool hasNonNeg() const {
2309 return cast<llvm::PossiblyNonNegInst>(Val)->hasNonNeg();
2310 }
2311 void setNonNeg(bool B);
2312
2313 static bool classof(const Value *From) {
2314 if (auto *I = dyn_cast<Instruction>(From)) {
2315 switch (I->getOpcode()) {
2316 case Opcode::ZExt:
2317 case Opcode::UIToFP:
2318 return true;
2319 default:
2320 return false;
2321 }
2322 }
2323 return false;
2324 }
2325 };
2326
2327
2328 template <Instruction::Opcode Op> class CastInstImpl : public CastInst {
2329 public:
2330 static Value *create(Value *Src, Type *DestTy, InsertPosition Pos,
2331 Context &Ctx, const Twine &Name = "") {
2332 return CastInst::create(DestTy, Op, Src, Pos, Ctx, Name);
2333 }
2334
2335 static bool classof(const Value *From) {
2336 if (auto *I = dyn_cast<Instruction>(From))
2337 return I->getOpcode() == Op;
2338 return false;
2339 }
2340 };
2341
2342 class TruncInst final : public CastInstImpl<Instruction::Opcode::Trunc> {};
2343 class ZExtInst final : public CastInstImpl<Instruction::Opcode::ZExt> {};
2344 class SExtInst final : public CastInstImpl<Instruction::Opcode::SExt> {};
2345 class FPTruncInst final : public CastInstImpl<Instruction::Opcode::FPTrunc> {};
2346 class FPExtInst final : public CastInstImpl<Instruction::Opcode::FPExt> {};
2347 class UIToFPInst final : public CastInstImpl<Instruction::Opcode::UIToFP> {};
2348 class SIToFPInst final : public CastInstImpl<Instruction::Opcode::SIToFP> {};
2349 class FPToUIInst final : public CastInstImpl<Instruction::Opcode::FPToUI> {};
2350 class FPToSIInst final : public CastInstImpl<Instruction::Opcode::FPToSI> {};
2351 class IntToPtrInst final : public CastInstImpl<Instruction::Opcode::IntToPtr> {
2352 };
2353 class PtrToIntInst final : public CastInstImpl<Instruction::Opcode::PtrToInt> {
2354 };
2355 class BitCastInst final : public CastInstImpl<Instruction::Opcode::BitCast> {};
2356 class AddrSpaceCastInst final
2357 : public CastInstImpl<Instruction::Opcode::AddrSpaceCast> {
2358 public:
2359
2360 Value *getPointerOperand() { return getOperand(0); }
2361
2362 const Value *getPointerOperand() const {
2363 return const_cast<AddrSpaceCastInst *>(this)->getPointerOperand();
2364 }
2365
2366 static unsigned getPointerOperandIndex() { return 0u; }
2367
2368 unsigned getSrcAddressSpace() const {
2369 return getPointerOperand()->getType()->getPointerAddressSpace();
2370 }
2371
2372 unsigned getDestAddressSpace() const {
2373 return getType()->getPointerAddressSpace();
2374 }
2375 };
2376
2377 class PHINode final : public SingleLLVMInstructionImpl<llvm::PHINode> {
2378
2379 PHINode(llvm::PHINode *PHI, Context &Ctx)
2380 : SingleLLVMInstructionImpl(ClassID::PHI, Opcode::PHI, PHI, Ctx) {}
2381 friend Context;
2382
2383 struct LLVMBBToBB {
2384 Context &Ctx;
2385 LLVMBBToBB(Context &Ctx) : Ctx(Ctx) {}
2386 BasicBlock *operator()(llvm::BasicBlock *LLVMBB) const;
2387 };
2388
2389 public:
2390 static PHINode *create(Type *Ty, unsigned NumReservedValues,
2391 InsertPosition Pos, Context &Ctx,
2392 const Twine &Name = "");
2393
2394 static bool classof(const Value *From);
2395
2396 using const_block_iterator =
2397 mapped_iterator<llvm::PHINode::const_block_iterator, LLVMBBToBB>;
2398
2399 const_block_iterator block_begin() const {
2400 LLVMBBToBB BBGetter(Ctx);
2401 return const_block_iterator(cast<llvm::PHINode>(Val)->block_begin(),
2402 BBGetter);
2403 }
2404 const_block_iterator block_end() const {
2405 LLVMBBToBB BBGetter(Ctx);
2406 return const_block_iterator(cast<llvm::PHINode>(Val)->block_end(),
2407 BBGetter);
2408 }
2409 iterator_range<const_block_iterator> blocks() const {
2410 return make_range(block_begin(), block_end());
2411 }
2412
2413 op_range incoming_values() { return operands(); }
2414
2415 const_op_range incoming_values() const { return operands(); }
2416
2417 unsigned getNumIncomingValues() const {
2418 return cast<llvm::PHINode>(Val)->getNumIncomingValues();
2419 }
2420 Value *getIncomingValue(unsigned Idx) const;
2421 void setIncomingValue(unsigned Idx, Value *V);
2422 static unsigned getOperandNumForIncomingValue(unsigned Idx) {
2423 return llvm::PHINode::getOperandNumForIncomingValue(Idx);
2424 }
2425 static unsigned getIncomingValueNumForOperand(unsigned Idx) {
2426 return llvm::PHINode::getIncomingValueNumForOperand(Idx);
2427 }
2428 BasicBlock *getIncomingBlock(unsigned Idx) const;
2429 BasicBlock *getIncomingBlock(const Use &U) const;
2430
2431 void setIncomingBlock(unsigned Idx, BasicBlock *BB);
2432
2433 void addIncoming(Value *V, BasicBlock *BB);
2434
2435 Value *removeIncomingValue(unsigned Idx);
2436 Value *removeIncomingValue(BasicBlock *BB);
2437
2438 int getBasicBlockIndex(const BasicBlock *BB) const;
2439 Value *getIncomingValueForBlock(const BasicBlock *BB) const;
2440
2441 Value *hasConstantValue() const;
2442
2443 bool hasConstantOrUndefValue() const {
2444 return cast<llvm::PHINode>(Val)->hasConstantOrUndefValue();
2445 }
2446 bool isComplete() const { return cast<llvm::PHINode>(Val)->isComplete(); }
2447 void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New);
2448 void removeIncomingValueIf(function_ref<bool(unsigned)> Predicate);
2449
2450
2451
2452 };
2453
2454
2455
2456 #define WRAP_STATIC_PREDICATE(FunctionName) \
2457 static auto FunctionName(Predicate P) { return LLVMValType::FunctionName(P); }
2458
2459
2460 #define WRAP_MEMBER(FunctionName) \
2461 auto FunctionName() const { return cast<LLVMValType>(Val)->FunctionName(); }
2462
2463 #define WRAP_BOTH(FunctionName) \
2464 WRAP_STATIC_PREDICATE(FunctionName) \
2465 WRAP_MEMBER(FunctionName)
2466
2467 class CmpInst : public SingleLLVMInstructionImpl<llvm::CmpInst> {
2468 protected:
2469 using LLVMValType = llvm::CmpInst;
2470
2471 CmpInst(llvm::CmpInst *CI, Context &Ctx, ClassID Id, Opcode Opc)
2472 : SingleLLVMInstructionImpl(Id, Opc, CI, Ctx) {}
2473 friend Context;
2474 static Value *createCommon(Value *Cond, Value *True, Value *False,
2475 const Twine &Name, IRBuilder<> &Builder,
2476 Context &Ctx);
2477
2478 public:
2479 using Predicate = llvm::CmpInst::Predicate;
2480
2481 static Value *create(Predicate Pred, Value *S1, Value *S2, InsertPosition Pos,
2482 Context &Ctx, const Twine &Name = "");
2483 static Value *createWithCopiedFlags(Predicate Pred, Value *S1, Value *S2,
2484 const Instruction *FlagsSource,
2485 InsertPosition Pos, Context &Ctx,
2486 const Twine &Name = "");
2487 void setPredicate(Predicate P);
2488 void swapOperands();
2489
2490 WRAP_MEMBER(getPredicate);
2491 WRAP_BOTH(isFPPredicate);
2492 WRAP_BOTH(isIntPredicate);
2493 WRAP_STATIC_PREDICATE(getPredicateName);
2494 WRAP_BOTH(getInversePredicate);
2495 WRAP_BOTH(getOrderedPredicate);
2496 WRAP_BOTH(getUnorderedPredicate);
2497 WRAP_BOTH(getSwappedPredicate);
2498 WRAP_BOTH(isStrictPredicate);
2499 WRAP_BOTH(isNonStrictPredicate);
2500 WRAP_BOTH(getStrictPredicate);
2501 WRAP_BOTH(getNonStrictPredicate);
2502 WRAP_BOTH(getFlippedStrictnessPredicate);
2503 WRAP_MEMBER(isCommutative);
2504 WRAP_BOTH(isEquality);
2505 WRAP_BOTH(isRelational);
2506 WRAP_BOTH(isSigned);
2507 WRAP_BOTH(isTrueWhenEqual);
2508 WRAP_BOTH(isFalseWhenEqual);
2509 WRAP_BOTH(isUnsigned);
2510 WRAP_STATIC_PREDICATE(isOrdered);
2511 WRAP_STATIC_PREDICATE(isUnordered);
2512
2513
2514 static bool classof(const Value *From) {
2515 return From->getSubclassID() == ClassID::ICmp ||
2516 From->getSubclassID() == ClassID::FCmp;
2517 }
2518
2519
2520 static Type *makeCmpResultType(Type *OpndType);
2521
2522 #ifndef NDEBUG
2523 void dumpOS(raw_ostream &OS) const override;
2524 LLVM_DUMP_METHOD void dump() const;
2525 #endif
2526 };
2527
2528 class ICmpInst : public CmpInst {
2529
2530 ICmpInst(llvm::ICmpInst *CI, Context &Ctx)
2531 : CmpInst(CI, Ctx, ClassID::ICmp, Opcode::ICmp) {}
2532 friend class Context;
2533 using LLVMValType = llvm::ICmpInst;
2534
2535 public:
2536 void swapOperands();
2537
2538 WRAP_BOTH(getSignedPredicate);
2539 WRAP_BOTH(getUnsignedPredicate);
2540 WRAP_BOTH(getFlippedSignednessPredicate);
2541 WRAP_BOTH(isEquality);
2542 WRAP_MEMBER(isCommutative);
2543 WRAP_MEMBER(isRelational);
2544 WRAP_STATIC_PREDICATE(isGT);
2545 WRAP_STATIC_PREDICATE(isLT);
2546 WRAP_STATIC_PREDICATE(isGE);
2547 WRAP_STATIC_PREDICATE(isLE);
2548
2549 static std::optional<bool> isImpliedByMatchingCmp(CmpPredicate Pred1,
2550 CmpPredicate Pred2) {
2551 return llvm::ICmpInst::isImpliedByMatchingCmp(Pred1, Pred2);
2552 }
2553
2554 static auto predicates() { return llvm::ICmpInst::predicates(); }
2555 static bool compare(const APInt &LHS, const APInt &RHS,
2556 ICmpInst::Predicate Pred) {
2557 return llvm::ICmpInst::compare(LHS, RHS, Pred);
2558 }
2559
2560 static bool classof(const Value *From) {
2561 return From->getSubclassID() == ClassID::ICmp;
2562 }
2563 };
2564
2565 class FCmpInst : public CmpInst {
2566
2567 FCmpInst(llvm::FCmpInst *CI, Context &Ctx)
2568 : CmpInst(CI, Ctx, ClassID::FCmp, Opcode::FCmp) {}
2569 friend class Context;
2570 using LLVMValType = llvm::FCmpInst;
2571
2572 public:
2573 void swapOperands();
2574
2575 WRAP_BOTH(isEquality);
2576 WRAP_MEMBER(isCommutative);
2577 WRAP_MEMBER(isRelational);
2578
2579 static auto predicates() { return llvm::FCmpInst::predicates(); }
2580 static bool compare(const APFloat &LHS, const APFloat &RHS,
2581 FCmpInst::Predicate Pred) {
2582 return llvm::FCmpInst::compare(LHS, RHS, Pred);
2583 }
2584
2585 static bool classof(const Value *From) {
2586 return From->getSubclassID() == ClassID::FCmp;
2587 }
2588 };
2589
2590 #undef WRAP_STATIC_PREDICATE
2591 #undef WRAP_MEMBER
2592 #undef WRAP_BOTH
2593
2594
2595
2596 class OpaqueInst : public SingleLLVMInstructionImpl<llvm::Instruction> {
2597 OpaqueInst(llvm::Instruction *I, sandboxir::Context &Ctx)
2598 : SingleLLVMInstructionImpl(ClassID::Opaque, Opcode::Opaque, I, Ctx) {}
2599 OpaqueInst(ClassID SubclassID, llvm::Instruction *I, sandboxir::Context &Ctx)
2600 : SingleLLVMInstructionImpl(SubclassID, Opcode::Opaque, I, Ctx) {}
2601 friend class Context;
2602
2603 public:
2604 static bool classof(const sandboxir::Value *From) {
2605 return From->getSubclassID() == ClassID::Opaque;
2606 }
2607 };
2608
2609 }
2610
2611 #endif