// \brief Returns true if this terminator relates to exception handling.
bool isExceptional() const {
switch (getOpcode()) {
- case Instruction::CatchPad:
- case Instruction::CatchEndPad:
+ case Instruction::CatchSwitch:
case Instruction::CatchRet:
- case Instruction::CleanupEndPad:
case Instruction::CleanupRet:
case Instruction::Invoke:
case Instruction::Resume:
- case Instruction::TerminatePad:
return true;
default:
return false;
/// This class is the base class for the comparison instructions.
/// @brief Abstract base class of comparison instructions.
class CmpInst : public Instruction {
- void *operator new(size_t, unsigned) = delete;
- CmpInst() = delete;
-
-protected:
- CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
- Value *LHS, Value *RHS, const Twine &Name = "",
- Instruction *InsertBefore = nullptr);
-
- CmpInst(Type *ty, Instruction::OtherOps op, unsigned short pred,
- Value *LHS, Value *RHS, const Twine &Name,
- BasicBlock *InsertAtEnd);
-
- void anchor() override; // Out of line virtual method.
-
public:
/// This enumeration lists the possible predicates for CmpInst subclasses.
/// Values in the range 0-31 are reserved for FCmpInst, while values in the
BAD_ICMP_PREDICATE = ICMP_SLE + 1
};
+private:
+ void *operator new(size_t, unsigned) = delete;
+ CmpInst() = delete;
+
+protected:
+ CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred,
+ Value *LHS, Value *RHS, const Twine &Name = "",
+ Instruction *InsertBefore = nullptr);
+
+ CmpInst(Type *ty, Instruction::OtherOps op, Predicate pred,
+ Value *LHS, Value *RHS, const Twine &Name,
+ BasicBlock *InsertAtEnd);
+
+ void anchor() override; // Out of line virtual method.
+
+public:
// allocate space for exactly two operands
void *operator new(size_t s) {
return User::operator new(s, 2);
/// The specified Instruction is allowed to be a dereferenced end iterator.
/// @brief Create a CmpInst
static CmpInst *Create(OtherOps Op,
- unsigned short predicate, Value *S1,
+ Predicate predicate, Value *S1,
Value *S2, const Twine &Name = "",
Instruction *InsertBefore = nullptr);
/// two operands. Also automatically insert this instruction to the end of
/// the BasicBlock specified.
/// @brief Create a CmpInst
- static CmpInst *Create(OtherOps Op, unsigned short predicate, Value *S1,
+ static CmpInst *Create(OtherOps Op, Predicate predicate, Value *S1,
Value *S2, const Twine &Name, BasicBlock *InsertAtEnd);
/// @brief Get the opcode casted to the right type
/// @returns true if the predicate is unsigned, false otherwise.
/// @brief Determine if the predicate is an unsigned operation.
- static bool isUnsigned(unsigned short predicate);
+ static bool isUnsigned(Predicate predicate);
/// @returns true if the predicate is signed, false otherwise.
/// @brief Determine if the predicate is an signed operation.
- static bool isSigned(unsigned short predicate);
+ static bool isSigned(Predicate predicate);
/// @brief Determine if the predicate is an ordered operation.
- static bool isOrdered(unsigned short predicate);
+ static bool isOrdered(Predicate predicate);
/// @brief Determine if the predicate is an unordered operation.
- static bool isUnordered(unsigned short predicate);
+ static bool isUnordered(Predicate predicate);
/// Determine if the predicate is true when comparing a value with itself.
- static bool isTrueWhenEqual(unsigned short predicate);
+ static bool isTrueWhenEqual(Predicate predicate);
/// Determine if the predicate is false when comparing a value with itself.
- static bool isFalseWhenEqual(unsigned short predicate);
+ static bool isFalseWhenEqual(Predicate predicate);
/// @brief Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) {
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
+//===----------------------------------------------------------------------===//
+// FuncletPadInst Class
+//===----------------------------------------------------------------------===//
+class FuncletPadInst : public Instruction {
+private:
+ void init(Value *ParentPad, ArrayRef<Value *> Args, const Twine &NameStr);
+
+ FuncletPadInst(const FuncletPadInst &CPI);
+
+ explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, Instruction *InsertBefore);
+ explicit FuncletPadInst(Instruction::FuncletPadOps Op, Value *ParentPad,
+ ArrayRef<Value *> Args, unsigned Values,
+ const Twine &NameStr, BasicBlock *InsertAtEnd);
+
+protected:
+ // Note: Instruction needs to be a friend here to call cloneImpl.
+ friend class Instruction;
+ friend class CatchPadInst;
+ friend class CleanupPadInst;
+ FuncletPadInst *cloneImpl() const;
+
+public:
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ /// getNumArgOperands - Return the number of funcletpad arguments.
+ ///
+ unsigned getNumArgOperands() const { return getNumOperands() - 1; }
+
+ /// Convenience accessors
+
+ /// \brief Return the outer EH-pad this funclet is nested within.
+ ///
+ /// Note: This returns the associated CatchSwitchInst if this FuncletPadInst
+ /// is a CatchPadInst.
+ Value *getParentPad() const { return Op<-1>(); }
+ void setParentPad(Value *ParentPad) {
+ assert(ParentPad);
+ Op<-1>() = ParentPad;
+ }
+
+ /// getArgOperand/setArgOperand - Return/set the i-th funcletpad argument.
+ ///
+ Value *getArgOperand(unsigned i) const { return getOperand(i); }
+ void setArgOperand(unsigned i, Value *v) { setOperand(i, v); }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ op_range arg_operands() { return op_range(op_begin(), op_end() - 1); }
+
+ /// arg_operands - iteration adapter for range-for loops.
+ const_op_range arg_operands() const {
+ return const_op_range(op_begin(), op_end() - 1);
+ }
+
+ // Methods for support type inquiry through isa, cast, and dyn_cast:
+ static inline bool classof(const Instruction *I) { return I->isFuncletPad(); }
+ static inline bool classof(const Value *V) {
+ return isa<Instruction>(V) && classof(cast<Instruction>(V));
+ }
+};
+
+template <>
+struct OperandTraits<FuncletPadInst>
+ : public VariadicOperandTraits<FuncletPadInst, /*MINARITY=*/1> {};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(FuncletPadInst, Value)
+
/// \brief A lightweight accessor for an operand bundle meant to be passed
/// around by value.
struct OperandBundleUse {
return getTagID() == LLVMContext::OB_deopt;
}
+ /// \brief Return true if this is a "funclet" operand bundle.
+ bool isFuncletOperandBundle() const {
+ return getTagID() == LLVMContext::OB_funclet;
+ }
+
private:
/// \brief Pointer to an entry in LLVMContextImpl::getOrInsertBundleTag.
StringMapEntry<uint32_t> *Tag;
std::vector<InputTy> Inputs;
public:
- explicit OperandBundleDefT(StringRef Tag, std::vector<InputTy> Inputs)
- : Tag(Tag), Inputs(std::move(Inputs)) {}
-
explicit OperandBundleDefT(std::string Tag, std::vector<InputTy> Inputs)
: Tag(std::move(Tag)), Inputs(std::move(Inputs)) {}
+ explicit OperandBundleDefT(std::string Tag, ArrayRef<InputTy> Inputs)
+ : Tag(std::move(Tag)), Inputs(Inputs) {}
explicit OperandBundleDefT(const OperandBundleUse &OBU) {
Tag = OBU.getTagName();
/// may write to the heap.
bool hasClobberingOperandBundles() const {
for (auto &BOI : bundle_op_infos()) {
- if (BOI.Tag->second == LLVMContext::OB_deopt)
+ if (BOI.Tag->second == LLVMContext::OB_deopt ||
+ BOI.Tag->second == LLVMContext::OB_funclet)
continue;
- // This instruction has an operand bundle that is not a "deopt" operand
- // bundle. Assume the worst.
+ // This instruction has an operand bundle that is not known to us.
+ // Assume the worst.
return true;
}
return OBU.operandHasAttr(OpIdx - BOI.Begin, A);
}
+ /// \brief Return true if \p Other has the same sequence of operand bundle
+ /// tags with the same number of operands on each one of them as this
+ /// OperandBundleUser.
+ bool hasIdenticalOperandBundleSchema(
+ const OperandBundleUser<InstrTy, OpIteratorTy> &Other) const {
+ if (getNumOperandBundles() != Other.getNumOperandBundles())
+ return false;
+
+ return std::equal(bundle_op_info_begin(), bundle_op_info_end(),
+ Other.bundle_op_info_begin());
+ };
+
protected:
/// \brief Is the function attribute S disallowed by some operand bundle on
/// this operand bundle user?
/// \brief The index in the Use& vector where operands for this operand
/// bundle ends.
uint32_t End;
+
+ bool operator==(const BundleOpInfo &Other) const {
+ return Tag == Other.Tag && Begin == Other.Begin && End == Other.End;
+ }
};
/// \brief Simple helper function to map a BundleOpInfo to an