diff options
Diffstat (limited to 'include/llvm/IR/Instructions.h')
-rw-r--r-- | include/llvm/IR/Instructions.h | 487 |
1 files changed, 392 insertions, 95 deletions
diff --git a/include/llvm/IR/Instructions.h b/include/llvm/IR/Instructions.h index 0ff8f56f213a..215ce45c7b75 100644 --- a/include/llvm/IR/Instructions.h +++ b/include/llvm/IR/Instructions.h @@ -1,9 +1,8 @@ //===- llvm/Instructions.h - Instruction subclass definitions ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -522,9 +521,11 @@ private: // AtomicCmpXchgInst Class //===----------------------------------------------------------------------===// -/// an instruction that atomically checks whether a +/// An instruction that atomically checks whether a /// specified value is in a memory location, and, if it is, stores a new value -/// there. Returns the value that was loaded. +/// there. The value returned by this instruction is a pair containing the +/// original value as first element, and an i1 indicating success (true) or +/// failure (false) as second element. /// class AtomicCmpXchgInst : public Instruction { void Init(Value *Ptr, Value *Cmp, Value *NewVal, @@ -725,8 +726,14 @@ public: /// *p = old <unsigned v ? old : v UMin, + /// *p = old + v + FAdd, + + /// *p = old - v + FSub, + FIRST_BINOP = Xchg, - LAST_BINOP = UMin, + LAST_BINOP = FSub, BAD_BINOP }; @@ -748,6 +755,16 @@ public: static StringRef getOperationName(BinOp Op); + static bool isFPOperation(BinOp Op) { + switch (Op) { + case AtomicRMWInst::FAdd: + case AtomicRMWInst::FSub: + return true; + default: + return false; + } + } + void setOperation(BinOp Operation) { unsigned short SubclassData = getSubclassDataFromInstruction(); setInstructionSubclassData((SubclassData & 31) | @@ -805,6 +822,10 @@ public: return getPointerOperand()->getType()->getPointerAddressSpace(); } + bool isFloatingPointOperation() const { + return isFPOperation(getOperation()); + } + // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::AtomicRMW; @@ -1115,71 +1136,6 @@ GetElementPtrInst::GetElementPtrInst(Type *PointeeType, Value *Ptr, DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GetElementPtrInst, Value) //===----------------------------------------------------------------------===// -// UnaryOperator Class -//===----------------------------------------------------------------------===// - -/// a unary instruction -class UnaryOperator : public UnaryInstruction { - void AssertOK(); - -protected: - UnaryOperator(UnaryOps iType, Value *S, Type *Ty, - const Twine &Name, Instruction *InsertBefore); - UnaryOperator(UnaryOps iType, Value *S, Type *Ty, - const Twine &Name, BasicBlock *InsertAtEnd); - - // Note: Instruction needs to be a friend here to call cloneImpl. - friend class Instruction; - - UnaryOperator *cloneImpl() const; - -public: - - /// Construct a unary instruction, given the opcode and an operand. - /// Optionally (if InstBefore is specified) insert the instruction - /// into a BasicBlock right before the specified instruction. The specified - /// Instruction is allowed to be a dereferenced end iterator. - /// - static UnaryOperator *Create(UnaryOps Op, Value *S, - const Twine &Name = Twine(), - Instruction *InsertBefore = nullptr); - - /// Construct a unary instruction, given the opcode and an operand. - /// Also automatically insert this instruction to the end of the - /// BasicBlock specified. - /// - static UnaryOperator *Create(UnaryOps Op, Value *S, - const Twine &Name, - BasicBlock *InsertAtEnd); - - /// These methods just forward to Create, and are useful when you - /// statically know what type of instruction you're going to create. These - /// helpers just save some typing. -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name = "") {\ - return Create(Instruction::OPC, V, Name);\ - } -#include "llvm/IR/Instruction.def" -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name, BasicBlock *BB) {\ - return Create(Instruction::OPC, V, Name, BB);\ - } -#include "llvm/IR/Instruction.def" -#define HANDLE_UNARY_INST(N, OPC, CLASS) \ - static UnaryInstruction *Create##OPC(Value *V, \ - const Twine &Name, Instruction *I) {\ - return Create(Instruction::OPC, V, Name, I);\ - } -#include "llvm/IR/Instruction.def" - - UnaryOps getOpcode() const { - return static_cast<UnaryOps>(Instruction::getOpcode()); - } -}; - -//===----------------------------------------------------------------------===// // ICmpInst Class //===----------------------------------------------------------------------===// @@ -1524,25 +1480,44 @@ public: CallInst(Ty, Func, Args, Bundles, NameStr, InsertAtEnd); } - static CallInst *Create(Function *Func, const Twine &NameStr = "", + static CallInst *Create(FunctionCallee Func, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), NameStr, + InsertBefore); } - static CallInst *Create(Function *Func, ArrayRef<Value *> Args, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, Args, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles, + NameStr, InsertBefore); } - static CallInst *Create(Function *Func, const Twine &NameStr, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr, + InsertBefore); + } + + static CallInst *Create(FunctionCallee Func, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), NameStr, + InsertAtEnd); } - static CallInst *Create(Function *Func, ArrayRef<Value *> Args, + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, Args, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), Args, NameStr, + InsertAtEnd); + } + + static CallInst *Create(FunctionCallee Func, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), Args, Bundles, + NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] @@ -1684,9 +1659,6 @@ public: addAttribute(AttributeList::FunctionIndex, Attribute::ReturnsTwice); } - /// Check if this call is an inline asm statement. - bool isInlineAsm() const { return isa<InlineAsm>(getCalledOperand()); } - // Methods for support type inquiry through isa, cast, and dyn_cast: static bool classof(const Instruction *I) { return I->getOpcode() == Instruction::Call; @@ -1695,6 +1667,9 @@ public: return isa<Instruction>(V) && classof(cast<Instruction>(V)); } + /// Updates profile metadata by scaling it by \p S / \p T. + void updateProfWeight(uint64_t S, uint64_t T); + private: // Shadow Instruction::setInstructionSubclassData with a private forwarding // method so that subclasses cannot accidentally use it. @@ -2008,6 +1983,10 @@ public: return User::operator new(s, 3); } + /// Swap the first 2 operands and adjust the mask to preserve the semantics + /// of the instruction. + void commute(); + /// Return true if a shufflevector instruction can be /// formed with the specified operands. static bool isValidOperands(const Value *V1, const Value *V2, @@ -2696,6 +2675,14 @@ public: block_begin()[i] = BB; } + /// Replace every incoming basic block \p Old to basic block \p New. + void replaceIncomingBlockWith(const BasicBlock *Old, BasicBlock *New) { + assert(New && Old && "PHI node got a null basic block!"); + for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op) + if (getIncomingBlock(Op) == Old) + setIncomingBlock(Op, New); + } + /// Add an incoming value to the end of the PHI list /// void addIncoming(Value *V, BasicBlock *BB) { @@ -2739,6 +2726,19 @@ public: return getIncomingValue(Idx); } + /// Set every incoming value(s) for block \p BB to \p V. + void setIncomingValueForBlock(const BasicBlock *BB, Value *V) { + assert(BB && "PHI node got a null basic block!"); + bool Found = false; + for (unsigned Op = 0, NumOps = getNumOperands(); Op != NumOps; ++Op) + if (getIncomingBlock(Op) == BB) { + Found = true; + setIncomingValue(Op, V); + } + (void)Found; + assert(Found && "Invalid basic block argument to set!"); + } + /// If the specified PHI node always merges together the /// same value, return the value, otherwise return null. Value *hasConstantValue() const; @@ -3450,6 +3450,60 @@ public: } }; +/// A wrapper class to simplify modification of SwitchInst cases along with +/// their prof branch_weights metadata. +class SwitchInstProfUpdateWrapper { + SwitchInst &SI; + Optional<SmallVector<uint32_t, 8> > Weights = None; + + // Sticky invalid state is needed to safely ignore operations with prof data + // in cases where SwitchInstProfUpdateWrapper is created from SwitchInst + // with inconsistent prof data. TODO: once we fix all prof data + // inconsistencies we can turn invalid state to assertions. + enum { + Invalid, + Initialized, + Changed + } State = Invalid; + +protected: + static MDNode *getProfBranchWeightsMD(const SwitchInst &SI); + + MDNode *buildProfBranchWeightsMD(); + + void init(); + +public: + using CaseWeightOpt = Optional<uint32_t>; + SwitchInst *operator->() { return &SI; } + SwitchInst &operator*() { return SI; } + operator SwitchInst *() { return &SI; } + + SwitchInstProfUpdateWrapper(SwitchInst &SI) : SI(SI) { init(); } + + ~SwitchInstProfUpdateWrapper() { + if (State == Changed) + SI.setMetadata(LLVMContext::MD_prof, buildProfBranchWeightsMD()); + } + + /// Delegate the call to the underlying SwitchInst::removeCase() and remove + /// correspondent branch weight. + SwitchInst::CaseIt removeCase(SwitchInst::CaseIt I); + + /// Delegate the call to the underlying SwitchInst::addCase() and set the + /// specified branch weight for the added case. + void addCase(ConstantInt *OnVal, BasicBlock *Dest, CaseWeightOpt W); + + /// Delegate the call to the underlying SwitchInst::eraseFromParent() and mark + /// this object to not touch the underlying SwitchInst in destructor. + SymbolTableList<Instruction>::iterator eraseFromParent(); + + void setSuccessorWeight(unsigned idx, CaseWeightOpt W); + CaseWeightOpt getSuccessorWeight(unsigned idx); + + static CaseWeightOpt getSuccessorWeight(const SwitchInst &SI, unsigned idx); +}; + template <> struct OperandTraits<SwitchInst> : public HungoffOperandTraits<2> { }; @@ -3688,36 +3742,36 @@ public: NameStr, InsertAtEnd); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr, Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - None, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, None, NameStr, InsertBefore); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles = None, const Twine &NameStr = "", Instruction *InsertBefore = nullptr) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - Bundles, NameStr, InsertBefore); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, Bundles, NameStr, InsertBefore); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, NameStr, InsertAtEnd); } - static InvokeInst *Create(Function *Func, BasicBlock *IfNormal, + static InvokeInst *Create(FunctionCallee Func, BasicBlock *IfNormal, BasicBlock *IfException, ArrayRef<Value *> Args, ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr, BasicBlock *InsertAtEnd) { - return Create(Func->getFunctionType(), Func, IfNormal, IfException, Args, - Bundles, NameStr, InsertAtEnd); + return Create(Func.getFunctionType(), Func.getCallee(), IfNormal, + IfException, Args, Bundles, NameStr, InsertAtEnd); } // Deprecated [opaque pointer types] @@ -3852,6 +3906,249 @@ InvokeInst::InvokeInst(FunctionType *Ty, Value *Func, BasicBlock *IfNormal, } //===----------------------------------------------------------------------===// +// CallBrInst Class +//===----------------------------------------------------------------------===// + +/// CallBr instruction, tracking function calls that may not return control but +/// instead transfer it to a third location. The SubclassData field is used to +/// hold the calling convention of the call. +/// +class CallBrInst : public CallBase { + + unsigned NumIndirectDests; + + CallBrInst(const CallBrInst &BI); + + /// Construct a CallBrInst given a range of arguments. + /// + /// Construct a CallBrInst from a range of arguments + inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, Instruction *InsertBefore); + + inline CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, BasicBlock *InsertAtEnd); + + void init(FunctionType *FTy, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, const Twine &NameStr); + + /// Compute the number of operands to allocate. + static int ComputeNumOperands(int NumArgs, int NumIndirectDests, + int NumBundleInputs = 0) { + // We need one operand for the called function, plus our extra operands and + // the input operand counts provided. + return 2 + NumIndirectDests + NumArgs + NumBundleInputs; + } + +protected: + // Note: Instruction needs to be a friend here to call cloneImpl. + friend class Instruction; + + CallBrInst *cloneImpl() const; + +public: + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size()); + return new (NumOperands) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, None, + NumOperands, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size(), + CountBundleInputs(Bundles)); + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (NumOperands, DescriptorBytes) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, + NumOperands, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + BasicBlock *InsertAtEnd) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size()); + return new (NumOperands) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, None, + NumOperands, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionType *Ty, Value *Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + int NumOperands = ComputeNumOperands(Args.size(), IndirectDests.size(), + CountBundleInputs(Bundles)); + unsigned DescriptorBytes = Bundles.size() * sizeof(BundleOpInfo); + + return new (NumOperands, DescriptorBytes) + CallBrInst(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, + NumOperands, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles = None, + const Twine &NameStr = "", + Instruction *InsertBefore = nullptr) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, Bundles, NameStr, InsertBefore); + } + + static CallBrInst *Create(FunctionCallee Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, const Twine &NameStr, + BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, NameStr, InsertAtEnd); + } + + static CallBrInst *Create(FunctionCallee Func, + BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return Create(Func.getFunctionType(), Func.getCallee(), DefaultDest, + IndirectDests, Args, Bundles, NameStr, InsertAtEnd); + } + + /// Create a clone of \p CBI with a different set of operand bundles and + /// insert it before \p InsertPt. + /// + /// The returned callbr instruction is identical to \p CBI in every way + /// except that the operand bundles for the new instruction are set to the + /// operand bundles in \p Bundles. + static CallBrInst *Create(CallBrInst *CBI, + ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertPt = nullptr); + + /// Return the number of callbr indirect dest labels. + /// + unsigned getNumIndirectDests() const { return NumIndirectDests; } + + /// getIndirectDestLabel - Return the i-th indirect dest label. + /// + Value *getIndirectDestLabel(unsigned i) const { + assert(i < getNumIndirectDests() && "Out of bounds!"); + return getOperand(i + getNumArgOperands() + getNumTotalBundleOperands() + + 1); + } + + Value *getIndirectDestLabelUse(unsigned i) const { + assert(i < getNumIndirectDests() && "Out of bounds!"); + return getOperandUse(i + getNumArgOperands() + getNumTotalBundleOperands() + + 1); + } + + // Return the destination basic blocks... + BasicBlock *getDefaultDest() const { + return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() - 1)); + } + BasicBlock *getIndirectDest(unsigned i) const { + return cast<BasicBlock>(*(&Op<-1>() - getNumIndirectDests() + i)); + } + SmallVector<BasicBlock *, 16> getIndirectDests() const { + SmallVector<BasicBlock *, 16> IndirectDests; + for (unsigned i = 0, e = getNumIndirectDests(); i < e; ++i) + IndirectDests.push_back(getIndirectDest(i)); + return IndirectDests; + } + void setDefaultDest(BasicBlock *B) { + *(&Op<-1>() - getNumIndirectDests() - 1) = reinterpret_cast<Value *>(B); + } + void setIndirectDest(unsigned i, BasicBlock *B) { + *(&Op<-1>() - getNumIndirectDests() + i) = reinterpret_cast<Value *>(B); + } + + BasicBlock *getSuccessor(unsigned i) const { + assert(i < getNumSuccessors() + 1 && + "Successor # out of range for callbr!"); + return i == 0 ? getDefaultDest() : getIndirectDest(i - 1); + } + + void setSuccessor(unsigned idx, BasicBlock *NewSucc) { + assert(idx < getNumIndirectDests() + 1 && + "Successor # out of range for callbr!"); + *(&Op<-1>() - getNumIndirectDests() -1 + idx) = + reinterpret_cast<Value *>(NewSucc); + } + + unsigned getNumSuccessors() const { return getNumIndirectDests() + 1; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static bool classof(const Instruction *I) { + return (I->getOpcode() == Instruction::CallBr); + } + static bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } + +private: + + // Shadow Instruction::setInstructionSubclassData with a private forwarding + // method so that subclasses cannot accidentally use it. + void setInstructionSubclassData(unsigned short D) { + Instruction::setInstructionSubclassData(D); + } +}; + +CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, Instruction *InsertBefore) + : CallBase(Ty->getReturnType(), Instruction::CallBr, + OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands, + InsertBefore) { + init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr); +} + +CallBrInst::CallBrInst(FunctionType *Ty, Value *Func, BasicBlock *DefaultDest, + ArrayRef<BasicBlock *> IndirectDests, + ArrayRef<Value *> Args, + ArrayRef<OperandBundleDef> Bundles, int NumOperands, + const Twine &NameStr, BasicBlock *InsertAtEnd) + : CallBase( + cast<FunctionType>( + cast<PointerType>(Func->getType())->getElementType()) + ->getReturnType(), + Instruction::CallBr, + OperandTraits<CallBase>::op_end(this) - NumOperands, NumOperands, + InsertAtEnd) { + init(Ty, Func, DefaultDest, IndirectDests, Args, Bundles, NameStr); +} + +//===----------------------------------------------------------------------===// // ResumeInst Class //===----------------------------------------------------------------------===// |