#define LLVM_INSTRUCTION_TYPES_H
#include "llvm/Instruction.h"
+#include "llvm/OperandTraits.h"
namespace llvm {
}
};
+
//===----------------------------------------------------------------------===//
// UnaryInstruction Class
//===----------------------------------------------------------------------===//
class UnaryInstruction : public Instruction {
- Use Op;
+ void *operator new(size_t, unsigned); // Do not implement
- // avoiding warning: 'this' : used in base member initializer list
- UnaryInstruction* this_() { return this; }
protected:
- UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB =0)
- : Instruction(Ty, iType, &Op, 1, IB), Op(V, this_()) {
+ UnaryInstruction(const Type *Ty, unsigned iType, Value *V, Instruction *IB = 0)
+ : Instruction(Ty, iType, &Op<0>(), 1, IB) {
+ Op<0>() = V;
}
UnaryInstruction(const Type *Ty, unsigned iType, Value *V, BasicBlock *IAE)
- : Instruction(Ty, iType, &Op, 1, IAE), Op(V, this_()) {
+ : Instruction(Ty, iType, &Op<0>(), 1, IAE) {
+ Op<0>() = V;
}
public:
+ // allocate space for exactly one operand
+ void *operator new(size_t s) {
+ return User::operator new(s, 1);
+ }
+
// Out of line virtual method, so the vtable, etc has a home.
~UnaryInstruction();
- // Transparently provide more efficient getOperand methods.
- Value *getOperand(unsigned i) const {
- assert(i == 0 && "getOperand() out of range!");
- return Op;
- }
- void setOperand(unsigned i, Value *Val) {
- assert(i == 0 && "setOperand() out of range!");
- Op = Val;
- }
- unsigned getNumOperands() const { return 1; }
+ /// Transparently provide more efficient getOperand methods.
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const UnaryInstruction *) { return true; }
}
};
+template <>
+struct OperandTraits<UnaryInstruction> : FixedNumOperandTraits<1> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(UnaryInstruction, Value)
+
//===----------------------------------------------------------------------===//
// BinaryOperator Class
//===----------------------------------------------------------------------===//
class BinaryOperator : public Instruction {
- Use Ops[2];
+ void *operator new(size_t, unsigned); // Do not implement
protected:
void init(BinaryOps iType);
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
const std::string &Name, BasicBlock *InsertAtEnd);
public:
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
/// Transparently provide more efficient getOperand methods.
- Value *getOperand(unsigned i) const {
- assert(i < 2 && "getOperand() out of range!");
- return Ops[i];
- }
- void setOperand(unsigned i, Value *Val) {
- assert(i < 2 && "setOperand() out of range!");
- Ops[i] = Val;
- }
- unsigned getNumOperands() const { return 2; }
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// create() - Construct a binary instruction, given the opcode and the two
/// operands. Optionally (if InstBefore is specified) insert the instruction
/// swapOperands - Exchange the two operands to this instruction.
/// This instruction is safe to use on any binary instruction and
- /// does not modify the semantics of the instruction. If the
- /// instruction is order dependent (SetLT f.e.) the opcode is
- /// changed. If the instruction cannot be reversed (ie, it's a Div),
- /// then return true.
+ /// does not modify the semantics of the instruction. If the instruction
+ /// cannot be reversed (ie, it's a Div), then return true.
///
bool swapOperands();
}
};
+template <>
+struct OperandTraits<BinaryOperator> : FixedNumOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BinaryOperator, Value)
+
//===----------------------------------------------------------------------===//
// CastInst Class
//===----------------------------------------------------------------------===//
/// This class is the base class for the comparison instructions.
/// @brief Abstract base class of comparison instructions.
+// FIXME: why not derive from BinaryOperator?
class CmpInst: public Instruction {
+ void *operator new(size_t, unsigned); // DO NOT IMPLEMENT
CmpInst(); // do not implement
protected:
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
CmpInst(Instruction::OtherOps op, unsigned short pred, Value *LHS, Value *RHS,
const std::string &Name, BasicBlock *InsertAtEnd);
- Use Ops[2]; // CmpInst instructions always have 2 operands, optimize
-
public:
+ // allocate space for exactly two operands
+ void *operator new(size_t s) {
+ return User::operator new(s, 2);
+ }
/// Construct a compare instruction, given the opcode, the predicate and
/// the two operands. Optionally (if InstBefore is specified) insert the
/// instruction into a BasicBlock right before the specified instruction.
}
/// @brief Provide more efficient getOperand methods.
- Value *getOperand(unsigned i) const {
- assert(i < 2 && "getOperand() out of range!");
- return Ops[i];
- }
- void setOperand(unsigned i, Value *Val) {
- assert(i < 2 && "setOperand() out of range!");
- Ops[i] = Val;
- }
-
- /// @brief CmpInst instructions always have 2 operands.
- unsigned getNumOperands() const { return 2; }
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
/// This is just a convenience that dispatches to the subclasses.
/// @brief Swap the operands and adjust predicate accordingly to retain
}
};
+
+// FIXME: these are redundant if CmpInst < BinaryOperator
+template <>
+struct OperandTraits<CmpInst> : FixedNumOperandTraits<2> {
+};
+
+DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CmpInst, Value)
+
} // End llvm namespace
#endif