[Beignet] [PATCH 1/6] GBE: Support more instructions for constant expression handling.
Zhigang Gong
zhigang.gong at intel.com
Tue Nov 4 21:41:11 PST 2014
Add support for the following OPs:
FCmp/ICmp/FPToSI/FPToUI/SIToFP/UIToFP.
Signed-off-by: Zhigang Gong <zhigang.gong at intel.com>
---
backend/src/ir/immediate.cpp | 45 +++++++++++++++++++++++++++++----
backend/src/ir/immediate.hpp | 40 ++++++++++++++++++++++++-----
backend/src/llvm/llvm_gen_backend.cpp | 47 ++++++++++++++++++++++++++++++++++-
3 files changed, 120 insertions(+), 12 deletions(-)
diff --git a/backend/src/ir/immediate.cpp b/backend/src/ir/immediate.cpp
index 3a6b9a2..6c0922e 100644
--- a/backend/src/ir/immediate.cpp
+++ b/backend/src/ir/immediate.cpp
@@ -23,15 +23,15 @@ using namespace ir;
#define SCALAR_SAME_TYPE_ASSERT() \
GBE_ASSERT(this->getType() == right.getType() && \
this->getElemNum() == right.getElemNum() && \
- this->getElemNum() == 1 && \
- this->getType() != TYPE_BOOL);
+ this->getElemNum() == 1)
#define DECLAR_BINARY_ALL_TYPE_OP(OP) \
Immediate Immediate::operator OP (const Immediate &right) const { \
- SCALAR_SAME_TYPE_ASSERT(); \
+ /*SCALAR_SAME_TYPE_ASSERT();*/ \
switch (this->getType()) { \
default: \
GBE_ASSERT(0); \
+ case TYPE_BOOL: return Immediate(*this->data.b OP *right.data.b); \
case TYPE_S8: return Immediate(*this->data.s8 OP *right.data.s8); \
case TYPE_U8: return Immediate(*this->data.u8 OP *right.data.u8); \
case TYPE_S16: return Immediate(*this->data.s16 OP *right.data.s16); \
@@ -50,15 +50,24 @@ using namespace ir;
DECLAR_BINARY_ALL_TYPE_OP(-)
DECLAR_BINARY_ALL_TYPE_OP(*)
DECLAR_BINARY_ALL_TYPE_OP(/)
+ DECLAR_BINARY_ALL_TYPE_OP(>)
+ //DECLAR_BINARY_ALL_TYPE_OP(<)
+ DECLAR_BINARY_ALL_TYPE_OP(==)
+ DECLAR_BINARY_ALL_TYPE_OP(!=)
+ DECLAR_BINARY_ALL_TYPE_OP(>=)
+ DECLAR_BINARY_ALL_TYPE_OP(<=)
+ DECLAR_BINARY_ALL_TYPE_OP(&&)
#undef DECLAR_BINARY_ALL_TYPE_OP
+
#define DECLAR_BINARY_INT_TYPE_OP(OP) \
Immediate Immediate::operator OP (const Immediate &right) const { \
- SCALAR_SAME_TYPE_ASSERT(); \
+ /*SCALAR_SAME_TYPE_ASSERT();*/ \
switch (this->getType()) { \
default: \
GBE_ASSERT(0); \
+ case TYPE_BOOL: return Immediate(*this->data.b OP *right.data.b); \
case TYPE_S8: return Immediate(*this->data.s8 OP *right.data.s8); \
case TYPE_U8: return Immediate(*this->data.u8 OP *right.data.u8); \
case TYPE_S16: return Immediate(*this->data.s16 OP *right.data.s16); \
@@ -122,6 +131,25 @@ using namespace ir;
}
}
+ Immediate Immediate::less (const Immediate &left, const Immediate &right) {
+ GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_U64);
+ switch (left.getType()) {
+ default:
+ GBE_ASSERT(0);
+ case TYPE_S8: return Immediate(*left.data.s8 < *right.data.s8);
+ case TYPE_U8: return Immediate(*left.data.u8 < *right.data.u8);
+ case TYPE_S16: return Immediate(*left.data.s16 < *right.data.s16);
+ case TYPE_U16: return Immediate(*left.data.u16 < *right.data.u16);
+ case TYPE_S32: return Immediate(*left.data.s32 < *right.data.s32);
+ case TYPE_U32: return Immediate(*left.data.u32 < *right.data.u32);
+ case TYPE_S64: return Immediate(*left.data.s64 < *right.data.s64);
+ case TYPE_U64: return Immediate(*left.data.u64 < *right.data.u64);
+ case TYPE_FLOAT: return Immediate(*left.data.f32 < *right.data.f32);
+ case TYPE_DOUBLE: return Immediate(*left.data.f64 < *right.data.f64);
+ }
+ }
+
+
Immediate::Immediate(ImmOpCode op, const Immediate &left, const Immediate &right, Type dstType) {
switch (op) {
default:
@@ -181,9 +209,16 @@ using namespace ir;
}
break;
}
+ case IMM_OEQ: *this = left == right; break;
+ case IMM_ONE: *this = left != right; break;
+ case IMM_OLE: *this = left <= right; break;
+ case IMM_OGE: *this = left >= right; break;
+ case IMM_OLT: *this = less(left, right); break;
+ case IMM_OGT: *this = left > right; break;
+ case IMM_ORD: *this = (left == left) && (right == right); break;
}
// If the dst type is large int, we will not change the imm type to large int.
- GBE_ASSERT(type == (ImmType)dstType || dstType == TYPE_LARGE_INT);
+ GBE_ASSERT(type == (ImmType)dstType || dstType == TYPE_LARGE_INT || dstType == TYPE_BOOL);
}
Immediate::Immediate(const vector<const Immediate*> immVec) {
diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp
index 85f14a0..763d3e9 100644
--- a/backend/src/ir/immediate.hpp
+++ b/backend/src/ir/immediate.hpp
@@ -45,7 +45,18 @@ namespace ir {
IMM_LSHR,
IMM_AND,
IMM_OR,
- IMM_XOR
+ IMM_XOR,
+ IMM_OEQ,
+ IMM_ONE,
+ IMM_OLE,
+ IMM_OGE,
+ IMM_OLT,
+ IMM_OGT,
+ IMM_ORD,
+ IMM_FPTOUI,
+ IMM_FPTOSI,
+ IMM_SITOFP,
+ IMM_UITOFP
} ImmOpCode;
typedef enum {
@@ -190,11 +201,20 @@ namespace ir {
}
Immediate(ImmOpCode op, const Immediate &other, Type dstType) {
- if (op == IMM_TRUNC) {
- copy(other, 0, 1);
- } else if (op == IMM_BITCAST) {
- *this = other;
- type = (ImmType)dstType;
+ switch (op) {
+ default:
+ GBE_ASSERT(0);
+ case IMM_TRUNC:
+ copy(other, 0, 1);
+ break;
+ case IMM_BITCAST:
+ *this = other;
+ type = (ImmType)dstType;
+ break;
+ case IMM_FPTOUI: *this = Immediate((uint32_t)*other.data.f32); break;
+ case IMM_FPTOSI: *this = Immediate((int32_t)*other.data.f32); break;
+ case IMM_UITOFP: *this = Immediate((float)*other.data.u32); break;
+ case IMM_SITOFP: *this = Immediate((float)*other.data.s32); break;
}
}
@@ -231,6 +251,12 @@ namespace ir {
Immediate operator- (const Immediate &) const;
Immediate operator* (const Immediate &) const;
Immediate operator/ (const Immediate &) const;
+ Immediate operator> (const Immediate &) const;
+ Immediate operator== (const Immediate &) const;
+ Immediate operator!= (const Immediate &) const;
+ Immediate operator>= (const Immediate &) const;
+ Immediate operator<= (const Immediate &) const;
+ Immediate operator&& (const Immediate &) const;
Immediate operator% (const Immediate &) const;
Immediate operator& (const Immediate &) const;
Immediate operator| (const Immediate &) const;
@@ -238,6 +264,8 @@ namespace ir {
Immediate operator<< (const Immediate &) const;
Immediate operator>> (const Immediate &) const;
static Immediate lshr (const Immediate &left, const Immediate &right);
+ static Immediate less (const Immediate &left, const Immediate &right);
+
void copy(const Immediate &other, int32_t offset, uint32_t num);
GBE_CLASS(Immediate);
};
diff --git a/backend/src/llvm/llvm_gen_backend.cpp b/backend/src/llvm/llvm_gen_backend.cpp
index 6ccedbd..fe24b78 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -954,7 +954,7 @@ namespace gbe
ir::Type type = getType(ctx, ce->getType());
switch (ce->getOpcode()) {
default:
- //ce->dump();
+ ce->dump();
GBE_ASSERT(0 && "unsupported ce opcode.\n");
case Instruction::Trunc:
{
@@ -968,6 +968,23 @@ namespace gbe
return immIndex;
return ctx.processImm(ir::IMM_BITCAST, immIndex, type);
}
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::SIToFP:
+ case Instruction::UIToFP:
+ {
+ const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
+ switch (ce->getOpcode()) {
+ default:
+ GBE_ASSERT(0);
+ case Instruction::FPToUI: return ctx.processImm(ir::IMM_FPTOUI, immIndex, type);
+ case Instruction::FPToSI: return ctx.processImm(ir::IMM_FPTOSI, immIndex, type);
+ case Instruction::SIToFP: return ctx.processImm(ir::IMM_SITOFP, immIndex, type);
+ case Instruction::UIToFP: return ctx.processImm(ir::IMM_UITOFP, immIndex, type);
+ }
+ }
+ case Instruction::FCmp:
+ case Instruction::ICmp:
case Instruction::Add:
case Instruction::Sub:
case Instruction::Mul:
@@ -1007,7 +1024,35 @@ namespace gbe
return ctx.processImm(ir::IMM_OR, lhs, rhs, type);
case Instruction::Xor:
return ctx.processImm(ir::IMM_XOR, lhs, rhs, type);
+ case Instruction::FCmp:
+ case Instruction::ICmp:
+ switch (ce->getPredicate()) {
+ default:
+ NOT_SUPPORTED;
+ case ICmpInst::ICMP_EQ:
+ case ICmpInst::FCMP_OEQ: return ctx.processImm(ir::IMM_OEQ, lhs, rhs, type);
+ case ICmpInst::ICMP_NE:
+ case ICmpInst::FCMP_ONE: return ctx.processImm(ir::IMM_ONE, lhs, rhs, type);
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::FCMP_OLE: return ctx.processImm(ir::IMM_OLE, lhs, rhs, type);
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ case ICmpInst::FCMP_OGE: return ctx.processImm(ir::IMM_OGE, lhs, rhs, type);
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT:
+ case ICmpInst::FCMP_OLT: return ctx.processImm(ir::IMM_OLT, lhs, rhs, type);
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ case ICmpInst::FCMP_OGT: return ctx.processImm(ir::IMM_OGT, lhs, rhs, type);
+ case ICmpInst::FCMP_ORD: return ctx.processImm(ir::IMM_ORD, lhs, rhs, type);
+ case ICmpInst::FCMP_TRUE:
+ Value *cv = ConstantInt::get(ce->getType(), 1);
+ return ctx.newImmediate(cv);
+ }
+ break;
}
+ break;
}
}
}
--
1.8.3.2
More information about the Beignet
mailing list