[Beignet] [PATCH v2 2/2] GBE: Add some missing constant expression cases.

Zhigang Gong zhigang.gong at intel.com
Thu Dec 4 01:45:17 PST 2014


From: Zhigang Gong <zhigang.gong at linux.intel.com>

Major for two types of constant expression cases:
1. The destination is a vector.
2. Some missing operators.

Signed-off-by: Zhigang Gong <zhigang.gong at linux.intel.com>
---
 backend/src/ir/context.hpp            |  4 +-
 backend/src/ir/immediate.cpp          | 34 +++++++++++++++--
 backend/src/ir/immediate.hpp          | 70 +++++++++++++++++++++++++++++++++--
 backend/src/llvm/llvm_gen_backend.cpp | 38 ++++++++++++++++++-
 4 files changed, 135 insertions(+), 11 deletions(-)

diff --git a/backend/src/ir/context.hpp b/backend/src/ir/context.hpp
index 485d558..cf5109d 100644
--- a/backend/src/ir/context.hpp
+++ b/backend/src/ir/context.hpp
@@ -74,11 +74,11 @@ namespace ir {
       return fn->newImmediate(imm);
     }
     /*! Create a new immediate value */
-    INLINE ImmediateIndex newImmediate(vector<ImmediateIndex>indexVector) {
+    INLINE ImmediateIndex newImmediate(vector<ImmediateIndex>indexVector, Type dstType) {
       vector<const Immediate*> immVector;
       for( uint32_t i = 0; i < indexVector.size(); i++)
         immVector.push_back(&fn->getImmediate(indexVector[i]));
-      const Immediate imm(immVector);
+      const Immediate imm(immVector, dstType);
       return fn->newImmediate(imm);
     }
     /*! Create an integer immediate value */
diff --git a/backend/src/ir/immediate.cpp b/backend/src/ir/immediate.cpp
index 7d26925..1aac9bc 100644
--- a/backend/src/ir/immediate.cpp
+++ b/backend/src/ir/immediate.cpp
@@ -132,7 +132,7 @@ using namespace ir;
     }
 
     Immediate Immediate::less (const Immediate &left, const Immediate &right) {
-      GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_U64);
+      GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_DOUBLE);
       switch (left.getType()) {
         default:
           GBE_ASSERT(0);
@@ -149,6 +149,30 @@ using namespace ir;
       }
     }
 
+    Immediate Immediate::extract (const Immediate &left, const Immediate &right, Type dstType) {
+      GBE_ASSERT(left.getType() > TYPE_BOOL && left.getType() <= TYPE_DOUBLE);
+      GBE_ASSERT(dstType == left.getType());
+      uint32_t index = right.getIntegerValue();
+      GBE_ASSERT(index >= 0 && index < left.getElemNum());
+      if (left.type != IMM_TYPE_COMP) {
+        switch (left.getType()) {
+          default:
+            GBE_ASSERT(0);
+          case TYPE_BOOL:   return Immediate(left.data.b[index]);
+          case TYPE_S8:     return Immediate(left.data.s8[index]);
+          case TYPE_U8:     return Immediate(left.data.u8[index]);
+          case TYPE_S16:    return Immediate(left.data.s16[index]);
+          case TYPE_U16:    return Immediate(left.data.u16[index]);
+          case TYPE_S32:    return Immediate(left.data.s32[index]);
+          case TYPE_U32:    return Immediate(left.data.u32[index]);
+          case TYPE_S64:    return Immediate(left.data.s64[index]);
+          case TYPE_U64:    return Immediate(left.data.u64[index]);
+          case TYPE_FLOAT:  return Immediate(left.data.f32[index]);
+          case TYPE_DOUBLE: return Immediate(left.data.f64[index]);
+        }
+      } else
+        return *left.data.immVec[index];
+    }
 
     Immediate::Immediate(ImmOpCode op, const Immediate &left, const Immediate &right, Type dstType) {
       switch (op) {
@@ -180,7 +204,7 @@ using namespace ir;
         case IMM_LSHR:
         {
           if (left.getElemNum() == 1)
-            lshr(left, right);
+            *this = lshr(left, right);
           else {
             GBE_ASSERT(right.getIntegerValue() <= (left.getElemNum() * left.getTypeSize() * 8));
             GBE_ASSERT(right.getIntegerValue() % (left.getTypeSize() * 8) == 0);
@@ -216,16 +240,17 @@ using namespace ir;
         case IMM_OLT: *this = less(left, right); break;
         case IMM_OGT: *this = left > right; break;
         case IMM_ORD: *this = (left == left) && (right == right); break;
+        case IMM_EXTRACT: *this = extract(left, right, dstType); 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 || dstType == TYPE_BOOL);
     }
 
-    Immediate::Immediate(const vector<const Immediate*> immVec) {
+    Immediate::Immediate(const vector<const Immediate*> immVec, Type dstType) {
       if (immVec.size() == 1) {
         *this = *immVec[0];
       } else if (!(immVec[0]->isCompType()) && immVec[0]->elemNum == 1) {
-        this->type = immVec[0]->type;
+        this->type = (ImmType)dstType;
         this->elemNum = immVec.size();
         if (immVec[0]->getTypeSize() * immVec.size() < 8)
           this->data.p = &this->defaultData;
@@ -238,6 +263,7 @@ using namespace ir;
           p += immVec[i]->getTypeSize();
         }
       } else {
+        GBE_ASSERT(0);
         this->type = IMM_TYPE_COMP;
         if (immVec.size() * sizeof(Immediate*) < 8)
           this->data.p = &this->defaultData;
diff --git a/backend/src/ir/immediate.hpp b/backend/src/ir/immediate.hpp
index 1f18a4c..7b6ba34 100644
--- a/backend/src/ir/immediate.hpp
+++ b/backend/src/ir/immediate.hpp
@@ -56,7 +56,11 @@ namespace ir {
     IMM_FPTOUI,
     IMM_FPTOSI,
     IMM_SITOFP,
-    IMM_UITOFP
+    IMM_UITOFP,
+    IMM_EXTRACT,
+    IMM_SEXT,
+    IMM_ZEXT,
+    IMM_FPEXT
   } ImmOpCode;
 
   typedef enum {
@@ -158,7 +162,7 @@ namespace ir {
     DECL_CONSTRUCTOR(double, f64, TYPE_DOUBLE, elemNum)
 #undef DECL_CONSTRUCTOR
 
-    Immediate(const vector<const Immediate*> immVec);
+    Immediate(const vector<const Immediate*> immVec, Type dstType);
 
     INLINE int64_t getIntegerValue(void) const {
       switch (type) {
@@ -176,6 +180,22 @@ namespace ir {
       }
     }
 
+    INLINE uint64_t getUnsignedIntegerValue(void) const {
+      switch (type) {
+        default:
+          GBE_ASSERT(0 && "Invalid immediate type.\n");
+        case TYPE_BOOL: return *data.b;
+        case TYPE_S8:   return *data.s8;
+        case TYPE_U8:   return *data.u8;
+        case TYPE_S16:  return *data.s16;
+        case TYPE_U16:  return *data.u16;
+        case TYPE_S32:  return *data.s32;
+        case TYPE_U32:  return *data.u32;
+        case TYPE_S64:  return *data.s64;
+        case TYPE_U64:  return *data.u64;
+      }
+    }
+
     INLINE float getFloatValue(void) const {
       GBE_ASSERT(type == IMM_TYPE_FLOAT);
       return *data.f32;
@@ -208,13 +228,54 @@ namespace ir {
           copy(other, 0, 1);
           break;
         case IMM_BITCAST:
-          *this = other;
-          type = (ImmType)dstType;
+          if (other.type != IMM_TYPE_COMP) {
+            *this = other;
+            type = (ImmType)dstType;
+          } else {
+            vector<const Immediate*> immVec;
+            for(uint32_t i = 0; i < other.getElemNum(); i++)
+              immVec.push_back(other.data.immVec[i]);
+            *this = Immediate(immVec, 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;
+        case IMM_SEXT:
+        {
+          int64_t value = other.getIntegerValue();
+          if (other.getType() == TYPE_BOOL)
+            value = -value;
+          switch (dstType) {
+            default:
+              GBE_ASSERT(0 && "Illegal sext constant expression");
+            case TYPE_S8:     *this = Immediate((int8_t)value); break;
+            case TYPE_S16:    *this = Immediate((int16_t)value); break;
+            case TYPE_S32:    *this = Immediate((int32_t)value); break;
+            case TYPE_S64:    *this = Immediate((int64_t)value); break;
+          }
+        }
+        case IMM_ZEXT:
+        {
+          uint64_t value = other.getUnsignedIntegerValue();
+          switch (dstType) {
+            default:
+              GBE_ASSERT(0 && "Illegal sext constant expression");
+            case TYPE_U8:     *this = Immediate((uint8_t)value); break;
+            case TYPE_U16:    *this = Immediate((uint16_t)value); break;
+            case TYPE_U32:    *this = Immediate((uint32_t)value); break;
+            case TYPE_U64:    *this = Immediate((uint64_t)value); break;
+          }
+          break;
+        }
+        case IMM_FPEXT:
+        {
+          GBE_ASSERT(other.getType() == TYPE_FLOAT && dstType == TYPE_DOUBLE);
+          double value = other.getFloatValue();
+          *this = Immediate(value);
+          break;
+        }
       }
     }
 
@@ -265,6 +326,7 @@ namespace ir {
     Immediate operator>> (const Immediate &) const;
     static Immediate lshr (const Immediate &left, const Immediate &right);
     static Immediate less (const Immediate &left, const Immediate &right);
+    static Immediate extract (const Immediate &left, const Immediate &right, Type dstType);
 
     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 c7ecc44..a438f09 100644
--- a/backend/src/llvm/llvm_gen_backend.cpp
+++ b/backend/src/llvm/llvm_gen_backend.cpp
@@ -902,7 +902,7 @@ namespace gbe
       vector<ir::ImmediateIndex> immVector;
       for (uint32_t i = 0; i < cv->getNumOperands(); i++)
         immVector.push_back(processConstantImmIndex(cv->getOperand(i)));
-      return ctx.newImmediate(immVector);
+      return ctx.newImmediate(immVector, getType(ctx, cv->getType()->getElementType()));
     }
   }
 
@@ -1045,11 +1045,25 @@ namespace gbe
 
     if (dyn_cast<ConstantExpr>(CPV)) {
       ConstantExpr *ce = dyn_cast<ConstantExpr>(CPV);
+
+      if (!isScalarType(ce->getType())) {
+        VectorType *vecType = cast<VectorType>(ce->getType());
+        GBE_ASSERT(ce->getOpcode() == Instruction::BitCast);
+        GBE_ASSERT(isScalarType(vecType->getElementType()));
+        ir::Type elemType = getType(ctx, vecType->getElementType());
+
+        const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
+        const ir::Immediate imm = ctx.getImmediate(immIndex);
+        GBE_ASSERT(vecType->getNumElements() == imm.getElemNum() &&
+                   getTypeByteSize(unit, vecType->getElementType()) == imm.getTypeSize());
+        return ctx.processImm(ir::IMM_BITCAST, immIndex, elemType);
+      }
       ir::Type type = getType(ctx, ce->getType());
       switch (ce->getOpcode()) {
         default:
           ce->dump();
           GBE_ASSERT(0 && "unsupported ce opcode.\n");
+        case Instruction::FPTrunc:
         case Instruction::Trunc:
         {
           const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
@@ -1066,6 +1080,9 @@ namespace gbe
         case Instruction::FPToSI:
         case Instruction::SIToFP:
         case Instruction::UIToFP:
+        case Instruction::SExt:
+        case Instruction::ZExt:
+        case Instruction::FPExt:
         {
           const ir::ImmediateIndex immIndex = processConstantImmIndex(ce->getOperand(0), -1);
           switch (ce->getOpcode()) {
@@ -1075,15 +1092,26 @@ namespace gbe
             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::SExt:  return ctx.processImm(ir::IMM_SEXT, immIndex, type);
+            case Instruction::ZExt:  return ctx.processImm(ir::IMM_ZEXT, immIndex, type);
+            case Instruction::FPExt: return ctx.processImm(ir::IMM_FPEXT, immIndex, type);
           }
         }
+
+        case Instruction::ExtractElement:
         case Instruction::FCmp:
         case Instruction::ICmp:
+        case Instruction::FAdd:
         case Instruction::Add:
         case Instruction::Sub:
+        case Instruction::FSub:
         case Instruction::Mul:
+        case Instruction::FMul:
         case Instruction::SDiv:
+        case Instruction::UDiv:
+        case Instruction::FDiv:
         case Instruction::SRem:
+        case Instruction::FRem:
         case Instruction::Shl:
         case Instruction::AShr:
         case Instruction::LShr:
@@ -1096,15 +1124,23 @@ namespace gbe
           default:
             //ce->dump();
             GBE_ASSERTM(0, "Unsupported constant expression.\n");
+
+          case Instruction::ExtractElement:
+            return ctx.processImm(ir::IMM_EXTRACT, lhs, rhs, type);
           case Instruction::Add:
+          case Instruction::FAdd:
             return ctx.processImm(ir::IMM_ADD, lhs, rhs, type);
+          case Instruction::FSub:
           case Instruction::Sub:
             return ctx.processImm(ir::IMM_SUB, lhs, rhs, type);
           case Instruction::Mul:
+          case Instruction::FMul:
             return ctx.processImm(ir::IMM_MUL, lhs, rhs, type);
           case Instruction::SDiv:
+          case Instruction::FDiv:
             return ctx.processImm(ir::IMM_DIV, lhs, rhs, type);
           case Instruction::SRem:
+          case Instruction::FRem:
             return ctx.processImm(ir::IMM_REM, lhs, rhs, type);
           case Instruction::Shl:
             return ctx.processImm(ir::IMM_SHL, lhs, rhs, type);
-- 
1.8.3.2



More information about the Beignet mailing list