[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