aboutsummaryrefslogtreecommitdiff
path: root/include/llvm/IR/Instructions.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/IR/Instructions.h')
-rw-r--r--include/llvm/IR/Instructions.h487
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
//===----------------------------------------------------------------------===//