#ifndef LLVM_INSTRUCTION_H
#define LLVM_INSTRUCTION_H
#include "llvm/User.h"
#include "llvm/ADT/ilist_node.h"
namespace llvm {
template<typename ValueSubClass, typename ItemParentClass>
class SymbolTableListTraits;
class Instruction : public User, public ilist_node<Instruction> {
void operator=(const Instruction &); Instruction(const Instruction &);
BasicBlock *Parent;
friend class SymbolTableListTraits<Instruction, BasicBlock>;
void setParent(BasicBlock *P);
protected:
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
Instruction *InsertBefore = 0);
Instruction(const Type *Ty, unsigned iType, Use *Ops, unsigned NumOps,
BasicBlock *InsertAtEnd);
public:
~Instruction();
bool mayWriteToMemory() const;
bool mayReadFromMemory() const;
virtual Instruction *clone() const = 0;
bool isIdenticalTo(const Instruction *I) const;
bool isSameOperationAs(const Instruction *I) const;
bool isUsedOutsideOfBlock(const BasicBlock *BB) const;
Instruction *use_back() { return cast<Instruction>(*use_begin());}
const Instruction *use_back() const { return cast<Instruction>(*use_begin());}
inline const BasicBlock *getParent() const { return Parent; }
inline BasicBlock *getParent() { return Parent; }
void removeFromParent();
void eraseFromParent();
void insertBefore(Instruction *InsertPos);
void insertAfter(Instruction *InsertPos);
void moveBefore(Instruction *MovePos);
unsigned getOpcode() const { return getValueID() - InstructionVal; }
const char *getOpcodeName() const { return getOpcodeName(getOpcode()); }
bool isTerminator() const { return isTerminator(getOpcode()); }
bool isBinaryOp() const { return isBinaryOp(getOpcode()); }
bool isShift() { return isShift(getOpcode()); }
bool isCast() const { return isCast(getOpcode()); }
static const char* getOpcodeName(unsigned OpCode);
static inline bool isTerminator(unsigned OpCode) {
return OpCode >= TermOpsBegin && OpCode < TermOpsEnd;
}
static inline bool isBinaryOp(unsigned Opcode) {
return Opcode >= BinaryOpsBegin && Opcode < BinaryOpsEnd;
}
static inline bool isShift(unsigned Opcode) {
return Opcode >= Shl && Opcode <= AShr;
}
inline bool isLogicalShift() const {
return getOpcode() == Shl || getOpcode() == LShr;
}
inline bool isArithmeticShift() const {
return getOpcode() == AShr;
}
static inline bool isCast(unsigned OpCode) {
return OpCode >= CastOpsBegin && OpCode < CastOpsEnd;
}
bool isAssociative() const { return isAssociative(getOpcode(), getType()); }
static bool isAssociative(unsigned op, const Type *Ty);
bool isCommutative() const { return isCommutative(getOpcode()); }
static bool isCommutative(unsigned op);
bool isTrapping() const {
return isTrapping(getOpcode());
}
static bool isTrapping(unsigned op);
static inline bool classof(const Instruction *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() >= Value::InstructionVal;
}
enum TermOps { #define FIRST_TERM_INST(N) TermOpsBegin = N,
#define HANDLE_TERM_INST(N, OPC, CLASS) OPC = N,
#define LAST_TERM_INST(N) TermOpsEnd = N+1
#include "llvm/Instruction.def"
};
enum BinaryOps {
#define FIRST_BINARY_INST(N) BinaryOpsBegin = N,
#define HANDLE_BINARY_INST(N, OPC, CLASS) OPC = N,
#define LAST_BINARY_INST(N) BinaryOpsEnd = N+1
#include "llvm/Instruction.def"
};
enum MemoryOps {
#define FIRST_MEMORY_INST(N) MemoryOpsBegin = N,
#define HANDLE_MEMORY_INST(N, OPC, CLASS) OPC = N,
#define LAST_MEMORY_INST(N) MemoryOpsEnd = N+1
#include "llvm/Instruction.def"
};
enum CastOps {
#define FIRST_CAST_INST(N) CastOpsBegin = N,
#define HANDLE_CAST_INST(N, OPC, CLASS) OPC = N,
#define LAST_CAST_INST(N) CastOpsEnd = N+1
#include "llvm/Instruction.def"
};
enum OtherOps {
#define FIRST_OTHER_INST(N) OtherOpsBegin = N,
#define HANDLE_OTHER_INST(N, OPC, CLASS) OPC = N,
#define LAST_OTHER_INST(N) OtherOpsEnd = N+1
#include "llvm/Instruction.def"
};
};
template<>
class PointerLikeTypeTraits<Instruction*> {
typedef Instruction* PT;
public:
static inline void *getAsVoidPointer(PT P) { return P; }
static inline PT getFromVoidPointer(void *P) {
return static_cast<PT>(P);
}
enum { NumLowBitsAvailable = 2 };
};
}
#endif